DCPMultibus.mesa - Make Multibus Proms for Dicentra CP board
Hal Murray July 10, 1985 2:39:29 pm PDT
Transliterated from DCP-Multibus.bcpl, HGM, July 9, 1985 5:57:14 pm PDTxx
Compile DCPMultibus
Run DCPMultibus
Copy /Ivy/Murray/Dicentra/DCPMultibus.mesa ← DCPMultibus.mesa
Copy /Ivy/Murray/Dicentra/DCP-Multibus.mb ← DCP-Multibus.mb
DIRECTORY
Basics USING [],
Convert USING [RopeFromTime],
FS USING [StreamOpen],
IO USING [Close, PutChar, PutRope, STREAM, UnsafePutBlock],
Loader USING [BCDBuildTime],
Rope USING [Cat, Length, ROPE];
DCPMultibus: CEDAR PROGRAM
IMPORTS Convert, FS, IO, Loader, Rope =
BEGIN
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
mb: STREAM;
memory: CARDINAL ← 0;
Bit: TYPE = BOOLEAN;
virgin: BOOLEANTRUE; -- Virgin bits in TBP28L22s are high
Multibus: PROC =
BEGIN
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)};
addr: RECORD [
blank: [0..128),
state: State,
ioRef: Bit, -- ioRef AND mapRef => normal memory reference
mapRef: Bit,
xackBar: Bit,
initTrapBar: Bit,
masterBar: Bit ];
data: RECORD [
nextState: State,
cycle1: Bit,
cycle2: Bit,
cycle3: Bit,
doIt: Bit,
writeMar: Bit,
writeMdr: Bit,
bClk: Bit,
writeMd: Bit,
readMaxBar: Bit,
mbIdle: Bit,
blank1: [0..4) ← 3, -- ?? found these set in old MB file
ioCmd: Bit,
clearCmdBar: Bit,
readCmd: Bit,
writeCmd: Bit,
clearAd: Bit,
readMarBar: Bit,
readMapBar: Bit,
readMdrBar: Bit,
blank2: [0..256) ← 0 ];
StartNewMemory["Multibus", 24];
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;
END;
PutTimeStamp: PROC [name: ROPE] =
BEGIN
PutWord[4]; -- Define (fake) Memory
memory ← memory + 1;
PutWord[memory];
PutWord[8];
name ← Rope.Cat[name, " of ", Convert.RopeFromTime[Loader.BCDBuildTime[DoIt]]];
PutRope[name];
END;
StartNewMemory: PROC [name: ROPE, bitsPerWord: CARDINAL] =
BEGIN
PutWord[4]; -- Define Memory
memory ← memory + 1;
PutWord[memory];
PutWord[bitsPerWord];
PutRope[name];
PutWord[2]; -- Set Current Memory
PutWord[memory];
PutWord[0]; -- Current PC
END;
PutRope: PROC [rope: ROPE] =
BEGIN
IO.PutRope[mb, rope];
PutByte[0]; -- End of string
IF (rope.Length[] MOD 2) = 0 THEN PutByte[0]; -- Round up to word
END;
PutWord: PROC [data: CARDINAL] = TRUSTED
BEGIN
IO.PutChar[mb, LOOPHOLE[data/256, CHAR]];
IO.PutChar[mb, LOOPHOLE[data, CHAR]];
END;
PutByte: PROC [data: CARDINAL] = TRUSTED
BEGIN
IO.PutChar[mb, LOOPHOLE[data, CHAR]];
END;
DoIt: PROCEDURE =
BEGIN
mb ← FS.StreamOpen["DCP-Multibus.mb", $create];
PutTimeStamp["DCP-Multibus.mb"];
Multibus[];
PutWord[0]; -- End of data marker
IO.Close[mb];
mb ← NIL;
END;
DoIt[];
END.