TestMultibus.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Gasbarro October 6, 1986 2:20:27 pm PDT
Last Edited by: Gasbarro October 9, 1986 9:33:47 am PDT
Last edited by: Christian Jacobi, January 8, 1987 6:14:22 pm PST
DIRECTORY
Basics, IO, Process, Rope, LogViewer, XBus;
This program is designed to test the connection between a DTiger and a Multibus memory card. The connection is via a Busmaster interface board. The likely fault areas are the cable connecting the DTiger processor and the Busmaster, and the Busmaster board itself. The Multibus memory card should be configured to respond to addresses starting at location zero and should be at least one megabyte in size. Byte addressing is not tested.
TestMultibus: CEDAR PROGRAM
IMPORTS Basics, IO, Process, LogViewer, XBus
~ BEGIN
first: LONG POINTER = LOOPHOLE[LONG[0]];
last: LONG POINTER = LOOPHOLE[0FFFFEh];
page: LONG POINTER = LOOPHOLE[01FFFEh];
gpibBoard: LONG POINTER = LOOPHOLE[LONG[8000H]];
dataSize: CARDINAL = 16;
addSize: CARDINAL = 19;
weirdConst: CARDINAL = 0AAAAh;
errors: LONG CARDINAL ← 0;
Test: PROC [passes: CARDINAL ← 1] ~ {
w: WORD;
data: WORD;
lc: LONG CARDINAL;
add: LONG POINTER;
errors ← 0;
LogViewer.PutRope["\nStarting Test\n"];
FOR p: CARDINAL IN [0..passes) DO
R/W zero
LogViewer.PutRope["Checking first word of memory...\n"];
XBus.MemWrite[first, 0];
IF (data ← XBus.MemRead[first])#0 THEN ReportError[first, data, 0];
XBus.MemWrite[first, 0FFFFh];
IF (data ← XBus.MemRead[first])#0FFFFh THEN ReportError[first, data, 0FFFFh];
LogViewer.PutRope["Checking last word of memory...\n"];
XBus.MemWrite[last, 0];
IF (data ← XBus.MemRead[last])#0 THEN ReportError[last, data, 0];
XBus.MemWrite[last, 0FFFFh];
IF (data ← XBus.MemRead[last])#0FFFFh THEN ReportError[last, data, 0FFFFh];
left shift a one data bit
LogViewer.PutRope["Checking data bits...\n"];
w ← 1;
FOR i: NAT IN [0..dataSize) DO
XBus.MemWrite[LOOPHOLE[LONG[2*i]], w];
w ← Basics.BITSHIFT[w, 1];
ENDLOOP;
w ← 1;
FOR i: NAT IN [0..dataSize) DO
add ← LOOPHOLE[LONG[2*i]];
IF (data ← XBus.MemRead[add])#w THEN ReportError[add, data, w];
w ← Basics.BITSHIFT[w, 1];
ENDLOOP;
left shift a zero data bit
w ← 0FFFEh;
FOR i: NAT IN [0..dataSize) DO
XBus.MemWrite[LOOPHOLE[LONG[2*i]], w];
w ← Basics.BITSHIFT[w, 1]+1;
ENDLOOP;
w ← 0FFFEh;
FOR i: NAT IN [0..dataSize) DO
add ← LOOPHOLE[LONG[2*i]];
IF (data ← XBus.MemRead[add])#w THEN ReportError[add, data, w];
w ← Basics.BITSHIFT[w, 1]+1;
ENDLOOP;
left shift a one address bit (even addresses only)
LogViewer.PutRope["Checking address bits...\n"];
lc ← 2;
FOR i: NAT IN [0..addSize) DO
XBus.MemWrite[LOOPHOLE[lc], i];
lc ← Basics.DoubleShiftLeft[LOOPHOLE[lc], 1].lc;
ENDLOOP;
lc ← 2;
FOR i: NAT IN [0..addSize) DO
add ← LOOPHOLE[lc];
IF (data ← XBus.MemRead[add])#i THEN ReportError[add, data, i];
lc ← Basics.DoubleShiftLeft[LOOPHOLE[lc], 1].lc;
ENDLOOP;
left shift a zero address bit (even addresses only)
lc ← 0FFFFFCh;
FOR i: NAT IN [0..addSize) DO
XBus.MemWrite[LOOPHOLE[lc], i];
lc ← Basics.DoubleShiftLeft[LOOPHOLE[lc], 1].lc+2;
ENDLOOP;
lc ← 0FFFFFCh;
FOR i: NAT IN [0..addSize) DO
add ← LOOPHOLE[lc];
IF (data ← XBus.MemRead[add])#i THEN ReportError[add, data, i];
lc ← Basics.DoubleShiftLeft[LOOPHOLE[lc], 1].lc+2;
ENDLOOP;
LogViewer.PutRope["Exchange test, increasing addresses...\n"];
FOR i: LONG POINTER ← first, i+2 WHILE i#last DO
XBus.MemWrite[i, 0];
ENDLOOP;
FOR i: LONG POINTER ← first, i+2 WHILE i#last DO
IF (data ← XBus.MemRead[i])#0 THEN ReportError[i, data, 0];
XBus.MemWrite[i, 0FFFFh];
ENDLOOP;
FOR i: LONG POINTER ← first, i+2 WHILE i#last DO
IF (data ← XBus.MemRead[i])#0FFFFh THEN ReportError[i, data, 0FFFFh];
ENDLOOP;
LogViewer.PutRope["Exchange test, decreasing addresses...\n"];
FOR i: LONG POINTER ← last, i-2 WHILE i#first DO
XBus.MemWrite[i, 0];
ENDLOOP;
FOR i: LONG POINTER ← last, i-2 WHILE i#first DO
IF (data ← XBus.MemRead[i])#0 THEN ReportError[i, data, 0];
XBus.MemWrite[i, 0FFFFh];
ENDLOOP;
FOR i: LONG POINTER ← last, i-2 WHILE i#first DO
IF (data ← XBus.MemRead[i])#0FFFFh THEN ReportError[i, data, 0FFFFh];
ENDLOOP;
IF passes>1 THEN LogViewer.PutF["End pass %g\n", IO.int[p]];
ENDLOOP;
LogViewer.PutF["Done! Errors: %g\n", IO.int[errors]];
};
AddressTest: PROC [passes: CARDINAL ← 1] ~ {
data: WORD;
errors ← 0;
LogViewer.PutRope["\nStarting AddressTest\n"];
FOR p: CARDINAL IN [0..passes) DO
--clear the block
FOR i: LONG POINTER ← first, i+2 WHILE i#last DO
XBus.MemWrite[i, 0];
ENDLOOP;
--write into it
FOR i: LONG POINTER ← first, i+2 WHILE i#last DO
XBus.MemWrite[i, Basics.LowHalf[LOOPHOLE[i]]];
ENDLOOP;
--read it back
FOR i: LONG POINTER ← first, i+2 WHILE i#last DO
IF (data ← XBus.MemRead[i])#Basics.LowHalf[LOOPHOLE[i]] THEN {
ReportError[i, data, 0FFFFh];
data ← Basics.LowHalf[LOOPHOLE[i]];
FOR k: LONG POINTER ← first, k+2 WHILE k#last DO
IF XBus.MemRead[k]=data THEN
LogViewer.PutF["Found %g at %g\n", IO.int[data], IO.int[LOOPHOLE[k]]];
ENDLOOP;
};
ENDLOOP;
IF passes>1 THEN LogViewer.PutF["End pass %g\n", IO.int[p]];
ENDLOOP;
LogViewer.PutF["Done! Errors: %g\n", IO.int[errors]];
};
ReadWriteTest: PROC [passes: CARDINAL ← 1] ~ {
data: WORD;
errors ← 0;
LogViewer.PutRope["\nStarting ReadWriteTest\n"];
FOR p: CARDINAL IN [0..passes) DO
FOR i: LONG POINTER ← first, i+2 WHILE i#last DO
XBus.MemWrite[i, weirdConst];
ENDLOOP;
FOR i: LONG CARDINAL IN [0..1000000) DO
Process.CheckForAbort[];
XBus.MemWrite[first, 0];
IF (data ← XBus.MemRead[first])#0 THEN ReportAndScan[first, data, 0];
IF (data ← XBus.MemRead[first])#0 THEN {
XBus.IOWrite[gpibBoard, 0]; --for scope triggering
ReportError[first, data, 0];
};
XBus.MemWrite[first, 0FFFFh];
IF (data ← XBus.MemRead[first])#0FFFFh THEN ReportAndScan[first, data, 0FFFFh];
IF (data ← XBus.MemRead[first])#0FFFFh THEN {
XBus.IOWrite[gpibBoard, 0]; --for scope triggering
ReportError[first, data, 0FFFFh];
};
ENDLOOP;
IF passes>1 THEN LogViewer.PutF["End pass %g\n", IO.int[p]];
ENDLOOP;
LogViewer.PutF["Done! Errors: %g\n", IO.int[errors]];
};
ReportError: PROC [address: LONG POINTER, read, expected: WORD] ~ {
errors ← errors+1;
IF XBus.MemRead[address]#expected THEN LogViewer.PutRope["Hard error, "]
ELSE LogViewer.PutRope["Soft error, "];
LogViewer.PutF["address: %g, read: %g, expected: %g\n", IO.int[LOOPHOLE[address]], IO.int[read], IO.int[expected]];
};
ReportAndScan: PROC [address: LONG POINTER, read, expected: WORD] ~ {
data: WORD;
ReportError[address, read, expected];
FOR i: LONG POINTER ← first, i+2 WHILE i#last DO
IF (data ← XBus.MemRead[i])#weirdConst AND i#address THEN LogViewer.PutF["Found %g at %g\n", IO.int[data], IO.int[LOOPHOLE[i]]];
ENDLOOP;
};
WriteLoop: PROC ~ {
DO
Process.CheckForAbort[];
XBus.MemWrite[first, 0];
XBus.MemWrite[last, 0FFFFh];
ENDLOOP;
};
ReadLoop: PROC ~ {
DO
Process.CheckForAbort[];
[] ← XBus.MemRead[first];
[] ← XBus.MemRead[last];
ENDLOOP;
};
END.