{ LispCons.mc Created: 10-Aug-83 20:35:27 by don Last edit: 2-Sep-83 11:00:55 by don } Set[L2.ConsNil, 8], SetTask[0]; {******************************************************************* CONS *******************************************************************} { CONS ( X , Y ) returns cons with X as car Y is initially on top of stack } {ConsNot: Rx ← 32'b, GOTO[ufn2], c1; } Cons: opcode[32'b], {optionally hooked up} { TT ← uLispOptions, c1; TT ← TT and 4, ZeroBr, c2; BRANCH[$, ConsNot], c3; } { test if Y {top of stack} is NIL} Ybus ← TOS or TOSH, ZeroBr, L2 ← L2.ConsNil, c1; Q ← ConsNxtPg, BRANCH[ConsList, ConsNil], c2; ConsNil: PC ← PC + PC16, CALL[ConsMapDTD] c3; { SUBROUTINE ConsMapDTD} ConsMapDTD: rhTT ← DTDspace, c1; TT ← DTDbasePage, c2; TT ← TT LRot8, c3; Map ← [rhTT,TT], L0 ← L0.RedoCons1, c1; L1 ← L1.DecOnly, c2; Rx ← rhRx ← MD, XDirtyDisp, c3; { fetch ListpDTD:NextPage/Counter} MAR ← [rhRx, Q + 0], BRANCH[ConsMap1, $, 1], c1,at[L0.RedoCons1,10,WMapFixCaller]; L2Disp, c2; TT{NextPage/Counter} ← MD, RET[ConsMapDTDRet], c3; Ybus ← TT{NextPage}, ZeroBr, c1,at[L2.ConsNil,10,ConsMapDTDRet]; rhTT ← TT ← TT LRot8, BRANCH[$, ConsNxtPg0], c2; TT ← TT and ~0FF, CALL[ConsMakeCell], c3; ConsMakeCell: { map it} Map ← [rhTT,TT], L0 ← L0.RedoCons2, c1; uAddrNewCellLo ← TT, L1 ← L1.DecOnly, c2;{u ← hi part of Vaddr of cons cell} Rx ← rhRx ← MD, XDirtyDisp, c3; { get first word from cons page this is: [count,,next] } MAR ← [rhRx, 0 + 0], BRANCH[ConsMap2, $, 1], c1,at[L0.RedoCons2,10,WMapFixCaller]; Rx ← Rx and ~0FF, c2; TT{cnt,,next} ← MD, c3; { MakeConsCell} Q{next} ← TT and 0FF, c1;{lo part of Vaddr of cons cell} Rx ← Rx or Q, c2;{Raddr of cons cell} TT ← TT LRot8, c3; TT{cnt} ← TT and 0FF, c1;{TT now has cnt} Q ← Q or uAddrNewCellLo, c2;{merge hi and lo Vaddr of cons cell} TT{cnt-1} ← TT - 1, NegBr, c3;{test if more space} TT ← TT LRot8, BRANCH[$, ConsNoRoom1], c1; uNewCount ← TT, c2; uGcLov ← 0, c3; { get first word of cons cell} MAR ← [rhRx, Rx + 0], c1; uAddrNewCellLo ← Q, c2; Q ← MD, c3; TT{newnext} ← Q and ~0FF, c1; 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}, c2; Q ← rhTT, c3;{saves rh of Vaddr of cons cell} { build new cons} { get second word of X, put to TOS and conspage} MAR ← [rhS, S + 0], c1; uConsTemp ← Q, c2; TOS{X.Lo} ← MD, c3; MAR ← [rhRx, Rx + 1], c1; MDR ← TOS, CANCELBR[$, 2], LOOPHOLE[wok], c2; c3; { get first word of X} MAR ← [rhS, S - 1], c1; TOSH ← 0FF, CANCELBR[$, 0], L2Disp, c2; TOSH{X.Hi} ← MD and TOSH, RET[ConsCMCRet], c3; { change cdrcode to nil (= 200B), put to TOSH and conspage} TOSH ← LShift1 TOSH, SE ← 0, c1,at[L2.ConsNil,10,ConsCMCRet]; TOSH ← RShift1 TOSH, SE ← 1, c2; Q ← Q.AddRef, c3; MAR ← [rhRx, Rx + 0], c1; MDR ← TOSH, c2; {goto AddRef X, DelRef newconscell,increment ListpDTD:counter, fix stack and exit} { there is one abnormal exit from this section if entries are added to the overflow table } {setup for GcLookup: Rx ← addrHi & 0FF TT ← addrLo uGcLov ← 0 {before first call only} L2 ← subr # Q ← 0 if addref, 1 if delref, 2 if stkref Trashes rhTT and rhRx } ConsCom: {Q set to Q.AddRef previously} TT ← TOS, L2 ← L2.ConsAdd, c3; Rx ← TOSH and 0FF, CALL[GcLookup], c1; {GcLookup Subroutine here} {setup for GcLookup: Rx ← addrHi & 0FF TT ← addrLo uGcLov ← 0 {before first call only} L2 ← subr # Q ← 0 if addref, 1 if delref, 2 if stkref Trashes rhTT and rhRx } TT ← uAddrNewCellLo, c2,at[L2.ConsAdd,10,GcLookRet]; TOS ← TT, c3; TOSH ← uConsTemp, c1; c2; Rx ← uConsTemp, L2 ← L2.ConsDel, c3; Q ← Q.DelRef, CALL[GcLookup], c1; {GcLookup Subroutine here} Q ← ConsCnt, c2,at[L2.ConsDel,10,GcLookRet]; CALL[ConsMapDTD], c3; { increment ListpDTD:COUNTER} MAR ← [rhRx, Q + 0], c1,at[L2.ConsDel,10,ConsMapDTDRet]; MDR ← TT + 1, c2; , c3; S ← S - 2, c1; TT ← uGcLov{set by GcLookup}, c2; Ybus ← TT, NZeroBr, c3; Rx ← AtomGCSCAN {371'b}, BRANCH[ConsNoOvXit, ConsOvXit], c1; ConsNoOvXit: L2 ← L2.0, IBDisp, GOTO[DNI.nop], c2; ConsOvXit: IB ← Rx LRot0, L3{ib's} ← 0, c2; PC ← PC - PC16, IBPtr ← 0, c3; MAR ← Q ← [rhS, S + 1], GOTO[FN1Ext], c1; { Cons List} {ConsNoList: Rx ← 32'b, GOTO[ufn1], c3; } ConsList: { optionable} { Q ← uLispOptions, c3; Ybus ← Q and 1, ZeroBr, c1; BRANCH[$, ConsNoList], c2; } uGcLov ← 0, L2 ← L2.ConsList, c3; { get real address of type table entry} TT ← 32'b, CALL[NewTyp], c1; { pc bumped by one in subroutine} { get type table entry} MAR ← [rhRx, Rx + 0], c1,at[L2.ConsList,10,NewTypRet]; Q ← 0FF, c2; Rx{entry} ← MD and Q{0FF}, c3; { test if Y is of type list} Ybus ← Rx xor ListType, ZeroBr, c1; BRANCH[ConsOther, $], c2; rhTT ← TOSH LRot0, c3; TT ← TOS and ~0FF, c1; uKeepTOS ← TOS, c2; uKeepTOSH ← TOSH, CALL[ConsMakeCell], c3; TT ← uKeepTOS, c1,at[L2.ConsList,10,ConsCMCRet]; TT ← TT and 0FE, c2; TT ← TT LRot8, c3; TOSH ← LShift1 TOSH, SE ← 0, c1; TOSH ← TOSH or TT, c2; TOSH ← RShift1 TOSH, SE ← 1, c3; MAR ← [rhRx, Rx + 0], c1; MDR ← TOSH, c2; {setup for GcLookup: Rx ← addrHi & 0FF TT ← addrLo uGcLov ← 0 {before first call only} L2 ← subr # Q ← 0 if addref, 1 if delref, 2 if stkref Trashes rhTT and rhRx } L2 ← L2.ConsListAdd, c3; TT ← uKeepTOS , c1; Rx ← uKeepTOSH, c2; Rx ← Rx and 0FF, c3; Q ← Q.AddRef, CALL[GcLookup], c1; {GcLookup Subroutine here} Q ← Q.AddRef, GOTO[ConsCom], c2,at[L2.ConsListAdd,10,GcLookRet]; ConsMap1: CALL[WLMapFix], c2; ConsMap2: CALL[WLMapFix], c2; ConsNoRoom1: GOTO[ConsUfn3], c2; ConsNxtPg0: PC ← PC - PC16, GOTO[ConsUfn1], c3; ConsOther: {ufn for now} ConsUfn3: PC ← PC - PC16, c3; ConsUfn1: Rx ← 32'b, GOTO[ufn2], c1; { E N D }