DIRECTORY CedarMicrocode, ListerUtils, OpDebug, RESInterpreter, PrincOps; RESIDisp: CEDAR PROGRAM IMPORTS CedarMicrocode, OpDebug, RI: RESInterpreter EXPORTS RESInterpreter = { OPEN PrincOps; Value: TYPE = RI.Value; DValue: TYPE = RI.DValue; Ptr1: TYPE = RI.Ptr1; Ptr2: TYPE = RI.Ptr2; LPtr1: TYPE = RI.LPtr1; LPtr2: TYPE = RI.LPtr2; LCB: TYPE = RI.LCB; Machine: TYPE = RI.Machine; Byte: TYPE = RI.Byte; Bytes: TYPE = RI.Bytes; Pair: TYPE = RI.Pair; FieldDescriptor: TYPE = PrincOps.FieldDescriptor; StrangeCode: PUBLIC SIGNAL = CODE; Execute: PUBLIC PROC [m: Machine] = TRUSTED { hist: RI.OpHistory; opData: ListerUtils.OpCodeArray; IF m.traceOps THEN { hist _ m.history; opData _ OpDebug.OpData[]}; DO savedPc: CARDINAL = m.pc; op: Byte; op _ RI.NextOpByte[m, TRUE]; IF m.countOps THEN m.opCount[op] _ m.opCount[op] + 1; m.iCount _ m.iCount + 1; IF m.traceOps THEN { cb: LONG POINTER TO PACKED ARRAY [0..0) OF Byte = m.cb; hi: RI.OpHistoryItem; hi _ [pc: savedPc, gf: m.g, stkDepth: m.sd, stk: NULL, op: [op,0,0]]; FOR j: CARDINAL IN [0..m.sd) DO hi.stk[j] _ m.stack[j]; ENDLOOP; IF opData # NIL THEN SELECT opData[op].length FROM 2 => hi.op[1] _ cb[savedPc+1]; 3 => {hi.op[2] _ cb[savedPc+2]; hi.op[1] _ cb[savedPc+1]}; ENDCASE; hist.data[hist.tail] _ hi; hist.tail _ (hist.tail+1) MOD RI.OpHistorySize; IF hist.tail = hist.head THEN hist.head _ (hist.head+1) MOD RI.OpHistorySize}; SELECT op FROM zLI0, zLI1, zLI2, zLI3, zLI4, zLI5, zLI6 => {RI.Push[m, RI.VCard[op - zLI0]]}; zLIB => {RI.Push[m, RI.VCard[RI.NextOpByte[m]]]}; zLGDB => { n: CARDINAL _ RI.NextOpByte[m]; RI.Push2[m, RI.ReadDouble[m, LOOPHOLE[LONG[m.g+n]]]]}; zRFL => { p: LPtr1 _ RI.LPtr1V[RI.Pop2[m]]; n: CARDINAL = RI.NextOpByte[m]; fd: FieldDescriptor _ LOOPHOLE[RI.NextOpByte[m]]; RI.Push[m, RI.ReadField[m, p+n, fd]]}; zRILPL => { pr: Pair _ LOOPHOLE[RI.NextOpByte[m]]; p: LPtr1; RI.DoubleReadLocal[m, PrincOps.localbase+pr.p1]; p _ RI.LPtr1V[LOOPHOLE[(m.l+PrincOps.localbase+pr.p1), Ptr2]^]; RI.Push[m, RI.Read[m, p+pr.p2]]}; zNOOP, zME, zMRE, zMXW, zMXD, zNOTIFY, zBCAST, zREQUEUE => RI.DoMonitorOps[m, op]; zLL0, zLL1, zLL2, zLL3, zLL4, zLL5, zLL6, zLL7 => { n: CARDINAL _ op - zLL0; p: POINTER TO Value = m.l+PrincOps.localbase+n; RI.ReadLocal[m, n]; RI.Push[m, p^]}; zLLB => { n: CARDINAL _ RI.NextOpByte[m]; p: POINTER TO Value = m.l+n; RI.ReadLocal[m, n]; RI.Push[m, p^]}; zLLDB => { n: CARDINAL _ RI.NextOpByte[m]; p: POINTER TO DValue = LOOPHOLE[m.l+n]; RI.DoubleReadLocal[m, n]; RI.Push2[m, p^]}; zSL0, zSL1, zSL2, zSL3, zSL4, zSL5, zSL6, zSL7 => { n: CARDINAL _ op - zSL0; p: POINTER TO Value = m.l+PrincOps.localbase+n; RI.StoreLocal[m, n]; p^ _ RI.Pop[m]}; zSLB => { n: CARDINAL _ RI.NextOpByte[m]; p: POINTER TO Value = m.l+n; RI.StoreLocal[m, n]; p^ _ RI.Pop[m]}; zSLDB => { n: CARDINAL _ RI.NextOpByte[m]; p: POINTER TO DValue = LOOPHOLE[m.l+n]; RI.DoubleStoreLocal[m, n]; p^ _ RI.Pop2[m]}; zPL0, zPL1, zPL2, zPL3 => { n: CARDINAL _ op - zPL0; p: POINTER TO Value = m.l+PrincOps.localbase+n; RI.StoreLocal[m, n]; p^ _ RI.Top[m]}; zLG0, zLG1, zLG2, zLG3, zLG4, zLG5, zLG6, zLG7, zLGB, zLGDB, zSG0, zSG1, zSG2, zSG3, zSGB, zSGDB => RI.DoGlobalOps[m, op]; zLI0, zLI1, zLI2, zLI3, zLI4, zLI5, zLI6, zLIN1, zLINI, zLIB, zLIW, zLCO, zLINB, zLADRB, zGADRB => RI.DoLiteralOps[m, op]; zR0, zR1, zR2, zR3, zR4, zRB, zRBL, zRD0, zRDB, zRDBL, zRF, zRFL => RI.DoReadOps[m, op]; zWCDBL, zICDBL, zW0, zW1, zW2, zWB, zWBL, zWD0, zWDB, zWDBL, zWF, zWFL => RI.DoWriteOps[m, op]; zRSTR => { n: CARDINAL _ RI.NextOpByte[m]; i: CARDINAL _ RI.CardV[RI.Pop[m]]; p: Ptr1 _ RI.Ptr1V[RI.Pop[m]]; fd: FieldDescriptor _ IF (n+i) MOD 2 = 0 THEN [offset: 0, posn: 0, size: 8] ELSE [offset: 0, posn: 8, size: 8]; RI.Push[m, RI.ReadField[m, LONG[p+(n+i)/2], fd]]}; zWSTR => { n: CARDINAL _ RI.NextOpByte[m]; i: CARDINAL _ RI.CardV[RI.Pop[m]]; p: Ptr1 _ RI.Ptr1V[RI.Pop[m]]; v: Value _ RI.Pop[m]; fd: FieldDescriptor _ IF (n+i) MOD 2 = 0 THEN [offset: 0, posn: 0, size: 8] ELSE [offset: 0, posn: 8, size: 8]; RI.WriteField[m, LONG[p+(n+i)/2], fd, v]}; zRSTRL => { n: CARDINAL _ RI.NextOpByte[m]; i: CARDINAL _ RI.CardV[RI.Pop[m]]; p: LPtr1 _ RI.LPtr1V[RI.Pop2[m]]; fd: FieldDescriptor _ IF (n+i) MOD 2 = 0 THEN [offset: 0, posn: 0, size: 8] ELSE [offset: 0, posn: 8, size: 8]; RI.Push[m, RI.ReadField[m, p+(n+i)/2, fd]]}; zWSTRL => { n: CARDINAL _ RI.NextOpByte[m]; i: CARDINAL _ RI.CardV[RI.Pop[m]]; p: LPtr1 _ RI.LPtr1V[RI.Pop2[m]]; v: Value _ RI.Pop[m]; fd: FieldDescriptor _ IF (n+i) MOD 2 = 0 THEN [offset: 0, posn: 0, size: 8] ELSE [offset: 0, posn: 8, size: 8]; RI.WriteField[m, p+(n+i)/2, fd, v]}; zRXLP, zRXLPL, zRXGPL, zRILP, zRILPL, zRIGP, zRIGPL, zRIL0 => RI.DoReadIndirectOps[m, op]; zWXLP, zWXLPL, zWXGPL, zWILP, zWILPL, zWIGPL => RI.DoWriteIndirectOps[m, op]; zWS0, zWSB, zWSDB, zWSF => RI.DoWriteSwappedOps[m, op]; zRFC => { -- read from code segment n: CARDINAL _ RI.NextOpByte[m]; fd: FieldDescriptor _ LOOPHOLE[RI.NextOpByte[m]]; p: LONG POINTER _ m.cb + n + RI.CardV[RI.Pop[m]]; RI.Push[m, RI.ReadField[m, p, fd]]}; zRFS => { fd: FieldDescriptor _ LOOPHOLE[RI.Pop[m]]; p: Ptr1 _ RI.Ptr1V[RI.Pop[m]]; p _ p + fd.offset; fd.offset _ 0; RI.Push[m, RI.ReadField[m, LONG[p], fd]]}; zRFSL => { fd: FieldDescriptor _ LOOPHOLE[RI.Pop[m]]; p: LPtr1 _ RI.LPtr1V[RI.Pop2[m]]; p _ p + fd.offset; fd.offset _ 0; RI.Push[m, RI.ReadField[m, p, fd]]}; zWFS => { fd: FieldDescriptor _ LOOPHOLE[RI.Pop[m]]; p: Ptr1 _ RI.Ptr1V[RI.Pop[m]]; p _ p + fd.offset; fd.offset _ 0; RI.WriteField[m, LONG[p], fd, RI.Pop[m]]}; zWFSL => { fd: FieldDescriptor _ LOOPHOLE[RI.Pop[m]]; p: LPtr1 _ RI.LPtr1V[RI.Pop2[m]]; p _ p + fd.offset; fd.offset _ 0; RI.WriteField[m, p, fd, RI.Pop[m]]}; zLP => { RI.Push2[m, RI.VLPtr1[LONG[RI.Ptr1V[RI.Pop[m]]]]]}; zPUSH => { m.sd _ m.sd + 1}; zPOP => { m.sd _ m.sd - 1}; zEXCH => { t: Value _ m.stack[m.sd-1]; m.stack[m.sd-1] _ m.stack[m.sd-2]; m.stack[m.sd-2] _ t}; zDUP => { m.stack[m.sd] _ m.stack[m.sd-1]; m.sd _ m.sd + 1}; zNILCK => { IF RI.Ptr1V[m.stack[m.sd-1]] = NIL THEN RI.NilFault[m]}; zNILCKL => { IF RI.Ptr1V[m.stack[m.sd-1]] = NIL AND RI.Ptr1V[m.stack[m.sd-2]] = NIL THEN RI.NilFault[m]}; zBNDCK => { bound: CARDINAL _ RI.CardV[RI.Pop[m]]; IF RI.CardV[m.stack[m.sd-1]] >= bound THEN RI.BoundsFault[m]}; zLINKB => { delta: CARDINAL _ RI.NextOpByte[m]; indirectLoc: CARDINAL _ RI.CardV[m.stack[m.sd]]; (m.l + localbase)^ _ RI.VCard[indirectLoc - delta]}; zJ2, zJ3, zJ4, zJ5, zJ6, zJ7, zJ8, zJ9 => { alpha: INTEGER = op - zJ2 + 2; RI.SetPc[m, savedPc + alpha]}; zJB => { alpha: INTEGER = RI.SignedOpByte[m]; RI.SetPc[m, savedPc + alpha]}; zJW => { alpha: RECORD [SELECT OVERLAID * FROM int => [i: INTEGER], pair => [bp: RI.Bytes], ENDCASE]; alpha.bp.b1 _ RI.NextOpByte[m]; alpha.bp.b2 _ RI.NextOpByte[m]; RI.SetPc[m, savedPc + alpha.i]}; zJEQ2, zJEQ3, zJEQ4, zJEQ5, zJEQ6, zJEQ7, zJEQ8, zJEQ9 => { alpha: INTEGER = op - zJEQ2 + 2; op2: CARDINAL = RI.CardV[RI.Pop[m]]; op1: CARDINAL = RI.CardV[RI.Pop[m]]; IF op1 = op2 THEN RI.SetPc[m, savedPc + alpha]}; zJNE2, zJNE3, zJNE4, zJNE5, zJNE6, zJNE7, zJNE8, zJNE9 => { alpha: INTEGER = op - zJNE2 + 2; op2: CARDINAL = RI.CardV[RI.Pop[m]]; op1: CARDINAL = RI.CardV[RI.Pop[m]]; IF op1 # op2 THEN RI.SetPc[m, savedPc + alpha]}; zJLB, zJGEB, zJGB, zJLEB => RI.DoSignedJump[m, savedPc, op]; zJEQB, zJNEB, zJULB, zJUGEB, zJUGB, zJULEB => RI.DoUnsignedJump[m, savedPc, op]; zJZEQB => { alpha: INTEGER = RI.SignedOpByte[m]; op1: CARDINAL = RI.CardV[RI.Pop[m]]; IF op1 = 0 THEN RI.SetPc[m, savedPc + alpha]}; zJZNEB => { alpha: INTEGER = RI.SignedOpByte[m]; op1: CARDINAL = RI.CardV[RI.Pop[m]]; IF op1 # 0 THEN RI.SetPc[m, savedPc + alpha]}; zJIB => { tab: RECORD [SELECT OVERLAID * FROM bytes => [bp: Bytes], ptr => [p: RI.LCB RELATIVE POINTER TO PACKED ARRAY [0..0) OF Byte], ENDCASE]; delta: LONG POINTER TO PACKED ARRAY [0..0) OF Byte; index, bound: CARDINAL; tab.bp.b1 _ RI.NextOpByte[m]; tab.bp.b2 _ RI.NextOpByte[m]; delta _ @LOOPHOLE[m.cb, RI.LCB][tab.p]; bound _ RI.CardV[RI.Pop[m]]; index _ RI.CardV[RI.Pop[m]]; IF index < bound THEN { alpha: Byte; RI.ReadAtAddress[m, delta + index/2]; alpha _ delta[index]; RI.SetPc[m, savedPc + alpha]}; }; zJIW => { tab: RECORD [SELECT OVERLAID * FROM bytes => [bp: Bytes], ptr => [p: RI.LCB RELATIVE POINTER TO ARRAY [0..0) OF INTEGER], ENDCASE]; delta: LONG POINTER TO ARRAY [0..0) OF INTEGER; index, bound: CARDINAL; tab.bp.b1 _ RI.NextOpByte[m]; tab.bp.b2 _ RI.NextOpByte[m]; delta _ @LOOPHOLE[m.cb, RI.LCB][tab.p]; bound _ RI.CardV[RI.Pop[m]]; index _ RI.CardV[RI.Pop[m]]; IF index < bound THEN { alpha: INTEGER; RI.ReadAtAddress[m, delta + index]; alpha _ delta[index]; RI.SetPc[m, savedPc + alpha]}; }; zADD, zADD01, zSUB, zMUL, zDBL, zDIV, zLDIV, zNEG, zINC, zAND, zOR, zXOR, zSHIFT => RI.DoShortArithmetic[m, op]; zDADD => { c2: LONG CARDINAL = RI.LCardV[RI.Pop2[m]]; c1: LONG CARDINAL = RI.LCardV[RI.Pop2[m]]; RI.Push2[m, RI.VLCard[c1+c2]]}; zDSUB => { c2: LONG CARDINAL = RI.LCardV[RI.Pop2[m]]; c1: LONG CARDINAL = RI.LCardV[RI.Pop2[m]]; RI.Push2[m, RI.VLCard[c1-c2]]}; zDCOMP => { c2: LONG INTEGER = RI.LIntV[RI.Pop2[m]]; c1: LONG INTEGER = RI.LIntV[RI.Pop2[m]]; Compare: PROC [x, y: LONG INTEGER] RETURNS [Value] = TRUSTED MACHINE CODE { PrincOps.zDCOMP}; RI.Push[m, Compare[c1,c2]]}; zDUCOMP => { c2: LONG CARDINAL = RI.LCardV[RI.Pop2[m]]; c1: LONG CARDINAL = RI.LCardV[RI.Pop2[m]]; UnsignedCompare: PROC [x, y: LONG CARDINAL] RETURNS [Value] = TRUSTED MACHINE CODE { PrincOps.zDUCOMP}; RI.Push[m, UnsignedCompare[c1,c2]]}; zEFC0, zEFC1, zEFC2, zEFC3, zEFC4, zEFC5, zEFC6, zEFC7, zEFC8, zEFC9, zEFC10, zEFC11, zEFC12, zEFC13, zEFC14, zEFC15, zEFCB => { lk: Byte = IF op = zEFCB THEN RI.NextOpByte[m] ELSE op-zEFC0; RI.WriteAtAddress[m, LONG[@LOOPHOLE[m.l, FrameHandle].pc]]; LOOPHOLE[m.l, FrameHandle].pc _ [m.pc]; RI.Xfer[m: m, dst: RI.FetchLink[m, lk], src: [frame[RI.FH[m.l]]]]}; zLFC1, zLFC2, zLFC3, zLFC4, zLFC5, zLFC6, zLFC7, zLFC8, zLFC9, zLFC10, zLFC11, zLFC12, zLFC13, zLFC14, zLFC15, zLFC16, zLFCB => { evi: CARDINAL = IF op = zLFCB THEN RI.NextOpByte[m] ELSE op-zLFC1+1; ev: EntryVectorItem; nlf: FrameHandle; nPc: CARDINAL; RI.WriteAtAddress[m, LONG[@LOOPHOLE[m.l, FrameHandle].pc]]; LOOPHOLE[m.l, FrameHandle].pc _ [m.pc]; RI.DoubleReadAtAddress[m, @LOOPHOLE[m.cb, LCB].entry[evi]]; ev _ LOOPHOLE[m.cb, LCB].entry[evi]; nPc _ ev.initialpc * 2; IF nPc = 0 THEN RI.UnboundProcTrap[m, RI.MakeProcDesc[m, LOOPHOLE[m.g], evi]]; nlf _ RI.AllocFrame[ev.info.framesize]; RI.WriteAtAddress[m, LONG[@nlf.accesslink]]; nlf.accesslink _ LOOPHOLE[m.g]; RI.WriteAtAddress[m, LONG[@nlf.returnlink]]; nlf.returnlink _ [frame[RI.FH[m.l]]]; nlf.pc _ [nPc+1]; -- for interpreter display of lf m.l _ LOOPHOLE[nlf]; RI.SetPc[m, nPc]}; zSFC => { RI.WriteAtAddress[m, LONG[@LOOPHOLE[m.l, FrameHandle].pc]]; LOOPHOLE[m.l, FrameHandle].pc _ [m.pc]; RI.Xfer[m: m, dst: LOOPHOLE[RI.Pop[m]], src: [frame[RI.FH[m.l]]]]}; zRET => { link: PrincOps.ControlLink = LOOPHOLE[m.l, FrameHandle].returnlink; RI.ReadAtAddress[m, LONG[@LOOPHOLE[m.l, FrameHandle].returnlink]]; IF link = RI.MagicReturn THEN SIGNAL RI.FinishedExecution; RI.Xfer[m: m, dst: link, src: NullLink, free: TRUE]}; zPORTO => { port: PortHandle _ LOOPHOLE[RI.Pop[m]]; RI.WriteAtAddress[m, LONG[@LOOPHOLE[m.l, FrameHandle].pc]]; LOOPHOLE[m.l, FrameHandle].pc _ [m.pc]; RI.WriteAtAddress[m, LONG[@port.frame]]; port.frame _ RI.FH[m.l]; RI.Xfer[m: m, dst: port.dest, src: LOOPHOLE[port]]}; zPORTI => { port: PortHandle _ LOOPHOLE[m.stack[m.sd+1]]; src: ControlLink _ LOOPHOLE[m.stack[m.sd]]; RI.WriteAtAddress[m, LONG[@port.frame]]; port.frame _ NIL; IF src # NullLink THEN { RI.WriteAtAddress[m, LONG[@port.dest]]; port.dest _ src}; }; zKFCB => { alpha: CARDINAL _ RI.NextOpByte[m]; link: ControlLink; SELECT alpha FROM sBLTEC, sBLTECL => { -- can't let these through as cb reg points to us data, const: LPtr1; equal: Value _ [1]; count: CARDINAL; const _ m.cb + RI.CardV[RI.Pop[m]]; count _ RI.CardV[RI.Pop[m]]; IF alpha = sBLTEC THEN { sp: Ptr1 _ RI.Ptr1V[RI.Pop[m]]; data _ sp} ELSE data _ RI.LPtr1V[RI.Pop2[m]]; THROUGH [0..count) DO IF RI.Read[m, data] # RI.Read[m, const] THEN GO TO false; data _ data + SIZE[Value]; const _ const + SIZE[Value]; REPEAT false => equal _ [0]; ENDLOOP; RI.Push[m, equal]}; sBYTBLTEC, sBYTBLTECL => SIGNAL StrangeCode; ENDCASE => { RI.ReadAtAddress[m, LONG[@SD[alpha]]]; link _ SD[alpha]; RI.WriteAtAddress[m, LONG[@LOOPHOLE[m.l, FrameHandle].pc]]; LOOPHOLE[m.l, FrameHandle].pc _ [m.pc]; RI.Xfer[m: m, dst: link, src: [frame[RI.FH[m.l]]]]}; }; zDESCB => { alpha: CARDINAL _ RI.NextOpByte[m]/2; -- Alto compatibility, I believe RI.Push[m, LOOPHOLE[RI.MakeProcDesc[m: m, gf: LOOPHOLE[m.g], entry: alpha]]]}; zDESCBS => { alpha: CARDINAL _ RI.NextOpByte[m]/2; -- Alto compatibility, I believe gf: GlobalFrameHandle _ LOOPHOLE[RI.Pop[m]]; RI.Push[m, LOOPHOLE[RI.MakeProcDesc[m: m, gf: gf, entry: alpha]]]}; zDST => { alpha: CARDINAL _ RI.NextOpByte[m]; st: POINTER TO StateVector = LOOPHOLE[m.l + alpha]; FOR i: CARDINAL IN [0..MIN[m.sd+2, PrincOps.stackDepth]) DO RI.StoreLocal[m, alpha +i]; st.stk[i] _ m.stack[i]; ENDLOOP; RI.StoreLocal[m, alpha + PrincOps.stackDepth]; st.stkptr _ m.sd; }; zLST => { RI.LoadState[m, FALSE]}; zLSTF => { RI.LoadState[m, TRUE]}; zALLOC => {RI.Push[m, LOOPHOLE[RI.AllocFrame[RI.CardV[RI.Pop[m]]]]]}; zFREE => {RI.FreeFrame[LOOPHOLE[RI.Pop[m]]]}; zLLKB => { alpha: CARDINAL _ RI.NextOpByte[m]; RI.Push[m, LOOPHOLE[RI.FetchLink[m, alpha]]]}; zBLT => { to: Ptr1 _ RI.Ptr1V[RI.Pop[m]]; nwords: CARDINAL _ RI.CardV[RI.Pop[m]]; from: Ptr1 _ RI.Ptr1V[RI.Pop[m]]; THROUGH [0..nwords) DO RI.Write[m, to, RI.Read[m, from]]; to _ to + SIZE[Value]; from _ from + SIZE[Value]; ENDLOOP; }; zBLTL => { to: LPtr1 _ RI.LPtr1V[RI.Pop2[m]]; nwords: CARDINAL _ RI.CardV[RI.Pop[m]]; from: LPtr1 _ RI.LPtr1V[RI.Pop2[m]]; THROUGH [0..nwords) DO RI.Write[m, to, RI.Read[m, from]]; to _ to + SIZE[Value]; from _ from + SIZE[Value]; ENDLOOP; }; zBLTC => { to: Ptr1 _ RI.Ptr1V[RI.Pop[m]]; nwords: CARDINAL _ RI.CardV[RI.Pop[m]]; delta: CARDINAL _ RI.CardV[RI.Pop[m]]; from: LPtr1 _ m.cb + delta; THROUGH [0..nwords) DO RI.Write[m, to, RI.Read[m, from]]; to _ to + SIZE[Value]; from _ from + SIZE[Value]; ENDLOOP; }; zBLTCL => { to: LPtr1 _ RI.LPtr1V[RI.Pop2[m]]; nwords: CARDINAL _ RI.CardV[RI.Pop[m]]; delta: CARDINAL _ RI.CardV[RI.Pop[m]]; from: LPtr1 _ m.cb + delta; THROUGH [0..nwords) DO RI.Write[m, to, RI.Read[m, from]]; to^ _ from^; to _ to + SIZE[Value]; from _ from + SIZE[Value]; ENDLOOP; }; zBITBLT => { DoBitBlt: PROC [Value] = TRUSTED MACHINE CODE {zBITBLT}; DoBitBlt[RI.Pop[m]]}; zIWDC => { NULL}; --SIGNAL StrangeCode zDWDC => { NULL}; --SIGNAL StrangeCode zSTOP => { SIGNAL StrangeCode}; zCATCH => { [] _ RI.NextOpByte[m]}; zMISC => DoMiscOp[m]; zSTARTIO => { SIGNAL StrangeCode}; zJRAM => { SIGNAL StrangeCode}; zWR => { SIGNAL StrangeCode}; zRR => { -- legal values are 0-8, each returns an UNSPECIFIED regVal: Value; alpha: Byte = RI.NextOpByte[m]; SELECT alpha FROM -- ugly, but since alpha is in the instruction stream ... 0 => regVal _ RR0[]; 1 => regVal _ RR1[]; 2 => regVal _ RR2[]; 3 => regVal _ RR3[]; 4 => regVal _ RR4[]; 5 => regVal _ RR5[]; 6 => regVal _ RR6[]; 7 => regVal _ RR7[]; 8 => regVal _ RR8[]; ENDCASE => SIGNAL StrangeCode; RI.Push[m, regVal]}; zBRK => {SIGNAL StrangeCode}; ENDCASE; IF m.singleStep OR (LOOPHOLE[m.g, CARDINAL] = LOOPHOLE[m.breakGF, CARDINAL] AND m.pc = m.breakPC) THEN EXIT; ENDLOOP; }; RR0: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 0}; RR1: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 1}; RR2: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 2}; RR3: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 3}; RR4: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 4}; RR5: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 5}; RR6: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 6}; RR7: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 7}; RR8: PROC RETURNS [Value] = TRUSTED MACHINE CODE {zRR, 8}; aLocalZERO: CARDINAL = 103B; --? DoASSOC: PROC [vp: CARDINAL, m: MapFlags] = TRUSTED MACHINE CODE {zMISC, aASSOC}; DoSETF: PROC [vp: CARDINAL, new: MapFlags] RETURNS [old: UNSPECIFIED] = TRUSTED MACHINE CODE {zMISC, aSETF}; DoLOADRAMJ: PROC [item: LONG POINTER, flag: BOOL] = TRUSTED MACHINE CODE {zMISC, aLOADRAMJ}; DoINPUT: PROC [device: CARDINAL] RETURNS [CARDINAL] = TRUSTED MACHINE CODE {zMISC, aINPUT}; DoOUTPUT: PROC [data, device: CARDINAL] = TRUSTED MACHINE CODE {zMISC, aOUTPUT}; DoCHKSUM: PROC [s: CARDINAL, count: CARDINAL, p: LONG POINTER] RETURNS [CARDINAL] = TRUSTED MACHINE CODE {zMISC, aCHKSUM}; DoSETMP: PROC [CARDINAL] = TRUSTED MACHINE CODE {zMISC, aSETMP}; DoRCLK: PROC RETURNS [LONG CARDINAL] = TRUSTED MACHINE CODE {zMISC, aRCLK}; DoRPRINTER: PROC RETURNS [CARDINAL] = TRUSTED MACHINE CODE {zMISC, aRPRINTER}; DoWPRINTER: PROC [CARDINAL] = TRUSTED MACHINE CODE {zMISC, aWPRINTER}; DoGETF: PROC [vp: CARDINAL] RETURNS [MapEntry] = TRUSTED MACHINE CODE {zMISC, aGETF}; DoFADD: PROC [REAL, REAL] RETURNS [REAL] = TRUSTED MACHINE CODE {zMISC, aFADD}; DoFSUB: PROC [REAL, REAL] RETURNS [REAL] = TRUSTED MACHINE CODE {zMISC, aFSUB}; DoFMUL: PROC [REAL, REAL] RETURNS [REAL] = TRUSTED MACHINE CODE {zMISC, aFMUL}; DoFDIV: PROC [REAL, REAL] RETURNS [REAL] = TRUSTED MACHINE CODE {zMISC, aFDIV}; DoFCOMP: PROC [x, y: REAL] RETURNS [INTEGER] = TRUSTED MACHINE CODE {zMISC, aFCOMP}; DoFIX: PROC [REAL] RETURNS [INT] = TRUSTED MACHINE CODE {zMISC, aFIX}; DoFLOAT: PROC [INT] RETURNS [REAL] = TRUSTED MACHINE CODE {zMISC, aFLOAT}; DoFIXI: PROC [REAL] RETURNS [INTEGER] = TRUSTED MACHINE CODE {zMISC, aFIXI}; DoFIXC: PROC [REAL] RETURNS [CARDINAL] = TRUSTED MACHINE CODE {zMISC, aFIXC}; DoFSTICKY: PROC [WORD] RETURNS [WORD] = TRUSTED MACHINE CODE {zMISC, aFSTICKY}; DoFREM: PROC [REAL, REAL] RETURNS [REAL] = TRUSTED MACHINE CODE {zMISC, aFREM}; DoROUND: PROC [REAL] RETURNS [INT] = TRUSTED MACHINE CODE {zMISC, aROUND}; DoROUNDI: PROC [REAL] RETURNS [INTEGER] = TRUSTED MACHINE CODE {zMISC, aROUNDI}; DoROUNDC: PROC [REAL] RETURNS [CARDINAL] = TRUSTED MACHINE CODE {zMISC, aROUNDC}; DoFSQRT: PROC [REAL] RETURNS [REAL] = TRUSTED MACHINE CODE {zMISC, aFSQRT}; DoFSC: PROC [REAL, INTEGER] RETURNS [REAL] = TRUSTED MACHINE CODE {zMISC, aFSC}; DoLocalZERO: PROC [count: CARDINAL] = TRUSTED MACHINE CODE {zMISC, aLocalZERO}; DoZERO: PROC [lp: LONG POINTER, count: CARDINAL] RETURNS [LONG POINTER] = TRUSTED MACHINE CODE {zMISC, aZERO}; DoVERSION: PROC RETURNS [LONG CARDINAL] = TRUSTED MACHINE CODE {zMISC, aVERSION}; MapFlags: TYPE = UNSPECIFIED; MapEntry: TYPE = UNSPECIFIED; DoMiscOp: PROC [m: Machine] = TRUSTED { OPEN CM: CedarMicrocode; alpha: Byte = RI.NextOpByte[m]; SELECT alpha FROM aASSOC => { p2: UNSPECIFIED = RI.Pop[m]; p1: UNSPECIFIED = RI.Pop[m]; DoASSOC[p1, p2]}; aSETF => { p2: UNSPECIFIED = RI.Pop[m]; p1: UNSPECIFIED = RI.Pop[m]; RI.Push[m, LOOPHOLE[DoSETF[p1, p2]]]}; aLOADRAMJ => { p2: UNSPECIFIED = RI.Pop[m]; p1: LONG POINTER = LOOPHOLE[RI.Pop2[m]]; DoLOADRAMJ[p1, p2]}; aINPUT => { p1: UNSPECIFIED = RI.Pop[m]; RI.Push[m, LOOPHOLE[DoINPUT[p1]]]}; aOUTPUT => { p2: UNSPECIFIED = RI.Pop[m]; p1: UNSPECIFIED = RI.Pop[m]; DoOUTPUT[p1, p2]}; aCHKSUM => { p3: LONG POINTER = LOOPHOLE[RI.Pop2[m]]; p2: UNSPECIFIED = RI.Pop[m]; p1: UNSPECIFIED = RI.Pop[m]; RI.Push[m, LOOPHOLE[DoCHKSUM[p1, p2, p3]]]}; aSETMP => { p1: UNSPECIFIED = RI.Pop[m]; DoSETMP[p1]}; aRCLK => { RI.Push2[m, LOOPHOLE[DoRCLK[]]]}; aRPRINTER => { RI.Push[m, LOOPHOLE[DoRPRINTER[]]]}; aWPRINTER => { p1: UNSPECIFIED = RI.Pop[m]; DoWPRINTER[p1]}; aGETF => { p1: UNSPECIFIED = RI.Pop[m]; RI.Push[m, LOOPHOLE[DoGETF[p1]]]}; aFADD, aFSUB, aFMUL, aFDIV, aFREM => { p2: REAL = LOOPHOLE[RI.Pop2[m]]; p1: REAL = LOOPHOLE[RI.Pop2[m]]; res: REAL; SELECT alpha FROM aFADD => res _ DoFADD[p1, p2]; aFSUB => res _ DoFSUB[p1, p2]; aFMUL => res _ DoFMUL[p1, p2]; aFDIV => res _ DoFDIV[p1, p2]; aFREM => res _ DoFREM[p1, p2]; ENDCASE; RI.Push2[m, LOOPHOLE[res]]}; aFIXI, aFIXC, aROUNDI, aROUNDC => { par: REAL = LOOPHOLE[RI.Pop2[m]]; res: UNSPECIFIED; SELECT alpha FROM aFADD => res _ DoFIXI[par]; aFSUB => res _ DoFIXC[par]; aFMUL => res _ DoROUNDI[par]; aFDIV => res _ DoROUNDC[par]; ENDCASE; RI.Push[m, LOOPHOLE[res]]}; aFCOMP => { p2: REAL = LOOPHOLE[RI.Pop2[m]]; p1: REAL = LOOPHOLE[RI.Pop2[m]]; res: INTEGER = DoFCOMP[p1, p2]; RI.Push[m, LOOPHOLE[res]]}; aFSQRT => { p1: REAL = LOOPHOLE[RI.Pop2[m]]; res: REAL; res _ DoFSQRT[p1]; RI.Push2[m, LOOPHOLE[res]]}; aFLOAT => { p1: INT = LOOPHOLE[RI.Pop2[m]]; res: REAL; res _ DoFLOAT[p1]; RI.Push2[m, LOOPHOLE[res]]}; aFIX, aROUND => { p1: REAL = LOOPHOLE[RI.Pop2[m]]; res: INT; SELECT alpha FROM aFIX => res _ DoFIX[p1]; aROUND => res _ DoROUND[p1]; ENDCASE; RI.Push2[m, LOOPHOLE[res]]}; aFSTICKY => { p1: UNSPECIFIED = RI.Pop[m]; RI.Push[m, LOOPHOLE[DoFSTICKY[p1]]]}; aFSC => { p2: UNSPECIFIED = RI.Pop[m]; p1: REAL = LOOPHOLE[RI.Pop2[m]]; RI.Push2[m, LOOPHOLE[DoFSC[p1, p2]]]}; aLocalZERO => { p1: UNSPECIFIED = RI.Pop[m]; DoLocalZERO[p1]}; aZERO => { p2: UNSPECIFIED = RI.Pop[m]; p1: LONG POINTER = LOOPHOLE[RI.Pop2[m]]; RI.Push2[m, LOOPHOLE[DoZERO[p1, p2]]]}; aVERSION => { RI.Push2[m, LOOPHOLE[DoVERSION[]]]}; CM.aRECLAIMEDREF => { r: REF = LOOPHOLE[RI.Pop2[m]]; RI.Push2[m, LOOPHOLE[CM.RECLAIMEDREF[r]]]; }; CM.aENABLEMICROCODE => TRUSTED { zct: LONG POINTER = LOOPHOLE[RI.Pop2[m]]; n: NAT = CM.ENABLEMICROCODE[zct]; RI.Push[m, LOOPHOLE[n]]; }; CM.aDISABLEMICROCODE => { zct: LONG POINTER = LOOPHOLE[RI.Pop2[m]]; CM.DISABLEMICROCODE[zct]; }; CM.aCREATEREF => { nhp: LONG POINTER = LOOPHOLE[RI.Pop2[m]]; CM.CREATEREF[nhp]; }; CM.aRECLAIMABLEREF => { nhp: LONG POINTER = LOOPHOLE[RI.Pop2[m]]; cd: UNSPECIFIED _ CM.RECLAIMABLEREF[nhp]; RI.Push[m, LOOPHOLE[cd]]; }; CM.aALLOCATEOBJECT => { type: UNSPECIFIED = RI.Pop[m]; size: CARDINAL = RI.CardV[RI.Pop[m]]; r: REF = CM.ALLOCATE[size, type]; RI.Push2[m, LOOPHOLE[r]]; }; CM.aFREEOBJECT => { nhp: LONG POINTER = LOOPHOLE[RI.Pop2[m]]; success: BOOL = CM.FREEPLEASE[nhp]; RI.Push[m, LOOPHOLE[success]]; }; CM.aRTMOVESTATUS => { gcStateBank: CARDINAL = RI.CardV[RI.Pop[m]]; msOperation: CARDINAL = RI.CardV[RI.Pop[m]]; val: CARDINAL = CM.RTMOVESTATUS[msOperation, gcStateBank]; RI.Push[m, RI.VCard[val]]; }; CM.aGETCANONICALREFERENTTYPE => { ref: REF = LOOPHOLE[RI.Pop2[m]]; type: UNSPECIFIED = CM.GETCANONICALREFERENTTYPE[ref]; RI.Push[m, type]; }; ENDCASE => ERROR StrangeCode}; }. alpha=240b Zero and Enable Event counters alpha=241b Read Event counters alpha=242b Stop Event counters alpha=243b Set PC Histogram Address alpha=244b Unused alpha=245b Unused alpha=246b Read/write muffler/manifold system alpha=247b Reset Ethernet hardware and tasks (PrincOps only) alpha=250B Reset 10MBEthernet hardware and tasks (PrincOps only) alpha=251B Get size of real and virtual memory alpha=252B Halt Dorado (for timed power-off) alpha=253B Set display field rate alpha=254b Reset disk hardware and task (PrincOps only) alpha=255b Set interval timer (PrincOps only) alpha=256b Stable Storage block input alpha=257b Stable Storage block output ΈRESIDisp.mesa Last Edited by: Sweet, March 7, 1985 3:05:08 pm PST Types and Global Data Instruction execution savedSP: CARDINAL = m.sd; Most popular operations, avoiding an extra procedure call Monitor stuff Loads & Stores of Locals Loads & Stores of Globals Loads of Constants Reads from pointer on stack Writes from pointer on stack Read and write string Read indirect through locals Write indirect through locals Write Swapped Field descriptor on stack Random stack operations StoreLocal[localbase]; Jumps Short arithmetic Long arithmetic Function call compiler doesn't generate the next two. Block Transfer Punt memory reference statistics Random others Why are we disabling interrupts Enabling interrupts is a little more socially acceptable I think this is ALTO only Treat as a two byte NOOP I think this is ALTO only I think this is ALTO only I think this is ALTO only Machine codes for read register Machine codes for misc operations Κ!%˜Icodešœ ™ K™3K˜šΟk ˜ K˜K˜ K˜K˜K˜ K˜—šœ  œ˜Kšœœ˜4Kšœ˜—Kšœ ˜šœ™Kšœœœ˜Kšœœœ ˜Kšœœœ˜Kšœœœ˜Kšœœœ˜Kšœœœ˜Kšœœœœ˜K˜šœ œœ ˜K˜—Kšœœœ˜Kšœœœ˜Kšœœœ˜šœœ˜1K˜—Kšœ œœœ˜"K˜K˜—šœ™šΟnœœœœ˜-Kšœœ ˜K˜ šœ œ˜K˜K˜—š˜Kšœ œ˜Kšœ™Kšœ ˜ Kšœœœ˜Kšœ œ#˜5K˜K˜šœ œ˜Kš œœœœœœœ ˜7Kšœœ˜Kšœ1œ˜Ešœœœ ˜K˜Kšœ˜—š œ œœœ˜2Kšœ˜Kšœ:˜:Kšœ˜—K˜Kšœœœ˜/Kšœœœœ˜N—K˜šœ˜šœ9™9Kšœ-œ œ˜NKšœ œ œœ˜1˜ Jšœœœ˜Jšœ œœœ ˜6—˜ Jšœ œœ ˜!Jšœœœ˜Jšœœœ˜1Jšœ œ˜&—˜ Jšœ œœ˜&Jšœ ˜ Jšœ.˜0Jšœœœ)˜?Jšœ œ˜!—K˜—šœ ™ šœ;˜;Kšœ˜——šœ™˜3Jšœœ ˜Jšœœœ"˜/Jšœ˜Jšœ˜—˜ Jšœœœ˜Jšœœœ˜Jšœ˜Jšœ˜—˜ Jšœœœ˜Jšœœœ œ˜'Jšœ˜Jšœ˜—˜3Jšœœ ˜Jšœœœ"˜/Jšœ˜Jšœœ ˜—˜ Jšœœœ˜Jšœœœ˜Jšœ˜Jšœœ ˜—˜ Jšœœœ˜Jšœœœ œ˜'Jšœ˜Jšœœ ˜—˜Jšœœ ˜Jšœœœ"˜/Jšœ˜Jšœœ ˜——šœ™šœd˜dKšœ˜——šœ™šœc˜cKšœ˜——šœ™šœD˜DKšœ˜——šœ™šœJ˜JKšœ˜——™˜ Kšœœœ˜Kšœœœœ ˜"Kšœ œœ ˜šœ˜Kšœœœ˜5Kšœ˜#—Kšœ œœ˜2—šœ ˜ Kšœœœ˜Kšœœœœ ˜"Kšœ œœ ˜Kšœ œ˜šœ˜Kšœœœ˜5Kšœ˜#—Kšœœ˜*—˜ Kšœœœ˜Kšœœœœ ˜"Kšœ œœ ˜!šœ˜Kšœœœ˜5Kšœ˜#—Kšœ œ˜,—˜ Kšœœœ˜Kšœœœœ ˜"Kšœ œœ ˜!Kšœ œ˜šœ˜Kšœœœ˜5Kšœ˜#—Kšœ"˜$——™Kšœ>œ˜[—™Kšœ0œ˜M—™ Kšœœ˜7—šœ Οc˜#Kšœœœ˜Kšœœœ˜1Kš œœœœœ ˜1Kšœ œ˜$—™˜ Kšœœœ ˜*Kšœ œœ ˜Kšœ!˜!Kšœ œœ ˜*—˜ Kšœœœ ˜*Kšœ œœ ˜!Kšœ!˜!Kšœ œ˜$—˜ Kšœœœ ˜*Kšœ œœ ˜Kšœ!˜!Kšœœ œ ˜*—˜ Kšœœœ ˜*Kšœ œœ ˜!Kšœ!˜!Kšœœ ˜$——™˜Kš œ œœœœ ˜3—˜ K˜—˜ K˜—˜ K˜K˜"K˜—˜ K˜ K˜—˜ Kš œœœœœ˜8—šœ ˜ Kšœœœœœœœœ˜\—˜ Kšœœœœ ˜&Kšœœ!œœ˜>—˜ Kšœœœ˜#Kšœ œœ˜1Kšœ™Kšœœ˜4——™˜+Kšœœ˜K˜—˜Kšœœœ˜$K˜—˜šœœœœ˜%Kšœ œ˜Kšœ œ˜Kšœ˜ —Kšœœ˜Kšœœ˜Kšœ ˜ —šœ;˜;Kšœœ˜ Kšœœœœ ˜$Kšœœœœ ˜$Kšœ œ˜0—˜;Kšœœ˜ Kšœœœœ ˜$Kšœœœœ ˜$Kšœ œ˜0—Kšœœ˜