; Memory Test
; Two kind of tests are executed
; 1. Pattern test using bit-patterns defined in mempatt where memory is filled 
;    with this patterns and tested for correctness
; 2. Pseudo-random test where memory is filled with pseudo-random content and 
;    tested for correctness afterwards
; Test-result is stored to storage variable (view with memory view)
; 1. Word is Error-count
; For Pattern-test only faulty address is written to storage,
; for Memory-test #2 (pseudo-random) two long words (32 bit) are written 
;  - faulty address (long), 
;  - expected value (16bit) and value read from memory (16 bit) is written
; To test different memory regions adopt MEM_START and MEM_LEN below.
; TAKE CARE!!! ORG address below needs to be outside of tested Memory area!!!


       org $90000    ; Needs to be outside of MEM_START:MEM_LEN
MEM_START equ $400   ; Start-address of memory range to be tested
MEM_LEN equ $80000   ; number of bytes to be tested

start:
        lea mempatt(pc),a2    ; A2 points to Memory pattern list
        lea patt_buf(pc),a3   ;
        lea storage(pc),a1
        clr.l d3                ; Fehler-counter
        move.l d3,(a1)+         ; First word is error-count
        clr.l (a1)

;        bra memt2            ; uncomment to skip test #1

; Memory-test #1 -> Patter test
loop1:
        move.b (a2)+,d0        ; Get Pattern
        tst.b d0
        beq.s memt2             ; done with pattern testing
        move.w d0,-(a7)         ; backup D0
        bsr print1

        lea MEM_START,a0
        move.l #MEM_LEN,d1
        move.w (a7)+,d0         ; Restore D0
        bsr memset              ; Fill memory with pattern


        lea MEM_START,a0
        move.l #MEM_LEN,d6
        bsr dupl                 ; create 32bit word from pattern (duplicate 4 times)
        move.l d0,(a3)+          ; write to pattern buffer - for debug
;        move.w #((MEM_LEN/4)&$FFFF)-1,d6  ;Low
;        move.w #((MEM_LEN/4)/65536),d7    ;HIGH
        lsr.l #2,d6     ; div by 4
        subq.l #1,d6    ; prepare for dbra
        move.l d6,d7    ; low word of MEM_LEN in d6
        swap d7         ; high word of MEM_LEN in d7

m1:     move.l (a0)+,d1 ; Read memory content
        cmp.l d0,d1     ; And compare it with pattern
        beq.s equal
;        bra.s equal
mm:
        move.l a0,d2    ; Memory error detected!
        subq.l #4,d2
        move.l d2,(a1)+ ; Store erroneous address
        addq.w #1,d3    ; Increment Fehler counter

        cmp.w #10,d3    ; Abort after 10 errors
        bhs.s stop
equal:  dbra d6,m1
        dbra d7,m1
;        move.l a0,debug2
        bra.s loop1

memt2:  ; Memory-test #2 -> fill with ascending numbers
        lea MEM_START,a0
        move.l #MEM_LEN,d6
        clr.w d0
        move.w #$cf31,d4        ; xor value
        lsr.l #1,d6     ; div by 2
        subq.l #1,d6    ; prepare for dbra
        move.l d6,d7
        swap d7
        movem.l d4/d6-d7/a0,-(a7)
        
mt1:    move.w d0,d1
        eor.w d4,d1

        move.w d1,(a0)+
        addq.w #1,d0
        add.w #4232,d4  ; Make values pseudo-random
        rol.w #1,d4
        dbra d6,mt1
        dbra d7,mt1

; Now test memory content
        movem.l (a7)+,d4/d6-d7/a0
        clr.w d0
mt2:
        move.w d0,d2
        eor.w d4,d2

        move.w (a0)+,d1
        cmp.w d2,d1     ; Memory content correct?
        beq.s mt3
        move.l a0,d5
        subq.l #2,d5
        move.l d5,(a1)+ ; 1. Store address
        move.w d2,(a1)+ ; 2. store soll
        move.w d1,(a1)+ ; 3. store ist
        addq.w #1,d3    ; Increment Fehler counter

        cmp.w #10,d3    ; Abort after 10 errors
        bhs.s stop
mt3:
        addq.w #1,d0
        add.w #4232,d4
        rol.w #1,d4
        dbra d6,mt2
        dbra d7,mt2

stop:   lea storage(pc),a1
        move.l d3,(a1)
        rts
; Addresse in A0 - nees to be align(4)
; value in d0.b
; len d1.l
memset: bsr.s dupl
        lsr.l #2,d1     ; div by 4
        subq.l #1,d1    ; prepare for dbra
        move.l d1,d2
        swap d2
mset1:  move.l d0,(a0)+
        dbra d1, mset1
        dbra d2, mset1
        move.l a0,debug1
        rts
        
;duplicate byte in d0.b to 32bit
dupl:   movem.l d2/d7,-(a7)   ; 
        clr.l d2
        move.b d0,d2
        and.l #$ff,d0
        moveq #3-1,d7
l1:
        lsl.l #8,d2
        or.l d2,d0
        dbra d7,l1
        movem.l (a7)+,d2/d7
        rts

print1: lea buffer(pc),a0
        jsr @print2x
        clr.b (a0)
        lea buffer(pc),a0
p1:     move.b (a0)+,d0
        tst.b d0
        beq.s p2
        jsr @co2
        bra.s p1
 p2:    move.b #' ',d0
        jsr @co2
        rts


mempatt: dc.b $55,$aa,$01,$02,$04,$08,$10,$20,$40,$80,0
ds 0
debug1: ds.l 1
debug2: ds.l 1
buffer: ds.b 16
patt_buf: ds.l 10
storage:
; 1. Word is Error-count
; For Pattern-test only faulty address is written to storage,
; for Memory-test #2 (pseudo-random) two long words (32 bit) are written 
;  - faulty address (long), 
;  - expected value (16bit) and value read from memory (16 bit) is written
