--EU.Mesa --created by RoseTranslate from EU.Rose of June 18, 1984 2:56:55 pm PDT for monier.pa at June 18, 1984 3:01:51 pm PDT DIRECTORY RoseTypes, RoseCreate, Rope, DragOpsCross, Atom, IO, BitOps, Cucumber, Dragon, RoseRun, CacheOps, DragOpsCrossUtils, NumTypes, EUPorts, EURam, EURegs, EUAlu, EUField; EU: CEDAR PROGRAM IMPORTS RoseCreate, Atom, IO, BitOps, Cucumber, Dragon, RoseRun, RoseTypes, CacheOps, DragOpsCrossUtils, NumTypes, EUPorts, EURam, EURegs, EUAlu, EUField = BEGIN OPEN RoseTypes; --Signal Type decls PBusFaults: TYPE = Dragon.PBusFaults; ALUOps: TYPE = Dragon.ALUOps; CondSelects: TYPE = Dragon.CondSelects; RegisterCells: PROC = BEGIN CreateEUPorts[]; [] _ RoseCreate.RegisterCellClass[className: "EU", expandProc: EUExpand, ioCreator: CreateEUIO, initializer: InitializeEU, evals: [], blackBox: NIL, stateToo: NIL, ports: EUPorts, drivePrototype: NEW [EUDrive]]; END; --explicitly requested CEDAR: mdfAdr: INTEGER = PRtoByte[euMDF]; mqAdr: INTEGER = PRtoByte[euMQ]; marAdr: INTEGER = PRtoByte[euMAR]; AllOnes: Dragon.HexWord = 0FFFFFFFFH; -- used for generating masks ALUOpcode: TYPE = {Add, Sub, Or, And, Xor}; ShiftOpcode: TYPE = {Sh2R, Sh1L, ShNop}; WriteDest: TYPE = {Ram, KBus, NoWhere}; Remark: PROC [ message: Rope.ROPE ] = {RoseRun.DisableableStop[Remark, message]}; ALUOp: PROC[aluLeft, aluRight: Dragon.HexWord, opcode: ALUOpcode, shift: ShiftOpcode, carryin: BOOL] RETURNS [result1: Dragon.HexWord, c32: BOOL, preShiftResult1: Dragon.HexWord] = BEGIN SELECT opcode FROM Add => [result1, c32] _ DoubleADD[aluLeft, aluRight, carryin]; Sub => [result1, c32] _ DoubleSUB[aluLeft, aluRight, carryin]; Or => {result1 _ WordOp[or, aluLeft, aluRight]; c32 _ FALSE}; And => {result1 _ WordOp[and, aluLeft, aluRight]; c32 _ FALSE}; Xor => {result1 _ WordOp[xor, aluLeft, aluRight]; c32 _ FALSE}; ENDCASE => ERROR Stop["Invalid ALU Opcode"]; END; FieldOp: PROC[aluLeft, aluRight, fieldDesc: Dragon.HexWord] RETURNS [result: Dragon.HexWord] = BEGIN shiftout, maskhole: Dragon.HexWord; fd: DragOpsCross.FieldDescriptor _ DragOpsCrossUtils.CardToFieldDescriptor[fieldDesc MOD 65536]; shiftout _ ShiftLeft2LtoL[aluLeft, aluRight, fd.shift]; maskhole _ ShiftRight2LtoL[0, AllOnes, 32-fd.mask]; --The default mask has fd.mask 1's right-justified in the word IF fd.insert THEN maskhole _ WordOp[xor, maskhole, ShiftLeft2LtoL[0, AllOnes, fd.shift]]; --fd.insert => invert rightmost fd.shift bits of the mask result _ IF fd.insert THEN WordOp[or, WordOp[and, maskhole, shiftout], WordOp[and, WordOp[not, maskhole], aluRight]] ELSE WordOp[and, maskhole, shiftout]; END; --Generate the appropriate multiple of mdf (0, 1, or 2). An Add or Sub is generated independantly MultPhA: PROC[mdf, mqAB: Dragon.HexWord, mq32: BOOL] RETURNS [multiple: Dragon.HexWord] = BEGIN n: CARDINAL _ 4*BoolToCard[EBFL[mqAB, 30]]+2*BoolToCard[EBFL[mqAB, 31]]+BoolToCard[mq32]; multiple _ SELECT n FROM 0,7 => 0, -- zero 1,2,5,6 => mdf, -- one 3,4 => DoubleADD[mdf, mdf, FALSE].sl, -- two ENDCASE => ERROR; END; --Returns a+b+carry and c32, where a and b are considered to be signed numbers DoubleADD: PROC[al, bl: Dragon.HexWord, carry: BOOL] RETURNS [sl: Dragon.HexWord, c32: BOOL] = { Xor: PROC[x, y: BOOL] RETURNS [z: BOOL] = {RETURN[(x AND NOT y) OR (y AND NOT x)]}; ai, bi: BOOL; s: BOOL _ FALSE; c: BOOL _ carry; i: INTEGER; sum: BitOps.BitDWord _ [0,0]; FOR i IN [1..32] DO ai _ EBFL[al, 32-i]; bi _ EBFL[bl, 32-i]; s _ Xor[ai, Xor[bi, c]]; c _ (ai AND bi) OR (bi AND c) OR (ai AND c); sum _ BitOps.IBID[s, sum, 32, 32-i]; ENDLOOP; RETURN[LFD[sum], c]}; --Returns a-b-carry and c32, where a and b are considered to be signed numbers --Implemented as a+(~b)+1+(~carry) DoubleSUB: PROC[a, b: Dragon.HexWord, carry: BOOL] RETURNS [dif: Dragon.HexWord, c32: BOOL] ={ [dif, c32] _ DoubleADD[a, WordOp[not,b], NOT carry]}; SelectALUOpcode: PROC[EUAluOpAB: Dragon.ALUOps, multSUb: BOOL] RETURNS[opcodeForALU: ALUOpcode] = BEGIN opcodeForALU _ SELECT EUAluOpAB FROM SAdd, UAdd, VAdd, LAdd => Add, SSub, USub, VSub, LSub, BndChk, DivStep => Sub, And => And, Or, FOP, FOPK => Or, -- field unit ops ??? Xor => Xor, MulStep => IF multSUb THEN Sub ELSE Add, ENDCASE => ERROR Stop["Invalid ALU Operation"]; END; SelectShifterOpcode: PROC[EUAluOpAB: Dragon.ALUOps] RETURNS[opcodeForShifter: ShiftOpcode] = BEGIN opcodeForShifter _ SELECT EUAluOpAB FROM MulStep => Sh2R, DivStep => Sh1L, ENDCASE => ShNop; END; SelectCarryIn: PROC[EUAluOpAB: Dragon.ALUOps, carryAB: BOOL] RETURNS[carryIn: BOOL] = BEGIN carryIn _ SELECT EUAluOpAB FROM VAdd, VSub, LAdd, LSub, And, Or, Xor, BndChk, MulStep, DivStep => FALSE, SAdd, SSub, UAdd, USub => carryAB, FOP, FOPK => carryAB, -- check ??? ENDCASE => ERROR Stop["Invalid ALU Operation"]; END; SelectCarryOut: PROC[EUAluOpAB: Dragon.ALUOps, c32, carryAB: BOOL] RETURNS[carryOut: BOOL] = BEGIN carryOut _ SELECT EUAluOpAB FROM SAdd, SSub, LAdd, LSub, MulStep, DivStep => FALSE, UAdd, USub => c32, VAdd, VSub, FOP, FOPK, And, Or, Xor, BndChk => carryAB, ENDCASE => ERROR Stop["Invalid ALU Operation"]; END; ComputeCC: PROC[result1, aluLeft, aluRight: Dragon.HexWord, overflow: BOOL, EUCondSelAB: Dragon.CondSelects] RETURNS [conditionB: BOOL] = BEGIN conditionB _ SELECT EUCondSelAB FROM EZ => result1=0, -- result1=0 LZ => EBFL[result1, 0], -- result1<0 by checking the high-order bit LE => (result1=0) OR EBFL[result1, 0], -- result1<=0, OvFl => overflow, BC => NOT (NOT EBFL[aluLeft, 0] -- 0<=arg -- AND EBFL[result1, 0] -- arg-limit<0 --), IL => (EBFL[aluLeft, 0]#EBFL[aluLeft, 1]) OR (EBFL[aluRight, 0]#EBFL[aluRight, 1]) OR (EBFL[result1, 0]#EBFL[result1, 1]), False => FALSE, NE => result1#0, -- result1#0 GE => NOT EBFL[result1, 0], -- result1>=0 by checking the high-order bit GZ => NOT ((result1=0) OR EBFL[result1, 0]), -- result1>0, NotOvFl => NOT overflow, NotBC => NOT EBFL[aluLeft, 0] -- 0<=arg -- AND EBFL[result1, 0] -- arg-limit<0 --, NotIL => NOT ((EBFL[aluLeft, 0]#EBFL[aluLeft, 1]) OR (EBFL[aluRight, 0]#EBFL[aluRight, 1]) OR (EBFL[result1, 0]#EBFL[result1, 1])), True => TRUE, ENDCASE => ERROR Stop["Invalid EUConditionBA Code"]; END; --Here we compute the overflow by checking the high-order bits of the operands (aluLeft and aluRight or - aluRight) and of the result. The actual implementation will use the last carry (c32) and c31. ComputeOverflow: PROC[aluLeft, aluRight, result1: Dragon.HexWord, EUAluOpAB: Dragon.ALUOps] RETURNS [overflow: BOOL] = BEGIN PlusOrMinusAluRight: Dragon.HexWord; SELECT EUAluOpAB FROM SSub, USub, VSub, LSub, BndChk => [PlusOrMinusAluRight, ] _ DoubleSUB[0, aluRight, FALSE]; ENDCASE => PlusOrMinusAluRight _ aluRight; overflow _ (EBFL[aluLeft, 0] = EBFL[PlusOrMinusAluRight, 0]) AND (EBFL[aluLeft, 0] # EBFL[result1, 0]); END; WriteCBus: PROC[cAdr: Dragon.HexByte, rejectBA, faultBA: BOOL] RETURNS [address: Dragon.HexByte, whereToWrite: WriteDest] = BEGIN SELECT TRUE FROM --The last cycle of a faulty cache access: rejectBA and EPFaultB are both high rejectBA AND faultBA => { address _ marAdr; whereToWrite _ Ram}; -- save the faulty address in a fixed location --The normal reject case rejectBA AND NOT faultBA => { whereToWrite _ NoWhere}; -- --The normal case (NOT rejectBA) AND (cAdr IN [PRtoByte[euStack] .. PRtoByte[euConstant]+12)) => { address _ cAdr; whereToWrite _ Ram}; -- --We send a value back to the IFU through KBus, so no write in the RAM (NOT rejectBA) AND (cAdr IN [PRtoByte[ifuXBus] .. PRtoByte[ifuLast]]) => { whereToWrite _ KBus}; --The bug ENDCASE => Dragon.Assert[FALSE, "EU cAdr out of range"]; END; PRtoByte: PROC[pr:DragOpsCross.ProcessorRegister] RETURNS [byte:Dragon.HexByte] = {byte _ LOOPHOLE[pr]}; AdFromK: PROC[KBus: BitOps.BitDWord] RETURNS [aAdr, bAdr, cAdr: Dragon.HexByte] = {aAdr _ BitOps.ECFD[KBus, 32, 0, 8]; Dragon.Assert[aAdr IN [0..164)]; bAdr _ BitOps.ECFD[KBus, 32, 8, 8]; Dragon.Assert[bAdr IN [0..164)]; cAdr _ BitOps.ECFD[KBus, 32, 16, 8]; }; WordOp: PROC[op:{not, or, and, xor}, left, right:Dragon.HexWord _ 0] RETURNS[result:Dragon.HexWord] = { RETURN[LFD[SELECT op FROM not => BitOps.DNOT [LTD[left], 32], or => BitOps.DOR [LTD[left], LTD[right]], and => BitOps.DAND [LTD[left], LTD[right]], xor => BitOps.DXOR [LTD[left], LTD[right]], ENDCASE => ERROR]] }; EBFL: PROC[word:Dragon.HexWord, index:CARDINAL] RETURNS[BOOL] = { RETURN[ BitOps.EBFD[LTD[word], 32, index]] }; IBIL: PROC[word:Dragon.HexWord, bit:BOOL, index:CARDINAL] RETURNS[Dragon.HexWord] = { RETURN[ LFD[BitOps.IBID[bit, LTD[word], 32, index]]] }; LTD: PROC[word:Dragon.HexWord] RETURNS[BitOps.BitDWord] = { RETURN[ BitOps.ILID[word,[0,0],32,0,32]] }; LFD: PROC[bdw:BitOps.BitDWord] RETURNS[Dragon.HexWord] = { RETURN[ BitOps.ELFD[bdw,32,0,32]] }; BoolToCard: PROC[bit:BOOL] RETURNS[CARDINAL] = { RETURN[ IF bit THEN 1 ELSE 0] }; --this shift used by multiplier: index=0 => shiftout _ right ShiftRight2LtoL: PROC[left, right:Dragon.HexWord, index:CARDINAL] RETURNS[shiftout:Dragon.HexWord] = BEGIN temp: BitOps.BitDWord; SELECT index FROM 0 => shiftout _ right; 32 => shiftout _ left; IN [1..32) => {temp _ BitOps.MDTD[LTD[right], 32, 0, 32-index, temp, 32, index, 32-index]; temp _ BitOps.MDTD[LTD[left], 32, 32-index, index, temp, 32, 0, index]; shiftout _ LFD[temp]}; ENDCASE => ERROR; END; --this shift used by divider: index=0 => shiftout _ left ShiftLeft2LtoL: PROC[left, right:Dragon.HexWord, index:CARDINAL] RETURNS[shiftout:Dragon.HexWord] = BEGIN temp: BitOps.BitDWord; SELECT index FROM 0 => shiftout _ left; 32 => shiftout _ right; IN [1..32) => {temp _ BitOps.MDTD[LTD[right], 32, 0, index, temp, 32, 32-index, index]; temp _ BitOps.MDTD[LTD[left], 32, index, 32-index, temp, 32, 0, 32-index]; shiftout _ LFD[temp]}; ENDCASE => ERROR; END; CreateEUPorts: PROC = {EUPorts _ RoseCreate.PortsFromFile["EU.EU.rosePorts"]}; EUIORef: TYPE = REF EUIORec; EUIORec: TYPE = MACHINE DEPENDENT RECORD [ EPData(0:0..31): ARRAY [0..2) OF CARDINAL, fill1(2:0..14): [0..32767], EPRejectB(2:15..15): BOOLEAN, fill2(3:0..12): [0..8191], EPFaultB(3:13..15): PBusFaults, fill3(4:0..14): [0..32767], EPParityB(4:15..15): BOOLEAN, fill4(5:0..14): [0..32767], EPNPErrorB(5:15..15): BOOLEAN, fill5(6:0..14): [0..32767], PhA(6:15..15): BOOLEAN, fill6(7:0..14): [0..32767], PhB(7:15..15): BOOLEAN, fill7(8:0..14): [0..32767], ResetAB(8:15..15): BOOLEAN, fill8(9:0..14): [0..32767], Vdd(9:15..15): BOOLEAN, fill9(10:0..14): [0..32767], Gnd(10:15..15): BOOLEAN, fill10(11:0..14): [0..32767], PadVdd(11:15..15): BOOLEAN, fill11(12:0..14): [0..32767], PadGnd(12:15..15): BOOLEAN, KBus(13:0..31): ARRAY [0..2) OF CARDINAL, fill13(15:0..14): [0..32767], EUAluLeftisR1BA(15:15..15): BOOLEAN, fill14(16:0..14): [0..32767], EUAluLeftisR3BA(16:15..15): BOOLEAN, fill15(17:0..14): [0..32767], EUAluRightisKBA(17:15..15): BOOLEAN, fill16(18:0..14): [0..32767], EUAluRightisR1BA(18:15..15): BOOLEAN, fill17(19:0..14): [0..32767], EUAluRightisR3BA(19:15..15): BOOLEAN, fill18(20:0..14): [0..32767], EUS1isR1BA(20:15..15): BOOLEAN, fill19(21:0..14): [0..32767], EUS1isR3BA(21:15..15): BOOLEAN, fill20(22:0..14): [0..32767], EUR2isR3BA(22:15..15): BOOLEAN, fill21(23:0..14): [0..32767], EUS3isR3BA(23:15..15): BOOLEAN, fill22(24:0..14): [0..32767], EUHoldCarryBA(24:15..15): BOOLEAN, fill23(25:0..14): [0..32767], EUR3isR2AB(25:15..15): BOOLEAN, fill24(26:0..14): [0..32767], EUWriteToCacheAB(26:15..15): BOOLEAN, fill25(27:0..10): [0..2047], EUAluOpAB(27:11..15): ALUOps, fill26(28:0..11): [0..4095], EUCondSelAB(28:12..15): CondSelects, fill27(29:0..14): [0..32767], EUTrapBA(29:15..15): BOOLEAN, fill28(30:0..14): [0..32767], EUConditionBA(30:15..15): BOOLEAN, InstrCountAB(31:0..31): ARRAY [0..2) OF CARDINAL, fill30(33:0..14): [0..32767], DShiftAB(33:15..15): BOOLEAN, fill31(34:0..14): [0..32767], DExecuteAB(34:15..15): BOOLEAN, fill32(35:0..14): [0..32767], DNSelectAB(35:15..15): BOOLEAN, fill33(36:0..14): [0..32767], DHoldAB(36:15..15): BOOLEAN, fill34(37:0..14): [0..32767], DDataInAB(37:15..15): BOOLEAN, fill35(38:0..14): [0..32767], DDataOutAB(38:15..15): BOOLEAN]; -- port indices: EUDrive: TYPE = MACHINE DEPENDENT RECORD [ fill0(0:0..14): [0 .. 32768), EPData(0:15..15): BOOLEAN, fill1(1:0..14): [0 .. 32768), EPRejectB(1:15..15): BOOLEAN, fill2(2:0..14): [0 .. 32768), EPFaultB(2:15..15): BOOLEAN, fill3(3:0..14): [0 .. 32768), EPParityB(3:15..15): BOOLEAN, fill4(4:0..14): [0 .. 32768), EPNPErrorB(4:15..15): BOOLEAN, fill5(5:0..14): [0 .. 32768), PhA(5:15..15): BOOLEAN, fill6(6:0..14): [0 .. 32768), PhB(6:15..15): BOOLEAN, fill7(7:0..14): [0 .. 32768), ResetAB(7:15..15): BOOLEAN, fill8(8:0..14): [0 .. 32768), Vdd(8:15..15): BOOLEAN, fill9(9:0..14): [0 .. 32768), Gnd(9:15..15): BOOLEAN, fill10(10:0..14): [0 .. 32768), PadVdd(10:15..15): BOOLEAN, fill11(11:0..14): [0 .. 32768), PadGnd(11:15..15): BOOLEAN, fill12(12:0..14): [0 .. 32768), KBus(12:15..15): BOOLEAN, fill13(13:0..14): [0 .. 32768), EUAluLeftisR1BA(13:15..15): BOOLEAN, fill14(14:0..14): [0 .. 32768), EUAluLeftisR3BA(14:15..15): BOOLEAN, fill15(15:0..14): [0 .. 32768), EUAluRightisKBA(15:15..15): BOOLEAN, fill16(16:0..14): [0 .. 32768), EUAluRightisR1BA(16:15..15): BOOLEAN, fill17(17:0..14): [0 .. 32768), EUAluRightisR3BA(17:15..15): BOOLEAN, fill18(18:0..14): [0 .. 32768), EUS1isR1BA(18:15..15): BOOLEAN, fill19(19:0..14): [0 .. 32768), EUS1isR3BA(19:15..15): BOOLEAN, fill20(20:0..14): [0 .. 32768), EUR2isR3BA(20:15..15): BOOLEAN, fill21(21:0..14): [0 .. 32768), EUS3isR3BA(21:15..15): BOOLEAN, fill22(22:0..14): [0 .. 32768), EUHoldCarryBA(22:15..15): BOOLEAN, fill23(23:0..14): [0 .. 32768), EUR3isR2AB(23:15..15): BOOLEAN, fill24(24:0..14): [0 .. 32768), EUWriteToCacheAB(24:15..15): BOOLEAN, fill25(25:0..14): [0 .. 32768), EUAluOpAB(25:15..15): BOOLEAN, fill26(26:0..14): [0 .. 32768), EUCondSelAB(26:15..15): BOOLEAN, fill27(27:0..14): [0 .. 32768), EUTrapBA(27:15..15): BOOLEAN, fill28(28:0..14): [0 .. 32768), EUConditionBA(28:15..15): BOOLEAN, fill29(29:0..14): [0 .. 32768), InstrCountAB(29:15..15): BOOLEAN, fill30(30:0..14): [0 .. 32768), DShiftAB(30:15..15): BOOLEAN, fill31(31:0..14): [0 .. 32768), DExecuteAB(31:15..15): BOOLEAN, fill32(32:0..14): [0 .. 32768), DNSelectAB(32:15..15): BOOLEAN, fill33(33:0..14): [0 .. 32768), DHoldAB(33:15..15): BOOLEAN, fill34(34:0..14): [0 .. 32768), DDataInAB(34:15..15): BOOLEAN, fill35(35:0..14): [0 .. 32768), DDataOutAB(35:15..15): BOOLEAN]; EUExpand: ExpandProc = { PrivateLookupNode: PROC [name: ROPE] RETURNS [node: Node] = {node _ RoseCreate.LookupNode[from: thisCell, path: LIST[name]]}; EPData: Node _ PrivateLookupNode["EPData"]; EPRejectB: Node _ PrivateLookupNode["EPRejectB"]; EPFaultB: Node _ PrivateLookupNode["EPFaultB"]; EPParityB: Node _ PrivateLookupNode["EPParityB"]; EPNPErrorB: Node _ PrivateLookupNode["EPNPErrorB"]; PhA: Node _ PrivateLookupNode["PhA"]; PhB: Node _ PrivateLookupNode["PhB"]; ResetAB: Node _ PrivateLookupNode["ResetAB"]; Vdd: Node _ PrivateLookupNode["Vdd"]; Gnd: Node _ PrivateLookupNode["Gnd"]; PadVdd: Node _ PrivateLookupNode["PadVdd"]; PadGnd: Node _ PrivateLookupNode["PadGnd"]; KBus: Node _ PrivateLookupNode["KBus"]; EUAluLeftisR1BA: Node _ PrivateLookupNode["EUAluLeftisR1BA"]; EUAluLeftisR3BA: Node _ PrivateLookupNode["EUAluLeftisR3BA"]; EUAluRightisKBA: Node _ PrivateLookupNode["EUAluRightisKBA"]; EUAluRightisR1BA: Node _ PrivateLookupNode["EUAluRightisR1BA"]; EUAluRightisR3BA: Node _ PrivateLookupNode["EUAluRightisR3BA"]; EUS1isR1BA: Node _ PrivateLookupNode["EUS1isR1BA"]; EUS1isR3BA: Node _ PrivateLookupNode["EUS1isR3BA"]; EUR2isR3BA: Node _ PrivateLookupNode["EUR2isR3BA"]; EUS3isR3BA: Node _ PrivateLookupNode["EUS3isR3BA"]; EUHoldCarryBA: Node _ PrivateLookupNode["EUHoldCarryBA"]; EUR3isR2AB: Node _ PrivateLookupNode["EUR3isR2AB"]; EUWriteToCacheAB: Node _ PrivateLookupNode["EUWriteToCacheAB"]; EUAluOpAB: Node _ PrivateLookupNode["EUAluOpAB"]; EUCondSelAB: Node _ PrivateLookupNode["EUCondSelAB"]; EUTrapBA: Node _ PrivateLookupNode["EUTrapBA"]; EUConditionBA: Node _ PrivateLookupNode["EUConditionBA"]; InstrCountAB: Node _ PrivateLookupNode["InstrCountAB"]; DShiftAB: Node _ PrivateLookupNode["DShiftAB"]; DExecuteAB: Node _ PrivateLookupNode["DExecuteAB"]; DNSelectAB: Node _ PrivateLookupNode["DNSelectAB"]; DHoldAB: Node _ PrivateLookupNode["DHoldAB"]; DDataInAB: Node _ PrivateLookupNode["DDataInAB"]; DDataOutAB: Node _ PrivateLookupNode["DDataOutAB"]; NodeCreateHack1: PROC [name: ROPE] RETURNS [node: Node] = {node _ RoseCreate.CreateNode[within: thisCell, name: name, type: NumTypes.NumType[32]]}; aBus: Node _ NodeCreateHack1["aBus"]; bBus: Node _ NodeCreateHack1["bBus"]; cBus: Node _ NodeCreateHack1["cBus"]; rBus: Node _ NodeCreateHack1["rBus"]; OpLeftBus: Node _ NodeCreateHack1["OpLeftBus"]; OpRightBus: Node _ NodeCreateHack1["OpRightBus"]; ConstBus: Node _ NodeCreateHack1["ConstBus"]; storeBus: Node _ NodeCreateHack1["storeBus"]; sBus: Node _ NodeCreateHack1["sBus"]; NodeCreateHack2: PROC [name: ROPE] RETURNS [node: Node] = {node _ RoseCreate.CreateNode[within: thisCell, name: name, type: NumTypes.NumType[8]]}; aAddBus: Node _ NodeCreateHack2["aAddBus"]; bAddBus: Node _ NodeCreateHack2["bAddBus"]; cAddBus: Node _ NodeCreateHack2["cAddBus"]; NodeCreateHack3: PROC [name: ROPE] RETURNS [node: Node] = {node _ RoseCreate.CreateNode[within: thisCell, name: name, type: NumTypes.boolType]}; writeMDFBA: Node _ NodeCreateHack3["writeMDFBA"]; rejectBA: Node _ NodeCreateHack3["rejectBA"]; faultBA: Node _ NodeCreateHack3["faultBA"]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "kport", className: "EUKport", interfaceNodes: ""]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "ram", className: "EURam", interfaceNodes: ""]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "OpLeft", className: "EUOpLeft", interfaceNodes: ""]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "OpRight", className: "EUOpRight", interfaceNodes: ""]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "Result1", className: "EUResult1", interfaceNodes: ""]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "alu", className: "EUAlu", interfaceNodes: ""]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "field", className: "EUField", interfaceNodes: ""]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "Store", className: "EUStore", interfaceNodes: ""]; [] _ RoseCreate.CreateCell[within: thisCell, instanceName: "mport", className: "EUMport", interfaceNodes: ""]; }; CreateEUIO: IOCreator = { cell.realCellStuff.newIO _ NEW [EUIORec]; cell.realCellStuff.oldIO _ NEW [EUIORec]; }; InitializeEU: Initializer = { IF leafily THEN BEGIN ioRec: EUIORef _ NARROW[cell.realCellStuff.newIO]; BEGIN OPEN ioRec; IF initData#NIL THEN WITH initData SELECT FROM pl: Atom.PropList => BEGIN r: REF; IF (r _ pl.GetPropFromList[$LogRef]) # NIL THEN euLogRef _ NARROW[r, REF REF]; END; ENDCASE => NULL; -- -- END; END; }; EUPorts: Ports _ NEW [PortsRep[36]]; --explicitly requested CEDAR: EULog:PROC[ instr: BitOps.BitDWord, aRam: Dragon.HexByte, left: Dragon.HexWord, bRam: Dragon.HexByte, right: Dragon.HexWord, store: Dragon.HexWord, cRam: Dragon.HexByte, result: Dragon.HexWord] = { SELECT TRUE FROM reset => { log.Flush[]; log.PutF["\n\n\nEULog.txt %g", IO.time[] ]; log.PutF["\n**Reset**" ]}; rejected => { log.PutF["\n**Rejected**" ]}; ENDCASE => { log.PutF["\n%5g", IO.card[ LFD[instr] ] ]; log.PutF[" %02x:%08x", IO.card[aRam], IO.card[ left ] ]; log.PutF[" %02x:%08x", IO.card[bRam], IO.card[ right ] ]; log.PutF[":%08x", IO.card[ store ] ]; log.PutF[" %02x:%08x", IO.card[cRam], IO.card[ result ] ]; } }; reset, resetting:BOOL _ FALSE; rejected:BOOL _ FALSE; phBLastFLAG:BOOL _ FALSE; log:IO.STREAM _ IO.noWhereStream; EUStateHandler: Cucumber.Handler = NEW[Cucumber.HandlerRep _ [ PrepareWhole: EUStatePrepareProc, PartTransfer: EUTransferProc ]]; EUStatePrepareProc: PROC [ whole: REF ANY, where: IO.STREAM, direction: Cucumber.Direction, data: REF ANY ] RETURNS [ leaveTheseToMe: Cucumber.SelectorList ] -- Cucumber.Bracket -- = {leaveTheseToMe _ LIST[$euLogRef]}; EUTransferProc: PROC [ whole: REF ANY, part: Cucumber.Path, where: IO.STREAM, direction: Cucumber.Direction, data: REF ANY ] -- Cucumber.PartTransferProc -- = {NULL}; Cucumber.Register[EUStateHandler, CODE[EUStateRec]]; RegisterCells[]; END.