Example: Identifying SPiceX inputs

This example program is handy for familiarizing yourself with the mapping of the SPiceX inputs.

;IDENTIN.SPT : Sample program to identify which inputs get
;reflected in which bytes/bits of U when using the
;SPxTxfr instruction.

;The program senses just one expansion input turned on 
;at a time. It reads in up to 8 bytes of input data using SPxTxfrU
;and saves them in RAM. It then inspects the RAM to find a set bit.
;Finally it displays the byte/bit number in onboard outputs
; 0-7. Bits 3-6 contain the byte number. Bits 0-2 contain the
;bit number within that byte. Bit 7 is BLINKed to signal the presence of data
;(otherwise byte 0, bit 0 would show nothing).

;You can also inspect the raw data using SPLatLink (The SL button
;in the Module window of SPLat/PC). 
;Data is in locations 0 up, inverted. Click the Format button in the 
;Data memory window to get binary formatting.

****************************************************************
;Set the following constant to reflect the number of bytes of 
;data being shifted in.
;
;       XBIO16          2 bytes
;       MBIO16          2 bytes
;       XIRO16          1 byte
;       HIO16           1 byte
;       FP16            1 byte


ShiftLength     EQU             8       ;Minimum 5 with standard expansion boards!

**** NOTE ****
;SPiceX mode works only with standard XPice expansion boards when
;there are more than 4 bytes of data. For less than that the
;automatic detection will sense the boards and map them as
;regular I/O. 
;With custom expansion boards it may work with fewer than 5 bytes,
;depending on the design of the board. Please consult the board documentation.
****************************************************************

                SPxMode         6
                SetV            ShiftLength     ;Will henceforth control how
                                                ;many bytes get transferred
;Back here when no inputs are detected
Nothing:
                LoadX           0       ;Data
                LoadX           255     ;Bit select mask for OutputM
                OutputM         0       ;Clear result display
NextRead:
                ClrU                    ;Don't want any output data
                SPxTxfrU        0       ;Reads the inputs
                UVToMem         0,0     ;Copy V bytes from U to memory

;Identify the first non-zero byte. I is used as a counter/pointer
                LoadI           ShiftLength
ByteLoop:
                ItoX                    ;Check the counter/pointer
                Push
                GoIfZ           Nothing ;Exhausted all bytes
                DecX                    ;Bump the pointer
                XtoI
                iRecall         0       ;Get byte pointed to by I
                notm                    ;Raw input data is inverted
                GoIfZ           ByteLoop

;Fall down here if we found a NZ byte
                ItoX                    ;Byte number
                LoadX           7       ;Select 3 bits of byte number
                OutputM         3       ;Display

;Identify the first NZ bit within the byte. We know the
;byte is NZ, so there's no need to defend against not finding
;a bit set.
                iRecall         0       ;Get back the byte pointed to by I
                notm                    ;Raw input data is inverted
                LoadI           0       ;Use I as a counter
BitLoop:
                Push
                LoadX           1       ;a mask
                AndM                    ;select bit 0
                GoIfNZ          FoundBit
                IncI
                RORM
                GoTo            BitLoop

FoundBit:
                ItoX
                LoadX           7
                OutputM         0
                Blink           7

                GoTo            NextRead