<> <> <> <> DIRECTORY DragomanOpDebug, DragomanPrivate, CedarMicrocode, ListerUtils, PrincOps; DragomanDisp: CEDAR PROGRAM IMPORTS CedarMicrocode, DragomanOpDebug, RI: DragomanPrivate EXPORTS DragomanPrivate = { 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 _ DragomanOpDebug.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 _ LOOPHOLE[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 <<>> <<>>