--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 =
--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]);
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];
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.