<> <> <> <> <> DIRECTORY Basics, IO, Process, Rope, LogViewer, XBus; <> 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 <> 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]; <> 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; <> 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; <> 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; <> 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 { <> ReportError[first, data, 0]; }; XBus.MemWrite[first, 0FFFFh]; <> IF (data _ XBus.MemRead[first])#0FFFFh THEN { <> 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.