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