{ File name CommonSubs.mc Description: Emulator Subroutines Author: DXC Created: March 28, 1980 Last edited: AHL/JPM 5-Jan-87 9:01:08 Change LGMap for MDS relief KXI 14-Jan-86 18:07:08 add coments. KXI 20-Dec-85 14:13:50 add L1.Push2Dec2 into WTrapFix fixups routine for @PushByte and @PushByteToWordBoundary. JPM 11-Sep-84 14:02:12 Altered to reflect new value of L1.Pop DEG 1-Sep-84 19:27:14 Add copyright notice AEF 18-Jul-83 15:42:32 Change WLMapFix for double byte codes JGS, September 23, 1981 4:41 PM New Instruction Set RXG, April 11, 1980 4:52 PM RXJ, January 20, 1981 10:22 AM DXC, October 8, 1980 9:23 AM } { Copyright (C) 1980, 1981, 1983, 1984, 1985, 1986 by Xerox Corporation. All rights reserved.} {***************************************************************************** Read Map Update Subroutines *****************************************************************************} {Timing: 4 cycles} {Enter at cycle 3, returns to cycle1} {returns thru L0 if map fixed ok} {returns thru L1 if wants to trap} {uses L3 to distinguish where virtual address is} RMapFix: Xbus ¬ Rx LRot0, XwdDisp, L3 ¬ L3.rhMDS.Q, c3; Map ¬ [rhMDS, Q], Xbus ¬ 0, XDisp, DISP2[RMapa], c1; RCMapFix: Xbus ¬ Rx LRot0, XwdDisp, L3 ¬ L3.rhTT.TT, c3; Map ¬ [rhTT, TT], Xbus ¬ 0, XDisp, DISP2[RMapa], c1; RMapa: MDR ¬ Rx or map.referenced, L0Disp, DISP4[RMapb], c2, at[0,10]; MDR ¬ Rx or map.referenced, L0Disp, DISP4[RMapb], c2, at[1,10,RMapa]; MDR ¬ Rx or map.referenced, L0Disp, DISP4[RMapb], c2, at[2,10,RMapa]; IBEmptyTrap: T ¬ qPageFault, L1Disp, DISP4[RTrap], c2, at[3,10,RMapa]; RMapb: Xbus ¬ 1{save step in caller}, XDisp, RET[RMFRtn], c3, at[0,10,RMapb]; RTrap: push, RET[RTrapFix], c3, at[0,10,RTrap]; {***************************************************************************** Write Map Update Subroutines *****************************************************************************} {Timing: 4 cycles} {Enter at cycle 3, returns to cycle1} {returns thru L0 if map fixed ok} {returns thru L1 if wants to trap} WMapFix: Xbus ¬ Rx LRot0,XwdDisp, L3 ¬ L3.rhMDS.Q, c3; Map ¬ [rhMDS,Q], DISP2[WMapa], c1; WMapa: MDR ¬ Rx or map.rd, L0Disp, GOTO[WMapb], c2, at[0,4]; T ¬ qWriteProtect, L1Disp, GOTO[WTrap], c2, at[1,4,WMapa]; MDR ¬ Rx or map.rd, L0Disp, GOTO[WMapb], c2, at[2,4,WMapa]; T ¬ qPageFault, L1Disp, GOTO[WTrap], c2, at[3,4,WMapa]; WMapb: Xbus ¬ 2, XDisp, RET[WMFRtn], c3; WTrap: push, RET[WTrapFix], c3; {***************************************************************************** Read Long Map Update Subroutines *****************************************************************************} {Timing: 4 cycles} {Enter at cycle 3, returns to cycle1} {returns thru L0 if map fixed ok} {returns thru L1 if wants to trap} {uses L3 to distinguish where virtual address is} RLMapFix: Xbus ¬ Rx LRot0,XwdDisp, L3 ¬ L3.rhTT.Q, c3; RLMapx: Map ¬ [rhTT,Q], Xbus ¬ 1, XDisp, DISP2[RMapa], c1; RLMapb: Xbus ¬ 1, XDisp, RET[RLMFRtn], c3, at[1,10,RMapb]; RLTrap: push, RET[RLTrapFix], c3, at[1,10,RTrap]; {***************************************************************************** Write Long Map Update Subroutines *****************************************************************************} {Timing: 4 cycles} {Enter at cycle 3, returns to cycle1} {returns thru L0 if map fixed ok} {returns thru L1 if wants to trap} WLMapFix: Xbus ¬ Rx LRot0, XwdDisp, L3 ¬ L3.rhTT.Q, c3; Map ¬ [rhTT,Q], L0Disp, DISP2[WLMapa], c1; WLMapa: MDR ¬ Rx or map.rd, L0Disp, CANCELBR[WLMapb,0F], LOOPHOLE[wok], c2, at[0,4]; T ¬ qWriteProtect, L1Disp, BRANCH[WLTrapD,WLTrap,0E], c2, at[1,4,WLMapa]; MDR ¬ Rx or map.rd, L0Disp, CANCELBR[WLMapb,0F], LOOPHOLE[wok], c2, at[2,4,WLMapa]; T ¬ qPageFault, L1Disp, BRANCH[WLTrapD,WLTrap,0E], c2, at[3,4,WLMapa]; WLMapb: Xbus ¬ 2, XDisp, RET[WLMFRtn], c3; WLTrapD:Noop, RET[WTrapFix], c3; WLTrap: push, RET[WTrapFix], c3; {***************************************************************************** Local and Global Remap Subroutines *****************************************************************************} {Timing: 8 cycles (2 2/3 clicks), + 2 clicks if flags need fixing } {Enter at cycle 2, returns to cycle 1} {returns thru L2 if all ok, thru LGRemapCaller} {returns thru L1 {from RLMapFix} if wants to trap, thru FixForTrap} {assumes caller executed "TT ¬ UvL/UvG, rhTT ¬ UvMDS/UvGhigh"} LGMap: Q ¬ Q - TT, c2; Q ¬ Q and 0FF, c3; Map ¬ Q ¬ [rhTT, TT + Q], c1; Noop, c2; Rx ¬ rhRx ¬ MD, XRefBr, c3; LGMa: MAR ¬ [rhRx, Q + 0], BRANCH[LGMUD,$], c1; L2Disp, c2; rhTT ¬ TT ¬ MD, RET[LGMRtn], c3; LGMUD: L1¬L1.PopDec2, c2; Xbus ¬ Rx LRot0, XwdDisp, L3 ¬ L3.rhTT.Q, c3; Map ¬ [rhTT, Q], Xbus ¬ 2, XDisp, DISP2[RMapa], c1; Xbus ¬ 1, XDisp, CANCELBR[LGMa,0F], c3, at[2,10,RMapb]; push, RET[RTrapFix], c3, at[2,10,RTrap]; {***************************************************************************** RTrapFix *****************************************************************************} MacroDef[RTF, at[#1,10,RTrapFix]]; NoFixes: Noop, GOTO[NoMoreFix], c1, RTF[L1.None]; PC ¬ PC - PC16, GOTO[NoMoreFix], c1, RTF[L1.Dec]; PC ¬ PC - 1, GOTO[NoMoreFix], c1, RTF[L1.Dec2]; PC ¬ PC - 1, pop, GOTO[NoMoreFix], c1, RTF[L1.PopDec2]; PC ¬ PC - PC16, pop, GOTO[NoMoreFix], c1, RTF[L1.PopDec]; PC ¬ PC - PC16, pop, GOTO[PopFix], c1, RTF[L1.Pop2Dec]; PC ¬ PC - 1, pop, GOTO[PopFix], c1, RTF[L1.Pop2Dec2]; {***************************************************************************** RLTrapFix *****************************************************************************} MacroDef[RLTF, at[#1,10,RLTrapFix]]; Noop, GOTO[NoMoreFix], c1, RLTF[L1.None]; PC ¬ PC - PC16, GOTO[NoMoreFix], c1, RLTF[L1.Dec]; PC ¬ PC - 1, GOTO[NoMoreFix], c1, RLTF[L1.Dec2]; PC ¬ PC - 1, pop, GOTO[NoMoreFix], c1, RLTF[L1.PopDec2]; PC ¬ PC - PC16, pop, GOTO[NoMoreFix], c1, RLTF[L1.PopDec]; PC ¬ PC - PC16, pop, GOTO[PopFix], c1, RLTF[L1.Pop2Dec]; PC ¬ PC - 1, pop, GOTO[PopFix], c1, RLTF[L1.Pop2Dec2]; push, GOTO[PushFix], c1, RLTF[L1.Push2]; PC ¬ PC - PC16, push, GOTO[NoMoreFix], c1, RLTF[L1.PushDec]; PC ¬ PC - 1, push, GOTO[NoMoreFix], c1, RLTF[L1.PushDec2]; push, GOTO[NoMoreFix], c1, RLTF[L1.Push]; PC ¬ PC - 1 - PC16, GOTO[NoMoreFix], c1, RLTF[L1.Dec3]; {***************************************************************************** WTrapFix fixups *****************************************************************************} MacroDef[WTF, at[#1,10,WTrapFix]]; Noop, GOTO[NoMoreFix], c1, WTF[L1.None]; PC ¬ PC - PC16, GOTO[NoMoreFix], c1, WTF[L1.Dec]; PC ¬ PC - 1, GOTO[NoMoreFix], c1, WTF[L1.Dec2]; PC ¬ PC - 1, pop, GOTO[NoMoreFix], c1, WTF[L1.PopDec2]; PC ¬ PC - PC16, pop, GOTO[NoMoreFix], c1, WTF[L1.PopDec]; PC ¬ PC - PC16, pop, GOTO[PopFix], c1, WTF[L1.Pop2Dec]; PC ¬ PC + PC16, push, GOTO[NoMoreFix], c1, WTF[L1.PushInc]; push, GOTO[PushFix], c1, WTF[L1.Push2]; PC ¬ PC - PC16, push, GOTO[NoMoreFix], c1, WTF[L1.PushDec]; PC ¬ PC - 1, push, GOTO[NoMoreFix], c1, WTF[L1.PushDec2]; push, GOTO[NoMoreFix], c1, WTF[L1.Push]; PC ¬ PC - 1 - PC16, push, GOTO[NoMoreFix], c1, WTF[L1.PushDec3]; PopOnlyFix: pop, GOTO[NoMoreFix], c1, WTF[L1.Pop]; PC ¬ PC - 1, push, GOTO[PushFix], c1, WTF[L1.Push2Dec2]; {***************************************************************************** Trap Handling *****************************************************************************} NoMoreFix: L3Disp, GOTO[TrapFixDone], c2; PushFix: push, L3Disp, GOTO[TrapFixDone], c2; PopFix: pop, L3Disp, GOTO[TrapFixDone], c2; TrapFixDone: L3Disp, BRANCH[LowQ, LowTT, 2], c3; LowQ: uFaultParm0 ¬ Q, BRANCH[HiMDS, HiTT, 1], c1; LowTT: uFaultParm0 ¬ TT, BRANCH[HiMDS, HiTT, 1], c1; HiMDS: Q ¬ rhMDS, GOTO[Faultc3], c2; HiTT: Q ¬ rhTT, GOTO[Faultc3], c2; {At Faultc3, uFaultParm0 stored, Q has uFaultPram1, T has FaultQueuePointer} Faultc3: uFaultParm1 ¬ Q, c3; Faultc1: Rx ¬ pFault, STK ¬ TOS, pop, GOTO[SaveRegs], c1; {At Trapc1, TT holds the trap parmater, T has the sSDIndex} Trapc2: GOTO[Trapc3], c2; Trapc3: G ¬ 0, GOTO[Trapc1], c3; Trapc1: uTrapParm0 ¬ TT, L2 ¬ L2.TRAPSpc, c1; TT ¬ UvPCpage, L1¬0, GOTO[StashPC0] {in Xfer.mc}, c2; {***************************************************************************** CycleMask *****************************************************************************} {Timing: 1 click} {Used by: SHIFT, RF, WF, BITBLT instructions} {Entry: T = data to be rotated & masked, TT = pre-rotated version of T a DISP4 pending which determines rotation: 0 => no rotation 1 => left rotate 1 : 0F => left rotate 15; rhT = value to be dispatched on to determine mask 0 => 1 1 => 3 : 0F => 0FFFF Exit: TT holds the mask, TOS holds the rotated data, T does not contain the original data, rhT is untouched} CycleMask: [] ¬ rhT, XDisp, GOTO[ShiftOK0], c*, at[0,10,CycleMask]; T ¬ TT, [] ¬ rhT, XDisp, GOTO[ShiftOK0], c*, at[1,10,CycleMask]; T ¬ LRot1 TT, [] ¬ rhT, XDisp, GOTO[ShiftOK0], c*, at[2,10,CycleMask]; T ¬ RRot1 T, [] ¬ rhT, XDisp, GOTO[ShiftOK4], c*, at[3,10,CycleMask]; [] ¬ rhT, XDisp, GOTO[ShiftOK4], c*, at[4,10,CycleMask]; T ¬ LRot1 T, [] ¬ rhT, XDisp, GOTO[ShiftOK4], c*, at[5,10,CycleMask]; T ¬ LRot1 TT, [] ¬ rhT, XDisp, GOTO[ShiftOK4], c*, at[6,10,CycleMask]; T ¬ RRot1 T, [] ¬ rhT, XDisp, GOTO[ShiftOK8], c*, at[7,10,CycleMask]; [] ¬ rhT, XDisp, GOTO[ShiftOK8], c*, at[8,10,CycleMask]; T ¬ LRot1 T, [] ¬ rhT, XDisp, GOTO[ShiftOK8], c*, at[9,10,CycleMask]; T ¬ LRot1 TT, [] ¬ rhT, XDisp, GOTO[ShiftOK8], c*, at[0A,10,CycleMask]; T ¬ RRot1 T, [] ¬ rhT, XDisp, GOTO[ShiftOK12], c*, at[0B,10,CycleMask]; [] ¬ rhT, XDisp, GOTO[ShiftOK12], c*, at[0C,10,CycleMask]; T ¬ LRot1 T, [] ¬ rhT, XDisp, GOTO[ShiftOK12], c*, at[0D,10,CycleMask]; T ¬ LRot1 TT, [] ¬ rhT, XDisp, GOTO[ShiftOK12], c*, at[0E,10,CycleMask]; T ¬ RRot1 T, [] ¬ rhT, XDisp, GOTO[ShiftOK0], c*, at[0F,10,CycleMask]; ShiftOK0: TOS ¬ T, L2Disp, DISP4[MaskTbl], c*; ShiftOK4: TOS ¬ T LRot4, L2Disp, DISP4[MaskTbl], c*; ShiftOK8: TOS ¬ T LRot8, L2Disp, DISP4[MaskTbl], c*; ShiftOK12: TOS ¬ T LRot12, L2Disp, DISP4[MaskTbl], c*; {***************************************************************************** MaskTbl SUBROUTINE first cycle = c* , one cycle long This subroutine generates a right justified mask. of n ones given n (n = 1 gives 1, n = 8 gives 00FF and n = 16 gives FFFF). The subroutine may also be used to generate a left justified mask. REGISTERS Rn number of 1 bits desired in mask (0 means 16) mask where the mask is generated CALLING SEQUENCES For a right justified mask [] ¬ Rn - 1, YDisp, c1; [] ¬ retnum, XDisp, DISP4[MaskTbl], c2; {rtn here} Noop, c1, at[retnum,10,MaskRet]; For a left justified mask [] ¬ 0 - Rn, YDisp, c2; [] ¬ retnum, XDisp, DISP4[MaskTbl], c3; {rtn here} mask ¬ RShift1 ~mask, SE ¬ 1, c2, at[retnum,10,MaskRet]; RETURNS THRU MaskRet *****************************************************************************} MaskTbl: TT ¬ 1, RET[MaskRet], c*, at[0,10,MaskTbl]; TT ¬ 3, RET[MaskRet], c*, at[1,10,MaskTbl]; TT ¬ 7, RET[MaskRet], c*, at[2,10,MaskTbl]; TT ¬ 0F, RET[MaskRet], c*, at[3,10,MaskTbl]; TT ¬ 1F, RET[MaskRet], c*, at[4,10,MaskTbl]; TT ¬ 3F, RET[MaskRet], c*, at[5,10,MaskTbl]; TT ¬ 7F, RET[MaskRet], c*, at[6,10,MaskTbl]; TT ¬ 0FF, RET[MaskRet], c*, at[7,10,MaskTbl]; TT ¬ LShift1 0FF, SE¬1, RET[MaskRet] {TT ¬ 1FF}, c*, at[8,10,MaskTbl]; TT ¬ RShift1 u7FF, RET[MaskRet] {TT ¬ 3FF}, c*, at[9,10,MaskTbl]; TT ¬ u7FF, RET[MaskRet] {TT ¬ 7FF}, c*, at[0A,10,MaskTbl]; TT ¬ RShift1 u1FFF, RET[MaskRet] {TT ¬ FFF}, c*, at[0B,10,MaskTbl]; TT ¬ u1FFF, RET[MaskRet] {TT ¬ 1FFF}, c*, at[0C,10,MaskTbl]; TT ¬ u3FFF, RET[MaskRet] {TT ¬ 3FFF}, c*, at[0D,10,MaskTbl]; TT ¬ RShift1 (~TT xor TT), RET[MaskRet] {TT ¬ 7FFF}, c*, at[0E,10,MaskTbl]; TT ¬ ~TT xor TT, RET[MaskRet] {TT ¬ FFFF}, c*, at[0F,10,MaskTbl];