; MMTEST.a -- Mass Memory test

        include gbl.i
        org GBL_4K
        jmp mmtest
        include debug.i
        include ioports.i

nwords  equ 4  ; 16 bytes per read/write

;pat1    db 00Ah,0A0h,00Ah,0A0h,00Ah,0A0h,00Ah,0A0h
;        db 00Ah,0A0h,00Ah,0A0h,00Ah,0A0h,00Ah,0A0h
;        db 00Ah,0A0h,00Ah,0A0h,00Ah,0A0h,00Ah,0A0h
;        db 00Ah,0A0h,00Ah,0A0h,00Ah,0A0h,00Ah,0A0h
pat1     ds 16
genramp: lxi h,pat1
        mvi a,0
        mvi c,16
g22:    mov M,a
        inx h
        inr a
        dcr c
        jnz g22
        ret

nerrs    ds 1

p_mm_addr ds 2

; HL - points to starting MM address to test
; Each call tests 1024 words
; Return: 
;   A=0 - success
;   A=1 - error; HL points to address of bad MM word
mmtest: 
        shld p_mm_addr

        call genramp

        mvi a,0
        sta nerrs

; select pattern
        lxi h,pat1
        lxi d,report_pattern
        mvi c,4*nwords
        call copy_bytes

; setup address for Dump command

; write pattern in all MM
        call mm_zero    ; MM addr=0
loop1:  call task
        out WATCHDOG_PET_O
; write pattern
        lxi b,nwords
        lxi d,mm_addr
        lxi h,report_pattern
        call MM_STORE
; next MM address
        call add_to_addr
; has MM address passed max?
        lda mm_addr+1
        cpi 1
        jnz loop1
 call debug_asc
 asc "readback$"

; zero the readback area
        mvi a,0
        mvi c,75
        lxi h,rest_of_pkt
zrba:   mov M,a
        inx h
        dcr c
        jnz zrba

; Now read it back
        call mm_zero    ; MM addr=0
loop2:  call task
        out WATCHDOG_PET_O
; read pattern back
        lxi b,nwords
        lxi d,mm_addr
        lxi h,report_readback
        call MM_FETCH

; compare with pattern
        lxi h,report_pattern
        lxi d,report_readback
        mvi c,4*nwords
loop3:  ldax d
        cmp M
        jnz eroar
        inx h
        inx d
        dcr c
        jnz loop3
        jmp next

eroar:  call debug_asc
        asc " **error: addr, wrote, got back$"
        lxi h,report_mm_addr
        mvi c,4
        call debug_dump
        lxi h,report_pattern
        mvi c,16
        call debug_dump
        lxi h,report_readback
        call debug_dump

; stop after generating 16 error packets
        lda nerrs
        inr a
        sta nerrs
        cpi 16
        jz quit

next:
; next MM address
        call add_to_addr
; has MM address passed max?
        lda mm_addr+1
        cpi 1
        jnz loop2

; send "OK" dump
        mvi a,090h
        sta packet_id
        lxi h,packet_id
        mvi a,09h       ; ApID = 709
        lxi b,152       ; total packet length
;***        lhld sq09       ; this ApID's source sequence number
        xchg            ; in DE
        lxi h,packet_id ; point to data
        call CCSDS_SEND ; generate CCSDS and send it out


quit:
        call debug_asc
        asc "MMTEST done.$"
        pop h
        pop d
        pop b
        pop psw
        ret

cinc    db 0,0,0,nwords

add_to_addr:
        lxi h,cinc+3   ; low byte of increment
; 4-byte add
        lxi d,mm_addr+3
        ldax d  ; byte 3

        add M             
        stax d
        dcx d
        dcx h

        ldax d  ; byte 2
        adc M           ; add with carry 
        stax d
        dcx d
        dcx h

        ldax d  ; byte 1
        adc M           ; add with carry 
        stax d
        dcx d
        dcx h

        ldax d  ; byte 0
        adc M           ; add with carry 
        stax d
        
        ret

; set MM address 0
mm_zero:
        mvi a,0
        sta mm_addr
        sta mm_addr+1
        sta mm_addr+2
        sta mm_addr+3
        ret

