This is the text of the SAM microcode that is used in the 
CIRSI controller, version HAW411.asm, which is a two-cycle
SAM and was used in the May/June 1998 LPO Observing Runs
*************************************************************
Updated Craig D Mackay
Institute of Astronomy

4.00: copy as per version 3.19 from mgb
4.01: Shutter implemented, if bits are 0,0,1 (shutter code =4 in 
pixcel.ini), then Uniblitz is operated, else delay of 
shutter without actually opening it occurs.
4.02: implement region read-out.
4.04: As 4.02 but without trailing pixel/row skipping
4.05: As 4.04 but with X5 slow down in pixel reads.

20/5/97
4.06: As 4.05 but with all vfg pulses etc removed
NOTE: Pixcel.ini also modified, for 0,0 in PDCI section 

22/5/97
4.07: Attempted to install new modes, but unsuccessfully

8/6/97
4.08: Installed Shutter control mode selection:
type 2 = single line multiple repeat
type 4 = normal
type 8 = read-reset-read
else = normal but reset after each line

also pick up y-size from adds_24
9/6/97
4.09: Modified Black level read to enable proper set-up

19/6/97
4.13: Update and complete type 2 read-out.
Removed skip pixels after AOI.
Completed type 8 read-out.
Reset still only 2 clock cycles.

20/6/97
4.14: Lengthen reset pulses to 2.1 microsecs each

2/7/97
4.15: Install chip/quadrant select. Allows multiple chip
reset with flush. Expose integrated into main
control loop, and shutter open and close times
removed for code space economy.
Reset pulse now 10 microsecs

18/7/97
4.17: Updated field pulses to improve operations

25/8/97
4.18: Improving initialisation procedures

8/9/97
4.19: Further work on initialisation

2/10/97
4.21: Modification of Initialisation to use only reference
level for multi-quadrant stability.
16/11/97
4.22: Make chip selection work as in 4.19.
26/11/97
4.27: Improve and remove unnecessary frame pulse errors
added 30 msec delay at start of each frame to avoid
DMA timeouts.
As 4.25 except 5 cycles per integration period to
give 119-1090 KHz operation.
9/2/98
4.31: As 4.26 but with error in pixel_read routines corrected
to give true DCS operation.
10/2/98
4.34: Modified to reduce number of relay operations during read out.
13/2/98
4.37: Improved initialisation procedures

17/2/98
4.40: Modified Initialisation procedures to minimise glitches
Changed pixel read so that the ref/out and up/down are
synchronised
13/3/98
4.41: Exactly as 4.40 except 2 cycles per integration



-
U60
-
SAM448

Note all MGB comments on series 3 SAMs removed for 
printout compactness. See versions 4.14 and earlier 
for full text
--------------------------------------
PART:
SAM448

% Define generic names for input pins %
INPUTS:
BIT0 @ 12
BIT1 @ 11
BIT2 @ 10
BIT3 @ 9
BIT4 @ 5
BIT5 @ 4
BIT6 @ 3
BIT7 @ 2

% Define alternative names for output pins %
OUTPUTS:
F0 @ 13 % RAMA0 / READ1 %
F1 @ 14 % RAMA1 / READ2 %
F2 @ 15 % RAMA2 / READ3 %
F3 @ 16 % RAMA3 / READ4 %
F4 @ 17 % RAMA4 / FSYNC % 
F5 @ 18 % RAMA5 / LINE %
F6 @ 19 % HOLD / LSYNC %
F7 @ 20 % RESI / PIXEL %
F8 @ 22 % OUT / OPEN1 %
F9 @ 23 % RESET / OPEN2 %
F10 @ 24 % QUADSEL / OPEN3 %
F11 @ 25 % CHIPSEL / OPEN4 %
F12 @ 26 % CONVERT / VBLANK %
F13 @ 27 % UPDOWN / VFIELD %
F14 @ 28 % MODE / VLINE %
F15 @ 1 % latch select %

% CAMERA (bit15 = 1) % 
% RAMA0 variable address lsB %
% RAMA1 %
% RAMA2 %
% RAMA3 %
% RAMA4 %
% RAMA5 msB %
% HOLD hold DCS integrator H=freeze %
% RESI reset integrator H=reset %
% OUT select real hawaii output (M_RES) %
% RESET reset HAWAII row, active low (M_SER1) %
% QUADSEL latches READx bits into head (M_SER2) %
% CHIPSEL latches CHIPx bits into head (M_SER3) % 
% CONVERT send ADC convert pulse, should be SER4 according to TechRef %
% UPDOWN DCS integrator sign select H=up L=down %
% MODE %

% CONTROL (bit15 = 0) % 
% READ1 select quadrant/chip 1 (M_ST1) %
% READ2 2 (M_ST2) %
% READ3 3 (M_ST3) %
% READ4 4 (M_ST4) %
% FSYNC vertical data bit (M_IM1) % 
% LINE vertical clock bit (M_IM2) % 
% LSYNC horizontal data bit (M_IM3) % 
% PIXEL horizontal clock bit (M_IM4) % 
% OPEN1 not used %
% OPEN2 not used %
% OPEN3 not used %
% OPEN4 not used %
% VBLANK pixel strobe to grabber board , BLANK renamed VBLANK%
% VFIELD field strobe to grabber board to avoid confusion %
% VLINE line strobe to grabber board of VFG LINE with Hawaii LINE%

% General useful defn %
MACROS:
L = "0" % Output line LOW %
H = "1" % Output line HIGH %


%Addresses in the SAM %
ADDS_0 = "L L L L L L" %Mode selection
0 - Initialize (A)
1 - RESET
2 - READ
3 - RESET-READ
4 - READ-RESET-READ
5 - QUAD Select 
6 - CHIP Select 
7 - Initialize (B)
%

ADDS_1 = "H L L L L L" %Shutter open time - middle byte%
ADDS_2 = "L H L L L L" %Shutter open time - lower byte%
ADDS_3 = "H H L L L L" %Integrator integration time%
ADDS_4 = "L L H L L L" %Rate parameter... (NOT USED)%
ADDS_5 = "H L H L L L" %X offset of region (PXBEFORE_PAIRS)%
ADDS_6 = "L H H L L L" %X size of region (PXREAD_PAIRS)%
ADDS_7 = "H H H L L L" %X after region (PXAFTER_PARIS) %
ADDS_8 = "L L L H L L" %Y offset of region (ROWBEFORE_PAIRS) %
ADDS_9 = "H L L H L L" %Y size of region (ROWREAD_PAIRS) %
ADDS_10 = "L H L H L L" %Y after region (ROWAFTER_PAIRS) %
ADDS_11 = "H H L H L L" %Quadrant mask (was Vertical bin)%
ADDS_12 = "L L H H L L" %Array mask (was Horizontal bin)%
ADDS_13 = "H L H H L L" %NOT USED %
ADDS_14 = "L H H H L L" %NOT USED %
ADDS_15 = "H H H H L L" %NOT USED %
ADDS_16 = "L L L L H L" %NOT USED %
ADDS_17 = "H L L L H L" %Test routine pixel reads%
ADDS_18 = "L H L L H L" %Shutter control 
type 2 = single line repeat read-out
type 4 = normal
type 8 = read-reset-read
else = normal, with reset after each line%
ADDS_19 = "H H L L H L" %X bin control (NOT USED) %
ADDS_20 = "L L H L H L" %Shutter open time (top byte)%
ADDS_21 = "H L H L H L" %Shutter open delay%
ADDS_22 = "L H H L H L" %Shutter close delay%
ADDS_23 = "H H H L H L" %X size of quadrant (N/8) %
ADDS_24 = "L L L H H L" %Y size of quadrant (N/8) %
ADDS_25 = "H L L H H L" %Parallel pulse width (NOT USED)%
ADDS_26 = "L H L H H L" %Parallel pulse delay (NOT USED)%
ADDS_27 = "H H L H H L" %Reserved%
ADDS_28 = "L L H H H L" %Reserved%
ADDS_29 = "H L H H H L" %Reserved%
ADDS_30 = "L H H H H L" %Reserved%
ADDS_31 = "H H H H H L" %Reserved%

% ADDS_32 to ADDS_63 Not Used %

%States of the individual bits%
HOLD = "L" %Hold integrator%
_HOLD = "H" %Don't hold integrator%
RES_I = "H" %Reset integrator = CHIP%
_RES_I = "L" %Don't reset integrator = REF%
CONVT = "H" %Do conversion%
_CONVT = "L" %No conversion%
UP = "H" %Integrate up%
DOWN = "L" %Integrate down%
WR_RM = "H" %Write to remote bus latches = CAMERA%
WR_CTRL = "L" %Write to control bus latches = CONTROL% 

PROG = "L" %Program DACS%
CAMA = "H" %Send clocks to head%

% HAWAII renaming of some CCD functions %
OUT = "H" %Select real output to mux,error in PCB OUT==RST want REF==RST%
REF = "L" %Select ref output = _OUT %
CONTROL = "L" %Latch to generally 4100 functions (WR_CTRL) %
CAMERA = "H" %Latch to camera head functions (WR_RM) %
NOSHUT = "L L L L" % All shutter bits OFF %
SHUT = "L H H L" % All shutter bits ON %

% For original data card, needed for PCI ? %
NOSYNC = "L L L" % Don't use sync lines%
VBLANK = "H" 
_VBLANK = "L" 
VFIELD = "H" 
_VFIELD = "L" 
VLINE = "H" 
_VLINE = "L" 

% Null replacements for CCD clock settings %
H_NONE = "L L L" % replaces H_NONE,2 etc %
V_NONE = "L L L L L L L L" % replaces V1,2 etc % 

% HAWAII address clocks %
FSYNC = "L" % Vertical data bit (active low) %
_FSYNC = "H" 
LINE = "H" % Vertical clock bit %
_LINE = "L" 
LSYNC = "L" % Horizontal data bit (active low) %
_LSYNC = "H" 
PIXEL = "H" % Horizontal clock bit %
_PIXEL = "L" 
RESET = "L" % Reset current row (active low) %
_RESET = "H" 

NOCLOCK = "_FSYNC _LINE _LSYNC _PIXEL"

% Quadrant access %
READ1 = "H" % Enable quadrant 1 %
_READ1= "L" % Disable quadrant 1 %
READ2 = "H" % Enable quadrant 2 %
_READ2= "L" % Disable quadrant 2 %
READ3 = "H" % Enable quadrant 3 %
_READ3= "L" % Disable quadrant 3 %
READ4 = "H" % Enable quadrant 4 %
_READ4= "L" % Disable quadrant 4 %

QUAD1 = "H L L L" % Quadrant 1 only %
QUAD2 = "L H L L" % Quadrant 2 only %
QUAD3 = "L L H L" % Quadrant 3 only %
QUAD4 = "L L L H" % Quadrant 4 only %
QUADALL = "H H H H" % All quadrants active %
QUADNONE= "L L L L" % No quadrants active %

CHIP1 = "H L L L" % Chip 1 only %
CHIP2 = "L H L L" % Chip 2 only %
CHIP3 = "L L H L" % Chip 3 only %
CHIP4 = "L L L H" % Chip 4 only %
CHIPALL = "H H H H" % All Chips active %
CHIPNONE= "L L L L" % No Chips active %

QUADSEL= "H" % Latch new quadrant mask %
_QUADSEL= "L" % don't new quadrant mask %
CHIPSEL= "H" % Latch new chip mask %
_CHIPSEL= "L" % don't new chip mask %
_SELECT = "L L" % Don't change quad or chip select%
NODATA= "L L L L" % Latch not active so don't care%


% pixels to read to get black level%
% Reduced to speed up testing %
BLACK_H_READ = "16D" % was "100D" %
BLACK_V_READ = "16D" % was "49D" %


% real size 64D,63D testing 8x8 = 1D,0D %
% Vertical size n/8 %
SIZE_ROWS = "64D" % real "64D" %
% Horizontal size (n-1)/8 %
SIZE_PIXELS = "63D" % real "63D" %

%Equation feature not used%
EQUATIONS:

%Program names based on RISC code and KAF.asm%
PROGRAM:



% ********************************************************************* %
% * * %
% * Astrocam based routines, initialisation * %
% * * %
% ********************************************************************* %


% --------------------------------------------------------------------- %
% Entry point at SAM reset %
% Must select chip 1 and quadrant 1 first %
% --------------------------------------------------------------------- %
0D:
[ADDS_0 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE; 
[ADDS_0 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE; 
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] JUMP MODE_SELECT; 



% --------------------------------------------------------------------- %
% Test address 0 for mode %
% %
% Values to be compatible with PIXCEL %
% 0 = 0 0 0 0 INIT_A % 
% 1 = 1 0 0 0 RESET_FULL (=flush) %
% 2 = 0 0 1 0 READ_FULL (=region) %
% 3 = 0 0 1 0 READ_REGION (=region) comment one of these out %
% 7 = 1 1 1 0 INIT_B %
% --------------------------------------------------------------------- %
MODE_SELECT:
IF /BIT0*/BIT1*/BIT2*/BIT3 THEN % 0 0 0 0 %
[ADDS_0 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] JUMP INIT_A;

ELSEIF BIT0*BIT1*BIT2*/BIT3 THEN % 1 1 1 0 %
[ADDS_0 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] JUMP INIT_B;

ELSEIF BIT0*/BIT1*/BIT2*/BIT3 THEN % 1 0 0 0 %
[ADDS_0 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] JUMP RESET_FULL;

ELSE 
[ADDS_0 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] JUMP READ_CHIPS_AND_QUADRANTS; 





% --------------------------------------------------------------------- %
% Initialise at power up A %
% %
% Used to program DACS, but still needed by pixcel %
% Reads a dummy pixel, not dcs %
% --------------------------------------------------------------------- %
INIT_A:
% Get X size of chip and read dummy pixels to get black level %
[ADDS_17 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_ADDRESS_F;
INITA_A:
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL DUMMY_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ INITA_A;
INITA_END:
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] JUMP INITA_END; 

% --------------------------------------------------------------------- %
% Initialise at power up B %
% %
% Used to set black level %
% Reads a dummy pixel, so Quad/chip doesn't have to be selected %
% --------------------------------------------------------------------- %
INIT_B:
% Number of pixels to read in each line%
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 130D;
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_8_DUMMY_PIXEL;
INITB_END:
[NODATA NOCLOCK NOSHUT VBLANK VFIELD _VLINE WR_CTRL] JUMP INITB_END; 


% ********************************************************************* %
% * * %
% * HAWAII readout modes * %
% * * %
% * Read whole frame, or blocks made up of 8*8 pixel blocks * %
% * * %
% ********************************************************************* %

% Note: in the labels R=Read X=Reset S=Skip, RXR = Read,Reset_Read %


% --------------------------------------------------------------------- %
% Reset Frame =flush %
% %
% During flush line=high, field=low %
% after flush line=low, field=high %
% --------------------------------------------------------------------- %
RESET_FULL:
[1111 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD;
[1111 NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CALL SEL_CHIP;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL RESET_ROWFULL;
[0000 NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CALL SEL_CHIP;
[0000 NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CALL SEL_QUAD
RETURNTO INITB_END;


% --------------------------------------------------------------------- %
% Sync for frame readout %
% field,line high for exposure %
% field=low for readout %
% field=high at end of frame %
% --------------------------------------------------------------------- %

% --------------------------------------------------------------------- %
% Next is main supervisory routine. %
% Selects chip and quadrant from ADDS_25/6 bit patterns and latches them%
% --------------------------------------------------------------------- %

READ_CHIPS_AND_QUADRANTS:
[ADDS_20 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;

% Open the shutter %
[NODATA NOCLOCK SHUT VBLANK VFIELD VLINE WR_CTRL] CALL SHUTTER_OPEN_DELAY; 

% Close the shutter%
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE;
% [ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;%

IF /BIT0*/BIT1*/BIT2*/BIT3 THEN
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
ELSE
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL SEL_CHIP_1;
SEL_CHIP_1_1:
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;

IF /BIT4*/BIT5*/BIT6*/BIT7 THEN
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
ELSE
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL SEL_CHIP_2;
SEL_CHIP_2_2:
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
IF /BIT0*/BIT1*/BIT2*/BIT3 THEN
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
ELSE
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL SEL_CHIP_3;
SEL_CHIP_3_3:
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;

IF /BIT4*/BIT5*/BIT6*/BIT7 THEN
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
ELSE
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL SEL_CHIP_4;
SEL_CHIP_4_4:
[0000 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD
RETURNTO READ_CHIPS_AND_QUADRANTS; 

% --------------------------------------------------------------------- %
% Next is routine to select quadrant needed %
% --------------------------------------------------------------------- %
SEL_QUAD:
[ADDS_25 HOLD _RES_I REF _RESET _CHIPSEL QUADSEL _CONVT UP CAMA WR_RM] CONTINUE;
% [ADDS_25 HOLD _RES_I REF _RESET _CHIPSEL QUADSEL _CONVT UP CAMA WR_RM] CONTINUE;%
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL MS_DELAY;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;



% --------------------------------------------------------------------- %
% Next is routine to select chip 1 and select quadrants needed %
% --------------------------------------------------------------------- %
SEL_CHIP_1:
[1000 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_CHIP;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL QUAD_SEL_CHIP12;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;
% --------------------------------------------------------------------- %
% Next is routine to select chip 2 and select quadrants needed %
% --------------------------------------------------------------------- %
SEL_CHIP_2:
[0100 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_CHIP;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL QUAD_SEL_CHIP12;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;

% --------------------------------------------------------------------- %
% Next is routine to select chip 3 and select quadrants needed %
% --------------------------------------------------------------------- %
SEL_CHIP_3:
[0010 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_CHIP;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL QUAD_SEL_CHIP34;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;

% --------------------------------------------------------------------- %
% Next is routine to select chip 4 and select quadrants needed %
% --------------------------------------------------------------------- %
SEL_CHIP_4:
[0001 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_CHIP;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL QUAD_SEL_CHIP34;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;


% --------------------------------------------------------------------- %
% Next is routine to select quads of chips 1 and 2 needed %
% --------------------------------------------------------------------- %
QUAD_SEL_CHIP12:
IF BIT0+BIT4 THEN
[1000 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD_25;
ELSE
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE;
IF BIT1+BIT5 THEN
[0100 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD_25;
ELSE
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE;
IF BIT2+BIT6 THEN
[0010 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD_25;
ELSE
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE;
IF BIT3+BIT7 THEN
[0001 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD_25;
ELSE
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE; 

[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;

% --------------------------------------------------------------------- %
% Next is routine to select quads of chips 3 and 4 needed %
% --------------------------------------------------------------------- %
QUAD_SEL_CHIP34:
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
IF BIT0+BIT4 THEN
[1000 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD_26;
ELSE
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE;
IF BIT1+BIT5 THEN
[0100 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD_26;
ELSE
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE;
IF BIT2+BIT6 THEN
[0010 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD_26;
ELSE
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE;
IF BIT3+BIT7 THEN
[0001 NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CALL SEL_QUAD_26;
ELSE
[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] CONTINUE; 

[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;


% --------------------------------------------------------------------- %
% Next is routine to select Chip needed %
% --------------------------------------------------------------------- %
SEL_CHIP:
% [ADDS_25 HOLD _RES_I REF _RESET CHIPSEL _QUADSEL _CONVT UP CAMA WR_RM] CONTINUE;%
[ADDS_25 HOLD _RES_I REF _RESET CHIPSEL _QUADSEL _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL MS_DELAY;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;



% --------------------------------------------------------------------- %
% Next is routine to select quadrant 1-8 needed and read it out %
% --------------------------------------------------------------------- %
SEL_QUAD_25:
% [ADDS_25 HOLD _RES_I REF _RESET _CHIPSEL QUADSEL _CONVT UP CAMA WR_RM] CONTINUE;%
[ADDS_25 HOLD _RES_I REF _RESET _CHIPSEL QUADSEL _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL MS_DELAY;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_REGION;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;

% --------------------------------------------------------------------- %
% Next is routine to select quadrant 9-16 needed and read it out %
% --------------------------------------------------------------------- %
SEL_QUAD_26:
% [ADDS_26 HOLD _RES_I REF _RESET _CHIPSEL QUADSEL _CONVT UP CAMA WR_RM] CONTINUE;%
[ADDS_26 HOLD _RES_I REF _RESET _CHIPSEL QUADSEL _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL MS_DELAY;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_REGION;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_26 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;


% --------------------------------------------------------------------- %
% Non-destructive Read-out of sub-array %
% %
% [NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CALL CLR; %
% --------------------------------------------------------------------- %
READ_REGION:

% Delay for frame sync (10us too short), expose and start frame%
[ADDS_9 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 30D;
MS_ADEL:
[ADDS_9 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL MS_DELAY;
[ADDS_9 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ MS_ADEL;
[ADDS_9 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;

% [NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CONTINUE;%
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CALL FRAMESTART; 

% Now starts the readout...
Flush the first N*8 lines%
[ADDS_8 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_ADDRESS_F;
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CALL EIGHT_LINE_FLUSH_F;
% Read N*8 line segments (FIELD IS ACTIVE)%
[ADDS_9 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_ADDRESS_F;
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CALL EIGHT_SEGMENT_READ; 

[NODATA NOCLOCK NOSHUT VBLANK VFIELD VLINE WR_CTRL] RETURN; 

%-----------------------------
| |
| DELAY WHILE SHUTTER IS OPEN |
| |
-----------------------------%
% This routine DOES NOT preserve the counter%
SHUTTER_OPEN_DELAY:
% Delay for address to settle%
[ADDS_20 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
% Save highest byte on the stack%
[ADDS_1 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHI;
[ADDS_1 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
% Save middle byte%
[ADDS_2 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHI;
[ADDS_2 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
% Save bottom byte%
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHI;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC GOTO SOD_C;
SOD_A:
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 255D;
SOD_B:
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 255D;
SOD_C:
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL MS_DELAY;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ SOD_C;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ SOD_B;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ SOD_A;
[ADDS_25 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;

%----------------------------------------------
| |
| SKIP (N*8) ROWS VERTICALLY |
| |
----------------------------------------------%
% Place N in the counter first
This routine DOES NOT preserve the counter%
EIGHT_LINE_FLUSH_F:
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ ELF_START
ONZERO ELF_EXIT;
ELF_START:
% SKIP 8 rows%
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 7D;
ELF_LOOP:
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CALL NEW_ROW;
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] LOOPNZ ELF_LOOP;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC
GOTO EIGHT_LINE_FLUSH_F;
ELF_EXIT:
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;

%---------------------------------------
| |
| READ OUT (N+1)*8 LINE SEGMENTS |
| |
---------------------------------------%
% Place N in the counter first
This routine DOES NOT preserve the counter
Flushes unwanted pixels as fast as possible
If mode 2, start with a first row reset %

EIGHT_SEGMENT_READ:
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
%IF /BIT0*BIT1*/BIT2*/BIT3 THEN%
% Coment outr one of the following lines to either enable a reset before each%
%of these repeat line (mode 2) frames, or not %
% [ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL RESET_THIS_ROW;%
% [ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;%

%ELSE
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;%
EIGHT_SEGMENT_READ2:
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 7D;
% Now starts the real readout...
Dump pixels before active segment (6MHz)%
ESR_A:
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 0D;
%if shutter mode 2 then omit new_row call, and repeat same row%
IF /BIT0*BIT1*/BIT2*/BIT3 THEN
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL ZERO_ROW;
ELSE
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL NEW_ROW;

[ADDS_5 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_ADDRESS_F;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL EIGHT_PIXEL_FAST_SKIP;
% Read out the pixels%
[ADDS_6 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_ADDRESS_F;

% Read out the pixels, in groups of four if shutter mode 8, otherwise groups of 8%

[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;

IF /BIT0*/BIT1*/BIT2*BIT3 THEN
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
ELSE
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_8PIXEL
RETURNTO READ_N_PX2;
RD_4_PX:
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_4PIXEL;
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL RESET_THIS_ROW;
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL ZERO_ROW;

[ADDS_5 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_ADDRESS_F;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL EIGHT_PIXEL_FAST_SKIP;
[ADDS_6 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_ADDRESS_F;
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_4PIXEL;

READ_N_PX2:
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;

% Go round again%
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ ESR_A;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ EIGHT_SEGMENT_READ2;
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;


%--------------------------------------------------
| |
| SKIP (N*8) PIXELS ALONG THE SERIAL REGISTER |
| |
--------------------------------------------------%
% Place N in the counter first
This routine DOES NOT preserve the counter%
EIGHT_PIXEL_FAST_SKIP:
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ ESF_START
ONZERO ESF_EXIT;
ESF_START:
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 6D;
ESF_A:
[NODATA _FSYNC _LINE _LSYNC PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] CONTINUE;
[NODATA _FSYNC _LINE _LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] LOOPNZ ESF_A;
[NODATA _FSYNC _LINE _LSYNC PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] CONTINUE;
[NODATA _FSYNC _LINE _LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] POPC
GOTO EIGHT_PIXEL_FAST_SKIP;
ESF_EXIT:
[ADDS_4 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;

% --------------------------------------------------------------------- % 
% %
% Reset all pixels on n*8 rows % 
% %
% --------------------------------------------------------------------- %
RESET_ROWFULL:
[ADDS_24 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL FRAMESTART;
[ADDS_24 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL READ_ADDRESS_F;

RESET_ROWFULL2:
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ XRF_START 
ONZERO XRF_EXIT;
XRF_START:
[ADDS_0 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 7D; 

XRF_A:
[ADDS_0 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL NEW_ROW; 
[ADDS_4 HOLD RES_I REF RESET _SELECT _CONVT UP CAMA WR_RM] CALL RESET_THIS_ROW; 
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ XRF_A;

[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC GOTO RESET_ROWFULL2;
XRF_EXIT:
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN; 



% ********************************************************************* %
% * * %
% * PIXEL read routines * %
% * * %
% ********************************************************************* %


% --------------------------------------------------------------------- %
% Read blocks of (n+1)*8 adjacent DUMMY pixels %
% From EPR3 in KAF, %
% --------------------------------------------------------------------- %
READ_8_DUMMY_PIXEL:
% Put n=number of blocks, into counter %
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 4D;
R8P_A_DD:
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL D_PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ R8P_A_DD;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL D_PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL D_PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ R8P_B_DD;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL D_PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;
R8P_B_DD:
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL D_PIXEL_READ
RETURNTO READ_8_DUMMY_PIXEL;

% --------------------------------------------------------------------- %
% Read blocks of (n+1)*8 adjacent pixels %
% From EPR3 in KAF, %
% --------------------------------------------------------------------- %
READ_8PIXEL:
% Put n=number of blocks, into counter %
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 4D;
R8P_A:
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ R8P_A;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ R8P_B;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ;
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;


% Decide whether to reset this row, not if shutter is mode 2 or 4 or 8%

IF /BIT0*BIT1*/BIT2*/BIT3 THEN
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
ELSEIF /BIT0*/BIT1*BIT2*/BIT3 THEN
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
ELSEIF /BIT0*/BIT1*/BIT2*BIT3 THEN
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
ELSE
[ADDS_18 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL RESET_THIS_ROW;

[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;

R8P_B:
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ
RETURNTO READ_8PIXEL;
% --------------------------------------------------------------------- %
% Read blocks of (n+1)*4 adjacent pixels, reset and read them again %
% From EPR3 in KAF, %
% --------------------------------------------------------------------- %


READ_4PIXEL:
% Put n=number of blocks, into counter %
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 0D;
R4P_A:
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ R4P_A;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ R4P_B;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;



R4P_B:
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL PIXEL_READ
RETURNTO READ_4PIXEL;

% --------------------------------------------------------------------- %
% Read a single DUMMY pixel , from KAF PIXEL_READ, preserves counter %
% Hawaii REF=DOWN REF=UP to give CCD style slope %
% --------------------------------------------------------------------- %

D_PIXEL_READ:
% Clock pixel - put here to extend pulse %
[NODATA _FSYNC _LINE _LSYNC PIXEL NOSHUT NOSYNC WR_CTRL] CONTINUE;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 0D;
% End of pixel pulse %
[NODATA _FSYNC _LINE _LSYNC _PIXEL NOSHUT NOSYNC WR_CTRL] CONTINUE;
[ADDS_3 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHI; 
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC; 
PR_A_DD:
% Integrate DOWN on REF %
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ PR_A_DD;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT DOWN CAMA WR_RM] PUSHI; 
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT DOWN CAMA WR_RM] POPC; 
PR_B_DD:
% Integrate UP on OUT %
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT DOWN CAMA WR_RM] CONTINUE;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT DOWN CAMA WR_RM] LOOPNZ PR_B_DD;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT DOWN CAMA WR_RM] POPC;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT CONVT DOWN CAMA WR_RM] RETURN;


% --------------------------------------------------------------------- %
% Read a single pixel , from KAF PIXEL_READ, preserves counter %
% Hawaii REF=DOWN OUT=UP to give CCD style slope %
% --------------------------------------------------------------------- %
PIXEL_READ:
% Clock pixel - put here to extend pulse %
[NODATA _FSYNC _LINE _LSYNC PIXEL NOSHUT NOSYNC WR_CTRL] CONTINUE;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 0D;
% End of pixel pulse %
[NODATA _FSYNC _LINE _LSYNC _PIXEL NOSHUT NOSYNC WR_CTRL] CONTINUE;
[ADDS_3 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHI; 
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC; 
PR_A:
% Integrate DOWN on REF %
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ PR_A;
[ADDS_3 _HOLD _RES_I OUT _RESET _SELECT _CONVT DOWN CAMA WR_RM] PUSHI; 
[ADDS_3 _HOLD _RES_I OUT _RESET _SELECT _CONVT DOWN CAMA WR_RM] POPC; 
PR_B:
% Integrate UP on OUT %
[ADDS_3 _HOLD _RES_I OUT _RESET _SELECT _CONVT DOWN CAMA WR_RM] CONTINUE;
[ADDS_3 _HOLD _RES_I OUT _RESET _SELECT _CONVT DOWN CAMA WR_RM] LOOPNZ PR_B;
[ADDS_3 HOLD _RES_I OUT _RESET _SELECT _CONVT DOWN CAMA WR_RM] POPC;
[ADDS_3 HOLD _RES_I OUT _RESET _SELECT CONVT DOWN CAMA WR_RM] RETURN;


% --------------------------------------------------------------------- %
% Read a dummy pixel , Half pixel read for INIT %
% --------------------------------------------------------------------- %
DUMMY_READ:
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 0D;
[ADDS_3 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHI;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
DR_A:
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CONTINUE;
[ADDS_3 _HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ DR_A;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT CONVT UP CAMA WR_RM] RETURN;

% ********************************************************************* %
% * * %
% * HAWAII clock routines * %
% * * %
% ********************************************************************* %

% --------------------------------------------------------------------- %
% Load row register for start of frame %
% --------------------------------------------------------------------- %
FRAMESTART:
[NODATA _FSYNC _LINE _LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] CONTINUE;
[NODATA FSYNC _LINE _LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] CONTINUE;
[NODATA _FSYNC _LINE _LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] RETURN;


% --------------------------------------------------------------------- %
% Go to start of next row, and Load registers for start of row %
% --------------------------------------------------------------------- %
NEW_ROW:
% [NODATA _FSYNC LINE _LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] CONTINUE;%
[NODATA _FSYNC LINE _LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] CONTINUE;
ZERO_ROW:
% [NODATA _FSYNC _LINE LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] CONTINUE;%
[NODATA _FSYNC _LINE LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] CONTINUE;

[NODATA _FSYNC _LINE _LSYNC _PIXEL NOSHUT VBLANK _VFIELD _VLINE WR_CTRL] RETURN;



% --------------------------------------------------------------------- %
% Resets current selected row %
% --------------------------------------------------------------------- %
RESET_THIS_ROW:
[ADDS_3 HOLD _RES_I REF RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 250D;
RESET_DELAY:
[ADDS_3 HOLD _RES_I REF RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ RESET_DELAY;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_3 HOLD _RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;


% ********************************************************************* %
% * * %
% * General utility routines * %
% * * %
% ********************************************************************* %


% --------------------------------------------------------------------- %
% Read address and return in counter %
% --------------------------------------------------------------------- %
READ_ADDRESS_F:
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] CONTINUE;
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] PUSHI;
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] POPC;
[NODATA NOCLOCK NOSHUT VBLANK _VFIELD VLINE WR_CTRL] RETURN; 


% --------------------------------------------------------------------- %
% Delay 1 millsec %
% Preserve counter %
% --------------------------------------------------------------------- %
MS_DELAY:
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 99D;
MS_A:
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] CALL US10_DELAY;
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ MS_A;
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;


% --------------------------------------------------------------------- %
% Delay 10 microsec %
% Preserve counter %
% --------------------------------------------------------------------- %
US10_DELAY:
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] PUSHLOADC 116D;
US10_A:
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ US10_A;
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOADC 116D;
US10_B:
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] LOOPNZ US10_B;
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] POPC;
[ADDS_4 HOLD RES_I REF _RESET _SELECT _CONVT UP CAMA WR_RM] RETURN;