{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: 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} 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[GcSTestX, GcSExit], c3; GcSTestX: Ybus ← Rx and 1, ZeroBr, L2Disp, GOTO[GcST1], c1; GcZero: TOSH ← 0, L2 ← 0, GOTO[GcSExit2], c1; GcScanFound: L2 ← 0, GOTO[GcSExit2], c1; GcSAllThru: TT ← TT + 1, GOTO[GcSExit], c3; GcSExit: TOSH ← 0, L2 ← 0, GOTO[GcSExit2], c1; GcSExit2: PC ← PC + PC16, IBDisp, c2; TOS ← TT + 1, L2 ← 0, DISPNI[OpTable], c3; {END}