       COMMENT *

This file is used to generate DSP code for the a Gen III = ARC22
	timing board to operate a 256 x 256 pixel PICNIC IR FPA 
   *

   PAGE    132     ; Printronix page width - 132 columns

; Include the boot and header files so addressing is easy
        INCLUDE "timhdr.asm"
	INCLUDE	"timboot.asm"

	ORG	P:,P:

CC	EQU	IRREV4+TIMREV5+CONT_RD


; Put number of words of application in P: for loading application from EEPROM
	DC	TIMBOOT_X_MEMORY-@LCV(L)-1

;  Reset entire array and don't transmit any pixel data
RESET_ARRAY
	MOVE	#<READ_ON,R0		; Turn Read ON 
	JSR	<CLOCK
	MOVE	#<INIT_FRAME,R0
	JSR	<CLOCK

	DO	#64,END_FRAME
	MOVE	#<SHIFT_RESET_ODD_ROW,R0
	JSR	<CLOCK
	DO	#64,L_ODD
	MOVE	#<SHIFT_PIXELS,R0
	JSR	<CLOCK
	NOP
L_ODD
	MOVE	#<SHIFT_RESET_EVEN_ROW,R0
	JSR	<CLOCK
	DO	#64,L_EVEN
	MOVE	#<SHIFT_PIXELS,R0
	JSR	<CLOCK
	NOP
L_EVEN	
	JSR	(R5)		; Check for incoming command if in
	JCC	<NOT_COMMAND	;  continuous reset mode
	ENDDO			; If there is an incoming command then
	JMP	<RST_END	;  exit continuous mode and return
NOT_COMMAND
	NOP
END_FRAME NOP
	MOVE	#<READ_OFF,R0	; Turn Read OFF
	JSR	<CLOCK
	RTS			; Return from subroutine call

RST_END	MOVE	#<READ_OFF,R0	; Turn Read OFF
	JSR	<CLOCK
	BSET	#0,SR		; Set carry bit to indicate command was received
	NOP
	RTS

; Dummy subroutine to not call receiver checking routine
NO_CHK	BCLR	#0,SR		; Clear status register clear bit
	NOP
	RTS

; Continuously reset array, checking for host commands every line
CONT_RST
	MOVE	#<COM_BUF,R3
	MOVE	#<GET_RCV,R5
	JSR	<RESET_ARRAY
	JCS	<PRC_RCV	; Process the command if its there
	JMP	<CONT_RST

;  ***********************   ARRAY READOUT   ********************
RD_ARRAY
	JSR	<PCI_READ_IMAGE		; Wake up the PCI interface board
	JSET	#TST_IMG,X:STATUS,SYNTHETIC_IMAGE

	JCLR	#ST_RD,X:<STATUS,C_RD
	MOVE	#<READ_ON,R0		; Turn the PICNIC 'READ' line ON
	JSR	<CLOCK
	DO	#600,DLY_ON		; Wait 5 msec for the signal to settle
	JSR	<PAL_DLY
	NOP
DLY_ON

; Compute NXLOOP and NYLOOP including the number of readout channels
C_RD	MOVE	Y:<OS,A
	CMP	#'ALL',A
	JNE	<ONE_RD
	MOVE	Y:<NROWS,A	; Read from all four corners
	LSR	A
	JCLR	#ST_CDS,X:<STATUS,NO_CDS1
	LSR	A		; If CDS read only half of NROWS at a time
	NOP
NO_CDS1	MOVE	A1,Y:<NYLOOP
	MOVE	Y:<NCOLS,A
	LSR	A
	NOP
	MOVE	A1,Y:<NXLOOP
	JMP	<RDFRAME

; Dimensions for reading from just one quadrant
ONE_RD	MOVE	Y:<NROWS,A
	JCLR	#ST_CDS,X:<STATUS,NO_CDS2
	LSR	A		; If CDS read only half of NROWS at a time
	NOP
NO_CDS2	MOVE	A1,Y:<NYLOOP
	MOVE	Y:<NCOLS,X0
	MOVE	X0,Y:<NXLOOP

; Initialize the reading of the frame
RDFRAME	MOVE    #<INIT_FRAME,R0
	JSR     <CLOCK

; Skip over Y:ROW_OFFSET rows, keeping track of even/odd effects
	BSET	#0,Y:<ODD_ROW
	MOVE	Y:<ROW_OFFSET,A
	TST	A
	JLE	<WHOLE_FRAME
ROWSKIP	MOVE	#<SHIFT_ODD_ROW,R0
	JSR	<CLOCK
	BCHG	#0,Y:<ODD_ROW
	SUB	#1,A
	TST	A
	JEQ	<READOUT
	MOVE	#<SHIFT_EVEN_ROW,R0
	JSR	<CLOCK
	BCHG	#0,Y:<ODD_ROW
	SUB	#1,A
	TST	A
	JEQ	<READOUT
	JMP	<ROWSKIP

WHOLE_FRAME
	MOVE	#<SHIFT_ODD_ROW,R0
	JSR	<CLOCK

READOUT	MOVE	Y:<NYLOOP,A
NXT_ROW	BCHG	#0,Y:<ODD_ROW

	BCLR	#0,Y:<ODD_COL
	MOVE	Y:<COL_OFFSET,B
	TST	B
	JLE	<WHOLE_ROW
COLSKIP	JCLR	#SSFHF,X:HDR,*		; Only write to FIFO if < half full
	MOVEP	#(CLK3+DELAY+H_PIXEL),Y:WRSS
	BCHG	#0,Y:<ODD_COL
	SUB	#1,B
	TST	B
	JLE	<RD_PXLS
	MOVEP	#(CLK3+DELAY+L_PIXEL),Y:WRSS
	BCHG	#0,Y:<ODD_COL
	SUB	#1,B
	TST	B
	JLE	<RD_PXLS
	JMP	<COLSKIP

RD_PXLS	MOVE	Y:<NXLOOP,B
RD_LINE	JSET	#0,Y:<ODD_COL,O_COL
	JCLR	#SSFHF,X:HDR,*
	MOVEP	#(CLK3+DELAY+H_PIXEL),Y:WRSS
	JMP	<RD_PXL
O_COL	MOVEP	#(CLK3+DELAY+L_PIXEL),Y:WRSS

RD_PXL	BCHG	#0,Y:<ODD_COL
	DO	Y:<NUM_RDS,RD_PXL0
	MOVE	#<READ_PIXEL,R0
	JSR	<CLOCK
	SUB	#1,B
RD_PXL0	NOP
	TST	B
	JGT	<RD_LINE
	JMP	<END_LINE

; Read out the entire row
WHOLE_ROW
	DO	Y:<NXLOOP,RD_PIX0
	MOVE	#<SHIFT_READ_PIXELS,R0
	JSR	<CLOCK
	NOP
RD_PIX0

END_LINE
	SUB	#1,A			; A = ROW number down counter
	TST	A
	JEQ	<READ_END
	JSET	#0,Y:<ODD_ROW,ODD

; Shift either and odd or an even row number depending on where we are
EVEN	MOVE	#<SHIFT_EVEN_ROW,R0
	JSR	<CLOCK
	JMP	<NXT_ROW
ODD	MOVE	#<SHIFT_ODD_ROW,R0
	JSR	<CLOCK
	JMP	<NXT_ROW

READ_END
	MOVE	#<SXMIT_EIGHT_PIXELS,R0
	JSR	<CLOCK
	NOP

	JCLR	#ST_RD,X:<STATUS,NO_RD
	MOVE	#<READ_OFF,R0		; Turn the PICNIC Read line OFF
	JSR	<CLOCK
NO_RD

; We're all done with the readout, so return
	RTS

; ******  Minclude many routines not directly needed for readout  *******
	INCLUDE "timIRmisc.asm"

TIMBOOT_X_MEMORY	EQU	@LCV(L)

; Define the address in P: space where the table of constants begins

	IF	@SCP("DOWNLOAD","HOST")
	ORG     X:END_COMMAND_TABLE,X:END_COMMAND_TABLE
	ENDIF

	IF	@SCP("DOWNLOAD","ROM")
	ORG     X:END_COMMAND_TABLE,P:
	ENDIF

	DC	'SEX',START_EXPOSURE
	DC      'AEX',ABORT_EXPOSURE
	DC      'PON',POWER_ON
	DC      'POF',POWER_OFF	
	DC	'SET',SET_EXPOSURE_TIME
	DC	'RET',READ_EXPOSURE_TIME
	DC	'SBN',SET_BIAS_NUMBER
	DC	'SMX',SET_MUX
	DC	'SBV',SET_BIASES   
	DC	'RCC',READ_CONTROLLER_CONFIGURATION 
	DC      'DON',START

; Continuous readout commands
	DC	'SNC',SET_NUMBER_OF_COADDS
	DC	'FPB',SET_NUMBER_OF_FRAMES_PER_BUFFER

; Custom commands
	DC	'STM',SET_TRIGGER_MODE
	DC	'SOS',SELECT_OUTPUT_SOURCE
	DC      'SNR',SET_NUM_READS
	DC      'SFR',SET_NUMBER_OF_FRAMES_PER_RESET
	DC	'SSA',SPECIFY_SUB_ARRAY
	DC	'CDS',SET_CDS_MODE
	DC	'SRD',SET_READ_MODE	; READ signal on PICNIC on and off?

END_APPLICATON_COMMAND_TABLE	EQU	@LCV(L)

	IF	@SCP("DOWNLOAD","HOST")
NUM_COM			EQU	(@LCV(R)-COM_TBL_R)/2	; Number of boot + 
							;  application commands
EXPOSING		EQU	CHK_TIM			; Address if exposing
CONTINUE_READING	EQU	CONTINUE_READ 		; Address if reading out
	ENDIF

	IF	@SCP("DOWNLOAD","ROM")
	ORG     Y:0,P:
	ENDIF

; Now let's go for the timing waveform tables
	IF	@SCP("DOWNLOAD","HOST")
        ORG     Y:0,Y:0
	ENDIF

GAIN	DC	END_APPLICATON_Y_MEMORY-@LCV(L)-1

NCOLS	DC	256		; Number of columns
NROWS	DC	256		; Number of rows
COL_OFFSET DC	0		; Number of columns to skip in subarray mode 
ROW_OFFSET DC	0		; Number of rows to skip in subarray mode
NUM_RDS	DC	1		; Number of reads per reset
N_FPR	DC	1		; Number of frames per reset
I_FPR	DC	1		; Counter for frames per reset
RST_DLY	DC	50		; Delay after array reset for settling
PWR_DLY	DC	100		; Delay in millisec for power to turn on
VDD_DLY	DC	300		; Delay in millise for VDD to settle   
CONFIG	DC	CC		; Controller configuration
TST_DAT	DC	0		; Synthetic image test datum
ODD_ROW	DC	0		; Odd or even row number
ODD_COL	DC	0		; Odd or even column number
OS	DC	'ALL'		; Number of readouts
NXLOOP	DC	0		; Loop index for the columns
NYLOOP	DC	0		; Loop index for the rows

; Continuous readout mode constants
NCOADDS	DC	1		; Number of coadditions per exposure
ICOADD	DC	0		; Counter of number of coadds done so far
IBUFFER	DC	0		; Buffer pointer - counts from 0 to N_FPB
N_FPB	DC	1		; Number of frames in each image buffer

; Include the waveform table for the PICNIC focal plane array
	INCLUDE "WAVEFORM_FILE" ; Readout and clocking waveform file

END_APPLICATON_Y_MEMORY	EQU	@LCV(L)

; End of program
	END
