State:
TYPE =
MACHINE
DEPENDENT {
-- See picture on DCP20.sil
c1fh(0), c1sh, c2fh, c2sh, c3fh, c3sh, c1wait, ref2fh, ref2sh, read3fh, read3sh, write3fh, write3sh, c1wfh, c1wsh, c2wfh(15)};
FOR i:
CARDINAL
IN [0..512)
DO
state, nextState: State;
ioRef, mapRef, xack, initTrap, master: Bit;
cycle1, cycle2, cycle3, doIt: Bit ← FALSE;
writeMar, writeMdr, bClk, writeMd, readMax, mbIdle: Bit ← FALSE;
ioCmd, clearCmd, readCmd, writeCmd: Bit ← FALSE;
clearAd, readMar, readMap, readMdr: Bit ← FALSE;
addr ← LOOPHOLE[i];
state ← addr.state;
ioRef ← addr.ioRef;
mapRef ← addr.mapRef;
xack ← ~addr.xackBar;
initTrap ← ~addr.initTrapBar;
master ← ~addr.masterBar;
IF initTrap AND state # c1fh THEN state ← c1wait;
SELECT state
FROM
c1fh => {
clearAd ← TRUE;
IF initTrap THEN nextState ← c1wait
ELSE {
IF ioRef
OR mapRef
THEN {
IF master THEN {writeMar ← TRUE; nextState ← c1sh}
ELSE nextState ← c1wait; }
ELSE nextState ← c1sh; }; };
c1sh => {
IF ioRef
OR mapRef
THEN {
ioCmd ← ioRef AND ~mapRef;
IF mapRef AND ~ioRef THEN readMap ← TRUE ELSE readMar ← TRUE;
readMax ← TRUE;
nextState ← ref2fh; }
ELSE { clearAd ← TRUE; nextState ← c2fh; }; };
c2fh => { clearAd ← TRUE; nextState ← c2sh; };
c2sh => { mbIdle ← TRUE; clearAd ← TRUE; nextState ← c3fh; };
c3fh => nextState ← c3sh;
c3sh => nextState ← c1fh;
c1wait => { clearCmd ← TRUE; nextState ← c1fh; };
ref2fh => {
IF ioRef AND mapRef THEN writeMdr ← TRUE ELSE readCmd ← TRUE;
readMax ← TRUE;
nextState ← ref2sh; };
ref2sh => {
readMax ← TRUE;
IF ioRef AND mapRef THEN { readMdr ← TRUE; nextState ← write3fh; }
ELSE nextState ← read3fh; };
read3fh => {
writeMd ← TRUE;
readMax ← TRUE;
IF xack THEN nextState ← read3sh ELSE nextState ← read3fh; };
read3sh => { readMax ← TRUE; clearCmd ← TRUE; nextState ← c1fh; };
write3fh => {
writeMd ← TRUE;
readMax ← TRUE;
IF ~(ioRef AND mapRef) THEN writeCmd ← TRUE;
nextState ← write3sh; };
write3sh => {
readMax ← TRUE;
IF ioRef AND mapRef THEN xack ← TRUE;
IF xack THEN { clearCmd ← TRUE; nextState ← c1fh; }
ELSE nextState ← c1wfh; };
c1wfh => {
readMax ← TRUE;
IF xack
THEN {
clearCmd ← TRUE;
IF ioRef OR mapRef THEN nextState ← c1fh
ELSE { nextState ← c1sh; }; }
ELSE {
IF ioRef OR mapRef THEN nextState ← c1wfh
ELSE nextState ← c1wsh; }; };
c1wsh => {
readMax ← TRUE;
IF xack THEN { clearCmd ← TRUE; nextState ← c2fh; }
ELSE nextState ← c2wfh; };
c2wfh => {
readMax ← TRUE;
IF xack THEN { clearCmd ← TRUE; nextState ← c2sh; }
ELSE nextState ← c2wfh; };
ENDCASE => ERROR;
SELECT nextState
FROM
-- NB: bClk won't flap during long series of writes
c1wait => bClk ← TRUE;
c2sh => bClk ← TRUE;
c3sh => bClk ← TRUE;
read3sh => bClk ← TRUE;
ENDCASE;
SELECT nextState FROM -- Old Way
c1fh => bClk ← TRUE;
c2fh => bClk ← TRUE;
c3fh => bClk ← TRUE;
ENDCASE;
SELECT nextState
FROM
-- doIt should be set IFF nextState will be *sh
c1sh => doIt ← TRUE;
c2sh => doIt ← TRUE;
c3sh => doIt ← TRUE;
c1wait => IF initTrap THEN doIt ← TRUE; -- Well, amost IFF
ref2sh => doIt ← TRUE;
read3sh => doIt ← TRUE;
write3sh => doIt ← TRUE;
c1wsh => doIt ← TRUE;
ENDCASE;
SELECT nextState
FROM
-- Factor out calculations for cycle1, cycle2 and cycle3
c1fh => cycle1 ← TRUE;
c1sh => cycle1 ← TRUE;
c2fh => cycle2 ← TRUE;
c2sh => cycle2 ← TRUE;
c3fh => cycle3 ← TRUE;
c3sh => cycle3 ← TRUE;
c1wait => cycle1 ← TRUE;
ref2fh => cycle2 ← TRUE;
ref2sh => cycle2 ← TRUE;
read3fh => cycle3 ← TRUE;
read3sh => cycle3 ← TRUE;
write3fh => cycle3 ← TRUE;
write3sh => cycle3 ← TRUE;
c1wfh => cycle1 ← TRUE;
c1wsh => cycle1 ← TRUE;
c2wfh => cycle2 ← TRUE;
ENDCASE => ERROR;
data ← [
nextState: nextState,
cycle1: cycle1, cycle2: cycle2, cycle3: cycle3, doIt: doIt,
writeMar: writeMar, writeMdr: writeMdr, bClk: bClk,
writeMd: writeMd, readMaxBar: ~readMax, mbIdle: mbIdle,
ioCmd: ioCmd, clearCmdBar: ~clearCmd, readCmd: readCmd, writeCmd: writeCmd,
clearAd: clearAd, readMarBar: ~readMar, readMapBar: ~readMap, readMdrBar: ~readMdr ];
PutWord[1]; -- Memory contents
PutWord[0]; -- Source line number
TRUSTED {
IO.UnsafePutBlock[mb, [base: LOOPHOLE[LONG[@data]], startIndex: 0, count: 2*2]]; };
ENDLOOP;