/*============================================================================
TRACE Sequencer Instructions V0.00: 15 Aug 96 Dnyanesh Mathur Copied from \trace\trinstr.cpp (v4). This base version contains a set of instructions sufficient for a defining an observation which takes a set number of pictures. V0.01: 26 Aug 96 Dnyanesh Mathur The instructions setr2v and TSI_stop have been verified. V0.02: 26 Aug 96 Dnyanesh Mathur 1. TAPT instruction modified extensively. The state machine is now run by the CC. Added SetConfigParam and DecodeFrame routines. V0.03: 4 Sep 96 Dnyanesh Mathur 1. Added other time wait routines, Delay and Tim. 2. Rearranged Opcodes. Defined all 256 possible opcodes. Most map to NOI____ (No Instructions). V0.04: 16 Sep 96 Dnyanesh Mathur 1. Added STTG instruction. The ACS test will be run with a sequence. 2. Added Call and Return instructions. V0.05: 26 Sep 96 Dnyanesh Mathur 1. Major reassignment of opcodes. This has become necessary to streamline operand decoding. The new opcodes are described in /tra/opcodes.txt. All opcodes are now decoded by GetOperand function in trseq.c. 2. Added arithmatic instructions (ADD, SUB, MUL and DIV). 3. Renamed several old instruction routines. V0.06: 16 Oct 96 Dnyanesh Mathur 1. Added Wavelength, PZT configuration code in FRAME instruction. 2. Updated DecFrame routine to reflect the latest format of the the Frame Definition Block. 3. Added an instruction to select CCD Readout Amplitfier and set the ADC offset. v0.07 Apr 97 Dnyanesh Mathur 1. Corrected start address calculation for extracted regions. 2. Corrected WAIT 0 error (it used to wait for 65535 tics). 3. Store error codes in global variables rather than defined symbols. This will allow codes to be changed more easily during the mission. 4. Save TickCount on sequence Calls. 5. Copy sequence ID to register 14 and 15. 6. Added a NOID instruction which *does not* set the ID but still provides pointer to the next sequence. v0.08: 8 May 97 Dnyanesh Mathur 1. Added HTML tags to each instruction function. v0.09: 12 May 97 Dnyanesh Mathur 1. Changed FocusPos to s *signed* int to enable both positive and negative offsets. 2. Added RUNDHCP instruction to execute a DHC program. 3. Added SETDHCR instruction to set a DHC register. (DEV instruction is no longer available). 4. Added instructions to open and close the ISS loop. v0.10: 19 Jun 97 Dnyanesh Mathur 1. Corrected setting of AEC-Execute Flag (AECX) in the IPB. It was being if "specific exposure" flag was *not* set in the exposure control word. 2. Histogram bin is set to 127 if it is greater than 127. (AEHB, SFHB, FHB). 3. Corrected an error in computing AEHC and AELC. Extractsize of 0 was not being set to 16. Made similar correction for Rowblocks and Column blocks. 4. Corrected the scaling for ADC Offset. It was divided by 32768 instead of 32. v0.11: 24 Jun 97 Dnyanesh Mathur 1. Made ADCOffset and Rowlengths tables to global arrays. 2. Determine the currently selected amplifier from cct.amp rather than using fb->RdOutAmp as the latter can be set to 3, resulting in array index which is out of bounds. 3. Corrected AEC adjustment code. The else clause of the (-1, Decrease) case was executed even for (+1, Increase exposure) case. 4. Abort sequence if DHC detects a dangerous event (Flare in EUV quadrent). 5. Corrected RESETAEC instruction to update all AEC CUR values. 6. Corrected UPDIMX instruction to compute the max location from DHCRES block directly rather than using the values computed by FRAME. 7. If a buffer is locked the output to that buffer is stopped. V0.12: 26 Jun 97 Dnyanesh Mathur 1. Initialize slew_delay to 60. Correct the test for busy in STTG. 2. Correct dark frame exposure setting (RAR) v0.13: 9 Jul 97 Dnyanesh Mathur 1. Corrected AEC offset exposures. 2. Corrected bad pixel table number. It could be incorrect is "default" amplifier was specified - since it used cct.amp * 4 to compute the bad pixel table number. v0.14: 11 Jul 97 Dnyanesh Mathur 1. Corrected the check for slew flag in STTG routine. This change was actually made in v0.12. However, it was lost because the next set of changes were made to an older version. 2. Update Flare flag, Super flare flag and the transient flags only if they have been set in the frame definition block. 3. Corrected binning factor for normalising counts (SFHC and FHC) in the image processing block. 4. The Bad Pixel Offset and Length (number of rows) are filled in for camera modes 0-3 (They were set to zero). ============================================================================*/ #include "..\l2\tlm.h" #include "..\l4\cmd.h" #include "..\l4\tim.h" #include "..\l6\cam.h" #include "..\l8\trsymdef.h" #include "..\l8\trseqdef.h" #define TRACE2 1 #include "..\l8\sqtables.h" #define ULI unsigned long int #define MAX_EXP_INDEX 72 int ADCoffset[2][8] = {94, 376, 1504, 6106, 94, 94, 94, 94, 94, 376, 1504, 6106, 94, 94, 94, 94}; int PXdone; extern int sh_exp; unsigned int WaitDur; unsigned long int RefTicks; unsigned long int MarkTicks; unsigned char *curr_instr_addr; unsigned char *next_instr_addr; unsigned int TargIndx = 0; unsigned int PZTindx = 0; int FocusPos = 0; unsigned int InstOp[3]; unsigned int OpRegn[3]; int PRVrow = 512; unsigned int TASample = 0; int WL_indx; int AEC_indx; int AEC_Offset; int AEC_Offset_sign; unsigned int CamFrmPg[2] = {0, 1}; unsigned int PageIndx = 1; int RdoutAmp, prv_RdOutAmp; int A1RO, A1CO, A1RB, A1CB; int RefRow, RefCol; int prv_RefRow = 512, prv_RefCol = 512; int bad_pic = 0; unsigned int slew_delay = 60; unsigned int sttg_delay; long int OverFlow = 0; unsigned int ExtractSize; unsigned int RowBlks[2]; unsigned int ColBlks[2]; struct CCDLOC { unsigned int Row; unsigned int Col; }; struct CCDLOC MaxLoc; struct CCDLOC MinLoc; struct shtr_ex { long int actual; unsigned int exp; unsigned int rep; }; extern struct shtr_ex extab[]; extern void opnLT (unsigned int LT_state); extern void clsLT (void); extern void runmac (unsigned int *qadr); extern void ipreg (unsigned int *regp); #define sh_exp sa1E.kshnexp #define INT_OP *((int *)(*sp))++ #define CHAR_OP *(*sp)++ //#include "\tra\l6\exp_tb.h" /*----- GetOperands ---------------------------------------------------------- This routine returns the operands in a unsigned int array. --..........................................................................*/ void GetOperands (unsigned char **sp, unsigned int *op, unsigned int *rnum) { int numop; int i; if (TSRopcode < 0x80) numop = 3; else if (TSRopcode < 0xB0) numop = 2; else if (TSRopcode < 0xE0) numop = 1; else numop = 0; for (i = 0; i < numop; i++) { if (TSRopcode & (1 << (3 - i))) { *(op + i) = INT_OP; *(rnum + i) = -1; } else { *(rnum + i) = CHAR_OP; *(op + i) = *(SeqReg + *(rnum + i)); } } return; } /*---------------------------------------------------------------------- Arithmatic Instructions: ------------------------------------------------------------------------*/ //
struct ErrBlk ADD (unsigned char **sp) { struct ErrBlk EB; int i; GetOperands (sp, InstOp, OpRegn); *(SeqReg + OpRegn[0]) = InstOp[1] + InstOp[2]; EB.status = 0; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk SUB (unsigned char **sp) { struct ErrBlk EB; int i; GetOperands (sp, InstOp, OpRegn); *(SeqReg + OpRegn[0]) = InstOp[1] - InstOp[2]; EB.status = 0; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk MUL (unsigned char **sp) { struct ErrBlk EB; int i; long int result; GetOperands (sp, InstOp, OpRegn); result = (long)InstOp[1] * (long)InstOp[2]; *(SeqReg + OpRegn[0]) = result & 0xffff; OverFlow = (result & 0xffff0000) >> 16; EB.status = 0; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk DIV (unsigned char **sp) { struct ErrBlk EB; int i; GetOperands (sp, InstOp, OpRegn); if (InstOp[2]) *(SeqReg + OpRegn[0]) = InstOp[1] / InstOp[2]; else *(SeqReg + OpRegn[0]) = 0; EB.status = 0; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } /*----------------------------------------------------------------------*/ /*---------------------------------------------------------------------- Register Instructions: ------------------------------------------------------------------------*/ //
struct ErrBlk SET (unsigned char **sp) { struct ErrBlk EB; int i; GetOperands (sp, InstOp, OpRegn); *(SeqReg + OpRegn[0]) = InstOp[1]; EB.status = 1; EB.status = 0; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk INC (unsigned char **sp) { struct ErrBlk EB; int regnum; EB.status = 0; regnum = *(*sp)++; *(SeqReg + regnum) += 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk DEC (unsigned char **sp) { struct ErrBlk EB; int regnum; EB.status = 0; regnum = *(*sp)++; *(SeqReg + regnum) -= 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } /*---------------------------------------------------------------------- Branch Instructions: ------------------------------------------------------------------------*/ //
struct ErrBlk BRANCHIF (unsigned char **sp) { struct ErrBlk EB; char *sqp; int dest_addr; int new_addr; int op1, op2; int i; GetOperands (sp, InstOp, OpRegn); new_addr = (int) (*sp - &seq[0]); dest_addr = InstOp[0]; switch (TSRopcode & 0x00F0) { case 0x0000: if (InstOp[1] == InstOp[2]) new_addr = dest_addr; break; //BEQ case 0x0010: if (InstOp[1] != InstOp[2]) new_addr = dest_addr; break; //BNE case 0x0020: if (InstOp[1] < InstOp[2]) new_addr = dest_addr; break; //BLT case 0x0030: if (InstOp[1] <= InstOp[2]) new_addr = dest_addr; break; //BLE case 0x0040: if (InstOp[1] > InstOp[2]) new_addr = dest_addr; break; //BGT case 0x0050: if (InstOp[1] >= InstOp[2]) new_addr = dest_addr; break; //BGE case 0x0080: if (InstOp[1] != 0) new_addr = dest_addr; break; //BZ case 0x0090: if (InstOp[1] == 0) new_addr = dest_addr; break; //BNZ case 0x00C0: new_addr = dest_addr; break; //UBR } if (new_addr > MAX_ADDR) { EB.status = 91; //TSI_goto_ADDRESS_ERROR; EB.OpCode = TSRopcode; EB.param = (int) new_addr; EB.TrSqAddr = (int) *sp; } else { *sp = &seq[0] + new_addr; EB.status = 0; EB.OpCode = **sp; EB.param = 0; EB.TrSqAddr = (int) *sp; } EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } /*---------------------------------------------------------------------- Control Instructions: ------------------------------------------------------------------------*/ //
struct ErrBlk EXIT (unsigned char **sp) { struct ErrBlk EB; char *sqaddr; int i; int *pSeqID; int *ptr; GetOperands (sp, InstOp, OpRegn); if (CallDepth != 0) { BlkRptCount = *(--SqCallStack); for (i = NLCLREG-1; i >= 0; i--) *(SeqReg + i) = *(--SqCallStack); ptr = (int *) &TRefSec; ptr++; *ptr-- = *(--SqCallStack); *ptr = *(--SqCallStack); ptr = (int *) &TickCount; ptr++; *ptr-- = *(--SqCallStack); *ptr = *(--SqCallStack); ptr = (int *) &SeqID; ptr++; *ptr-- = *(--SqCallStack); *ptr = *(--SqCallStack); *sp = (unsigned char *) *(--SqCallStack); CallDepth--; EB.status = 1; } else { EB.status = SEQ_EXIT; //SeqActive = 0; //EB.status = 100; EB.OpCode = **sp; EB.TrSqState = 0; EB.TrSqAddr = (int) *sp; TSSActive = 0; } RBI_RTN = InstOp[0]; return EB; } //
struct ErrBlk TERM (unsigned char **sp) { struct ErrBlk EB; char *sqaddr; sqaddr = *sp; //SeqActive = 0; EB.status = SEQ_END; EB.OpCode = **sp; EB.TrSqState = 0; EB.TrSqAddr = (int) sqaddr; TSSActive = 0; return EB; } //
struct ErrBlk SQABORT (unsigned char **sp) { struct ErrBlk EB; EB.status = SEQ_ABORT + 1; EB.OpCode = **sp; EB.TrSqState = 0; TSSActive = 0; EB.TrSqAddr = (int) *sp; return EB; } /*---------------------------------------------------------------------- Timing Instructions: ------------------------------------------------------------------------*/ //
struct ErrBlk SRT (unsigned char **sp) { struct ErrBlk EB; TRefSec = lulobt; /* TRefSec = 0; */ EB.status = 0; EB.OpCode = **sp; EB.TrSqState = 11; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk DELAY (unsigned char **sp) { char *sqaddr; struct ErrBlk EB; int i; switch (DELAY_state) { case 0: curr_instr_addr = *sp - 1; //SeqReg[7] = (int) curr_instr_addr; GetOperands (sp, InstOp, OpRegn); DelayTime = InstOp[0]; next_instr_addr = *sp; //SeqReg[8] = (int) next_instr_addr; DELAY_state = 1; case 1: if (TickCount >= DelayTime) { TickCount = 0; *sp = next_instr_addr; DELAY_state = 0; } else *sp = curr_instr_addr; break; } //SeqReg[6] = DelayTime; sqaddr = *sp; EB.status = 51; EB.OpCode = **sp; EB.TrSqState = 31; EB.TrSqAddr = (int) sqaddr; return EB; } //
struct ErrBlk TIM (unsigned char **sp) { char *sqaddr; struct ErrBlk EB; int i; switch (TIM_state) { case 0: curr_instr_addr = *sp - 1; //SeqReg[7] = (int) curr_instr_addr; GetOperands (sp, InstOp, OpRegn); TimeOffset = InstOp[0]; next_instr_addr = *sp; //SeqReg[8] = (int) next_instr_addr; TIM_state = 1; // There is no "break" here to handle the case where Time Mark // has already passed. case 1: if (lulobt >= TRefSec + TimeOffset) { *sp = next_instr_addr; TIM_state = 0; } else *sp = curr_instr_addr; break; } //SeqReg[6] = TimeOffset; sqaddr = *sp; EB.status = 51; EB.OpCode = **sp; EB.TrSqState = 31; EB.TrSqAddr = (int) sqaddr; return EB; } //
struct ErrBlk WAIT (unsigned char **sp) { char *sqaddr; struct ErrBlk EB; int i; switch (WAIT_state) { case 0: curr_instr_addr = *sp - 1; GetOperands (sp, InstOp, OpRegn); WaitDur = InstOp[0]; if (0 == WaitDur) WaitDur = 1; // Wait Duration of 0 & 1 are same next_instr_addr = *sp; WAIT_state = 1; *sp = curr_instr_addr; break; case 1: if (0 == --WaitDur) { WAIT_state = 0; *sp = next_instr_addr; } else *sp = curr_instr_addr; break; } sqaddr = *sp; EB.status = 51; EB.OpCode = **sp; EB.TrSqState = 31; EB.TrSqAddr = (int) sqaddr; return EB; } //
struct ErrBlk NOI____ (unsigned char **sp) { struct ErrBlk EB; char *sqaddr; sqaddr = *sp; EB.status = 101; EB.TrSqState = 21; EB.TrSqAddr = (int) sqaddr; return EB; } /*-------------------------------------------------------------------------*/ // Make Camera Control Table void mk_cct (struct FRMDEFB *fb, struct CCD_CT *ct) { int summing_mode; if (fb->CameraMode <= 3) { summing_mode = (1 << fb->CameraMode); ct->xsum = summing_mode; ct->ysum = summing_mode; ct->ofst = 0; ct->len = 0; } else { ct->xsum = 1; ct->ysum = 1; ct->len = ExtractSize * 64; switch (fb->CameraMode) { case 4: ct->ofst = 512 - (ExtractSize * 32); PRVrow = 512; break; case 5: ct->ofst = PRVrow - (ExtractSize * 32); break; case 6: ct->ofst = RBI_MXR - (ExtractSize * 32); PRVrow = RBI_MXR; break; case 7: ct->ofst = RBI_MNR - (ExtractSize * 32); PRVrow = RBI_MNR; break; } } if (fb->RdoutAmp < 2) ct->amp = fb->RdoutAmp; } /*-----------------------------------------------------------------------*/ void set_exp (int ecword) { int exp_idx; if ((ecword & 0x4000) != 0) { // specific exposure pic_idx = ecword & 0x007f; // from bits 0-6 } else { // AEC Exposure WL_indx = (ecword & 0x0f80) >> 7; AEC_indx = (FrmPCT.TC << 5) | WL_indx; if ((ecword & 0x2000) != 0) exp_idx = (*(TS_AECT + AEC_indx)).DEF; else exp_idx = TS_AECT[AEC_indx].CUR; AEC_Offset = ecword & 0x003f; AEC_Offset_sign = ecword & 0x0040; if (AEC_Offset_sign) AEC_Offset = -AEC_Offset; exp_idx += AEC_Offset; if (exp_idx > MAX_EXP_INDEX) exp_idx = MAX_EXP_INDEX; if (exp_idx < 0) exp_idx = 0; pic_idx = exp_idx; } if ((ecword & 0x8000) != 0) shtr_md = 0; // dark frame else { shtr_md = 3; sh_exp = extab[pic_idx].exp; if (sh_exp) shtr_md = 1; } } /*-------------------------------------------------------------------------*/ unsigned long int GetStartAddr (struct FRMDEFB *fb, int an) { unsigned long int StartAddr; //int an; //unsigned long int camsz; unsigned int SumFactor; unsigned long int RowLen; unsigned long int NumRows; unsigned long int RowOffset, ColOffset; unsigned long int IMaxRow, IMaxCol; unsigned long int IMinRow, IMinCol; unsigned long int ES; unsigned long int maxA1RO; unsigned long int maxA1CO; unsigned int RotTrack; unsigned long int PntgLOBT; long int StartRow, EndRow; long int StartCol, EndCol; RowLen = RowLengths[fb->CameraMode]; if (4 == fb->SubArea[an].Ref) { A1RO = FrmPCT.SubArea[an].RowOffset; A1CO = FrmPCT.SubArea[an].ColOffset; A1RB = FrmPCT.SubArea[an].RowBlks; A1CB = FrmPCT.SubArea[an].ColBlks; } else { A1RO = fb->SubArea[an].RowOffset; A1CO = fb->SubArea[an].ColOffset; A1RB = fb->SubArea[an].RowBlks; A1CB = fb->SubArea[an].ColBlks; } if (0 == A1RB) A1RB = 16; if (0 == A1CB) A1CB = 16; //if (fb->CameraMode < 4) { // A1RO = A1RO >> fb->CameraMode; // A1CO = A1CO >> fb->CameraMode; // A1RB = A1RB >> fb->CameraMode; // A1CB = A1CB >> fb->CameraMode; // NumRows = 1024 >> fb->CameraMode; // } if (fb->CameraMode > 3) { ES = ExtractSize; A1RB = (A1RB > ES ? ES : A1RB); //maxA1RO = (ES - A1RB) << 5; //A1RO = (A1RO > maxA1RO ? maxA1RO : A1RO); A1CB = (A1CB > 16 ? 16 : A1CB); //maxA1CO = (16 - A1CB) << 5; //A1CO = (A1CO > maxA1CO ? maxA1CO : A1CO); NumRows = ES * 64; } else { SumFactor = 1 << fb->CameraMode; A1RB = (A1RB >= SumFactor ? A1RB : SumFactor); A1CB = (A1CB >= SumFactor ? A1CB : SumFactor); NumRows = 1024; } if (cct.amp & 1) { // if (fb->CameraMode < 4) camsz = 1024 / (fb->CameraMode + 1); // else camsz = fb->ExtractSize * 64; A1RO = - A1RO; A1CO = - A1CO; IMaxRow = NumRows - RBI_MXR; IMaxCol = (RowLen - 16) - RBI_MXC; IMinRow = NumRows - RBI_MNR; IMinCol = (RowLen - 16) - RBI_MNC; } else { // camsz = 0; IMaxRow = RBI_MXR; IMaxCol = RBI_MXC; IMinRow = RBI_MNR; IMinCol = RBI_MNC; } switch (fb->SubArea[an].Ref) { case 0: // if (fb->CameraMode > 3) RefRow = cct.len / 2; // else RefRow = (RowLen - 16) / 2; // RefCol = (RowLen - 16) / 2; RefRow = NumRows / 2; RefCol = 512; break; case 1: RefRow = prv_RefRow; RefCol = prv_RefCol; break; case 2: RefRow = IMaxRow; RefCol = IMaxCol; break; case 3: RefRow = IMinRow; RefCol = IMinCol; break; } prv_RefRow = RefRow; prv_RefCol = RefCol; StartRow = RefRow + A1RO - (A1RB * 32); if (StartRow < 0) StartRow = 0; EndRow = StartRow + (A1RB * 64); if (EndRow >= NumRows) StartRow = NumRows - (A1RB * 64); StartCol = RefCol + A1CO - (A1CB * 32); if (StartCol < 0) StartCol = 0; EndCol = StartCol + (A1CB * 64); if (EndCol >= 1024) StartCol = 1024 - (A1CB * 64); StartAddr = ((StartRow / cct.xsum) * RowLen) + (StartCol / cct.ysum) + 1300; //StartAddr = (((RefRow + A1RO - (A1RB * 32)) * RowLen) / cct.xsum) + // ((RefCol + A1CO - (A1CB * 32)) / cct.ysum) + 1300; return StartAddr; } /*-------------------------------------------------------------------------*/ /* Area Parameters: This function sets up the area parameters as per Table 17 of the TRACE Science Sequences document. Calling Seq: status = AreaParam (struct AREASPEC *ap, int an); where ap is a pointer to an area parameters structure an is the area number; 0=Full Camera, 1=Area 1, 2=area 2 */ int AreaParams (struct AREASPEC *ap, struct FRMDEFB *fb, int an) { int n; int num_rows, num_cols; if (0 == an) { /* Full Camera Output */ ap->out = fb->FullCamOP; ap->TMS = 0; if (1 == fb->DoTimeAvg) { ap->TMS = fb->TimeAvgIntrvl; if (0 == ap->TMS) ap->TMS = 16; ap->TM0 = ((TASample == 1)? 1:0); } ap->SA = 1300; ap->RL = RowLengths[fb->CameraMode]; if (fb->CameraMode > 3) ap->NR = cct.len; else ap->NR = ap->RL - 16; ap->NC = ap->RL - 16; ap->BM = 1 << fb->FullCamBin; if (1 == ap->BM) ap->BM = 0; ap->APID = AppIDSet[fb->FullCamOP]; if (fb->FullCamOP > 1) { if (0 == EventsFile[RBI_CBF]) ap->APID += (RBI_CBF * 2); // Correct apid for op to events buf else ap->APID = 0; } ap->CMP = (fb->FullCamOpFmt & 0x0100) >> 8; if (ap->CMP) { ap->QT_PCK = (fb->FullCamOpFmt & 0x0030) >> 4; ap->HT_LUT = (fb->FullCamOpFmt & 0x00C0) >> 6; ap->QM = fb->FullCamOpFmt & 0x000F; } else { ap->QT_PCK = (fb->FullCamOpFmt & 0x00F0) >> 4; ap->HT_LUT = fb->FullCamOpFmt & 0x000F; ap->QM = 0; } } else { n = an - 1; ap->out = fb->SubArea[n].OP; ap->TMS = 0; if (1 == an) { if (2 == fb->DoTimeAvg) { ap->TMS = fb->TimeAvgIntrvl; if (0 == ap->TMS) ap->TMS = 16; ap->TM0 = ((TASample == 1)? 1:0); } } ap->SA = GetStartAddr (fb, n); ap->RL = RowLengths[fb->CameraMode]; num_rows = A1RB * 64; //num_rows = fb->SubArea[n].RowBlks * 64; //if (0 == num_rows) num_rows = 1024; if (fb->CameraMode > 3) ap->NR = ((num_rows < cct.len) ? num_rows : cct.len); if (fb->CameraMode < 4) ap->NR = num_rows >> fb->CameraMode; num_cols = A1CB * 64; //num_cols = fb->SubArea[n].ColBlks * 64; //if (0 == num_cols) num_cols = 1024; if (fb->CameraMode > 3) ap->NC = ((num_cols < 1024) ? num_cols : 1024); if (fb->CameraMode < 4) ap->NC = num_cols >> fb->CameraMode; ap->BM = 1 << fb->SubArea[n].Bin; if (1 == ap->BM) ap->BM = 0; ap->APID = AppIDSet[fb->SubArea[n].OP]; if (fb->SubArea[n].OP > 1) { if (0 == EventsFile[RBI_CBF]) ap->APID += (RBI_CBF * 2); else ap->APID = 0; } ap->CMP = (fb->SubArea[n].OpFmt & 0x0100) >> 8; if (ap->CMP) { ap->QT_PCK = (fb->SubArea[n].OpFmt & 0x0030) >> 4; ap->HT_LUT = (fb->SubArea[n].OpFmt & 0x00C0) >> 6; ap->QM = fb->SubArea[n].OpFmt & 0x000F; } else { ap->QT_PCK = (fb->SubArea[n].OpFmt & 0x00F0) >> 4; ap->HT_LUT = fb->SubArea[n].OpFmt & 0x000F; ap->QM = 0; } } return 1; } /*-------------------------------------------------------------------------*/ void mk_ipb (struct FRMDEFB *fb, struct P1IPB *p1) { int i; unsigned long int evb; unsigned int evb_idx; unsigned long int binning; unsigned long int NPix; long int ExpT; unsigned int amp; amp = cct.amp & 1; // Currently selected amplifier PageIndx = 1 - PageIndx; p1->SPG = CamFrmPg[PageIndx]; for (i = 0; i < 4; i++) mp_hd2.b[i] = 0x40 | p1->SPG; mp_hd2.pg = (p1->SPG) << 3; p1->BPT = amp * 4; // cct.amp has been updated by a call to mk_cct p1->BPYO = cct.ofst; // These are only valid for modes 4-7. p1->BPYL = cct.len; if (fb->CameraMode < 4) { p1->BPT += fb->CameraMode; p1->BPYL = 1024 / (fb->CameraMode + 1); } i = AreaParams (&p1->FCP2P, fb, 0); i = AreaParams (&p1->A1P2P, fb, 1); i = AreaParams (&p1->A2P2P, fb, 2); if (0 == fb->EvtDetectArea) { p1->P1SA = p1->FCP2P.SA; p1->P1RL = p1->FCP2P.RL; p1->P1NR = p1->FCP2P.NR; p1->P1NC = p1->FCP2P.NC; p1->P1BF = p1->FCP2P.BM; } else { p1->P1SA = p1->A1P2P.SA; p1->P1RL = p1->A1P2P.RL; p1->P1NR = p1->A1P2P.NR; p1->P1NC = p1->A1P2P.NC; p1->P1BF = p1->A1P2P.BM; } /* evb_idx = (fb->EvtDetectArea ? fb->SubArea[0].Bin : fb->FullCamBin); evb = 1 << evb_idx; */ evb = p1->P1BF; if (0 == evb) evb = 1; ExpT = extab[pic_idx].actual; p1->SF = fb->DetectSuFlr; p1->SFHB = (((ULI) fb->SuFlrCntRate * ExpT * cct.xsum * cct.xsum) / 32768) + ((ADCoffset[amp][fb->CameraMode]) / 32); if (p1->SFHB > 127) p1->SFHB = 127; p1->SFHC = (fb->FlarePixCnt) / ((cct.xsum * cct.xsum) * (evb * evb)); p1->FF = fb->DetectFlare; p1->FHB = (((ULI)fb->FlareCntRate * ExpT * cct.xsum * cct.xsum) / 32768) + ((ADCoffset[amp][fb->CameraMode]) / 32); if (p1->FHB > 127) p1->FHB = 127; p1->FHC = (fb->FlarePixCnt) / ((cct.xsum * cct.xsum) * (evb * evb)); //CurrECW = fb->ExpCtrlWord; p1->AECX = (fb->ExpCtrlWord & 0x1000) >> 12; p1->AEHB = TS_AECT[AEC_indx].INH + (ADCoffset[amp][fb->CameraMode]/32); if (p1->AEHB > 127) p1->AEHB = 127; p1->AELB = TS_AECT[AEC_indx].INL + (ADCoffset[amp][fb->CameraMode]/32); //*(SeqReg+20) = 3; if (fb->EvtDetectArea == 0) { binning = 1 << fb->FullCamBin; NPix = (ULI) 1024 * ExtractSize * 64; } else { binning = 1 << fb->SubArea[0].Bin; NPix = (ULI) RowBlks[0] * ColBlks[0] * 4096; } p1->AELC = (NPix * TS_AECT[AEC_indx].PAL) / (100 * binning * binning); p1->AEHC = (NPix * TS_AECT[AEC_indx].PAH) / (100 * binning * binning); //*(SeqReg+20) = 4; p1->TF = fb->DetectTrans; p1->TMUL = fb->TransMult; p1->TPC = fb->TransPixCnt; p1->DT = fb->DarkTransient; p1->TAI = fb->TimeAvgIntrvl; if (0 == p1->TAI) p1->TAI = 16; p1->T0 = ((TASample == 1)? 1:0); p1->IMX = fb->LocateImax; p1->IMN = fb->LocateImin; } /*-------------------------------------------------------------------------*/ /*-----[SetupConfigParams]-------------------------------------------------*/ /* Decodes Frame Definition Block and Target Select tables to update */ /* configuration tables; */ /*-------------------------------------------------------------------------*/ // This function decodes the Frame Definition Block CurrFDB to update the // configuration tables. A telecommand to take a picture causes the // command processor to copy the "default" FDB to CurrFDB and append the // 'focus' and 'pzt_offset' parameters to the block. The sequence instruction // 'FRAME' causes the FDB specified by the fid to be copied to CurFDB // and also appends the PZT offset and focus information to the block. // For the purposes of this function CurrFDB is treated as a 18 word block. // void SetupConfigParams (struct FRMDEFB *fb) // int pindx, int fpos) { int i; int wl_indx; ExtractSize = (fb->ExtractSize ? fb->ExtractSize : 16); RowBlks[0] = (fb->SubArea[0].RowBlks ? fb->SubArea[0].RowBlks : 16); ColBlks[0] = (fb->SubArea[0].ColBlks ? fb->SubArea[0].ColBlks : 16); RowBlks[1] = (fb->SubArea[1].RowBlks ? fb->SubArea[1].RowBlks : 16); ColBlks[1] = (fb->SubArea[1].ColBlks ? fb->SubArea[1].ColBlks : 16); /* DecFrame (fb); */ if (fb->DoTimeAvg) TASample++; wl_indx = (fb->ExpCtrlWord & 0x0f80) >> 7; FrmWLT = TS_WLT[wl_indx]; if (FocusPos) { FrmWLT.FMA += FocusPos; FocusPos = 0; } pWLT = (unsigned int *) &FrmWLT; for (i = 0; i < 4; i++) ocb[i] = *pWLT++; set_exp (fb->ExpCtrlWord); mk_cct (fb, &cct); mk_ipb (fb, &DHCP1); } /*-----------------------------------------------------------------------*/ struct CCDLOC ccd_loc (unsigned long loc) { struct CCDLOC pos; unsigned long bf2; bf2 = 1 << DHCP1.P1BF; bf2 = bf2 * bf2; pos.Row = (((loc * bf2) / DHCP1.P1NC) + ((DHCP1.P1SA - 1300) / DHCP1.P1RL)) * cct.xsum + RefRow - (DHCP1.P1NR /2); pos.Col = (((loc * bf2) % DHCP1.P1NC) + ((DHCP1.P1SA - 1300)% DHCP1.P1RL)) * cct.ysum; /* Invert row and column numbers if B amplifier used for the image */ if (cct.amp & 1) { pos.Row = 1024 - pos.Row; pos.Col = 1024 - pos.Col; } return pos; } /*-----[ Frame ]---------------------------------------------------------*/ /* */ /* Copy specified FDB to CurrFDB */ /*-----------------------------------------------------------------------*/ //
struct ErrBlk FRAME (unsigned char **sp) { struct ErrBlk EB; struct FRMDEFB *save_fdbp; unsigned int fdbidx; int i; unsigned int numFDB; char *sq_addr; //int sht_rdo_xx; //sht_rdo_xx = 4; EB.status = 0; curr_instr_addr = *sp - 1; switch (tapt_state) { case 1: for (i = 0; i < 3; i++) InstOp[i] = 0xFFFF; GetOperands (sp, InstOp, OpRegn); next_instr_addr = *sp; fdbidx = InstOp[0]; if (InstOp[1] != 0xFFFF) PZTindx = InstOp[1]; if (InstOp[2] != 0xFFFF) FocusPos = InstOp[2]; //*(SeqReg+16) = 1; save_fdbp = 0; fdbp = FDBarray; while ((*fdbp).fid) { if (((*fdbp).fid & 0xFFF8) == (fdbidx & 0xFFF8)) save_fdbp = fdbp; fdbp -= 1; } if (save_fdbp != 0) fdbp = save_fdbp; if (save_fdbp != 0) { //CurrFDB = *fdbp; fdbp = save_fdbp; sa19.ksqfid = (*fdbp).fid; //CurrFDB.fid; SetupConfigParams (fdbp); //FDB gets decoded here req_ps1 = 1; tapt_state = 6; //It's a long story... *sp = curr_instr_addr; EB.status = 52; EB.TrSqState = SEQ_WAIT_DEV; //*(SeqReg+16) = 2; } else { fdbp = FDBarray; EB.status = UNDEFINED_FDB; EB.OpCode = TSRopcode; EB.param = (*fdbp).fid; //CurrFDB.fid; EB.TrSqAddr = (int) *sp; *sp = next_instr_addr; EB.TrSqState = SEQ_RUN; //*(SeqReg+16) = 103; } break; /* case 5: if (sht_rdo & 0x13) tapt_state = 6; // Frame in progress *sp = curr_instr_addr; break; */ case 6: if (DHCRes.NewRes) { DHCRes.NewRes = 0; tapt_state = 1; // INT 1 recieved from DHC *sp = next_instr_addr; bad_pic = 0; /* Frame Post Processing */ // If STOPSeq flag is set ABORT sequence if (DHCRes.STOPSeq) { EB.status = 512; EB.OpCode = **sp; EB.TrSqAddr = (int) *sp; EB.param = DHCRes.STOPSeq; return EB; } // if MX set, Update IMAX location if ((fdbp->LocateImax) || (DHCRes.TransEvt)) { MaxLoc = ccd_loc (DHCRes.IMaxLoc); RBI_MXR = MaxLoc.Row; RBI_MXC = MaxLoc.Col; } // if MN set, Update IMIN location if ((fdbp->LocateImin) || (DHCRes.TransEvt)) { MinLoc = ccd_loc (DHCRes.IMinLoc); RBI_MNR = MinLoc.Row; RBI_MNC = MinLoc.Col; } // if AEC-ADJUST set, adjust AEC exposure switch (DHCRes.AECAdjust) { case 1: TS_AECT[AEC_indx].CUR += TS_AECT[AEC_indx].SUP; if (TS_AECT[AEC_indx].CUR > MAX_EXP_INDEX) TS_AECT[AEC_indx].CUR = MAX_EXP_INDEX; break; case -1: if (TS_AECT[AEC_indx].CUR > TS_AECT[AEC_indx].SDN) TS_AECT[AEC_indx].CUR -= TS_AECT[AEC_indx].SDN; else TS_AECT[AEC_indx].CUR = 0; // smallest possible break; default: break; } // Update Event Flags (FLARE, SUPERFLARE and TRANSIENT) if (fdbp->DetectFlare) RBI_FEF = DHCRes.FlareEvt; if (fdbp->DetectSuFlr) RBI_SEF = DHCRes.SuFlareEvt; if (fdbp->DetectTrans) RBI_TEF = DHCRes.TransEvt; EB.status = 1; } else { *sp = curr_instr_addr; EB.status = 52; if (!(pic_stt & 0x000f)) { *sp = next_instr_addr; tapt_state = 1; EB.status = PIC_TIMEOUT; } } break; } EB.OpCode = **sp; EB.TrSqAddr = (int) *sp; return EB; } /*-----[ TAPT ]------------------------------------------------------------*/ /* */ /* Sends a request to the CC to take a picture */ /* Waits for Frame Gate Interrupt */ /* Outputs DHC processing parameters to the Parameter Exchange Area */ /* Waits for DHC phase 1 Completion interrupt */ /* Reads in the phase 1 processing results */ /* Continues.. */ /*.........................................................................*/ struct ErrBlk TAP (unsigned char **sp) { struct ErrBlk EB; extern PXdone; char *sq_addr; sq_addr = *sp - 1; switch (tapt_state) { case 1: req_ps1 = 1; tapt_state = 6; break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: //if (PXdone) { // PXdone = 0; tapt_state = 1; // } break; } if (tapt_state != 1) *sp = sq_addr; // EB.status = 52; EB.OpCode = 0x05; EB.TrSqState = tapt_state+10; EB.TrSqAddr = (int) *sp; return EB; } /*-----[ SETTARG ]---------------------------------------------------------* Argument: 1. Target Index Register or Immediate Value /*.........................................................................*/ //
struct ErrBlk STTG (unsigned char **sp) { void wedgeC(unsigned int *); struct ErrBlk EB; unsigned int wdgpos[2]; unsigned int rnum; unsigned int TargetIDLo; unsigned int TargetIDHi; int i; unsigned int slewflag; switch (STTG_state) { case 0: curr_instr_addr = *sp - 1; for (i = 0; i < 3; i++) InstOp[i] = 0xFFFF; GetOperands (sp, InstOp, OpRegn); TargIndx = InstOp[0]; TargetIDLo = InstOp[0]; //TargetIDHi = InstOp[1]; next_instr_addr = *sp; // *(SeqReg+18) = rnum; // *(SeqReg+17) = TargIndx; TargIndx = 0; while ( (TargetIDLo != TS_PCT[TargIndx].TID_l) && (TargIndx < NUMPTG) ) TargIndx++; if (NUMPTG == TargIndx) { TargIndx = 0; EB.status = TARGET_NOT_FOUND; *sp = next_instr_addr; } else { FrmPCT = TS_PCT[TargIndx]; wdgpos[0] = FrmPCT.W1; wdgpos[1] = FrmPCT.W2; sa19.ksqtarg = FrmPCT.TID_l; sa19.ksqtarg |= (unsigned long int) FrmPCT.TID_h << 16; RBI_TRC = FrmPCT.TC; wedgeC (wdgpos); STTG_state = 1; sttg_delay = slew_delay; *sp = curr_instr_addr; EB.status = 52; EB.TrSqState = SEQ_WAIT_DEV; EB.TrSqAddr = (int) *sp; } break; case 1: *sp = curr_instr_addr; EB.status = 52; EB.TrSqState = SEQ_WAIT_DEV; slewflag = sa1D.flag & 0x0200; if (slewflag == 0) STTG_state = 2; break; case 2: if (sttg_delay > 0) sttg_delay -= 1; if (sttg_delay == 0) { STTG_state = 0; *sp = next_instr_addr; EB.status = 0; EB.TrSqState = SEQ_RUN; } else { *sp = curr_instr_addr; EB.status = 52; EB.TrSqState = SEQ_WAIT_DEV; } break; } EB.TrSqAddr = (int) *sp; return EB; } /* Set readout amplifier and offset Call SAMP amplifier(0|1) offset(0-15) Opcodes - 91, 95, 99 and 9D */ //
struct ErrBlk SAMP (unsigned char **sp) { struct ErrBlk EB; GetOperands (sp, InstOp, OpRegn); if (InstOp[0] < 2) cct.amp = InstOp[0]; if (InstOp[1] < 16) cct.ofstab[cct.amp & 1] = InstOp[1] - 1; EB.status = 0; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk CLL (unsigned char **sp) { unsigned char *SqPtr (unsigned long id); struct ErrBlk EB; unsigned int CallAddr; int i; int *ptr; unsigned long SqID; GetOperands (sp, InstOp, OpRegn); SqID = *( (unsigned long *) &InstOp[0]); CallAddr = (unsigned int) SqPtr (SqID); if (CallAddr == 0xFFFF) { EB.status = SEQ_NOT_FOUND; return EB; } if (CallDepth < MAX_CALL_DEPTH) { *SqCallStack++ = (int) *sp; /* save pc */ ptr = (int *) &SeqID; *SqCallStack++ = *ptr++; /* save SID */ *SqCallStack++ = *ptr; /* save SID */ ptr = (int *) &TickCount; *SqCallStack++ = *ptr++; /* save SID */ *SqCallStack++ = *ptr; /* save SID */ ptr = (int *) &TRefSec; *SqCallStack++ = *ptr++; /* save SID */ *SqCallStack++ = *ptr; /* save SID */ CallDepth++; for (i = 0; i < NLCLREG; i++) *SqCallStack++ = *(SeqReg + i); /* save local registers */ *SqCallStack++ = BlkRptCount; *sp = seq + CallAddr; /* Set pc to call address */ EB.status = 1; } else { EB.status = SEQ_STACK_DEPTH_EXCEEDED; EB.OpCode = **sp; EB.TrSqState = 0; EB.TrSqAddr = (int) *sp; TSSActive = 0; } EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk RET (unsigned char **sp) { struct ErrBlk EB; int i; int *ptr; if (CallDepth != 0) { BlkRptCount = *(--SqCallStack); for (i = NLCLREG-1; i >= 0; i--) *(SeqReg + i) = *(--SqCallStack); ptr = (int *) &TRefSec; ptr++; *ptr-- = *(--SqCallStack); *ptr = *(--SqCallStack); ptr = (int *) &TickCount; ptr++; *ptr-- = *(--SqCallStack); *ptr = *(--SqCallStack); ptr = (int *) &SeqID; ptr++; *ptr-- = *(--SqCallStack); *ptr = *(--SqCallStack); *sp = (unsigned char *) *(--SqCallStack); CallDepth--; EB.status = 1; } else { EB.status = SEQ_EXIT; //SeqActive = 0; //EB.status = 100; EB.OpCode = **sp; EB.TrSqState = 0; EB.TrSqAddr = (int) *sp; TSSActive = 0; } EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk SID (unsigned char **sp) { struct ErrBlk EB; int i; GetOperands (sp, InstOp, OpRegn); //*(SeqReg + 23) = InstOp[0]; //*(SeqReg + 24) = InstOp[1]; SeqID = *((long *)(&InstOp[0])); EB.TrSqAddr = INT_OP; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk NOID (unsigned char **sp) { struct ErrBlk EB; int i; //GetOperands (sp, InstOp, OpRegn); //*(SeqReg + 23) = InstOp[0]; //*(SeqReg + 24) = InstOp[1]; //SeqID = *((long *)(&InstOp[0])); EB.TrSqAddr = INT_OP; EB.TrSqAddr = INT_OP; EB.TrSqAddr = INT_OP; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk TIMCHK (unsigned char **sp) { struct ErrBlk EB; GetOperands (sp, InstOp, OpRegn); if ((TRefSec + InstOp[0]) < lulobt) *(SeqReg + OpRegn[1]) = -1; if ((TRefSec + InstOp[0]) == lulobt) *(SeqReg + OpRegn[1]) = 0; if ((TRefSec + InstOp[0]) > lulobt) *(SeqReg + OpRegn[1]) = 1; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk DEV (unsigned char **sp) { struct ErrBlk EB; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk LOCKBUF (unsigned char **sp) { struct ErrBlk EB; int nxtflb; if (RBI_NBF) { EventsFile[RBI_CBF] = 1; // Event File Locked; RBI_CBF = (RBI_CBF + 1) % 4; RBI_NBF -= 1; // This has to be reset EB.status = 1; } else EB.status = 51; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk RESETAEC (unsigned char **sp) { struct ErrBlk EB; int i; for (i = 0; i < 128; i++) TS_AECT[i].CUR = TS_AECT[i].DEF; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk STARTAVE (unsigned char **sp) { struct ErrBlk EB; TASample = 0; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk UPDIMX (unsigned char **sp) { struct ErrBlk EB; if (DHCRes.IMaxValid) { MaxLoc = ccd_loc (DHCRes.IMaxLoc); RBI_MXR = MaxLoc.Row; RBI_MXC = MaxLoc.Col; } EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk NOOP (unsigned char **sp) { struct ErrBlk EB; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } /* LDA - Load register from address */ //
struct ErrBlk LDA (unsigned char **sp) { struct ErrBlk EB; int numops; GetOperands (sp, InstOp, OpRegn); *(SeqReg + OpRegn[0]) = *(int *)InstOp[1]; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } /* LDR - Load register from register specified by source reg */ //
struct ErrBlk LDR (unsigned char **sp) { struct ErrBlk EB; int numops; int RNum; GetOperands (sp, InstOp, OpRegn); RNum = *(SeqReg + OpRegn[1]); *(SeqReg + OpRegn[0]) = *(SeqReg + RNum++); *(SeqReg + OpRegn[1]) = RNum; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } /* SETREGS - Load a block of registers with immediate values */ //
struct ErrBlk SETREGS (unsigned char **sp) { struct ErrBlk EB; unsigned int RNum; unsigned int NumReg; int i; GetOperands (sp, InstOp, OpRegn); RNum = (OpRegn[0] == 0xFFFF ? InstOp[0] : OpRegn[0]); //RNum = InstOp[0]; NumReg = InstOp[1]; for (i = 0; i < NumReg; i++) *(SeqReg + RNum++) = INT_OP; EB.status = 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
/* RQP - Runs a DHC Queue Program */ struct ErrBlk RUNDHCP(unsigned char **sp) { struct ErrBlk EB; GetOperands (sp, InstOp, OpRegn); runmac (&InstOp[0]); EB.status = SEQ_BREAK + 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
/* SETDHR - Sets a DHC Regsiter to specified value */ struct ErrBlk SETDHCR (unsigned char **sp) { struct ErrBlk EB; GetOperands (sp, InstOp, OpRegn); ipreg (&InstOp[0]); EB.status = SEQ_BREAK + 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
/* OPENLOOP - Opens ISS Loop */ struct ErrBlk OPENLOOP (unsigned char **sp) { struct ErrBlk EB; opnLT (1); // Opens loop, Lowers gains, no auto close EB.status = SEQ_BREAK + 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
/* SETDHR - Closes ISS Loop */ struct ErrBlk CLOSELOOP (unsigned char **sp) { struct ErrBlk EB; clsLT (); EB.status = SEQ_BREAK + 1; EB.OpCode = TSRopcode; EB.TrSqAddr = (int) *sp; return EB; } //
struct ErrBlk (*func[256])(unsigned char **) = { BRANCHIF, ADD, BRANCHIF, ADD, NOI____, ADD, NOI____, ADD, //00 01 02 03 04 05 06 07 BRANCHIF, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //08 09 0a 0b 0c 0d 0e 0f BRANCHIF, SUB, BRANCHIF, SUB, NOI____, SUB, NOI____, SUB, //10 11 12 13 14 15 16 17 BRANCHIF, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //18 19 1a 1b 1c 1d 1e 1f BRANCHIF, MUL, BRANCHIF, MUL, NOI____, MUL, NOI____, MUL, //20 21 22 23 24 25 26 27 BRANCHIF, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //28 29 2a 2b 2c 2d 2e 2f BRANCHIF, DIV, BRANCHIF, DIV, NOI____, DIV, NOI____, DIV, //30 31 32 33 34 35 36 37 BRANCHIF, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //38 39 3a 3b 3c 3d 3e 3f BRANCHIF, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //40 41 42 43 44 45 46 47 BRANCHIF, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //48 49 4a 4b 4c 4d 4e 4f BRANCHIF, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //50 51 52 53 54 55 56 57 BRANCHIF, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //58 59 5a 5b 5c 5d 5e 5f NOI____, NOI____, NOI____, NOI____, NOI____, NOI____, NOI____, NOI____, //60 61 62 63 64 65 66 67 NOI____, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //68 69 6a 6b 6c 6d 6e 6f FRAME, NOI____, FRAME, NOI____, FRAME, NOI____, FRAME, NOI____, //70 71 72 73 74 75 76 77 FRAME, NOI____, FRAME, NOI____, FRAME, NOI____, FRAME, NOI____, //78 79 7a 7b 7c 7d 7e 7f SET, CLL, BRANCHIF, STTG, SET, CLL, NOI____, STTG, //80 81 82 83 84 85 86 87 NOI____, CLL, BRANCHIF, STTG, NOI____, CLL, NOI____, STTG, //88 89 8a 8b 8c 8d 8e 8f BRANCHIF, SAMP, TIMCHK, SETREGS, NOI____, SAMP, NOI____, SETREGS, //90 91 92 93 94 95 96 97 BRANCHIF, SAMP, TIMCHK, SETREGS, NOI____, SAMP, NOI____, SETREGS, //98 99 9a 9b 9c 9d 9e 9f SID, LDA, SETDHCR, LDR, SID, LDA, SETDHCR, NOI____, //a0 a1 a2 a3 a4 a5 a6 a7 SID, NOI____, SETDHCR, NOI____, SID, NOI____, SETDHCR, NOI____, //a8 a9 aa ab ac ad ae af TIM, EXIT, DELAY, RUNDHCP, WAIT, NOI____, STTG, NOI____, //b0 b1 b2 b3 b4 b5 b6 b7 TIM, EXIT, DELAY, RUNDHCP, WAIT, NOI____, STTG, NOI____, //b8 b9 ba bb bc bd be bf FRAME, NOI____, BRANCHIF, NOI____, NOI____, NOI____, INC, NOI____, //c0 c1 c2 c3 c4 c5 c6 c7 FRAME, NOI____, BRANCHIF, NOI____, NOI____, NOI____, NOI____, NOI____, //c8 c9 ca cb cc cd ce cf DEC, NOI____, SID, NOI____, NOI____, NOI____, NOI____, NOI____, //d0 d1 d2 d3 d4 d5 d6 d7 NOI____, NOI____, NOI____, NOI____, NOI____, NOI____, NOI____, NOI____, //d8 d9 da db dc dd de df RET, NOID, TERM, NOI____, SQABORT, NOI____, NOI____, NOI____, //e0 e1 e2 e3 e4 e5 e6 e7 SRT, NOI____, TAP, NOI____, LOCKBUF, OPENLOOP, RESETAEC, CLOSELOOP, //e8 e9 ea eb ec ed ee ef STARTAVE, NOI____, UPDIMX, NOI____, NOI____, NOI____, NOI____, NOI____, //f0 f1 f2 f3 f4 f5 f6 f7 NOI____, NOI____, NOI____, NOI____, NOI____, NOI____, NOI____, NOOP}; //f8 f9 fa fb fc fd fe ff //