-- Error prom (revsion E)
-- for Rev B & up CP’s
-- last edited by R. Garner on April 8, 1980 1:08 AM
-- File: ErrorProm.mesa in [Iris]<Workstation>LH>CPPromsMesa-C.dm
--
and in [Iris]<Workstation>LH>CPProms-C.press

DIRECTORY
ImageDefs: FROM "ImageDefs"
USING [StopMesa],
PromBlowDefs: FROM "PromBlowDefs"
USING [WritePromData, WritePromList];

ErrorProm: PROGRAM IMPORTS ImageDefs, PromBlowDefs =
BEGIN OPEN PromBlowDefs;

Size:
CARDINAL = 1024;-- number of prom locations
addrWidth:
CARDINAL = 10;-- number of prom address bits
dataWidth:
CARDINAL = 4;-- number of prom output data bits

-- Note: a "n" at the end of a name indicates it is an active low signal, i.e. assigning
FALSE means that it represents a true state.

Addr: TYPE = MACHINE DEPENDENT RECORD -- Right-justified
[pad: [0..77B],
IBEmpty: BOOLEAN,
EmuMemErrc1: BOOLEAN,
CSParErr: BOOLEAN,
StackErr: BOOLEAN,
VirtAddrErrc2: BOOLEAN,
ClrIntErrn: BOOLEAN,
CtEmu: BOOLEAN,
Cycle1: BOOLEAN,
EKErrn: [0..3]];

Output:
TYPE = MACHINE DEPENDENT RECORD -- Left-justified
[EKTrapc2n: BOOLEAN,
EKTrapc2: BOOLEAN,
EKErrn: [0..3],
pad: [0..7777B]];

Prom:
ARRAY [0..Size] OF Output;
A: Addr;
Out: Output;
GenErrorProm: PROCEDURE =
BEGIN
i: CARDINAL;

-- values of EKErr’

IBEmptyErr: CARDINAL = 0;
StackErr: CARDINAL = 1;
EmuMemoryErr: CARDINAL = 2;-- Double bit mem err if MStatus[0]=1 ELSE Virtual address out of range.
NoErr: CARDINAL = 3;-- implies CSParErr when EKErr read at loc 0.

FOR i IN [0..Size) DO
A ← LOOPHOLE[i];
Out.EKTrapc2 ←FALSE;-- init to no error
Out.EKErrn ← A.EKErrn;-- assume current value

-- EKErr only holds one error condition. Thus if multiple errors occur only one of ’em is reported. The priority of error reporting is: 1) Double bit mem error, 2) stack error, 3) virt addr out of range, and 4) IB Empty Error. Note that the CSPar error is independently (and always) reported.

IF ~A.ClrIntErrn THEN Out.EKErrn ← NoErr;-- reset to no errors
IF Out.EKErrn = NoErr THEN-- If currently no errors look for new one.
Out.EKErrn ← SELECT TRUE FROM
A.EmuMemErrc1 => EmuMemoryErr,
A.StackErr => StackErr,
(A.VirtAddrErrc2 AND A.CtEmu) => EmuMemoryErr,
A.IBEmpty => IBEmptyErr,
ENDCASE => NoErr;

-- If EKErr is non-zero (indicating an emulator error) and it is c1 and the emulator is running, then EKErrc2 is asserted. This causes the microinstruction which will be read in c3 (and executed in c1) to be fetched from location 0. (Note that 0 is written in the emulator’s TPC in c3 if the emulator doesn’t run next.)

-- In general, if a stack error (any c), virtual address error (c1), or memory error (c3) occur, then at most one additional emulator click will run before the emulator is at location 0 in c1. If an IO click immediately follows the errored emulator click or the following click is aborted, then an addtional emulator click will not execute. Usually the operands that caused or point to the error (such as memory address, cs address, Mesa pc, L, G, etc.) are lost.

IF (Out.EKErrn#NoErr AND A.Cycle1 AND A.CtEmu) THEN Out.EKTrapc2 ← TRUE;

-- If CSParErr is true and it is c1, then the kernel will run in the next click (by command of the ScheduleProm). (If it is c2 or c3 and CSParErr is true, KernReq’ will not be acknowledged by the ScheduleProm until the next c2, assuring that the ErrorProm will see CSParErr in time to assert its EKTrapc2.)

--Thus a CS parity error overrides the emulator errors since the Kernel superceeds the emulator in the Schedule Prom. Note that the SwitchProm does not cause a task switch when entering the Kernel, so location 0 will be the kernel’s starting point, not the location given by the kernel’s TPC.

-- The CSParErr line is also sent to the IOP, which will pole the line. If true (after doublechecking it), the IOP will activate IOPWait & display a number in the maintance panel.

IF (A.CSParErr AND A.Cycle1 AND A.ClrIntErrn) THEN Out.EKTrapc2 ← TRUE;

-- Note that the instruction at location 0 must ClrIntErr and read EKErr, else the ErrorProm will cause another trap to location 0.

Out.EKTrapc2n ← ~Out.EKTrapc2;
Prom[i] ← Out;
ENDLOOP;
END;


GenErrorProm[];
WritePromData["ErrorProm-RevE", addrWidth, dataWidth, @Prom[0]];
WritePromList["ErrorProm-RevE", addrWidth, dataWidth, @Prom[0]];
ImageDefs.StopMesa[]

END.