
;BOOT MEMORY TEST PROGRAM

	.PABS
	.PHEX
STRTAD	==	9000H
LOGTBL	==	9400H
CR	==	0Dh
LF	==	0Ah
RXRDY	==	0
TXRDY	==	2
SIO1AC	==	2AH
SIO1AD	==	28H
BLANK	==	20H
FINISH	==	80H
INCR	==	4000H
	.LOC   STRTAD
START:	LXI	SP,STACK
	IN	02	; TURN OFF PROM
	CALL	LOGINT
	LXI	H,0000
	SHLD	STAD
	CALL	TEST
	LXI	H,0C000H
	SHLD	STAD
	CALL	TEST
	MVI	A,FINISH
	STA	PHASE
ENDLOOP:
	CALL	CHECKCON
	JMPR	ENDLOOP
	
;------------------
STAD:	.word 	0000	;START ADDRESS
SIZE:	.word 	0000	;SIZE TO BE CHECKED
;
BADB:	.byte 	0	;BAD BYTE
GOODB:	.byte 	0	;PATTERN BEING TESTED
ERLOC:	.word 	0	;ADDRESS OF BAD BYTE
TLOC:	.word 	0	;WALKING BIT PATTERN
RECORD:	.word 	0000	;
BMPCNT:	.word 	0000	;
COUNT:	.word 	0000	;
SAVAD:	.word 	0000	;SAVE INITIAL STARTAD
;
PHASE:	.byte 	0	;PHASE ID
ERRORS:	.BYTE	0
;stack defined at bottom of program
;

TEST:   MVI	A,1
	STA	PHASE
        XRA    A        ; START WITH 0
;
LP11:	PUSH	PSW
	call   CHECKCON	; check for console chr
	POP	PSW
        CALL   SETM     ; SET MEMORY TO VALUE IN ACC
        CALL   CMPM     ; COMPARE MEMORY WITH VALUE IN ACC
        INR    A        ; BMP TO NXT CODE
        JNZ    LP11     ; JMP IF NOT 0
;
;  END OF PHASE 1
;
;  BEGIN PHASE 2 - WALK A 1 THRU A FIELD OF 0'S.
;
	MVI	A,2
	STA	PHASE
        LXI    B,00FFH  ; SET UP TO WALK A 1 THRU 0'S
        CALL   WALK     ; DO IT
;
;  END OF PHASE 2
;
;  BEGIN PHASE 3 - WALK A 0 THRU A FIELD OF 1'S
;
	MVI	A,3
	STA	PHASE
        LXI    B,0FF00H ; SET UP TO WALK A 0 THRU 1'S
        CALL   WALK     ; DO IT
;
;  END OF MEMORY CHECK
;

        RET             ;
;
;
SETM:   CALL   SETRG    ; SET UP HL=A(MEM), DE=SIZE
SMLP1:  MOV    M,A      ; STORE A INTO MEM
        INX    H        ; BMP TO NXT LOC
        DCR    E        ; DEC LP CTL
        JNZ    SMLP1    ; JMP IF MORE
        DCR    D        ; ALL DONE?
        JNZ    SMLP1    ; JMP IF NO
        RET             ; RETURN IF YES
;
CMPM:   CALL   SETRG    ; SET UP HL & DE
CMLP1:  CMP    M        ; IS MEM SAME AS ACC?
        JNZ    CMPER    ; JMP IF NO
CMPOK:  INX    H        ; BMP TO NXT LOC
        DCR    E        ; DEC LP CTL
        JNZ    CMLP1    ; JMP IF MORE
        DCR    D        ; DONE?
        JNZ    CMLP1    ; JMP IF NO
        RET             ; RETURN IF YES
;
CMPER:  PUSH   PSW      ; SAVE PSW
        LDA    PHASE    ; GET PHASE NO. IN A
        CPI    1        ; IN 1ST PHASE?
        JZ     ERR      ; JMP IF YES
        LDA    TLOC     ; AT TEST LOC?
        CMP    L        ; *
        JNZ    ERR      ; JMP IF NO
        LDA    TLOC+1   ; *
        CMP    H        ; *
        JNZ    ERR      ; *
        POP    PSW      ; RESTORE PSW
        JMP    CMPOK    ; CONTINUE
;
ERR:	MVI	A,0FFH
	STA	ERRORS
	POP    PSW      ; RESTORE ACC
        PUSH   PSW      ; PUT IT BACK ON STK
        STA    GOODB    ; STORE GOOD BYTE
        MOV    A,M      ; GET BAD BYTE
        STA    BADB     ; STORE IT
        LDA    GOODB    ;GET GOOD BYTE
        MOV    M,A      ;FIX-UP BAD BYTE
        SHLD   ERLOC    ; STORE ERROR LOCATION
        CALL   SAVE     ; SAVE ALL ON STACK
	CALL   SPTTY    ;SPACE CARRIAGE
        LXI    H,413DH  ; A=
        CALL   HLCTTY   ; A= TO TTY
        LHLD   ERLOC    ;GET FAILING LOCATION
        CALL   HLBTTY   ;PUT IT OUT
        CALL   SPTTY    ;SPACE CARRIAGE
        LXI    H,GBM    ;GOOD/BAD MESSAGE
        CALL   TTYSTR   ;MESSAGE OUT
        LHLD   BADB     ;GET G/B BYTES
        CALL   HLBTTY   ;PUT THEM OUT
        LDA    PHASE    ;GET CURRENT PHASE
        CPI    1        ;FIRST?
        JZ     RSTRT	;RESTART IF YES
        CALL   SPTTY    ;SPACE CARRIAGE
        LXI    H,573DH  ; W=    (WALK LOCATION)
        CALL   HLCTTY   ;W= TO TTY
        LHLD   TLOC     ;GET WALK LOCATION
        CALL   HLBTTY   ;...TO TTY
;
RSTRT:  CALL   UNSAVE   ; RESTORE ALL
        POP    PSW      ; RESTORE ACC
        JMP    CMPOK    ; CONTINUE
;
SETRG:  LXI	H,INCR
        XCHG            ; DE=LOOP SIZE
        LHLD   STAD     ; HL=A(LOC TO BE TESTED)
        RET             ; AND RETURN
;
;
WALK:   LHLD   STAD     ; INIT TLOC
        SHLD   TLOC     ; *
        MOV    A,B      ; INIT MEM TO SET VALUE
        CALL   SETM     ; *
        JMP    WALK1    ; BEGIN WALK
WLP1:   MOV    A,B      ; GET BASE PATTERN IN A
        CALL   CMPM     ; CHECK ALL LOCATIONS
        MOV    A,C      ; GET WALKING BIT IN A
        RRC             ; SHIFT ONE STEP
        MOV    C,A      ; RETPRN IT TO C
        XRA    B        ; DETERMINE WHERE BIT IS
        JM     WNEW     ; JMP IF BACK TO BEGINNING
WALK1:  LHLD   TLOC     ; GET A(TST LOC) IN HL
WALK2:  MOV    M,C      ; PUT WALKING BIT INTO TST LOC
	call   CHECKCON	; check for console chr
        JMP    WLP1     ; GO CHECK MEMORY FOR CHANGES
	
;
WNEW:   call   CHECKCON	; check for console chr
	XCHG            ; GET HI MEM LIMIT IN DE
        LHLD   TLOC     ; GET A(TST LOC) IN HL
        MOV    M,B      ; RESTORE TST LOC TO NORMAL
        INX    H        ; BMP TO NXT TST LOC
        SHLD   TLOC     ; STORE NEW TST LOC
        MOV    A,E      ; CHECK FOR END
        CMP    L        ; *
        JNZ    WALK2    ; JMP IF MORE
        MOV    A,D      ; *
        CMP    H        ; DONE?
        JNZ    WALK2    ; JMP IF NO
        RET             ; RETURN IF YES
;
GBM:    .byte   3
	.ASCII	'GB='    
PHASEM: .byte   6
	.ASCII	'PHASE '       
; SUBROUTINES FOR CHARACTER & STRING I/O
;
; SAVE & UNSAVE ROUTINES
SAVE:   SHLD   TEMPHL   ;SAVE H&L
        XTHL            ;GET RETURN, PUSH H
        PUSH   PSW      ;SAVE PSW
        PUSH   B        ;SAVE B&C
        PUSH   D        ;SAVE D&E
        PUSH   H        ;RETURN BACK ONTO STACK
        LHLD   TEMPHL   ;RESTORE ORIGINAL H&L
        RET             ;
UNSAVE: POP    H        ;RESTORE RETURN
        POP    D        ;RESTORE D&E
        POP    B        ;RESTORE B&C
        POP    PSW      ;RESTORE PSW
        XTHL            ;RETURN ONTO STACK, POP H
        RET             ;
DOCRLF: MVI	A,CR
	CALL	CONOUT
	MVI	A,LF
	CALL	CONOUT
        RET             
CONOUT:	PUSH	PSW
..WAIT:	IN	SIO1AC
	BIT	TXRDY,A
	JRZ	..WAIT
	POP	PSW
	OUT	SIO1AD
	RET
SPTTY:  PUSH   PSW      ;SAVE PSW
        MVI    A,BLANK  ; 'SPACE' INTO AC
        CALL   ACCTTY   ;CHARACTER IN AC TO TTY
        POP    PSW      ;RESTORE PSW
        RET             ;
ACCTTY: PUSH	H
	PUSH	B
	MOV	B,A
	LDA	BUFFAD+1
	CPI	0A0H
	JRZ	..CONT
	LHLD	BUFFAD
	MOV	M,B
	INX	H
	SHLD	BUFFAD
..CONT:	POP	B
	POP	H
        RET             ;
TTYSTR: PUSH   B        ;SAVE B&C
        MOV    B,M      ;GET MSG COUNT
        INX    H        ;BUMP TO MSG PROPER
        CALL   STCTTY   ;CHARACTER STRING TO TTY
        POP    B        ;RESTORE B&C
        RET             
;
;
STCTTY: CALL   SAVE     ;SAVE ALL
STCOUT: MOV    A,M      ;NEXT CHARACTER INTO AC
        CALL   ACCTTY   ;PUT IT OUT
        INX    H        ;NEXT MEMORY LOC
        DCR    B        ;COUNT -1
        JNZ    STCOUT   ;OUTPUT 'B' CHARACTERS
        CALL   UNSAVE   ;RESTORE ALL
        RET             ;
ACBTTY: PUSH   PSW      ;SAVE
        RRC             ;SWAP
        RRC             ; RIGHT AND LEFT
        RRC             ;  BITS WITHIN
        RRC             ;   THE BYTE.
        ANI    00FH     ;KEEP ONLY RIGHT 4 BITS
        CALL   HEXEX    ;GENERATE ASCII FROM NIBBLE
        POP    PSW      ;ORIGINAL BYTE AGAIN
        ANI    00FH     ;GET SECOND NIBBLE
        CALL   HEXEX    ;NIBBLE INTO ASCII
        RET             ;
HEXEX:  CPI    10       ;LOWER THAN 10?
        JM     CON      ;JUMP IF YES
        ADI    007H     ;
CON:    ADI    030H     ;ASCII BIAS
        JMP    ACCTTY   ;PUT OUT THIS CHARACTER
HLCTTY: PUSH   PSW      ;SAVE
        MOV    A,H      ;GET FIRST CHARACTER
        CALL   ACCTTY   ;PUT IT OUT
        MOV    A,L      ;SECOND CHARACTER
        CALL   ACCTTY   ;PUT IT OUT
        POP    PSW      ;RESTORE
        RET             ;
HLBTTY: PUSH   PSW      ;SAVE
        MOV    A,H      ;FIRST BYTE
        CALL   ACBTTY   ;PUT OUT 2 ASCII CHARACTERS
        MOV    A,L      ;SECOND BYTE
        CALL   ACBTTY   ;OUTPUT 2 MORE
        POP    PSW      ;RESTORE
        RET             ;
;----------

TEMPHL: .word      0000     ;
LOGINT:	LXI	H,LOGTBL
	SHLD	BUFFAD
	MVI	M,20H
	LXI	D,LOGTBL+1
	LXI	B,0C00H
	LDIR
	RET

;----------------
; Subroutine:  CheckCON
; Regs  in:	none
; Regs out:	none
; Destroyed:	none
; Check for a chr ready from the console.
; Print status if a chr is found.
CHECKCON:
	IN	SIO1AC
	BIT	RXRDY,A
	RZ
	IN	SIO1AD
	PUSH	H
	LDA	ERRORS
	ORA	A
	CNZ	ERRPRT
	LXI	H,PROGmsg
	CALL	OUTSTR
	LDA	PHASE
	CPI	FINISH
	JZ	FINAL
	CALL	PRTBYT
	LXI	H,LOCmsg
	CALL	OUTSTR
	LHLD	TLOC
	MOV	A,H
	CALL	PRTBYT
	MOV	A,L
	CALL	PRTBYT
	CALL	DOCRLF
	POP	H
	RET
ERRPRT:	LXI	H,ERRmsg
	CALL	OUTSTR
	RET
FINAL:	LXI	H,ENDmsg
	CALL	OUTSTR
	POP	H
	RET
OUTSTR:	MOV	A,M
	ORA	A
	RZ
	CALL	CONOUT
	INX	H
	JMPR	OUTSTR
	
;-------
; Sub: prtchr
; Make a hex byte an ascii byte. Print it.
PRTBYT:	PUSH	PSW
	RRC
	RRC
	RRC
	RRC
	CALL	PRTNBL
	POP	PSW
PRTNBL:	ANI	0FH
	ADI	'0'
	CPI	'9'+1
	JC	CONOUT
	ADI	'A'-('9'+1)
	JMP	CONOUT
	
;-------
; CheckCON Messages
PROGmsg: .ASCII [CR][LF]' SHORT MEMORY TEST IS IN PROGRESS'
	 .ASCIZ [CR][LF]' CURRENT PHASE: '
ERRmsg:	 .ASCIZ [CR][LF]' ERRORS'
LOCmsg:  .ASCIZ [CR][LF]' CURRENT TEST LOCATION: '
ENDmsg:	 .ASCIZ [CR][LF]' TEST FINISHED'
BUFFAD:	.word 	0	; filled in at START
bufcnt:	.byte 	0	; updated by stobyt,Diskit
;
stk:	.blkb 	128
stack	 = 	.
;
.END

