:TITLE[Misc.0mc...January 21, 1983 10:30 AM, van Melle];

* ReadPrinterPort
* Push Printer input as a smallp

@ReadPrinterPort:
Stack&+1 ← (Smallpl), opcode[164];
T ← Printer, goto[PushTChkP5];

* WritePrinterPort
* Printer ← TOS as smallp

@WritePrinterPort:
loadpage[pgArithOps], opcode[165];
lspUfn ← 165c, call[CheckSmallp];
Printer ← Stack, goto[nxiLBL];



MC[MiscMax, IFE[WithPPBlt, 0, 4, 5]];
* Max misc alpha + 1

@MISC1:
lspUFN ← 170c, goto[MiscDispatch], opcode[170];

@MISC2:
loadpage[pgHStack], call[CheckElt2P5], opcode[171];
lspUFN ← 171c, goto[MiscDispatch];

onpage[opPage1];
MiscDispatch:
T ← NextData[IBuf];
lspLN ← T, loadpage[pgMisc];
lu ← (lspLN) - (MiscMax);
onpage[pgMisc];
Dispatch[lspLN, 15, 3], skip[alu>=0];
disp[@STARTIO];
goto[ufnLBL];


:IF[With10MB];
@STARTIO:
T ← Stack&-1, at[MiscDisp, 0];
lu ← Stack&+1, loadpageExternal[StartIOPage];
RTemp1 ← (Zero) xnor T, gotoExternal[StartIOLoc];
:ELSE;
@STARTIO: goto[ufnLBL], at[MiscDisp, 0];
:ENDIF;

@INPUT:
*TOS is Task[10:13], IOReg#[14:17], as smallp
T ← Stack&-1, at[MiscDisp, 1];
Input[Stack], goto[nxiLBL];* Might want to check smallp[TOS]


@OUTPUT:
* TOS as for Input, TOS-1 is smallp value to output
T ← Stack&-2, at[MiscDisp, 2];* Might want to check smallp[TOS]
Output[Stack];* Now need 5 mi til task to avoid gotcha
Stack&+1;* restore stack
goto[Misc2ret];* dillydally
Misc2ret:
StkState ← rsh[StkState, 1], goto[nxiLBL];

@SETMP:
* TOS is smallp number to put in MP
T ← Stack&-1, loadpageExternal[PNIPPage], at[MiscDisp, 3];
lu ← Stack&+1, CallExternal[PNIPLoc];
Misc1ret:
NextOpCode;

:IF[WithPPBlt];
onpage[pgMisc];
@@PPBLT:
loadpage[opPage3], at[MiscDisp, 4];
lspL4 ← 400c, call[GetVal&Base]; * smallp(TOS) in L1, base in lspGenBr
lspInstFlag ← (InPPBltState);
Stack&+2, call[ppLP];* Point Stack at bytecount
ppLP:
lu ← Stack, skip[R Even];
PFetch1[lspGenBr, lspL0, 0], goto[ppByte2];* odd count, start with right byte
lu ← Printer, goto[ppExit, alu=0];
PFetch1[lspGenBr, lspL0, 0], skip[alu>=0];
T ← lspGenBr, dblgoto[ppInterrupt, ppRet, IntPending];
T ← rsh[lspL0, 10];* left byte
lspL2 ← T;
Printer ← lspL2;
nop;* Need 300ns between changes
Printer ← lspL4;* constant 400
Stack ← (Stack) - 1;* allow a mi before ←Printer for signal propagation?
ppByte2:
lu ← Printer;
lspL0 ← rhmask[lspL0], skip[alu>=0];* Right byte
T ← lspGenBr, dblgoto[ppInterrupt, ppRet, IntPending];
T ← lspGenBr ← (lspGenBr) + 1;
Printer ← lspL0, skip[Carry’];
lspGenBrHi ← (lspGenBrHi) + 1;
nop;
Printer ← lspL4;
Stack ← (Stack) - 1, dblgoto[ppInterrupt, ppRet, IntPending];

ppRet:
return;

ppInterrupt:
* T = lspGenBr here
Stack&-2 ← T;* Fault could be happening here, but its
* cleanup will do exactly the same thing, so
* no harm in modifying stack here
T ← rsh[lspGenBrHi, 10];
Stack&-1 ← T, loadpage[opPage0];* After third mi after PFetch1
Stack&+3, gotop[TakeInterrupt];

ppExit:
Stack&-2, loadpage[opPage3];
lspInstFlag ← (NormalState), gotop[PopState1];


ppFault:
* Here from page fault.
* Just like interrupt, but page constraints prevent sharing
T ← rsh[lspGenBrHi, 10], at[FaultDisp, InPPBltState!];
Stack&-3 ← T;* Store Hi base
T ← lspGenBr;
Stack&+1 ← T;
Stack&+2, goto[lspDoFault];
%

Stack&-2, loadpage[opPage0];
T ← (Stack&-1) + T;
onpage[opPage0];
Stack ← (Stack) + 1, UseCOutAsCIn;
Stack&+1 ← T, goto[TakeInterrupt];
%
:ENDIF;

:IF[WithPilotBitBlt];
@PBITBLT:
LoadPage[pgHStack], call[CheckElt2P5], opcode[166];
T ← Stack&-2;* look at second arg
RTemp ← T, goto[bbRestart, alu#0];* initially zero
bbResume:
T ← Stack&-1;
bbArgLo ← T, loadPage[pgBitBlt];
T ← lsh[Stack, 10];
onpage[pgBitBlt];
T ← (rhmask[Stack&+1]) + T + 1;* build hi base reg
bbArgHi ← T, goto[LispBitBlt];

onpage[opPage1];
bbRestart:
* Fetch 8 regs that we stashed away on interrupt
T ← (BitBltStash);
PFetch4[MDS, uBuf], task;
RTemp ← (Zero) - 1;
T ← add[BitBltStash!, 4]c;
PFetch4[MDS, qBuf];
T ← uBuf;* get the guy that missed the quad buf
bbDestBitOffset ← T, goto[bbResume];

onpage[pgBitBlt];
BitBltInterrupt:
* come here when IntPending during bitblt
Stack&+2 ← T, call[BitBltSaveState];* Odd placement
loadpage[opPage0];
gotop[TakeInterrupt];


onpage[pgLisp0];
bbTakeFault:
* Pagefault fixup routine. Stkp has already been
* restored
T ← AllOnes, loadpage[pgBitBlt], at[FaultDisp, InBitBltState!];
Stack ← T, callp[BitBltSaveState];
goto[lspDoFault]


onpage[pgBitBlt];
BitBltSaveState:
* Save 8 bitblt regs in MDS space
T ← add[BitBltStash!, 4]c;
PStore4[MDS, qBuf];
T ← bbDestBitOffset;* this guy didn’t fit into uBuf quad, sigh
uBuf ← T;
T ← (BitBltStash);
PStore4[MDS, uBuf], return;

:ELSE;
@PBITBLT:
lspUFN ← 166c, goto[lspUfnxP5], opcode[166];
:ENDIF;