{
LispBin.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
}

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[1, 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, XRefBr, GOTO[BinGet],	c3;

BinGet:
	{get contents of address}
	MAR ← Q ← [rhRx, TT + 0], BRANCH[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[0, 4, BinRemap];

	CALL[WLMapFix],	c2, at[2, 4, BinRemap];

	CALL[WLMapFix],	c2, at[3, 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 }