1802 Memory Test

Published on 3 December 2023 at 14:16

I wrote this memory test program while restoring an ELF II 4K ram board. I've included the ASM as well as the HEX file which was compiled using Michael Kohn's excellent light-weight assemblers.


The program runs in a 256 byte 'page' and tests any memory above that page. Note that the test proceeds from the END of the test memory up to, and not including, the page that the program is running in. The ASM file is configured to not display each test page as it is tested and to loop continuously. You can change that in the assembler source if desired.

Assembler listing in naken assembler format.

Instructions for use is in the ASM file.

// Memory Test (c) 2023 Geekgineering - Tim Stoddard 
// You must start this program with R0=P @ 0xXX00 or R3=P @ 0xXX02 as the program counter
// an array of bytes to use for testing stored after the program must end with 0x00 
// this signals the final test to be performed of storing and comparing 0x00
// any number of test bytes can be used as long as the array ends with 0x00
// This program tests at a minimum of one page
// I'm calling a 'test page' as a 256 byte block... IE: 0x0200 to 0x02ff is a 'page'
// Program will run using each test byte in the array writing all of the test memory and then comparing that back
// ... by setting Q during the writing of each test byte and output port displaying test pages
// ... then will read each location back with Q not set and the output port displaying test pages 
// ... after all of the test bytes in the array have been used
// ... The end result is either 0xA1 (Q lit) for passage or 0xEE (Q lit) for an error
// Upon an error pressing the input key will cycle the output to:
// 1st press) Test location high byte (Q is lit)
// 2nd press) Test location low byte (Q is not lit)
// 3rd press) Test byte used (Q is not lit)
// 4th press) byte read from the test location (Q is not lit)
// subsequent presses cycles through the above 4 steps moving backward in test memory
// R1=X output port pointer R3=program R5=mtest subroutine R8.1=last page to test R8.0=test byte
// R9=X test pointer RA= test byte array RB= pass counter
// Memory test routine writes byte from R8.0 to memory pages defined in R8.1 starting from END of test memory
// working backwards to the end of the page containing this test program: 0x{R3.1}ff

.1802
.org    0x0000      // coded to run on the start of any page
        ghi 0       // start here 0xXX00 if entering with R0=P
        phi 3       // setup R3 as program counter if running stand-alone
        ldi start   // start here 0xXX02 if entering with R3=P
        plo 3
mret:
        sep 3       // return to caller - if just starting this begins the program
mtest:              // entry to subroutine for testing a page (256 bytes) using a test byte in R8.0
        ghi 8       // setup X R9 pointer to end of test memory
        phi 9
        ldi 0xff    // point to last location of end page
        plo 9
        seq         // signal memory write
wloop:              // write loop
        sex 9       // set X for memory testing
        glo 8       // get the test byte
        stxd        // store the test byte via R9 (X) and decrement
        sex 1       // point to work area
        ghi 9       // get current page  of test memory
        str 1       // store it via R1 (X)
//        out 4       // display current testing page
//        dec 1       // stay on work location
        ghi 3       // get program run page
        sd          // compare to current test page
        bnz wloop   // continue while test page is higher than program run page, otherwise you hit location 0x{R3}ff
        ghi 8       // setup X R9 pointer to end of test memory again, to prepare for read/compare
        phi 9
        ldi 0xff    // point to last location of end page
        plo 9
        req         // signal memory read
rcloop:             // read/compare loop
        sex 9       // set X for memory testing
        glo 8       // get the test byte
        sd          // compare test byte to memory
        bnz error   // error found!
        dec 9       // otherwise decrement and continue
        sex 1       // point to work area
        ghi 9       // get current page of test memory 
        str 1       // store it via R1 (X)
//        out 4       // display current testing page
//        dec 1       // stay on work location
        ghi 3       // get program run page
        sd          // compare to current test page
        bnz rcloop  // continue while test page is higher than program run page, otherwise you hit location 0x{R3}ff
        ldi 0xa1    // A1 completion - no errors
        str 1       // store for output
        out 4       // display passing code
        dec 1       // stay on work location
        br  mret    // finished without errors. return to calling program
error:
        sex 1       // set X for output
        ldi 0xee    // indicate error
        str 1
        out 4
        dec 1       // stay on work area
eloop:
        sex 1       // while in loop switch X back to work area for output
        bn4 $       //wait for input key
        ghi 9       // get high test memory pointer
        str 1
        out 4       // display it
        dec 1       // stay on work area
        seq         // Q signals start of error readout (page number)
        b4  $       // wait for input key release
        bn4 $       //wait for input key
        req
        glo 9       // get low test memory pointer
        str 1
        out 4       // display it
        dec 1       // stay on work area
        b4  $       // wait for input key release
        bn4 $       //wait for input key
        glo 8       // get test byte
        str 1
        out 4       // display it
        dec 1       // stay on work area
        b4  $       // wait for input key release
        bn4 $       //wait for input key
        sex 9       // point X to test memory and get the stored test byte
        out 4       // display it
        dec 9       // decrement twice to move pointer backward
        dec 9
        b4  $       // wait for input key release
        br  eloop   // read backward through test memory

start:
        req         // clear Q
        ldi 0       // clear pass counter
        phi b
        plo b
        ghi 3       // setup pointers
        phi 5       // in R5 for subroutine
        phi a       // in RA for test byte array
        phi 1       // in R1 as X for output port work area
        ldi mtest
        plo 5
        ldi testend
        plo 1
        sex 1       // switch X for output
        bn4 $       // wait for key press
        inp 4       // read in keys for LAST 256 byte page to test
        out 4       // display it
        dec 1       // stay on work location
        phi 8       // store the end page in R8.1
        b4  $       // wait for key release
repeat:
        ldi array   // set RA.0 for array start
        plo a
        sex a       // switch X to byte array
bloop:
        ldx         // load test byte
        plo 8       // save it in R8.0
        str 1       // as well as work area for output
        sex 1
        out 4       // display it
        dec 1       // stay on work location
        sep 5       // run test using the byte
        sex a       // switch X to byte array
        ldxa        // check if test byte is also test terminator zero (and increment byte pointer for next test)
        bz  term    // if last test was also a terminator then end testing
        br bloop    // otherwise continue
term:
        br  repeat  // replace with nops to run just one pass and stop
        seq         // set Q
        idl         // and STOP
array:              // Follows is an array of test bytes to use... last byte should be zero to terminate
.dl     0x01020408  // test bytes
.dl     0x10204080  // test bytes
.dl     0x7fbfdfef  // test bytes
.dl     0xf7fbfdfe  // test bytes
.dl     0x55aaff00  // test bytes
.dl     0x00000000  // reserve some ram to separate work area
        
testend:

Mtest Hex
Plain text – 452.0 B 64 downloads

This HEX file version is modified to start at 0x0000 from reset and runs continuous passes displaying the test bytes as they are used. Q lights to show the write cycle on a page and then turns off during the read/verify of the test byte on the pages.

0000: 90B3 F85B A3D3 98B9 F8FF A97B E988 73E1
0010: 9951 93F5 3A0C 98B9 F8FF A97A E988 F53A
0020: 3029 E199 5193 F53A 1CF8 A151 6421 3005
0030: E1F8 EE51 6421 E13F 3799 5164 217B 373E
0040: 3F40 7A89 5164 2137 473F 4988 5164 2137
0050: 4F3F 51E9 6429 2937 5730 367A F800 BBAB
0060: 93B5 BAB1 F806 A5F8 A0A1 E13F 6B6C 6421
0070: B837 71F8 88AA EAF0 A851 E164 21D5 EA72
0080: 3284 3077 3073 7B00 0102 0408 1020 4080
0090: 7FBF DFEF F7FB FDFE 55AA FF00 0000 0000


Instructions:

To test the 4K board:

  • enter the program at 0x0000 and start it
  • it is now waiting for the top page to test. 0x0F for the 4K board... enter that in the hex keypad (OUT 4 will not display as you are entering)
  • press and release the input key
  • Program will now run continuously displaying the test byte as it tests backward from 0x0F to 0x01. Q LED is lit during write and off during read/verify of test byte
  • If there is an error while testing EE is displayed and Q lit  
  • and you will enter the error loop

 

Error loop (Loops from the first bad test location and decrementing for each loop pass)

  • Press and release input key
  • Q will light and the upper address being tested is displayed (Q lit signals the beginning of a new loop location)
  • Press and release input key
  • Q will extinguish and the lower address byte is displayed
  • Press and release the input key
  • The test byte used is displayed
  • Press and release the input key
  • The STORED byte is read and displayed, and memory pointer is decremented
  • loop back to start of error loop

Operational Demo Video

Add comment

Comments

There are no comments yet.