:IF[AltoMode]; TITLE[MesaLS--Alto.Mode]; :ELSE; TITLE[MesaLS--Pilot.Mode]; :ENDIF; *Common tail and refill for instructions on page 4 ONPAGE[4]; MesaRefill4: gotop[MesaRefill], Pfetch4[PC,IBUF,4], at[2377]; *NOP *In DMesa, we should only get here if IntPending is set by an I/O controller. *AMesa uses NOP for padding. @NOP: T _ (RZero) + 1, goto[NOPint,IntPending], opcode[0]; P4Tail: lu _ NextInst[IBUF]; P4Tailx: NIRET; *NOPint is entered from @NOP above and from BLTstop (in Mesax). MIPend *backs up the PC by IntType (which is always =1 here, but is 0 if MIPend is *entered from IdleLoop in MesaP). Then it clears IntPending and checks *(NWW#0 & xfWDC=0). If this quantity is true, MIPend starts the interrupt; *otherwise it returns. The return will cause a BLT to be restarted. The *return sends control to the byte code that was elided when the NOP was forced. NOPint: IntType _ T, loadpage[prPage]; * IntType _ (PC backup if stopping) T _ (GetRSpec[103]) xor (377c), callp[MIPend]; * T _ Stkp xor 377 lu _ NextInst[IBUF], call[P4Tailx]; * Monitor instructions are in MesaP.mc P4Ret: RETURN; *Load Local n, n=0-7 LL0: T _ LocalCache0, goto[PushT], opcode[10] ; LL1: T _ LocalCache1, goto[PushT], opcode[11] ; LL2: T _ LocalCache2, goto[PushT], opcode[12] ; LL3: T _ LocalCache3, goto[PushT], opcode[13] ; *LL0: Pfetch1[LOCAL,Stack,4], goto[P4Tail], opcode[10] ; *LL1: Pfetch1[LOCAL,Stack,5], goto[P4Tail], opcode[11] ; *LL2: Pfetch1[LOCAL,Stack,6], goto[P4Tail], opcode[12] ; *LL3: Pfetch1[LOCAL,Stack,7], goto[P4Tail], opcode[13] ; LL4: Pfetch1[LOCAL,Stack,10], goto[P4Tail], opcode[14] ; LL5: Pfetch1[LOCAL,Stack,11], goto[P4Tail], opcode[15] ; LL6: Pfetch1[LOCAL,Stack,12], goto[P4Tail], opcode[16] ; LL7: Pfetch1[LOCAL,Stack,13], goto[P4Tail], opcode[17] ; *Load Local Byte LLB: T _ NextData[IBUF], opcode[20]; Pfetch1[LOCAL,Stack], goto[P4Tail]; *Load Local Double Byte LLDB: T _ NextData[IBUF], opcode[21]; LLDB1: Pfetch2[LOCAL,Stack], call[FQT]; *If FQT returns, quadOVF has occurred. Fetch the first word into RTEMP CALL[IncT1], Pfetch1[LOCAL,RTEMP]; Pfetch1[LOCAL,Stack], goto[DoubleReadTail]; *By this time, we know that the first fetch has not faulted. If the second one faults, *the fourth instruction after the Pfetch will be aborted. If we wait to update the first *word, we don't have to tell the fault handler anything about the state of the memory. DoubleReadTail: nop; Stack&-1; *Adjust the stackpointer to point to the first word of the pair DoubleReadTailx: T _ RTEMP; Stack _ T; *deposit the first word lu _ NextInst[IBUF]; Stack&+1, NIRET; *final stkp adjust IncT1: T _ (Zero) + (T) + 1, return; *increment T by 1 FQT: goto[.+2, QuadOVF]; lu _ NextInst[IBUF], call[P4Tailx]; Stack&-1, return; *adjust the stackpointer modified by the failed fetch to point *one below the SECOND word to be fetched. *Store Local n, n=0-7 SL0: T _ stack&-1, Opcode[22]; SL0x: LocalCache0 _ T, goto[StoreLocalCache]; SL1: T _ stack&-1, Opcode[23]; SL1x: LocalCache1 _ T, goto[StoreLocalCache]; SL2: T _ stack&-1, Opcode[24]; SL2x: LocalCache2 _ T, goto[StoreLocalCache]; SL3: T _ stack&-1, Opcode[25]; SL3x: LocalCache3 _ T, goto[StoreLocalCache]; *SL0: PStore1[LOCAL,Stack,4], goto[P4Tail], Opcode[22]; *SL1: PStore1[LOCAL,Stack,5], goto[P4Tail], Opcode[23]; *SL2: PStore1[LOCAL,Stack,6], goto[P4Tail], Opcode[24]; *SL3: PStore1[LOCAL,Stack,7], goto[P4Tail], Opcode[25]; SL4: PStore1[LOCAL,Stack,10], goto[P4Tail], Opcode[26]; SL5: PStore1[LOCAL,Stack,11], goto[P4Tail], Opcode[27]; SL6: PStore1[LOCAL,Stack,12], goto[P4Tail], Opcode[30]; SL7: PStore1[LOCAL,Stack,13], goto[P4Tail], Opcode[31]; StoreLocalCache: lu _ NextInst[IBUF]; PStore4[LOCAL,LocalCache0,4], NIRET ; *Store Local Byte SLB: T _ NextData[IBUF], opcode[32]; PStore1[LOCAL,Stack], goto[P4Tail]; *Put Local n, n=0-3. Equivalent to SLn,Push % PL0: PStore1[LOCAL,Stack,4], goto[QPutTail], Opcode[33]; PL1: PStore1[LOCAL,Stack,5], goto[QPutTail], Opcode[34]; PL2: PStore1[LOCAL,Stack,6], goto[QPutTail], Opcode[35]; PL3: PStore1[LOCAL,Stack,7], goto[QPutTail], Opcode[36]; QPutTail: Stack&+1, goto[P4Tail]; % PL0: T _ stack&-1,opcode[33]; LocalCache0 _ T, goto[PutTail]; PL1: T _ stack&-1,opcode[34]; LocalCache1 _ T, goto[PutTail]; PL2: T _ stack&-1,opcode[35]; LocalCache2 _ T, goto[PutTail]; PL3: T _ stack&-1,opcode[36]; LocalCache3 _ T, goto[PutTail]; PutTail: Stack&+1; PStore4[LOCAL,LocalCache0,4], goto[P4Tail]; *Load Global n, n=0-7 LG0: Pfetch1[GLOBAL,Stack,3], goto[P4Tail], opcode[37] ; LG1: Pfetch1[GLOBAL,Stack,4], goto[P4Tail], opcode[40] ; LG2: Pfetch1[GLOBAL,Stack,5], goto[P4Tail], opcode[41] ; LG3: Pfetch1[GLOBAL,Stack,6], goto[P4Tail], opcode[42] ; LG4: Pfetch1[GLOBAL,Stack,7], goto[P4Tail], opcode[43] ; LG5: Pfetch1[GLOBAL,Stack,10], goto[P4Tail], opcode[44] ; LG6: Pfetch1[GLOBAL,Stack,11], goto[P4Tail], opcode[45] ; LG7: Pfetch1[GLOBAL,Stack,12], goto[P4Tail], opcode[46] ; *Load Global Byte LGB: T _ NextData[IBUF], opcode[47]; Pfetch1[GLOBAL,Stack], goto[P4Tail]; *Load Global Double Byte LGDB: T _ NextData[IBUF], opcode[50] ; LGDB1: Pfetch2[GLOBAL,Stack], call[FQT]; *If FQT returns, quadOVF occurred. See LLDB. Call[IncT1], Pfetch1[GLOBAL,RTEMP]; Pfetch1[GLOBAL,Stack], goto[DoubleReadTail]; *Store Global n, n=0-7 SG0: PStore1[GLOBAL,Stack,3], goto[P4Tail], Opcode[51]; SG1: PStore1[GLOBAL,Stack,4], goto[P4Tail], Opcode[52]; SG2: PStore1[GLOBAL,Stack,5], goto[P4Tail], Opcode[53]; SG3: PStore1[GLOBAL,Stack,6], goto[P4Tail], Opcode[54]; *Store Global Byte SGB: T _ NextData[IBUF], opcode[55]; PStore1[GLOBAL,Stack], goto[P4Tail]; *Load Immediate n, n=0-6 LI0: T _ 0c, goto[PushT], Opcode[56]; LI1: T _ 1c, goto[PushT], Opcode[57]; LI2: T _ 2c, goto[PushT], Opcode[60]; LI3: T _ 3c, goto[PushT], Opcode[61]; LI4: T _ 4c, goto[PushT], Opcode[62]; LI5: T _ 5c, goto[PushT], Opcode[63]; LI6: T _ 6c, goto[PushT], Opcode[64]; *Load Immediate Negative 1. LIN1: T _ (Zero)-1, goto[PushT], Opcode[65]; *Load Immediate Negative Infinity LINI: T _ 100000c, goto[PushT], Opcode[66]; *Load Immediate Byte LIB: T _ NextData[IBUF], Opcode[67]; PushT: lu _ NextInst[IBUF]; Stack&+1 _ T, NIRET; *Load Immediate Word :IF[AltoMode]; **************************************** LIW: lu _ GetRSpec[127], skip[R even], Opcode[70]; lu _ NextData[IBuf]; T _ NextData[IBUF]; lu _ CycleControl _ NextData[IBUF]; :ELSE; ************************************************ LIW: lu _ CycleControl _ NextData[IBUF], Opcode[70]; T _ NextData[IBUF]; :ENDIF; *********************************************** T _ (lhmask[GetRSpec[127]]) OR T, goto[PushT]; *Load Immediate Negative Byte LINB: T _ 177400c, opcode[71]; T _ NextData[IBuf] OR T, call[PushT]; *Local Address Byte - since MDS is 64K aligned, the low half of the base register is L LADRB: T _ LOCAL, Opcode[72]; LADRBx: T _ (NextData[IBUF]) + (T), call[PushT]; *Global Address Byte GADRB: T _ GLOBAL, goto[LADRBx], Opcode[73]; *unused opcodes on page 4 T _ sUnimplemented, goto[doTrapP4], opcode[74]; T _ sUnimplemented, goto[doTrapP4], opcode[75]; T _ sUnimplemented, goto[doTrapP4], opcode[76]; T _ sUnimplemented, goto[doTrapP4], opcode[77]; doTrapP4: LoadPage[opPage3]; gotop[kfcr]; *Common tail and refill for instructions on page 5 OnPage[5]; MesaRefill5: gotop[MesaRefill], Pfetch4[PC,IBUF,4], at[2777]; P5Tail: lu _ NextInst[IBUF]; P5Tailx: NIRET; FetchMDSToStack: Pfetch1[MDS,Stack],RETURN; FetchMDSToRTEMPx: RTEMP1 _ T; *save pointer FetchMDSToRTEMP: Pfetch1[MDS,RTEMP]; P5Ret: RETURN; *allow time for T to be written FetchCODEToStack: Pfetch1[CODE,Stack], return; DecS1IncT1: Stack&-1, goto[IncT1p5]; FetchMNBRLPToRTEMP: T _ MNBR; FetchLPToRTEMP: Pfetch1[LP,RTEMP], goto[P5Ret]; * allow time to write T FetchMNBRLPToStack: T _ MNBR; FetchLPToStack: Pfetch1[LP,Stack], goto[P5Ret]; * allow time to write T TtoRTEMP: RTEMP _ T, return; AddTtoStack: T _ (Stack&-1) + (T), return; *Read n, n=0-4 R0: T _ (Stack&-1) + (0c), goto[ReadTail], Opcode[100]; R1: T _ (Stack&-1) + (1c), goto[ReadTail], Opcode[101]; R2: T _ (Stack&-1) + (2c), goto[ReadTail], Opcode[102]; R3: T _ (Stack&-1) + (3c), goto[ReadTail], Opcode[103]; R4: T _ (Stack&-1) + (4c), goto[ReadTail], Opcode[104]; *Read Byte @RB: T _ CNextData[IBUF], call[AddTtoStack], Opcode[105]; ReadTail: Pfetch1[MDS,Stack],goto[P5Tail]; *Write n, n=0-2 W0: T _ (Stack&-1) + (0c), goto[WriteTail], Opcode[106]; W1: T _ (Stack&-1) + (1c), goto[WriteTail], Opcode[107]; W2: T _ (Stack&-1) + (2c), goto[WriteTail], Opcode[110]; *Write Byte WB: T _ CNextData[IBUF], call[AddTtoStack], Opcode[111]; WriteTail: PStore1[MDS,Stack], goto[SQT]; *PStore1's cant cause quadOVF, so this checks the local cache *Read Field :IF[AltoMode]; **************************************** AlignField: usectask, gotop[AF6]; onpage[6]; AF6: T _ apc&apctask; RTEMP _ T; lu _ GetRSpec[127], skip[R even]; lu _ NextData[IBuf]; lu _ CycleControl _ NextData[IBUF]; *get field descriptor T _ NextData[IBUF]; *get offset apc&apctask _ RTEMP; return; onpage[5] @RF: loadpage[6], call[AlignField], Opcode[112]; :ELSE; ************************************************ @RF: T _ NextData[IBUF], Opcode[112]; *get offset lu _ CycleControl _ NextData[IBUF]; *get field descriptor :ENDIF; *********************************************** RFy: T _ (Stack&-1) + (T), call[FetchMDSToStack]; *add pointer, fetch lu _ NextInst[IBUF]; RFx: Stack _ RF[Stack], NIRET; *do the work on the stack *Write Field :IF[AltoMode]; **************************************** WF: loadpage[6], call[AlignField], Opcode[113]; :ELSE; ************************************************ WF: T _ NextData[IBUF], Opcode[113]; *get offset lu _ CycleControl _ NextData[IBUF]; *get field descriptor :ENDIF; *********************************************** Wfz: T _ (Stack&-1) + (T), call[FetchMDSToRTEMPx]; *add pointer, fetch T _ WFA[Stack&-1]; *field to be inserted WFy: RTEMP _ (WFB[RTEMP]) or (T); *do insert WFx: T _ RTEMP1, goto[WS0x]; *Read Double Byte RDB: T _ NextData[IBUF], Opcode[114]; T _ (Stack&-1) + (T), LoadPage[4], goto[DoubleRead]; *Read Double 0 RD0: T _ Stack&-1, LoadPage[4], Opcode[115]; DoubleRead: Pfetch2[MDS,Stack], callp[FQT]; *If FQT returns, quadOVF has occurred. See LLDB. Call[IncT1p5], Pfetch1[MDS,RTEMP]; Pfetch1[MDS,Stack]; DoubleReadx: LoadPage[4]; Stack&-1, gotop[DoubleReadTailx]; IncS2T1: Stack&+2; *Increment stkp by 2, and... IncT1p5: T _ (Zero) + (T) + 1, RETURN; *increment T by 1 *Write Double Byte WDB: T _ CNextData[IBUF], call[AddTtoStack], opcode[116]; DoubleWrite: PStore2[MDS,Stack], call[SQT]; *If SQT returns, do two single stores PStore1[MDS,Stack], call[IncS2T1]; PStore1[MDS,Stack], goto[WSDBx]; *Write Double 0 WD0: T _ Stack&-1, goto[DoubleWrite], opcode[117]; *Store quadword test SQT: RTemp1 _ T, goto[.+3, quadOVF]; *Bypass kludge LoadPage[4]; CLCR0: T _ (rsh[LOCAL,2]) + 1, , gotop[CLCR1]; *Check for local cache refill required Stack&+1, return; *set stkp to point to the first word to be stored *Read String RSTR: T _ CNextData[IBUF], call[RWSTRx], opcode[120]; *get alpha lu _ RTEMP1, dblgoto[RSTRLeft, RSTRRight, Reven], LoadPage[4]; RSTRLeft: T _ rsh[RTEMP,10], gotop[PushT]; RSTRRight: T _ rhmask[RTEMP], gotop[PushT]; *Write String WSTR: T _ CNextData[IBUF], call[RWSTRx], opcode[121]; RTEMP1 _ T, dblgoto[WSTRLeft, WSTRRight, Reven]; *test low bit of RTEMP1, save pointer WSTRLeft: T _ lsh[Stack&-1, 10]; RTEMP _ (rhmask[RTEMP]) or (T), goto[WFx]; WSTRRight: T _ rhmask[Stack&-1]; RTEMP _ (lhmask[RTEMP]) or (T), goto[WFx]; RWSTRx: T _ (Stack&-1) + (T); *string index RTEMP1 _ T; T _ (Stack&-1); *pointer T _ (rsh[RTEMP1,1]) + (T), goto[FetchMDSToRTEMP]; *Read Indexed by Local Pair RXLP: T _ NextData[IBUF], opcode[122]; RTEMP1 _ T, call[LPPointer]; T _ (Stack&-1) + (T), goto[RILPx]; *Write Indexed by Local Pair WXLP: T _ NextData[IBUF], opcode[123]; RTEMP1 _ T, call[LPPointer]; T _ (Stack&-1) + (T), goto[WILPx]; *Read Indirect Local Pair RILP: T _ NextData[IBUF], opcode[124]; RTEMP1 _ T, call[LPPointer]; RILPx: T _ (RTEMP) + (T), goto[ReadTail]; *Read Indirect Global Pair RIGP: T _ NextData[IBUF], opcode[125]; RTEMP1 _ T, call[GPPointer]; RIGPx: T _ (RTEMP) + (T), goto[ReadTail]; *Write Indirect Local Pair WILP: T _ NextData[IBUF], opcode[126]; RTEMP1 _ T, call[LPPointer]; WILPx: T _ (RTEMP) + (T), goto[WriteTail]; *Read Indirect Local 0 RIL0: T _ LocalCache0, goto[ReadTail], opcode[127]; *RIL0: PFetch1[LOCAL,RTEMP,4], opcode[127]; T _ RTEMP, goto[ReadTail]; LPPointer: T _ 4c; *offset of local 0 T _ (ldf[RTEMP1, 10, 4]) + (T); Pfetch1[LOCAL,RTEMP]; LPPointerx: T _ ldf[RTEMP1, 14, 4], return; GPPointer: T _ 3c; *offset of global 0 T _ (ldf[RTEMP1, 10, 4]) + (T); Pfetch1[GLOBAL,RTEMP], goto[LPPointerx]; *Write Swapped 0 WS0: T _ (Stack&-1), call[WSPointer], opcode[130]; *T _ data WS0x: RTEMP1 _ T, LoadPage[4]; PStore1[MDS, RTEMP], gotop[CheckLocalCacheRefill]; OnPage[4]; CheckLocalCacheRefill: T _ (rsh[LOCAL,2]) + 1; CLCR1: lu _ (rsh[RTEMP1,2]) xor (T); skip[ALU#0]; PFetch4[LOCAL,LocalCache0,4], goto[P4Tail]; lu _ NextInst[IBUF], call[P4Tailx]; *Write Swapped Byte WSB: T _ Stack&-1, call[WSPointer], opcode[131]; WSBx: T _ (NextData[IBUF]) + (T), call[WS0x]; WSPointer: RTEMP _ T; T _ Stack&-1, return; *T _ pointer *Write Swapped Field :IF[AltoMode]; **************************************** WSF: Stack&-1, loadpage[6], call[AlignField], Opcode[132]; :ELSE; ************************************************ WSF: Stack&-1, opcode[132]; T _ NextData[IBUF]; lu _ CycleControl _ NextData[IBUF]; :ENDIF; *********************************************** T _ (Stack&+1) + (T), call[FetchMDSToRTEMPx]; *T _ pointer T _ WFA[Stack&-2], goto[WFy]; *Write Swapped Double Byte WSDB: T _ NextData[IBUF], opcode[133]; Stack&-2; T _ (Stack&+2) + (T); *T _ pointer + alpha Pstore2[MDS,Stack]; RTemp1 _ T, goto[.+2, quadOVF]; WSDBx: stack&-1, LoadPage[4], goto[CLCR0]; *back up stkp over pointer *Do two single stores Stack&+1; Pstore1[MDS, stack], call[IncS2T1]; Pstore1[MDS, stack]; Stack&-2, LoadPage[4], goto[CLCR0]; *back up stkp over lsb(data) and pointer *Read Field Code :IF[AltoMode]; **************************************** RFC: loadpage[6], call[AlignField], Opcode[134]; :ELSE; ************************************************ RFC: T _ NextData[IBUF], Opcode[134]; *get offset lu _ CycleControl _ NextData[IBUF]; *get field descriptor :ENDIF; *********************************************** T _ (Stack&-1) + (T), call[FetchCODEToStack]; lu _ NextInst[IBUF], call[RFx]; *Read Field Stack RFS: T _ (Stack&-1), call[StackFD], opcode[135]; :IF[AltoMode]; **************************************** lu _ GetRSpec[127], skip[Reven]; lu _ NextData[IBuf]; :ENDIF; *********************************************** CycleControl _ RTEMP, goto[RFy]; *Write Field Stack WFS: T _ Stack&-1, call[StackFD], opcode[136]; :IF[AltoMode]; **************************************** lu _ GetRSpec[127], skip[Reven]; lu _ NextData[IBuf]; :ENDIF; *********************************************** CycleControl _ RTEMP, goto[WFz]; *Displacement is in left byte, FD is in right byte StackFD: RTEMP _ T; T _ rsh[RTEMP, 10], return; *get displacement *Read Byte Long RBL: T _ (Stack&-1) and (377c), call[StackLPx], opcode[137]; T _ NextData[IBUF], call[RILPLx]; *displacement from pointer *Write Byte Long WBL: T _ (Stack&-1) and (377c), call[StackLPx], opcode[140]; T _ NextData[IBUF], call[WILPLx]; *displacement *Read Double Byte Long RDBL: T _ (Stack&-1) and (377c), call[StackLPx], opcode[141]; T _ NextData[IBUF]; DoubleReadLong: Pfetch2[LP,Stack]; goto[.+2,quadOVF]; lu _ NextInst[IBUF], call[P5Tailx]; *Do two single fetches, the first to RTEMP Pfetch1[LP,RTEMP], call[DecS1IncT1]; Pfetch1[LP,Stack], goto[DoubleReadx]; *Write Double Byte Long WDBL: T _ (Stack&-1) and (377c), call[StackLPx], opcode[142]; T _ NextData[IBUF]; DoubleWriteLong: Pstore2[LP, Stack], call[SQT]; *Do two single stores Pstore1[LP,Stack], call[IncS2T1]; *straigntforward increment of stkp aborts. We can speed this up by being more devious. Pstore1[LP,Stack], goto[WSDBx]; StackLP: T _ (Stack&-1) and (377c); StackLPx: LPhi _ T; T _ LPhi _ (lsh[LPhi,10]) + (T) + 1; LPhi _ (fixVA[LPhi]) or (T); T _ Stack&-1; LP _ T, return; *Read Indexed by Local Pair Long RXLPL: T _ NextData[IBUF], opcode[143]; RTEMP _ T, call[LocalLP]; T _ (Stack&-1) + (T), goto[RILPLx]; *Write Indexed by Local Pair Long WXLPL: T _ NextData[IBUF], opcode[144]; RTEMP _ T, call[LocalLP]; T _ (Stack&-1) + (T), goto[WILPLx]; *Read Indexed by Global Pair Long RXGPL: T _ NextData[IBUF], opcode[145]; RTEMP _ T, call[GlobalLP]; T _ (Stack&-1) + (T), goto[RILPLx]; *Write Indexed by Global Pair Long WXGPL: T _ NextData[IBUF], opcode[146]; RTEMP _ T, call[GlobalLP]; T _ (Stack&-1) + (T), goto[WILPLx]; *Read Indirect Local Pair Long RILPL: T _ NextData[IBUF], opcode[147]; RTEMP _ T, call[LocalLP]; RILPLx: Pfetch1[LP,Stack], goto[P5Tail]; *Write Indirect Local Pair Long WILPL: T _ NextData[IBUF], opcode[150]; RTEMP _ T, call[LocalLP]; WILPLx: Pstore1[LP,Stack], goto[P5Tail]; *Read Indirect Global Pair Long RIGPL: T _ NextData[IBUF], opcode[151]; RTEMP _ T, call[GlobalLP]; Pfetch1[LP,Stack], goto[P5Tail]; *Write Indirect Global Pair Long WIGPL: T _ NextData[IBUF], opcode[152]; RTEMP _ T, call[GlobalLP]; Pstore1[LP,Stack], goto[P5Tail]; *Format a long pointer from a local selector,,offset pair LocalLP: T _ RTEMP1 _ 5c; *rtemp1 is a flag for decLPTR (below). T _ (ldf[RTEMP, 10, 4]) + (T); *note - high half of pointer is fetched first Pfetch1[LOCAL,LPhi], goto[decLPTR]; LocalLPy: Pfetch1[LOCAL,LP]; *low half LocalLPx: T _ (LPhi) and (377c); T _ LPhi _ (lsh[LPhi,10]) +(T) + 1; LPhi _ (fixVA[LPhi]) or (T); *if we decide to trap on references to page 377, do it here T _ ldf[RTEMP, 14, 4], return; *Format a long pointer from a global selector,,offset pair GlobalLP: T _ RTEMP1 _ 4c; T _ (ldf[RTEMP, 10, 4]) + (T); *note - high half of pointer is fetched first Pfetch1[GLOBAL,LPhi], goto[decLPTR]; GlobalLPy: Pfetch1[GLOBAL,LP], goto[LocalLPx]; *low half decLPTR: lu _ ldf[RTEMP1,17,1]; *where to return (T is written here) T _ (AllOnes) + (T), dblgoto[LocalLPy,GlobalLPy,ALU#0]; *Read String Long RSTRL: T _ CNextData[IBUF], call[RWSTRLx], opcode[153]; T _ rsh[RTEMP1, 1], call[FetchLPToRTEMP]; lu _ RTEMP1, dblgoto[RSTRLeft, RSTRRight, Reven], LoadPage[4]; RWSTRLX: T _ (Stack&-1) + (T); RTEMP1 _ T, goto[StackLP]; *RTEMP1 _ String index *Write String Long WSTRL: T _ CNextData[IBUF], call[RWSTRLx], opcode[154]; T _ rsh[RTEMP1,1], call[FetchLPToRTEMP]; RTEMP1 _ T, dblgoto[WSTRLLeft, WSTRLRight, Reven]; *test low bit of RTEMP1 WSTRLLeft: T _ lsh[Stack&-1, 10]; RTEMP _ (rhmask[RTEMP]) or (T), goto[WFLx]; WSTRLRight: T _ rhmask[Stack&-1]; RTEMP _ (lhmask[RTEMP]) or (T), goto[WFLx]; *Read Field Long :IF[AltoMode]; **************************************** RFL: loadpage[6], call[AlignField], Opcode[155]; RTEMP _ T, call[StackLP]; T _ RTEMP, call[FetchLPToStack]; :ELSE; ************************************************ RFL: MNBR _ CNextData[IBUF], call[StackLP], opcode[155]; lu _ CycleControl _ CNextData[IBUF], call[FetchMNBRLPToStack]; :ENDIF; *********************************************** RFLx: lu _ NextInst[IBUF], call[RFx]; *Write Field Long :IF[AltoMode]; **************************************** WFL: loadpage[6], call[AlignField], Opcode[156]; RTEMP _ T, call[StackLP]; T _ RTEMP, call[FetchLPToRTEMP]; :ELSE; ************************************************ WFL: MNBR _ CNextData[IBUF], call[StackLP], opcode[156]; lu _ CycleControl _ CNextData[IBUF], call[FetchMNBRLPToRTEMP]; :ENDIF; *********************************************** RTEMP1 _ T; WFLy: T _ WFA[Stack&-1]; RTEMP _ (WFB[RTEMP]) or (T); WFLx: T _ RTEMP1; Pstore1[LP,RTEMP], goto[P5Tail]; *Read Field Stack Long RFSL: T _ Stack&-1, call[TtoRTEMP], opcode[157]; CycleControl _ RTEMP, call[StackLP]; T _ rsh[RTEMP,10]; :IF[AltoMode]; **************************************** lu _ GetRSpec[127], skip[R even]; lu _ NextData[IBuf]; :ENDIF; *********************************************** Pfetch1[LP,Stack], goto[RFLx]; *Write Field Stack Long WFSL: T _ Stack&-1, call[TtoRTEMP], opcode[160]; CycleControl _ RTEMP, call[StackLP]; T _ rsh[RTEMP,10], call[FetchLPToRTEMP]; :IF[AltoMode]; **************************************** lu _ GetRSpec[127], skip[R even]; lu _ NextData[IBuf]; :ENDIF; *********************************************** RTEMP1 _ T, goto[WFLy]; *Lengthen Pointer @LP: T _ Stack&-1, opcode[161]; *pop to interlock PFetch2's Stack&+1, skip[ALU=0]; *test for NIL T _ rsh[MDShi,10]; *push MDShi if non-NIL PushTP5: lu _ NextInst[IBuf]; Stack&+1 _ T, NIRET; *Store Local Double Byte SLDB: T _ NextData[IBUF], opcode[162]; Pstore2[LOCAL,Stack], call[SQT]; Pstore1[LOCAL,stack], call[IncS2T1]; Pstore1[LOCAL,Stack], goto[WSDBx]; *Store Global Double Byte SGDB: T _ NextData[IBUF], opcode[163]; Pstore2[GLOBAL,Stack], call[SQT]; Pstore1[GLOBAL,stack], call[IncS2T1]; Pstore1[GLOBAL,Stack], goto[WSDBx]; *Push PUSH: Stack&+1, goto[P5Tail], opcode[164]; *Pop POP: Stack&-1, goto[P5Tail], opcode[165]; *Exchange EXCH: T _ Stack&-1, Opcode[166]; MNBR _ Stack, Stack _ T, NoRegILockOK; T _ MNBR, goto[PushTP5]; *Link Byte - equivalent to PUSHX; LIB; SUB; SL0;, except that nothing is above stkp LINKB: T _ NextData[IBUF], opcode[167]; xfMX _ T _ (xfMX) - (T), LoadPage[4]; * PStore1[LOCAL,xfMX,4], goto[P4Tail]; LocalCache0 _ T, goto[StoreLocalCache]; *Duplicate DUP: T _ Stack&-1, opcode[170]; Stack&+2 _ T, goto[P5Tail]; :IF[AltoMode]; **************************************** NILCK: goto[P5Tail], Opcode[171]; NILCKL: goto[P5Tail], opcode[172]; BNDCK: Stack&-1, goto[P5Tail], opcode[173]; :ELSE; ************************************************ *NIL Check NILCK: T _ Stack&-1, Opcode[171]; NILCKx: Stack&+1, dblgoto[doTrapP5, P5Tail, ALU=0], T _ sPointerFault; *NIL Check Long NILCKL: T _ Stack&-1, opcode[172]; lu _ (Stack) or (T), goto[NILCKx]; *Bounds Check - Trap if (TOS-1) >= TOS (unsigned) BNDCK: Stack&-1, opcode[173]; T _ Stack&+1; lu _ (Stack&-1) - (T) - 1; dblgoto[doTrapP5, P5Tail, NoCarry], T _ sBoundsFault; :ENDIF; *********************************************** *Unimplemented opcodes on page 5 T _ sUnimplemented, goto[doTrapP5], opcode[174]; T _ sUnimplemented, goto[doTrapP5], opcode[175]; T _ sUnimplemented, goto[doTrapP5], opcode[176]; T _ sUnimplemented, goto[doTrapP5], opcode[177]; doTrapP5: LoadPage[opPage3]; gotop[kfcr]; :END[MesaLS];