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:
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
Add comment
Comments