: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];