Dragon.Assert[ resetBA OR mStateBA.exceptions IN [aboutToReset..reset] OR NOT instReadyBA OR OpBA IN (0..255), "Breakpoint XOP encountered" ];
IF
NOT dHoldBA
THEN {
IF
NOT phALastFLAG
THEN {
Get Next Micro Trap Instruction
phALastFLAG ← TRUE;
iLogged ← resetBA OR mStateBA.exceptions = aboutToReset;
[mTrapAB, mStateAB] ← DragonMicroPLA.GetMicroTrap[ [
state :mStateBA,
ifuStatusControl :ifuStatusControlBA,
iTrapEffect3 :Lev3ITrapEffectBA,
delayed :delayedBA,
done :doneBA,
reset :resetBA,
reschedule :rescheduleBA,
preFetchFaulted :PreFetchFaultedBA,
pushPending :pushPendingBA,
popPending :popPendingBA,
iTrapEffectPending :iTrapEffectPendingBA,
iStkOverflow :iStkOverflowBA,
eStkOverflow :EStkOverflowBA,
aluCondResult2 :EUConditionBA,
aluCond2 :Lev2CondSelBA,
condEffect2 :Lev2CondEffectBA,
pBusReject3 :lev3RejectBA,
pBusFault3 :lev3FaultBA
] ];
instrCountAB ←
IF resetBA
OR mStateBA.exceptions = aboutToReset
THEN 0
ELSE
IF (
NOT mInstrBA.dontGetNextMacro )
OR mInstrBA.doMacroJump
THEN instrCountBA+1
ELSE instrCountBA };
Check to see if PhA XBus driven from IDecoder
SELECT mInstrBA.xASource
FROM
none => { };
alpha => XBus ← Dragon.LTD[AlphaBA];
beta => XBus ← Dragon.LTD[BetaBA];
betaAlpha => XBus ← Dragon.LTD[BetaBA*256 + AlphaBA];
deltaGammaBetaAlpha =>
XBus ← Dragon.LTD[((deltaBA*LONG[256]+gammaBA)*256+BetaBA)*256+AlphaBA];
bAddrIFUReg => {
IF Lev0BaddrBA=DragonIFU.PRtoByte[ifuStatus]
THEN XBus ← Dragon.LTD[ReadIFUStatus[mStateBA]]};
fpLdMode => XBus ← DragonFP.InsertLoadFunction[mode, AlphaBA, XBus];
fpLdAMsw => XBus ← DragonFP.InsertLoadFunction[aHi, AlphaBA, XBus];
fpLdALsw => XBus ← DragonFP.InsertLoadFunction[aLo, AlphaBA, XBus];
fpLdBMsw => XBus ← DragonFP.InsertLoadFunction[bHi, AlphaBA, XBus];
fpLdBLsw => XBus ← DragonFP.InsertLoadFunction[bLo, AlphaBA, XBus];
fpUnldMsw => XBus ← DragonFP.InsertUnload[msw, XBus];
fpUnldLsw => XBus ← DragonFP.InsertUnload[lsw, XBus];
ENDCASE => ERROR;
ReadSLimitA ← mInstrBA.xASource=bAddrIFUReg AND Lev0BaddrBA=DragonIFU.PRtoByte[ifuSLimit];
Buffer copy of PhA XBus
xAB ← Dragon.LFD[XBus];
Load P,L and S
pAB ← xBA;
LSum0A ← mInstrBA.lSource.s0;
LSum1A ← mInstrBA.lSource.s1;
DeltaSPlus2A ← 2 +
(IF (mInstrBA.deltaSc = push) THEN 1 ELSE 0) -
(IF (mInstrBA.deltaSa = pop) THEN 1 ELSE 0) -
(IF (mInstrBA.deltaSb = pop) THEN 1 ELSE 0);
SSum0A ← mInstrBA.sSource.s0;
SSum1A ← mInstrBA.sSource.s1;
Load PreFetch MacroWord
instReadyAB ← InstReadyA;
opAB ← PreOpA; TRUSTED {opNameAB ← LOOPHOLE[PreOpA]};
alphaAB ← PreAlphaA;
betaAB ← PreBetaA;
gammaAB ← PreGammaA;
deltaAB ← PreDeltaA;
lengthAB ← PreLengthA;
Save IStack overflow conditions
iStkEmptyAB ← IStkEmptyA;
iStkOverflowAB ← IStkTooFullA;
Check to see if PhA XBus has IFU data
SetSLimitA ← Lev3CaddrBA=DragonIFU.PRtoByte[ifuSLimit];
ifuStatusControlAB ←
IF Lev3CaddrBA=DragonIFU.PRtoByte[ifuStatus]
THEN ReadStatusControl[XBus]
ELSE [nop, nop];
Send out the PhA Piped PLS
SELECT mInstrBA.pipedPLSASpec
FROM
pls => {
Lev0PA ← Dragon.LTD[pBA];
Lev0LA ← lBA;
Lev0SA ← sBA };
pLenLSnext => {
Lev0PA ← Dragon.LTD[pBA + lengthBA];
Lev0LA ← LAB;
Lev0SA ← SAB };
pAlphasLSnext => {
Lev0PA ← Dragon.LTD[(pBA + SExtnd[AlphaBA])];
Lev0LA ← LAB;
Lev0SA ← SAB };
ENDCASE => ERROR;
Send out C and killpipe to Pipe
CSum0A ← mInstrBA.cReg.s0;
CSum1A ← mInstrBA.cReg.s1;
KillPipeAB ← mTrapAB.killPipe;
Register instruction count update (for simulation only)
InstrCountAB ← Dragon.LTD[instrCountBA];
};
};
IF
NOT PhA
AND
NOT iLogged
AND log #
IO.noWhereStream
THEN {
This logging was formerly done at the beginning of Ph0B. Now we do it
at the end of Ph1A. This means that we have to pipeline instReadyAB.
iLogged ← TRUE;
IF mStateBA.exceptions=reset
THEN {
log.Flush[];
log.PutF["\n\n\nIDecoder Log %g", IO.time[] ]};
log.PutF["\n%5g", IO.card[instrCountBA] ];
SELECT
TRUE
FROM
mStateBA.exceptions=reset
=> log.PutF["**Reset "];
mStateBA.exceptions=epFault
=> log.PutF["**EPFault "];
mStateBA.exceptions=euCC
=> log.PutF["**EUCC "];
mStateBA.exceptions=epReject
=> log.PutF["**EPReject "];
mStateBA.exceptions=cJump
=> log.PutF["**CJRestrt "];
mStateBA.exceptions=rschlWait
=> log.PutF["**Reschdl "];
mStateBA.exceptions=iStkOFlow
=> log.PutF["**IStkOver "];
mStateBA.exceptions=eStkOFlow
=> log.PutF["**EStkOver "];
mStateBA.exceptions=iFtchFault
=> log.PutF["**IPgFault "];
mInstrBA.doMacroJump
AND xBA=4010040B
=> log.PutF["**IStkUndr "];
ENDCASE
=> log.PutF[" "];
IF mInstrBA.delayed
THEN log.PutF["dly "]
ELSE log.PutF[" "];
log.PutF["pc:%08x", IO.card[pBA] ];
IF
NOT instReadyBA
THEN log.PutF["---"]
ELSE {
log.PutF[" %-7g", IO.rope[opName[OpBA]]];
IF lengthBA > 3
THEN log.PutF[" %02x%02x", IO.card[deltaBA], IO.card[gammaBA]]
ELSE log.PutF[" "];
IF lengthBA > 2 THEN log.PutF["%02x", IO.card[BetaBA]] ELSE log.PutF[" "];
IF lengthBA > 1 THEN log.PutF["%02x", IO.card[AlphaBA]] ELSE log.PutF[" "];
log.PutF[" l:%02x", IO.card[lBA]]; -- at beginning of instruction
log.PutF[ " s:%02x", IO.card[sBA]]; -- at beginning of instruction
IF
NOT mInstrBA.delayed
THEN {
log.PutF[" a:%02x", IO.card[Lev0AaddrBA]];
log.PutF[ " b:%02x", IO.card[Lev0BaddrBA]];
log.PutF[ " c:%02x", IO.card[Lev0CaddrA]] } } };
IF
PhB
AND
NOT DHoldAB
THEN {
IF phALastFLAG
THEN {
phALastFLAG ← FALSE;
[mInstrBA] ← DragonMicroPLA.GetMicroInst[ [
state :mStateAB,
op :opNameAB,
alpha :alphaAB,
beta :betaAB,
delayACycle :DelayACycleAB,
iStkEmpty :iStkEmptyAB,
pushPending :PushPendingAB,
popPending :PopPendingAB,
instReady :instReadyAB
] ] };
Latch PhB Copies
OpBA ← opAB;
AlphaBA ← alphaAB;
BetaBA ← betaAB;
gammaBA ← gammaAB;
deltaBA ← deltaAB;
lengthBA ← lengthAB;
instReadyBA ← instReadyAB;
pBA ← pAB;
lBA ← LAB;
sBA ← SAB;
mStateBA ← mStateAB;
doneBA ←
mInstrBA.doMacroJump OR
( NOT mInstrBA.dontGetNextMacro ) OR
mStateAB.cycle = 0 AND NOT instReadyAB;
delayedBA ← mInstrBA.delayed;
resetBA ← ResetAB;
rescheduleBA ← RescheduleAB;
iStkOverflowBA ← iStkOverflowAB;
pushPendingBA ← PushPendingAB OR mInstrBA.iStackPostEffect=push;
popPendingBA ← PopPendingAB OR mInstrBA.iStackPostEffect=pop;
iTrapEffectPendingBA ←
IF mInstrBA.iTrapPostEffect#none
THEN mInstrBA.iTrapPostEffect
ELSE ITrapEffectPendingAB;
lev3RejectBA ← EPRejectB;
lev3FaultBA ← EPFaultB;
ifuStatusControlBA ← ifuStatusControlAB;
instrCountBA ← instrCountAB;
Check to see if XBus driven from IDecoder during phB
SELECT mInstrBA.xBSource
FROM
pcPlusAlphaS => XBus ← Dragon.LTD[pBA+SExtnd[alphaAB]];
pcPlusBetaAlphaS => XBus ← Dragon.LTD[pBA+SExtnd[betaAB]*256 + alphaAB];
deltaGammaBetaAlpha =>
XBus ← Dragon.LTD[((deltaAB*LONG[256]+gammaAB)*256+betaAB)*256+alphaAB];
pc => XBus ← Dragon.LTD[pBA];
pcPlusLen => XBus ← Dragon.LTD[pBA + lengthAB];
xA => XBus ← Dragon.LTD[xAB];
pcPlusXA => XBus ← Dragon.LTD[pBA + xAB];
xopGenerator => XBus ← Dragon.LTD[16*(opAB+DragOpsCross.XopBase)];
trapPCGenerator => XBus ← Dragon.LTD[mTrapAB.trapPC];
iStackPC => {-- Driven in IStack --};
pipe3PC => {-- Driven in IPipe --};
ENDCASE => ERROR;
Latch PhB XBus Copies
xBA ← Dragon.LFD[XBus];
Calculate A and B register addresses
ASum0B ← mInstrBA.aReg.s0;
ASum1B ← mInstrBA.aReg.s1;
BSum0B ← mInstrBA.bReg.s0;
BSum1B ← mInstrBA.bReg.s1;
Send out PhB IFetcher control and data
GetNextInstB ← NOT ResetAB AND NOT mInstrBA.dontGetNextMacro;
JumpB ← ResetAB OR mInstrBA.doMacroJump;
Send out the PhB Pipe goodies
Lev0AluRtIsKBA ← mInstrBA.aluRtIsK;
Lev0AluOpBA ←
IF mInstrBA.aluOp = op47
THEN LOOPHOLE[opAB MOD 16]
ELSE mInstrBA.aluOp;
Lev0CondSelBA ←
IF mInstrBA.condSel = op57
THEN LOOPHOLE[opAB MOD 8]
ELSE mInstrBA.condSel;
Lev0CondEffectBA ← mInstrBA.condEffect;
DontBypassBA ← mInstrBA.dontBypass;
PushLevel3BA ← mInstrBA.pushLevel3;
Lev0IStackPostEffectBA ← mInstrBA.iStackPostEffect;
Lev0ITrapPostEffectBA ← mInstrBA.iTrapPostEffect;
Lev0EuPBusCmdBA ← mInstrBA.euPBusCmd;
XBSourceBA ← mInstrBA.xBSource;
};