{XFer.mc, HGM, 4-Nov-84 3:03:13, Dicentra version
HGM, 25-Nov-83 19:20:31, MesaIntBr on way to Reschedule (and lots of CANCLEBRs)
HGM, 25-Nov-83 19:20:31, Check c2 at TrapGo
HGM, 28-Sep-83 3:57:11, Dangling branch at LGCa
File name: Xfer.mc
Description: Xfer and related opcodes,
Daniels 25-Oct-83 18:30:07 Rearrange LFC so that uXferType isn't at fZ = ←ib.
Daniels 22-Sep-83 15:06:44 Don't use TOS in GLFrame.
Daniels 17-Jun-83 12:03:30 new instruction set
Johnsson 3-Aug-83 11:18:00
Sandman March 5, 1982 12:02 PM Disable same G after RET trap fix
Sandman January 26, 1982 4:00 PM XferTraps vs disabled for module
Sandman January 22, 1982 XferTraps vs fsi last of page
Sandman November 17, 1981 10:35 AM New Instruction Set
Last edited by Jim Frandeen February 11, 1981 1:54 PM: catch KFCB for Block Equal
Created by R. Johnsson }
{Fault/Trap flag}
Set[L3.XTrap, 0];
Set[L3.XFault, 1];
{LoadGC returns - Link 2; relative to LGCRtn}
MacroDef[LGCr, at[#1,10,LGCRtn]];
Set[L2.LGCFrame,9];{1 mod 3};
Set[L2.LGCFr,0B];{3 mod 3};
Set[L2.LGCEVAlloc,0D]; {must be odd; same as XCode, AllocSub}
{AllocSub returns - Link 2}
MacroDef[Allocr, at[#1,10,AllocRtn]];
Set[L2.LGCEVAlloc,0D]; {must be odd; same as XCode, LoadGC}
Set[L2.AF,0C];
{XCode returns - Link 2}
MacroDef[XCoder, at[#1,10,XCodeRtn]];
Set[L2.LGCEVAlloc,0D]; {must be odd; same as LoadGC, AllocSub}
Set[L2.XFrame,0A];
{GetLink returns - Link 2; relative to GLRtn}
MacroDef[GLr, at[#1,10,GLRtn]];
Set[L2.LLKBLink,0];
Set[L2.RKIBLink,1];
Set[L2.RKDIBLink,3];
Set[L2.EFCLink,2];{Same as L1.Xfer}
{XMDSWrite returns - Link 2; relative to XWRtn}
MacroDef[XWr, at[#1,10,XWRtn]];
Set[L2.POSpc,5]; {also SPCr}
Set[L2.PI,6];
Set[L2.DSKLoop,7];
Set[L2.DSKStkp,8];
{XMDSRead returns - Link 2; relative to XRRtn}
MacroDef[XRr, at[#1,10,XRRtn]];
Set[L2.LSKStkp,9];
Set[L2.LSKLoop,0A];
Set[L2.XSource,0B];
Set[L2.XIndirect,0C];
{****************************************************************************
LKB - Link Byte
****************************************************************************}
@LKB: T ← ib, push{tos}, c1, opcode[172'b];
PC ← PC + 1, push{destlo}, c2;
TT ← STK, pop{tos}, c3;
MAR ← [rhL, L+0], pop, c1;
MDR ← TT - T, IBDisp, GOTO[DISPNIonly], c2;
{****************************************************************************
EFCn - External Function Call n (n = 0-12)
****************************************************************************}
@EFC0: T ← 0, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[337'b];
@EFC1: T ← 1, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[340'b];
@EFC2: T ← 2, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[341'b];
@EFC3: T ← 3, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[342'b];
@EFC4: T ← 4, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[343'b];
@EFC5: T ← 5, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[344'b];
@EFC6: T ← 6, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[345'b];
@EFC7: T ← 7, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[346'b];
@EFC8: T ← 8, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[347'b];
@EFC9: T ← 9, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[350'b];
@EFC10: T ← 0A, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[351'b];
@EFC11: T ← 0B, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[352'b];
@EFC12: T ← 0C, L2←L2.EFCnSpc, GOTO[EFCn], c1, opcode[353'b];
EFCn: TT ← UvPCpage, push, L1←1, CALL[StashPC1], c2;
rhT ← xtFC1, T ← T + T + 1, CANCELBR[EFCGetLink], c3, SPCr[L2.EFCnSpc];
{****************************************************************************
EFCB - External Function Call Byte
****************************************************************************}
@EFCB: T ← ib, L2←L2.EFCBSpc, c1, opcode[354'b];
TT ← UvPCpage, L1←2, push, CALL[StashPC2], c2;
rhT ← xtFC2, T ← T + T + 1, CANCELBR[$], c3, SPCr[L2.EFCBSpc];
EFCGetLink:
MAR ← [rhG, G-GF.word], GOTO[GetLink], L2←L2.EFCLink, c1;
{****************************************************************************
LFC - Local Function Call
****************************************************************************}
@LFC: T ← UvL, L2←L2.LFCSpc, c1, opcode[355'b];
TT ← UvPCpage, push, L1←3, CALL[StashPC3], c2;
rhT ← xtFC3, STK ← TOS, CANCELBR[$], c3, SPCr[L2.LFCSpc];
uSourceLo ← T, c1;
Rx ← XferType.lfc, c2;
uXferType ← Rx, c3;
PC ← ib, pop, c1;
PC ← PC LRot8, c2;
Noop, c3;
TT ← ib, L2←L2.LGCEVAlloc, c1;
T ← UvC, L1←L1.Xfer, c2;
uDestHi ← PC ← TT or PC, XC2npcDisp, GOTO[XCode], c3;
{****************************************************************************
SFC - Stack Function Call
****************************************************************************}
@SFC: T ← STK, push, L2←L2.SFCSpc, c1, opcode[356'b];
TT ← UvPCpage, L1←1, CALL[StashPC1], c2;
STK ← Q ← TOS, rhT ← xtSFC1, CANCELBR[$], c3, SPCr[L2.SFCSpc];
Rx ← XferType.call, c1;
uXferType ← Rx, pop, c2;
TT ← UvL, c3;
uSourceLo ← TT, pop, c1;
uDestHi ← TT ← Q, pop, c2;
SFCa: uDestLo ← T, YDisp, L1←L1.Xfer, GOTO[XFER], c3;
{****************************************************************************
RET - Return
****************************************************************************}
@RET: MAR ← [rhL,L-LF.word], L0←0, c1, opcode[357'b];
Rx ← UvPCpage, CANCELBR[$,0], c2;
TT ← MD{fsi}, uRetPChi ← Rx, c3;
RETa: T ← PC LShift1, Cin←pc16, c1;
UreturnPC ← T, L0Disp, c2;
Rx ← UvC, BRANCH[RETb, AFa], c3;
RETb: uRetC ← Rx, Rx ← XferType.ret, c1;
Ufsi ← TT, TT ← 0, c2;
uSourceLo ← TT, c3;
MAR ← [rhL,L-LF.returnLink], push, L1←L1.Xfer, c1;
rhT ← xtRET, STK ← TOS, CANCELBR[$,0], c2;
T ← MD, uXferType ← Rx, pop, XDisp, GOTO[XFER], c3;
{****************************************************************************
LLKB - Load Link Byte
****************************************************************************}
@LLKB: T ← ib, push, L2←L2.LLKBLink, c1, opcode[167'b];
STK ← TOS, push, PC ← PC + 1, L1←L1.Pop2Dec2, c2;
LLKBa: rhTT ← UvChigh, c3;
MAR ← [rhG,G-GF.word], c1;
TT ← UvC, CANCELBR[$,0], c2;
T ← T + T + 1, Xbus ← MD, XLDisp, GOTO[GLd], c3;
STK ← T, CANCELBR[$,0F], c1, GLr[L2.LLKBLink];
TOS ← TT, push, fZpop, IBDisp, GOTO[DISPNIonly], c2;
{****************************************************************************
RKIB - Read Link Indirect Byte
****************************************************************************}
@RKIB: T ← ib, push, L2←L2.RKIBLink, c1, opcode[170'b];
STK ← TOS, push, PC ← PC + 1, L1←L1.Pop2Dec2, GOTO[LLKBa], c2;
Map ← Q ← [rhTT, T], CANCELBR[$,0F], c1, GLr[L2.RKIBLink];
pop, L1←L1.PopDec2, GOTO[RLMpc3], c2;
{****************************************************************************
RKDIB - Read Link Double Indirect Byte
****************************************************************************}
@RKDIB: T ← ib, push, L2←L2.RKDIBLink, c1, opcode[171'b];
STK ← TOS, push, PC ← PC + 1, L1←L1.Pop2Dec2, GOTO[LLKBa], c2;
Map ← Q ← [rhTT, T], CANCELBR[$,0F], c1, GLr[L2.RKDIBLink];
pop, L1←L1.Pop2Dec2, GOTO[RDLMc3], c2;
{****************************************************************************
PO - Port Out
****************************************************************************}
@POR: PC ← PC - 1, L2←L2.POSpc, GOTO[POa], c1, at[0E,10,ESC0n];
@PO: PC ← PC - 1, L2←L2.POSpc, c1, at[0D,10,ESC0n];
POa: TT ← UvPCpage, L1←2, CALL[StashPC2], c2;
TT ← STK, L0←L0.XWrite, pop, CANCELBR[$], c3, SPCr[L2.POSpc];
Map ← Q ← [rhMDS,TT], L1←L1.Xfer, pop, c1;
T ← UvL, CALL[XWritex], c2;
Q ← TT + 1, rhT ← xtSFC2, c3, XWr[L2.POSpc];
Map ← Q ← [rhMDS, Q + 1], L2←L2.EFCLink, c1;
Rx ← XferType.port, GOTO[GLe], c2;
{****************************************************************************
PI - Port In
****************************************************************************}
@PI: T ← 0, L1←L1.PopDec2, push{tos}, c1, at[0C,10,ESC0n];
rhTT ← UvMDS, push{dest}, c2;
Rx ← STK{dest}, push{source}, L2←L2.PI, c3;
Map ← [rhTT,Rx], TT ← STK{source}, pop{dest}, c1;
Q ← Rx, pop{tos}, L0←L0.XWrite, CALL[XWritex], c2;
T ← TT, ZeroBr, c3, XWr[L2.PI];
TOS ← STK, pop, BRANCH[PIa,IBDispOnly], c1;
PIa: Q ← Q + 2, push, c2;
L1←L1.Dec2, c3;
Map ← [rhMDS, Q], c1;
GOTO[WMpc3], c2;
{****************************************************************************
KFCB - Kernel Function Call Byte
****************************************************************************}
@KFCB: T ← ib, L2←L2.KFCBSpc, c1, opcode[360'b];
TT ← UvPCpage, L1←2, push, CALL[StashPC2], c2;
T ← T + T + 1, rhT ← xtFC2, CANCELBR[$], c3, SPCr[L2.KFCBSpc];
Rx ← XferType.call, STK ← TOS, pop, c1;
KFCBa: TOS ← LShift1 0FF, SE ← 1, c2;
rhTT ← UvMDS, c3;
Map ← Q ← [rhMDS, TOS + T], L2←L2.EFCLink, c1;
TT ← UvL, GOTO[GLe], c2;
{****************************************************************************
AF - Allocate frame
****************************************************************************}
@AF: UrL ← L, L ← rhL, pop, c1, at[0A,10,ESC0n];
UrLHi ← L, push, L0←1, c2;
PC ← PC - 1, GOTO[RETa], c3;
AFa: uRetC ← Rx, L2←L2.AF, c1;
Rx ← UvPCpage, Cin←pc16, c2;
uRetPChi ← Rx, c3;
rhT ← xtAF, c1;
T ← 0FF + 1, c2;
L1←L1.Xfer, c3;
Map ← Q ← [rhMDS, T + TOS], L1←L1.Xfer, CALL[AllocSub], c1;
rhL ← UrLHi, c3, Allocr[L2.AF];
TOS ← TT, c1;
L ← UrL, IBDisp, GOTO[NegNI], c2;
{****************************************************************************
FF - Free frame
****************************************************************************}
@FF: Map ← uFrame ← Q ← [rhMDS, TOS], L1←L1.Dec2, c1, at[0B,10,ESC0n];
L0←L0.FF, c2;
rhRx ← Rx ← MD, XDirtyDisp, c3;
MAR ← [rhRx, Q-LF.word], BRANCH[FFMUD,$,1], c1, WMFRet[L0.FF];
Q ← 0FF, CANCELBR[$,0], c2;
TT ← MD and Q, c3;
Map ← [rhMDS, Q + 1], L2←1, c1;
GOTO[Freex], c2;
FFb: MAR ← [rhRx, Q+0], GOTO[Wb], c1;
FFMUD: CANCELBR[WMapFix,0], c2;
{****************************************************************************
DI - Disable Interrupts
****************************************************************************}
@DI: T ← uWDC, c1, at[0,10,ESC1n];
T ← T+1, PgCarryBr, c2;
DIc: uWDC ← T, BRANCH[DIa, DIb], c3;
DIa: GOTO[IBDispOnly], c1;
DIb: T ← sInterruptError, GOTO[Trapc2], c1;
{****************************************************************************
EI - Enable Interrupts
****************************************************************************}
@EI: T ← uWDC, c1, at[1,10,ESC1n];
T ← T - 1, NegBr, GOTO[DIc], c2;
{****************************************************************************
DSK - Dump Stack
****************************************************************************}
@DSK: Q ← UvL, L1←L1.Dec2, c1, at[0,10,ESC2n];
Q ← Q + ib, L2←0, c2;
Rx ← State.word, c3;
DSKg: T ← UBrkByte, c1;
T ← T LRot8, L2Disp, c2;
UBrkByte ← 0, BRANCH[DSKf, PSSf], c3;
DSKf: TT ← ~ErrnIBnStkp, c1;
TT ← TT and 0F, L2←L2.DSKStkp, c2;
T ← T or TT, c3;
Map ← Q ← [rhMDS, Q+Rx], CALL[XWrite], c1;
T ← TT + 4, NibCarryBr, c3, XWr[L2.DSKStkp];
Q ← Q - State.word, BRANCH[DSTa, DSTb], c1;
DSTa: stackP ← TT ← TT + 2, GOTO[DSKc], c2;
DSTb: stackP ← TT ← 0E, GOTO[DSKc], c2;
DSKc: Q ← Q + TT, push, L2←L2.DSKLoop, c3;
DSKh: Map ← Q ← [rhMDS, Q - 1], BRANCH[DSKd, DSKe], c1;
DSKd: T ← STK, pop, CALL[XWritex], c2;
TT ← TT - 1, ZeroBr, GOTO[DSKh], c3, XWr[L2.DSKLoop];
DSKe: PC ← PC + PC16, pop, IBDisp, GOTO[DISPNIonly], c2;
{****************************************************************************
LSK - Load Stack
****************************************************************************}
@LSK: T ← UvL, L1←L1.Dec2, c1, at[3,10,ESC2n];
T ← T + ib, L2←L2.LSKStkp, c2;
TOS ← State.word, c3;
Map ← Q ← [rhMDS, TOS + T], c1;
stackP ← 1, L0←L0.XRead, CALL[XReadx], c2;
rhT ← TT LRot8, T ← TT + 1, c1, XRr[L2.LSKStkp];
T ← rhT, uPsbLink ← T, c2;
TT ← TT + 4, NibCarryBr, c3;
UBrkByte ← T, BRANCH[LSKa, LSKb], c1;
LSKa: TT ← TT and 0F, GOTO[LSKc], c2;
LSKb: TT ← 10, GOTO[LSKc], c2;
LSKc: T ← TT - 2, L2←L2.LSKLoop, c3;
LSKf: Map ← Q ← [rhMDS, Q-TOS], CALL[XRead], c1;
T ← T - 1, ZeroBr, push, c1, XRr[L2.LSKLoop];
STK ← TT, BRANCH[LSKd, LSKe], c2;
LSKd: TOS ← TOS xor ~TOS, GOTO[LSKf], c3;
LSKe: stackP ← uPsbLink, c3;
PC ← PC + PC16, c1;
TOS ← STK, pop, IBDisp, GOTO[DISPNIonly], c2;
{****************************************************************************
XF - XFER and Free
****************************************************************************}
@XF: MAR ← [rhL, L-LF.word], c1, at[2,10,ESC2n];
rhT ← xtXF, CANCELBR[$,0], c2;
T ← MD, L2←L2.XSpc, GOTO[Xa], c3;
{****************************************************************************
XE - XFER and Enable
****************************************************************************}
@XE: T ← uWDC, c1, at[1,10,ESC2n];
rhT ← xtX, T ← T - 1, c2;
uWDC ← T, L2←L2.XSpc, c3;
Xa: PC ← PC - 1, c1;
TT ← UvPCpage, L1←3, CALL[StashPC3], c2;
Ufsi ← T, CANCELBR[$], c3, SPCr[L2.XSpc];
TT ← UvL, L1←L1.Xfer, c1;
T ← TT + ib + 1, L0←L0.XRead, c2;
rhTT ← UvMDS, c3;
Map ← Q ← [rhMDS, T - 1], L2←L2.XSource, c1;
uFrame ← TT, CALL[XReadx], c2;
Map ← Q ← [rhMDS, T + 1], L2←L2.EFCLink, c1, XRr[L2.XSource];
Rx ← XferType.xfer, GOTO[GLe], c2;
{****************************************************************************
BRK - BreakPoint
****************************************************************************}
@BRK: T ← UBrkByte, ZeroBr, push, c1, opcode[75'b];
STK ← TOS, pop, BRANCH[BRKa, BRKb], c2;
BRKb: G ← 0, GOTO[Trapc1], c3;
BRKa: UBrkByte ← 0, c3;
BRKc: Xbus ← T LRot12, XDisp, c1;
Ybus ← T, YDisp, DISP4[OpD0], c2;
{OpD0:} GOTOABS[Add[OpcodeBase,0]], c3, at[0,10,OpD0];
GOTOABS[Add[OpcodeBase,10]], c3, at[1,10,OpD0];
GOTOABS[Add[OpcodeBase,20]], c3, at[2,10,OpD0];
GOTOABS[Add[OpcodeBase,30]], c3, at[3,10,OpD0];
GOTOABS[Add[OpcodeBase,40]], c3, at[4,10,OpD0];
GOTOABS[Add[OpcodeBase,50]], c3, at[5,10,OpD0];
GOTOABS[Add[OpcodeBase,60]], c3, at[6,10,OpD0];
GOTOABS[Add[OpcodeBase,70]], c3, at[7,10,OpD0];
GOTOABS[Add[OpcodeBase,80]], c3, at[8,10,OpD0];
GOTOABS[Add[OpcodeBase,90]], c3, at[9,10,OpD0];
GOTOABS[Add[OpcodeBase,0A0]], c3, at[0A,10,OpD0];
GOTOABS[Add[OpcodeBase,0B0]], c3, at[0B,10,OpD0];
GOTOABS[Add[OpcodeBase,0C0]], c3, at[0C,10,OpD0];
GOTOABS[Add[OpcodeBase,0D0]], c3, at[0D,10,OpD0];
GOTOABS[Add[OpcodeBase,0E0]], c3, at[0E,10,OpD0];
GOTOABS[Add[OpcodeBase,0F0]], c3, at[0F,10,OpD0];
{****************************************************************************
Xfer:
Entry:
Udest and T hold destination link
PC has LRot1 T (for procedure descriptor decode)
L has va of caller's frame (to be stored into Usource)
calling instruction executed on c1 and entera at one of:
XferFrame, XferProc1, XferIndirect, XferProc3
****************************************************************************}
XFER: Map←Q←[rhMDS,T], uDestLo←T, DISP4[XferFrame,0C], c1, GLr[L2.EFCLink];
{ ********* Frame link ********* }
XferFrame:
TOS ← Q, L0←L0.Xfer, ZeroBr, c2, at[0C,10,XferFrame];
L ← MD, rhL ← MD, XDirtyDisp, BRANCH[$, ControlTrap], c3;
XFStartRead:
MAR ← [rhL, Q-LF.globalLink], BRANCH[XFMUD,XFMOK,1], c1;
MAR ← [rhL, Q-LF.globalLink], BRANCH[XFMUD,XFMOK,1], c1, WMFRet[L0.Xfer];
XFMUD: Rx ← L, CANCELBR[WMapFix, 0], c2;
XFMOK: T ← UvL, CANCELBR[$, 0], c2;
TT ← MD, uFrame ← T, c3;
Map ← Q ← [rhMDS, TT], c1;
Ybus ← Q xor UvG, ZeroBr, L2←L2.LGCFrame, c2;
G ← rhG ← MD, XRefBr, BRANCH[$,SameG], c3;
MAR ← [rhG,Q-GF.codeLow], L0←L0.LGCRead, BRANCH[LGCa,LGCb], c1, RMFRet[L0.LGCRead];
SameG: MAR ← G ← [rhG, Q+0], CANCELBR[$,1], c1, RMFRet[L0.LGCSameG];
T ← UvC, c2;
rhTT ← TT ← UvChigh, c3;
MAR ← L ← [rhL,TOS-LF.pc], L2←L2.XFrame, c1, LGCr[L2.LGCFrame];
L ← L + LF.pc, CANCELBR[$,0], c2;
PC ← MD, XC2npcDisp, UvChigh ← TT, CALL[XCode], c3;
UvL ← TOS, c1, XCoder[L2.XFrame];
uPCCross ← 0, c2;
Q ← T - 1, Xbus ← rhT, XDisp, c3;
Map ← [rhMDS, Q + 1], L2←0, push, DISP3[XFTrap], c1;
XFTrap: Rx ← Rx + 1, c2, at[0,8,XFTrap];
uWDC ← Rx, GOTO[XPEnd], c3;
XFRet: TT ← Ufsi and Q, L2←0, GOTO[Freex,0], c2, at[3,8,XFTrap];
XFCall: GOTO[XferDone], c2, at[2,8,XFTrap];
XFRetI: T ← uSourceLo, push, GOTO[XPSD], c2, at[7,8,XFTrap];
XFCalI: T ← uSourceLo, push, GOTO[XPSD], c2, at[6,8,XFTrap];
{ ********* Indirect link ********* }
XferIndirect:
T ← rhT, c2, at[0E,10,XferFrame];
T ← T or 4, L2←L2.XIndirect, c3;
Map ← Q ← [rhMDS, Q+1], L0←L0.XRead, c1;
rhT ← T LRot0, GOTO[XReadx], c2;
MAR ← [rhRx, Q-1], c1, XRr[L2.XIndirect];
T ← UvL, CANCELBR[$,0], c2;
T ← MD, uFrame ← T, XDisp, c3;
Map ← Q ← [rhMDS, T], DISP4[XferFrame,0C], c1;
{ ********* Procedure descriptor ********* }
XferProc:
Q ← T-1, ZeroBr, GOTO[XProc], L2←L2.LGCEVAlloc, c2, at[0D,10,XferFrame];
Q ← T-1, ZeroBr, GOTO[XProc], L2←L2.LGCEVAlloc, c2, at[0F,10,XferFrame];
XProc: rhG ← G ← MD, XRefBr, uTT ← TT, BRANCH[$, UnboundTrap], c3;
MAR ← [rhG,Q-GF.codeLow], L0←L0.LGCRead, BRANCH[LGCa,LGCb], c1;
UvChigh ← TT, c1, LGCr[L2.LGCEVAlloc];
PC ← uTT, c2;
XC2npcDisp, GOTO[XCode], c3;
XAlloc: Map←Q←[rhMDS, T or ib], CALL[AllocSub], c1, XCoder[L2.LGCEVAlloc];
uPCCross ← 0, c3, Allocr[L2.LGCEVAlloc];
MAR ← Q ← [rhL, Q-LF.globalLink], c1;
MDR ← TOS, L ← Q + LF.globalLink, CANCELBR[$,0], c2;
UvL ← TT, Xbus ← rhT, XDisp, push, c3;
XPEnd: MAR ← [rhL,L-LF.returnLink], L2 ← 0, DISP3[XPTrap], c1;
XPTrap: MDR ← uSourceLo, CANCELBR[XTrap,0], c2, at[0,8,XPTrap];
XPRet: MDR ← uSourceLo, CANCELBR[XPFree,0], c2, at[3,8,XPTrap];
XPCall: MDR ← uSourceLo, CANCELBR[XferDone,0], c2, at[2,8,XPTrap];
XPRetI: MDR ← T ← uSourceLo, push, CANCELBR[XPSD,0], c2, at[7,8,XPTrap];
XPCalI: MDR ← T ← uSourceLo, push, CANCELBR[XPSD,0], c2, at[6,8,XPTrap];
XTrap: T ← UrG, ZeroBr, c3;
BRANCH[STPa, STPb], c1;
STPb: GOTO[XferDone], c2;
STPa: Noop, c2;
STPc: T ← T - 1, Ybus ← T, YDisp, c3;
MAR ← [rhL, L+T], DISP4[STPd], c1;
MDR ← uTrapParm0, CANCELBR[XferDone,0], c2, at[1,10,STPd];
MDR ← uTrapParm1, CANCELBR[STPc,0], c2, at[2,10,STPd];
MDR ← uTrapParm2, CANCELBR[STPc,0], c2, at[3,10,STPd];
XPSD: TT ← uDestLo, push, c3;
STK ← T, pop, L2Disp, c1;
STK ← TT, pop, BRANCH[XferDone,XPFree,0E], c2;
XPFree: Q ← 0FF, c3;
{map av item}
Free: Map ← [rhMDS, Q + 1], GOTO[XFRet], c1;
Freex: rhRx ← Rx ← MD, XDirtyDisp, c3;
{store new head, fetch old head}
MAR ← [rhRx,TT+0], L0←L0.Free, BRANCH[FreeMUD,FreeMOK,1], c1;
MAR ← [rhRx,Q+0], BRANCH[XXXXX,XXXX,1], c1, WMFRet[L0.Free];
FreeMUD:
Q ← TT + Q + 1, GOTO[WMapFix], c2;
XXXXX: GOTO[XXXXX], c*;
XXXX: GOTO[FreeMO2], c2;
FreeMOK:
Q ← TT + Q + 1, c2;
FreeMO2:
T ← MD{old list head}, c3;
MAR ← [rhRx, Q+0], c1;
MDR ← Rx ← uFrame, c2;
Noop, c3;
{map old frame}
Map ← Q ← [rhMDS,Rx], c1;
L2Disp, c2;
rhRx ← Rx ← MD, BRANCH[$, FFb], c3;
{store old list head}
MAR ← [rhRx,Q+0], c1;
MDR ← T, c2;
XferDone:
TT ← RShift1 uXTS, XLDisp, c3;
XTail: uPCValid ← PC xor ~PC, BRANCH[$, XferTrap, 2], c1;
uXTS ← TT, IBDisp, GOTO[SLa], c2;
XferTrap:
TT ← TT LShift1, SE ← 1, uXTS ← TT, c2;
Rx ← uXferType, c3;
MAR ← [rhG, G-GF.word], c1;
T ← 30, CANCELBR[$,0], c2;
Xbus ← MD, XDisp, uTrapParm2 ← Rx, c3;
XTc: [] ← T and ~ErrnIBnStkp, ZeroBr, BRANCH[XTa, XTb, 0D], c1;
XTa: uXTS ← TT, IBDisp, CANCELBR[SLa,1], c2;
XTb: [] ← PC - PC16, PgCarryBr, pop, BRANCH[XTd, XTe], c2;
XTd: T ← sXferTrap, Cin←pc16, CANCELBR[XTg, 1], c3;
XTe: T ← sXferTrap, Cin←pc16, BRANCH[XTf, XTg], c3;
XTf: uPCCross ← T xor ~T, GOTO[XTh], c1;
XTg: GOTO[XTh], c1;
XTh: TT ← uDestHi, c2;
uTrapParm1 ← TT, c3;
TT ← uDestLo, c1;
uTrapParm0 ← TT, c2;
G ← 3, GOTO[Trapc1], c3;
{****************************************************************************
Xfer Code:
Entry:
T has UvC
TT has UvChigh
Fetch pending on PC
Exit:
PC has real PC
IB has first byte(s) of code
UvChigh, UvC stored
UrhPCsave has byte PC
****************************************************************************}
XCode: TT ← RShift1 PC, ZeroBr, BRANCH[xcOdd, xcEven, 0E], c1;
xcOdd: Q ← TT + T, IBPtr←1, BRANCH[XCa, XCb], c2;
xcEven: Q ← TT + T, IBPtr←1, Cin←pc16, BRANCH[XCa, XCb], c2;
XCa: TT ← Q and ~0FF, L0←L0.XCode, c3;
Map ← UvPCpage ← [rhTT, TT], Xbus ← ib, c1;
T ← 0FF + 1, c2;
PC ← rhPC ← MD, XRefBr, UrhPCsave ← PC, c3;
MAR←Q←[rhPC,Q+0], Xbus←UrhPCsave, XLDisp, BRANCH[XCd, XCe], c1, RMFRet[L0.XCode];
XCe: Rx ← uWDC, BRANCH[xcE, xcO, 2], L2Disp, c2;
xcE: IB ← MD, PC ← Q, Cin←pc16, RET[XCodeRtn], c3;
xcO: IB ← MD, PC ← Q, IBPtr←1, RET[XCodeRtn], c3;
XCd: Rx ← PC, CANCELBR[RCMapFix, 3], c2;
XCb: GOTO[UnboundTrap], c3;
{****************************************************************************
Trap Handler:
Entry:
calling instruction on c1
UvL is valid for trapping frame
T has SD index;
Exit:
PC of UvL backed up by amount in rhT
rhT has xtTrap
goes to SDFetch
****************************************************************************}
CodeTrap: {TT already has parameter}
T ← sCodeTrap, CANCELBR[TH1,0], c2;
ControlTrap:
T ← sControlTrap, CANCELBR[$,3], c1;
TT ← uSourceLo, c2;
TH1: G ← 1, GOTO[TH], c3;
UnboundTrap:
T ← sUnbound, CANCELBR[$,1], c1;
TT ← uDestLo, c2;
Rx ← uDestHi, c3;
G ← 2, c1;
uTrapParm1 ← Rx, c2;
Noop, c3;
TH: Noop, c1;
TOS ← UvL, L3←L3.XTrap, c2;
THa: Xbus ← rhT, XwdDisp, c3;
Map ← [rhMDS, TOS], DISP2[THb], c1;
THb: Q ← 0, GOTO[THc], c2, at[0,4,THb];
Q ← 1, GOTO[THc], c2, at[1,4,THb];
Q ← 2, GOTO[THc], c2, at[2,4,THb];
Q ← 3, GOTO[THc], c2, at[3,4,THb];
THc: L ← rhL ← MD, c3;
MAR ← L ← [rhL, TOS+0], c1;
Xbus ← rhT, XLDisp, c2;
uTrapParm0 ← TT, BRANCH[THx, THy, 1], c3;
THy: push, c1;
push, c2;
Noop, c3;
THx: MAR ← [rhL, L-LF.pc], c1;
Xbus ← rhT, XRefBr, CANCELBR[$,0], c2;
PC ← MD, L3Disp, BRANCH[THd, THe], c3;
TrapGo: uPCValid ← 0, CANCELBR[$], c3, SPCr[L2.TRAPSpc];
rhT ← xtTrap, T ← T + T + 1, GOTO[Trapping], c1;
THd: MAR ← [rhL, L-LF.pc], CANCELBR[$,1], c1;
MDR ← PC - Q, L3Disp, CANCELBR[$,0], c2;
uPCValid ← 0, BRANCH[$, XferFault], c3;
rhT ← xtTrap, T ← T + T + 1, c1;
Trapping:
UrG ← G, XC2npcDisp, c2;
Rx ← XferType.trap, BRANCH[CyclesOutOfPhaseTrap, $, 0D], c3;
GOTO[KFCBa], c1;
FaultGo:
uPCValid ← 0, CANCELBR[$,1], c3, SPCr[L2.FAULTSpc];
XferFault:
Rx ← pFault, GOTO[SaveRegs], c1;
THe: Q ← uRetC, XC2npcDisp, L2←L2.TRAPSpc, BRANCH[THj, THk], c1;
THj: PC ← RShift1 UreturnPC, SE ← 0, XLDisp, BRANCH[THf, THg, 0E], c2;
THk: PC ← RShift1 UreturnPC, SE ← 0, XLDisp, BRANCH[THf, THg, 0E], c2;
THf: UvC ← Q, Cin←pc16, BRANCH[THh, THi, 2], c3;
THg: UvC ← Q, BRANCH[THh, THi, 2], c3;
THh: TT ← uRetPChi, GOTO[THl], c1;
THi: TT ← uRetPChi, Cin←pc16, GOTO[THl], c1;
THl: UvG ← 0{disable SameG}, L1←0, GOTO[StashPC0], c2;
{****************************************************************************
Xfer Page Faults:
Entry:
push from R/WTrap
L3 tells where VA is;
Exit:
returns to Xfer's Trap handler
****************************************************************************}
XPF: Rx ← pFault, L3Disp, GOTO[XPFa], c1, at[L1.Xfer,10,RTrapFix];
Rx ← pFault, L3Disp, GOTO[XPFa], c1, at[L1.Xfer,10,RLTrapFix];
Rx ← pFault, L3Disp, GOTO[XPFa], c1, at[L1.Xfer,10,WTrapFix];
XPFa: TOS ← UvL, L3Disp, BRANCH[XPFb, XPFc, 2], c2;
XPFb: uFaultParm0 ← Q, BRANCH[XPFd, XPFe, 1], c3;
XPFc: uFaultParm0 ← TT, BRANCH[XPFd, XPFe, 1], c3;
XPFd: Q ← rhMDS, L3←L3.XFault, GOTO[XPFf], c1;
XPFe: Q ← rhTT, L3←L3.XFault, GOTO[XPFf], c1;
XPFf: uFaultParm1 ← Q, pop, GOTO[THa], c2;
{****************************************************************************
LoadGC subroutine:
Entry:
preceeding two instructions are:
Map←Q←[rhMDS,globalFrameAddr], L2←ret, c1;
[] ← Q xor UvG, NZeroBr, L1←L1w.XFWFault, GOTO[LoadGC], c2;
Exit:
T saved in uPsbLink
G, rhG, UvG set up
T has low 16 bits of codebase; stored in UvC
rhTT and TT have high bits of codebase (to be stored in UvChigh)
traps if page fault or odd codebase
returnee executed on c1
****************************************************************************}
LGCa: Rx ← G{map word}, CANCELBR[RMapFix,2], {****} c2;
LGCb: TT ← Q, CANCELBR[$,0], c2;
T ← MD{low codebase}, XLDisp, c3;
LGCHi: MAR ← G ← [rhG, TT-GF.codeHi], BRANCH[$,CodeTrap,2], c1;
G ← G + GF.codeHi, UvC ← T, L2Disp, CANCELBR[$,0], c2;
rhTT ← TT ← MD, UvG ← TT, RET[LGCRtn], c3;
{****************************************************************************
StashPC subroutine:
Entry:
calling instruction executed on c2 and includes:
TT ← UvPCpage, L1←n, goto[StashPCn]; {n = 0,1,2}
uPCCross is -1 if UvPCpage might be one too small, 0 if UvPCpage is OK
Link1 has PC increment in low two bits
Link2 has return index
Exit:
byte PC computed and stored in L+1
rhTT has UvChigh
Rx has 0
TT and Q smashed
returnee executed on c3
****************************************************************************}
StashPC0: Q ← UvC, GOTO[StashPCa], c3;
StashPC1: Q ← UvC, GOTO[StashPCa], c3;
StashPC2: Q ← UvC, GOTO[StashPCa], c3;
StashPC3: Q ← UvC, GOTO[StashPCa], c3;
StashPCa: Rx ← 0, Xbus ← uPCCross, XRefBr, c1;
StashPCa1: Q ← TT - Q, L1Disp, BRANCH[StGood,StCross], c2;
StGood: TT ← 0FF and PC, BRANCH[StLT2, StEQ2, 1], c3;
StLT2: TT ← TT + Q, GOTO[StShift], c1;
StEQ2: TT ← TT + Q + 1, GOTO[StShift], c1;
StShift:
TT ← LShift1 TT, SE ← pc16, c2;
TT ← TT+1, L1Disp, GOTO[StashPCb], c3;
StashPCb:
MAR ← [rhL,L-LF.pc], L2Disp, BRANCH[St0, St1, 2], c1;
St0: MDR ← TT-1, rhTT ← UvChigh, MesaIntBr, RET[SpcRtn], c2;
St1: MDR ← TT, rhTT ← UvChigh, MesaIntBr, RET[SpcRtn], c2;
{no page carry and uPCCross#0 => UvPCpage must be advanced}
StCross:
[] ← PC+1, PgCarryBr, CANCELBR[$, 3], c3;
Q ← UvC, BRANCH[$,StashPCa1], c1;
TT ← TT + 0FF + 1, c2;
uPCCross ← 0, GOTO[StashPCa], c3;
{****************************************************************************
GetLink subroutine:
Entry:
calling instruction executed on c1 and includes:
MAR ← [rhG, g]
T has link index
rhTT has UvChigh
Link2 has return index
Exit:
T has destination control link
L has caller frame
TOS saved in STK
TT and Q smashed
returnee executed on c1
****************************************************************************}
GetLink:
TT ← UvC, L1←L1.Xfer, CANCELBR[$,0], c2;
Rx ← Rx + 1, Xbus ← MD, XLDisp, STK ← TOS, pop, c3;
GLd: Map ← Q ← [rhTT, TT-T-1], BRANCH[GLFrame,GLCode,2], c1;
GLCode: TT ← UvL, c2;
GLe: rhRx ← Rx ← MD, XRefBr, uXferType ← Rx, c3;
MAR ← [rhRx, Q+1], L0←L0.CLRead, BRANCH[$,GLa], c1, RLMFRet[L0.CLRead];
CANCELBR[RLMapFix,0], c2;
GLa: uSourceLo ← TT, CANCELBR[$,0], c2;
GLf: rhTT ← TT ← MD, c3;
MAR ← [rhRx, Q+0], L1←L1.Xfer, c1;
GLc: uDestHi ← TT, L2Disp, CANCELBR[$,0], c2;
T ← MD, XDisp, RET[GLRtn], c3;
GLFrame:
Q ← T + 4, c2;
TT ← UvG, c3;
Map ← Q ← [rhMDS, TT-Q-1], c1;
TT ← UvL, c2;
rhRx ← Rx ← MD, XRefBr, uXferType ← Rx, c3;
MAR ← [rhRx, Q+1], L0←L0.CLRead, BRANCH[$,GLb], c1, RMFRet[L0.CLRead];
CANCELBR[RMapFix,0], c2;
GLb: uSourceLo ← TT, CANCELBR[GLf,0], c2;
{****************************************************************************
Alloc subroutine:
Entry:
calling instruction executed on c1
Map fetch started on AV
Exit:
rhL set up
TOS has UvG
Q, TT has new frame L (VA)
PC incremented for Xfer
returns through L2 relative to AllocRtn
returnee executed on c1
****************************************************************************}
AllocSub:
uFaultParm0 ← T ← Q, L0←L0.Alloc1, c2;
rhRx ← Rx ← MD, XDirtyDisp, c3;
Alloc1: MAR ← [rhRx, T+0], BRANCH[AllocMUD1,$,1], c1, WMFRet[L0.Alloc1];
TOS ← UvG, c2;
TT ← MD, XDisp, uRx ← Rx, c3;
Map ← Q ← [rhMDS, TT], DISP4[AV0,0C], c1;
AV0: PC ← PC + PC16, L0←L0.Alloc2, c2, at[0C,10,AV0];
rhL ← MD, L ← MD, XDirtyDisp, c3;
MAR ← [rhL, TT+0], BRANCH[AllocMUD2,$,1], c1, WMFRet[L0.Alloc2];
Rx ← uRx, c2;
uTTemp ← TT, TT ← MD, c3;
MAR ← [rhRx, T+0], L2Disp, {Write AV} c1;
MDR ← TT, TT ← uTTemp, RET[AllocRtn] c2;
AV3: TT ← RShift1 TT, GOTO[AV2a], c2, at[0F,10,AV0];
AV2: TT ← RShift1 TT, GOTO[AV2a], c2, at[0E,10,AV0];
AV2a: T ← RShift1 TT, Xbus ← 2, XDisp, GOTO[Alloc1], c3;
AV1: T ← qFrameFault, c2, at[0D,10,AV0];
Q ← 0FF, L3←L3.rhMDS.Q, c3;
Q ← Q and uFaultParm0, push, L3Disp, GOTO[XPFa], c1;
AllocMUD1: GOTO[WMapFix], c2;
AllocMUD2: Rx ← L, GOTO[WMapFix], c2;
{****************************************************************************
XRead subroutine:
Entry:
calling instruction executed on c1 and includes:
Map ← Q ← [mumble]
Link2 has return index
Exit:
TT has memory data
XDisp pending on data in T
L1 smashed
returnee executed on c1
****************************************************************************}
XRead: Noop, c2;
XReadx: rhRx ← Rx ← MD, XRefBr, c3;
XReady: MAR ← [rhRx,Q+0], BRANCH[XRMUD,$], c1, RMFRet[L0.XRead];
XReadz: L2Disp, CANCELBR[$,0], c2;
TT ← MD, LOOPHOLE[mdok], RET[XRRtn], c3;
XRMUD: GOTO[RMapFix], c2;
{****************************************************************************
XMDSWrite subroutine:
Entry:
calling instruction executed on c1 and includes:
Map ← Q ← [mumble]
T has memory data
Link2 has return index
Exit:
returnee executed on c3
****************************************************************************}
XWrite: L0←L0.XWrite, c2;
XWritex:
rhRx ← Rx ← MD, XDirtyDisp, c3;
MAR ← [rhRx,Q+0], L2Disp, BRANCH[XWMUD,$,1], c1, WMFRet[L0.XWrite];
MDR ← T, RET[XWRtn], c2;
XWMUD: Noop, CANCELBR[WMapFix, 0F], c2;