GaBuZoMeu wrote:
Doing a RAM test on a 6502 system is somewhat more difficult than with any (?, perhaps most) other 8 bit CPUs because the 6502 lacks a 16 bit register. In order to address any location you need at least two reliable RAM cells in page 0.
Any 6502 (or 65C802/65C816 in emulation mode) RAM test is going to need some zero page (ZP) storage to test absolute RAM, which means ZP itself has to first be qualified, using only the MPU's registers during testing. Fortunately, MPU registers alone can touch all of ZP.
The first step would be to write at least two different checkerboard patterns (conventionally,
%10100101 and
%01011010) to all ZP locations, execute a short delay and then compare the accumulator (which has the test pattern) against all test locations. If that procedure succeeds, it tells us ZP can be addressed and apparently is able to hold data.
The next test would be walking bits. Walking bits would take two forms to be thorough. The first would write
%00000000 into the test location, set carry and then rotate 9 times. Here it gets interesting. Ideally, the bit shifted from carry into the test location will be the only bit circulating in that memory cell. That being the case, carry should be set when the loop exits. However, that doesn't prove the memory cell didn't mess up. The final test would be to load the accumulator from the test location to prove that it is still contains
%00000000. If it doesn't, a bit ended up getting "stuck" on and the test has failed. The following is code that does this test:
Code:
*=$2000
;
ldx #0 ;ZP location index
txa ;initialize
sec ;test "bit"
;
loop0010 sta $00,x ;clear test cell
ldy #9 ;bit shift iterations
;
loop0020 rol $00,x ;rotate away
dey ;step counter
bne loop0020 ;not done
;
bcc badram ;RAM defective...abort
;
lda $0,x ;any "stuck" bits?
bne badram ;yes, bad RAM...abort
;
inx ;we done?
bne loop0010 ;no, do next
;
clc ;good ZP RAM
brk ;done
nop
;
badram sec ;bad ZP RAM
brk ;done
nop
Naturally, the above code would be in ROM. Execution time according to the Kowalski simulator is 29,959 clock cycles.
The next test would be inverted walking bits. In this one, the pattern
%11111111 is written into the test location, carry is cleared and 9 rotations are executed. If carry is cleared when the loop exits, the test location is incremented, which should change its contents to
%00000000. If it doesn't there is a bit stuck off and the test has failed. The following is code that does this test:
Code:
*=$2000
;
ldx #0 ;ZP location index
clc ;test "bit"
;
loop0030 lda #%11111111 ;initialize...
sta $00,x ;test cell
ldy #9 ;bit shift iterations
;
loop0040 rol $00,x ;rotate away
dey ;step counter
bne loop0040 ;not done
;
bcs badram ;RAM defective...abort
;
inc $0,x ;any "stuck" bits?
bne badram ;yes, bad RAM...abort
;
inx ;we done?
bne loop0030 ;no, do next
;
brk ;good ZP RAM...done
nop
;
badram sec ;bad ZP RAM
brk ;done
nop
Execution time is 30,979 cycles. All ZP locations will be cleared when testing has successfully completed.
Beyond that, the really paranoid among us would do individual address line testing. That would mean writing different patterns into the ZP addresses that correspond to only one bit in the LSB of the address being set. Hence the test addresses would be
$0000,
$0001,
$0002,
$0004,
$0008,
$0010,
$0020,
$0040 and
$0080. After a short delay, each of those locations would be checked to see if the unique pattern for that location is present. Needless to say, a compare error would mean there's a major hardware malfunction.
If ZP survives these tests absolute RAM testing can commence, since ZP should be trustworthy for pointers and counters. The same test regimen could be used on absolute RAM, assuming you are willing to endure what could be a lengthy test, even on a 65C02 system running a 14 MHz. The first step would be to qualify the stack, using the same regimen used on ZP. If stack RAM checks out, your test functions can safely call subroutines and otherwise make use of the stack. The address line test would be similar to that for ZP, except the address pattern would be
$0100,
$0200,
$0400,
$0800,
$1000,
$2000,
$4000 and
$8000.
The address line tests can also be inverted so that only one of the address lines is at logic zero.
In a 65C816 system with extended RAM, detailed testing could take a long time. There are two approaches to testing extended RAM: using 16-bit indexing and incrementing the
DB register each time the end of a bank is reached, or using a 24-bit direct page (DP) pointer to touch extended RAM. The former method should be faster, since all 24-bit addressing modes incur a one clock cycle penalty compared to their 16-bit counterparts. Also, the first method allows the RAM in each bank to be accessed with DP addressing, since the 16-bit index will effectively make direct page appear as 64KB of RAM. I haven't actually tested either method to date, but will once POC V2 is fully operational.