:TITLE[EOMLoTask]; % Edit by Fiala 17 March 1982: absort EOMInit code; have init fall dirctly into eomLoSleep. Edit by Fiala 28 April 1981: Replaced pNWW by IP[NWW]C. Edit by srd March 27, 1980 4:51 PM Put in new list overflow notify Edit by srd March 27, 1980 4:38 PM Fixed OUTPUT and LOADPAGE gotchas Edit by srd March 26, 1980 4:02 PM Modified low task size specification. Edit by srd March 24, 1980 9:12 AM Eliminated font banks. Edit by srd February 26, 1980 2:34 PM Added hooks for verdi disk change, put in font bank bypass code, and diagnostic register dump. Edit by rej August 6, 1979 1:45 PM The low task constructs parameter blocks, handles Mesa requests, and processes various error conditions. % SetTask[eomLoTask]; eomLoTaskInit: eomCsbBaseLo _ (eomLhLoCsbBase), At[eomLoTaskInitLoc]; eomCsbBaseLo _ (eomCsbBaseLo) or (eomRhLoCsbBase); eomCsbBaseHi _ (eomLhHiCSBbase); LoadPage[eomLoTaskPage] ; eomCsbBaseHi _ (eomCsbBaseHi) or (eomRhHiCSBbase), GoToP[.+1]; OnPage[eomLoTaskPage]; eomLoSleep: Call[eomLoTaskSwitch]; eomLoRun: T _ eomBandListPointer; *Set up the offset for fetching the new list entry. The pointer is not *incremented here, because we may go to special reason processing, or *the new list may be full, and we may have to fetch this list entry again *This must be the second instruction for the IOATTEN to work properly. DBLGOTO[eomSpecialReason,eomBuildBlock,IOATTEN]; % ******************** This is the normal low task activity. The code comes here if there is no IOATTEN present at eomLoRun+1. % ******************** eomBuildBlock: *T already loaded above PFETCH2[eomBandListA,eomBListEntryA]; *force the interlock to work and dispatch on the three most *significant bits of the entry type code *This will process the most common type of band list entries on the first *dispatch. DISPATCH[eomBListEntryA,0,3], LU _ eomBListEntryA; *Now we can increment the offset pointer because the new list is known to *contain space for the parameter block. T will be used as a memory offset *if the entry is a rule. DISP[eomEntryType], eomBandListPointer _ T _ (eomBandListPointer) + (2C); % ******************** BLOCK BUILDER TRANSFER BRANCH 0 This branch processes type 1 band list entries with font IN [0..7] % ******************** eomEntryType: *high 2 font bits are zero, pick up the low 3 bits in T and get the parm *block fragment. T _ LDF[eomBListEntryB,0,3], GOTO[eomGenFontParmBlock], AT[loTaskBlockBldDispatch]; % ******************** BLOCK BUILDER TRANSFER BRANCH 1 This branch processes type 1 band list entries with font IN [10B..17B] % ******************** *the high 2 font bits are known to be 01, pick up the low 3 bits T _ (10C), GOTO[eomConstructFontCode], AT[loTaskBlockBldDispatch,1]; % ******************** BLOCK BUILDER TRANSFER BRANCH 2 This branch processes type 1 band list entries with font IN [20B..27B] % ******************** *the high 2 font bits are known to be 10, pick up the low 3 bits T _ (20C), GOTO[eomConstructFontCode], AT[loTaskBlockBldDispatch,2]; % ******************** BLOCK BUILDER TRANSFER BRANCH 3 This branch processes type 1 band list entries with font IN [30B..37B] % ******************** *the high 2 font bits are known to be 11, pick up the low 3 bits T _ (30C), AT[loTaskBlockBldDispatch,3]; eomConstructFontCode: T _ (LDF[eomBListEntryB,0,3]) OR T, GOTO[eomGenFontParmBlock]; % ******************** BLOCK BUILDER TRANSFER BRANCH 4 This branch processes type 2 band list entries (Rules). % ******************** eomBuildRule: *this is a 4 word band list entry, fetch the other 2 words and stash in *eomFragA and eomFragB which will not be used otherwise. Note that eomFragC and *eomFragD do not contain any information, and may be used as temps. T was *already loaded with eomBandListPointer at the top level dispatch. PFETCH2[eomBandListA,eomFragA], AT[loTaskBlockBldDispatch,4]; *Pick up the rule load block number. *(most significant 6 bits of the rule load number) T _ LDF[eomBListEntryB,0,6], TASK; *Bump the band list pointer to account for words 3 and 4 of the rule entry. eomBandListPointer _ (eomBandListPointer) + (2C); *Fetch a double word from the junk area. This has been initialized by the *application software to contain a skeleton of a rule parameter block. *The words at 10 and 11 contain word 0 and a font bank relative pointer *to the beginning of the rule loads. PFETCH2[eomParameterTransferBaseA,eomFragC,10]; *Stash the rule load block number in eomTemp for shifting. eomTemp _ T; *Construct partial parameter word 2 to indicate *blocks to request = 0, rule = true, save partial state, *previous line not present, line buffer position = 0. eomParmC _ (ruleParmWord2); *Pick up the word pointer from the low 4 *bits of the rule load number field in the second band list entry word and *shift to the proper field. T _ (170000C); T _ (LSH[eomBListEntryB,6]) AND T; *Stash away the completed word 2 of the parameter block. eomParmC _ (eomParmC) OR T; *Fetch the short base pointer which was obtained from the junk area. T _ eomFragD; *Multiply the rule number by 16 and add to the base. The subroutine merges *the current default zPlane information into this and stores the result in *eomParmB (rule parameter word 1). T _ (LSH[eomTemp,4]) + T, CALL[eomSnarfZPlaneInfo]; T _ (eomFragC), USECTASK, CALL[eomStashTInParmA]; *Construct the mask for use in building the height. This mask has zero *bits (which will be complemented to one bits) in the positions where *the raw data flag and the fresh start bit must go. T _ (34000C); *construct parameter word 3 to indicate fresh start, raw data, nibble *pointer = 0, font, and height from band list entry. Also compute *adjustment to height, and compute rule mask. *Dispatch on the 2 least significant bits of the height. DISPATCH[eomFragB,16,2]; *eomFragC now has ones in bits 5-15 and a 1 in bit position 1. eomFragC _ (ZERO) OR NOT T, DISP[eomSetUpRuleMask0]; *eomFragD is no longer significant, so it is used here as a temp eomSetUpRuleMask0: *set up T to indicate no adjustment to height T _ (1C), AT[ruleMaskDispatch]; *set up eomFragD to provide 000 for the rule mask and indicate rule eomFragD _ (200C), GOTO[eomMergeHeight]; eomSetUpRuleMask1: *set up eomFragD to provide 111 for the rule mask and indicate rule eomFragD _ (360C), GOTO[eomMergeHeightSetT], AT[ruleMaskDispatch,1]; eomSetUpRuleMask2: *set up eomFragD to provide 011 for the rule mask and indicate rule eomFragD _ (260C), GOTO[eomMergeHeightSetT], AT[ruleMaskDispatch,2]; eomSetUpRuleMask3: *set up eomFragD to provide 001 for the rule mask and indicate rule eomFragD _ (220C), GOTO[eomMergeHeightSetT], AT[ruleMaskDispatch,3]; eomMergeHeightSetT: *Set T to indicate a +1 adjustment to the height. T _ (0C); eomMergeHeight: *pick up the 11 most significant bits of the height from the band list entry *and subtract the increment value. This increment value will be either 0 or 1. *The value supplied to the hardware must be one less than the value in the *band list entry. Therefore, if the increment value is one, subtract 0 and if *it is zero, subtract 1. T _ (LDF[eomFragB,3,13]) - T, CALL[eomLoTaskSwitch]; *Take the ones complement of the height, and mask off the most significant *bits to restrict the value to only the height field. The FRD bit is *automatically generated at this point, since the most significant bits of *NOT T will be ones. T _ (eomFragC) AND NOT T; *Stash away parameter word 3 and output the quad word to the new list. eomParmD _ T, CALL[eomRuleStashSub]; *Parameter block word 4 need not be initialized in this case because of the *rule being forced raw data. *Pick up the width from the band list entry. The subroutine stashes it in *eomParmB. T _ eomFragA, USECTASK, CALL[eomStashTInParmB]; *set up the X and Y values T _ LDF[eomBListEntryB,12,6]; *stash the X value eomParmC _ T; T _ LDF[eomBListEntryA,3,15]; *stash the Y value and output the quadWord to the new list eomParmD _ T, CALL[eomRuleStashSub]; *construct word 8 of the parameter block *eomFragD already contains the low byte of word 8, except for the ink setting, *from the rule setup dispatch above. T _ (eomFragD) OR (partialStateSave); *indicate partial state save *The sign bit of the eomInkSetting, which is used as a fast branch *flag to indicate abnormal ink must be masked out. *Goto eomAbnormalInkA to stash parameter word 8 and output the quadWord *to the new list. T _ (RHMASK[eomInkSetting]) OR T, GOTO[eomAbnormalInkA]; % ******************** BLOCK BUILDER TRANSFER BRANCH 5 This branch processes type 3 band list entries (Command Codes). % ******************** *dispatch on the 4 bits of command DISPATCH[eomBListEntryA,6,4], AT[loTaskBlockBldDispatch,5]; DISP[eomType6NOP]; eomType6NOP: *this is the nop command GOTO[eomLoSleep], AT[type6Dispatch]; eomType6EOP: *This is the end of page command. This is faked by setting the flag to indicate *end of band processed, and backing up the band list pointer to point once again *to the end of page entry. *Set up for the branch on EOP already sent. LU _ (eomState) AND (eopAlreadySent), AT[type6Dispatch,1]; *Do the branch, and set up eomFragB in case the branch is taken. GOTO[eomFirstEOPencounter,ALU=0], eomState _ (eomState) OR (eopAlreadySent); *Go and pause the low task. Also back up the band list pointer. eomBandListPointer _ (eomBandListPointer) - (2C), GOTO[eomType6EOB]; eomFirstEOPencounter: *Back up the band list pointer. eomBandListPointer _ (eomBandListPointer) - (2C); *Task out due to length of modify wakeup reasons subroutine. CALL[eomLoTaskSwitch]; *Store the modified wakeup reasons. T _ (EOPProcessed), CALL[eomModifyWakeupReasons]; *Go to pause the low task. GOTO[eomNoNewListOverflow]; eomType6EOB: *Check for new list overflow. First, pick up the maximum allowable new *list pointer value (the start of old list). T _ (eomState) AND (newListSizeMask), AT[type6Dispatch,2]; CALL[eomLoTaskSwitch]; *Subtract this from the current end of new list. LU _ (eomNewListWrite) - T; DBLGOTO[eomNewListOverflow,eomNoNewListOverflow,ALU>=0]; eomNewListOverflow: *The new list has overflowed, send the error notify. T _ (newListOverflow); CALL[eomModifyWakeupReasons]; NOP; eomNoNewListOverflow: *This is the end of band command. This simply sets the band done flag, *and pauses the low task. eomState _ (eomState) OR (bandDone); *Output the command for the low task automaton to pause. Also, activate the *high task if it needs it. It could be paused waiting for the band done *indication before sending out the end of band character. INPUT[eomTemp,resetLoTaskRun]; LU _ eomTemp, CALL[eomActivateHiTaskFromLoTask]; GOTO[eomLoSleep]; eomType6ZPlane: *this is the z-Plane change command. *pick up the z-Plane. T _ LDF[eomBListEntryA,14,4], AT[type6Dispatch,3]; eomZPlane _ T; *Pick up the ink setting, shift and mask to place it in the field where *it is used. T _ (14C); T _ (RSH[eomBlistEntryA,10]) AND T; *Stash the ink setting, and check for abnormal ink. *Abnormal ink is anything except visible black. DBLGOTO[eomNormalInk,eomAbnormalInk,ALU=0], eomInkSetting _ T; eomNormalInk: *Normal ink; don't do anything funny. GOTO[eomLoSleep]; eomAbnormalInk: *abnormal ink. Set the sign bit to be used as a fast branch flag *to indicate the abnormality eomInkSetting _ (eomInkSetting) OR (abnormalInkIndication), GOTO[eomLoSleep]; eomType6Link: *This is the link format T _ eomBListEntryB, AT[type6Dispatch,4]; eomBandListPointer _ T, GOTO[eomLoSleep]; eomType6Link&EOB: *this combines link format with end of band. Perform the link *here, then branch to the EOB code. T _ eomBListEntryB, AT[type6Dispatch,5]; eomBandListPointer _ T, GOTO[eomType6EOB]; eomType6Link&ZPlane: *this combines link format with z-plane change. Perform the link here, *then branch to the z-Plane change code. T _ eomBListEntryB, AT[type6Dispatch,6]; eomBandListPointer _ T, GOTO[eomType6ZPlane]; eomType6FBank: *this is a font bank change GOTO[eomLoSleep], AT[type6Dispatch,7]; eomType6FBank&EOB: *this combines a font bank change with an end of band. The font bank *is done here, then the EOB code is branched to GOTO[eomType6EOB], AT[type6Dispatch,10]; eomType6FBank&ZPlane: *this combines a font bank change with a z-Plane change. The font bank *change is done here, followed by a branch to the z-Plane code. GOTO[eomType6ZPlane], AT[type6Dispatch,11]; % ******************** BLOCK BUILDER TRANSFER BRANCH 7 This branch processes type 4 band list entries (Images). % ******************** eomBuildType2: T _ eomBListEntryB, CALL[eomBuildType4Sub], AT[loTaskBlockBldDispatch,7]; T _ (eomBListEntryB) + (4C), CALL[eomBuildType4Sub]; T _ (eomBListEntryB) + (10C), CALL[eomBuildType4Sub]; *increment the write pointer to take account of the last quadword, which *is not transferred. Go and remove the hi task pause, if one is in effect. eomNewListWrite _ (eomNewListWrite) + (4C), GOTO[eomActivateHiTask]; % ******************** This is the exceptional low task activity. The code comes here if there is an IOATTEN present at eomLoRun+1. % ******************** eomSpecialReason: *Get the wakeup reason from the hardware. NOTE-- this value in eomFragc *is also used in the eomMesaCommand dispatch if the special reason is a *mesa command. INPUT[eomFragC,loTaskStatus]; CALL[eomLoTaskSwitch]; *dispatch on the reason DISPATCH[eomFragC,16,2], LU _ eomFragC; *force the interlock to work; *Load up a 1 for use if the branch is band switch. eomFragB _ (1C), DISP[eomNoStatus]; % ******************** SPECIAL TRANSFER BRANCH 0 This branch is an error. Status zero should never occur with the IOATTEN line raised. % ******************** eomNoStatus: GOTO[eomLoSleep], AT[loTaskMainDispatch]; % ******************** SPECIAL TRANSFER BRANCH 1 This code is run if a parity error was detected. % ******************** eomParityError: *Merge the parity error wakeup reason in with whatever else is already *there. T _ (parityError), AT[loTaskMainDispatch,1]; CALL[eomLoTaskSwitch]; *This subroutine is so long, must task right before calling it. CALL[eomModifyWakeupReasons]; INPUT[eomTemp,resetParityError]; eomLoTaskResetInterlock: LU _ eomTemp, GOTO[eomLoSleep]; % ******************** SPECIAL TRANSFER BRANCH 2 The code comes here to handle a mesa request. % ******************** eomMesaCommand: *Pick up the mesa command field and dispatch on it. DISPATCH[eomFragC,11,3], AT[loTaskMainDispatch,2]; DISP[eomMesaCommandBase]; eomDummyDispatch5: GOTO[eomResetMesaRequestCode], AT[loTaskMesaDispatch,5]; % ******************** MESA COMMAND TRANSFER BRANCH 0 - - SECOND LEVEL DISPATCH Parametric Page Generation Startup The code comes here to handle a type 0 Mesa request: set up internal registers from the CSB and start generating parameter blocks. This is the normal parametric page printing start. % ******************** eomMesaCommandBase: *Clear the bitMapFirst indication, and indicate parametric time *operation starting from the new list eomState _ (newListAndParametricMode), AT[loTaskMesaDispatch]; eomMesaCommandBaseA: *This is the entry point from the real time page print option. *Fetch the long pointer to the working storage. Also activate the low *task wakeup automaton. PFETCH2[eomCsbBaseLo,eomParameterTransferBaseA,workingStorageOffset], CALL[eomActivateLoTask]; *Fetch the skeleton for the band buffer command word. *This skeleton will be in word 12B of the junk area. Also, initialize the *new list ring. PFETCH1[eomParameterTransferBaseA,eomFragA,12], CALL[eomInitNewList]; *Fetch the word to be sent to the OPC startup register, and the indication *of how large the new list should be. PFETCH2[eomCsbBaseLo,eomFragC,mesaCommandOffset], CALL[eomLoTaskSwitch]; *eomFragD contains the new list size in the 5 low order bits. eomFragD _ LSH[eomFragD,12]; *Be paranoid, mask the field in case Mesa is being bad. T _ (eomFragD) AND (newListSizeMask); eomState _ (eomState) OR T; *initialize the workspace. The low 16 words of the workspace are reserved *for misc. junk. eomOldListRead _ T; eomOldListWrite _ T; *fetch the long pointer to the band list PFETCH2[eomCsbBaseLo,eomBandListA,bandListOffset]; *initialize the offset from the band list base eomBandListPointer _ (0C); *Initialize the active attributes to image, to force a setup for any first *data block. The sign bit set means that the initial data block handler in *the hi task will not attempt to save any parameters about image 3 away in *the junk area. (eomActiveAttributes = 7 implies image # 3) eomActiveAttributes _ (ZERO) - 1; *Fetch the short pointer to the parameter block fragments. Note that this *pointer is relative to the working storage long pointer PFETCH1[eomCsbBaseLo,eomFragments,fragmentsOffset]; *indicate no parameter blocks in either list *empty is indicated by the sign bit set, that is, -1. eomOldBlocksFull _ (ZERO) - 1; eomOldBlocksReturned _ (ZERO) - 1; *Output the band buffer command fetched from word 12B in the junk area. OUTPUT[eomFragA,bandBufferCmndReg]; *Initialize to hi task not paused. eomState _ (eomState) OR (hiTaskRunning); *Perform the OUTPUT to start the EOM. OUTPUT[eomFragC,opcStartupOut]; eomResetMesaRequestCode: *reset the Mesa request *This is the location to branch to when the mesa request needs resetting. INPUT[eomTemp,resetMesaCommand], GOTO[eomLoTaskResetInterlock]; % ******************** MESA COMMAND TRANSFER BRANCH 1 - - SECOND LEVEL DISPATCH Reset Wakeup Reason % ******************** eomResetWakeupReason: *ALL CODE BETWEEN THE PFETCH4 AND THE PSTORE4 MUST BE DONE WITHOUT A TASK *SWITCH, OTHERWISE THE HIGH TASK COULD MODIFY THE WAKEUP REASON AFTER THE *PFETCH AND BEFORE THE PSTORE AND THAT MODIFICATION WOULD BE DESTROYED *WHEN LO TASK DID THE PSTORE4 *Pick up the current wakeup reason word in eomParmB and the mesa command *in eomParmC. PFETCH4[eomCsbBaseLo,eomParmA,wakeupMaskOffset], AT[loTaskMesaDispatch,1]; *Load T with the mask to use (from mesa command). T _ eomParmC; *The usectask call is manditory to allow time for eomFragB to be properly *stored prior to the start of the PSTORE. eomParmB _ (eomParmB) AND T, USECTASK, CALL[eomLoTaskSwitch]; *Store the masked reasons word back in the CSB. PSTORE4[eomCsbBaseLo,eomParmA,wakeupMaskOffset], CALL[eomLoTaskSwitch]; GOTO[eomResetMesaRequestCode]; % ******************** MESA COMMAND TRANSFER BRANCH 2 - - SECOND LEVEL DISPATCH Continue Parametric Page Print % ******************** eomContinueParaPrint: *Clear the bitMapFirst indication. The parametric operation flag is still *set. Also indicate no freezeEOBChar state. eomState _ (eomState) AND NOT (firstParametricAndBandDone), AT[loTaskMesaDispatch,2]; eomState _ (eomState) AND NOT (freezeEOBChar); *Activate the low task. This subroutine does not use T. T _ eomOldBlocksReturned, CALL[eomActivateLoTask]; *Set the old blocks full value for the upcoming band to the number of blocks *returned in the previous band. Also, initialize the new list parameters. eomOldBlocksFull _ T, CALL[eomInitNewList]; *Initialize the active attributes to image, to force a setup for the first *data block of the next band. Without this, the data transfer base can be *left pointing to the bitmap return buffer. The sign bit set means that the *initial data block handler in the hi task will not attempt to save any *parameters about image 3 away in the junk area. (eomActiveAttributes = 7 *implies image # 3) eomActiveAttributes _ (ZERO) - 1; *Set the old blocks returned value to its initial value to indicate no blocks *returned. Also, activate the hi task. eomOldBlocksReturned _ (ZERO) - 1, CALL[eomActivateHiTaskFromLoTask]; *Reset the mesa request wakeup for the lo task. GOTO[eomResetMesaRequestCode]; % ******************** MESA COMMAND TRANSFER BRANCH 3 - - SECOND LEVEL DISPATCH Increment Image Sector Value % ******************** eomIncrementImSectVal: *Pick up the image number to increment the sector count from. *eomFragA will contain the image number (0,1,2, or 3). PFETCH1[eomCsbBaseLo,eomFragA,mesaCommandOffset], AT[loTaskMesaDispatch,3]; *Set up the offset for fetching the sector count T _ (20C); T _ (LSH[eomFragA,2]) + T, CALL[eomLoTaskSwitch]; * *ALL THE CODE BETWEEN THE FOLLOWING "LU _" UP TO THE PSTORE4 MUST BE DONE *WITHOUT A TASK SWITCH, OR THE HIGH TASK CAN COME IN IN THE MIDDLE AND MODIFY *THE COUNT OF SECTORS AVAILABLE WITHOUT THE KNOWLEDGE OF LO TASK. *THIS IS TRUE WHETHER THE IMAGE IS ACTIVE OR NOT (it could become active *after the PFETCH4 but before the PSTORE4). * LU _ (LSH[eomActiveAttributes,2]) - T; DBLGOTO[eomImageActive,eomImageNotActive,ALU=0]; eomImageActive: *The image data is already present in the quad block starting at *eomDataTransferBaseA, so no fetch is required. eomRingChar _ (eomRingChar) + (incSectorsFilledByOne); eomSectorsFilled _ (eomSectorsFilled) + 1, TASK; PSTORE4[eomCsbBaseLo,eomDataTransferBaseA]; GOTO[eomResetMesaRequestCode]; eomImageNotActive: PFETCH4[eomCsbBaseLo,eomParmA]; eomParmD _ (eomParmD) + (400C); *The NOP is manditory to insure that eomParmD is stored prior to the *start of the PSTORE4. NOP, TASK; PSTORE4[eomCsbBaseLo,eomParmA]; *Go and reset the Mesa request. GOTO[eomResetMesaRequestCode]; % ******************** MESA COMMAND TRANSFER BRANCH 4 - - SECOND LEVEL DISPATCH Dump 64 CPU registers to main memory. % ******************** eomDiagnosticRegDump: *Pick up the microcode long pointer from the mesa command and the word *following. PFETCH2[eomCsbBaseLo,eomFragA,mesaCommandOffset], AT[loTaskMesaDispatch,4]; *Initialize eomFragC to be an offset. eomFragC _ (100C), CALL[eomLoTaskSwitch]; NOP; eomRegDumpLoopHead: T _ STKP; *Use eomFragD to save the stack pointer. eomFragD _ T; *Load the stack pointer for the current quad block. STKP _ eomFragC; *Set up the offset from the double word base. T _ (eomFragC) - (100C); PSTORE4[eomFragA,STACK]; *Retreive the actual stack pointer. eomFragD _ (eomFragD) XOR (377C); *Restore the stack pointer. STKP _ eomFragD, CALL[eomLoTaskSwitch]; eomFragC _ (eomFragC) + (4C); *Check for completion. LU _ (eomFragC) - (200C); DBLGOTO[eomRegDumpLoopHead,eomRegDumpDone,ALU<0]; eomRegDumpDone: GOTO[eomResetMesaRequestCode]; % ******************** MESA COMMAND TRANSFER BRANCH 6 - - SECOND LEVEL DISPATCH Terminate Page Print % ******************** eomTerminatePagePrint: *Zero the wakeup reasons word; eomFragB _ 0C, AT[loTaskMesaDispatch,6]; CALL[eomLoTaskSwitch]; *Output garbage to register 0 to do the IORESET. The output must be done *twice for the hardware to completely reset. OUTPUT[eomFragA,0]; OUTPUT[eomFragA,0]; *The store is done here to allow eomFragB to be stored; PSTORE1[eomCsbBaseLo,eomFragB,wakeupReasonOffset], GOTO[eomResetMesaRequestCode]; % ******************** MESA COMMAND TRANSFER BRANCH 7 - - SECOND LEVEL DISPATCH This option handles the startup of a real time page print. % ******************** eomStartRealTimePage: *Intialize the eomHiTaskState value to indicate real time page print and *working from new list. Then go and set up as in a parametric page print. eomState _ (workingFromNewList), GOTO[eomMesaCommandBaseA], AT[loTaskMesaDispatch,7]; % ******************** SPECIAL TRANSFER BRANCH 3 The code comes here to handle a band switch. % ******************** eomBandSwitch: *Fetch the count of bands processed. The count will be in eomParmD. PFETCH4[eomParameterTransferBaseA,eomParmA,thirdJunkQuad], AT[loTaskMainDispatch,3]; *Set up to send the notification of band switch; T _ (bandSwitch), CALL[eomLoTaskSwitch]; *Increment the bands processed count. eomParmD _ (eomParmD) + 1, CALL[eomModifyWakeupReasons]; *Check to see if we are in parametric or real time mode. LU _ (eomState) AND (parametricModeFlag); *Check for parametric band switch. If it is real time band switch, update *the old list full values. Also, store the count of bands processed. GOTO[eomParametricBandSwitch,ALU#0], PSTORE4[eomParameterTransferBaseA,eomParmA,thirdJunkQuad]; *Output the start bit, set up in the DISP instruction. This is required *in real time operation. Also, send the band switch notification. OUTPUT[eomFragB,opcStartupOut]; T _ eomOldBlocksReturned; eomOldBlocksFull _ T; eomOldBlocksReturned _ (ZERO) - 1; eomParametricBandSwitch: *Reset the wakeup condition. INPUT[eomTemp,resetBandSwitch], GOTO[eomLoTaskResetInterlock]; eomGenFontParmBlock: *T must contain the five bit font number when this code block is entered. *Stash this in eomFragA. eomFragA _ T, TASK; *Shift the font number up (multiply by 128) to make room for the character *code. eomFragA _ LSH[eomFragA,7]; *Pick up the character code. T _ (LDF[eomBListEntryB,3,7]); *Merge in the character code with the font number * 128. eomFragA _ (eomFragA) OR T; *Multiply by 4 for indexing quadword fragments T _ LSH[eomFragA,2]; *add in the base offset T _ (eomFragments) + T, TASK; *Fetch the fragment. PFETCH4[eomParameterTransferBaseA,eomFragA]; *Move the first word of the parameter block out of the fragment. T _ (eomFragA); eomParmA _ T; *Construct the third parameter word and stash it. This word is *all zero for a startup font character, except for the word pointer *and the previous line present bit. *Pick up the word pointer and shift it to the proper location. T _ LSH[eomFragB,14]; eomParmC _ T; *OR in the bit to indicate previous line not present. eomParmC _ (eomParmC) OR (previousLineNotPresent); *get the second parameter word and stash it. This involves masking out the *word pointer and replacing it with the current z-Plane setting T _ (eomFragB) AND NOT (17C), CALL[eomSnarfZPlaneInfo]; *move the fourth word T _ eomFragC; *output the first parameter quad eomParmD _ T; eomNewListWrite _ T _ (eomNewListWrite) + (4C); PSTORE4[eomParameterTransferBaseA,eomParmA]; *create the run length and terminator word and stash it. The run length *must be initialized to maximum, all ones. The terminator doesn't matter. eomParmA _ (ZERO) -1; *set up parameter word 5 from the fragment T _ eomFragD, USECTASK, CALL[eomStashTInParmB]; GOTO[eomNormalInkB,R>=0], A _ eomInkSetting; *the ink is abnormal, so the force word 8 to zero bit must be cleared. eomParmB _ (eomParmB) AND NOT (forceWord8ToZero); eomNormalInkB: *set up the Y value T _ LDF[eomBListEntryA,3,15]; eomParmD _ T; *set up the X value T _ LDF[eomBListEntryB,12,6]; *output the second parameter quad eomParmC _ T, CALL[eomRuleStashSub]; *check the abnormal ink flag, and pick up the ink setting in case we need it. DBLGOTO[eomNormalInkA,eomAbnormalInkA,R>=0], T _ RHMASK[eomInkSetting]; eomAbnormalInkA: *Stash the ink setting, and output the third quad word. eomParmA _ T, CALL[eomRuleStashSuB]; *bump the write pointer to pass over the fourth quad word. eomNewListWrite _ (eomNewListWrite) + (4C), GOTO[eomActivateHiTask]; eomNormalInkA: *bump the newPointer up to the start position for the next parameter block eomNewListWrite _ (eomNewListWrite) + (10C), GOTO[eomActivateHiTask]; eomActivateHiTask: *Indicate the addition of another block to the new list. *Also, activate the hi task if it needs it. eomNewBlocksFull _ (eomNewBlocksFull) + 1, CALL[eomActivateHiTaskFromLoTask]; GOTO[eomLoRun]; ******************** *LOW TASK SUBROUTINES ******************** eomSnarfZPlaneInfo: *pick up the default z-Plane information T _ (RHMASK[eomZPlane]) OR T; eomStashTInParmB: *Stash the second parameter eomParmB _ T, RETURN; eomStashTInParmA: eomParmA _ T, RETURN; % SUBROUTINE eomRuleStashSub AND eomBuildType4Sub ******************** This subroutine stashes parameter blocks into the new list and bumps the new list write pointer. % ******************** eomBuildType4Sub: *Fetch the quadblock from the parameter block PFETCH4[eomBandListA,eomParmA]; LU _ eomParmD; *force the interlock eomRuleStashSub: eomNewListWrite _ T _ (eomNewListWrite) + (4C); PSTORE4[eomParameterTransferBaseA,eomParmA], RETURN; % SUBROUTINE eomActivateLoTask ******************** This subroutine sends the command to the hardware to activate the low task wakeup automaton. % ******************** eomActivateLoTask: eomFragA _ setLoTaskRun; OUTPUT[eomFragA,loTaskCommandReg]; eomInterlockOUTPUT: *Interlock to force completion of the OUTPUT; eomFragA _eomFragA, RETURN; % SUBROUTINE eomModifyWakeupReasons ******************** This subroutine gets the current wakeup reasons word from the CSB and OR's into it the value in T, then puts it back. % ******************** eomModifyWakeupReasons: *Fetch the wakeup mask and wakeup reasons into eomTemp and eomTemp1 *respectively. PFETCH2[eomCsbBaseLo,eomTemp,wakeupMaskOffset]; *Use eomImageXferOffset as a temporary and load it with the register *address in emulator space where the naked notify needs to go. eomImageXferOffset _ IP[NWW]C; *Or the new wakeup reason into the current wakeup reasons word. eomTemp1 _ (eomTemp1) OR T, LOADPAGE[eomHiTaskPage]; *Save the current stack pointer in T. This is actually the ones complement *of the 8 bit value. Branch to high task page. T _ STKP, GOTO[eomLoEntryModifyWakeupReasons]; % SUBROUTINE eomActivateHiTaskFromLoTask ******************** This subroutine checks to see if the hi task is active, and if not it activates it. % ******************** eomActivateHiTaskFromLoTask: *Check if the high task is already active and if not, activate it. GOTO[eomHiTaskActive, R ODD], eomState _ (eomState) OR (hiTaskRunning); *Set up the pause remove command word. eomFragA _ (hiTaskUnPause); *Send the pause remove. OUTPUT[eomFragA,loTaskCommandReg], GOTO[eomInterlockOUTPUT]; eomHiTaskActive: eomLoTaskSwitch: NOP, RETURN; % SUBROUTINE eomInitNewList ******************** This subroutine initializes the new list ring parameters. % ******************** eomInitNewList: *lowest read transfer will be at 60B (increments by 20B) eomNewListRead _ (newListReadRingBase); *lowest write transfer will be at 60B (increments by 4) eomNewListWrite _ (newListWriteRingBase); *Indicate no parameter blocks in the new list (-1). eomNewBlocksFull _ (ZERO) - 1, RETURN; :END[EOMLoTask]; (1795)\f5