        
;
; Directives
;
                device  sx28, oschs2   ; device fuses
                device  turbo, stackx_optionx;, protect

                freq    50000000                        ; frequency directive for in-circuit debug

                id      'AEIDM1S'                       ; Analogic Engineering, Inc. - Digital Module 1 Slave

                reset   Start                           ; program start


;
; Port Definitions
;

;
; Port A is the DATA-FIFOs Write Strobes
;
FIFOWrites      =       ra              ; name of port
FIFOWritesDir   =       %0000           ; all outputs
FIFOWritesInit  =       %1111           ; output signals are active low, so initialize high
FIFO1Write      =       FIFOWrites.0    ; RA0 output - DATA FIFO 1 (LSB) write strobe output
FIFO2Write      =       FIFOWrites.1    ; RA1 output - DATA FIFO 2 write strobe output
FIFO3Write      =       FIFOWrites.2    ; RA2 output - DATA FIFO 3 write strobe output
FIFO4Write      =       FIFOWrites.3    ; RA3 output - DATA FIFO 4 (MSB) write strobe output

;
; Port B is control signals consisting of 4 bit command bus, command input, response output, 
; Data FIFO sync and Data FIFOs reset
;
ControlPort     =       rb              ; name of port
ControlPortDir  =       %00011111       ; FIFOReset, FIFOSync and Response are outputs, the rest are inputs
ControlPortInit =       %11111111       ; output signals are active low, so initialize high
Command         =       ControlPort.4   ; RC4 input - from control processor to signal new command 
Response        =       ControlPort.5   ; RC5 output - to control processor to signal response to last command
FIFOSync        =       ControlPort.6   ; RC6 output - to bit 9 of DATA FIFO 4 to signal end of cycle
FIFOReset       =       ControlPort.7   ; RC7 output - to reset of all DATA FIFO's

;
; Port C is the data bus for data transfer between the Main Controller, Sample Controller,
; A/D EROM and the 4 data FIFOs
;
DataPort        =       rc              ; name of port
DataPortDir     =       %11111111       ; start as all inputs, but will be used as bidirectional data bus
DataPortInit    =       %11111111       ; data bus is active low, so initialize high


;
; 4 bit command codes from the Main Controller (PIC17C756, U2)
;
; $0 -> restart - initialize all registers and clear FIFOs
; $1 -> clear (empty) the FIFOs
;
; $2 -> sample a cycle and update peak signal level for each pixel
;
; $3 -> output a cycle to FIFOs and reset pixels
;
; $4 -> read maximum pixel between Detect1From and Detect1To inclusive
; $5 -> read maximum pixel between Detect2From and Detect2To inclusive
; $6 -> read maximum pixel between Detect3From and Detect3To inclusive
; $7 -> read maximum pixel between Detect4From and Detect4To inclusive
;
; $8 -> receive the ReadWriteIndex register address from the Main Controller
; $9 -> write data to the ReadWriteIndex address
; $A -> read data from the ReadWriteIndex address
; $B -> write data to the ReadWriteIndex address and increment ReadWriteIndex
; $C -> read data from the ReadWriteIndex address and increment ReadWriteIndex
;
; All other command codes are invalid - they are acknowledged and ignored, and the error flag is set 
;
        
;
; Non-banked Variables
;

                org     $8              ; for RAM

ReadWriteIndex  ds      1               ; $8 = address to allow the Main Controller to read or write data

Flags           ds      1               ; $9 = Options/Status flags register

LevelBit0       =       Flags.0         ; Bit 0 is low bit of threshold levels select
LevelBit1       =       Flags.1         ; Bit 1 is high bit of threshold levels select
                                        ;      00 -> 1 threshold level, 2 colors
                                        ;            1 bit encoding - 1 (min) or 0 (max)
                                        ; 
                                        ;      01 -> 2 threshold levels, 3 colors
                                        ;            2 bit encoding - 11 (min), 10, or 00 (max)
                                        ;
                                        ;      10 -> 4 threshold levels, 5 colors 
                                        ;            4 bit encoding - 1111 (min), 1110, 1100, 1000 or 0000 (max)
                                        ;
                                        ;      11 -> 8 threshold levels, 9 colors
                                        ;            8 bit encoding  - 11111111 (min), 11111110, 11111100,
                                        ;                              11111000, 11110000, 11100000,
                                        ;                              11000000, 10000000 or 00000000 (max) 

LogEnable       =       Flags.2         ; Bit 2 is log output enable
                                        ;      0 -> use linear conversion from 8 bit to 1, 2, 4 or 8 output bits
                                        ;      1 -> use log conversion from 8 bit to 2 or 4 output bits

AnalogEnable    =       Flags.3         ; Bit 3 is analog sample enable
                                        ;      0 -> sample 8 bits as 8 signal threshold levels
                                        ;      1 -> sample 8 bits as binary digitized analog data

TestEnable      =       Flags.4         ; Bit 4 is test pattern enable
                                        ;      0 -> normal
                                        ;      1 -> generate test pattern

ErrorFlag       =       Flags.7         ; Bit 7 is error flag 

PixelSize       ds      1               ; $A = requested pixel size in clock cycles

PixelCount      ds      1               ; $B = the number of pixels per cycle (must be from 1 to 120)

AlarmLevel      ds      1               ; $C = alarm level threshhold


LoopCount       ds      1               ; $D = general purpose loop counter

Temp            ds      1               ; $E = general purpose register

Temp1           ds      1               ; $F = general purpose register

;
; Pixel array starts at Bank 0, $10 and uses the 16 upper RAM bytes of first 7 banks + $10-$17 of bank
; 8.  The 120 bytes of the pixel array are accessed using indirect addressing via the FSR and IND 
; registers.  If the FSR is incremented into the next bank, bit 4 of the FSR is set high to skip over 
; the lower 16 bytes of the bank.  It is quicker to always set this bit if it is possible that the 
; last FSR increment changed banks, rather than checking first to see if bit 4 is low - i.e. "setb FSR.4"
; verses "sb FSR.4, set FSR.4"  
;
PixelArray      =       $10             ; start of pixel array

;
; From-To paint array resides in the last 8 bytes of Bank 7.  There can be a maximum of 4 From-To
; values.
;
DetectArray     =       $F4             ; start of detect from/to array

		org	DetectArray     ; array starts in Byte 8 of Bank 7
Detect1From     ds      1               ; Detector 1 use from pixel
Detect1To       ds      1               ; Detector 1 use to pixel
Detect1AlarmLevel ds    1               ; Detector 1 alarm level
Detect2From     ds      1               ; Detector 2 use from pixel 
Detect2To       ds      1               ; Detector 2 use to pixel
Detect2AlarmLevel ds    1               ; Detector 2 alarm level
Detect3From     ds      1               ; Detector 3 use from pixel 
Detect3To       ds      1               ; Detector 3 use to pixel
Detect3AlarmLevel ds    1               ; Detector 3 alarm level
Detect4From     ds      1               ; Detector 4 use from pixel 
Detect4To       ds      1               ; Detector 4 use to pixel  
Detect4AlarmLevel ds    1               ; Detector 4 alarm level
;
; Macros for output routines
; NEEDS WORK ? - SET BITS DIRECTLY ON PORT ?

;
; OUT1BIT
;
; 1 bit per pixel, 8 pixels per output 
;
;     8 bit pixel in  ->  1 bit out
;     11111111            1         minimum signal (below lowest threshold)
;     11111110            1
;     11111100            1
;     11111000            1
;     11110000            1
;     11100000            1
;     11000000            1
;     10000000            1
;     00000000            0         maximum signal (over highest threshold)
;
OUT1BIT         MACRO

                clr     Temp                      ; reset Temp

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.0                    ; Y - set output bit 0

                mov     IND, #$FF                 ; reset pixel 1

                inc     FSR                       ; point to next pixel

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.1                    ; Y - set output bit 1

                mov     IND, #$FF                 ; reset pixel 2

                inc     FSR                       ; point to next pixel

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.2                    ; Y - set output bit 2

                mov     IND, #$FF                 ; reset pixel 3

                inc     FSR                       ; point to next pixel

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.3                    ; Y - set output bit 3

                mov     IND, #$FF                 ; reset pixel 4

                inc     FSR                       ; point to next pixel

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.4                    ; Y - set output bit 4

                mov     IND, #$FF                 ; reset pixel 5

                inc     FSR                       ; point to next pixel

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.5                    ; Y - set output bit 5

                mov     IND, #$FF                 ; reset pixel 6

                inc     FSR                       ; point to next pixel

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.6                    ; Y - set output bit 6

                mov     IND, #$FF                 ; reset pixel 7

                inc     FSR                       ; point to next pixel

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.7                    ; Y - set output bit 7

                mov     DataPort, Temp            ; place the output byte on the data port

                mov     IND, #$FF                 ; reset pixel 8

                inc     FSR                       ; point to next pixel

                ENDM


;                               
;OUT2BIT        MACRO
;
; 2 bits per pixel, 4 pixels per output 
;
;     8 bit pixel in  ->  2 bit out
;     11111111            11        minimum signal (below lowest threshold)
;     11111110            11
;     11111100            11
;     11111000            11
;     11110000            10
;     11100000            10
;     11000000            10
;     10000000            10
;     00000000            00        maximum signal (over highest threshold)
;
OUT2BIT         MACRO

                clr     Temp                      ; reset Temp

                snb     IND.3                     ; Q - is input bit 3 set          
                setb    Temp.0                    ; Y - set output bit 0

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.1                    ; Y - set output bit 1

                mov     IND, #$FF                 ; reset pixel 1

                inc     FSR                       ; point to next pixel

                snb     IND.3                     ; Q - is input bit 3 set          
                setb    Temp.2                    ; Y - set output bit 2

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.3                    ; Y - set output bit 3

                mov     IND, #$FF                 ; reset pixel 2

                inc     FSR                       ; point to next pixel

                snb     IND.3                     ; Q - is input bit 3 set          
                setb    Temp.4                    ; Y - set output bit 4

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.5                    ; Y - set output bit 5

                mov     IND, #$FF                 ; reset pixel 3

                inc     FSR                       ; point to next pixel

                snb     IND.3                     ; Q - is input bit 3 set          
                setb    Temp.6                    ; Y - set output bit 6

                snb     IND.7                     ; Q - is input bit 7 set          
                setb    Temp.7                    ; Y - set output bit 7

                mov     DataPort, Temp            ; place the output byte on the data port

                mov     IND, #$FF                 ; reset pixel 4

                inc     FSR                       ; point to next pixel

                ENDM


;
;OUT4BITLIN     MACRO                               
;
; 4 bits per pixel, 2 pixels per output, linear conversion 
;
;     8 bit pixel in  ->  4 bit out
;     11111111            1111      minimum signal (below lowest threshold)
;     11111110            1111
;     11111100            1110
;     11111000            1110
;     11110000            1100
;     11100000            1100
;     11000000            1000
;     10000000            1000
;     00000000            0000      maximum signal (over highest threshold)
;
OUT4BITLIN      MACRO 

                clr     Temp                      ; reset Temp

                snb     IND.1                     ; Q - is input bit 1 set          
                setb    Temp.0                    ; Y - set output bit 0
 
                snb     IND.3                     ; Q - is input bit 3 set            
                setb    Temp.1                    ; Y - set output bit 1               

                snb     IND.5                     ; Q - is input bit 5 set            
                setb    Temp.2                    ; Y - set output bit 2

                snb     IND.7                     ; Q - is input bit 7 set            
                setb    Temp.3                    ; Y - set output bit 3
                 
                mov     IND, #$FF                 ; reset pixel 1

                inc     FSR                       ; point to next pixel

                snb     IND.1                     ; Q - is input bit 1 set          
                setb    Temp.4                    ; Y - set output bit 4 

                snb     IND.3                     ; Q - is input bit 3 set            
                setb    Temp.5                    ; Y - set output bit 5               

                snb     IND.5                     ; Q - is input bit 5 set            
                setb    Temp.6                    ; Y - set output bit 6

                snb     IND.7                     ; Q - is input bit 7 set            
                setb    Temp.7                    ; Y - set output bit 7

                mov     DataPort, Temp            ; place the output byte on the data port

                mov     IND, #$FF                 ; reset pixel 2

                inc     FSR                       ; point to next pixel

                ENDM


;
;OUT4BITLOG     MACRO                               
;
; 4 bits per pixel, 2 pixels per output, logarithmic conversion 
;
;     8 bit pixel in  ->  4 bit out
;     11111111            1111      minimum signal (below lowest threshold)
;     11111110            1110
;     11111100            1100
;     11111000            1100
;     11110000            1000
;     11100000            1000
;     11000000            1000
;     10000000            1000
;     00000000            0000      maximum signal (over highest threshold)
;
OUT4BITLOG      MACRO 

                clr     Temp                      ; reset Temp

                snb     IND.0                     ; Q - is input bit 0 set          
                setb    Temp.0                    ; Y - set output bit 0
 
                snb     IND.1                     ; Q - is input bit 1 set            
                setb    Temp.1                    ; Y - set output bit 1               

                snb     IND.3                     ; Q - is input bit 4 set            
                setb    Temp.2                    ; Y - set output bit 2

                snb     IND.7                     ; Q - is input bit 8 set            
                setb    Temp.3                    ; Y - set output bit 3
                 
                mov     IND, #$FF                 ; reset pixel 1

                inc     FSR                       ; point to next pixel

                snb     IND.0                     ; Q - is input bit 0 set          
                setb    Temp.4                    ; Y - set output bit 4 

                snb     IND.1                     ; Q - is input bit 1 set            
                setb    Temp.5                    ; Y - set output bit 5               

                snb     IND.3                     ; Q - is input bit 4 set            
                setb    Temp.6                    ; Y - set output bit 6

                snb     IND.7                     ; Q - is input bit 8 set            
                setb    Temp.7                    ; Y - set output bit 7

                mov     DataPort, Temp            ; place the output byte on the data port

                mov     IND, #$FF                 ; reset pixel 2

                inc     FSR                       ; point to next pixel

                ENDM


;
;OUT8BIT        MACRO                               
;
; 8 bits per pixel, 1 pixel per output, no conversion 
;
;     8 bit pixel in  ->  8 bit out
;     11111111            11111111  minimum signal (below lowest threshold)
;     11111110            11111110
;     11111100            11111100
;     11111000            11111000
;     11110000            11110000
;     11100000            11100000
;     11000000            11000000
;     10000000            10000000
;     00000000            00000000  maximum signal (over highest threshold)
;
OUT8BIT         MACRO   

                mov     DataPort, IND             ; place the output byte on the data port         
                mov     IND, #$FF                 ; reset pixel 1

                inc     FSR                       ; point to next pixel

                ENDM


;
;OUTANALOG      MACRO                               
;
; 8 bits per pixel, 1 pixel per output, no conversion 
;
OUTANALOG       MACRO   

                mov     DataPort, IND             ; place the output byte on the data port         
                clr     IND                       ; reset pixel 1 ($00 for analog mode)

                inc     FSR                       ; point to next pixel

                ENDM


;
; End of output routine macros
;


                org     $10             ; for ROM

;
; Page 0 call routines - placed first in code to ensure they are in lower half of 512 word page as required for calls 
;

;
; Initialize everything - called by Start and Restart
;
Initialize      mov     w, #FIFOWritesInit        ; initialize FIFOWrites
                mov     FIFOWrites, w
                mov     w, #FIFOWritesDir
                mov     !ra, w                    ; !ra is hidden port direction register
                   
                mov     w, #DataPortInit          ; initialize DataPort
                mov     DataPort, w
                mov     w, #DataPortDir
                mov     !rc, w

                mov     w, #ControlPortInit       ; initialize ControlPort 
                mov     ControlPort, w
                mov     w, #ControlPortDir
                mov     !rb, w
                setb    Response                  ; set response pin high

                mov     ReadWriteIndex, #Flags    ; initialize the read-write address to the flag byte

                clr     Flags                     ; setup flag defaults - 1 threshold level, 2 colors
                                                  ;                     - LogEnable    : off
                                                  ;                     - AnalogEnable : off
                                                  ;                     - TestEnable   : off
                                                  ;                     - ErrorFlag    : cleared

                mov     PixelSize, #50            ; set default pixel size to 50 to give 50 * 0.02 uS = 1.00 uS
     
                mov     w, #120
                mov     PixelCount, w             ; set default pixel count for 120 pixels per test cycle 
                mov     LoopCount, w              ; and setup loop counter to clear all 120 pixels 

                mov     FSR, #PixelArray          ; point FSR to first pixel
                mov     w, #$FF                   ; put "clear" pixel value in w

:Next           mov     IND, w                    ; clear this pixel
                inc     FSR                       ; point to next pixel
                setb    FSR.4                     ; might be in next bank, skip first 16 registers 
                decsz   LoopCount                 ; decrement loop counter (pixels remaining to do)
                                                  ; Q - all pixels done
                jmp     :Next                     ; N - do next pixel

;  initialize the DetectXFrom/To values

                bank    DetectArray               ; setup access to detect from/to array

                mov     w, #1
                mov     Detect1From, w            ; set default detect 1 from pixel to 1
                mov     Detect2From, w            ; set default detect 2 from pixel to 1
                mov     Detect3From, w            ; set default detect 3 from pixel to 1
                mov     Detect4From, w            ; set default detect 4 from pixel to 1

                mov     w, #120
                mov     Detect1To, w              ; set default detect 1 to pixel to 120          
                mov     Detect2To, w              ; set default detect 2 to pixel to 120
                mov     Detect3To, w              ; set default detect 3 to pixel to 120
                mov     Detect4To, w              ; set default detect 4 to pixel to 120
                
;  clear data FIFOs

                clrb    FIFOReset                 ; take FIFO reset pin low to indicate a reset
                nop                               ; wait
                nop                               ;   and wait
                nop                               ;      and wait
                setb    FIFOReset                 ; take it back high again
                ret


;
; End of Page 0 call routines
;


;
; Program jumps here on hardware reset
;
Start           call    Initialize                ; do all initializations

; Wait for command from Main Controller

WaitCommand     snb     Command                   ; Q - is Command pin active (low)?
                jmp     WaitCommand               ; N - wait for command

                mov     w, ControlPort            ; Y - get Control Port data         
                and     w, #%00001111             ; the command code is contained in the lower 4 bits
                jmp     pc + w                    ; jump into CommandTable at command code "w" 

CommandTable    jmp     Restart                   ; $00 is restart - reset and initialize
                jmp     ClearFIFOs                ; $01 is clear (empty) the FIFOs
                jmp     SampleCycle               ; $02 is sample a cycle and update peak values in pixel array

                jmp     OutputCycle               ; $03 is output a cycle to FIFOs and clear peak values 
               
		jmp     Detect1                   ; $04 is read max pixel between Detect1From and Detect1To inclusive
                jmp     Detect2                   ; $05 is read max pixel between Detect2From and Detect2To inclusive
                jmp     Detect3                   ; $06 is read max pixel between Detect3From and Detect3To inclusive
                jmp     Detect4                   ; $07 is read max pixel between Detect4From and Detect4To inclusive

                jmp     IndexWrite                ; $08 is setup ReadWriteIndex register address from Main Controller
                jmp     DataWrite                 ; $09 is write data to ReadWriteIndex address
                jmp     DataRead                  ; $0A is read data from ReadWriteIndex address
                jmp     DataWriteAuto             ; $0B is write to ReadWriteIndex address, increment ReadWriteIndex
                jmp     DataReadAuto              ; $0C is read from ReadWriteIndex address, increment ReadWriteIndex

                jmp     @Detect1Back               ; $0D is get the peak pixel backward for detect 1
                jmp     @Detect2Back               ; $0E is get the peak pixel backward for detect 2
                jmp     @Detect3Back               ; $0F is get the peak pixel backward for detect 3


;
; Do a total restart to reset all options, ports, data etc
;
Restart         clrb    Response                  ; signal Main Controller that command has been received
                call    Initialize                ; initialize everything
                jmp     EndCommand                ; end of this command  


;
;  Clear (empty) all FIFOs
;
ClearFIFOs      clrb    Response                  ; signal Main Controller that command has been received
                clrb    FIFOReset                 ; take FIFO reset pin low to clear FIFOs
                nop                               ; wait
                nop                               ;   and wait
                nop                               ;      and wait
                setb    FIFOReset                 ; take it back high again
                jmp     EndCommand                ; end of this command  


;
; Begin a sample cycle, check for test pattern mode, or for threshold level or analog type samples
;
SampleCycle     clrb    Response                  ; signal Main Controller that command has been received
                mov     FSR, #PixelArray          ; point indirect register to start of pixel array
                mov     LoopCount, PixelCount     ; load loop counter with number of pixels to do
                snb     TestEnable                ; Q - is this a run with test pattern?
                jmp     TestPattern               ; Y - go make a test pattern instead of sampling                
                snb     AnalogEnable              ; Q - is this a run with output of 8-bit data for analog display?
                jmp     SampleAnalog              ; Y - sample in analog mode
                jmp     SampleLevels              ; N - sample in threshold level mode


;
; Generate test pattern "signal".
; The analog pattern starts with first pixel set to 0 (lowest signal).  Each consecutive pixel value is increased 
; by 8.  After 32 pixels the pattern is repeated.
; The threshold pattern starts with the first 4 pixels set to $FF (lowest signal).  After every 4th pixel the
; signal level is increased 1 threshold level.  After 36 pixels the pattern is repeated.  
;
TestPattern     snb     AnalogEnable              ; Q - is this a run with output of 8-bit data for analog display?
                jmp     TestAnalog                ; Y - test pattern for analog mode 

                mov     w, #%11111111             ; N - initialize w to %11111111 (lowest threshold signal)

:Next           mov     IND, w                    ; put pattern in pixel array

                dec     LoopCount                 ; decrement loop counter (pixels remaining to do)
                snz                               ; Q - all pixels done
                jmp     EndCommand                ; Y - end of this command

                REPT    3
                inc     FSR                       ; setup for next pixel

                mov     IND, w                    ; put pattern in pixel array

                dec     LoopCount                 ; decrement loop counter (pixels remaining to do)
                snz                               ; Q - all pixels done
                jmp     EndCommand                ; Y - end of this command
                ENDR

                clc                               ; clear carry for shift left
                mov     w, <<IND                  ; shift pattern to left (increase signal by 1 level)
                sc                                ; Q - is carry = 0 i.e. last pixel was %00000000 (max signal)
                mov     w, #%11111111             ; Y - re-initialize w to %11111111 (lowest signal)

                inc     FSR                       ; setup for next pixel
                setb    FSR.4                     ; may be next bank, must skip lower 16 bytes

                jmp     :Next                     ; jump for next 4 pixels

TestAnalog      mov     Temp, #$8                 ; amount to add each pixel
                mov     w, #0                     ; initialize w to 0 (lowest analog signal)

:Next           mov     IND, w                    ; put pattern in pixel array

                dec     LoopCount                 ; decrement loop counter (pixels remaining to do)
                snz                               ; Q - all pixels done
                jmp     EndCommand                ; Y - end of this command

                add     w, Temp                   ; step up next signal level (may "wrap" to zero)

                inc     FSR                       ; setup for next pixel
                setb    FSR.4                     ; may be next bank, must skip lower 16 bytes

                jmp     :Next                     ; jump for next 4 pixels 

                
;
; Sampling process for analog mode - each sample is 8 bit byte representing signal amplitude
;
SampleAnalog    mov     w, PixelSize              ; get pixel size (in instruction clock cycles) 
                mov     Temp, w                   ; move into Temp

                setb    Temp.0                    ; round up Temp to be multiple of 4
                setb    Temp.1                      

                jmp     @AnalogPixel              ; jump to page with analog sample routine 


;
; Sampling process for threshold level mode - each sample is 8 individual threshold levels
;
SampleLevels    mov     w, PixelSize              ; get pixel size (in instruction clock cycles)
                mov     Temp, w                   ; move into temp

                setb    Temp.0                    ; round up Temp to be multiple of 2
 
                jmp     @LevelsPixel              ; jump to page with threshold levels sample routine 


; 
; Find the maximum pixel signal level between DetectXFrom pixel and DetectXTo pixel inclusive where X is the detector
; number from 1 to 4.  The maximum signal is returned to the Main Controller and processed for Alarm detection.
; NEEDS WORK - LATER ADD ANALOG PEAK
;
Detect1         bank    DetectArray               ; setup access to detect from/to array
                mov     w, --Detect1From          ; get DetectXFrom - 1
                mov     w, Detect1To - w          ; calculate total detect pixels (DetectXTo - DetectXFrom + 1)
                mov     LoopCount, w              ;  and save to loop counter
                mov     w, Detect1AlarmLevel      ; get the Detect1AlarmLevel
                mov     AlarmLevel, w             ; save the alarm level for the detection
                mov     w, --Detect1From          ; get DetectXFrom pixel (convert to zero based)
                jmp     Detect                    ; jump to common detect routine

Detect2         bank    DetectArray               ; setup access to detect from/to array
                mov     w, --Detect2From          ; get DetectXFrom - 1
                mov     w, Detect2To - w          ; calculate total detect pixels (DetectXTo - DetectXFrom + 1)
                mov     LoopCount, w              ;  and save to loop counter
                mov     w, Detect2AlarmLevel      ; get the Detect1AlarmLevel
                mov     AlarmLevel, w             ; save the alarm level for the detection
                mov     w, --Detect2From          ; get DetectXFrom pixel (convert to zero based)

                jmp     Detect                    ; jump to common detect routine

Detect3         bank    DetectArray               ; setup access to detect from/to array
                mov     w, --Detect3From          ; get DetectXFrom - 1
                mov     w, Detect3To - w          ; calculate total detect pixels (DetectXTo - DetectXFrom + 1)
                mov     LoopCount, w              ;  and save to loop counter
                mov     w, Detect3AlarmLevel      ; get the Detect1AlarmLevel
                mov     AlarmLevel, w             ; save the alarm level for the detection
                mov     w, --Detect3From          ; get DetectXFrom pixel (convert to zero based)

                jmp     Detect                    ; jump to common detect routine

Detect4         bank    DetectArray               ; setup access to detect from/to array
                mov     w, --Detect4From          ; get DetectXFrom - 1
                mov     w, Detect4To - w          ; calculate total detect pixels (DetectXTo - DetectXFrom + 1)
                mov     LoopCount, w              ;  and save to loop counter
                mov     w, Detect4AlarmLevel      ; get the Detect1AlarmLevel
                mov     AlarmLevel, w             ; save the alarm level for the detection
                mov     w, --Detect4From          ; get DetectXFrom pixel (convert to zero based)

Detect
                mov     FSR, w                    ; move DetectXFrom pixel into FSR
                and     w, #%11110000             ; keep top 4 bits to adjust for pixel array bank select
                add     FSR, w                    ; point FSR into correct bank (block of 32 bytes)
                setb    FSR.4                     ; select top half of bank - FSR now points to specified pixel 
                mov     w, FSR
                mov     temp, w                   ; save the first pixel loc in temp
                mov     w, IND
                mov     temp1, w                   ; save the first pixel value in temp1

NextPixel
                csb     IND, temp1                    ; see if the current pixle less than pre "max"
                jmp    NotHigher
                mov     w, FSR                     ; this pixel is higher
                mov     temp, w                   ; save the this pixel loc in temp
                mov     w, IND
                mov     temp1, w                   ; save this pixel value in temp1

NotHigher
                inc     FSR                       ; point to next pixel
                setb    FSR.4                     ; might be in next bank, skip first 16 registers
                decsz   LoopCount                 ; decrement loop counter (pixels remaining to do)
                                                  ; Q - all pixels done
                jmp     NextPixel                     ; N - do next pixel
                and     temp1, AlarmLevel           ; Q - is the peak value below alarm level
                jnz     NoPeakFound                 ; N - no peak found, output 255
                mov     w, temp
                and     w, #%11100000             ; get the bank number
                mov     Temp1, w                   ; save into Temp
                clc
                rr      Temp1
                mov     w, temp                    ; get temp again
                and     w, #%00001111             ; get the loc in bank
                add     w, Temp1                   ; add bank #, get the final value in w
                jmp     SendDataToMC
NoPeakFound     mov     w, #%11111111             ; send 256 to data port
SendDataToMC    mov     DataPort, w               ; put the requested data on the data port
                mov     !rc, #%00000000           ; set data port to output
                clrb    Response                  ; signal Main Controller that data is available
:Wait           sb      Command                   ; Q - has Main Controller read the requested data
                jmp     :Wait                     ; N - wait for it
                mov     !rc, #%11111111           ; reset data port to input
                jmp     EndCommand                ; end of this command   


;
; Begin an output cycle, check for threshold level or analog type samples and do output to FIFOs
;
OutputCycle     clrb    Response                  ; signal Main Controller that command has been received
                mov     !rc, #%00000000           ; set data port to output
                mov     FSR, #PixelArray          ; point to first pixel
                snb     AnalogEnable              ; Q - is this a run with output of 8-bit byte for analog display?
                jmp     OutputAnalog              ; Y - output pixels as analog
                jmp     @OutputLevels             ; output levels data routine is on another page


;
; Output in analog mode - each pixel is 8 bit binary peak signal strength value
;
OutputAnalog    mov     w, #1                     ; 1 pixels per 16 bit output, so add 1 to round up any remainder
                add     w, PixelCount             ;      i.e. number of output loops = (pixel count + 1)/2
                mov     LoopCount, w                    

                rr      LoopCount                 ; divide by 2 (pixels per 16 bit output )

                and     LoopCount, #%01111111     ; clean up 1 top bits after shifts

                mov     w, --LoopCount            ; Q - does LoopCount = 1 
                snz
                clrb    FIFOSync                  ; Y - only 1 32 bit output, so always generate sync pulse

:Next           mov     w, #2                     ; Q - does LoopCount = 2
                mov     w, LoopCount - w 
                snz
                clrb    FIFOSync                  ; Y - 2nd last 32 bit output, so generate sync pulse
                 
                clrb    FIFO1Write                ; take FIFO 1 (LSB) write low        
                OUTANALOG
                setb    FIFO1Write                ; complete write strobe


                clrb    FIFO2Write                ; take FIFO 2 (MSB) write low
                OUTANALOG
                setb    FSR.4                     ; might be in next bank, skip first 16 registers
                setb    FIFO2Write                ; complete write strobe

                setb    FIFOSync                  ; complete sync pulse (if any)

                decsz   LoopCount                 ; Q - any more 16 bit outputs to do
                jmp     :Next                     ; Y - continue


                clrb    FIFO1Write                ;take FIFO 1 (LSB) write low
                mov     DataPort, #$FD            ; put $FD on the port to tell the end of a cycle
                nop
                nop
                setb    FIFO1Write                ; complete write strobe

                clrb    FIFO2Write                ;take FIFO 2  write low
                mov     DataPort, #$FD            ; put $FD on the port to tell the end of a cycle
                nop
                nop

                mov     !rc, #%11111111           ; N - reset data port to input
                jmp     EndCommand                ; end of this command  


;
; Main Controller writes Index address into ReadWriteIndex register
;
IndexWrite      mov     ReadWriteIndex, DataPort  ; get data from data port and write into ReadWriteIndex register
                clrb    Response                  ; signal Main Controller that command and data have been received
                jmp     EndCommand                ; end of this command  


;
; Main Controller writes data to the register selected by the ReadWriteIndex register
;
DataWrite       mov     FSR, ReadWriteIndex       ; put ReadWriteIndex in FSR (indirect register pointer)
                mov     IND, DataPort             ; get data from data port and write into indirect (FSR location)
                clrb    Response                  ; signal Main Controller that command and data have been received
                jmp     EndCommand                ; end of this command  


;
; Main Controller reads data from the register selected by the ReadWriteIndex register
;
DataRead        mov     FSR, ReadWriteIndex       ; put ReadWriteIndex in FSR (indirect register pointer)
                mov     DataPort, IND             ; put the requested data on the data port
                mov     !rc, #%00000000           ; set data port to output
                clrb    Response                  ; signal Main Controller that data is available
:Wait           sb      Command                   ; Q - has Main Controller read the requested data
                jmp     :Wait                     ; N - wait for it
                mov     !rc, #%11111111           ; reset data port to input
                jmp     EndCommand                ; end of this command   


;
; Main Controller writes to the register selected by ReadWriteIndex, and then ReadWriteIndex is incremented 
;
DataWriteAuto   mov     FSR, ReadWriteIndex       ; put ReadWriteIndex in FSR (indirect register pointer)
                mov     IND, DataPort             ; get data from data port and write into indirect (FSR location)
                clrb    Response                  ; signal Main Controller that command and data have been received
                inc     ReadWriteIndex            ; increment the read-write index address
                jmp     EndCommand                ; end of this command  


;
; Main Controller reads from the register selected by ReadWriteIndex, and then ReadWriteIndex is incremented 
;
DataReadAuto    mov     FSR, ReadWriteIndex       ; put ReadWriteIndex in FSR (indirect register pointer)
                mov     DataPort, IND             ; put the requested data on the data port
                mov     !rc, #%00000000           ; set data port to output
                clrb    Response                  ; signal Main Controller that data is available
                inc     ReadWriteIndex            ; increment the read-write index address
:Wait           sb      Command                   ; Q - has Main Controller read the requested data
                jmp     :Wait                     ; N - wait for it
                mov     !rc, #%11111111           ; reset data port to input
                jmp     EndCommand                ; end of this command   


;
; Unrecognized command - just acknowledge and do EndCommand             
;
BadCommand      clrb    Response                  ; tell the Main Controller that the message was received
                setb    ErrorFlag                 ; indicate that an error occurred    


;
; Common code executed at the end of all commands
;
EndCommand      sb      Command                   ; Q - is Command pin high?
                jmp     EndCommand                ; N - wait for Main Controller to acknowledge
                setb    Response                  ; tell Main Controller that last task is completed
                jmp     WaitCommand               ; wait for next command


;
; The remainder of the output routines that "start" on the next page fit in here
;
NextLog         mov     w, #2                     ; Q - does LoopCount = 2
                mov     w, LoopCount - w 
                snz
                clrb    FIFOSync                  ; Y - 2nd last 32 bit output, so generate sync pulse
                 
                clrb    FIFO1Write                ; take FIFO 1 (LSB) write low        
                OUT4BITLOG
                setb    FIFO1Write                ; complete write strobe

                clrb    FIFO2Write                ; take FIFO 2 write low        
                OUT4BITLOG
                setb    FIFO2Write                ; complete write strobe

                clrb    FIFO3Write                ; take FIFO 3 write low        
                OUT4BITLOG
                setb    FIFO3Write                ; complete write strobe

                clrb    FIFO4Write                ; take FIFO 4 (MSB) write low        
                OUT4BITLOG
                setb    FSR.4                     ; might be in next bank, skip first 16 registers 
                setb    FIFO4Write                ; complete write strobe

                setb    FIFOSync                  ; complete sync pulse (if any)

                decsz   LoopCount                 ; Q - any more 32 bit outputs to do
                jmp     NextLog                   ; Y - continue

                mov     !rc, #%11111111           ; N - reset data port to input
                jmp     EndCommand                ; end of this command  


OutputAs8Bit    mov     w, #3                     ; 4 pixels per 32 bit output, so add 3 to round up any remainder
                add     w, PixelCount             ;      i.e. number of output loops = (pixel count + 3)/4
                mov     LoopCount, w                    

                rr      LoopCount                 ; divide by 4 (pixels per 32 bit output )
                rr      LoopCount                 

                and     LoopCount, #%00111111     ; clean up 2 top bits after shifts

                mov     w, --LoopCount            ; Q - does LoopCount = 1 
                snz
                clrb    FIFOSync                  ; Y - only 1 32 bit output, so always generate sync pulse

:Next           mov     w, #2                     ; Q - does LoopCount = 2
                mov     w, LoopCount - w 
                snz
                clrb    FIFOSync                  ; Y - 2nd last 32 bit output, so generate sync pulse
                 
                clrb    FIFO1Write                ; take FIFO 1 (LSB) write low        
                OUT8BIT
                setb    FIFO1Write                ; complete write strobe

                clrb    FIFO2Write                ; take FIFO 2 write low        
                OUT8BIT
                setb    FIFO2Write                ; complete write strobe

                clrb    FIFO3Write                ; take FIFO 3 write low        
                OUT8BIT
                setb    FIFO3Write                ; complete write strobe

                clrb    FIFO4Write                ; take FIFO 4 (MSB) write low        
                OUT8BIT
                setb    FSR.4                     ; might be in next bank, skip first 16 registers 
                setb    FIFO4Write                ; complete write strobe

                setb    FIFOSync                  ; complete sync pulse (if any)

                decsz   LoopCount                 ; Q - any more 32 bit outputs to do
                jmp     :Next                     ; Y - continue

                mov     !rc, #%11111111           ; N - reset data port to input
                jmp     EndCommand                ; end of this command  


                org     $200                      ; set to beginning of new ROM page 
;
; --- page boundary ---------------------------------------------------------------------------------------------
;

;
; Output threshold level encoded pixels to FIFOs
;
OutputLevels    mov     w, Flags                  ; get Flags into w
                and     w, #%00000011             ; threshold levels in bottom 2 bits
                jmp     pc + w                    ; jump into threshold levels table

ThresholdTable  jmp     OutputAs1Bit              ; %00 is 1 bit, 2 color
                jmp     OutputAs2Bit              ; %01 is 2 bit, 3 color
                jmp     OutputAs4Bit              ; %10 is 4 bit, 5 color
                jmp     @OutputAs8Bit             ; %11 is 8 bit, 9 color (in first page)

OutputAs1Bit    mov     w, #31                    ; 32 pixels per 32 bit output, so add 31 to round up any remainder
                add     w, PixelCount             ;      i.e. number of output loops = (pixel count + 31)/32
                mov     LoopCount, w                    

                rr      LoopCount                 ; divide by 32 (pixels per 32 bit output )
                rr      LoopCount                 
                rr      LoopCount                 
                rr      LoopCount                 
                rr      LoopCount                 

                and     LoopCount, #%00000111     ; clean up 5 top bits after shifts

                mov     w, --LoopCount            ; Q - does LoopCount = 1 
                snz
                clrb    FIFOSync                  ; Y - only 1 32 bit output, so always generate sync pulse

:Next           mov     w, #2                     ; Q - does LoopCount = 2
                mov     w, LoopCount - w 
                snz
                clrb    FIFOSync                  ; Y - 2nd last 32 bit output, so generate sync pulse
                 
                clrb    FIFO1Write                ; take FIFO 1 (LSB) write low        
                OUT1BIT
                setb    FIFO1Write                ; complete write strobe

                clrb    FIFO2Write                ; take FIFO 2 write low        
                OUT1BIT
                setb    FSR.4                     ; should be in next bank, skip first 16 registers 
                setb    FIFO2Write                ; complete write strobe

                clrb    FIFO3Write                ; take FIFO 3 write low        
                OUT1BIT
                setb    FIFO3Write                ; complete write strobe

                clrb    FIFO4Write                ; take FIFO 4 (MSB) write low        
                OUT1BIT
                setb    FSR.4                     ; should be in next bank, skip first 16 registers 
                setb    FIFO4Write                ; complete write strobe

                setb    FIFOSync                  ; complete sync pulse (if any)

                decsz   LoopCount                 ; Q - any more 32 bit outputs to do
                jmp     :Next                     ; Y - continue

                mov     !rc, #%11111111           ; N - reset data port to input
                jmp     @EndCommand               ; end of this command  


OutputAs2Bit    mov     w, #15                    ; 16 pixels per 32 bit output, so add 15 to round up any remainder
                add     w, PixelCount             ;      i.e. number of output loops = (pixel count + 15)/16
                mov     LoopCount, w                    

                rr      LoopCount                 ; divide by 16 (pixels per 32 bit output )
                rr      LoopCount                 
                rr      LoopCount                 
                rr      LoopCount                 

                and     LoopCount, #%00001111     ; clean up 4 top bits after shifts

                mov     w, --LoopCount            ; Q - does LoopCount = 1 
                snz
                clrb    FIFOSync                  ; Y - only 1 32 bit output, so always generate sync pulse

:Next           mov     w, #2                     ; Q - does LoopCount = 2
                mov     w, LoopCount - w 
                snz
                clrb    FIFOSync                  ; Y - 2nd last 32 bit output, so generate sync pulse
                 
                clrb    FIFO1Write                ; take FIFO 1 (LSB) write low        
                OUT2BIT
                setb    FIFO1Write                ; complete write strobe

                clrb    FIFO2Write                ; take FIFO 2 write low        
                OUT2BIT
                setb    FIFO2Write                ; complete write strobe

                clrb    FIFO3Write                ; take FIFO 3 write low        
                OUT2BIT
                setb    FIFO3Write                ; complete write strobe

                clrb    FIFO4Write                ; take FIFO 4 (MSB) write low        
                OUT2BIT
                setb    FSR.4                     ; should be in next bank, skip first 16 registers 
                setb    FIFO4Write                ; complete write strobe

                setb    FIFOSync                  ; complete sync pulse (if any)

                decsz   LoopCount                 ; Q - any more 32 bit outputs to do
                jmp     :Next                     ; Y - continue

                mov     !rc, #%11111111           ; N - reset data port to input
                jmp     @EndCommand               ; end of this command  


OutputAs4Bit    mov     w, #3                     ; 4 pixels per 16 bit output, so add 3 to round up any remainder
                add     w, PixelCount             ;      i.e. number of output loops = (pixel count + 3)/4
                mov     LoopCount, w                    

                rr      LoopCount                 ; divide by 4 (pixels per 16 bit output )
                rr      LoopCount                 

                and     LoopCount, #%00011111     ; clean up 3 top bits after shifts

                mov     w, --LoopCount            ; Q - does LoopCount = 1 
                snz
                clrb    FIFOSync                  ; Y - only 1 32 bit output, so always generate sync pulse

                sb      LogEnable                 ; Q - is log mode enabled
                jmp     NextLin                   ; N - do linear 4 bit output
                jmp     @NextLog                  ; Y - do logarithmic 4 bit output (in first page)

NextLin         mov     w, #2                     ; Q - does LoopCount = 2
                mov     w, LoopCount - w 
                snz
                clrb    FIFOSync                  ; Y - 2nd last 32 bit output, so generate sync pulse
                 
                clrb    FIFO1Write                ; take FIFO 1 (LSB) write low
                OUT4BITLIN
                setb    FIFO1Write                ; complete write strobe

                clrb    FIFO2Write                ; take FIFO 2 write low        
                OUT4BITLIN
                setb    FIFO2Write                ; complete write strobe

                setb    FIFOSync                  ; complete sync pulse (if any)

                decsz   LoopCount                 ; Q - any more 32 bit outputs to do
                jmp     NextLin                   ; Y - continue

                clrb    FIFO1Write                ;take FIFO 1 (LSB) write low
                mov     DataPort, #$FD            ; put $FD on the port to tell the end of a cycle
                nop
                nop
                setb    FIFO1Write                ; complete write strobe

                clrb    FIFO2Write                ;take FIFO 2  write low
                mov     DataPort, #$FD            ; put $FD on the port to tell the end of a cycle
                nop
                nop
                setb    FIFO2Write                ; complete write strobe

                mov     !rc, #%11111111           ; N - reset data port to input

                jmp     @EndCommand               ; end of this command  


                org     $400                      ; set to beginning of new ROM page
;
; --- page boundary ---------------------------------------------------------------------------------------------
;

;
; Sampling process for threshold level mode - each sample is 8 individual threshold levels
; This routine is put into new page of ROM to allow for jmp w instruction
;
; Sampling is done using a 123 pairs of instructions that get a sample from the data port and 
; "or" it into the current position in the pixel array to find the peak value.  Since we use 
; active low logic, this is actually an "and" operation.  The format of the threshold level data
; that is sampled allows peak detection in 2 instructions to achieve a suitably high sampling rate.
; 
; The number of samples per pixel is controlled by jumping into the sampling sequence at the 
; correct entry point (must be a multiple of 2) in the lower half of the page.
;
; Each complete sample instruction sequence takes: 2 * 0.020 uS = 0.040 uS (at 50 MHz).
; An overhead of 9 instructions per pixel takes: 9 * 0.020 uS = 0.18 uS
; The actual number of instruction cycles used = 2 * ((requested cycle count - 8) / 2) + 9
; The minimum requested cycle count is 10, giving 1 actual sample per pixel, taking 0.26 uS
; The maximum requested cycle count is 255, giving 123 actual samples per pixel, taking 5.10 uS
;
                REPT    123      
                mov     w, DataPort       ;1      ; fetch next sample from port
                and     IND, w            ;1      ; AND this data with current pixel value to detect peak
                ENDR

                inc     FSR               ;1      ; set indirect register to next pixel
                setb    FSR.4             ;1      ; might be in next bank, skip first 16 registers
                dec     LoopCount         ;1      ; decrement loop counter (pixels remaining to do)
                snz                       ;2      ; check if all pixels done 
                jmp     LevelsEnd                 ; short (1 instruction) jump to allow for skip 

LevelsPixel     mov     w, /Temp          ;1      ; get the sample routine entry point into w 
                jmp     w                 ;3      ; jump to entry point

LevelsEnd       jmp     @EndCommand               ; end of this command   
                              

Detect1Back     bank    DetectArray               ; setup access to detect from/to array
                mov     w, --Detect1From          ; get DetectXFrom - 1
                mov     w, Detect1To - w          ; calculate total detect pixels (DetectXTo - DetectXFrom + 1)
                mov     LoopCount, w              ;  and save to loop counter
                mov     w, Detect1AlarmLevel      ; get the Detect1AlarmLevel
                mov     AlarmLevel, w             ; save the alarm level for the detection
                mov     w, --Detect1To          ; get DetectXFrom pixel (convert to zero based)
                jmp     DetectBack                    ; jump to common detect routine

Detect2Back     bank    DetectArray               ; setup access to detect from/to array
                mov     w, --Detect2From          ; get DetectXFrom - 1
                mov     w, Detect2To - w          ; calculate total detect pixels (DetectXTo - DetectXFrom + 1)
                mov     LoopCount, w              ;  and save to loop counter
                mov     w, Detect2AlarmLevel      ; get the Detect1AlarmLevel
                mov     AlarmLevel, w             ; save the alarm level for the detection
                mov     w, --Detect2To          ; get DetectXFrom pixel (convert to zero based)

                jmp     DetectBack                    ; jump to common detect routine

Detect3Back     bank    DetectArray               ; setup access to detect from/to array
                mov     w, --Detect3From          ; get DetectXFrom - 1
                mov     w, Detect3To - w          ; calculate total detect pixels (DetectXTo - DetectXFrom + 1)
                mov     LoopCount, w              ;  and save to loop counter
                mov     w, Detect3AlarmLevel      ; get the Detect1AlarmLevel
                mov     AlarmLevel, w             ; save the alarm level for the detection
                mov     w, --Detect3To          ; get DetectXFrom pixel (convert to zero based)

                jmp     DetectBack                    ; jump to common detect routine

Detect4Back     bank    DetectArray               ; setup access to detect from/to array
                mov     w, --Detect4From          ; get DetectXFrom - 1
                mov     w, Detect4To - w          ; calculate total detect pixels (DetectXTo - DetectXFrom + 1)
                mov     LoopCount, w              ;  and save to loop counter
                mov     w, Detect4AlarmLevel      ; get the Detect1AlarmLevel
                mov     AlarmLevel, w             ; save the alarm level for the detection
                mov     w, --Detect4To          ; get DetectXFrom pixel (convert to zero based)

DetectBack
                mov     FSR, w                    ; move DetectXFrom pixel into FSR
                and     w, #%11110000             ; keep top 4 bits to adjust for pixel array bank select
                add     FSR, w                    ; point FSR into correct bank (block of 32 bytes)
                setb    FSR.4                     ; select top half of bank - FSR now points to specified pixel 
                mov     w, FSR
                mov     temp, w                   ; save the first pixel loc in temp
                mov     w, IND
                mov     temp1, w                   ; save the first pixel value in temp1

NextBack
                csb     IND, temp1                    ; see if the current pixle less than pre "max"
                jmp    NotHigherBack
                mov     w, FSR                     ; this pixel is higher
                mov     temp, w                   ; save the this pixel loc in temp
                mov     w, IND
                mov     temp1, w                   ; save this pixel value in temp1
NotHigherBack
                dec     FSR                       ; point to next pixel
                jb      FSR.4, NoBankChange       
                sub     FSR, #16
NoBankChange
                decsz   LoopCount                 ; decrement loop counter (pixels remaining to do)
                                                  ; Q - all pixels done
                jmp     NextBack                     ; N - do next pixel
                and     temp1, AlarmLevel           ; Q - is the peak value below alarm level
                jnz     NoPeakFoundBack                 ; N - no peak found, output 255
                mov     w, temp
                and     w, #%11100000             ; get the bank number
                mov     Temp1, w                   ; save into Temp
                clc
                rr      Temp1
                mov     w, temp                    ; get temp again
                and     w, #%00001111             ; get the loc in bank
                add     w, Temp1                   ; add bank #, get the final value in w
                jmp     SendDataToMCBack
NoPeakFoundBack     mov     w, #%11111111             ; send 256 to data port
SendDataToMCBack    mov     DataPort, w               ; put the requested data on the data port
                mov     !rc, #%00000000           ; set data port to output
                clrb    Response                  ; signal Main Controller that data is available
:Wait           sb      Command                   ; Q - has Main Controller read the requested data
                jmp     :Wait                     ; N - wait for it
                mov     !rc, #%11111111           ; reset data port to input
                jmp     @EndCommand                ; end of this command   


                org     $600                      ; set to beginning of new ROM page
;
; --- page boundary ---------------------------------------------------------------------------------------------
;

;
; Sampling process for analog mode - each sample is 8 bit byte representing signal amplitude
; This routine is put into new page of ROM to allow for jmp w instruction
;
; Sampling is done using a 61 sets of 4 instructions that get a sample from the data port and 
; compare to the current peak value in the pixel array.  If the new value is greater the pixel is 
; updated with the new peak value. The analog peak detect routine is less efficient than the threshold 
; peak detection and is made available for diagnostic purposes only.
; 
; The number of samples per pixel is controlled by jumping into the sampling sequence at the 
; correct entry point (must be a multiple of 4) in the lower half of the page.
;
; Each complete sample instruction sequence takes: 4 * 0.020 uS = 0.080 uS (at 50 MHz)
; An overhead of 9 instructions per pixel takes: 9 * 0.020 uS = 0.18 uS
; The actual number of instruction cycles used = 4 * ((requested cycle count - 8) / 4) + 9
; The minimum requested cycle count is 12, giving 1 actual sample per pixel, taking 0.26 uS
; The maximum requested cycle count is 255, giving 61 actual samples per pixel, taking 5.06 uS
;
                REPT    61                        
                mov     w, DataPort       ;1      ; get new sample from data port
                mov     w, IND - w        ;1      ; do test subtraction
                sc                        ;1,2    ; Q - lower than previous data? Y - skip, keep previous value
                sub     IND, w            ;1,0    ; N - subtraction was negative, "add" back difference
                ENDR
 
                inc     FSR               ;1      ; set indirect register to next pixel
                setb    FSR.4             ;1      ; might be in next bank, skip first 16 registers
                dec     LoopCount         ;1      ; decrement loop counter (pixels remaining to do)
                snz                       ;2      ; check if all pixels done 
                jmp     AnalogEnd                 ; short (1 instruction) jump to allow for skip 

AnalogPixel     mov     w, /Temp          ;1      ; get the sample routine entry point into w 
                jmp     w                 ;3      ; jump to entry point

AnalogEnd       jmp     @EndCommand               ; end of this command   


                end                               ; end of program 

