{File name: Xfer.mc Description: Xfer and related opcodes, AHL/JAC 21-Sep-87 15:04:46 set uGFI to 0 in trapping case as Trapping+2 AHL/JPM 20-Feb-87 10:39:31 Favor frame links over code links. JPM 9-Jan-87 14:13:34 Fix bug in LGC (typo) AHL/JPM 6-Jan-87 11:31:42 Changes for MDS relief JPM 11-Feb-85 14:00:21 Separate stackP ¬ and push by one instr. (at DSKc) JPM 3-Jan-85 15:29:46 Fix branch mask at XCe (mask top 3 bits) JPM 11-Oct-84 14:04:04 Fix bug in rewritten StashPC routine (wrong-way branch) JPM 10-Oct-84 12:12:45 Fix XFTrap branch (must now mask bit 12); changed StashPC routine to decrement PCpage JPM 28-Sep-84 9:52:26 Use hardware to enable/disable interrupts (at @DI, @EI, @XE, and XFTrap) JPM 11-Sep-84 13:35:25 Fix BRANCH mask after XWtOKDisp; fix allocation error DEG 1-Sep-84 19:57:28 Add copyright notice. JPM, 22-Jun-84 9:55:20, replace XRefBr at THx+1 by XDisp (using bit 12), replace XDirtyDisp by XWtOKDisp HGM, 28-Nov-83 6:56:06, 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 AXD 25-Oct-83 18:30:07 Rearrange LFC so that uXferType isn't at fZ = ¬ib. AXD 22-Sep-83 15:06:44 Don't use TOS in GLFrame. AXD 17-Jun-83 12:03:30 new instruction set RXJ 3-Aug-83 11:18:00 JGS March 5, 1982 12:02 PM Disable same G after RET trap fix JGS January 26, 1982 4:00 PM XferTraps vs disabled for module JGS January 22, 1982 XferTraps vs fsi last of page JGS November 17, 1981 10:35 AM New Instruction Set Last edited by JXF February 11, 1981 1:54 PM: catch KFCB for Block Equal Created by RXJ} { Copyright (C) 1981, 1982, 1983, 1984, 1985 by Xerox Corporation. All rights reserved.} {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.XProc,0D]; {must be odd; same as XCode, AllocSub} {AllocSub returns - Link 2} MacroDef[Allocr, at[#1,10,AllocRtn]]; {Set[L2.XProc,0D]; {must be odd; same as XCode, LoadGC}} Set[L2.AF,0C]; {XCode returns - Link 2} MacroDef[XCoder, at[#1,10,XCodeRtn]]; {Set[L2.XProc,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]; {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 ¬ 3, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[337'b]; @EFC1: T ¬ 5, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[340'b]; @EFC2: T ¬ 7, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[341'b]; @EFC3: T ¬ 9, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[342'b]; @EFC4: T ¬ 0B, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[343'b]; @EFC5: T ¬ 0D, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[344'b]; @EFC6: T ¬ 0F, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[345'b]; @EFC7: T ¬ 11, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[346'b]; @EFC8: T ¬ 13, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[347'b]; @EFC9: T ¬ 15, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[350'b]; @EFC10: T ¬ 17, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[351'b]; @EFC11: T ¬ 19, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[352'b]; @EFC12: T ¬ 1B, L2¬L2.EFCnSpc, GOTO[EFCn], c1, opcode[353'b]; EFCn: TT ¬ UvPCpage, push, L1¬1, CALL[StashPC1], c2; rhT ¬ xtFC1, CANCELBR[EFCGetLink], c3, SPCr[L2.EFCnSpc]; {**************************************************************************** EFCB - External Function Call Byte ****************************************************************************} @EFCB: T ¬ ib + 1, c1, opcode[354'b]; TT ¬ UvPCpage, L1¬2, push, c2; Q ¬ UvC, L2¬L2.EFCBSpc, GOTO[StashPCa], c3; rhT ¬ xtFC2, T ¬ T + T + 1, CANCELBR[$], c3, SPCr[L2.EFCBSpc]; EFCGetLink: MAR ¬ [rhG, G-GF.word], L2¬L2.EFCLink, GOTO[GetLink], 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; TT ¬ ib, pop, c1; TT ¬ TT LRot8, L2¬L2.XProc, c2; TT ¬ TT or ib, GOTO[SameG], 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, L1¬L1.Xfer, c3; uSourceLo ¬ TT, pop, c1; uDestHi ¬ TT ¬ Q, pop, c2; SFCa: uDestLo ¬ T, YDisp, 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 + 1, push, L2¬L2.LLKBLink, c1, opcode[167'b]; STK ¬ TOS, push, PC ¬ PC + 1, L1¬L1.Pop2Dec2, c2; LLKBa: rhTT ¬ UvGhigh, c3; MAR ¬ [rhG,G-GF.word], c1; TT ¬ UvG, 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 + 1, 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 + 1, 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; L0¬L0.W, 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, XWtOKDisp, c3; MAR ¬ [rhRx, Q-LF.word], BRANCH[FFMUD,$,0D], 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, ClrIE, c1, at[0,10,ESC1n]; T ¬ T+1, PgCarryBr, c2; uWDC ¬ T, BRANCH[DIa, DIb], c3; DIa: GOTO[IBDispOnly], c1; DIb: T ¬ sInterruptError, GOTO[Trapc2], c1; {**************************************************************************** EI - Enable Interrupts ****************************************************************************} @EI: T ¬ uWDC, ZeroBr, c1, at[1,10,ESC1n]; T ¬ T - 1, ZeroBr, BRANCH[EIa, EIb], c2; EIa: uWDC ¬ T, BRANCH[EIc, EId], c3; EIb: uWDC ¬ T, CANCELBR[DIb,1], c3; EIc: GOTO[IBDispOnly], c1; EId: SetIE, GOTO[IBDispOnly], c1; {**************************************************************************** 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, L2¬L2.DSKLoop, c3; Map ¬ Q ¬ [rhMDS, Q - 1], push, c1; DSKd: T ¬ STK, pop, CALL[XWritex], c2; TT ¬ TT - 1, ZeroBr, c3, XWr[L2.DSKLoop]; Map ¬ Q ¬ [rhMDS, Q - 1], BRANCH[DSKd, DSKe], c1; 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[XEb], c3; {**************************************************************************** XE - XFER and Enable ****************************************************************************} @XE: T ¬ uWDC, ZeroBr, c1, at[1,10,ESC2n]; T ¬ T - 1, rhT ¬ xtX, BRANCH[XEa, $], c2; uWDC ¬ T, GOTO[DIb], c3; XEa: uWDC ¬ T, ZeroBr, L2¬L2.XSpc, c3; XEb: PC ¬ PC - 1, BRANCH[XEc, XEd], c1; XEc: TT ¬ UvPCpage, L1¬3, CALL[StashPC3], c2; XEd: TT ¬ UvPCpage, L1¬3, SetIE, 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: T and uDestHi 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 enters at one of: XferFrame, XferProc1, XferIndirect, XferProc3 ****************************************************************************} XFER: Map ¬ Q ¬ [rhMDS, T], uDestLo ¬ T, DISP4[XferFrame,0C], c1, GLr[L2.EFCLink]; { ********* Frame link ********* } XferFrame: rhTT ¬ GFTHi, [] ¬ Q, ZeroBr, c2, at[0C,10,XferFrame]; L ¬ MD, rhL ¬ MD, XWtOKDisp, BRANCH[$,ControlTrap], c3; XFStartRead: MAR ¬ [rhL, Q-LF.globalLink], BRANCH[XFMUD,XFMOK,0D], c1; MAR ¬ [rhL, Q-LF.globalLink], BRANCH[XFMUD,XFMOK,0D], c1, WMFRet[L0.Xfer]; XFMUD: Rx ¬ L, CANCELBR[WMapFix,0], c2; XFMOK: T ¬ UvL, CANCELBR[$,0], c2; T ¬ MD {global link}, uFrame ¬ T, L2 ¬ L2.XFrame, c3; MAR ¬ L ¬ [rhL, Q-LF.pc], {fix L in LGC subroutine} c1; TOS ¬ Q, CANCELBR[$,0], c2; TT ¬ MD {pc}, GOTO[LGC], c3; UvL ¬ TOS, c1, XCoder[L2.XFrame]; uPCCross ¬ 0, c2; Q ¬ T - 1, Xbus ¬ rhT, XDisp, c3; Map ¬ [rhMDS, T], L2 ¬ 8, push, DISP4[XFTrap,8], c1; XFTrap: Rx ¬ Rx + 1, c2, at[8,10,XFTrap]; uWDC ¬ Rx, ClrIE, GOTO[XPEnd], c3; XFCall: GOTO[XferDone], c2, at[0A,10,XFTrap]; XFRet: TT ¬ Ufsi and Q, L2¬0, GOTO[Freex,0], c2, at[0B,10,XFTrap]; XFCalI: T ¬ uSourceLo, push, GOTO[XPSD], c2, at[0E,10,XFTrap]; XFRetI: T ¬ uSourceLo, push, GOTO[XPSD], c2, at[0F,10,XFTrap]; { ********* Indirect link ********* } XferIndirect: T ¬ rhT, c2, at[0E,10,XferFrame]; T ¬ T or 4, L2¬L2.XIndirect, {set indirect xfer bit} 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; { ********* Old Procedure descriptor ********* } XferProc1: rhTT ¬ GFTHi, Q ¬ T-1, ZeroBr, c2, at[0D,10,XferFrame]; rhRx ¬ Rx ¬ MD, XRefBr, BRANCH[$,UnboundTrap], c3; MAR ¬ [rhRx, Q-GF.word], L0¬L0.XGfi, BRANCH[XOPa,XOPb], c1, RMFRet[L0.XGfi]; XOPa: CANCELBR[RMapFix,0], c2; XOPb: T ¬ ~3, L2¬L2.XProc, CANCELBR[$,0], c2; T ¬ MD and T, GOTO[LGC], c3; { ********* New Procedure descriptor ********* } XferProc3: T ¬ T and ~3, ZeroBr, L2¬L2.XProc, c2, at[0F,10,XferFrame]; rhTT ¬ GFTHi, BRANCH[XNPa,XNPb], c3; XNPa: Map ¬ Q ¬ [rhTT, T], GOTO[LGCx], c1; XNPb: T ¬ sUnbound, GOTO[UBTa], c1; XAlloc: Map ¬ Q ¬ [rhMDS, T or ib], CALL[AllocSub], c1, XCoder[L2.XProc]; uPCCross ¬ 0, c3, Allocr[L2.XProc]; 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 ¬ 8, DISP4[XPTrap,8], c1; XPTrap: MDR ¬ uSourceLo, CANCELBR[XTrap,0], c2, at[8,10,XPTrap]; XPCall: MDR ¬ uSourceLo, CANCELBR[XferDone,0], c2, at[0A,10,XPTrap]; XPRet: MDR ¬ uSourceLo, CANCELBR[XPFree,0], c2, at[0B,10,XPTrap]; XPCalI: MDR ¬ T ¬ uSourceLo, push, CANCELBR[XPSD,0], c2, at[0E,10,XPTrap]; XPRetI: MDR ¬ T ¬ uSourceLo, push, CANCELBR[XPSD,0], c2, at[0F,10,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, XWtOKDisp, c3; {store new head, fetch old head} MAR ¬ [rhRx,TT+0], L0¬L0.Free, BRANCH[FreeMUD,FreeMOK,0D], 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 ¬ TT xor ~TT, 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; {**************************************************************************** LoadGC subroutine: Entry: rhTT has GFTHi T has gfi Exit: G, rhG, UvG, UvGhigh, UvC, UvChigh, PC, rhPC, UvPCpage set up traps if page fault or odd codebase returnee executed on c1 ****************************************************************************} LGC: Map ¬ Q ¬ [rhTT, T], c1; LGCx: [] ¬ Q xor uGFI, ZeroBr, L0¬L0.GFTRead, c2; rhRx ¬ Rx ¬ MD, XRefBr, IBPtr ¬ 1, BRANCH[$,SameG], c3; MAR ¬ [rhRx, Q+GFTE.codeLo], BRANCH[LGCa,LGCb], c1, RLMFRet[L0.GFTRead]; LGCa: CANCELBR[RLMapFix,0], c2; LGCb: uTT ¬ PC ¬ TT, CANCELBR[$,0], c2; T ¬ MD{low codebase}, XLDisp, uGFI ¬ T, c3; MAR ¬ [rhRx, Q+GFTE.globalHi], BRANCH[$,CodeTrap,2], c1; PC ¬ RShift1 PC, SE ¬ 0, ZeroBr, CANCELBR[$,0], c2; rhTT ¬ TT ¬ MD{high global frame}, BRANCH[XCa,XCb], c3; XCb: T ¬ sUnbound, GOTO[UBTa], c1; XCa: MAR ¬ Rx ¬ [rhRx, Q+GFTE.globalLo], XC2npcDisp, c1; UvGhigh ¬ TT, BRANCH[xcOdd,xcEven,0E], c2; xcOdd: Q ¬ MD{low global frame}, GOTO[XMapG], c3; xcEven: Q ¬ MD{low global frame}, Cin¬pc16, GOTO[XMapG], c3; XMapG: Map ¬ UvG ¬ [rhTT, Q], c1; PC ¬ PC + T, c2; G ¬ rhG ¬ MD, XRefBr, UvC ¬ T, c3; LGCe: MAR ¬ [rhRx, Rx+GFTE.codeHi], BRANCH[LGCc,LGCd], c1; LGCc: T ¬ qPageFault, CANCELBR[GMapFix,0], c2; LGCd: T ¬ 0FF + 1, CANCELBR[$,0], c2; rhTT ¬ TT ¬ MD{high codebase}, c3; MAR ¬ G ¬ [rhG, Q+0], c1; SGRet: UvChigh ¬ TT, L ¬ L + 1 {for frame links}, c2; XCode: TT ¬ PC and ~0FF, L0¬L0.XCode, c3; Map ¬ UvPCpage ¬ [rhTT, TT], c1; Q ¬ PC, Xbus ¬ ib, c2; PC ¬ rhPC ¬ MD, XRefBr, c3; MAR ¬ Q ¬ [rhPC, Q+0], Xbus ¬ uTT, XLDisp, BRANCH[XCd,XCe], c1, RMFRet[L0.XCode]; XCd: Rx ¬ PC, CANCELBR[RCMapFix,3], c2; XCe: Rx ¬ uWDC, L2Disp, BRANCH[xcE,xcO,0E], c2; xcE: IB ¬ MD, PC ¬ Q, Cin¬pc16, RET[XCodeRtn], c3; xcO: IB ¬ MD, PC ¬ Q, IBPtr¬1, RET[XCodeRtn], c3; SameG: rhTT ¬ UvChigh, XC2npcDisp, CANCELBR[$,1], c1, RLMFRet[L0.SameG]; uTT ¬ TT, BRANCH[sgOdd,sgEven,0E], c2; sgOdd: PC ¬ UvC, GOTO[sg], c3; sgEven: PC ¬ UvC, Cin¬pc16, GOTO[sg], c3; sg: TT ¬ RShift1 TT, ZeroBr, IBPtr ¬ 1, c1; PC ¬ PC + TT, BRANCH[sgX,sgY], c2; sgY: GOTO[UnboundTrap], c3; sgX: T ¬ 0FF + 1, c3; TT ¬ UvChigh, GOTO[SGRet], c1; GMapFix: Xbus ¬ G LRot0, XwdDisp, L3¬L3.rhTT.Q, c3; Map ¬ [rhTT, Q], DISP2[GMapa], c1; GMapa: MDR ¬ G or map.referenced, GOTO[GMapb], c2, at[0,4]; MDR ¬ G or map.referenced, GOTO[GMapb], c2, at[1,4,GMapa]; MDR ¬ G or map.referenced, GOTO[GMapb], c2, at[2,4,GMapa]; uGFI ¬ 0, L1Disp, DISP4[RTrap], c2, at[3,4,GMapa]; GMapb: Xbus ¬ 1, XDisp, GOTO[LGCe], 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: T ¬ sCodeTrap, CANCELBR[$,0], c2; TT ¬ uGFI, c3; G ¬ 1, GOTO[THz], c1; ControlTrap: T ¬ sControlTrap, CANCELBR[$,0F], c1; TT ¬ uSourceLo, c2; G ¬ 1, GOTO[TH], c3; UnboundTrap: T ¬ sUnbound, CANCELBR[$,1], c1; UBTa: TT ¬ uDestLo, c2; Rx ¬ uDestHi, c3; G ¬ 2, c1; uTrapParm1 ¬ Rx, c2; Noop, c3; TH: Noop, c1; THz: 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, XDisp, CANCELBR[$,0], c2; PC ¬ MD, L3Disp, BRANCH[THd, THe, 7], 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, c2; Rx ¬ XferType.trap, c3; uGFI ¬ 0{disable SameG}, 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: uGFI ¬ 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; {**************************************************************************** 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 large, 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 UvGhigh 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 ¬ UvGhigh, MesaIntBr, RET[SpcRtn], c2; St1: MDR ¬ TT, rhTT ¬ UvGhigh, MesaIntBr, RET[SpcRtn], c2; {page carry and uPCCross#0 => UvPCpage must be decremented} 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.word] T has 2*index + 3 rhTT has UvGhigh Link2 has return index Exit: T and uDestHi have destination control link L has caller frame TOS saved in STK TT and Q smashed returnee executed on c1 ****************************************************************************} GetLink: TT ¬ UvG, 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; GLFrame: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; GLCode: {This code takes advantage of two facts: 1) UvC is always even (i.e. the LSB is 0); 2) DRShift1 and DLShift1 are not symmetric, so the shifted bit is inverted. Thus TT acquires the value (UvC+1).} TT ¬ DRShift1 UvC, c2; rhTT ¬ UvChigh, TT ¬ DLShift1 TT, c3; Map ¬ Q ¬ [rhTT, TT-T], GOTO[GLFrame], c1; {**************************************************************************** Alloc subroutine: Entry: calling instruction executed on c1 Map fetch started on AV Exit: rhL set up TOS has uGFI 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, XWtOKDisp, c3; Alloc1: MAR ¬ [rhRx, T+0], BRANCH[AllocMUD1,$,0D], c1, WMFRet[L0.Alloc1]; TOS ¬ uGFI, 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, XWtOKDisp, c3; MAR ¬ [rhL, TT+0], BRANCH[AllocMUD2,$,0D], 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, XWtOKDisp, c3; MAR ¬ [rhRx,Q+0], L2Disp, BRANCH[XWMUD,$,0D], c1, WMFRet[L0.XWrite]; MDR ¬ T, RET[XWRtn], c2; XWMUD: Noop, CANCELBR[WMapFix, 0F], c2;