{
QLispBin.mc
Last edit: by don 23-Mar-84 11:33:57
Last edit: by don 16-Feb-84 10:41:14 fixed for big mem
Created: 29-Nov-83 10:17:04 by don
modified for DLion/Dove compatability 22-Oct-85 15:31:37
}
SetTask[0];
{- - - - - - - - - - - - - - - - - - - - - - - - - -
# name len-1 stk level effect UFN table entry
40 BIN 0 0 \BIN
If TOS is not of type STREAM (13q), PUNT
Fetch quadword pointed to by TOS. Format is:
word 0: CCOFF ; a byte offset from BUFFER
word 1: NCCHARS ; size of buffer in bytes
word 2, 3: flags [byte] = READABLE(bit 0), WRITABLE(bit 1),
EXTENDABLE(bit 2)
BUFFER [24-bits]
If CCOFF >= NCCHARS, PUNT [buffer overflow]
If READABLE is off, PUNT
Fetch and remember the byte at BUFFER + CCOFF[byte offset]
Note that this address is guaranteed to be valid at this point,
but it could pagefault.
Update the CCOFF word: CCOFF ← CCOFF + 1, and store back in the stream
Return the remembered byte as a small positive number.
[not required; in Dorado, D0]
- - - - - - - - - - - - - - - - - - - - - - - - - -
# name len-1 stk level effect UFN table entry
41 BOUT 0 -1 \BOUT
If TOS-1 is not of type STREAM (13q), PUNT.
If TOS is not a small positive number (< 400Q), PUNT.
Fetch quadword pointed to by TOS. (see format under BIN)
if WRITABLE is off, PUNT
if CCOFF >= NCCHARS then:
if EXTENDABLE is off, PUNT
if NCCHARS >= 512, PUNT
increment & remember NCCHARS
deposit byte from TOS at BUFFER + CCOFF[byte offset]
Update the stream:
store CCOFF ← CCOFF + 1
store NCCHARS if incremented
return the smallposp one (1)
[not required; not implemented yet]
- - - - - - - - - - - - - - - - - - - - - - - - - -}
@BIN: opcode[40'b],
rhTT ← TOSH LRot0, c1;
, c2;
Rx ← TOS, rhRx ← crhTypeTable, c3;
MAR ← Q ← [TOS, TOSH + 0], c1; {not mem req }
TT ← TOS, L1 ← L1.NoFixes, c2;
, c3;
Rx ← Q, c1;
Rx ← Rx LRot8, c2;
Rx ← Rx RShift1, getTypemsBit, c3;
{get type table entry}
MAR ← [rhRx, Rx + 0], c1;
Q ← 0FF, c2;
Rx{entry} ← MD and Q{0FF}, c3;
{test if type stream}
, c1;
Ybus ← Rx xor STREAMTYPE, ZeroBr, c2;
BRANCH[TTEnotStream, $], c3;
{map the address}
Map ← [rhTT, TT], L0 ← L0.RedoBin, c1;
, c2;
Rx ← rhRx ← MD, XwdDisp{XDirtyDisp}, c3;
{get 4 word contents of address}
MAR ← Q ← [rhRx, TT + 0], DISP2[BinRemap], c1,at[L0.RedoBin,10,WMapFixCaller];
Rx ← uSavAddr ← Q, c2, at[PgDirty, 4, BinRemap];
Q{CCOFF} ← MD, c3;
MAR ← [rhRx, Rx + 1], c1;
CANCELBR[$, 2], c2;
TT{NCCHARS} ← MD, c3;
MAR ← [rhRx, Rx + 3], c1;
Ybus ← Q - TT, CarryBr, BRANCH[$, lbCant, 1], c2;
TT{Buff.Lo} ← MD, BRANCH[$, BinFull], c3;
MAR ← [rhRx, Rx + 2], c1;
uGcLlo ← TT, CANCELBR[$, 2], c2;
rhTT ← TT{Buff.Hi} ← MD, c3;
Rx ← Q + 1, c1;
uGcLTem ← Rx, c2;
Ybus ← TT, NegBr, c3;
Q ← rhRx, BRANCH[BinNoRead, $], c1;
Ybus ← Rx and 1, YDisp, c2;
TT ← uGcLlo, L2 ← 0, BRANCH[BinO, BinE], c3;{L2 ← Odd/Even}
BinO:
Rx ← RShift1 (Rx - 1), SE ← 0, GOTO[BinEO], c1;
BinE:
Rx ← RShift1 (Rx - 1), SE ← 0, GOTO[BinEO], c1;
BinEO:
TT ← TT + Rx, CarryBr, c2;
urhRx ← Q, BRANCH[BinNoC,$], c3;
Q ← rhTT, c1;
Q ← Q + 1, c2;
rhTT ← Q LRot0, c3;
BinNoC:
Map ← [rhTT, TT], L0 ← L0.RedoBinA, c1;
, c2;
Rx ← rhRx ← MD, ReadXRefBr, GOTO[BinGet], c3;
BinGet:
{get contents of address}
MAR ← Q ← [rhRx, TT + 0], ReadBRANCH[BinRemapA, $], c1,at[L0.RedoBinA,10,RMapFixCaller];
L2Disp, c2;
TT{BinWord} ← MD, BRANCH[BinOdd, BinEven], c3;
BinOdd:
TT ← TT, GOTO[BinMask], c1;
BinEven:
TT ← TT LRot8, GOTO[BinMask], c1;
BinMask:
TOS ← TT and 0FF, c2;
TOSH ← smallpl, c3;
rhRx ← urhRx, c1;
Rx ← uSavAddr, c2;
, c3;
MAR ← [rhRx, Rx + 0], c1;
MDR ← uGcLTem, L2 ← L2.0, IBDisp, GOTO[DNI.pc1], c2;
CALL[WLMapFix], c2, at[PgClean, 4, BinRemap];
CALL[WLMapFix], c2, at[PgProt, 4, BinRemap];
CALL[WLMapFix], c2, at[PgVacant, 4, BinRemap];
BinRemapA:
CALL[RLMapFix], c2;
TTEnotStream:
GOTO[ufnX2], c1;
BinFull:
GOTO[ufnX2], c1;
BinNoRead:
GOTO[ufnX3], c2;
lbCant:
CANCELBR[ufnX1], c3;
{ E N D }