{ 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; 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 }