<> <> <<>> <> <> <> <> <> <<>> <<>> 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: BOOLEAN _ TRUE; -- 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; <