123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- ; code: language=asm-collection tabSize=8
- ; Requirements:
- ; This function must be RELOCATABLE (only relative jumps), and use NO RAM or STACK.
- ; These restrictions lead to somewhat long-winded, repetative code.
- ;; March C- algorithm:
- ;; 1: (up w0) write each location bottom to top with test value
- ;; 2: (up r0,w1) read each location bottom to top, compare to test value, then write complement
- ;; 3: (up r1,w0) read each location bottom to top, compare to complement, then write test value
- ;; 4: (dn r0,w1) read each location top to bottom, compare to test value, then write complement
- ;; 5: (dn r1,w0) read each location top to bottom, compare to complement, then write test value
- ;; 6: (dn r0) read each location top to bottom, compare to test value
- ; Arguments:
- ; hl = current memory position under test
- ; bc = bytes remaining to test
- ; iy = test data structure
- ; returns:
- ; e = all errored bits found in this block/bank/range of memory
- ; destroys: a,bc,d,hl
- ; preserves: ix
- memtestmarch:
- xor a
- ld e,a ; reset error accumulator
- ld d,a ; set the first testing value to 0
- checkabsent: ; quick test for completely missing bank
- memtest_ld_hl_base
- ld b,h
- ld c,1
- cpl ; A := FF
- .redo ld (hl),a ; write FF to base
- cpl ; A := 0
- ld (bc),a ; write 00 to base+1
- cp (hl) ; compare to base (should be FF, should not match)
- jr z,.allbad ; if they match, all bits are bad, but double-check
- cp 0 ; are we on the first round?
- jr z,.redo ; yes, redo with reversed bits
- jr mtm1
- .allbad:
- ld e,$FF ; report all bits bad
- jr mtm_done_bounce
- mtm1:
- memtest_loadregs
- mtm1loop: ; fill initial value upwards
- ld (hl),d
- inc hl
- dec bc
- ld a,c
- or b
- jr nz,mtm1loop
- mtm2: ; read value, write complement upwards
- memtest_loadregs
- mtm2loop:
- ld a,(hl)
- cp d ; compare to value
- jr z, mtm2cont ; memory changed, report
- xor d ; calculate errored bits
- or e
- ld e,a ; save error bits to e
- ld a,d ; reload a with correct value
- mtm2cont:
- cpl ; take the complement
- ld (hl),a ; write the complement
- inc hl
- dec bc
- ld a,c
- or b
- jr nz,mtm2loop
-
- mtm3: ; read complement, write original value upwards
- memtest_loadregs
- mtm3loop:
- ld a,(hl)
- cpl
- cp d ; compare to the complement
- jr z, mtm3cont ; memory changed, report
- xor d ; calculate errored bits
- or e
- ld e,a ; save error bits to e
- ld a,d ; reload a with correct value
- mtm3cont:
- ld (hl),d ; fill with test value
- inc hl
- dec bc
- ld a,c
- or b
- jr nz,mtm3loop
- jr mtm4
-
- mtm_done_bounce:
- jr mtm_done
- mtm1_bounce:
- jr mtm1
- mtm4: ; read test value, write complement downwards
- memtest_loadregs
- add hl,bc ; move to end of the test area
- dec hl
- mtm4loop:
- ld a,(hl)
- cp d ; compare to value
- jr z, mtm4cont
- xor d ; calculate errored bits
- or e
- ld e,a ; save error bits to e
- ld a,d ; reload a with correct value
- mtm4cont:
- cpl ; take the complement
- ld (hl),a ; write complement
- dec hl
- dec bc
- ld a,c
- or b
- jr nz,mtm4loop
- mtm5: ; read complement, write value downwards
- memtest_loadregs
- add hl,bc ; move to end of the test area
- dec hl
- mtm5loop:
- ld a,(hl)
- cpl
- cp d
- jr z, mtm5cont
- xor d ; calculate errored bits
- or e
- ld e,a ; save error bits to e
- ld a,d ; reload a with correct value
- mtm5cont:
- ld (hl),d
- dec hl
- dec bc
- ld a,c
- or b
- jr nz,mtm5loop
-
- mtm6: ; final check that all are zero
- memtest_loadregs
- add hl,bc ; move to end of the test area
- dec hl
- mtm6loop:
- ld a,(hl)
- cp d
- jr z,mtm6cont
- xor d ; calculate errored bits
- or e
- ld e,a ; save error bits to e
- ld a,d ; reload a with correct value
- mtm6cont:
- dec hl
- dec bc
- ld a,c
- or b
- jr nz,mtm6loop
- mtmredo:
- ld a,d
- cp 0 ; if our test value is 0
- ld d,$55
- jr z,mtm1_bounce ; then rerun the tests with value $55
- mtm_done:
- sub a ; set carry flag if e is nonzero
- or e
- mtm_return:
- ret z
- scf
- ret
- memtestmarch_end equ $
- ;-----------------------------------------------------------------------------
|