:IF[AltoMode]; TITLE[MesaJ.Alto.Mode]; :ELSE; TITLE[MesaJ.Pilot.Mode]; :ENDIF; % MESA JUMP AND ARITHMETIC INSTRUCTIONS This code assumes that PC,,PChi is a base register pair pointing to the current instruction quadword. The low two bits of PC are 0, and the low 3 bits of the PC (which point to a byte within the quadword) are kept in the (hardware) register PCF. Since code segments cannot cross 64K boundaries, and are limited to 32K words in length, the two bytes of PCh are forced to be equal, rather than having the least significant byte differ from the msb by 1 as is the normal case for base registers. PCF is incremented by the functions NextInst and NextData. It is assumed that the register PCX is loaded automatically from PCF at the start of every bytecode. Only the low 3 bits of PCF are loaded by PCF_, but PCF and PCX contain 4 bits so that overflow will be handled properly. % MesaRefill6: gotop[MesaRefill], Pfetch4[PC,IBUF,4], at[3377]; *refill for page 6 ONPAGE[0]; *Buffer refill. MesaRefill: PC _ (PC) + (4C); PCF _ RZero; %*Addition for trapping RZero _ 41400c; *notify task 4, location 1400 APC&APCTask _ RZero; return; RZero _ 0c, AT[250]; *End of addition % :IF[AltoMode]; **************************************** SwapBytes: IBuf _ lcy[IBuf, 10]; IBuf1 _ lcy[IBuf1, 10]; IBuf2 _ lcy[IBuf2, 10]; IBuf3 _ lcy[IBuf3, 10], return; :ELSE; ************************************************ nop; * hold page fault on page 0 return; :ENDIF; *********************************************** %*Trapping stuff: SetTask[4]; RV[TrapRet,10, 250]; *notify word for return to emulator (task 0, location 250) RV[TrapVal,11,177777]; *value checked RV[TrapAddr,12,1]; *address of quadword to be checked RV[TrapAddrHi,13,0]; *high part of address RV[TrapData,14]; RV[TrapData1,15]; RV[TrapData2,16]; RV[TrapData3,17]; lu _ TrapAddr, skip[REven], AT[1400]; APC&APCTask _ TrapRet, goto[TrapRetLoc]; PFetch4[TrapAddr,TrapData,0]; T _ TrapVal; lu _ (TrapData) xor (T); lu _ (TrapData1) xor (T), skip[ALU=0]; Trap0Bad: breakpoint; lu _ (TrapData2) xor (T), skip[ALU=0]; Trap1Bad: breakpoint; lu _ (TrapData3) xor (T), skip[ALU=0]; Trap2Bad: breakpoint; skip[ALU=0]; Trap3Bad: breakpoint; APC&APCTask _ TrapRet; TrapRetLoc: return; SetTask[0]; % ONPAGE[6]; % Jn, n=2-8. PCF points to the byte beyond the opcode when execution starts, so if PCF is odd, the opcode is in the even byte of the current word, if PCF is even, the opcode is in the odd byte of the previous word. The word displacement of the target from PCF[0:2] and the final lsb of the PC are: n PCF PCF even odd 2 0,1 1,0 3 1,0 1,1 4 1,1 2,0 5 2,0 2,1 6 2,1 3,0 7 3,0 3,1 8 3,1 4,0 9 4,0 4,1 % J2: T_0C, GETRSPEC[127], dblgoto[JnE,JnO,Reven], opcode[200]; J3: T_1C, goto[Jnx], opcode[201]; J4: T_1C, GETRSPEC[127], dblgoto[JnE,JnO,Reven], opcode[202]; J5: T_2C, goto[Jnx], opcode[203]; J6: T_2C, GETRSPEC[127], dblgoto[JnE,JnO,Reven], opcode[204]; J7: T_3C, goto[Jnx], opcode[205]; J8: T_3C, GETRSPEC[127], dblgoto[JnE,JnO,Reven], opcode[206]; J9: T_4C, goto[Jnx], opcode[207]; JnX: T_ (ldf[GETRSPEC[127],14,3]) + (T), goto[JnOcom]; JnE: T_ (ldf[GETRSPEC[127],14,3]) + (T), goto[JnECom]; JnO: T_ (ldf[GETRSPEC[127],14,3]) + (T) +1, goto[JnECom]; JnECom: Pfetch4[PC,IBUF]; T_ PC _ T; *bypass kludge GETRSPEC[127], dblgoto[JnECo, JnECe, Rodd]; JnECe: PC _ (lsh[PC,1]) + 1, goto[JnFin]; JnECo: PC _ (lsh[PC,1]), goto[JnFin]; JnOCom: Pfetch4[PC,IBUF]; T_ PC _ T; *bypass kludge GETRSPEC[127], dblgoto[JnOCo, JnOCe, Rodd]; JnOCo: PC _ (lsh[PC,1]) + 1, goto[JnFin]; JnOCe: PC _ (lsh[PC,1]), goto[JnFin]; :IF[AltoMode]; **************************************** JnFin: PCF _ PC; *only the low 3 bits of PCF are loaded PC _ T; JSwapx: IBUF _ lcy[IBUF,10]; IBUF1 _ lcy[IBUF1,10]; IBUF2 _ lcy[IBUF2,10]; IBUF3 _ lcy[IBUF3,10]; lu _ NextInst[IBUF], call[JnRETx]; :ELSE; ************************************************ JnFin: PCF _ PC; *only the low 3 bits of PCF are loaded PC _ T; :ENDIF; *********************************************** P6Tail: JnRET: lu _ NextInst[IBUF]; JnRETx: PC _ (PC) and not (3c), NIRET; % Jump Byte: alpha is a signed displacement from the opcode This works for -128 < alpha < 122. This code (and that for JW) uses the register AllOnes as a temporary, and resets it when done. % JB: T_ (NextData[IBUF])-1, opcode[210]; T _ (PCXREG) + (T); *PCX = 0..7 here (the NextData may have caused refill, but *PCX is still correct, since PCX is loaded when the refill code returns) *T has the signed BYTE displacement relative to PC *If jumping backward in same quadword, negative may have become positive; *mask T to 8 bits :IF[AltoMode]; **************************************** JBr: T _ (rhmask[AllOnes]) AND T; AllOnes _ (Zero) + (T) + 1, goto[JBq, noH2bit8]; :ELSE; ************************************************ JBr: AllOnes _ (rhmask[AllOnes]) AND T, goto[JBq, noH2bit8]; :ENDIF; *********************************************** PC _ (PC) - (200C); *If bit 8 = 1, the quantity in T and AllOnes is the byte *displacement + 400b. We subtract 400b bytes from PC. JBq: T _ rsh[AllOnes,1]; *form word displacement *T has positive WORD displacement relative to PC JBy: Pfetch4[PC,IBUF]; PC _ T; PCF _ AllOnes; :IF[AltoMode]; **************************************** AllOnes _ (Zero)-1, goto[JSwapx]; :ELSE; ************************************************ AllOnes _ (Zero)-1, goto[JnRet]; :ENDIF; *********************************************** *Jump Word: alpha,,beta is a 2's complement displacement from the opcode. :IF[AltoMode]; **************************************** JW: lu _ GetRSpec[127], skip[R even], opcode[211]; lu _ NextData[IBuf]; T _ NextData[IBUF]; *get beta lu _ CycleControl _ NextData[IBUF]; *get alpha :ELSE; ************************************************ JW: lu _ CycleControl _ NextData[IBUF], opcode[211]; *get alpha T _ NextData[IBUF]; *get beta :ENDIF; *********************************************** T _ (lhmask[GetRSpec[127]]) OR T; *CycleControl is in bits 0:7 *T has signed WORD displacement relative to the opcode :IF[AltoMode]; **************************************** JWx: T _ (PCFREG) + (T); AllOnes _ T _ (AllOnes)+(T), dblgoto[JWp,JWn,ALU>=0]; *T-1 :ELSE; ************************************************ JWx: T _ (PCFREG) + (T); AllOnes _ T _ (FormMinus4[AllOnes])+(T)+1, dblgoto[JWp,JWn,ALU>=0]; *-4+T+1 = T-3 :ENDIF; *********************************************** JWn: T _ 100000C; *negative displacement - put in the bit that the shift is about to lose T _ (rsh[AllOnes,1]) or (T), goto[JBy]; JWp: T _ (rsh[AllOnes,1]), goto[JBy]; *Jump Equal n, n=2..9: JEQ2: T _ (stack&-1), call [JEQEVtest], opcode[212]; T _ T, goto[JnECom]; * Load T for bypass kludge JEQ3: T _ (stack&-1), call [JEQODtest], opcode[213]; T _ (Form1[AllOnes]) + (T), goto[JnOCom]; JEQ4: T _ (stack&-1), call [JEQEVtest], opcode[214]; T _ (Form1[AllOnes]) + (T), goto[JnECom]; JEQ5: T _ (stack&-1), call [JEQODtest], opcode[215]; T _ (Form2[AllOnes]) + (T), goto[JnOCom]; JEQ6: T _ (stack&-1), call [JEQEVtest], opcode[216]; T _ (Form2[AllOnes]) + (T), goto[JnECom]; JEQ7: T _ (stack&-1), call [JEQODtest], opcode[217]; T _ (Form3[AllOnes]) + (T), goto[JnOCom]; JEQ8: T _ (stack&-1), call [JEQEVtest], opcode[220]; T _ (Form3[AllOnes]) + (T), goto[JnECom]; JEQ9: T _ (stack&-1), call [JEQODtest], opcode[221]; T _ (Form4[AllOnes]) + (T), goto[JnOCom]; JEQEVtest: lu _ (stack&-1) - (T); dblgoto[JEQjmp,JnRET,alu=0], T _ (ldf[GETRSPEC[127],17,1]); JEQODtest: lu _ (stack&-1) - (T); dblgoto[JEQjmp,JnRET,alu=0], T _ 0C; JEQjmp: T _ (ldf[GETRSPEC[127],14,3]) + (T), return; *Jump Equal Byte JEQB: T _ (Stack&-1),call[stkdif],usectask, opcode[222]; JEQBx: T _ 2c, dblgoto[Ejmp,Onojmp,ALU=0]; Ejmp: * T contains length of instuction (2) T _ (NextData[IBUF]) - T; Ejmpx: T _ (PCFREG) + (T), goto[JBr]; Onojmp: lu _ NextData[IBUF]; Onojmpx: lu _ NextInst[IBUF],call[JnRETx]; stkdif: lu _ (stack&-1) - (T), return; *Jump Not Equal n, n=2..9: JNE2: T _ (stack&-1), call [JNEEVtest], opcode[223]; T _ T, goto[JnECom]; * Load T for bypass kludge JNE3: T _ (stack&-1), call [JNEODtest], opcode[224]; T _ (Form1[AllOnes]) + (T), goto[JnOCom]; JNE4: T _ (stack&-1), call [JNEEVtest], opcode[225]; T _ (Form1[AllOnes]) + (T), goto[JnECom]; JNE5: T _ (stack&-1), call [JNEODtest], opcode[226]; T _ (Form2[AllOnes]) + (T), goto[JnOCom]; JNE6: T _ (stack&-1), call [JNEEVtest], opcode[227]; T _ (Form2[AllOnes]) + (T), goto[JnECom]; JNE7: T _ (stack&-1), call [JNEODtest], opcode[230]; T _ (Form3[AllOnes]) + (T), goto[JnOCom]; JNE8: T _ (stack&-1), call [JNEEVtest], opcode[231]; T _ (Form3[AllOnes]) + (T), goto[JnECom]; JNE9: T _ (stack&-1), call [JNEODtest], opcode[232]; T _ (Form4[AllOnes]) + (T), goto[JnOCom]; JNEEVtest: lu _ (stack&-1) - (T); dblgoto[JNEjmp,JNEnojmp,alu#0], T _ (ldf[GETRSPEC[127],17,1]); JNEODtest: lu _ (stack&-1) - (T); dblgoto[JNEjmp,JNEnojmp,alu#0], T _ 0C; JNEjmp: T _ (ldf[GETRSPEC[127],14,3]) + (T), return; JNEnojmp: lu _ NextInst[IBUF], call[JnRETx]; *Jump Not Equal Byte JNEB: T _ (Stack&-1),call[stkdif], usectask, opcode[233]; JNEBx: T _ 2c, dblgoto[Ojmp,Enojmp,ALU#0]; Ojmp: * T contains length of instuction (2) T _ (NextData[IBUF]) - T, call[Ejmpx]; Enojmp: lu _ NextData[IBUF],call[Onojmpx]; *Jump Less Byte - jump if (TOS-1) < TOS JLB: T _ (Stack&-1),call[stkdif],usectask, opcode[234]; JLBx: T _ (RZero)+1, dblgoto[JLBpos,JLBneg,ALU>=0], FREEZERESULT; * T _ 1 JLBpos: T _ (RZero) + (T) + 1, dblgoto[Onojmp,Ejmp,NOOVF]; * T _ 2 JLBneg: T _ (RZero) + (T) + 1, dblgoto[Ojmp,Enojmp,NOOVF]; * T _ 2 *Jump Greater Equal Byte JGEB: T _ (Stack&-1),call[stkdif],usectask, opcode[235]; JGEBx: T _ (RZero)+1, dblgoto[JGEBpos,JGEBneg,ALU>=0], FREEZERESULT; * T _ 1 JGEBpos: T _ (RZero) + (T) + 1, dblgoto[Enojmp,Ojmp,OVF]; * T _ 2 JGEBneg: T _ (RZero) + (T) + 1, dblgoto[Ejmp,Onojmp,OVF]; * T _ 2 *Jump Greater Byte JGB: Stack&-1,usectask,call[stksw], opcode[236]; lu _ (Stack&-2) - (T), goto[JLBx]; *Jump Less Equal Byte JLEB: Stack&-1,usectask,call[stksw], opcode[237]; lu _ (Stack&-2) - (T), goto[JGEBx]; stksw: T _ stack&+1, return; *Jump Unsigned Less Byte JULB: T _ (Stack&-1), usectask,call[stkdif], opcode[240]; JULBx: T _ 2c, dblgoto[Onojmp,Ejmp,Carry]; *Jump Unsigned Greater Equal Byte JUGEB: T _ (Stack&-1), usectask,call[stkdif], opcode[241]; JUGEBx: T _ 2c, dblgoto[Ojmp,Enojmp,Carry]; *Jump Unsigned Greater Byte JUGB: Stack&-1,usectask,call[stksw], opcode[242]; lu _ (Stack&-2) - (T), goto[JULBx]; *Jump Unsigned Less Equal Byte JULEB: Stack&-1,usectask,call[stksw], opcode[243]; lu _ (Stack&-2) - (T), goto[JUGEBx]; *Jump Zero Equal Byte JZEQB: lu _ (Stack&-1), goto[JEQBx], opcode[244]; *Jump Zero Not Equal Byte JZNEB: lu _ (Stack&-1), goto[JNEBx], opcode[245]; *Jump Indexed Byte :IF[AltoMode]; **************************************** JIB: T _ sUnimplemented, goto[doTrapP6], opcode[246]; :ELSE; ************************************************ JIB: T _ Stack&-1, usectask, call[stkdif], opcode[246]; goto[JIBnojmp,carry],Stack&+1; lu _ CycleControl _ NextData[IBUF]; *get alpha T _ NextData[IBUF]; *get beta T _ (lhmask[GetRSpec[127]]) OR T; *CycleControl is in bits 0:7 T _ (rsh[Stack,1]) + (T),task; PFETCH1[CODE,RTEMP]; Stack&-1, dblgoto[JIBl,JIBr,Reven]; JIbl: T _ (ldf[RTEMP,0,10]), goto[JWx]; JIBr: T _ (rhmask[RTEMP]), goto[JWx]; JIBnojmp: lu _ NextData[IBUF], call[JIWnojmpx]; *skip alpha :ENDIF; ********************************************** *Jump Indexed Word :IF[AltoMode]; **************************************** JIW: lu _ GetRSpec[127], skip[R even], opcode[247]; lu _ NextData[IBuf]; T _ Stack&-1; usectask, call[stkdif]; goto[JIWnojmp,carry],Stack&+1; T _ NextData[IBUF]; *get beta lu _ CycleControl _ NextData[IBUF]; *get alpha :ELSE; ************************************************ JIW: T _ Stack&-1, usectask, call[stkdif], opcode[247]; goto[JIWnojmp,carry],Stack&+1; lu _ CycleControl _ NextData[IBUF]; *get alpha T _ NextData[IBUF]; *get beta :ENDIF; ********************************************** T _ (lhmask[GetRSpec[127]]) OR T; *CycleControl is in bits 0:7 T _ (Stack&-1) + (T),task; PFETCH1[CODE,RTEMP]; T _ RTEMP, goto[JWx]; JIWnojmp: lu _ NextData[IBUF]; *skip alpha JIWnojmpx: Stack&-1; *adjust the stack lu _ NextData[IBUF], call[JnRET]; *skip beta *ADD @ADD: T _ Stack&-1, opcode[250]; Addx: lu _ NextInst[IBuf]; Stack _ (Stack) + (T), NIRet; *SUB @SUB: T _ Stack&-1, opcode[251]; Subx: lu _ NextInst[IBuf]; Stack _ (Stack) - (T), NIRet; *Multiply - The high half of the 32-bit product is left above the top of the stack * product low in Stack, hi in RTEMP1 * multipliplicand low in RTEMP, hi in xfMX * multiplier in xfMY @MUL: T _ RTEMP1 _ 0c, opcode[252]; SALUF _ T, call[PopToT]; * Saluf = 0 is a no op xfMY _ T, UseCTask, call[PopToT]; Stack&+1 _ 0c, skip[alu#0]; * tests xfMY _ T Stack&+1 _ 0c, goto[mdPop]; RTEMP _ T, call[.+1]; xfMY _ (rsh[xfMY,1]) salufop (T), skip[reven]; * top of loop1 Stack _ (Stack) + (T), dblgoto[mulDone, MULa, alu=0]; MULb: T _ RTEMP _ (RTEMP) + (T), FreezeResult, dblgoto[MULl,MULm,R<0]; MULl: RTEMP1 _ (RTEMP1) + 1, UseCoutAsCin, goto[mulLong]; MULm: RTEMP1 _ (RTEMP1) + 1, UseCoutAsCin, return; MULa: T _ RTEMP _ (RTEMP) + (T), FreezeResult, dblgoto[MULl,MULm,R<0]; mulLong: xfMX _ 1c, call[.+1]; lu _ (xfMY) salufop (T), skip[reven]; * top of loop2 Stack _ (Stack) + (T); RTEMP1 _ (RTEMP1) + 1, UseCoutAsCin; RTEMP _ (RTEMP) + (T); T _ xfMX, FreezeResult; xfMX _ (xfMX) + (T) + 1, UseCoutAsCin; xfMY _ rsh[xfMY,1], skip[reven]; T _ RTEMP1 _ (RTEMP1) + (T), dblgoto[mdPush, MULc, alu=0]; T _ RTEMP, return; MULc: T _ RTEMP, return; mulDone: T _ (RTEMP1) + 1, UseCoutAsCin, goto[mdPush]; mdPush: Stack&+1 _ T; mdPop: lu _ NextInst[IBUF]; Stack&-1, NIRET; PopToT: T _ Stack&-1, FreezeResult, return; *Double DBL: T _ lsh[Stack&-1,1], Opcode[253]; PushTP6: lu _ NextInst[IBUF]; Stack&+1 _ T, NIRET; *Divide - (TOS-1)/TOS. Single word dividend, single word divisor, no check for overflow. *The remainder is left above the stack. @DIV: MNBR _ Stack&-1, opcode[254]; T _ 0c, goto[LDIVx]; *Long Divide - (TOS-1),,(TOS-2)/TOS. Double word dividend, single word divisor, no check for overflow. *The remainder is left above the stack. * dividend low in Stack; hi in RTEMP * divisor in T * quotient appears in Stack; remainder in RTEMP @LDIV: MNBR _ Stack&-1, call[PopToT], opcode[255]; LDIVx: RTEMP _ T, LoadPage[opPage0]; T _ MNBR, gotop[.+1]; onpage[opPage0]; lu _ (RTEMP) - (T), goto[zerodivide, alu=0]; goto[dividecheck, carry]; nop; rcnt _ 17c, call[divStart]; lu _ RTEMP1; * top of loop RTEMP _ (RTEMP) - (T), skip[alu=0]; * subtract divisor Stack _ (lsh[Stack,1]) + 1, dblgoto[divs1, divs0, r<0]; * q bit 1 skip[nocarry]; Stack _ (lsh[Stack,1]) + 1, dblgoto[divs1, divs0, r<0]; * q bit 1 RTEMP _ (RTEMP) + (T); * add back divisor divStart: Stack _ lsh[Stack,1], dblgoto[divs1, divs0, r<0]; * q bit 0 divs1: rcnt _ (rcnt) - 1, goto[divDone1, r<0]; * shift 1 RTEMP _ (lsh[RTEMP,1]) + 1, dblgoto[divhs1, divhs0, r<0]; divs0: rcnt _ (rcnt) - 1, goto[divDone2, r<0]; * shift 0 RTEMP _ lsh[RTEMP,1], dblgoto[divhs1, divhs0, r<0]; divhs1: RTEMP1 _ 1c, return; * next quotient bit known to be 1 divhs0: RTEMP1 _ 0c, return; * next quotient bit unknown divDone1: T _ RTEMP, LoadPage[opPage2], goto[divPush]; divDone2: T _ RTEMP, LoadPage[opPage2], goto[divPush]; divPush: Stack&+1 _ T, gotop[mdPop]; :IF[AltoMode]; **************************************** dividecheck: RTEMP _ 0c, goto[divDone1]; *no checks in Alto mode zerodivide: RTEMP _ 0c, goto[divDone1]; :ELSE; ************************************************ dividecheck: T _ sDivideCheck, goto[doTrapP4]; zerodivide: T _ sZeroDivisor, goto[doTrapP4]; :ENDIF; *********************************************** onpage[opPage2]; *Negate @NEG: T _ Stack&-1, Opcode[256]; T _ (Zero) - (T), goto[PushTP6]; *Increment @INC: T _ (Stack&-1) + 1, goto[PushTP6], Opcode[257]; *And @AND: T _ Stack&-1, Opcode[260]; Stack _ (Stack) and (T), goto[P6Tail]; *OR @OR: T _ Stack&-1, Opcode[261]; Stack _ (Stack) or (T), goto[P6Tail]; *XOR @XOR: T _ Stack&-1, Opcode[262]; Stack _ (Stack) xor (T), goto[P6Tail]; *Shift @SHIFT: T _ Stack&-1, Opcode[263]; dblgoto[ShiftRight,ShiftLeft,ALU<0] , RTEMP _T ; ShiftRight: RTEMP _ (RTEMP) + (17C); dblgoto[SHF1,SHF2,Carry]; SHF2: goto[P6Tail],Stack _ Zero; *shift count > 17 , use zero SHF1: CycleControl _ RTEMP; goto[P6Tail],Stack _ RF[Stack]; ShiftLeft: lu _ (RTEMP) and not (17C); dblgoto[SHF3,SHF4,ALU=0], T _ (RTEMP) ; SHF4: goto[P6Tail],Stack _ Zero ; *shift count > 17 , use zero *T has positive count. form 0,,-count, then use WFA SHF3: RTEMP _ (Zero) - (T) - 1 ; RTEMP _ (RTEMP) and (17C) ; CycleControl _ RTEMP ; goto[P6Tail],Stack _ WFA[Stack]; *Double Add @DADD: MNBR _ Stack&-1, call[GetTDecStk2], opcode[264]; *point to lsb of top doubleword Stack _ (Stack) + (T); * add low bits Stack&+1, goto[dAddC, carry]; T _ MNBR, goto[Addx]; * pick up high bits of top doubleword dAddC: T _ (MNBR) + 1, goto[Addx]; * pick up high bits of top doubleword *Double Subtract @DSUB: MNBR _ Stack&-1, call[GetTDecStk2], opcode[265]; *point to lsb of top doubleword Stack _ (Stack) - (T); * subtract low bits Stack&+1, goto[dSubC, NoCarry]; *point to msb of second doubleword T _ MNBR, goto[Subx]; *remember msb of top doubleword (TOS) dSubC: T _ (MNBR) + 1, goto[Subx]; GetTDecStk2: T _ (Stack&-2), return; *grab it, point to lsb of second doubleword *Double Signed Compare: *If (TOS-2),,(TOS-3) < TOS,,(TOS-1), push -1 *If (TOS-2),,(TOS-3) = TOS,,(TOS-1), push 0 *If (TOS-2),,(TOS-3) > TOS,,(TOS-1), push 1 *Comparisons are signed DCOMP: T _ (Stack&-2) + (100000c), Opcode[266]; Stack _ (Stack) + (100000c), goto[DUCOMPy]; *Double Compare: *If (TOS-2),,(TOS-3) < TOS,,(TOS-1), push -1 *If (TOS-2),,(TOS-3) = TOS,,(TOS-1), push 0 *If (TOS-2),,(TOS-3) > TOS,,(TOS-1), push 1 *Comparisons are unsigned DUCOMP: T _ Stack&-2, Opcode[267]; DUCOMPy: lu _ (Stack&+1) - (T); *Compare msb's, point at lsb of high doubleword goto[DUCompareLowBits, ALU=0], T _ Stack&-2, FREEZERESULT; *grab lsb of top doubleword, *point at lsb of second doubleword DUCompx: dblgoto[DUCompL, DUCompG, NoCarry]; DUCompL: T _ (RZero) - 1, goto[DUCompEqual]; DUCompG: T _ (RZero) + 1, goto[DUCompEqual]; DUCompareLowBits: T _ (Stack) - (T); goto[DUCompEqual, ALU=0], FREEZERESULT; dblgoto[DUCompL, DUCompG, NoCarry]; DUCompEqual: Stack _ T, goto[P6Tail]; *ADD01 - on D0, equivalent to ADD ADD01: goto[Addx], T _ Stack&-1, Opcode[270]; *Unused opcodes on page 6 T _ sUnimplemented, goto[doTrapP6], opcode[271]; T _ sUnimplemented, goto[doTrapP6], opcode[272]; T _ sUnimplemented, goto[doTrapP6], opcode[273]; T _ sUnimplemented, goto[doTrapP6], opcode[274]; T _ sUnimplemented, goto[doTrapP6], opcode[275]; T _ sUnimplemented, goto[doTrapP6], opcode[276]; T _ sUnimplemented, goto[doTrapP6], opcode[277]; doTrapP6: LoadPage[opPage3]; gotop[kfcr]; :END[MesaJ];