memtestmarch.asm 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. ; code: language=asm-collection tabSize=8
  2. ; Requirements:
  3. ; This function must be RELOCATABLE (only relative jumps), and use NO RAM or STACK.
  4. ; These restrictions lead to somewhat long-winded, repetative code.
  5. ;; March C- algorithm:
  6. ;; 1: (up w0) write each location bottom to top with test value
  7. ;; 2: (up r0,w1) read each location bottom to top, compare to test value, then write complement
  8. ;; 3: (up r1,w0) read each location bottom to top, compare to complement, then write test value
  9. ;; 4: (dn r0,w1) read each location top to bottom, compare to test value, then write complement
  10. ;; 5: (dn r1,w0) read each location top to bottom, compare to complement, then write test value
  11. ;; 6: (dn r0) read each location top to bottom, compare to test value
  12. ; Arguments:
  13. ; hl = current memory position under test
  14. ; bc = bytes remaining to test
  15. ; iy = test data structure
  16. ; returns:
  17. ; e = all errored bits found in this block/bank/range of memory
  18. ; destroys: a,bc,d,hl
  19. ; preserves: ix
  20. memtestmarch:
  21. xor a
  22. ld e,a ; reset error accumulator
  23. ld d,a ; set the first testing value to 0
  24. checkabsent: ; quick test for completely missing bank
  25. memtest_ld_hl_base
  26. ld b,h
  27. ld c,1
  28. cpl ; A := FF
  29. .redo ld (hl),a ; write FF to base
  30. cpl ; A := 0
  31. ld (bc),a ; write 00 to base+1
  32. cp (hl) ; compare to base (should be FF, should not match)
  33. jr z,.allbad ; if they match, all bits are bad, but double-check
  34. cp 0 ; are we on the first round?
  35. jr z,.redo ; yes, redo with reversed bits
  36. jr mtm1
  37. .allbad:
  38. ld e,$FF ; report all bits bad
  39. jr mtm_done_bounce
  40. mtm1:
  41. memtest_loadregs
  42. mtm1loop: ; fill initial value upwards
  43. ld (hl),d
  44. inc hl
  45. dec bc
  46. ld a,c
  47. or b
  48. jr nz,mtm1loop
  49. mtm2: ; read value, write complement upwards
  50. memtest_loadregs
  51. mtm2loop:
  52. ld a,(hl)
  53. cp d ; compare to value
  54. jr z, mtm2cont ; memory changed, report
  55. xor d ; calculate errored bits
  56. or e
  57. ld e,a ; save error bits to e
  58. ld a,d ; reload a with correct value
  59. mtm2cont:
  60. cpl ; take the complement
  61. ld (hl),a ; write the complement
  62. inc hl
  63. dec bc
  64. ld a,c
  65. or b
  66. jr nz,mtm2loop
  67. mtm3: ; read complement, write original value upwards
  68. memtest_loadregs
  69. mtm3loop:
  70. ld a,(hl)
  71. cpl
  72. cp d ; compare to the complement
  73. jr z, mtm3cont ; memory changed, report
  74. xor d ; calculate errored bits
  75. or e
  76. ld e,a ; save error bits to e
  77. ld a,d ; reload a with correct value
  78. mtm3cont:
  79. ld (hl),d ; fill with test value
  80. inc hl
  81. dec bc
  82. ld a,c
  83. or b
  84. jr nz,mtm3loop
  85. jr mtm4
  86. mtm_done_bounce:
  87. jr mtm_done
  88. mtm1_bounce:
  89. jr mtm1
  90. mtm4: ; read test value, write complement downwards
  91. memtest_loadregs
  92. add hl,bc ; move to end of the test area
  93. dec hl
  94. mtm4loop:
  95. ld a,(hl)
  96. cp d ; compare to value
  97. jr z, mtm4cont
  98. xor d ; calculate errored bits
  99. or e
  100. ld e,a ; save error bits to e
  101. ld a,d ; reload a with correct value
  102. mtm4cont:
  103. cpl ; take the complement
  104. ld (hl),a ; write complement
  105. dec hl
  106. dec bc
  107. ld a,c
  108. or b
  109. jr nz,mtm4loop
  110. mtm5: ; read complement, write value downwards
  111. memtest_loadregs
  112. add hl,bc ; move to end of the test area
  113. dec hl
  114. mtm5loop:
  115. ld a,(hl)
  116. cpl
  117. cp d
  118. jr z, mtm5cont
  119. xor d ; calculate errored bits
  120. or e
  121. ld e,a ; save error bits to e
  122. ld a,d ; reload a with correct value
  123. mtm5cont:
  124. ld (hl),d
  125. dec hl
  126. dec bc
  127. ld a,c
  128. or b
  129. jr nz,mtm5loop
  130. mtm6: ; final check that all are zero
  131. memtest_loadregs
  132. add hl,bc ; move to end of the test area
  133. dec hl
  134. mtm6loop:
  135. ld a,(hl)
  136. cp d
  137. jr z,mtm6cont
  138. xor d ; calculate errored bits
  139. or e
  140. ld e,a ; save error bits to e
  141. ld a,d ; reload a with correct value
  142. mtm6cont:
  143. dec hl
  144. dec bc
  145. ld a,c
  146. or b
  147. jr nz,mtm6loop
  148. mtmredo:
  149. ld a,d
  150. cp 0 ; if our test value is 0
  151. ld d,$55
  152. jr z,mtm1_bounce ; then rerun the tests with value $55
  153. mtm_done:
  154. sub a ; set carry flag if e is nonzero
  155. or e
  156. mtm_return:
  157. ret z
  158. scf
  159. ret
  160. memtestmarch_end equ $
  161. ;-----------------------------------------------------------------------------