{
LispRplCons.mc
Created: 26-Nov-84 16:03:47 by don
Last edit: 4-Dec-84 11:08:53 by don
}
SetTask[0];
#LispRplCons:
{
- - - - - - - - - - - - - - - - - - - - - - - - - -
# name len-1 stk level effect UFN table entry
46 RPLCONS 0 -1 \RPLCONS
takes two args (LST ITEM):
check (LISTP LST)
LST's pages CNT field # 0 (see CONS below),
LST's cdrcode = 200q.
call UFN if any of these are not true
MAKECONSCELL on LST's page
store ITEM as in cell, with cdr code = 200q (\CDR.NIL)
store as LST's new cdrcode (((LOLOC newcell) and 377) rsh 1) + 200q.
ADDREF item
increment LISTPDTD:COUNTER
return new cell
[not required; in D0, Dorado?]
- - - - - - - - - - - - - - - - - - - - - - - - - -
# name len-1 stk level effect UFN table entry
32 CONS 0 -1 CONS
Cons pages start with two word header:
word 0: [cnt, nxtcell] (two 8-bit fields: count of available cells
on this page, and word# of next free cell
on this page)
word 1: nextpage (page# of next cons page)
DTDs (data type descriptors) have (ucode relevant fields in caps)
word 0: NAME
word 1: SIZE
words 2,3: FREE
words 4,5: descrs
words 6,7: tyspecs
words 10,11: POINTERS
words 12,13: oldcnt
word 14: COUNTER
word 15: NEXTPAGE
\CDR.NIL= 200q
LISTPDTD is the DTD for type LISTP, i.e., at DTDbase + (LLSH 5 4)
Subroutine MAKECONSCELL[page] (given page, return new cell from it):
new cell is at page + page:nxtcell
new CNT is old CNT - 1; punt if CNT was zero
new NXTCELL is new cell's cdr code
Subroutine NEXTCONSPAGE:
if LISTPDTD:NEXTPAGE # 0 then return it, else punt
(lisp code scans for page with cnt>1)
CONS(X Y) // note: this may not be right. Check sources for truth
If Y is NIL:
get NEXTCONSPAGE
MAKECONSCELL on it
store new cell with \CDR.NIL in cdrcode (hi byte)
X in rest of cell
Elseif Y is a listp and the CNT in Y's page > 0, then
MAKECONSCELL[Y's page]
store X as CAR, CDR code = ([(LOLOC Y) and 377q] rsh 1) + 200q
Else:
get NEXTCONSPAGE
MAKECONSCELL on it
store Y in new cell (hi byte 0)
(remember this as Z)
MAKECONSCELL on same page
store X in new cell, with hi byte= [(LOLOC Z) and 377q] rsh 1
ADDREF X
ADDREF Y
increment LISTPDTD:COUNTER
DELREF result
- - - - - - - - - - - - - - - - - - - - - - - - - -
}
{ start by verifying that tos-1 is a LISTP
}
{@RPLCONS: opcode[46'b],
MAR ← [rhS, S - 1], L3 ← L3.RPLCONS, c1;} ufn[46]; asdfasdf:
rhRx ← crhTypeTable, CANCELBR[rplTypC3, 2], c2;
{
rplTypC3:
rhTT ← TT ← MD, c3;{tos-1 hi = Hi 8 bits of old cell VA}
MAR ← [rhS, S + 0], c1;
, c2;
Rx ← MD, c3;{tos-1 lo = Lo 16 bits of old cell VA}
Q ← Rx, c1;{Lo 16 bits of old cell VA}
, c2;
, c3;
MAR ← Rx ← [Rx, TT + 0], c1;{byte merge}
Rx ← Rx LRot8, c2;
Rx ← Rx RShift1, getTypemsBit, c3;
MAR ← [rhRx, Rx + 0], L1 ← L1.NoFixes, c1;{type table fetch}
Rx ← ListType, c2;
Rx ← MD xor Rx, L0 ← L0.RedoRplX, c3;
rplxmap:
Map ← TT ← [rhTT, Q], c1;{map the old cell}
Ybus ← Rx - 1, PgCarryBr, c2;{check if type = list}
rhRx ← Rx ← MD, XwdDisp, BRANCH[$, rplUfn], c3;
uTOSm1 ← TT, DISP2[rplxremap], c1, at[L0.RedoRplX, 10, WxMapFixCaller];{uTOSm1 ← Lo 16 bits of old cell VA}
Q ← rhTT, c2, at[1, 4, rplxremap];
uTOSHm1 ← Q, c3;{uTOSHm1 ← Hi 8 bits of cell VA}
MAR ← Rx ← [rhRx, TT + 0], c1;
uSavAddr ← Rx, L3Disp, c2;{uSavAddr ← lo 16 bits old cell RA}
rhTT ← TT ← MD, DISP4[rpls], c3;{high data of old cell}
}
uTT ← TT, c1, at[L3.RPLCONS, 10, rpls];{uTT ← high data of old cell}
TT ← TT LRot8, c2;
TT ← TT xor 200'b, c3;
Ybus ← TT - 1, PgCarryBr, L1 ← L1.NoFixes, c1;{test if old cell cdrcode = 200'b}
BRANCH[$, rplcNot200ufn], c2;
TT ← uTOSm1, c3;{Lo 16 bits of old cell VA}
TT ← TT and ~0FF, c1;{mid 8 bits of cell VA}
uAddrNewCellLo ← TT, c2;{uAddrNewCellLo ← mid 8 bits of cell VA}
Xbus ← 1, XDisp, CALL[ConsMakeCellnoMap], c3;
{
ConsMakeCellnoMap:
{ get first word from cons page
this is: [count,,next]}
MAR ← [rhRx, 0 + 0], DISP2[ConsMap2], c1,at[L0.RedoCons2,10,WMapFixCaller];
Rx ← Rx and ~0FF, c2, at[1, 4, ConsMap2];{Rx ← mid 8 bits of cell RA}
TT ← MD, c3;{cell page cnt,,next}
{ MakeConsCell}
Q{next} ← TT and 0FF, c1;{lo 8 bits of new cell addr}
Rx ← Rx or Q, c2;{Rx ← lo 16 bits of new cell RA}
TT ← TT LRot8, c3;
TT{cnt} ← TT and 0FF, c1;{TT now has cnt}
Q ← Q or uAddrNewCellLo, c2;{Q ← lo 16 bits of new cell VA}
TT{cnt-1} ← TT - 1, NegBr, c3;{test if no more space, and gen cnt-1}
TT ← TT LRot8, BRANCH[$, ConsNoRoom1], c1;{hi 8 bits = cnt-1}
uNewCount ← TT, c2;{uNewCount ← hi 8 bits = cnt-1}
uGcLov ← 0, c3;{prepare for GcRef}
{ get hi word of new cell}
MAR ← [rhRx, Rx + 0], c1;
uAddrNewCellLo ← Q, c2;{uAddrNewCellLo ← lo 16 bits of new cell VA}
Q ← MD, c3;{Q ← hi 16 bits of data from new cell}
TT{newnext} ← Q and ~0FF, c1;{ptr to next free cell from new cell}
TT ← TT LRot8, c2;
Q ← uNewCount, c3;
{ rewrite first word of cons page with new [count,,nextcell]}
MAR ← [rhRx, 0 + 0], c1;
MDR ← TT{Lo: newnext} or Q{Hi: cnt-1}, L3Disp, c2;
Q ← rhTT, DISP4[CMCEarly], c3;{saves rh of Vaddr of cons cell}
}
at[L3.RPLCONS, 10, CMCEarly],
{ store new value into new cell }
TT ← LShift1 TOSH and 0FF, c1;
TT ← RShift1 TT, SE ← 1, c2;{tos hi with cdrcode = 200'b}
, c3;
MAR ← [rhRx, Rx + 0], c1;
MDR ← TT, c2;{tos hi with cdrcode = 200'b}
TT ← uTT, c3;{hi data of old cell}
MAR ← [rhRx, Rx + 1], c1;
MDR ← TOS, CANCELBR[$, 2], LOOPHOLE[wok], c2;{tos lo}
{ change cdr code of old cell to RSH1(loloc new cell) + 200'b }
TT ← TT and 0FF, c3;{lo half of hi 16 bits of old cell}
Rx ← RShift1 Rx and 0FF, c1;{lo 8 bits of new cell addr RSH 1}
Rx ← Rx or 080, c2;{add 200'b}
Rx ← Rx LRot8, c3;{move to hi 8 bits}
TT ← TT or Rx, c1;{new hi 16 bits for old cell}
Rx ← uSavAddr, c2;{lo 16 bits old cell RA}
, c3;
MAR ← [rhRx, Rx + 0], c1;
MDR ← TT, c2;{new high contents for old cell}
{ set tos to be new cell }
uTOS ← TOS, c3;{uTOS ← old tos lo}
Q ← TOSH and 0FF, c1;
uTOSH ← Q, c2;{uTOSH ← old tos hi and 0FF}
TOS ← uAddrNewCellLo, c3;{lo 16 bits of new cell VA}
TOSH ← uTOSHm1, c1;{high 8 bits cell VA}
{setup for GcLookup:
Rx ← addrHi & 0FF
TT ← addrLo
uGcLov ← 0 {before first call only}
L2 used for return via GcLookRet {to c2}
Q ← Q.AddRef or Q.DelRef
Trashes rhTT and rhRx
}
{ AddRef to item = tos}
Rx ← uTOSH, L2 ← L2.ConsDel{share exit}, c2;{old tos hi and 0FF}
TT ← uTOS, c3;{old tos lo}
Q ← Q.AddRef, CALL[GcLookup], c1;
{
{ increment LISTDTD:COUNTER and return }
Q ← ConsCnt, c2,at[L2.ConsDel,10,GcLookRet];
CALL[ConsMapDTD], c3;
ConsMapDTD:
rhTT ← DTDspace, c1;
TT ← DTDbasePage, c2;
TT ← TT LRot8, c3;
Map ← [rhTT,TT], L0 ← L0.RedoCons1, c1;
L1 ← L1.NoFixes, c2;
Rx ← rhRx ← MD, XwdDisp, c3;
{ fetch ListpDTD:NextPage/Counter}
MAR ← [rhRx, Q + 0], DISP2[ConsMap1], c1,at[L0.RedoCons1, 10, WMapFixCaller];
L2Disp, c2, at[1, 4, ConsMap1];
TT{NextPage/Counter} ← MD, RET[ConsMapDTDRet], c3;
{ increment ListpDTD:COUNTER}
MAR ← [rhRx, Q + 0], c1,at[L2.ConsDel, 10, ConsMapDTDRet];
MDR ← TT + 1, c2;
S ← S - 2, c3;
TT ← TT and ~u0FFF, ZeroBr, c1;
Rx ← uGcLov{set by GcLookup}, BRANCH[ConsCntBig, ReclX1], c2;
}
rplcNot200ufn:
GOTO[ufnX1], c3;
{ E N D }