{File name LispGc.mc Description: part of DandeLion InterLisp Emulator Author: Charnley Last edited by Charnley: 16-Aug-83 14:39:35 Created by Charnley: April 18, 1983 9:45 AM } SetTask[0]; {******************************************************************* GCSCAN1, GCSCAN2 1 or 2 clicks per entry *******************************************************************} { GCScan opcodes: on entry, TOS contains (index + 1) into the HashTable index is first entry tested. on exit, TOS contains (index) found, or NIL if table exhausted. GcScan1 finds (collision = 1) or (stk = cnt = 0). GcScan2 finds (collision = 1) or (stk = 1). L2 = 0 if GcScan1, L2 = 2 if GcScan2 L1 = 0 if more to scan, L1 = 2 if on last entry Interrupts are tested every 256 entries if no entry found by then } GcScan1: Q _ 0, {L2 = 0 for GcScan1} GOTO[GcSCom], c1, opcode[173'b]; GcScan2: Q _ 0, L2 _ 2, {L2 _ 2 for GcScan2} c1, opcode[174'b]; GcSCom: TT _ TOS - 1, NegBr, L1 _ 0, c2; rhTT _ crhHashTable, BRANCH[GcScanStart, GcZero], c3; GcScanStart: { IfEqual[hashmsbit, 1,,CauseError];} TT _ LShift1 TT, c1; TT _ RShift1 TT, getHashmsBit, c2; , c3; MAR _ [rhTT, TT + 0], GOTO[GcSmarP1], c1; GcScanLoop: TT _ MAR _ [rhTT, TT - 1], c1; GcSmarP1: Rx _ Q, ZeroBr, BRANCH[$, GcSPgC, 1], c2, at[1,4,GcSDispX]; Q _ MD, BRANCH[GcStest, GcScanLoop], c3; { Through here if Entry is non-zero } GcStest: Ybus _ Rx and 1, ZeroBr{test coll bit}, L2Disp, c1; GcST1: Rx _ Rx LRot8, DISP2[GcSdisp], c2; {GcS1,coll} GOTO[GcScanFound], c3,at[0,4,GcSdisp]; {GcS1,no coll} Ybus _ Rx - 2, PgCarryBr, L1Disp, GOTO[GcSchmore], c3,at[1,4,GcSdisp]; GcSF: {GcS2,coll} GOTO[GcScanFound], c3,at[2,4,GcSdisp]; {GcS2,no coll} Ybus _ Rx and 2, ZeroBr, L1Disp, GOTO[GcSchmore], c3,at[3,4,GcSdisp]; GcSchmore: {passing thru here makes TT one too small} TT _ MAR _ [rhTT, TT - 1], DISP2[GcSDispX], c1; BRANCH[GcFoundFix,GcFoundPg,1], c2, at[0,4,GcSDispX]; CANCELBR[GcSAllThru,2], c2, at[3,4,GcSDispX]; BRANCH[GcFoundFix,GcFoundPg,1], c2, at[2,4,GcSDispX]; GcFoundFix: TT _ TT + 1, GOTO[GcScanFound], c3; GcFoundPg: TT _ TT - 0FF, GOTO[GcScanFound], c3; GcSPgC: TT _ TT - 0FF - 1, CANCELBR[$], c3; {fix TT} Ybus _ TT, NegBr, c1;{test for end} IfEqual[hashmsbit, 1, , CauseError]; BRANCH[GcSLastRx, $], c2; { INTERRUPT TESTING DISABLED} GOTO[GcScanStart], c3; {GcSinttest: {gc Interrupt test here,} Noop, c1; Q _ Rx, MesaIntBr, c2; Rx _ 0, BRANCH[GcScanStart, $], c3; Ybus _ uWDC, NZeroBr, c1; Ybus _ uWP, ZeroBr, BRANCH[$, GcSIgnoreInt], c2; uWP _ Rx, ClrIntErr, BRANCH[GcSIntHere, GcSS1], c3; GcSIntHere: Rx _ 1, c1; uWDC _ Rx, c2; Rx _ KbdFXP, L2 _ 0, GOTO[GcSpunt], c3; GcSpunt: {*****}Noop, GOTO[ufn2], c1; GcSIgnoreInt: ClrIntErr, CANCELBR[GcSS1], c3; GcSS1: MAR _ [rhTT, TT + 0], GOTO[GcSmarP1], c1; } GcSLastRx: Noop, c3; Noop, c1; Ybus _ Rx, ZeroBr, L1 _ 2,{L1 = 2 during last test} c2; BRANCH[$, GcSExit], c3; Ybus _ Rx and 1, ZeroBr, L2Disp, GOTO[GcST1], c1; GcZero: {hi bit not turned on yet} TOS _ TT + 1, GOTO[GcSExit2], c1; GcScanFound: TOS _ TT + 1, GOTO[GcSExit2], c1; GcSAllThru: TT _ TT + 1, GOTO[GcSExit], c3; GcSExit: TOS _ TT + 1, GOTO[GcSExit2], c1; GcSExit2: TOS _ LShift1 TOS, c2;{remove high bit -- which was used for table address} TOS _ RShift1 TOS, SE _ 0, ZeroBr, c3; BRANCH[GcSExit2X, GcSRetNIL], c1; GcSExit2X: TOSH _ smallpl, L2 _ 0, IBDisp, GOTO[DNI.pc1], c2; GcSRetNIL: TOSH _ 0, L2 _ 0, IBDisp, GOTO[DNI.pc1], c2; {END}