{ PrologBase.mc
by don: 16-Apr-85 14:49:02
}
{ Refill }
{
PHILOSOPHY:
PC is kept pointing to the last word fetched into IB, which is essentially PC + 1 {in words}. This is not always true during refill, and must be kept track of carefully.
2 byte refill:
IB ← [PC ← PC + 1], AlwaysIBDisp
4 byte refill:
IB ← [PC ← PC + 1],
IB ← [PC ← PC + 1], AlwaysIBDisp
6 byte refill:
IB ← [PC ← PC + 2],
IB ← [PC ← PC + 1], AlwaysIBDisp
}
{ moved to Prolog.dfn
Set[L0.PC2, 1],{if PF then PC is + 0, VPC is + 0}
Set[L0.PC4a, 3],{if PF then PC is + 0, VPC is + 0}
Set[L0.PC4b, 4],{if PF then PC is + 1, VPC is + 1}
Set[L0.PCcont, 7],{if PF then PC is + 0, VPC is + 0}
{the following values are used when returning to Lisp}
Set[L1.PrDebugSS, 1],
Set[L1.PrInt, 2],
Set[L1.PrDebugC, 3],
Set[L1.PrPF, 4],
Set[L1.PrUI, 5],
}
{ there are specific entry points to refill for 2, 4, 6 byte ops }
{ last c3 contained: "L3Disp, MesaIntBr, " }
{--------------------------------------------------------------------}
Pr2Refill:
MAR ← PC ← [rhPC, PC + 1], BRANCH[Pr2RefillC2, PrologExit2{PC-0}], c1;
Pr2RefillC2:
AlwaysIBDisp, L2Disp, BRANCH[$, PrbumpPC2, 1], c2;
PrRemap2C3:
IB ← MD, DISPNI[PrologOpTable], c3;
PrbumpPC2:
TT ← upVPClo, CANCELBR[$], c3;
Q ← 0FF + 1, L0 ← L0.PC2, c1;
TT ← TT + Q, CarryBr, GOTO[PrBumpCom], c2;
PrBumpCom:
Q ← rhTT ← upVPChi, BRANCH[PrPCMap, PrincrhTT], c3;
PrincrhTT:
Q ← Q + 1, c1;
upVPChi ← Q, c2;
rhTT ← Q LRot0, GOTO[PrPCMap], c3;
PrPCMap:
Map ← MAR ← TT ← [rhTT, PC + 0], c1;{move low 8 bits of PC to TT}
upVPClo ← TT, L0Disp, c2;
PC ← rhPC ← MD, XRefBr, DISP4[PrRMapFixret], c3;
MAR ← Q ← [rhPC, TT + 0], BRANCH[remapPC2, $], c1, at[L0.PC2, 10, PrRMapFixret];{move all 16 bits of PC from PC and TT to Q}
PC ← Q, AlwaysIBDisp, L2Disp, GOTO[PrRemap2C3], c2;{restore PC}
remapPC2:
Rx ← PC, GOTO[PrRMapFix], c2;
{--------------------------------------------------------------------}
Pr4Refill:
MAR ← PC ← [rhPC, PC + 1], BRANCH[Pr4RefillC2, PrologExit4], c1;
Pr4RefillC2:
BRANCH[$, PrbumpPC4a, 1], c2;
Pr4RefillC3a:
IB ← MD, c3;
PrSecondIBFetch:
MAR ← PC ← [rhPC, PC + 1], IBPtr ← 0, c1;
AlwaysIBDisp, L2Disp, BRANCH[$, PrbumpPC4b, 1], c2;
Pr4RefillC3b:
IB ← MD, DISPNI[PrologOpTable], c3;
PrbumpPC4a:
TT ← upVPClo, L0 ← L0.PC4a, CANCELBR[$], c3;
Q ← 0FF + 1, c1;
TT ← TT + Q, CarryBr, GOTO[PrBumpCom], c2;
MAR ← Q ← [rhPC, TT + 0], BRANCH[remapPC4a, $] c1, at[L0.PC4a, 10, PrRMapFixret];
PC ← Q, GOTO[Pr4RefillC3a], c2;
remapPC4a:
Rx ← PC, GOTO[PrRMapFix], c2;
PrbumpPC4b:
TT ← upVPClo, CANCELBR[$], c3;
Q ← 0FF + 1, L0 ← L0.PC4b, c1;
TT ← TT + Q, CarryBr, GOTO[PrBumpCom], c2;
MAR ← [rhPC, TT + 0], BRANCH[remapPC4b, $] c1, at[L0.PC4b, 10, PrRMapFixret];
PC ← Q, AlwaysIBDisp, L2Disp, GOTO[Pr4RefillC3b], c2;
remapPC4b:
Rx ← PC, GOTO[PrRMapFix], c2;
{--------------------------------------------------------------------}
Pr6Refill:
MAR ← PC ← [rhPC, PC + 2], BRANCH[Pr4RefillC2, PrologExit4], c1;
{--------------------------------------------------------------------}
{ Refill Exits }
{ come here if Interrupt or DebugMode}
{ there is a pending page cross branch to handle }
PrologExit2:
{PC is + 1, and VPC is correct }
TT ← upVPClo, CANCELBR[$, 2], c2;{ignore PageCross}
Prvpcok:
PC ← PC - 1, GOTO[PrSaveVPC], c3;
PrologExit4:
{there is a pending page cross branch to handle }
{PC is + 0, and VPC is - 1 }
TT ← upVPClo, BRANCH[PrExPCok, PrExPgCr, 1], c2;
PrExPCok:
GOTO[PrSaveVPC], c3;
PrExPgCr:
{add 1 to VPC}
Q ← 0FF + 1, c3;
TT ← TT + Q, CarryBr, c1;
upVPClo ← TT, BRANCH[$, PrfixPChi], c2;
GOTO[PrSaveVPC], c3;
PrfixPChi:
Q ← upVPChi, c3;
Q ← Q + 1, c1;
upVPChi ← Q, c2;
GOTO[PrSaveVPC], c3;
PrSaveVPC:
MAR ← TT ← [TT, PC + 0], c1;{byte merge}
upVPClo ← TT, c2;
GOTO[VerifyPrologExit], c3;
VerifyPrologExit:
Q ← upDebug, L1 ← L1.PrDebugSS, c1;
Ybus ← Q - 2, CarryBr, c2;
BRANCH[PrDebugSS, PrNotDebugSS], c3;
PrDebugSS:
{save Prolog state and perform Lisp IBDisp}
GOTO[SavePrologC2], c1;
PrNotDebugSS:
MesaIntBr, L1 ← L1.PrInt, c1;
BRANCH[PrNoInt, PrInt], c2;
PrInt:
Ybus ← uWDC, NZeroBr, BRANCH[PrNointc1, $], c3;
Ybus ← uWP, ZeroBr, BRANCH[$, PrNointc2], c1;
uWP ← 0, BRANCH[PrIntNow, PrNointc3], c2;
PrIntNow:
ClrIntErr, Rx ← 1, CANCELBR[SavePrologC1], c3;
PrInttoLisp: , c1;
uWDC ← Rx,{off interrupts} c2;
Rx ← KbdFXP, GOTO[SavePrologC1], c3;
PrNoInt: GOTO[PrNointc1], c3;
PrNointc3: ClrIntErr, GOTO[PrNointc1], c3;
PrNointc1: CANCELBR[PrNointc2], c1;
PrNointc2: CANCELBR[$], c2;
, c3;
Ybus ← Q, ZeroBr, L1 ← L1.PrDebugC, c1;
BRANCH[PrDebugC, PrNoDebug], c2;
PrDebugC:
{save Prolog state and GOTO[PrologOpDisp]}
GOTO[SavePrologC1], c3;
PrNoDebug:
{redo PrRefill - no reason to stop - PC is ok}
, c3;
, c1;
TT ← upVPClo, c2;
rhTT ← upVPChi, c3;
Map ← MAR ← TT ← [rhTT, PC + 0], L0 ← L0.PCcont, c1;
PrPCcont:
L0Disp, c2;
PC ← rhPC ← MD, XRefBr, DISP4[PrRMapFixret], c3;
MAR ← Q ← [rhPC, TT + 0], BRANCH[remapPCcont, $], c1, at[L0.PCcont, 10, PrRMapFixret];
PC ← Q, c2;
IB ← MD, c3;
MAR ← PC ← [rhPC, PC + 1], IBPtr ← 0, c1;
AlwaysIBDisp, L2Disp, BRANCH[Pr4RefillC3b, PrbumpPC4b, 1], c2;
remapPCcont:
Rx ← PC, GOTO[PrRMapFix], c2;
UI3:
, c3;
UI1:
, c1;
UI2: {standard entry point for UI's}
{PC is + 1 and VPC is + 1 }
PC ← PC - 1, PgCarryBr, L1 ← L1.PrUI, c2;
TT ← upVPClo, BRANCH[$, PrSaveVPCforUI], c3;
TT ← TT and ~0FF, c1;
, c2;
, c3;
PrPCdecCont:
TT ← TT - 1, CarryBr, c1;
upVPClo ← TT, BRANCH[PrfixdecPChi, $], c2;
GOTO[PrSaveVPCforUI], c3;
PrfixdecPChi:
Q ← upVPChi, c3;
Q ← Q - 1, c1;
upVPChi ← Q, c2;
GOTO[PrSaveVPCforUI], c3;
PrSaveVPCforUI:
MAR ← TT ← [TT, PC + 0], c1;{byte merge}
upVPClo ← TT, GOTO[SavePrologC3], c2;
{ SAVE PROLOG REGISTERS }
{ PC has been saved to upVPChi and upVPClo
L1 has been set with the type of exit
BB to uprhB and upB
TR to uprhTR and upTR
H to uprhHH and upHH
S to uprhSS and upSS
A1 to upA1hi and upA1lo
A2 to upA2hi and upA2lo
A3 to upA3hi and upA3lo
A4 to upA4hi and upA4lo
{L2 {Write-Mode} to upWriteMode -- done whenever Write-Mode changes}
}
SavePrologC1:
, c1;
SavePrologC2:
, c2;
SavePrologC3:
upB ← BB, c3;
Q ← rhBB, c1;
uprhB ← Q, c2;
upCC ←CC, c3;
Q ← rhCC, c1;
uprhCC ← Q, c2;
upHH ← HH, c3;
Q ← rhHH, c1;
uprhHH ← Q, c2;
upSS ← SS, c3;
Q ← rhSS, c1;
uprhSS ← Q, c2;
Q ← upPRA4hi, c3;
upA4hi ← Q, c1;
Q ← upPRA4lo, c2;
upA4lo ← Q, c3;
Q ← upPRA1hi, c1;
upA1hi ← Q, c2;
Q ← upPRA1lo, c3;
upA1lo ← Q, c1;
Q ← upPRA2hi, c2;
upA2hi ← Q, c3;
Q ← upPRA2lo, c1;
upA2lo ← Q, c2;
Q ← upPRA3hi, c3;
upA3hi ← Q, c1;
Q ← upPRA3lo, c2;
upA3lo ← Q, c3;
SavePrologEnd:
Bank ← EmuBank, c1;
, c2;
CROSS[PrologToLisp], c3;
{--------------------------------------------------------------}
{ entry from Lisp
restore regs and L2, and L3 do PC fetch and PrologIBDisp
}
at[LispToProlog],
BB ← upB, c1;
rhBB ← uprhB, c2;
CC ← upCC, c3;
rhCC ←uprhCC, c1;
HH ← upHH, c2;
rhHH ← uprhHH, c3;
SS ← upSS, c1;
rhSS ←uprhSS, c2;
Q ← upA4hi, c3;
upPRA4hi ← Q, c1;
Q ← upA4lo, c2;
upPRA4lo ← Q, c3;
Q ← upA1hi, c1;
upPRA1hi ← Q, c2;
Q ← upPRA1lo, c3;
upA1lo ← Q, c1;
Q ← upA2hi, c2;
upPRA2hi ← Q, c3;
Q ← upA2lo, c1;
upPRA2lo ← Q, c2;
Q ← upA3hi, c3;
upPRA3hi ← Q, c1;
Q ← upA3lo, c2;
upPRA3lo ← Q, c3;
Ybus ← upDebug, NZeroBr, c1;
BRANCH[LPrDB0, LPrDB1], L3 ← 0, c2;{set L3 to 1 if Debug not zero}
LPrDB0:
GOTO[RestorePrologEnd], c3;
LPrDB1:
GOTO[RestorePrologEnd], c3;
RestorePrologEnd:
Ybus ← upWriteMode, NZeroBr, c1;
TT ← upVPClo, BRANCH[LPrWM0, LPrWM1], L2 ← 0, c2;
LPrWM0:
rhTT ← upVPChi, GOTO[startprologpcfetch], c3;
LPrWM1:
rhTT ← upVPChi, GOTO[startprologpcfetch], c3;
startprologpcfetch:
Map ← [rhTT, TT], L0 ← L0.PCcont, GOTO[PrPCcont], c1;
{--------------------------------------------------------------}
{ Read Map Update Routine}
{ returns thru L0 }
PrRMapFix:
PC ← Q, c3;
, c1;
, c2;
PrRMapFixNorm:
Xbus ← Rx LRot0, XwdDisp, c3;
Map ← [rhTT,TT], DISP2[PrRFixFlags], c1;
MDR ← Rx or 10, L0Disp, GOTO[PrReRead], c2, at[0, 4, PrRFixFlags];
MDR ← Rx or 10, L0Disp, GOTO[PrReRead], c2, at[1, 4, PrRFixFlags];
MDR ← Rx or 10, L0Disp, GOTO[PrReRead], c2, at[2, 4, PrRFixFlags];
GOTO[PrRWTrap], L1 ← L1.PrPF, c2, at[3, 4, PrRFixFlags];
PrReRead:
Xbus ← 1, XDisp, RET[PrRMapFixret], c3;
PrRWTrap:
{L0 indicates current state of PC
if L0 is odd, then PC is + 0, VPC is + 0
if L0 is even, then PC is + 1, VPC is + 1}
{rebuild correct PC and goto SaveProlog}
L0Disp, c3;
BRANCH[PrPFdecPC, PrPCstate0, 0E], c1;
PrPCstate0:
GOTO[SavePrologC3], c2;
PrPFdecPC:
Rx ← upVPClo, L1 ← L1.PrPF, c2;
, c3;
MAR ← Rx ← [Rx, PC + 0], c1;{byte merge}
PC ← Rx - 1, CarryBr, c2;
upVPClo ← PC, BRANCH[PrfixPChigh, $], c3;
GOTO[SavePrologC2], c1;
PrfixPChigh:
Q ← upVPChi, c1;
Q ← Q - 1, c2;
upVPChi ← Q, GOTO[SavePrologC1], c3;
{--------------------------------------------------------------}
{ E N D }