IO.
PORTS [
XBus < INT[32],
DPRejectedBA < BOOL,
OpAB < INT[8],
AlphaAB < INT[8],
BetaAB < INT[8],
GammaAB < INT[8],
DeltaAB < INT[8],
OpLengthBA < INT[3],
InstReadyAB < BOOL,
ExceptionCodeAB < EnumType["IFUPLAMainControl.ExceptionCode"],
MicroCycleAB < INT[8],
MicroCycleNextBA < EnumType["IFUPLAInstrDecode.MicroCycleNext"],
MacroJumpBA < BOOL,
PCBusSrcB < EnumType["IFUPLAInstrDecode.PCBusSrc"],
PCForLogAB < INT[32],
LAB < INT[8],
SAB < INT[8],
AReg0BA < INT[8],
BReg0BA < INT[8],
CReg0BA < INT[8],
P Interfaces for EU cache
DPCmnd3A < EnumType["Dragon.PBusCommands"],
DPData < INT[32],
DPRejectB < BOOL,
DPFaultB < EnumType["Dragon.PBusFaults"],
LoadStage1Ac < BOOL, -- Pipe Controls
LoadStage1Bc < BOOL,
LoadStage2Ac < BOOL,
BubbleStage2A1BA < BOOL,
NormalStage2A1BA < BOOL,
AbortStage2B2AB < BOOL,
NormalStage2B2AB < BOOL,
LoadStage3Ac < BOOL,
AbortStage3A2BA < BOOL,
NormalStage3A2BA < BOOL,
PhA < BOOL,
PhB < BOOL
]
State
opPipe: ARRAY [0..3] OF ARRAY Dragon.Phase OF LogPipeState,
last: {a,ab,b,ba},
firstMicroOfMacro: LogPipeState,
dpRejectedAB: BOOL,
dpFaultedBA: BOOL,
dpFaultedAB: BOOL,
doTrap3BA: BOOL,
xbusBCopy: Dragon.HexWord,
logRegistersB: BOOL,
interruptPending: BOOL,
trapped: BOOL
EvalSimple
NewDisposition:
PROC [ pipeState: LogPipeState, disp: MicroInstDisposition ]
RETURNS [ newPipeState: LogPipeState ] = {
newPipeState ← pipeState;
newPipeState.disposition ← disp;
};
log: IO.STREAM;
IF
NOT PhB
AND last=b
THEN {
last ← ba;
IF logRegistersB
AND (log ← logRef^) #
IO.noWhereStream
THEN {
log.PutF[" a:%02x", IO.card[AReg0BA]];
log.PutF[ " b:%02x", IO.card[BReg0BA]];
log.PutF[ " c:%02x", IO.card[CReg0BA]];
};
logRegistersB ← FALSE;
SELECT opPipe[3][b].microCyc FROM
117 => {
-- Reset finished
ClusterParams.clusterPanel.instrCount ← -1;
trapped ← FALSE;
};
120 => {
-- first cycle of trap
trapped ← TRUE;
};
0 =>
IF
NOT DPRejectedBA
AND (
SELECT opPipe[3][b].disposition
FROM
valid => TRUE,
killed3a, killed3b =>
(MicroCycleAB = 120 -- trap that will apply to the new instruction -- ),
ENDCASE => FALSE) THEN {
The first microinstruction of a new macroinstruction instrCount+1 is now committed to retire, either in victory or defeat (as in "trapped"). This means that all register stores for the macroinstruction instrCount are completed, and none for macroinstruction instrCount+1 have yet occurred.
ClusterParams.clusterPanel.instrCount ← ClusterParams.clusterPanel.instrCount
+
LizardRosemary.CheckSynch[
lizardSimRef: lizardSimRef,
clusterInst: [
-- the completed instruction
cycle: ClusterParams.clusterPanel.cycle,
instr: ClusterParams.clusterPanel.instrCount,
trapped: trapped,
trapPC: IF trapped THEN opPipe[3][b].pc ELSE 0,
pc: firstMicroOfMacro.pc,
op: firstMicroOfMacro.op,
alpha: firstMicroOfMacro.alpha,
beta: firstMicroOfMacro.beta,
gamma: firstMicroOfMacro.gamma,
delta: firstMicroOfMacro.delta
]
].deltaInstrCount;
firstMicroOfMacro ← opPipe[3][b];
trapped ← FALSE;
};
ENDCASE => NULL;
};
IF PhA THEN {dpRejectedAB ← DPRejectedBA; dpFaultedAB ← dpFaultedBA};
Pipe
IF PhB
THEN opPipe[0][b] ← [
pc: DragonRoseExtras.LFD[PCForLogAB],
op: LOOPHOLE[OpAB],
alpha: AlphaAB,
beta: BetaAB,
gamma: GammaAB,
delta: DeltaAB,
microCyc: MicroCycleAB,
disposition: IF InstReadyAB THEN valid ELSE unready
];
IF LoadStage1Ac THEN opPipe[1][a] ← opPipe[0][b];
IF LoadStage1Bc THEN opPipe[1][b] ← opPipe[1][a];
IF LoadStage2Ac
THEN opPipe[2][a] ← (
SELECT
TRUE
FROM
NormalStage2A1BA => opPipe[1][b],
BubbleStage2A1BA => NewDisposition[opPipe[1][b], interlocked],
ENDCASE => ERROR);
IF PhB
THEN opPipe[2][b] ← (
SELECT
TRUE
FROM
NormalStage2B2AB => opPipe[2][a],
AbortStage2B2AB => NewDisposition[opPipe[2][a], killed2b],
ENDCASE => ERROR);
IF LoadStage3Ac
THEN opPipe[3][a] ← (
SELECT
TRUE
FROM
NormalStage3A2BA => opPipe[2][b],
AbortStage3A2BA => NewDisposition[opPipe[2][b], killed3a],
ENDCASE => ERROR);
IF PhB
THEN
{opPipe[3][b] ← opPipe[3][a]; IF dpFaultedAB THEN opPipe[3][b].disposition ← killed3b};
IF PhB THEN {
xbusBCopy ← DragonRoseExtras.LFD[XBus];
dpFaultedBA ← DPFaultB # none;
doTrap3BA ←
SELECT ExceptionCodeAB
FROM
none, cJump => FALSE,
ENDCASE => TRUE;
IF last#b
THEN {
last ← b;
Log instruction at the beginning of Ph0B.
IF ((log ← logRef^) #
IO.noWhereStream)
AND (ExceptionCodeAB # reset)
THEN {
IF (ExceptionCodeAB # none)
OR InstReadyAB
THEN {
log.PutF["\n%5g%5g", IO.int[ClusterParams.clusterPanel.cycle], IO.int[ClusterParams.clusterPanel.instrCount] ];
SELECT
TRUE
FROM
ExceptionCodeAB=reseting
=> log.PutF["**Reseting "];
ExceptionCodeAB=reset
=> log.PutF["**Reset "];
ExceptionCodeAB=dpFault
=> log.PutF["**DPFault "];
dpRejectedAB
=> log.PutF["**DPReject "];
ExceptionCodeAB=cTrap
=> log.PutF["**EUCC "];
ExceptionCodeAB=bubble
=> log.PutF["**Bubble "];
ExceptionCodeAB=cJump
=> log.PutF["**CJRestrt "];
ExceptionCodeAB=rschlWait
=> log.PutF["**Reschdl "];
ExceptionCodeAB=iStkOFlow
=> log.PutF["**IStkOver "];
ExceptionCodeAB=eStkOFlow
=> log.PutF["**EStkOver "];
ExceptionCodeAB=ipFault
=> log.PutF["**IPgFault "];
ExceptionCodeAB=none
=> log.PutRope[" "];
ENDCASE
=> log.PutF[" cy: %2g ", IO.card[ExceptionCodeAB.ORD]];
log.PutF["pc:%08x", IO.card[DragonRoseExtras.LFD[PCForLogAB]] ];
SELECT
TRUE
FROM
dpRejectedAB => log.PutF[" --EU reject delay..."];
NOT InstReadyAB => log.PutF[" --IFetch delay..."];
ENDCASE => {
opLength: [0..5] = DragonRosemary.OpLength[OpAB];
log.PutF[" %-7g",
IO.rope[Rope.Cat[DragonRosemary.OpName[OpAB],
(IF MicroCycleAB=0 THEN "" ELSE IO.PutFR["-%g", IO.int[MicroCycleAB]])]]];
IF opLength > 1
THEN log.PutF[" %02x", IO.card[AlphaAB]] ELSE log.PutF[" "];
IF opLength > 2
THEN log.PutF["%02x", IO.card[BetaAB]] ELSE log.PutF[" "];
IF opLength > 3
THEN log.PutF["%02x%02x", IO.card[GammaAB], IO.card[DeltaAB]]
ELSE log.PutF[" "];
log.PutF[" l:%02x", IO.card[LAB]]; -- at beginning of instruction
log.PutF[ " s:%02x", IO.card[SAB]]; -- at beginning of instruction
logRegistersB ← TRUE;
};
};
};
IF ExceptionCodeAB=reset
THEN
ClusterParams.clusterPanel.instrCount ← -1;
};
};