;
; This file contains all the standard dhc programs for trace. These include the normal ; science data program, the jitter mode program, and the table load program. ; Addresses and register numbers are in hex unless otherwise noted. The dimension of regblk's, ; which are decimal unless otherwise noted. ; This first section handles Phase 0. The standard CCD frame invokes the program whose vector ; is at 0. Vector zero must be loaded with 100. Regsiters 400-40f are reserved for phase 0 ; activities. Phase 0 gets the ccd temperatures, transfers them to the CC side of the Data ; Transfer buffer (DTB), asserts an interrupt with code 0, and ends. ; ; Version 1.29 .... Fixed bug in register dump (missing endmac) ; See file dhc_que_RevisionSummary.txt for development summary .ORG 0x100 0 .RORG PARAM 0x400 REGBLK $PARAM AVGT_PRM[3] .RORG ZERO 0 REGDEF $ZERO ABS REGBLK $ZERO CCDTEMPS[20] REGEQU $ABS+0X1E NORMALMODE REGEQU $ABS+0X1F TESTMODE .RORG TEST 0x90 REGDEF $TEST AVGTESTFLAG SETREGS $AVGT_PRM 3 0x134L 0x0c CCDADDR $AVGT_PRM+1 AVGTEMPS $AVGT_PRM DTBOUT $CCDTEMPS 0x14 SETREG $NEWFRAME 1 ; Indicate a new frame has arrived BRANCHNE $TESTMODE 0xFFF0 &P0_10 ; TestMode flag for phase 0 error (Vr1.21) THROW 0xFFF0 ; (Vr 1.21) P0_10: SETIRPT 0 ENDMAC ; Phase I results are in 12 registers starting at 28e. REGBLK 0x028E P1_RESULTS[12] ; Equates for readbility REGEQU $P1_RESULTS P1_RESULT_FF REGEQU $P1_RESULTS+1 P1_RESULT_SF REGEQU $P1_RESULTS+2 P1_RESULT_TF REGEQU $P1_RESULTS+3 P1_RESULT_AEF REGEQU $P1_RESULTS+4 P1_RESULT_IMXV REGEQU $P1_RESULTS+5 P1_RESULT_IMXL REGEQU $P1_RESULTS+7 P1_RESULT_IMNV REGEQU $P1_RESULTS+8 P1_RESULT_IMNL ; The status and control block from the CC begins at 103. A Sync and type are inserted in the 3 ; words before the IPB to make the Data Product Header, which thus begins at 100. REGBLK 0x0100 DP_HDR[505] ; These register equivalences are defined for make the code more ; readable and less suspectable to typos. REGEQU $DP_HDR+3 CC_INBLK ; the input block is 3 words down from header start REGEQU $CC_INBLK CC_TIMEWORDS ; REGEQU $CC_INBLK+291 FDB REGEQU $FDB+1 FDB_CMMODEWORD ; FDB word containing the camera mode field (Vr 1.26) REGEQU $FDB+3 FDB_SAFEFLAGWORD ; FDB word containing the safety flag bit (Vr 1.26) REGEQU $CC_INBLK+307 IPB REGEQU $IPB+1 IPB_BPT REGEQU $IPB+2 IPB_BPYO REGEQU $IPB+3 IPB_BPYL REGEQU $IPB+4 IPB_P1SA REGEQU $IPB+6 IPB_P1NC REGEQU $IPB+7 IPB_P1NR REGEQU $IPB+8 IPB_P1RL REGEQU $IPB+9 IPB_P1BF REGEQU $IPB+10 IPB_SF REGEQU $IPB+11 IPB_SFHB REGEQU $IPB+12 IPB_SFHC REGEQU $IPB+14 IPB_FF REGEQU $IPB+15 IPB_FHB REGEQU $IPB+16 IPB_FHC REGEQU $IPB+18 IPB_AECX REGEQU $IPB+19 IPB_AEHB REGEQU $IPB+20 IPB_AEHC REGEQU $IPB+22 IPB_AELB REGEQU $IPB+23 IPB_AELC REGEQU $IPB+25 IPB_TF REGEQU $IPB+26 IPB_TMUL REGEQU $IPB+27 IPB_TPC REGEQU $IPB+29 IPB_DT REGEQU $IPB+30 IPB_TAI REGEQU $IPB+31 IPB_T0 REGEQU $IPB+32 IPB_IMX REGEQU $IPB+33 IPB_IMN REGEQU $IPB+40 IPB_FCO REGEQU $IPB+56 IPB_A1O REGEQU $IPB+72 IPB_A2O REGEQU $DP_HDR+417 PURGEBLOCK ; 8 word purge table block REGEQU $DP_HDR+424 PURGENUMBER ; Number of blocks (8K) to purge REGEQU $DP_HDR+425 APID0_COUNT ; Counts APID0 Errors (Vr1.23) REGEQU $DP_HDR+426 SAFE_BLK ; CCD_Safety Block (Vr1.26) REGEQU $SAFE_BLK SAFE_SCOUNT ; Safe Frame Counter (Vr1.26) REGEQU $SAFE_BLK+1 SAFE_DCOUNT ; Danger Frame Counter (Vr1.26) REGEQU $SAFE_BLK+2 SAFE_STHRSH ; Safe Frame Counter Threshold (Vr1.26) REGEQU $SAFE_BLK+3 SAFE_DTHRSH ; Danger Frame Counter Threshold(Vr1.26) REGEQU $SAFE_BLK+4 SAFE_1X1THR ; safety check 1x1 thresh (Vr1.26) REGEQU $SAFE_BLK+5 SAFE_2X2THR ; safety check 2X2 thresh (Vr1.26) REGEQU $SAFE_BLK+6 SAFE_4X4THR ; safety check 4X4 thresh (Vr1.26) REGEQU $SAFE_BLK+7 SAFE_8X8THR ; safety check 8x8 thresh (Vr1.26) REGEQU $SAFE_BLK+8 SAFE_1X1BIN ; safety check 1x1 BIN (Vr1.26) REGEQU $SAFE_BLK+9 SAFE_2X2BIN ; safety check 2X2 BIN (Vr1.26) REGEQU $SAFE_BLK+10 SAFE_4X4BIN ; safety check 4X4 BIN (Vr1.26) REGEQU $SAFE_BLK+11 SAFE_8X8BIN ; safety check 8x8 BIN (Vr1.26) REGEQU $SAFE_BLK+12 SAFE_HISTTHR ; safety check Histogram thresh (Vr1.26) REGEQU $SAFE_BLK+13 SAFE_PLACEH ; Place holder since thr is long(Vr1.26) ; ********************* TEST vs. NORMAL MODE CONTROLS **************************** ; The normal and test flags are redundant control of testmode. For testmode to execute, normal ; mode must be 0 and test mode must be non-zero. Test mode outputs the source images page as a ; full 1033 by 1040 image with header regardless of the settings of the Image Processing Block. ; ******************* Phase 1-2 common parameters **************** ; ; The registers from 800-8ff are for parameters common to phase 1 and 2. The ones defined here ; are like globals in that there are used by multiple routines. There are additional P1_P2 ; parameters that are used inside particular routines. Those are defined within the routines. .RORG P1_P2 0x800 ; 256 registers are reserved for inter-phase parameters REGDEF $P1_P2 CCDPAGE ; Holds the page number REGBLK $P1_P2 DPLENGTH[2] ; Carries the data product length REGBLK $P1_P2 XYRLEN[3] ; 3 length words for various instructions REGBLK $P1_P2 TRANSDPL[2] ; Transient length (in case done in phase 1) REGBLK $P1_P2 TRANSXYR[3] ; Tranient XYR lengths REGDEF $P1_P2 TRANSDONE ; true if transient average completed in phase 1 REGBLK $P1_P2 BINEXTADD ; address of binext params for binextsub REGDEF $P1_P2 AVGCOUNT ; Counts samples in an average REGDEF $P1_P2 NEWFRAME ; set to 1 in phase 0 and cleared in phase 1 REGBLK $P1_P2 FLOGGER[11] ; for a scaledsum done for EMI testing REGDEF $P1_P2 PURGECOUNT ; Counts number of 8K purgetabs done ; ****************** Phase 1 parameters ************************ ; ; The registers from 420 - 5FF are for parameters used during phase 1. The ones defined here ; Are like globals in that they are used by mulitple routines. There are additional P1_PARAMS ; parameters that are used within particular routines. Those are defined within the routines. .RORG P1_PARAMS 0x420 ; Parameter Area for Phase I REGDEF $P1_PARAMS P1_BADFLAG REGDEF $P1_PARAMS P1_BADPIX REGDEF $P1_PARAMS P1_DOSOME REGDEF $P1_PARAMS P1_BINFLAG REGDEF $P1_PARAMS P1_HISTFLAG REGDEF $P1_PARAMS P1_TRANSFLAG REGDEF $P1_PARAMS P1_EVENTFLAG REGDEF $P1_PARAMS P1_EVENT REGDEF $P1_PARAMS P1_IMAXFLAG REGBLK $P1_PARAMS P1_AVGMOVE[6] ; used to move the averaged data REGBLK $P1_PARAMS P1_HISTOUT[262] ; the output from HIST128 REGEQU $P1_HISTOUT+256 P1_HIMINVAL REGEQU $P1_HISTOUT+257 P1_HIMINLOC REGEQU $P1_HISTOUT+259 P1_HIMAXVAL REGEQU $P1_HISTOUT+260 P1_HIMAXLOC REGDEF $P1_PARAMS P1_FLAREVNT ; True if FF or SF detected REGBLK $P1_PARAMS P1_FINDIMIN[3] REGEQU $P1_FINDIMIN+1 P1_FINDIMINLOC REGBLK $P1_PARAMS P1_FINDIMAX[3] REGEQU $P1_FINDIMAX+1 P1_FINDIMAXLOC REGBLK $P1_PARAMS P1_TRANSCOUNT[2] ; Result from TRANSDETECT REGDEF $P1_PARAMS P1_TRANSFIRST ; 1 if this is the first transient REGDEF $P1_PARAMS P1_TEMP ; For timeword swap (Vr1.21) REGDEF $P1_PARAMS P1_SAFECHK ; Set by FlagSub if FDB danger set(Vr1.26) ; ******************* Phase I ; This is the main program invoked by the CC via a BeginMac using Vector 1. The start address is 180, ; so vector 1 must be loaded with this value. This section of the program is more or less like main. ; First, the CCD Page address is copied from the phase 0 location to a phase I-II location. This ; is to make sure we don't lose that address to a new frame. The program then calls a phase I routine. ; Upon return, the phase I results are tranferred to the CC side of the DTB, and an interrupt is ; asserted with code 1. When the CC resumes the queue, the program calls the phase II routine. ; Upon return, it asserts an interrupt with code 2, and ends when the CC resumes the queue. Most of ; the action happens in the phase I and II routines. .ORG 0x0180 1 OBSERVING_MAIN: SETREG $NEWFRAME 0 COPYREG $AVGT_PRM+1 $CCDPAGE ; Save CCD frame address CALLQUE &InitLiteralSub ; Initialize Literals CALLQUE &DoPhase1Sub ;Call the Phase I routine BRANCHNE $TESTMODE 0xFFF1 &Main_10 ; TestMode flag for phase 1 error (Vr1.21) THROW 0xFFF1 ; (Vr1.21) Main_10: BRANCHNE $TESTMODE 0xFFFC &Main_20 ; Flag value to test safety mode(Vr1.22) SETREG $P1_RESULTS+11 1 THROW 0xCCD0 ; (Vr1.26) Main_20: DTBOUT $P1_RESULTS 0x0C ;transfer 12 words of phase I results to CC. SETIRPT 1 ;assert the phase I interrupt CALLQUE &DoPhase2Sub ;Call the Phase II section Main_80: ; top of emi test loop BRANCHNE $NORMALMODE 1 &Main_90 ; is this the special EMI testmode? BRANCHNE $TESTMODE 0xFFFE &Main_90 ; We are in EMI testmode (flog it) .. execute a scaledsum until the next frame BRANCHNE $NEWFRAME 0 &Main_99 ; If a new frame is in, stop flogging SETREGS $FLOGGER 11 2:0 7:0 6:0 0 1 1 1 0x10 ; flog is a 64K scalesum SCALESUM $FLOGGER GOTO &Main_80 ; Here we purge the tables page unless the testmode flag is 0xFFFD ; Purge 8k at a time until all is done or the next picture arrives Main_90: BRANCHNE $NORMALMODE 1 &Main_99 ; skip if not normal mode BRANCHEQ $TESTMODE 0xFFFD &Main_99 ; or if testmode fffd SETREG $PURGECOUNT 96 ; purge no more than a full page Main_95: ; top of purge loop SETREG $PURGENUMBER 1 ; purge 8K each time PURGETAB $PURGEBLOCK ; this is the purge BRANCHNE $NEWFRAME 0 &Main_99 ; if there's a new picture, exit ADDREGD $PURGECOUNT -1 ; decrease the count BRANCHGT $PURGECOUNT 96 &Main_99 ; bound check (limit to initial value) BRANCHGT $PURGECOUNT 0 &Main_95 ; repeat if page not alll swept ; Picture Processing is complete Main_99: BRANCHNE $TESTMODE 0xFFF2 &Main_100 ; TestMode flag for phase 2 error (Vr1.21) THROW 0xFFF2 ; (Vr 1.21) Main_100: SETIRPT 2 ;Assert the Phase II interrupt ENDMAC ;That's it ; This is the main Phase I routine. It is invoked from TakePicture main via call queue. .ORG 0x200 DoPhase1Sub: DTBIN $CC_INBLK 0x18A ;(394 words from add 259) ; read in the CC data block COPYREG $CC_TIMEWORDS $P1_TEMP ; swap timewords 1 and 3 (VR 1.21) COPYREG $CC_TIMEWORDS+2 $CC_TIMEWORDS COPYREG $P1_TEMP $CC_TIMEWORDS+2 ; If the normal mode flag is 0 and the test mode flag is FFFF, branch to test mode. ; This double check prevents the program from reverting to test mode by a single hit. BRANCHNE $TESTMODE 0xFFFF &P1_NormalMode BRANCHIF $NORMALMODE &P1_TestMode ; This is the normal mode code P1_NormalMode: CALLQUE &P1_InitSub ; Initialization (TBD) CALLQUE &P1_FlagSub ; Setup a few easily testable flags BRANCHGT $IPB_BPT 7 &P1_BadDone ; Bp value must be 0 - 7 BRANCHLT $IPB_BPT 0 &P1_BadDone BRANCHEQ $TESTMODE 0xFFFD &P1_BadDone ; Skip Bad is testMode is FFFD CALLQUE &P1_BadPixSub P1_BadDone: BRANCHIF $P1_SAFECHK &P1_SafetyDone ; is safety check requested (Vr1.26) CALLQUE &P1_SafetySub ; call the safety check routine (Vr1.26) P1_SafetyDone: BRANCHIF $P1_DOSOME &P1_AllDone ;If DOSOME is 0, there's no Further Phase I SETREG $BINEXTADD $IPB_P1SA ; set the address of the bin/ext params CALLQUE &BinExtSub ; call the P1-P2 common binext routine BRANCHIF $P1_HISTFLAG &P1_HistDone ; do the histogram routine if required CALLQUE &P1_HistSub BRANCHNE $P1_EVENTFLAG 0 &P1_AllDone ; If there's an event, we're done P1_HistDone: BRANCHIF $P1_TRANSFLAG &P1_TransDone ;do the transient, if requested CALLQUE &P1_TransSub BRANCHNE $P1_EVENTFLAG 0 &P1_AllDone ; If there's an event, we're done P1_TransDone: BRANCHNE $P1_HISTFLAG 0 &P1_AllDone ; if histogram, IMX already done BRANCHIF $P1_IMAXFLAG &P1_AllDone ; If there's IMAX request, do it CALLQUE &P1_ImaxSub P1_AllDone: ; That's it for Phase I RTNQUE ; Phase I Normal Mode Subroutines ;
; Phase IInitialization Subroutine ... Clears various parameters P1_InitSub: SETREGS $P1_RESULTS 12 0 0 0 0 0 0 0 0 0 0 0 0 ; Clear phase 1 results BRANCHNE $TESTMODE 0xFFFC &P1_In05 ; Flag value to test safety mode (1.22) SETREG $P1_RESULTS+11 1 P1_In05: SETREGS $P1_BADFLAG 9 0 0 0 0 0 0 0 0 0 ; Clear Flags SETREG $TRANSDONE 0 ; clear transient done flag BRANCHIF $IPB_TF &P1_In20 ; is transient requested? BRANCHNE $IPB_T0 0 &P1_In10 ; yes .. 1st sample? BRANCHNE $AVGCOUNT 0 &P1_In20 ; not first, is it a restart SETREG $P1_TRANSFIRST 0 ; clear first sample flag GOTO &P1_In20 P1_In10: SETREG $P1_TRANSFIRST 1 ; 1st tran. set the first flag P1_In20: RTNQUE ;
; Flags Subroutine ... ; Examine the IPB and set some simple testable flags to control the Phase I main REGDEF $P1_PARAMS P1_FLTEMP ; temp used by flag routine P1_FlagSub: SETREG $P1_DOSOME 0 ; clear the do something flag BRANCHNE $IPB_SF 0 &P1_Fl10 ; set histogram flag if sf,ff,or aecx BRANCHNE $IPB_FF 0 &P1_Fl10 BRANCHIF $IPB_AECX &P1_Fl20 P1_Fl10: SETREG $P1_HISTFLAG 1 SETREG $P1_DOSOME 1 ; also set do something GOTO &P1_Fl40 P1_Fl20: BRANCHNE $IPB_IMX 0 &P1_Fl30 ; set imax flag if max or min set BRANCHIF $IPB_IMN &P1_Fl40 P1_Fl30: SETREG $P1_IMAXFLAG 1 SETREG $P1_DOSOME 1 ; also set do something P1_Fl40: BRANCHIF $IPB_TF &P1_Fl50 ; if transient requested (Vr1.26) REGSUB $IPB_TAI $AVGCOUNT $P1_FLTEMP ; and the count will be up on this BRANCHNE $P1_FLTEMP 1 &P1_Fl50 ; sample (Vr1.26) SETREG $P1_TRANSFLAG 1 ; set the transient SETREG $P1_DOSOME 1 ; and the do something flags P1_Fl50: REGAND $FDB_SAFEFLAGWORD $LITERAL40 $P1_SAFECHK ; Mask all but the safety bit (Vr1.26) P1_Fl99: RTNQUE ; Bad Pixel Subroutine ; Correct bad pixels and columns REGBLK $P1_PARAMS P1_BPTST[6] ; Test Register set for Verification REGBLK $P1_PARAMS P1_BPCOR[6] ; register to both badcol and badpix REGEQU $P1_BPCOR P1_BPPG ; set to the ccd page number REGEQU $P1_BPCOR+1 P1_BPRL ; row length REGEQU $P1_BPCOR+2 P1_BPYO ; Y offset REGEQU $P1_BPCOR+3 P1_BPYL ; Y length REGEQU $P1_BPCOR+4 P1_BPADD ; Badcol or badpix table REGDEF $P1_PARAMS P1_BPTEMP ; temp for intermediate results P1_BadPixSub: NOOP ; ****** Replace with RTNQUE if there are problems P1_BP10: COPYREG $IPB_BPT $P1_BPADD ; bad col tables are 4096 long REGMULT $P1_BPADD $LITERAL4096 $P1_BPADD ; mult by 4096 SETREG $P1_BPADD+1 6 ; set to seg 6 COPYREG $IPB_BPYO $P1_BPYO ; transfer parameters from the cc block COPYREG $IPB_BPYL $P1_BPYL COPYREG $IPB_P1RL $P1_BPRL COPYREG $CCDPAGE $P1_BPPG BADCOL $P1_BPCOR ; do the badcol correction COPYRD2D $P1_BPCOR $P1_BPTST 6 ; copy to temp for verification REGAND $IPB_BPT $LITERAL1 $P1_BPADD ; BP tables are 32K starting at seg 7 BRANCHIF $P1_BPADD &P1_BP20 ; odds start at add 0x8000 and evens SETREG $P1_BPADD 0x8000 ; start at add 0 P1_BP20: COPYREG $IPB_BPT $P1_BPADD+1 ; table numbers 0 - 7 become segs 7 - A SHIFT $P1_BPADD+1 $P1_BPADD+1 $LITERALMINUS1 ; i.e. (tab >> 1) + 7 ADDREGD $P1_BPADD+1 7 ; bias the index by 7 BADPIX $P1_BPCOR ; correct pixels RTNQUE ;
; Safety Check Routine ... (Vr1.26)
; Creates a histogram of a full CCD image frame binned to 8x8. (Vr1.26)
; Tests a specific bin and if the counts in that bin exceed a threshold (Vr1.26)
; increments the danger frame counter and clears the safe frame counter.(Vr1.26)
; If the danger frame counter exceeds the danger counter threshold, set (Vr1.26)
; the danger flag in the return block. If the histogram bin does not (Vr1.26)
; exceed the threshold, increment the safe frame count. If the safe frame(Vr1.26)
; count exceeds the safe frame threshold, clear danger frame counter. (Vr1.26)
REGBLK $P1_PARAMS P1_SAFBINEXT[8] ; for bin or extract (Vr1.26)
REGBLK $P1_PARAMS P1_SAFHIST[6] ; for histogram (Vr1.26)
REGDEF $P1_PARAMS P1_SAFCMMODE ; camera Mode (Vr1.26)
REGDEF $P1_PARAMS P1_SAFTEMP ; Temp for count threshold tests (Vr1.26)
P1_SafetySub: ; (Vr1.26)
SHIFT $FDB_CMMODEWORD $P1_SAFCMMODE $LITERALMINUS13 ; (Vr1.26)
REGAND $P1_SAFCMMODE $LITERAL7 $P1_SAFCMMODE ; (Vr1.26)
BRANCHGT $P1_SAFCMMODE 3 &P1_Safe99 ; Works only for full camera readout (Vr1.26)
COPYRD2D $IPB_FCO+3 $P1_SAFBINEXT 2 ; Get the full camera parameters (Vr1.26)
COPYRD2D $IPB_FCO+5 $P1_SAFBINEXT+4 3 ; (Vr1.26)
REGADD $P1_SAFBINEXT+1 $CCDPAGE $P1_SAFBINEXT ; insert page number (Vr1.26)
SETREGS $P1_SAFBINEXT+2 2 7:0 ; set output to page 7 (Vr1.26)
SETREG $SAFE_HISTTHR+1 0 ; (Vr1.26)
BRANCHNE $P1_SAFCMMODE 3 &P1_Safe20 ; if it's already 8x8 .... (Vr1.26)
EXTRACT $P1_SAFBINEXT ; Extract (Vr1.26)
GOTO &P1_Safe60 ; (Vr1.26)
P1_Safe20: ; (Vr1.26)
SETREG $P1_SAFBINEXT+7 8 ; set the bin mode (Vr1.26)
BRANCHIF $P1_SAFCMMODE &P1_Safe40 ; (Vr1.26)
SETREG $P1_SAFBINEXT+7 4 ; (Vr1.26)
BRANCHEQ $P1_SAFCMMODE 1 &P1_Safe40 ; (Vr1.26)
SETREG $P1_SAFBINEXT+7 2 ; (Vr1.26)
P1_Safe40: ; (Vr1.26)
BINNXN $P1_SAFBINEXT ; bin images that are < 8x8 to 8x8 (Vr1.26)
P1_Safe60: ; (Vr1.26)
SETREGS $P1_SAFHIST 6 7:0 128 128 128 $P1_HISTOUT ; setup histogram (Vr1.26)
REGMULT $P1_SAFHIST+2 $P1_SAFHIST+3 $DPLENGTH ; 128x128 to dplength (Vr1.28)
HIST128 $P1_SAFHIST ; do the histogram (Vr1.26)
SETREG $P1_SAFTEMP $SAFE_1X1BIN ; Get the right threshold (Vr1.26)
REGADD $P1_SAFTEMP $P1_SAFCMMODE $P1_SAFTEMP ; (Vr1.26)
COPYRI2D $P1_SAFTEMP $P1_HISTBIN 1 ; (Vr1.26)
CALLQUE &P1_GetHistBinSub ; determine if this is an s or a d (Vr1.26)
BRANCHIF $P1_HISTBINOK &P1_Safe99 ; (this out is the bin # is bad (Vr1.26)
SETREG $P1_SAFTEMP $SAFE_1X1THR ; Get the right threshold (Vr1.26)
REGADD $P1_SAFTEMP $P1_SAFCMMODE $P1_SAFTEMP ; (Vr1.26)
COPYRI2D $P1_SAFTEMP $SAFE_HISTTHR 1 ; (Vr1.26)
COMPLONG $SAFE_HISTTHR $P1_COMPTEST &P1_Safe80 &P1_Safe70 &P1_Safe70 ; (Vr1.26)
P1_Safe70: ; (Vr1.26)
SETREG $SAFE_SCOUNT 0 ; Dangerous frame... test threshold (Vr1.26)
ADDREGD $SAFE_DCOUNT 1 ; clear s counts,alert CC as required (Vr1.26)
REGSUB $SAFE_DTHRSH $SAFE_DCOUNT $P1_SAFTEMP ; (Vr1.26)
BRANCHGT $P1_SAFTEMP 0 &P1_Safe99 ; (Vr1.26)
SETREG $P1_RESULTS+11 1 ; (Vr1.26)
THROW 0xCCD0 ; (Vr1.26)
GOTO &P1_Safe99 ; (Vr1.26)
P1_Safe80: ; Safe frame ... test threshold and (Vr1.26)
ADDREGD $SAFE_SCOUNT 1 ; Reset d counts as required (Vr1.26)
REGSUB $SAFE_STHRSH $SAFE_SCOUNT $P1_SAFTEMP ; (Vr1.26)
BRANCHGT $P1_SAFTEMP 0 &P1_Safe99 ; (Vr1.26)
SETREG $SAFE_DCOUNT 0 ; (Vr1.26)
P1_Safe99: ; (Vr1.26)
RTNQUE ; (Vr1.26)
; Histogram Subroutine ...
; Create a histogram, test for events, and set the event flag if any have happened
; Serious changes in VR1.20 .... Add General Purpose Routine to get the
; histogram bin value and check the bin for 0-127. Also, divide AEC High pixel
; count by 8.
REGBLK $P1_PARAMS P1_HIST[6] ; for doing the histogram
REGBLK $P1_PARAMS P1_COMPREF[2]
REGBLK $P1_PARAMS P1_COMPTEST[2]
REGBLK $P1_PARAMS P1_COMPTESTADD[2]
REGBLK $P1_PARAMS P1_AECTEMP[2] ; for shift the high count -3 (VR1.20)
REGDEF $P1_PARAMS P1_HISTBIN ; The histogram bin Number (VR1.20)
REGDEF $P1_PARAMS P1_HISTBINOK ; Set if histogram bin is okay (VR1.20)
; *** Create the histogram ***
P1_HistSub:
SETREGS $P1_HIST 2 7:0 ; Source data always is in Page 7
COPYRD2D $XYRLEN $P1_HIST+2 3 ; Copy in the length parameters
SETREG $P1_HIST+5 $P1_HISTOUT ; Set the histogram address
HIST128 $P1_HIST ; do a 128 bin histogram
SETREG $P1_EVENTFLAG 0 ; clear the event flag
SETREG $P1_FLAREVNT 0 ; clear the flare event flag
; *** Test for superflare ***
BRANCHIF $IPB_SF &P1_Hi20 ; is there a superflare request
COPYREG $IPB_SFHB $P1_HISTBIN ; get the bin value
CALLQUE $P1_GetHistBinSub
BRANCHIF $P1_HISTBINOK $P1_Hi20 ; Make sure it's Okay
COMPLONG $IPB_SFHC $P1_COMPTEST &P1_Hi20 $P1_Hi10 &P1_Hi10
P1_Hi10: SETREG $P1_EVENTFLAG 1
SETREG $P1_RESULT_SF 1
SETREG $P1_FLAREVNT 1
; *** Test for flare ***
P1_Hi20:
BRANCHIF $IPB_FF &P1_Hi40 ; is there a flare request
COPYREG $IPB_FHB $P1_HISTBIN
CALLQUE $P1_GetHistBinSub
BRANCHIF $P1_HISTBINOK $P1_Hi40
COMPLONG $IPB_FHC $P1_COMPTEST &P1_Hi40 $P1_Hi30 &P1_Hi30
P1_Hi30: SETREG $P1_EVENTFLAG 1
SETREG $P1_RESULT_FF 1
SETREG $P1_FLAREVNT 1
; *** Test for AEC ***
P1_Hi40:
BRANCHIF $IPB_AECX &P1_Hi80 ; is there an AEC request
; **** Overexposure test ****
COPYREG $IPB_AEHB $P1_HISTBIN
CALLQUE $P1_GetHistBinSub
BRANCHIF $P1_HISTBINOK $P1_Hi80
; Added code to shift the AEC High Pixel count 3 right (divide by 8) (VR1.20)
SHIFT $IPB_AEHC $P1_AECTEMP $LITERALMINUS3
REGAND $P1_AECTEMP $P1_AECTEMP $LITERAL1FFF
REGAND $IPB_AEHC+1 $P1_AECTEMP+1 7
SHIFT $P1_AECTEMP+1 $P1_AECTEMP+1 13
REGOR $P1_AECTEMP+1 $P1_AECTEMP $P1_AECTEMP
SHIFT $IPB_AEHC+1 $P1_AECTEMP+1 $LITERALMINUS3
REGAND $P1_AECTEMP+1 $P1_AECTEMP+1 $LITERAL1FFF
COMPLONG $P1_AECTEMP $P1_COMPTEST &P1_Hi60 &P1_Hi50 &P1_Hi50
P1_Hi50: SETREG $P1_EVENTFLAG 1 ; Overexposure
SETREG $P1_RESULT_AEF 0xFFFF ; Indicate exp goes down
GOTO $P1_Hi80 ; skip the underexposure test
P1_Hi60: ;**** Underexposure test ****
COPYREG $IPB_AELB $P1_HISTBIN
CALLQUE $P1_GetHistBinSub
BRANCHIF $P1_HISTBINOK $P1_Hi80
COMPLONG $IPB_AELC $P1_COMPTEST &P1_Hi70 $P1_Hi80 &P1_Hi80
P1_Hi70: SETREG $P1_EVENTFLAG 1
SETREG $P1_RESULT_AEF 1
P1_Hi80:
BRANCHNE $IPB_IMX 0 &P1_Hi90 ; peek at the imx flag
BRANCHIF $P1_FLAREVNT $P1_Hi95 ; Not set, was there a flare?
P1_Hi90: ; Flare or Imax requested
SETREG $P1_RESULT_IMXV 1 ; set the validity flag
COPYRD2D $P1_HIMAXLOC $P1_RESULT_IMXL 2 ; and location
P1_Hi95:
BRANCHEQ $IPB_IMN 0 &P1_Hi99 ; peek at the imn flag (Vr1.20)
SETREG $P1_RESULT_IMNV 1 ; Imn requested, set validity
COPYRD2D $P1_HIMINLOC $P1_RESULT_IMNL 2 ; and location
P1_Hi99: RTNQUE
;
; Invert Histogram ... Routine removed in 1.20 ... replaced with GetHistBinSub
; Get Histogram Bin Value ... added (VR1.20)
; This routine retrieves the value in the designated histogram Bin
; Makes sure the histogram bin is between 0 and 127
; Doubles the bin number and adds it to histogram start address
; Retreives the value and inverts it (i.e., subtracts the count from the
; dat product length).
;
P1_GetHistBinSub:
SETREG $P1_HISTBINOK 0
BRANCHLT $P1_HISTBIN 0 &P1_GetHistBin99
BRANCHGT $P1_HISTBIN 127 &P1_GetHistBin99
SETREG $P1_HISTBINOK 1
SETREG $P1_COMPTESTADD $P1_HISTOUT ; set test to the histogram start add
REGADD $P1_COMPTESTADD $P1_HISTBIN $P1_COMPTESTADD ; and add the SF bin number
REGADD $P1_COMPTESTADD $P1_HISTBIN $P1_COMPTESTADD ; add again (hist is 32 bit)
COPYRI2D $P1_COMPTESTADD $P1_COMPTEST 2
COPYRD2D $DPLENGTH $SUB32IN 2 ; Invert the histogram value
COPYRD2D $P1_COMPTEST $SUB32IN+2 2
CALLQUE &Sub32Sub
COPYRD2D $SUB32OUT $P1_COMPTEST 2
P1_GetHistBin99: RTNQUE
; Transient Subroutine ...
; Apply the transient detection algorithm and set the event flag if a transient has happened
; Note: This routine is called only if the averaging interval is complete with this sample.
REGBLK $P1_PARAMS P1_TRANSBUF[10]
REGEQU $P1_TRANSBUF P1_TRANSSOURCE
REGEQU $P1_TRANSBUF+2 P1_TRANSLENGTHS
REGEQU $P1_TRANSBUF+5 P1_TRANSREF
REGEQU $P1_TRANSBUF+7 P1_TRANSREG
REGEQU $P1_TRANSBUF+8 P1_TRANSSF1
REGEQU $P1_TRANSBUF+9 P1_TRANSSF2
REGBLK $P1_PARAMS P1_TRANSSCALE[11]
REGBLK $P1_PARAMS P1_TRANSMIN[6]
REGBLK $P1_PARAMS P1_TRANSMOVE[6]
REGBLK $P1_PARAMS P1_TRANSVLOC[3]
P1_TransSub:
COPYREG $IPB_TAI $AVGMAX ; Set the average max
BRANCHNE $AVGMAX 1 &P1_Tr10 ; if it's just a one sample transient
SETREGS $P1_TRANSMOVE 4 7:0 7:0x90000 ; skip the sum and scale and just
COPYRD2D $DPLENGTH $P1_TRANSMOVE+4 2 ; move the data
MOVSBLKI $P1_TRANSMOVE
GOTO &P1_Tr20
P1_Tr10:
CALLQUE &SumSub ; add in this image
SETREGS $AVGDEST 2 7:0x90000 ; set dest to upper half page of 7
CALLQUE &AvgSub ; Finalize the new average
SETREG $AVGCOUNT 0 ; Reset count for next pass (Vr 1.25)
P1_Tr20:
COPYRD2D $XYRLEN $TRANSXYR 3 ; save parameters for use during phase 2
COPYRD2D $DPLENGTH $TRANSDPL 2
SETREG $TRANSDONE 1
BRANCHNE $P1_TRANSFIRST 0 &P1_Fl99 ; 1st result
COPYRD2D $XYRLEN $P1_TRANSLENGTHS 3 ; set the lengths
SETREGS $P1_TRANSREG 2 $P1_TRANSCOUNT -100 ; set outreg (2) and source mult (-100)
COPYREG $IPB_TMUL $P1_TRANSSF2 ; the second is from the info block (Vr 1.23)
BRANCHIF $IPB_DT &P1_Tr30 ; check for dark or bright
; *** Dark Transient ***
SETREGS $P1_TRANSSOURCE 2 2:0x90000 ; dark is -100*old + tmul*new
SETREGS $P1_TRANSREF 2 7:0x90000
GOTO &P1_Tr40
P1_Tr30: ; *** Bright Transient ***
SETREGS $P1_TRANSSOURCE 2 7:0x90000 ; bright is -100*new + tmul*old
SETREGS $P1_TRANSREF 2 2:0x90000
P1_Tr40: TRDETECT $P1_TRANSBUF ; test for transient
COMPLONG $IPB_TPC $P1_TRANSCOUNT &P1_Tr99 &P1_Tr50 &P1_Tr50 ; (Vr 1.23)
P1_Tr50: SETREG $P1_RESULT_TF 1 ; set trans flag
SETREG $P1_EVENTFLAG 1 ; set event flag
; *** Transient detected ... now the fun begins ... redo the process to get the location
SETREGS $P1_TRANSSCALE 6 2:0x90000 7:0x90000 6:0 ; set up scaled sum into page 6
COPYRD2D $DPLENGTH $P1_TRANSSCALE+6 2 ; page 2 must be s1
BRANCHIF $IPB_DT &P1_Tr60 ; set up dark or bright scale factors
SETREG $P1_TRANSSCALE+9 -100
COPYREG $IPB_TMUL $P1_TRANSSCALE+8
GOTO &P1_Tr70
P1_Tr60:
SETREG $P1_TRANSSCALE+8 -100
COPYREG $IPB_TMUL $P1_TRANSSCALE+9
P1_Tr70:
SETREG $P1_TRANSSCALE+10 13 ; I think shift gets best significance
SCALESUM $P1_TRANSSCALE ; scale the data
SETREGS $P1_TRANSMIN 2 6:0 ; set up a findmin
COPYRD2D $XYRLEN $P1_TRANSMIN+2 3
SETREG $P1_TRANSMIN+5 $P1_TRANSVLOC ; register to receive min v and loc
FINDMIN $P1_TRANSMIN ; find the min
COPYRD2D $P1_TRANSVLOC+1 $P1_RESULT_IMXL 2 ; save loc in max loc
SETREG $P1_RESULT_IMXV 1 ; declare max location valid
P1_Tr99: RTNQUE
; IMAX Subroutine ...
; Locate the IMAX and/or IMIN in cases where it has not yet been done but is requested.
REGBLK $P1_PARAMS P1_IMAXMIN[6] ; reg block for max/min
REGEQU $P1_IMAXMIN P1_IMAXSOURCE ; equ's for readability
REGEQU $P1_IMAXMIN+2 P1_IMAXXYR
REGEQU $P1_IMAXMIN+5 P1_IMAXOUT
P1_ImaxSub:
SETREGS $P1_IMAXSOURCE 2 7:0 ; source has always bin binned/extract to 7
COPYRD2D $XYRLEN $P1_IMAXXYR 3 ; set the length words
BRANCHIF $IPB_IMX &P1_Im10 ; If max is set,
SETREG $P1_IMAXOUT $P1_FINDIMAX ; set register for result
FINDMAX $P1_IMAXMIN ; do max instructio
SETREG $P1_RESULT_IMXV 1 ; set validity flag and
COPYRD2D $P1_FINDIMAXLOC $P1_RESULT_IMXL 2 ; location
P1_Im10:
BRANCHIF $IPB_IMN &P1_Im99 ; if min is set,
SETREG $P1_IMAXOUT $P1_FINDIMIN ; set register for result
FINDMIN $P1_IMAXMIN ; find min
SETREG $P1_RESULT_IMNV 1 ; set validity flag
COPYRD2D $P1_FINDIMINLOC $P1_RESULT_IMNL 2 ; and location
P1_Im99: RTNQUE
; Test mode for phase I Plases a fixed pattern in the phase I results area and returns
P1_TestMode:
SETREGS $P1_RESULTS 4 0 1 2 3 ; (3 setregs to initialize phaseI results)
SETREGS $P1_RESULTS+4 4 4 5 6 7 ; (3 setregs to initialize phaseI results)
SETREGS $P1_RESULTS+8 4 8 9 10 11 ; (3 setregs to initialize phaseI results)
RTNQUE
;
;
; Phase II main routine
;
.RORG P2_PARAMS 0x600 ; Register 600-7FF reserved for phase II
REGBLK $P2_PARAMS P2_OUTPARAMS[16] ; this block contains the 16 output parameters
REGEQU $P2_OUTPARAMS+1 P2_AVGREQ ; Averaging request flag
REGEQU $P2_OUTPARAMS+3 P2_AREASTART ; Area Start Address
REGBLK $P2_PARAMS P2_MEMFILL[5] ; Used for memory fills
REGDEF $P2_PARAMS P2_AVGMAX ; Number of Images to Average
REGBLK $P2_PARAMS P2_AVGTIME0[3] ; Time of the First Sample
REGBLK $P2_PARAMS P2_TEMP[11] ; reglist for a variety of instructions
REGDEF $P2_PARAMS P2_FIELDCODE ; FC,A1, or A2 code for the output block
REGBLK $P2_PARAMS P2_DPLASTADD[2] ; last add of dp (Used to test for que full)
REGBLK $P2_PARAMS P2_DPL505[2] ; Length of DP plus header
REGDEF $P2_PARAMS P2_HSSQUESTART[2] ; Next add in output queue
REGDEF $P2_PARAMS P2_QUETIMER ; used to see if swap has timed out
REGDEF $P2_PARAMS P2_HSSTIMEOUT ; set to one if a swap times out
REGBLK $P2_PARAMS P2_MOVBLK[6] ; Used for move blocks
REGBLK $P2_PARAMS P2_TABCOPY[5] ; reglist for table copies
REGBLK $P2_PARAMS P2_JPEG[8] ; reg list for the jpeg
REGBLK $P2_PARAMS P2_SOURCEDEST[4] ; Source/Destination array
REGBLK $P2_PARAMS P2_MULT[2] ; Results of multiply when needed as a temp
DoPhase2Sub: ; first main split is test vs. normal mode
SETREGS $DP_HDR 2 0x352e 0xf853 ; set sync directly into the output buffer
BRANCHNE $TESTMODE 0xFFFF &P2_NormalMode
BRANCHIF $NORMALMODE &P2_TestMode
;
;
P2_NormalMode: ; Normal Mode code
CALLQUE &P2_InitSub ; Initialize (Place holder for now)
SETREG $P2_FIELDCODE 0 ; Set the Field Code to FC
COPYRD2D $DP_HDR+0x15E $P2_OUTPARAMS 0x10 ; Copy parameters to standard area
CALLQUE &P2_OutSub ; Call the output routine
BRANCHIF $P2_HSSTIMEOUT &P2_FCODone ; if there's a timeout
THROW 0xF001 ; throw f001 and rtn
RTNQUE
P2_FCODone:
SETREG $P2_FIELDCODE 1 ; Set the Field Code to A1
COPYRD2D $DP_HDR+0x16E $P2_OUTPARAMS 0x10 ; Copy parameters to standard area
CALLQUE &P2_OutSub ; Call the output routine
BRANCHIF $P2_HSSTIMEOUT &P2_A1Done ; If there's a timeout
THROW 0xF002 ; throw f001 and rtn
RTNQUE
P2_A1Done:
SETREG $P2_FIELDCODE 2 ; Set the Field Code to A2
COPYRD2D $DP_HDR+0x17E $P2_OUTPARAMS 0x10 ; Copy parameters to standard area
CALLQUE &P2_OutSub ; Call the output routine
BRANCHIF $P2_HSSTIMEOUT &P2_A2Done ; If there's a timeout
THROW 0xF003 ; throw f001 and rtn
RTNQUE
P2_A2Done:
RTNQUE
; This section contains phase II subroutines
P2_InitSub: ; Phase II initialization routine (Place Holder)
BRANCHIF $TRANSDONE &P2_Is10 ; see if transient done in phase 1
COPYRD2D $TRANSDPL $P2_MOVBLK+4 2 ; yes, move result (at 7:90000 back to Page 2)
SETREGS $P2_MOVBLK 4 7:0x90000 2:0x90000
MOVBLKI $P2_MOVBLK
P2_Is10:
RTNQUE
; This is the output management routine
P2_OutSub:
SETREG $P2_HSSTIMEOUT 0 ; Clear the Hss error flag
SETREG $P2_SOURCEDEST+1 0 ; Initialize the source and dest to 7,6
CALLQUE &P2_SwapSub
BRANCHIF $P2_AVGREQ &P2_Out05 ; if the field is averaged
BRANCHIF $TRANSDONE &P2_Out10 ; and the average has been done
BRANCHIF $P2_OUTPARAMS &P2_Out20 ; Unless there's not ouput request..
SETREGS $P2_MOVBLK 4 2:0x90000 7:0 ; move from page 2 to 7
COPYRD2D $TRANSDPL $P2_MOVBLK+4 2 ; Fixed typo in dest address (Vr 1.2a)
MOVBLKI $P2_MOVBLK
COPYRD2D $TRANSXYR $XYRLEN 3
COPYRD2D $TRANSDPL $DPLENGTH 2
GOTO &P2_Out30
P2_Out05:
BRANCHIF $P2_OUTPARAMS &P2_Out20 ; No avg, no out ... return
P2_Out10:
SETREG $BINEXTADD $P2_AREASTART
CALLQUE &BinExtSub ; first do a bin or extract
BRANCHIF $P2_AVGREQ &P2_Out30 ; Is this subfield averaged
CALLQUE &P2_AvgSub ; otherwise call the averaging routine
BRANCHIF $AVGCOUNT &P2_Out30 ; is the average complete
P2_Out20:
RTNQUE ; no... return (no output yet)
; At this point, the uncompressed data product is in page 7 at address 0
; The Data Product header is still in registers start at 100(Hex).
P2_Out30:
BRANCHIF $P2_OUTPARAMS &P2_Out20 ; once last peek at output flag
; Added code here in Vr 1.23 to bypass output if APID is 0 (Vr 1.23)
; If the APID0_COUNT is 0, throw error A000. Increment count in (Vr 1.23)
; any case (Vr 1.23)
BRANCHNE $P2_OUTPARAMS+9 0 $P2_Out35 ; (Vr 1.23)
BRANCHNE $APID0_COUNT 0 $P2_Out32 ; (Vr 1.23)
THROW 0xA000 ; (Vr 1.23)
P2_Out32: ; (Vr 1,23)
ADDREGD $APID0_COUNT 1 ; (Vr 1.23)
RTNQUE ; No output (Vr 1.23)
P2_Out35: ; (Vr 1.23)
SETREG $DP_HDR+2 0 ; Initialize type to Raw
BRANCHIF $P2_OUTPARAMS+10 &P2_Out40 ; Is JPEG requested?
CALLQUE &P2_JpegSub ; Yes call JPEG Routine
GOTO &P2_Out60 ; Skip Lut and Pack checks
P2_Out40:
BRANCHIF $P2_OUTPARAMS+12 &P2_Out50 ; Is lookup requested
CALLQUE &P2_LutSub ; Yes, call the LUT Routine
P2_Out50:
BRANCHIF $P2_OUTPARAMS+11 &P2_Out60 ; is Packing requested?
CALLQUE &P2_PackSub ; Yes, call the packing routine
P2_Out60:
CALLQUE &P2_HSSInitSub ; Initialize the HSS output
BRANCHIF $P2_HSSTIMEOUT &P2_Out70 ; Return if there was a timeout
RTNQUE
P2_Out70:
COPYRD2D $P2_DPL505 $DP_HDR+410 2 ; Put the length in the header
COPYREG $EXTRAWORD $DP_HDR+412 ; Put in the extra word flag
COPYREG $P2_FIELDCODE $DP_HDR+413
COPYRD2D $P2_AVGTIME0 $DP_HDR+414 2 ; Put in the Time 0 Time word
SETREGS $P2_MOVBLK 2 $DP_HDR 505
COPYRD2D $P2_HSSQUESTART $P2_MOVBLK+2 2
SAVERLSI $P2_MOVBLK
COPYRD2D $P2_SOURCEDEST $P2_MOVBLK 2 ;Move the data product
COPYRD2D $DPLENGTH $P2_MOVBLK+4 2
ADDADR $P2_MOVBLK+2 $LITERAL505L $P2_MOVBLK+2
MOVBLKI $P2_MOVBLK
COPYREG $P2_OUTPARAMS+9 $HSSAPID ; setup the HSS enter (APID first)
COPYRD2D $P2_HSSQUESTART $HSSADR 2 ; address (From the hssaddr)
COPYRD2D $P2_DPL505 $HSSCOUNT 2 ; The total length including header
COPYRD2D $DP_HDR+3 $HSSTIME 3 ; the time words
CALLQUE &HssOutSub ; call the output subroutine
P2_Out99:
RTNQUE ; the phase 2 output phase is done
; Averaging Routine
P2_AvgSub:
BRANCHEQ $P2_OUTPARAMS+2 0 &P2_Avg10 ; check for first sample
SETREG $AVGCOUNT 0 ; set the counter to 0
P2_Avg10:
BRANCHNE $AVGCOUNT 0 &P2_Avg20
CALLQUE &P2_AvgInitSub ; Initialize averaging
SETREGS $P2_MOVBLK 2 7:0 ; just move data to 2
SETREG $AVGCOUNT 1 ; set the counter to 0
GOTO &P2_Avg25
P2_Avg20:
SETREGS $P2_MOVBLK 2 6:0 ; it's not, data to page 2
CALLQUE $SumSub ; do the Intermediate sum
P2_Avg25:
REGSUB $P2_AVGMAX $AVGCOUNT &P2_TEMP ; see if the average is done
BRANCHIF $P2_TEMP &P2_Avg30 ; see if the average is done
SETREGS $P2_MOVBLK+2 2 2:0
COPYRD2D $DPLENGTH $P2_MOVBLK+4 2
MOVBLKI $P2_MOVBLK
RTNQUE ; since average not ready, there's no output
P2_Avg30:
BRANCHEQ $P2_AVGMAX 1 &P2_Avg40 ; guard against stupidity (Avg 1 sample)
SETREGS $AVGDEST 2 7:0 ; set destination for done routine
COPYREG $P2_AVGMAX $AVGMAX ; set the max value for the scale factor routine
CALLQUE &AvgSub ; finalize the average
P2_Avg40: ; reset the counter
SETREG $AVGCOUNT 0
RTNQUE
; Jpeg Subroutine
P2_JpegSub:
REGMULT $LITERAL544 $P2_OUTPARAMS+12 $P2_TABCOPY ; Copy tables
SETREGS $P2_TABCOPY+1 4 3 0 2 512 ; First, copy the huffman tables
COPYTAB $P2_TABCOPY
ADDREGD $P2_TABCOPY 512
SETREGS $P2_TABCOPY+1 4 3 0x200 2 16
COPYTAB $P2_TABCOPY
ADDREGD $P2_TABCOPY 16
SETREGS $P2_TABCOPY+1 4 3 0x300 2 16
COPYTAB $P2_TABCOPY
REGMULT $LITERAL1024 $P2_OUTPARAMS+11 $P2_TABCOPY ; Then copy the qualtization table
; Subtract 1 removed in vr 1.1A
REGAND $P2_OUTPARAMS+13 $LITERALF $P2_MULT
REGMULT $P2_MULT $LITERAL64 $P2_MULT
REGADD $P2_MULT $P2_TABCOPY $P2_TABCOPY
SETREGS $P2_TABCOPY+1 4 4 0x400 2 64
COPYTAB $P2_TABCOPY
COPYRD2D $P2_SOURCEDEST $P2_JPEG 4 ; setup the jpeg instruction
COPYRD2D $XYRLEN $P2_JPEG+4 3
SETREG $P2_JPEG+7 0x4000 ; initalize quality to unity
P2_Jpeg90:
JPEGCOMP $P2_JPEG ; do the jpeg
COPYRD2D R64 $DPLENGTH 2 ; transfer the length to the normal place
CALLQUE &P2_SwapSub ; swap source and dest
SETREG $DP_HDR+2 1 ; Set data type to jpeg
RTNQUE
; Lut Subroutine
P2_LutSub:
REGMULT $LITERAL4096 $P2_OUTPARAMS+12 $P2_TABCOPY ; copy Lut to bottom of seg 5
SETREGS $P2_TABCOPY+1 4 5 0 5 4096 ; (all lut's are 4096)
COPYTAB $P2_TABCOPY
COPYRD2D $P2_SOURCEDEST $P2_TEMP 4 ; set up the lookup instruction
COPYRD2D $DPLENGTH $P2_TEMP+4 2
SETREGS $P2_TEMP+6 2 0 5
LOOKUP $P2_TEMP ; do the lookup
CALLQUE &P2_SwapSub ; swap source and dest
RTNQUE
; Pack Subroutine - PlaceHolder for now
P2_PackSub:
COPYRD2D $P2_SOURCEDEST $P2_TEMP 4 ; Get the source and dest addresses
COPYRD2D $XYRLEN $P2_TEMP+4 3 ; Set up packls instruction
COPYREG $P2_OUTPARAMS+11 $P2_TEMP+7
PACKLS $P2_TEMP ; do the pack
CALLQUE &P2_SwapSub ; Swap source and dest
COPYRD2D R66 $DPLENGTH 2 ; copy pack length to the normal place
COPYREG $P2_OUTPARAMS+11 $DP_HDR+2 ; set the type to the pack size
RTNQUE
; HSS Initialization Routine
P2_HSSInitSub:
HSSADDR $P2_HSSQUESTART ; Get the HSS Address
ADDADR $DPLENGTH $LITERAL505L $P2_DPL505 ; generate total length
COPYRD2D $P2_DPL505 $HSSLEN 2
CALLQUE $HssExtraSub ; add extraword as needed
BRANCHIF $EXTRAWORD $P2_HSSInit10
ADDADR $EXTRAWORD $P2_DPL505 $P2_DPL505
ADDADR $EXTRAWORD $DPLENGTH $DPLENGTH
P2_HSSInit10:
ADDADR $P2_DPL505 $P2_HSSQUESTART $P2_DPLASTADD ; add the length to the hss address
REGAND $P2_DPLASTADD+1 $LITERAL7FF $P2_DPLASTADD+1 ; and see if it overflows a page
BRANCHLT $P2_DPLASTADD+1 0x12 &P2_HssInit20 ; There's room, move ahead
SETREG $P2_QUETIMER 22000 ;*** NOT ENOUGH QUE SPACE
P2_QueSwap: ; Retry swap for 22 seconds
HSSSWAP &P2_HSSInit15 &P2_QueBusy ; If que is busy all that time,
P2_QueBusy:
ADDREGD $P2_QUETIMER -1
BRANCHIF $P2_QUETIMER &P2_QueTimeOut
WAIT 1000
GOTO $P2_QueSwap
P2_QueTimeOut:
SETREG $P2_HSSTIMEOUT 1 ; Return an error
RTNQUE
P2_HSSInit15:
HSSADDR $P2_HSSQUESTART ; Queue was busy, get new address
P2_HssInit20:
RTNQUE
; P2_AvgInitSub -
; This Phase II routine initializes various parameters
P2_AvgInitSub:
COPYREG $P2_OUTPARAMS+1 $P2_AVGMAX ; Init the total expected for the average
BRANCHLT $P2_AVGMAX 17 &P2_AvgI10 ; Force a legal value
SETREG $P2_AVGMAX 16
P2_AvgI10:
BRANCHGT $P2_AVGMAX 0 &P2_AvgI20
SETREG $P2_AVGMAX 1
P2_AvgI20:
COPYRD2D $DP_HDR+3 $P2_AVGTIME0 3 ; save the time words
RTNQUE
; P2_SwapSub -
; Little routine for swapping source and dest between pg 6 and 7
P2_SwapSub:
BRANCHNE $P2_SOURCEDEST+1 0x3800 &P2_Swap7
SETREGS $P2_SOURCEDEST 4 6:0 7:0
RTNQUE
P2_Swap7:
SETREGS $P2_SOURCEDEST 4 7:0 6:0
RTNQUE
; This is the TESTMODE Phase II Routine.
; This is the mode simple mind program that output a full camera image from the current CCD page.
; It tests for nothing.
; Registers from 340 - 3FF are reserved for Phase II test mode
; NOTE: Revised slightly in VR 1.1C to use the generalized output utility to
; get the timewords swapped.
.RORG P2_TESTMODEREG 0x340
REGBLK $P2_TESTMODEREG P2T_HDR[6] ; for moving the header register to page 7
REGBLK $P2_TESTMODEREG P2T_IMG[8] ; for moving the image data and doing an addadr
REGBLK $P2_TESTMODEREG P2T_HSS[8] ; for queing the HSS Data
P2_TestMode:
SETREG $DP_HDR+2 0xffff ; set type to test mode image
SETREGS $DP_HDR+410 4 0x106785L 0 0 ;( set the word count for the output)
HSSADDR $P2T_HDR+2 ; first get the HSS Queue address
SAVERLST $DP_HDR 505 7:0x0000 ; save 505 words starting a r100
SETREGS $P2T_HDR 2 7:0x00000 ; Set up Source and the count
SETREGS $P2T_HDR+4 2 505L
MOVBLKI $P2T_HDR ; Do the Move
SETREGS $P2T_IMG+4 4 0x10658CL 505L ; setup image move length and prep an address add
ADDADR $P2T_HDR+2 $P2T_IMG+6 $P2T_IMG+2 ; Add 505 to the hss addr and put in dest of image move
SETREG $P2T_IMG 0
COPYREG $CCDPAGE $P2T_IMG+1
; at P2T_IMG is the image address, the hssaddress + 1f9 (505), and the image data length (658C,10)
MOVBLKI $P2T_IMG ; move the image data
SETREG $HSSAPID 0x3c ; set the appid to 60
COPYRD2D $P2T_HDR+2 $HSSADR 2 ; get the HSS address for where it was used to copy the header
ADDADR $P2T_IMG+4 $P2T_IMG+6 $HSSCOUNT ; add 505 to image length to account for DP Header
COPYRD2D $DP_HDR+3 $HSSTIME 3 ; finally get the time word
CALLQUE &HssOutSub
DONE:
RTNQUE
;********************************* Phase 1-2 common routines **********
; BinExt Subroutine
; Called with the adress of a bin/extract parameter in BINEXTADD
; Extracts or bins into page 7
; Returns length of data product in DPLENGTH
; X,Y, and Row Length in XYRLEN
REGDEF $P1_P2 BINSHIFT ; for computing the output sizes
REGBLK $P1_P2 BINEXTPARAMS[6] ; for the input parameters
REGBLK $P1_P2 BINEXT[8] ; for the bin or extract instruction
BinExtSub:
COPYRI2D $BINEXTADD $BINEXTPARAMS 6 ; copy the parameters
COPYRD2D $BINEXTPARAMS $BINEXT 2 ; Initialize parameters for extract or Bin
REGADD $BINEXT+1 $CCDPAGE $BINEXT+1 ; use the actual page as determined by the DHC
SETREGS $BINEXT+2 2 7:0 ; temp output goes to page 7
COPYRD2D $BINEXTPARAMS+2 $BINEXT+4 4 ; x,y,row, and bin factor
BRANCHIF $BINEXTPARAMS+5 &BinExt_20 ; See if it's a bin or an extract
BINNXN $BINEXT ; Binning.... do it, then
SETREG $BINSHIFT -1 ; Change binning numbers (2,4,8)
BRANCHEQ $BINEXTPARAMS+5 2 &BinExt_10 ; to shift counts (-1,-2,-3)
ADDREGD $BINSHIFT -1
BRANCHEQ $BINEXTPARAMS+5 4 &BinExt_10
ADDREGD $BINSHIFT -1
BinExt_10:
SHIFT $BINEXT+4 $BINEXT+4 $BINSHIFT ;adjust the row and column
SHIFT $BINEXT+5 $BINEXT+5 $BINSHIFT ;sizes by the binning factor
GOTO &BinExt_30
BinExt_20:
EXTRACT $BINEXT ; Extract the selected field
BinExt_30:
REGMULT $BINEXT+4 $BINEXT+5 $DPLENGTH ; set the length to col times rows
COPYRD2D $BINEXT+4 $XYRLEN 2 ; Copy the x and y lengths
COPYREG $BINEXT+4 $XYRLEN+2 ; Set row length to x length
RTNQUE
; InitLiterals Routine
; This routines sets up literals. Through this is called only once from phase 1, it is considered a phase 1-2 routine
; because the literals are used in both phases.
; Changed literal block to 24 in Vr1.20
REGBLK $P1_P2 LITERALS[24] ; block for 24 literals (Equ's follow for readability)
REGEQU $LITERALS LITERAL6
REGEQU $LITERALS+1 LITERAL1
REGEQU $LITERALS+2 LITERAL7FF
REGEQU $LITERALS+3 LITERALx12
REGEQU $LITERALS+4 LITERAL505L ; Long word 505 so takes up this word and next
REGEQU $LITERALS+6 LITERAL4096
REGEQU $LITERALS+7 LITERAL1024
REGEQU $LITERALS+8 LITERAL64
REGEQU $LITERALS+9 LITERAL10
REGEQU $LITERALS+10 LITERAL544 ; this obscure number is to access huffman tables
REGEQU $LITERALS+11 LITERALF
REGEQU $LITERALS+12 LITERALMINUS1
REGEQU $LITERALS+13 LITERALMINUS3 ; Added 4 literals in VR1.20
REGEQU $LITERALS+14 LITERAL13
REGEQU $LITERALS+15 LITERAL1FFF
REGEQU $LITERALS+16 LITERAL7
REGEQU $LITERALS+17 LITERAL40 ; Safety check bit mask (Vr1.26)
REGEQU $LITERALS+18 LITERALMINUS13 ; camera mode mask for safety check (Vr1.26)
InitLiteralSub:
SETREGS $LITERALS 8 6 1 0x7FF 0x12 505 0 4096 1024
SETREGS $LITERALS+8 8 64 10 544 0xF 0xFFFF -3 13 0x1FFF ; (Vr1.26)
SETREGS $LITERALS+16 8 7 0x40 -13 0 0 0 0 0 ; (Vr1.26)
RTNQUE
; SumSub -
; This routine adds page 2 to page 7 and leaves result in page 6. Number of
; words is in DPLENGTH. Done using scalesum with unity multipliers and no shift.
; The summing is an intermediate result of the averaging process.
REGBLK $P1_P2 AVGTEMP[11]
REGEQU $AVGTEMP AVGSOURCE
REGEQU $AVGTEMP+2 AVGDEST
REGEQU $AVGTEMP+6 AVGSCALESHIFT
SumSub:
SETREGS $AVGTEMP 11 2:0 7:0 6:0 0 0 1 1 0x10 ; setup a unity scalesum
COPYRD2D $DPLENGTH $AVGTEMP+6 2 ; Copy length to scalesum instruction
SCALESUM $AVGTEMP ; do the scalesum
ADDREGD $AVGCOUNT 1
RTNQUE
; AvgSub -
; This routine finalizes the averaging process by doing a uscale into the caller
; specified destination. Call set AVGMAX to the sample count and AVGDEST to the
; destination page and address. Source must be page 6:address 0.
REGDEF $P1_P2 AVGMAX ; Caller puts averaging maximum here
AvgSub:
SETREGS $AVGSOURCE 2 6:0 ; Set source and Length
COPYRD2D $DPLENGTH $AVGTEMP+4 2
CALLQUE $AvgSetScaleSub ; set scale and shift
USCALE $AVGTEMP ; do the USCALE
RTNQUE
; AvgSetScaleSub -
; This routine sets scalefactors for averaging.
;
; Method ...
; The input data is the sum of 1 to 16 images. The USCALE instruction then shifts the result
; right 1 place then mulitplier by a scale factor then shift the result of the multiple. This
; uses the number of images in the sum to generate a branch address, i.e., a computed goto. Each
; GOTO branch set the pair of registers labeled AVGSCALESHIFT to a shift count and mulitplier
; that will return the summed data to 12 bit resolution. If you are reviewing this routine, remember
; that USCALE first shifts right 1, then mulitplies, and finally shift the result 16-shift count
; places right. All shift counts, except those for integer powers of 2 are 1, i.e., 15 bit right
; shift. The multiplier was determined by by rounding 65536/Nimages. The results are within
; 1 of the result of a true integer divide.
REGDEF $P1_P2 SCALEBRANCH[2] ; Temp for address computation
AvgSetScaleSub:
BRANCHLT $AVGMAX 17 &AvgScale10 ; Screen the count value
SETREG $AVGMAX 16
AvgScale10:
BRANCHGT $AVGMAX 0 &AvgScale20
SETREG $AVGMAX 1
AvgScale20:
REGMULT $LITERAL6 $AVGMAX $SCALEBRANCH ; a set regs and rtn require 6 words, so mulitply the
ADDREGD $SCALEBRANCH &AvgScale30 ; number in the sum by six, add the address of the
REGSUB $SCALEBRANCH $LITERAL6 $SCALEBRANCH ; 1st branch, and subtract (since there's no 0)
GOTOREG $SCALEBRANCH ; goto the right address.
AvgScale30:
SETREGS $AVGSCALESHIFT 2 2 16 ; 1 sample
RTNQUE
SETREGS $AVGSCALESHIFT 2 1 16 ; 2 samples
RTNQUE
SETREGS $AVGSCALESHIFT 2 21845 1 ; 3
RTNQUE
SETREGS $AVGSCALESHIFT 2 1 15 ; 4
RTNQUE
SETREGS $AVGSCALESHIFT 2 13107 1 ; 5
RTNQUE
SETREGS $AVGSCALESHIFT 2 10923 1 ; 6
RTNQUE
SETREGS $AVGSCALESHIFT 2 9362 1 ; 7
RTNQUE
SETREGS $AVGSCALESHIFT 2 1 14 ; 8
RTNQUE
SETREGS $AVGSCALESHIFT 2 7282 1 ; 9
RTNQUE
SETREGS $AVGSCALESHIFT 2 6554 1 ; 10
RTNQUE
SETREGS $AVGSCALESHIFT 2 5958 1 ; 11
RTNQUE
SETREGS $AVGSCALESHIFT 2 5461 1 ; 12
RTNQUE
SETREGS $AVGSCALESHIFT 2 5041 1 ; 13
RTNQUE
SETREGS $AVGSCALESHIFT 2 4681 1 ; 14
RTNQUE
SETREGS $AVGSCALESHIFT 2 4369 1 ; 15
RTNQUE
SETREGS $AVGSCALESHIFT 2 1 13 ; 16
RTNQUE
; ********************************** Jitter Mode ******************************************
; Jitter mode program.
; The CC sends 1 seconds worth of jitter data starting at address 2000 (hex) in the
; Data transfer buffer. The data length is in (DTB copy of) Regisiter 50 (hex)
; This program blocks up 64 samples of this data and outputs the block using apid 48 (hex)
;
; The output format is FRAMESYNC DATATYPE SAMPLECOUNT WORDCOUNT DATASAMPLES
; FRAMESYNC 2 words containing 352E F853
; DATATYPE 1 word containing FFF0
; SAMPLECOUNT 1 word containing the number of samples in this block
; (should be 64)
; WORDCOUNT 2 words containing the number of additional words in the block
; i.e., total length not counting the first 6 words.
; DATASAMPLES Up to 64 data samples in the form:
; SAMPLESYNC LENGTH SAMPLEDATA
; SAMPLESYNC 2 words containing F0F0 E0E0
; LENGTH 1 word containg the number of remaining words in the sample
; SAMPLEDATA a 1 seconds jitter mode data sample as defined in
; TRACE FLIGHT SOFTWARE GUIDE TELESCOPE & IMAGE STABLIZATION
; REQUIREMENTS (TRA-231002)
; The time word passed to the HSSENTER and thus the time word on all packets in the block
; is the time of the first sample. There is no special checking of the output process, i.e.,
; once the output is entered, the program swaps the queue and takes no action if the swap
; does not occur.
.RORG JM_CCINFO 0x50 ; the cc sends the length to reg 50
REGBLK $JM_CCINFO JM_INFOBLK[16]
REGEQU $JM_INFOBLK JM_SAMPLEN
.RORG JM_DATA 0x2000 ; the data is at DTB 2000 (hex)
REGBLK $JM_DATA JM_SAMPLE[2000] ; Leave space for up to 2000 (dec) words
REGEQU $JM_SAMPLE+1 JM_SAMPLETIME ; The time is in words 1-3
REGEQU $JM_SAMPLE+4 JM_SAMPLENUMBER ; the sample number is in word 4
.RORG JM_REGS 0x900 ; jitter mode working registers
REGBLK $JM_REGS JM_FRAMESTART[3] ; 3 words for the frame sync and type
REGBLK $JM_REGS JM_SAMPLESTART[3] ; 3 words for sample start and length
REGBLK $JM_REGS JM_TOTALS[3] ; this counts samples and length
REGEQU $JM_TOTALS JM_TOTALSAMP ; this counts samples
REGEQU $JM_TOTALS+1 JM_TOTALLENGTH ; total length accumulated here
REGBLK $JM_REGS JM_OUTPUT[9] ; used for movblk and hss enter
REGBLK $JM_REGS JM_COPYSAMP[4] ; used to copy the sample (reg to mem)
REGBLK $JM_REGS JM_SAMPLEN32[2] ; 32 bit version of the length
REGBLK $JM_REGS JM_LITERALS[10] ; 10 jitter mode literals
REGEQU $JM_LITERALS JM_LITERAL3L ; used to add 3 to addresses and lengths
REGEQU $JM_LITERALS+2 JM_LITERAL6L ; added to total length for the hssenter
REGEQU $JM_LITERALS+4 JM_LITERAL3F ; used to test for the 64th sample
REGDEF $JM_REGS JM_RESTART ; indicates restart at the next sample
REGDEF $JM_REGS JM_TEMP ; used for output test
.ORG 0x1000 2
; Jitter mode starts at 0x1000 got this address must be laoded into que vecotr 2
JITTER_MODE:
DTBIN $JM_INFOBLK 16 ; get 16 words from cc (really only 1 is used)
DTBIN $JM_SAMPLE 2000 ; get the data block
BRANCHIF $JM_SAMPLENUMBER &Jm_10 ; if this is the first JM sample
BRANCHIF $JM_RESTART &Jm_15 ; or if this is a restart
Jm_10:
SETREGS $JM_FRAMESTART 3 0x352E 0xF853 0xFFF0 ;setup frame sync
SAVERLST $JM_FRAMESTART 3 7:0 ; in page 7
SETREGS $JM_SAMPLESTART 2 0xF0F0 0xE0E0 ; init the sample sync
SETREGS $JM_LITERALS 5 3 0 6 0 0x3F ; init Literals
SETREG $JM_RESTART 1 ; set the restart flag
SETREG $JM_RESTART 0 ; clear the restart flag
SETREGS $JM_OUTPUT 9 0 0 0 0 0 0 0 0 0 ; init the output block
SETREGS $JM_TOTALS 3 0 0 0 ; init the sample counter
SETREGS $JM_SAMPLEN32 2 0 0 ; init the length counter
SETREGS $JM_COPYSAMP 4 0x2000 0 7:6 ; init the buffer pointer
COPYRD2D $JM_SAMPLETIME $HSSTIME 3 ; Save the timewords
Jm_15:
SETREGS $JM_COPYSAMP 2 $JM_SAMPLESTART 3 ; Copy sample sync and length
COPYREG $JM_SAMPLEN $JM_SAMPLESTART+2 ; to memory
SAVERLSI $JM_COPYSAMP
ADDADR $JM_LITERAL3L $JM_COPYSAMP+2 $JM_COPYSAMP+2 ; add 3 to the pointer
SETREG $JM_COPYSAMP 0x2000 ; set up data copy
COPYREG $JM_SAMPLEN $JM_COPYSAMP+1
SAVERLSI $JM_COPYSAMP ; copy the new data block
COPYREG $JM_SAMPLEN $JM_SAMPLEN32 ; add sample length
ADDADR $JM_SAMPLEN32 $JM_COPYSAMP+2 $JM_COPYSAMP+2 ;to buffer pointer
ADDREGD $JM_TOTALSAMP 1 ; increment the sample count
ADDADR $JM_SAMPLEN32 $JM_TOTALLENGTH $JM_TOTALLENGTH ; add sample length plus
ADDADR $JM_LITERAL3L $JM_TOTALLENGTH $JM_TOTALLENGTH ; 3 to total length
REGAND $JM_LITERAL3F $JM_SAMPLENUMBER $JM_TEMP ; do the output if
BRANCHEQ $JM_TEMP 0x3F &Jm_20 ; the low 6 bits of sample number
BRANCHGT $JM_TOTALSAMP 63 &Jm_20 ; are all 1's or this is the 64th sample
ENDMAC ; if not, ENDOFMACRO
Jm_20:
SETREG $JM_RESTART 1 ; set the restart flag
ADDADR $JM_TOTALLENGTH $JM_LITERAL6L $HSSLEN ; add the 6 for the hdr
CALLQUE &HssExtraSub ; see if extra word is needed
ADDADR $EXTRAWORD $JM_TOTALLENGTH $JM_TOTALLENGTH
SAVERLST $JM_TOTALS 3 7:3 ; save sample count and length
ADDADR $JM_TOTALLENGTH $JM_LITERAL6L $JM_TOTALLENGTH ; set the length
COPYRD2D $JM_TOTALLENGTH $JM_OUTPUT+4 2
COPYRD2D $JM_TOTALLENGTH $HSSCOUNT 2
HSSADDR $HSSADR ; get the output queue address
COPYRD2D $HSSENTERBLK+1 $JM_OUTPUT+2 2
SETREGS $JM_OUTPUT 2 7:0
MOVBLKI $JM_OUTPUT ; move the data to the output queue
SETREG $HSSAPID 0x3C ; 3c for now ; the apid is 48 (72 decimal)
CALLQUE &HssOutSub ; call the output subroutine
Jm_99: ENDMAC ; ENDOFMACRO
;*********************** DHC MEMORY DUMP *****************
; Memory Dump Program
; This program dumps data from a memory page to the high speed serial (HSS) output. It
; is invoked by interrupt vector 3. Upon call, Register 50,51 contain a main memory
; address (page and offset), registers 52,53 contain the number of words. The word order
; is the usual low,high. The program issues an int 3 to the CC in order to get timewords
; to label the packets. It then transfer the data to the HSS by the normal sequence
; HSSENTER... HSSSWAP.
; The output format is FRAMESYNC DATATYPE ADDRESS WORDCOUNT DATA
; FRAMESYNC 2 words containing 352E F853
; DATATYPE 1 word containing FFF2
; ADDRESS 2 words containing the starting address
; WORDCOUNT 2 words containing the number of words of dump data
;
; Note: the dump may contain one more word than the request if the requested data length
; does not satisfy the criterion that packets always end on a double word boundary.
.RORG DMP_IN 0x50 ; dump parametrs arrive here
REGBLK $DMP_IN DMP_INADD[2] ; The input address
REGBLK $DMP_IN DMP_INCOUNT[2] ; The input word count
.RORG DMP_PARAMS 0x980 ; DUMP Program paramters area
REGBLK $DMP_PARAMS DMP_HEADER[7] ; 7 header words
REGEQU $DMP_HEADER DMP_FRAMESTART ; equates for readability
REGEQU $DMP_HEADER+3 DMP_OUTADD
REGEQU $DMP_HEADER+5 DMP_OUTCOUNT
REGBLK $DMP_PARAMS DMP_MOVBLK[6] ; for move regs and data to hss queue
REGBLK $DMP_PARAMS DMP_LITERAL7L[2] ; the length of the header
.ORG 0x1100 3
DumpMem:
SETREG $DMP_FRAMESTART+2 0xFFF2
CALLQUE &DumpSub
ENDMAC
;
; The Dump Subroutine does all the word. Caller sets framestart+2 to the dumpid
; id's are: fff2 for memory and FFF6 for DTB and FFF4 for register.
;
DumpSub:
SETREGS $DMP_LITERAL7L 2 7 0 ; long word 7
SETREG $LOBTADD $HSSTIME ; timewords go directly to hssenter block
CALLQUE &Int3Sub ; get the timewords
COPYRD2D $DMP_INCOUNT $HSSLEN 2 ; determine if an extra word is needed
ADDADR $HSSLEN $DMP_LITERAL7L $HSSLEN ;account for header
CALLQUE &HssExtraSub ; the sub does it
COPYRD2D $DMP_INADD $DMP_OUTADD 4 ; copy input address and count to header
ADDADR $DMP_OUTCOUNT $EXTRAWORD $DMP_OUTCOUNT ; add extra word flag as needed
SETREGS $DMP_FRAMESTART 2 0x352E 0xF853 ; setup sync and type
HSSADDR $HSSADR ; get the hss address
COPYRD2D $HSSADR $DMP_MOVBLK+2 2 ; setup to move header for
SETREGS $DMP_MOVBLK 2 $DMP_FRAMESTART 7 ; register space directly to hss
SAVERLSI $DMP_MOVBLK ; done
ADDADR $HSSADR $DMP_LITERAL7L $DMP_MOVBLK+2 ; add header length to hss address
COPYRD2D $DMP_INADD $DMP_MOVBLK 2 ; setup data move
COPYRD2D $DMP_OUTCOUNT $DMP_MOVBLK+4 2
MOVBLKI $DMP_MOVBLK ; move directly to hss area
SETREG $HSSAPID 0x3C ; for now 0x49 eventuaslly dumps go out under 73 (dec)
ADDADR $DMP_OUTCOUNT $DMP_LITERAL7L $HSSCOUNT ; add header length to outcount
CALLQUE &HssOutSub
Dm_99: RTNQUE ; ENDOFMACRO
; ********************* Catch-up Program ***************
;
; This tiny program forces an HSS buffer swap. To be used if the image(s) currently
; queued must be sent out now.
;
.ORG 0x1200 4
HssOutProg:
HSSSWAP &Hso_10 &Hso_10
Hso_10: ENDMAC
; ********************** Initialization Program **********
;
; This program does an HSSADDR and a swap, which are needed to initialize the
; DHC output queing. Also initializes CC copy of queu version and patch by
; invoking an interrupt 3
;
.RORG INIT_PARAMS 0x9C0
REGBLK $INIT_PARAMS INIT_TW[3]
.ORG 0x1300 5
InitProg:
CALLQUE &InitLiteralSub
SETREG $LOBTADD $INIT_TW
CALLQUE &Int3Sub
ENDMAC
; ********************** DTB Dump Program **********
;
; This program dumps 8192 words from the DTB starting at address 2000 . The
; length of the dump is specified in regsiter is always 8191.
; **** What I do for now is copy the data to the upper area of page 7, set
; up 50-53 for a dump and go to the dump program.
.RORG DTBD_DATA 0x2000
REGBLK $DTBD_DATA DTBD_SAMPLE[8192]
.RORG DTBD_PARAMS 0x9D0
REGBLK $DTBD_PARAMS DTBD_SYNC[3]
.ORG 0x1400 6
DtbdProg:
DTBIN $DTBD_SAMPLE 0x1FFF
SAVERLST $DTBD_SAMPLE 0x2000 3 0x3811
SETREGS $DTBD_SYNC 0xFFF6 0x2000 0x1FFF
SAVERLST $DTBD_SYNC 3 0 0x3811
SETREG $DMP_FRAMESTART+2 0xFFF6
SETREGS 0x50 4 0 0x3811 8195 0
CALLQUE &DumpSub
ENDMAC
; ********************** Register Dump Program **********
;
; This program dumps registers. Start register and number of registers
; are in registers 91 and 92 (hex). This program also uses 90, 93 and 94.
; A sync word (FFF4), the start register, count, and the requested
; registers are transferred to the upper part of page 7. Then the general
; purpose dump subroutine is called to do the output.
.RORG REGD_INPUT 0x90
REGBLK $REGD_INPUT REGD_CALL[5]
.RORG REGD_PARAMS 0x9E0
REGBLK $REGD_PARAMS REGD_SYNC[3]
.ORG 0x1500 7
RegProg:
SETREGS $REGD_CALL+3 2 3 0x3811
SAVERLSI $REGD_CALL+1
SETREG $REGD_CALL 0xFFF4
SAVERLST $REGD_CALL 3 0 0x3811
SETREG $DMP_FRAMESTART+2 0xFFF4
SETREGS 0x50 4 0 0x3811 8195 0
COPYREG $REGD_CALL+2 0X52
ADDREGD 0x52 3
CALLQUE &DumpSub
ENDMAC
; ********************** ErrorLog Dump Program **********
;
; Copies the error log and dumps it.
; A sync word (FFF8), constant (3811) , count, and the error log
; are transferred to the upper part of page 7. Then the general
; purpose dump subroutine is called to do the output. This is all
; new in version 1.27. This uses the memory dump registers (50-53)
.ORG 0x1600 8
RegProg: ; (Vr1.27)
SETREGS $DMP_INADD 2 3 0x3811 ; Set up errlog call (Vr1.27)
COPYELOG $DMP_INADD ; (Vr1.27)
SETREG $DMP_INADD 0xFFF8 ; Set sync word in Page 7 (Vr1.27)
SAVERLST $DMP_INADD 3 0 0x3811 ; sync,3811, count to p7 (Vr1.27)
SETREG $DMP_FRAMESTART+2 0xFFF8 ; sync mark for dumpsub (Vr1.27)
SETREG $DMP_INADD 0 ; 0 to low address (Vr1.27)
SETREG $DMP_INADD+3 0 ; 0 to high count (Vr1.27)
ADDREGD $DMP_INADD+2 3 ; count the 3 xtra wrds (Vr1.27)
CALLQUE &DumpSub ; (Vr1.27)
ENDMAC ; (Vr1.27)
; ********************** General Utilities for all Programs
.RORG UTIL 0x1800 ; register space at 1800
.ORG 0x1E00
; HssExtraSub -
; This routine determines if an extra word is needed for an HSS data product
; Caller sets HSSLEN (2 words) to the desired length
; Routines sets the double word, extra word to 0,0 (extra not needed)
; or 1,0 (extra word needed)
; The double word allows the caller to do an addadr with the result
REGBLK $UTIL HSSLEN[2]
REGBLK $UTIL EXTRAWORD[2]
HssExtraSub:
HSSMOD $HSSLEN $EXTRAWORD ; get len mod 505
BRANCHIF $EXTRAWORD &Hse_20 ; 0 is okay
BRANCHGT $EXTRAWORD 0 &Hse_10 ; if negative
ADDREGD $EXTRAWORD 505 ; make if positive
Hse_10:
REGAND $EXTRAWORD $LITERAL1 $EXTRAWORD ; as are all odd numbers
REGXOR $EXTRAWORD $LITERAL1 $EXTRAWORD ; evens require extra word
Hse_20: SETREG $EXTRAWORD+1 0 ; make sure MSW is 0
RTNQUE
; Sub32Sub -
; This routine performs a 32 bit subraction. The caller places the minuend and
; subtrahend in SUB32IN. The routine places the result in SUB32OUT.
; .... that is SUB32OUT = SUB32IN - SUB32IN+2. 32 bit arguments are in the usual
; dhc order: low, high.
REGBLK $UTIL SUB32IN[4] ; source input buffer
REGEQU $SUB32IN SUB32MIN ; minuend
REGEQU $SUB32IN+2 SUB32SUBT ; subtrahend
REGBLK $UTIL SUB32OUT[2] ; result
REGBLK $UTIL SUB32TEMP[5] ; temps for 32 bit compare and borrow
REGEQU $SUB32TEMP+4 SUB32BORROW ; equate for the borrow flag
Sub32Sub:
SETREGS $SUB32TEMP 5 0 0 0 0 0 ; initialize registers
COPYREG $SUB32IN $SUB32TEMP ; do 32 compare of lower 16 to
COPYREG $SUB32IN+2 $SUB32TEMP+2 ; determine id borrow required
COMPLONG $SUB32TEMP $SUB32TEMP+2 &Sub32_20 &Sub32_20 &Sub32_10
Sub32_10:
SETREG $SUB32BORROW 1 ; need a borrow
Sub32_20:
REGSUB $SUB32IN $SUB32IN+2 $SUB32OUT ; subtract low then high
REGSUB $SUB32IN+1 $SUB32IN+3 $SUB32OUT+1
REGSUB $SUB32OUT+1 $SUB32BORROW $SUB32OUT+1 ; borrow as needed
RTNQUE
; HssOutSub-
; This routine handles the final stages of an output. Does and
; HSSENTER and and HSSSWAP. (For VR 1.1F-1.20 timeword was swapped
; here. From VR1.21 on, caller must pass in correct timewords).
; Caller must place hssenter parameters in HSSENTERB
REGBLK $UTIL HSSENTERBLK[8] ; Caller builds the call here
REGEQU $HSSENTERBLK HSSAPID ; Equivalences for readability
REGEQU $HSSENTERBLK+1 HSSADR
REGEQU $HSSENTERBLK+3 HSSCOUNT
REGEQU $HSSENTERBLK+5 HSSTIME
HssOutSub:
HSSENTER $HSSENTERBLK
HSSSWAP &HssOut99 &HssOut99
HssOut99:
RTNQUE
; Int3Sub -
; This routine handles the interrupt 3 processing. It executes a DTBOUT of
; REG 70-7F. Does an Int3 and transfers the (3) timewords to the callers location
; which is specified in LOBTADD.
; Added timewords swap in version 1.21
.RORG INT3_IN 0x60 ; where the cc puts lobt
REGBLK $INT3_IN INT3_LOBT[3]
.RORG INT3_OUT 0x70 ; DHC-CC communications area
REGBLK $INT3_OUT INT3_OUTPUTBLOCK[16]
REGEQU $INT3_OUTPUTBLOCK INT3_VRPN
REGDEF $UTIL LOBTADD ; caller supplied register number
REGDEF $UTIL LOBT_TEMP ; For timeword swap (VR1.21)
Int3Sub:
SETREG $INT3_VRPN 0x012A ; Version 1.2A
DTBOUT $INT3_OUTPUTBLOCK 16 ; output 70-7f
SETIRPT 3 ; interrupt the cc for timewords
DTBIN $INT3_LOBT 3 ; get timewords
COPYREG $INT3_LOBT $LOBT_TEMP ; swap timewords 1 and 3 (VR 1.21)
COPYREG $INT3_LOBT+2 $INT3_LOBT
COPYREG $LOBT_TEMP $INT3_LOBT+2
COPYRD2I $INT3_LOBT $LOBTADD 3 ; return to caller
RTNQUE
;