-- DES Slave Port Prom - Revision A - used in 16K CP’s to control the Encryption Option
-- Filed on [Indigo]<Dandelion>CPE>Proms>DesSpProm-RevA.mesa
-- This Prom is a Fairchild F93427 256 x 4 PROM
-- Last Edited by: TonyWest, January 23, 1983 2:02 PM
DIRECTORY
ImageDefsUSING [StopMesa],
PromBlowDefsUSING [WritePromData, WritePromList];
DesSpProm: PROGRAM IMPORTS ImageDefs, PromBlowDefs =
{promSize:CARDINAL = 256;-- number of prom locations
addressWidth:CARDINAL = 8;-- number of prom address bits
dataWidth:CARDINAL = 4;-- number of prom output data bits
State: TYPE = MACHINE DEPENDENT
{
-- Des Slave Port FSM State input and output fields are 2 bits wide.
Idle(0),
Reading(1),
Full(2),
(3)
};
-- NB: an "n" after a name means it is active LOW, i.e., assign FALSE to make it active.
PromInput: TYPE = MACHINE DEPENDENT RECORD
[-- Right-justified - upper byte unused
padding:[0..377B],-- 8-bit field
desSpState:State,-- 2-bit field
desSpError:BOOLEAN,
cycle1:BOOLEAN,
cycle2:BOOLEAN,
xBusFromDesn:BOOLEAN,-- Active-Low input
sFLGn:BOOLEAN,-- Active-Low input
unused:BOOLEAN
];
PromOutput: TYPE = MACHINE DEPENDENT RECORD
[-- Left-justified - lower 12 bits unused
nextDesSpState:State,-- 2-bit field
pDesSpError:BOOLEAN,
pSDS:BOOLEAN,
padding:[0..7777B]-- 12-bit field
];
desSpProm:ARRAY [0..promSize)OF PromOutput;
input:PromInput;
output:PromOutput;
-- Duplicate the inputs with logical true booleans
cycle1:BOOLEAN;
cycle2:BOOLEAN;
sFLG:BOOLEAN;
xBusFromDes:BOOLEAN;
-- This is not an input, it is deduced from cycle1 and cycle2
cycle3:BOOLEAN;
-- Duplicate the outputs with logical true booleans
nextDesSpState:State;
pDesSpError:BOOLEAN;
pSDS:BOOLEAN;
GenerateDesSpPromArray: PROC =
{FOR i: CARDINAL IN [0..promSize) DO
-- Initialise the input to the i-th bit-pattern
input ← LOOPHOLE[i];
-- Initialise the global input booleans to reflect the input state
-- Convert active-low inputs into logical true booleans
cycle1← input.cycle1;
cycle2← input.cycle2;
sFLG← NOT input.sFLGn;
xBusFromDes← NOT input.xBusFromDesn;
-- The Fsm only has inputs for cycle1 and cycle2. Deduce cycle3 as follows:
cycle3 ← NOT (cycle1 OR cycle2);
-- Set the global output booleans to their default values
-- By default, loop in the current state unless something changes this later on
-- If the Error signal is set, leave it set in the next state
-- These are logical true booleans, active-low outputs, if any, will be converted later
nextDesSpState← input.desSpState;
pDesSpError← input.desSpError;
pSDS← FALSE;
-- Now see what state we are in and set the global output booleans
SELECT input.desSpState FROM
Idle=>Idle[];
Reading=>Reading[];
Full=>Full[];
ENDCASE;
-- Set the Output bit-pattern to reflect the global output booleans
-- Invert the sense of any outputs which are active-low
output.nextDesSpState← nextDesSpState;
output.pDesSpError← pDesSpError;
output.pSDS← pSDS;
-- Now that we have assembled the Output bit-pattern, store it in the Prom array
desSpProm[i] ← output;
ENDLOOP;
};
Idle: PROC =
{
-- We are forced into this state by DesReset’ going active. We will remain in this state until DesReset’ is removed. Assertion and Removal of DesReset’ is synchronised with DesClk.
-- Test for error cases: can’t read data when there is none!
IF xBusFromDes THEN pDesSpError ← TRUE;
-- We loop in the current state (by default) until there is something to do.
IF cycle1 AND sFLG THEN
{pSDS ← TRUE;
nextDesSpState ← Reading;
};
};
Reading: PROC =
{
-- We are starting or in the middle of a SP read operation. Keep SDS asserted and loop into this state until we enter cycle3.
-- Test for error cases: can’t read data when FSM hasn’t finished reading it yet!
IF xBusFromDes THEN pDesSpError ← TRUE;
IF cycle3 THEN nextDesSpState ← Full ELSE pSDS ← TRUE;
};
Full: PROC =
{
-- In this state, we have finished an SP read operation, and we are waiting for the microcode to read the result out of the output latch. If the read takes place in cycle1, then a new SP read operation can be started in the next Des cycle, otherwise we return to Idle to wait until DesClk comes around again.
IF xBusFromDes THEN
{IF cycle1 AND sFLG THEN
{pSDS ← TRUE;
nextDesSpState ← Reading;
} ELSE nextDesSpState ← Idle;
};
-- If we get to here, then the microcode hasn’t tried to read the stored data yet. Simply loop (by default) and wait for the CP to get round to it.
};
GenerateDesSpPromArray[];
PromBlowDefs.WritePromData["DesSpProm-RevA", addressWidth, dataWidth, @desSpProm[0]];
PromBlowDefs.WritePromList["DesSpProm-RevA", addressWidth, dataWidth, @desSpProm[0]];
ImageDefs.StopMesa[]
}.