MITest: RosemaryUser.TestProc ~ {
PROC [cellType: Core.CellType, p: Ports.Port, Eval: PROC]
SwapBits:
PROC[value: BitOps.BitWord]
RETURNS [newvalue: BitOps.BitWord] = {
oldc: BitOps.BitWord ← value;
newvalue ← 0;
FOR i:
NAT ← 0, i+1
WHILE i < 16
DO
newvalue ← BitOps.IBIW[BitOps.EBFW[oldc, i, 16], newvalue, 15-i, 16];
ENDLOOP;
};
Parityof:
PROC [value:
CARD, size:
NAT]
RETURNS [bit:
NAT] = {
p: BitOps.BitWord ← 0;
FOR i:
NAT ← 0, i + 1
WHILE i < size
DO
p ← BitOps.WXOR[p, BitOps.ECFD[value, i, 1, size]];
ENDLOOP;
bit ← p;
};
HiParity:
PROC[hival:
CARD]
RETURNS [p:
NAT] = {
p ← Parityof[hival, 6];
};
DataParity:
PROC[data, tag:
CARD]
RETURNS [p:
NAT] = {
p ← BitOps.WXOR[Parityof[data, 32], Parityof[tag, 2]];
};
SetPVal:
PROC [port, value:
CARD] = {
IF (port = XA) OR (port = XD) THEN value ← SwapBits[value];
SELECT p[port].levelType
FROM
l => p[port].l ← IF value=0 THEN L ELSE H;
ls => Ports.LCToLS[value, p[port].ls];
c => p[port].c ← value;
lc => p[port].lc ← value;
b =>
SELECT value
FROM
0 => p[port].b ← FALSE;
1 => p[port].b ← TRUE;
ENDCASE => ERROR;
ENDCASE => ERROR;
};
RasDecode:
PROC [rasval:
NAT]
RETURNS [
NAT] = {
RETURN[
IF refreshinprogress
THEN 0
ELSE
SELECT rasval
FROM
0 => 0EH,
1 => 0DH,
2 => 0BH,
3 => 07H,
7 => 0FH,
ENDCASE => ERROR];
};
RasXDecode:
PROC [rasval:
NAT]
RETURNS [
NAT] = {
RETURN[
IF refreshinprogress
THEN 1
ELSE
SELECT rasval
FROM
0 => 01H,
1 => 01H,
2 => 01H,
3 => 01H,
7 => 00H,
ENDCASE => ERROR];
};
SetP:
PROC [port, value:
CARD] = {
SetPVal[port, value];
p[port].d ← force;
IF port = XA THEN curriopaddr ← value;
IF port = XPD THEN lastpd ← value;
};
ClrP:
PROC [port:
CARD] = {
SELECT p[port].levelType
FROM
l => p[port].l ← X;
ls => Ports.SetLS[p[port].ls, X];
c => p[port].c ← 0;
lc => p[port].lc ← 0;
b => p[port].b ← FALSE;
ENDCASE => ERROR;
p[port].d ← none;
};
ChkP:
PROC [port, value:
CARD] = {
SetPVal[port, value];
p[port].d ← expect;
};
ChkX:
PROC [port:
CARD] = {
ClrP[port];
p[port].d ← expect;
};
GoClock:
PROC [cycles:
NAT ← 1, extraEval:
BOOL ←
FALSE] = {
saveddrives: ARRAY [0..50] OF Ports.Drive;
ExpectsOff:
PROC = {
FOR i:
NAT ← 0, i + 1
WHILE i < p.size
DO {
-- Turn off Expects
saveddrives[i] ← p[i].d;
IF p[i].d = expect THEN p[i].d ← none;
};
ENDLOOP;
};
ExpectsOn:
PROC = {
FOR i:
NAT ← 0, i + 1
WHILE i < p.size
DO
-- Turn on Expects
p[i].d ← saveddrives[i];
ENDLOOP;
};
FOR i:
NAT ← 0, i + 1
WHILE i < cycles
DO {
-- Do clock cycles
IF refreshcycle
AND ~refreshhold
THEN {
refreshhold ← TRUE;
refreshinprogress ← TRUE;
ClockMemory1[3, 2, 0, 0];
ClockMemory2[FALSE, FALSE];
ClockMemory3[0];
ClockMemory4[];
GoClock[3];
refreshcycle ← FALSE;
refreshhold ← FALSE;
refreshrq ← FALSE;
refreshinprogress ← FALSE;
};
ExpectsOff[]; -- checks off
IF extraEval THEN Eval[]; -- Setup Values
extraEval ← FALSE;
SetP[XCLOCK2,0]; -- clock 0
Eval[]; -- Setup Values
ExpectsOn[]; -- Turn on expects
SetP[XCLOCK2,1]; -- clock 1
Eval[];
oddclock ← ~oddclock;
IF refreshrq
AND ~refreshcycle
THEN refreshcycle ←
TRUE;
IF (BitOps.
WAND[lastrefresh,
8000H] # 0)
AND ~oddclock
THEN {
refreshcount ← refreshcount - 1;
IF refreshcount = 0
THEN {
refreshrq ← TRUE;
refreshcount ← BitOps.WAND[lastrefresh, 0FFFH] + 1;
};
};
};
ENDLOOP;
};
SyncClock:
PROC = {
IF oddclock THEN GoClock[];
};
WriteLatch:
PROC [addr, value:
CARD] = {
-- Write value to the indicated MI latch
SetP[XA, addr];
SetP[XIOWbar, 1];
SetP[XD, value];
SetP[XIORDY, 1];
GoClock[1, addr = statuslatch];
SetP[XIOWbar, 0];
SetP[XCEbar, 0];
ChkP[XIORDY, 1];
GoClock[];
SetP[XIOWbar, 1];
SetP[XCEbar, 1];
ClrP[XIORDY];
GoClock[];
ClrP[XD];
ClrP[XA];
IF addr = statuslatch THEN laststatus ← value; -- save last status
IF addr = addrlatch THEN lastaddr ← value; -- save last addr
IF addr = refreshlatch
THEN {
lastrefresh ← value; -- save last refresh
refreshcount ← BitOps.WAND[lastrefresh, 0FFFH] + 1; -- init refresh counter
refreshrq ← BitOps.WAND[lastrefresh, 8000H] # 0;
};
};
ReadLatch:
PROC [addr, value:
CARD] = {
-- Read value from the indicated MI latch & compare with expected value
SetP[XA, addr];
SetP[XIORbar,1];
SetP[XIORDY,1];
GoClock[];
SetP[XIORbar,0];
SetP[XCEbar, 0];
ChkP[XD,value];
IF (addr = statuslatch)
AND statusignore
THEN
FOR i: NAT IN [14..15] DO p[XD].ls[i] ← X; ENDLOOP;
ChkP[XIORDY, 1];
GoClock[];
ClrP[XD];
ClrP[XA];
SetP[XIORbar,1];
SetP[XCEbar, 1];
ClrP[XIORDY];
GoClock[];
};
ClockMemory1:
PROC [delay1, delay2, holddelay:
NAT, casval:
NAT ← 1] = {
-- Clock Through the sequencer of a memory operation
-- Get to Hold logic & delay HOLDA for holddelay
ChkP[XWENTbar, 1];
ChkP[XWENWbar, 1];
GoClock[delay1-1];
ChkP[XHOLD, 1];
GoClock[];
IF Basics.
BITAND[laststatus, 8] = 0
THEN {
FOR i: NAT ← holddelay, i - 1 WHILE i > 0 DO GoClock[]; ENDLOOP;
SetP[XHOLDA, 1];
};
GoClock[delay2-1];
ChkP[XCASbar, casval];
GoClock[];
};
CasPA:
PROC
RETURNS[
CARD] = {
RETURN[
Basics.DoubleOr[
Basics.DoubleAnd[
Basics.DoubleShiftRight[[lc[curriopaddr]], 2],
[li[01FFH]]],
Basics.DoubleAnd[
Basics.DoubleShiftLeft[[lc[lastaddr]], 9],
[li[0200H]]]
].lc];
};
RasPA:
PROC
RETURNS[
CARD] = {
RETURN[
Basics.DoubleAnd[
Basics.DoubleShiftRight[[lc[lastaddr]], 1],
[li[03FFH]]].lc];
};
ClockMemory2:
PROC [checkwe:
BOOL ←
FALSE, do2ndclock:
BOOL ←
TRUE] = {
rasval: NAT ← Basics.DoubleAnd[Basics.DoubleShiftRight[[lc[lastaddr]], 11], [li[07H]]].lc;
rasdecodedval: NAT ← RasDecode[rasval];
-- Check for RAS & Ras Address
ChkP[XRASbar, rasdecodedval];
ChkP[XRASXbar, RasXDecode[rasval]];
ChkP[
XPA,
IF rasval = 7
THEN CasPA[]
ELSE RasPA[]];
GoClock[];
ClrP[XPA]; -- PA only on 1st RAS'
IF checkwe
THEN
-- Check WE on a write
{ ChkP[XWENTbar, 0]; ChkP[XWENWbar, 0]; };
IF do2ndclock THEN GoClock[];
};
ClockMemory3:
PROC [memdelay:
NAT] = {
Check for CAS & Cas Address
ChkP[XCASbar, 0];
SetP[XMEMRDY, IF memdelay = 0 THEN 1 ELSE 0];
GoClock[];
IF p[XRASXbar].l = H THEN ClrP[XPA]; -- Only 1 PA on CAS'
-- Test for MEMRDY delay
IF memdelay # 0
THEN {
FOR i: NAT ← memdelay, i - 1 WHILE i > 0 DO GoClock[]; ENDLOOP;
SetP[XMEMRDY, 1];
IF BitOps.WAND[memdelay, 1] = 1 THEN GoClock[];
};
-- Clear CAS' / RAS' / PA / RASX' / PD
ClrP[XIORDY];
ClrP[XCASbar];
ClrP[XRASbar];
ClrP[XRASXbar];
ClrP[XPD];
ClrP[XPDTAG];
ClrP[XPDHI];
ClrP[XPA];
ClrP[XPDTP];
ClrP[XPDWP];
ClrP[XWENTbar];
ClrP[XWENWbar];
ClrP[XHOLD];
GoClock[];
};
ClockMemory4:
PROC = {
SetP[XIORDY, 1];
SetP[XIORbar, 1];
SetP[XIOWbar, 1];
SetP[XCEbar, 1];
ClrP[XD];
ClrP[XA];
SetP[XHOLDA, 0];
GoClock[];
ChkP[XWENTbar, 1];
ChkP[XWENWbar, 1];
ChkP[XIORDY, 1];
GoClock[];
ClrP[XIORDY];
ClrP[XWENTbar];
ClrP[XWENWbar];
};
ReadMemory:
PROC [addr, memval, hival:
CARD, hibyte, badhiparity, baddataparity:
BOOL ←
FALSE, holddelay, memdelay:
NAT ← 0] = {
wordsel:
CARD ←
Basics.DoubleAnd[Basics.DoubleShiftRight[[lc[addr]], 1],
[li[1]]].lc;
rsltval:
CARD ←
IF hibyte
THEN hival
ELSE
Basics.DoubleAnd[
Basics.DoubleShiftRight[[lc[memval]], IF wordsel = 1 THEN 16 ELSE 0],
[lc[0FFFFH]]].lc;
tagval:
CARD ← Basics.DoubleAnd[[lc[hival]], [li[3]]].lc;
delay1: NAT ← 4 + Basics.BITAND[holddelay, 1];
delay2: NAT ← 2;
newaddr: CARD ← Basics.DoubleShiftRight[[lc[addr]], 11].lc;
hival ← Basics.DoubleShiftRight[[lc[hival]], 2].lc;
-- Set Latch with Upper part of address & Status Reg
IF lastaddr # newaddr THEN WriteLatch[addrlatch, newaddr];
IF hibyte
THEN WriteLatch[statuslatch, Basics.DoubleOr[[lc[laststatus]], [lc[1]]].lc]
ELSE WriteLatch[statuslatch, Basics.DoubleAnd[[lc[laststatus]], [lc[0FFFEH]]].lc];
Sync Clock
SyncClock[];
-- Do Memory Read, Setup Chip Select & Address
SetP[XHOLDA, 0];
SetP[XCEbar, 0];
SetP[XA, Basics.DoubleAnd[[lc[addr]],[li[07FFH]]].lc];
GoClock[];
SetP[XIORbar, 0];
ChkP[XIORDY, 0];
refreshhold ← TRUE;
-- Get through 1st clocking sequence
ClockMemory1[delay1, delay2, holddelay];
ClockMemory2[];
Set up values to read
SetP[XPD, memval];
SetP[XPDTAG, tagval];
SetP[XPDHI, hival];
SetP[XPDTP, BitOps.WXOR[HiParity[hival], LOOPHOLE[badhiparity]]];
SetP[XPDWP, BitOps.WXOR[DataParity[memval, tagval], LOOPHOLE[baddataparity]]];
-- Get through Cas' clocking sequence
ClockMemory3[memdelay];
-- Check for returned data
ChkP[XD, rsltval];
GoClock[2];
ClockMemory4[];
refreshhold ← FALSE;
};
WriteMemory:
PROC [addr, memval, hival, writeval:
CARD, hibyte, badhiparity, baddataparity:
BOOL ←
FALSE, holddelay, memdelay:
NAT ← 0] = {
wordsel:
CARD ←
Basics.DoubleAnd[Basics.DoubleShiftRight[[lc[addr]], 1],
[li[1]]].lc;
newmemval: CARD;
newhival, newtagval: CARD;
ioop: BOOL ← FALSE;
tagval:
CARD ←
Basics.DoubleAnd[[lc[hival]], [li[3]]].lc;
delay1: NAT ← 4 + Basics.BITAND[holddelay, 1];
delay2: NAT ← 2;
newaddr: CARD ← Basics.DoubleShiftRight[[lc[addr]], 11].lc;
hival ← Basics.DoubleShiftRight[[lc[hival]], 2].lc;
newhival ← hival;
newtagval ← tagval;
IF hibyte
THEN {
newhival ← Basics.DoubleShiftRight[
Basics.DoubleAnd[ [lc[writeval]], [lc[0FCH]]], 2].lc;
newtagval ← Basics.DoubleAnd[ [lc[writeval]], [lc[3H]]].lc;
};
-- Set Latch with Upper part of address & Status Reg
IF lastaddr # newaddr THEN WriteLatch[addrlatch, newaddr];
IF hibyte
THEN WriteLatch[statuslatch, Basics.DoubleOr[[lc[laststatus]], [lc[1]]].lc]
ELSE WriteLatch[statuslatch, Basics.DoubleAnd[[lc[laststatus]], [lc[0FFFEH]]].lc];
ioop ← RasXDecode[Basics.DoubleAnd[Basics.DoubleShiftRight[[lc[lastaddr]], 11], [li[07H]]].lc] # 1;
Sync Clock
SyncClock[];
-- Do Memory Read
SetP[XCEbar, 0];
SetP[XHOLDA, 0];
SetP[XA, Basics.DoubleAnd[[lc[addr]],[li[07FFH]]].lc];
GoClock[];
ChkP[XIORDY, 0];
SetP[XIOWbar,0];
SetP[XD, writeval];
refreshhold ← TRUE;
ClockMemory1[delay1, delay2, holddelay];
IF~ ioop
THEN {
-- Read Word Before Writing, unless an IO operation
ClockMemory2[];
-- Set Values to Read
SetP[XPD, memval];
SetP[XPDTAG, tagval];
SetP[XPDHI, hival];
SetP[XPDTP, BitOps.WXOR[HiParity[hival], LOOPHOLE[badhiparity]]];
SetP[XPDWP, BitOps.WXOR[DataParity[memval, tagval], LOOPHOLE[baddataparity]]];
-- Check for CAS & Cas Address
ClockMemory3[memdelay];
GoClock[2];
};
-- 3. WRITE Merged word ------------------------------------
-- Check for RAS & Ras Address
ClockMemory2[TRUE];
-- Check for CAS & Cas Address, data written
newmemval ←
IF hibyte
THEN lastpd
ELSE
Basics.DoubleOr[
Basics.DoubleAnd[ [lc[lastpd]],
Basics.DoubleShiftLeft[[lc[0FFFFH]], IF wordsel = 1 THEN 0 ELSE 16]],
Basics.DoubleShiftLeft[[lc[writeval]], IF wordsel = 1 THEN 16 ELSE 0]].lc;
ChkP[XPD, newmemval];
IF ~ ioop
THEN {
ChkP[XPDTAG, newtagval];
ChkP[XPDHI, newhival];
ChkP[XPDTP, HiParity[newhival]];
ChkP[XPDWP, DataParity[newmemval, newtagval]];
};
ClockMemory3[memdelay];
4. Clear time ---------------------------------------------
ClockMemory4[];
GoClock[3];
refreshhold ← FALSE;
};
ChipReady:
PROC = {
-- Set all pads of the chip so it is ready for input
& remove x's from the chip.
oddclock ← FALSE;
statusignore ← TRUE;
refreshcycle ← FALSE;
refreshhold ← FALSE;
refreshrq ← FALSE;
refreshinprogress ← FALSE;
lastrefresh ← 0;
refreshcount ← 0;
SetP[Gnd, 0];
SetP[Vdd, 1];
SetP[PadGnd, 0];
SetP[PadVdd, 1];
p[Vdd].b ← TRUE;
p[PadVdd].b ← TRUE;
-- Set IOP side 1st
SetP[XA, 0];
SetP[XD, 0];
SetP[XIOWbar, 1];
SetP[XIORbar, 1];
SetP[XCEbar, 1];
ClrP[XIORDY];
SetP[XHOSTRESET, 1];
ClrP[XHINT];
-- Set MI to LP pins
ClrP[XLPRESET];
ClrP[XHOLD];
SetP[XHOLDA, 0];
SetP[XPIRQ, 0];
ClrP[XXIRQ0];
-- Set Memory Pins
ClrP[XPDWP];
ClrP[XPDTP];
ClrP[XPDTAG];
ClrP[XPDHI];
ClrP[XPD];
-- Set Memory Control Pins
ClrP[XCASbar];
ClrP[XRASbar];
ClrP[XRASXbar];
ClrP[XPA];
SetP[XMEMRDY, 1];
ClrP[XWENTbar];
ClrP[XWENWbar];
-- Clock Pins
GoClock[4];
clear reset
Set the Latches
WriteLatch[statuslatch, 0800H];
GoClock[2];
SetP[XHOSTRESET, 0];
GoClock[12, TRUE];
ChkP[XLPRESET, 1]; -- Check for LPRESET = 1
WriteLatch[refreshlatch, 0]; -- Clear refresh counter
WriteLatch[addrlatch, 0]; -- Clear address latch
ClrP[XLPRESET]; -- Don't for LPRESET
WriteLatch[statuslatch, 1000H]; -- Clear LPRESET
GoClock[4];
ChkP[XLPRESET, 0]; -- Check for LPRESET = 0
WriteLatch[statuslatch, statusregreset];
ClrP[XLPRESET]; -- Don't for LPRESET
statusignore ← FALSE;
ReadLatch[statuslatch, statusregreset]; -- Read Status Reg
ReadLatch[refreshlatch, 0]; -- Read refreshcounter
ReadLatch[addrlatch, 0]; -- Read address latch
ReadMemory[0, 0, 0]; -- Clear Parity Errors
ReadMemory[1C00010H, 0, 0]; -- Read IO port
WriteMemory[1C00010H, 0, 0, 0]; -- Write IO port
WriteLatch[statuslatch, statusregreset]; -- Write Status Reg
};
ChkNClk:
PROC [port, value:
CARD] = {
ChkP[port, value];
GoClock[];
ClrP[port];
};
TestStatReg:
PROC = {
-- Test Bits in Status Regs
bits: 0 - Tag Parity Error
1 - Data Parity Error
2 - PIRQ
3 - Reset LPRESET
4 - Set LPRESET
5 - Enable Parity IRQ
6 - Reset PIRQ
7 - Reset Parity Error
8 - Enable PIRQ
12- Hold Ignore
13- Dint2 (XIRQ1)
14- XIRQ0
15- Hi Byte Select
-- Test XIRQ0
WriteLatch[statuslatch, statusregreset];
WriteLatch[statuslatch, 2]; -- Set XIRQ0
ChkP[XXIRQ0, 1]; -- Check for XIRQ0 = 1
GoClock[];
ClrP[XXIRQ0];
WriteLatch[statuslatch, statusregreset];
ChkP[XXIRQ0, 0]; -- Check for XIRQ0 = 0
GoClock[];
ClrP[XXIRQ0];
Test PIRQ logic
SetP[XPIRQ, 0];
WriteLatch[statuslatch, 0200H]; -- Clr PIRQ bit
ReadLatch[statuslatch, 0200H]; -- Latch should be clear
WriteLatch[statuslatch, 0080H]; -- Enable PIRQ
SetP[XPIRQ, 1]; -- Set PIRQ
GoClock[];
ChkP[XHINT, 1];
ReadLatch[statuslatch, 2080H]; -- Should have PIRQ & HINT
ClrP[XHINT];
SetP[XPIRQ, 0];
GoClock[];
ReadLatch[statuslatch, 2080H]; -- Should Still have PIRQ & HINT
WriteLatch[statuslatch, 0200H]; -- Clr PIRQ bit
ChkP[XHINT, 0];
GoClock[];
ReadLatch[statuslatch, 0200H]; -- Latch & HINT should be clear
WriteLatch[statuslatch, 0000H]; -- Clr Latch
SetP[XPIRQ, 1]; -- Set PIRQ
GoClock[];
ReadLatch[statuslatch, 2000H]; -- Should have PIRQ but no HINT
SetP[XPIRQ, 0];
ClrP[XHINT];
WriteLatch[statuslatch, statusregreset];
};
TestRefresh:
PROC = {
-- Refresh Count Register:
Bit: 0 - Enale Refresh Counter
4-15 Refresh Counter
Test Refresh Cycles
WriteLatch[refreshlatch, 8010H];
GoClock[100];
WriteLatch[refreshlatch, 0000H];
WriteLatch[refreshlatch, 8040H];
FOR i:
NAT ← 0, i+1
WHILE i < 10
DO {
ReadMemory[0, 0, 0];
GoClock[30];
};
ENDLOOP;
-- WriteLatch[refreshlatch, 0000H];
};
TestLatches:
PROC = {
-- Test Ability to Read / Write Internal Latches
ReadMemory[0, 0, 0];
WriteLatch[statuslatch, statusregreset];
-- Test Status Reg
FOR val:
ILIST ←
LIST [
0, 1, 2, 4, 8, 16, 32, 64, 128,
100H, 200H, 400H, statusregreset], val.rest
WHILE val #
NIL
DO
WriteLatch[statuslatch, val.first];
ReadLatch[statuslatch, val.first];
ENDLOOP;
-- Test Refresh Count Reg
FOR val:
ILIST ←
LIST[
0, 1, 2, 4, 8, 16, 32, 64, 128, 255, 100H, 200H, 400H, 800H], val.rest
WHILE val #
NIL
DO
WriteLatch[refreshlatch, val.first];
ReadLatch[refreshlatch, val.first];
ENDLOOP;
-- Test Address Latch
FOR val:
ILIST ←
LIST[0, 1, 2, 4, 8, 16, 32, 64, 128, 255,
100H, 200H, 400H, 800H, 1000H, 2000H, 4000H, 8000H, 0FF00H, 0FFFFH], val.rest
WHILE val #
NIL
DO
WriteLatch[addrlatch, val.first];
ReadLatch[addrlatch, val.first];
ENDLOOP;
Test Bits in Status Regs
TestStatReg[];
WriteLatch[statuslatch, statusregreset];
ReadMemory[0, 0, 0];
WriteLatch[statuslatch, statusregreset];
TestRefresh[];
WriteLatch[statuslatch, statusregreset];
WriteLatch[statuslatch, statusregnorm];
WriteLatch[refreshlatch, 0];
};
RandomMemoryTest:
PROC = {
addr: CARD;
RandomBool:
PROC
RETURNS [
BOOL] = {
RETURN[IF Random.ChooseInt[rs, 0, 1] = 0 THEN FALSE ELSE TRUE]};
RandomCard:
PROC [hi:
CARD, alt:
CARD ← 0]
RETURNS [
CARD] = {
IF (alt # 0) AND (Random.ChooseInt[rs, 0, 15] = 15) THEN RETURN[alt]
ELSE
RETURN[
Basics.DoubleOr[
Basics.DoubleShiftLeft[
[lc[Random.ChooseInt[rs, 0, Basics.DoubleShiftRight[ [lc[hi]], 16].lc ] ]],
16],
Basics.DoubleAnd[
[lc[Random.ChooseInt[rs, 0, Basics.DoubleAnd[ [lc[hi]], [lc[0FFFFH]] ].lc] ]],
[lc[0FFFFH]] ]
].lc
]
};
rs ← Random.Create[];
FOR i:
CARD ← 0, i + 1
WHILE i < 100
DO
addr ← RandomCard[08FFFFFH, 1C00000H];
IF RandomBool[]
THEN
ReadMemory[
addr,
RandomCard[0FFFFFFFFH],
RandomCard[0FFH],
IF addr = 1C00000H THEN FALSE ELSE RandomBool[],
FALSE,
FALSE,
RandomCard[10],
RandomCard[10]]
ELSE
WriteMemory[
addr,
RandomCard[0FFFFFFFFH],
RandomCard[0FFH],
RandomCard[0FFFFH],
IF addr = 1C00000H THEN FALSE ELSE RandomBool[],
FALSE,
FALSE,
RandomCard[10],
RandomCard[10]];
ENDLOOP;
};
TestMemory:
PROC = {
MemoryReadTest:
PROC = {
Test Memory Reads
ReadMemory[0, 0, 0, FALSE, FALSE, FALSE, 6, 9];
Go through some specific locations
FOR addr:
ILIST ←
LIST [
1C00000H, 0, 1, 2, 4, 8, 16, 32, 64, 128,
100H, 200H, 400H, 800H, 1000H, 2000H, 4000H, 8000H,
10000H, 20000H, 40000H, 80000H, 100000H, 200000H, 400000H, 800000H, 100000H, 200000H, 400000H, 800000H, 7FFFFFH ], addr.rest
WHILE addr #
NIL
DO
ReadMemory[addr.first ,0, 0, FALSE];
ReadMemory[addr.first ,0FFFFH, 0, FALSE];
ReadMemory[addr.first ,0, 3, FALSE, FALSE, FALSE, 7];
ReadMemory[addr.first ,0, 003FH, FALSE];
ReadMemory[addr.first ,0FFFFH, 003FH, FALSE];
ReadMemory[addr.first , 0, 0FFH, TRUE];
ReadMemory[addr.first , 0, 0AAH, TRUE];
ENDLOOP;
};
MemoryWriteTest:
PROC = {
-- Write Memroy Test
WriteMemory[0, 0, 0, 0, FALSE];
WriteMemory[0, 0, 0, 0, FALSE, FALSE, FALSE, 6];
Go through some specific locations
FOR addr:
ILIST ←
LIST [
1C00000H, 0, 1, 2, 4, 8, 16, 32, 64, 128,
100H, 200H, 400H, 800H, 1000H, 2000H, 4000H, 8000H,
10000H, 20000H, 40000H, 80000H, 100000H, 200000H, 400000H, 800000H, 100000H, 200000H, 400000H, 800000H, 7FFFFFH ], addr.rest
WHILE addr #
NIL
DO
WriteMemory[addr.first ,0, 0, 0FFFFH, FALSE];
WriteMemory[addr.first ,0FFFFH, 0, 0AAAAH, FALSE];
WriteMemory[addr.first ,0, 3, 5555H, FALSE, FALSE, FALSE, 2];
WriteMemory[addr.first ,0, 003FH, 055AA, FALSE];
WriteMemory[addr.first ,0FFFFH, 003FH, 0AA55H, FALSE];
IF addr.first #
1C00000H
THEN {
WriteMemory[addr.first , 0, 0FFH, 55H, TRUE];
WriteMemory[addr.first , 0, 0AAH, 0FFH, TRUE];
};
ENDLOOP;
};
ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 6];
ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 7];
ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 0, 3];
ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 0, 4];
ReadMemory[0 ,0, 0, FALSE, FALSE, FALSE, 3, 4];
ReadMemory[1C00000H ,0, 0, FALSE, FALSE, FALSE, 4, 5];
WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 4, 0];
WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 5, 0];
WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 0, 6];
WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 0, 7];
WriteMemory[0 ,0, 0, 0, FALSE, FALSE, FALSE, 5, 6];
WriteMemory[1C00000H ,0, 0, 0, FALSE, FALSE, FALSE, 6, 7];
MemoryWriteTest[];
MemoryReadTest[];
};
ParityTest:
PROC = {
-- Test the parity error detection & interrupt lines
-- Setup / clear status reg
WriteLatch[statuslatch, statusregreset];
WriteLatch[statuslatch, statusregnorm];
ChkP[XHINT, 0];
ReadLatch[statuslatch, statusregnorm];
-- Read with Tag Parity Error
ReadMemory[0,0,0, FALSE, TRUE, FALSE];
ReadLatch[statuslatch, statusregnorm + 8000H];
-- Turn on Interrupt Enable & check HINT
ClrP[XHINT];
WriteLatch[statuslatch, statusregnorm + 0400H];
ChkP[XHINT, 1];
ReadLatch[statuslatch, statusregnorm + 8400H];
-- Clear Interrupt Enable & check HINT cleared
ClrP[XHINT];
WriteLatch[statuslatch, statusregnorm];
ChkP[XHINT, 0];
GoClock[];
-- Clear Tag Parity Error
ReadMemory[0,0,0];
WriteLatch[statuslatch, statusregnorm + 0100H];
ReadLatch[statuslatch, laststatus];
WriteLatch[statuslatch, statusregnorm];
-- Read with Data Parity Error
ReadMemory[0,0,0, FALSE, FALSE, TRUE];
ReadLatch[statuslatch, statusregnorm + 4000H];
-- Turn on Interrupt Enable & check HINT
ClrP[XHINT];
WriteLatch[statuslatch, statusregnorm + 0400H];
ChkP[XHINT, 1];
ReadLatch[statuslatch, statusregnorm + 4400H];
-- Clear Interrupt Enable & check HINT cleared
ClrP[XHINT];
WriteLatch[statuslatch, statusregnorm];
ChkP[XHINT, 0];
GoClock[];
-- Clear Data Parity Error
ReadMemory[0,0,0];
WriteLatch[statuslatch, statusregnorm + 0100H];
ReadLatch[statuslatch, laststatus];
WriteLatch[statuslatch, statusregnorm];
ClrP[XHINT];
};