home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol005
/
memdiag.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
35KB
|
1,593 lines
;***********************************************************************
; MICROCOSM ASSOCIATES "SUPER MEMORY DIAGNOSTIC" VERSION 1.01 (C) 1979
;***********************************************************************
;
;DONATED TO THE "SIG/M" CP/M USER'S GROUP BY:
;KELLY SMITH, MICROCOSM ASSOCIATES
;3055 WACO AVENUE
;SIMI VALLEY, CALIFORNIA, 93065
;(805) 527-9321 (MODEM, CP/M-NET (TM))
;(805) 527-0518 (VERBAL)
;
;
;
ORG 0100H
;
;
;
DI ;DISABLE INTERRUPTS
LXI SP,STACK ;SET THE STACK POINTER
JMP INIT ;INITIALIZE
;
;
;
;
;
;
;DEFINE CONSOLE I/O PARAMETERS FOR ALTAIR 2SI/O BOARD
;
CCTRL EQU 010H ;CONSOLE COMMAND/STATUS PORT
CDATA EQU 011H ;CONSOLE DATA PORT
CRRDY EQU 001H ;RECEIVER READY BIT
CTRDY EQU 002H ;TRANSMITTER READY BIT
;
;
;
;SUBROUTINE TO CONVERT TWO HEX CHARACTERS TO ONE BYTE
;
NBL: SUI '0'
RC
ADI 0E9H
RC
ADI 6
JP NIO
ADI 7
RC
NIO: ADI 10
ORA A
RET
;
;
;
;SUBROUTINE TO CONVERT A BYTE TO TWO HEX CHARACTERS
;
LBYTE: PUSH PSW
RRC
RRC
RRC
RRC
ANI 0FH
CALL HXDA
POP PSW
ANI 0FH
JMP HXDA
;
;
;
HXDA: CPI 10
JM CNO
ADI 7
CNO: ADI 30H
MOV C,A
JMP CO
;
;
;
;CONSOLE INPUT ROUTINE
;
CI: IN CCTRL
ANI CRRDY
JZ CI
IN CDATA
ANI 7FH
RET
;
;
;
CRLF: MVI C,0DH
CALL CO
MVI C,0AH
JMP CO
;
;
;
CONO: CALL BYTEO
CALL CRLF
RET
;
;
;
CONI: PUSH B
CALL BYTEC
POP B
RET
;
;
;
;CONSOLE OUTPUT ROUTINE
;
CO: IN CCTRL
ANI CTRDY
JZ CO
MOV A,C
OUT CDATA
RET
;
;
;
INIT: LXI H,01000H ;SET DELAY COUNT FOR 6850 SETTLE TIME
DELAY: DCX H
MOV A,H
ORA L
JNZ DELAY
MVI A,003H ;RESET 6850 ACIA
OUT CCTRL
MVI A,015H
OUT CCTRL
LXI H,MSGN
CALL MSG
TOP: LXI H,MSG7 ;OUTPUT "TOP OF MEMORY=" TO CONSOLE
CALL MSG
LXI H,00FFFH ;SET BASE ADDRESS OF TEST RAM -1
FIND: INX H ;EXAMINE EACH BYTE
MOV A,M
CMA
MOV M,A
CMP M
JZ FIND
DCX H
CALL HLOUT
LXI H,QTMSG ;OUTPUT "MEMORY QUALIFICATION TEST
; IS IN PROGRESS" TO CONSOLE
CALL MSG
LXI H,01000H ;SET MEMORY "BOTTOM" ADDRESS
SHLD MBOT
LXI H,0C000H ;SET MEMORY "TOP" ADDRESS
SHLD MTOP
LXI H,TEST ;SAVE "FUNKY RETURN" ADDRESS
SHLD MTEST
JMP RNDSL ;GO DO RANDOM PATTERNS TEST ON 16K BYTE MEMORY
TEST: LXI SP,STACK ;RE-SET THE STACK
JMP MEMTS
;
;
;
MNTR: LXI SP,STACK
CALL CRLF
MVI C,'-' ;OUTPUT PROMPT (- CHARACTER)
CALL CO
CALL CECHO ;ECHO KEY-BOARD INPUT OUT TO CONSOLE
CPI 'M'
JZ MEM ;JUMP TO MEMORY DISPLAY/ALTER,IF "M"
CPI 'G'
JZ GO ;JUMP TO GO TO MEMORY ADDRESS,IF "G"
CPI 'T'
JZ MEMTS ;JUMP TO MEMORY TEST START,IF "T"
LER: CALL CRLF ;KEEP IT NEAT
MVI C,'?' ;LINE INPUT ERROR,OUTPUT "?" TO CONSOLE
CALL CO
JMP MNTR
;
;
;
CECHO: CALL CI
MOV C,A
CALL CO
RET
;
;
;
GO: LXI H,MSG2 ;OUTPUT "GO ADDRESS=" TO CONSOLE
CALL MSG
CALL PARAM
CALL CRLF
PCHL
;
;
;
PARAM: LXI H,0
PARM1: CALL CECHO
CPI 0DH
RZ
DAD H
DAD H
DAD H
DAD H
JC LER
CALL NBL
JC LER
ORA L
MOV L,A
JMP PARM1
;
;
;
BYTEC: CALL CECHO
BYTC1: CALL NBL
JC LER
RLC
RLC
RLC
RLC
PUSH PSW
CALL CECHO
CALL NBL
JC LER
POP B
ORA B
RET
;
;
;
BYTEO: PUSH PSW
CALL BYTO1
MOV C,A
CALL CO
POP PSW
CALL BYTO2
MOV C,A
JMP CO
BYTO1: RRC
RRC
RRC
RRC
BYTO2: ANI 0FH
CPI 0AH
JM BYTO3
ADI 7
BYTO3: ADI 30H
RET
;
;
;
HLCO: CALL CRLF
HLOUT: MOV A,H
CALL BYTEO
MOV A,L
CALL BYTEO
RET
;
;
;
DSPYM: CALL HLCO
MVI C,'='
CALL CO
MOV A,M
CALL BYTEO
MVI C,20H
CALL CO
RET
;
;
;
MEM: LXI H,MSG1 ;OUTPUT "MEMORY ADDRESS=" TO CONSOLE
CALL MSG
CALL PARAM
MEM1: CALL DSPYM
CALL CECHO
CPI 00DH
JZ MNTR
CPI 020H
JZ MEM9
CPI 05EH
JZ MEM10
CALL BYTC1
MOV M,A
CMP M
JZ MEM9
MVI C,' '
CALL CO
MVI C,'E'
CALL CO
MEM9: INX H
JMP MEM1
MEM10: DCX H
JMP MEM1
;
;
;
;KEY-BOARD INTERRUPT ROUTINE,KEYED WITH "SPACE-BAR"
;
KBINT: IN CCTRL
ANI CRRDY
RZ
IN CDATA
ANI 07FH ;MASK-OFF PARITY BIT
CPI 020H ;GOT A "SPACE-BAR"?
JZ MNTR ;GO TO COMMAND MONITOR,IF SO
RET
;
;
;
SP5: MVI C,20H
CALL CO
SP4: MVI C,20H
CALL CO
SP3: MVI C,20H
CALL CO
SP2: MVI C,20H
CALL CO
SP1: MVI C,20H
CALL CO
RET
;
;
;
;
;
;
MSGN: DB 71,0DH,0AH,'MICROCOSM ASSOCIATES "SUPER MEMORY DIAGNOSTIC"'
DB ' VERSION 1.01 (C) 1979'
;
MSG1: DB 14,'EMORY ADDRESS='
;
MSG2: DB 10,'O ADDRESS='
;
MSG7: DB 17,0DH,0AH,0AH,'TOP OF MEMORY='
;
QTMSG: DB 43,0DH,0AH,0AH,'MEMORY QUALIFICATION TEST IS IN PROGRESS'
;
AMMSG: DB 39,0DH,0AH,0AH,'TEST MEMORY IN "AUTO" MODE (Y OR N)?'
;
DFMSG: DB 47,0DH,0AH,0AH,'TEST "ALL","SELECT",OR "MONITOR" (A,S OR M)?'
;
TPMSG: DB 20,' TEST IS IN PROGRESS'
;
TMSG: DB 17,0DH,0AH,0AH,'TESTING MEMORY'
;
FMSG: DB 6,',FROM '
;
TOMSG: DB 4,' TO '
;
PSMSG: DB 7,0DH,0AH,'PASS='
;
ERMSG: DB 15,', TOTAL ERRORS='
;
PTSG: DB 25,0DH,0AH,'GALLOPING PATTERNS TEST'
;
RFMSG: DB 25,0DH,0AH,'STATIC CHECK CYCLE TEST'
;
CKMSG: DB 25,0DH,0AH,'CHECKING DATA RETENTION'
;
CLMSG: DB 24,0DH,0AH,'GALLOPING COLUMNS TEST'
;
RDMSG: DB 22,0DH,0AH,'RANDOM PATTERNS TEST'
;
SATSG: DB 23,0DH,0AH,'WRITE SATURATION TEST'
;
WMSG: DB 23,0DH,0AH,'WALKING PATTERNS TEST'
;
NDMSG: DB 27,0DH,0AH,0AH,'NO MEMORY BLOCKS DROPPED'
;
DMMSG: DB 27,0DH,0AH,0AH,'DROPPED MEMORY BLOCK(S)='
;
LMMSG: DB 22,0DH,0AH,0AH,'LOW MEMORY ADDRESS='
;
HMMSG: DB 22,0DH,0AH,'HIGH MEMORY ADDRESS='
;
NAMSG: DB 24,0DH,0AH,'INVALID MEMORY ADDRESS'
;
OPMSG: DB 20,0DH,0AH,0AH,'TEST OPTIONS ARE:'
;
TMSG1: DB 30,0DH,0AH,0DH,0AH,'01-GALLOPING PATTERNS TEST'
;
TMSG2: DB 27,0DH,0AH,'02-GALLOPING COLUMNS TEST'
;
TMSG3: DB 26,0DH,0AH,'03-WALKING PATTERNS TEST'
;
TMSG4: DB 25,0DH,0AH,'04-RANDOM PATTERNS TEST'
;
TMSG5: DB 26,0DH,0AH,'05-WRITE SATURATION TEST'
;
TMSG6: DB 28,0DH,0AH,'06-STATIC CHECK CYCLE TEST'
;
TMSGN: DB 44,0DH,0AH,0AH,'ENTER TEST NUMBER (01,02,03,04,05 OR 06)='
;
EPMSG: DB 24,0DH,0AH,0AH,'ENTER PATTERN(00-FF)='
;
REMSG: DB 29,0DH,0AH,'RETENTION ERROR AT ADDRESS='
;
EXMSG: DB 31,0DH,0AH,'EXPECTED "00" DATA,READ BACK '
;
MRER1: DB 20,0DH,0AH,'ERROR AT ADDRESS=',0
;
MRER2: DB 12,' READ BACK '
;
MRER3: DB 11,' ,EXPECTED '
;
MRER4: DB 27,0DH,0AH,'LAST ADDRESS WRITTEN WAS '
;
MRER5: DB 14,20H,',PATTERN WAS '
;
MRER6: DB 26,0DH,0AH,'ERROR READING OTHER CELL'
;
MRER7: DB 25,0DH,0AH,'ERROR READING TEST CELL'
;
MRER8: DB 12,0DH,0AH,'TEST CELL='
;
MRER9: DB 13,', OTHER CELL='
;
MER10: DB 18,20H,20H,'PATTERN STORED=',0
;
MER11: DB 16,20H,20H,'PATTERN READ=',0
;
MER12: DB 19,0DH,0AH,'BIT(S) IN ERROR=',0
;
;
;
;
;
MSG: PUSH PSW
PUSH B
MOV B,M
INX H
MSGA: MOV C,M
CALL CO
INX H
DCR B
JNZ MSGA
POP B
POP PSW
RET
;
;
;
;
;
;
;ROUTINE TO FIND ALL 4K MEMORY BLOCKS AVAILABLE TO SYSTEM
;
MEMTS: LXI H,00000H ;CLEAR THE PASS AND ERROR COUNTERS
SHLD PCTR
SHLD ECTR
LXI B,MBUF ;POINT TO MEMORY BUFFER
MVI E,1 ;SET-UP BASE RAM 1ST 4K BYTE TEST ADDRESS
STAAD: MOV A,E
STAX B ;SAVE IT IN BUFFER
INX B
INC4K: MVI A,00BH ;INCREMENT TO NEXT 4K MEMORY BLOCK,STOP IF ALL
; MEMORY BLOCKS TRIED,FOR 16 K BYTE MEMORY
INR E ;BUMP FOR NEXT MEMORY BLOCK
CMP E ;ALL DONE?
JP STAAD ;IF NOT,GO TEST THIS NEW MEMORY BLOCK
MVI A,080H ;YES,TAG WITH "END" IN BUFFER
STAX B
AUT: LXI H,AMMSG ;OUTPUT "TEST MEMORY IN "AUTO" MODE (Y OR N)?"
CALL MSG
CALL CECHO ;GET THE ANSWER
CPI 'Y'
JZ AUTO ;DO AUTO MODE,IF YES
CPI 'N'
JZ SELCT ;LET OPERATOR SELECT,IF NO
JMP AUT ;OOPS...GAVE HIM TWO CHOICES,AND HE PICKED THIRD
AUTO: CALL KBINT ;CHECK FOR KEY-BOARD INTERRUPT
LXI H,DROP ;SET-UP DROP LIST POINTER
SHLD DROPP ;SET DROP LIST POINTER TO START
XRA A ;CLEAR DROP COUNT AND ERROR FLAG
DCX H
MOV M,A
DCX H
MOV M,A
AUTO0: LXI H,MBUF ;POINT TO MEMORY BUFFER
SHLD MEMPT ;SAVE MEMORY POINTER FOR LOOPING
AUTO1: LDA ERFLG ;GET ERROR FLAG,TO SEE IF WE DROP MEMORY
; BLOCK JUST TESTED OR NOT
ORA A
JZ AUTO3 ;IF NOT ZERO,DROP THIS BLOCK FROM TEST
LHLD DROPP ;POINT TO NEXT DROP LIST SLOT
XCHG
LHLD BLKST ;GET MEMORY BLOCK START ADDRESS
XCHG ;AND NOW WE HAVE H&L REGS.AS DROP LIST POINTER,
; AND D&E REGS. AS THE BLOCK START
MOV M,E ;SAVE LOW BYTE OF BLOCK START
INX H
MOV M,D ;SAVE HIGH BYTE OF BLOCK START
INX H ;GET H&L REGS. TO POINT TO NEXT DROP LIST SLOT
SHLD DROPP ;SAVE THE NEW POINTER
LXI H,DROPC ;+1 TO THE DROP COUNT
INR M
LHLD MEMPT ;GET THE MEMORY BLOCK POINTER
DCX H ;BACK-UP TO MEMORY BLOCK JUST TESTED,AND LOG IT OUT
MVI M,000H
AUTO3: MVI A,9 ;SET ERROR DISPLAY COUNTER TO 8 PLUS 1
STA ERCNT
XRA A ;CLEAR ERROR FLAG
STA ERFLG
LHLD MEMPT ;GET MEMORY BLOCK AND BLOCK NUMBER
MOV A,M
INX H ;UPDATE AND SAVE NEW POINTER
SHLD MEMPT
ORA A ;TEST THE MEMORY BLOCK NUMBER
JM AUTO0 ;RE-START IF "END" OF BUFFER
JZ AUTO3 ;TRY NEXT ONE,IF DROPPED MEMORY BLOCK
RLC ;CONVERT MEMORY BLOCK NUMBER TO 4K BLOCK ADDRESS
RLC
RLC
RLC
MVI L,000H ;ZERO L REG.
MOV H,A ;MAKE A 16 BIT BLOCK ADDRESS OUT OF THIS,
; AND SAVE AS BLOCK STARTING ADDRESS
SHLD BLKST
ADI 010H ;ADD 4K TO START
MOV H,A
SHLD MEND ;SAVE AS MEMORY BLOCK END ADDRESS +1
LXI H,AUTO1 ;SAVE "AUTO1" FOR LOOPING ADDRESS
SHLD AUTOR
LXI H,TMSG ;OUTPUT "TESTING MEMORY " TO CONSOLE
CALL MSG
LXI H,FMSG ;OUTPUT ", FROM " TO CONSOLE
CALL MSG
LHLD BLKST ;GET THE MEMORY BLOCK STARTING ADDRESS
CALL HLOUT
LXI H,TOMSG ;OUTPUT " TO " TO CONSOLE
CALL MSG
LHLD MEND ;GET THE MEMORY ENDING ADDRESS
CALL HLOUT
LXI H,PSMSG ;OUTPUT "PASS=" TO CONSOLE
CALL MSG
LHLD PCTR ;GET THE PASS COUNTER,AND UPDATE IT
INX H
SHLD PCTR
CALL HLOUT
LXI H,ERMSG ;OUTPUT ", ERRORS TOTAL=" TO CONSOLE
CALL MSG
LHLD ECTR ;GET THE ERROR COUNTER,AND SHOW IT ALSO
CALL HLOUT
LXI H,WRTSAT ;SAVE "NEXT TEST" ADDRESS
SHLD MTEST
JMP RANPT ;GO DO RANDOM PATTERNS MEMORY TEST
;
;
;
;ROUTINE TO DO WRITE AMPLIFIER SATURATION TEST IN "AUTO MODE"
;
WRTSAT: LXI SP,STACK ;SET THE STACK POINTER
LXI H,SATSG ;OUTPUT "WRITE SATURATION TEST" TO CONSOLE
CALL MSG
LHLD BLKST ;GET MEMORY BLOCK STARTING ADDRESS
SHLD MBOT ;SAVE AS MEMORY BOTTOM ADDRESS
LHLD MEND ;GET MEMORY BLOCK END ADDRESS
SHLD MTOP ;SAVE A MEMORY "TOP" ADDRESS
MVI B,100 ;SET-UP FOR 100 WRITE SATURATION PASSES
XRA A ;SATURATE WITH 0'S FIRST
CALL SAT ;WRITE WITH PATTERN,100 TIMES
MVI A,0FFH ;FLIP PATTERN TO 1'S
CALL BAKPT ;WRITE 1 TIME ONLY
CALL SATRD ;DO SATURATION READ
MVI B,100 ;AGAIN SET-UP 100 WRITE SATURATION PASSES
MVI A,0FFH ;NOW SATURATE WITH 1'S
CALL SAT ;WRITE WITH PATTERN,100 TIMES
XRA A ;FLIP PATTERN TO 0'S
CALL BAKPT ;WRITE 1 TIME ONLY
CALL SATRD ;DO SATURATION READ
JMP GAL ;GO DO "GALLOPING PATTERNS" MEMORY TEST
;
;
;
;ROUTINE TO DO WRITE SATURATION TEST IN "SELECT MODE"
;
WSATT: MVI B,100 ;SET-UP FOR 100 WRITE SATURATION PASSES
CALL SAT ;WRITE WITH SELECTED PATTERN,100 TIMES
CMA ;WRITE WITH COMPLEMENT,1 PASS
CALL BAKPT
CALL SATRD ;READ THE DATA
LDA TPATT ;GET SAVED TEST PATTERN
MVI B,100 ;NOW DO COMPLEMENT 100 TIMES
CALL SAT ;....AND WE'RE OFF
CMA ;WRITE WITH COMPLEMENT,1 PASS
CALL BAKPT
CALL SATRD ;READ THE DATA
RET
;
;
;
;SUBROUTINE TO READ 1 PASS "BACKGROUND" PATTERN AS CONTAINED IN A REG.
;
SATRD: LHLD MTOP ;GET MEMORY "TOP" ADDRESS
XCHG ;SWAP H&L REGS. TO D&E REGS.
LHLD MBOT ;TOP'S IN D&E REGS.,BOTTOM'S IN H&L REGS.
MOV B,A ;SAVE PATTERN IN B REG.
STA TPATT ;SAVE DATA PATTERN FOR POSSIBLE ERROR DISPLAY
FSTRD: CALL COMP ;ALL DONE?
RZ
MOV A,M ;GET A BYTE FROM MEMORY
CMP B ;GOT A MATCH?
CNZ SATER ;INDICATE "WRITE SATURATION" ERROR IF NO MATCH
INX H ;BUMP POINTER FOR NEXT BYTE
JMP FSTRD ;DO FAST READ ON MORE MEMORY
;
;
;
SAT: PUSH PSW ;EXILE THE A REG.
CALL KBINT ;CHECK KEY-BOARD INTERRUPT
POP PSW ;BACK FROM EXILE
PUSH B ;SAVE PASSES ON STACK
CALL BAKPT ;WRITE THE "BACKGROUND" PATTERN
POP B ;GET PASS COUNT
DCR B ;DE-BUMP THE PASS COUNT
JNZ SAT ;CONTINUE WRITING 'TILL 100 PASSES COMPLETED
RET
;
;
;
;SUBROUTINE TO INDICATE ERROR IN WRITE SATURATION TEST
;
SATER: STA ERPAT ;SAVE "BAD" BYTE
MVI A,0FFH ;SET ERROR FLAG
STA ERFLG
PUSH H ;SAVE BAD BYTE ADDRESS
LHLD ECTR ;UPDATE THE ERROR COUNTER
INX H
SHLD ECTR
LDA ERCNT ;DONE DISPLAYING ALL ERRORS?
DCR A
JZ PTX ;DON'T DISPLAY ANY MORE ERRORS,IF SO
STA ERCNT
LXI H,MRER1 ;OUTPUT " ERROR AT ADDRESS=" TO CONSOLE
CALL MSG
POP H ;GET BAD BYTE ADDRESS,BUT DON'T
; CHANGE THE STACK
PUSH H
CALL HLOUT
LXI H,MRER2 ;OUTPUT " READ BACK " TO CONSOLE
CALL MSG
LDA ERPAT ;GET ERROR PATTERN
CALL BYTEO ;SHOW IT
LXI H,MRER3 ;OUTPUT " , EXPECTED " TO CONSOLE
JMP SATX ;DISPLAY EXPECTED DATA PATTERN AND EXIT
;
;
;
;ROUTINE TO DO STATIC CHECK CYCLE TEST IN "SELECT MODE"
;
STATT: MVI A,0FFH ;ALL 1'S PATTERN FOR FIRST PORTION OF TEST
PUSH PSW ;SAVE THE PATTERN
CALL BAKPT ;WRITE IT
LXI B,500*5 ;DO 5 MINUTE DELAY "DO NOTHING"
CALL LOOP1
POP PSW ;GET PATTERN
CALL SATRD ;READ AFTER DELAY TIME
XRA A ;ALL 0'S PATTERN FOR SECOND PORTION OF TEST
PUSH PSW ;SAVE THE PATTERN
CALL BAKPT ;WRITE IT
LXI B,500*5 ;DO 5 MINUTE DELAY "DO NOTHING"
CALL LOOP1
POP PSW ;GET PATTERN
CALL SATRD ;CHECK DATA AFTER 5 MINUTE DELAY
RET
;
;
;
;ROUTINE TO DO "GALLOPING" MEMORY TEST IN 256 BYTE CHUNKS
; (MEMORY DATA WILL BE FF HEX AND THEN 00 HEX)
;
GAL: LXI H,PTSG ;OUTPUT "GALLOPING PATTERN MEMORY TEST" TO CONSOLE
CALL MSG
LHLD BLKST ;GET MEMORY BLOCK STARTING ADDRESS
GAL1: SHLD MBOT ;SAVE AS "CHUNK" START
INR H ;ADD 256
MVI L,000H ;CLEAN-UP L REG.
SHLD MTOP ;SAVE AS "CHUNK" END +1
MVI A,0FFH ;ALL ONES BACK-GROUND PATTERN
CALL GALPT ;TEST THE "CHUNK" WITH 1'S
XRA A ;ALL ZEROS BACK-GROUND PATTERN
CALL GALPT ;TEST THE "CHUNK" WITH 0'S
LHLD MEND ;GET "CHUNK" AND MEMORY BLOCK END
CALL COMP ;HAVE WE DONE ALL 16 "CHUNKS" IN THE MEMORY BLOCK?
JZ STATIC ;IF DONE,GO DO 1 MINUTE STATIC TEST
XCHG ;OH...GO DO NEXT "CHUNK" IN SAME MEMORY BLOCK
JMP GAL1
;
;
;
STATIC: LXI H,RFMSG ;OUTPUT "STATIC CHECK CYCLE" TO CONSOLE
CALL MSG
LXI B,500
CALL LOOP1 ;DO ONE MINUTE DELAY FOR STATIC CHECK
LXI H,CKMSG ;OUTPUT "CHECKING DATA RETENTION" TO CONSOLE
CALL MSG
LHLD MEND ;GET MEMORY BLOCK END
XCHG ;SWAP TO D&E REGS.
LHLD BLKST ;GET MEMORY BLOCK STARTING ADDRESS
XRA A ;MAKE A 0'S BYTE FOR COMPARE
LOOP3: CMP M ;TEST "GALLOPING PATTERN" RESULT BYTE
CNZ RFERR ;IF IT DIDN'T SURVIVE,REPORT RETENTION ERROR
INX H ;BUMP FOR NEXT TEST BYTE
CALL COMP ;HAVE WE CHECKED THE WHOLE MEMORY BLOCK?
JC LOOP3 ;IF NOT,DO IT
LXI H,CLMSG ;OUTPUT "GALLOPING COLUMN MEMORY TEST" TO CONSOLE
CALL MSG
LHLD BLKST ;GET MEMORY BLOCK START
SHLD MBOT ;SAVE IT FOR FUTURE USE IN "GALLOPING COLUMN"
LHLD MEND ;GET MEMORY BLOCK END
SHLD MTOP ;SAVE FOR FUTURE USE IN "GALLOPING COLUMN"
MVI A,0FFH ;SET-UP ALL ONES PATTERN
CALL GALCL ;DO "GALLOPING COLUMN"
XRA A ;SET-UP ALL ZEROS PATTERN
CALL GALCL ;TEST THE MEMORY BLOCK AGAIN
;
;
;
;ROUTINE TO WALK PATTERNS THRU THE MEMORY BLOCK IN 256 BYTE "CHUNKS",
; (WRITES 1'S,WALKS 0'S,THEN WRITES 0'S,AND THEN WALKS 1'S)
;
WALK: LXI H,WMSG ;OUTPUT "WALKING PATTERNS MEMORY TEST" TO CONSOLE
CALL MSG
LHLD BLKST ;GET MEMORY BLOCK STARTING ADDRESS
WALK1: SHLD MBOT ;SAVE AS "CHUNK" STARTING ADDRESS
INR H ;ADD 256
MVI L,000H ;SCRUB L REG.
SHLD MTOP ;SAVE RESULT AS "CHUNK" END +1
MVI A,0FFH ;MAKE AN ALL 1'S PATTERN BYTE
CALL WALKT ;LET'S GO FOR A WALK
XRA A ;MAKE AN ALL 0'S PATTERN BYTE
CALL WALKT ;MAYBE WE COULD JOG FOR AWHILE?
LHLD MEND ;GET "CHUNK" AND BLOCK END
CALL COMP ;ALL THE "CHUNKS" DONE IN THE BLOCK?
JZ TEND ;IF ZERO,GO TO NEXT MEMORY BLOCK IN AUTO SEQUENCE
XCHG ;NO? GET NEW "CHUNK" START ADDRESS
JMP WALK1 ;GO TEST NEW "CHUNK"
TEND: CALL CDROP ;SHOW ANY "DROPPED BLOCKS"
LHLD AUTOR ;GET "AUTO1" RETURN ADDRESS
PCHL ;GO FOR IT
;
;
;
;ROUTINE TO DO RANDOM MEMORY TEST IN "SELECT MODE"
;
RNDSL: LHLD MTOP ;GET OPERATOR SELECTED MEMORY "TOP" ADDRESS
MOV B,H ;SAVE IT IN B&C REGS.
MOV C,L
DCX B ;DE-BUMP B&C REGS. TO GET PROPER "TOP"
; MEMORY BOUNDRY ADDRESS
LHLD MBOT ;GET OPERATOR SELECTED MEMORY "BOTTOM" ADDRESS
JMP RANST ;GO TO RANDOM PATTERNS TEST START
;
;
;
;ROUTINE TO DO RANDOM PATTERNS MEMORY TEST IN "AUTO MODE"
;
RANPT: LXI H,RDMSG ;OUTPUT "RANDOM PATTERNS MEMORY TEST" TO CONSOLE
CALL MSG
RANMT: LHLD MEND ;GET MEMORY BLOCK END ADDRESS INTO B&C REGS.
MOV B,H
MOV C,L
DCX B ;DE-BUMP B&C REGS. TO GET PROPER BLOCK END
; BOUNDRY ADDRESS
DCX B
DCX B
LHLD BLKST ;GET MEMORY BLOCK START ADDRESS INTO H&L REGS.,
; AND D&E REGS.
RANST: MOV D,H
MOV E,L
SPHL ;STUFF H&L REGS. INTO SP REG.
LXI H,1 ;MAKE A STARTING "SEED" FOR FIRST RANDOM PATTERN
;
;
;
;"STORR", STORES RANDOM NUMBERS THROUGHOUT THE MEMORY TEST AREA BY
;USING RANDOM NUMBERS,CAUSING MOST PATTERN SENSITIVE AND ADDRESSING
;PROBLEMS TO BE CAUGHT.THE NUMBERS ARE STORED USING THE
;8080/8085 "PUSH" COMMAND WHICH STORES TWO ADJACENT BYTES IN THE
;FASTEST MANNER POSSIBLE.
;
STORR: INX SP ;BUMP STACK POINTER BY 2'S
INX SP
PUSH H ;STUFF THE RANDOM DATA BYTE INTO MEMORY
POP H
LXI H,0 ;SCRUB H&L REGS.
DAD SP ;GET THE CURRENT TEST CELL ADDRESS
MOV A,C ;GET LOW BYTE OF MEMORY TOP ADDRESS
SUB L ;SUBTRACT LOW BYTE OF TEST CELL
MOV A,B ;GET HIGH BYTE OF MEMORY TOP ADDRESS,
; AND SAVE CARRY ONLY
SBB H ;SUBTRACT HIGH BYTE OF TEST CELL ADDRESS
JC DONE1 ;IF WE GOT THE CARRY,WERE DONE
DCX SP ;NO,NOT DONE YET
DCX SP
POP H
MOV A,L ;MAKE MORE "HASH" FOR MEMORY PATTERNS
ADD A
MOV L,A
MOV A,H
RAL
MOV H,A
MVI A,0
ADC L
MOV L,A
MOV A,H
RLC
RLC
RLC
XRA L
RRC
RRC
ANI 1
XRA L
MOV L,A
JMP STORR
;
;
;
;"DONE1" CHECKS THE FIRST TWO BYTES FOR ERRORS AND ALSO CHECKS
;TO SEE WHICH PASS-THROUGH THE PROGRAM IS ON.
;
DONE1: MOV L,E
MOV H,D
MVI A,1
CMP M
JNZ CHECK
DCR A
INX H
CMP M
JNZ ERROR
JMP CHKR
;
;
;
CHECK: MVI A,0FEH
CMP M
MVI A,1
JNZ ERROR
DCR A
DCR A
INX H
CMP M
JNZ ERROR
;
;
;
;"CHKR" GOES BACK AND CHECKS TO SEE IF WHAT IS STORED
;THROUGHOUT MEMORY,IS STILL THE SAME AS WHEN IT WAS STORED.
;
CHKR: MOV A,M
RAL
DCX H
MOV A,M
RAL
MOV M,A
INX H
MOV A,M
RAL
MOV M,A
INX H
MOV A,C
SUB L
MOV A,B
SBB H
JC DONE2
DCX H
MOV A,M
RLC
RLC
RLC
DCX H
XRA M
RRC
RRC
ANI 1
XRA M
INX H
INX H
CMP M
JNZ ERROR
INX H
MOV A,C
SUB L
MOV A,B
SBB H
JC DONE2
DCX H
DCX H
MOV A,M
INX H
INX H
CMP M
JNZ ERROR
JMP CHKR
;
;
;
;"DONE2" CHECKS TO SEE WHICH TEST HAS JUST BEEN DONE. IF IT WAS
;THE FIRST TEST THEN IT SETS UP TO TEST THE COMPLIMENT, ELSE IT
;SETS UP FOR THE FINAL FOUR TESTS
;
DONE2: MOV L,E
MOV H,D
SPHL
LXI H,0FFFEH
LDAX D
CPI 2
JZ STORR
MOV L,E
MOV H,D
LXI D,0AA55H
;
;
;
;"STOAL" STORES THE TWO BYTES IN THE D&E REGISTERS (AA HEX AND 55 HEX)
;THROUGHOUT THE TEST AREA
;
STOAL: MOV M,D
INX H
MOV M,E
INX H
MOV A,C
SUB L
MOV A,B
SBB H
JNZ STOAL
LXI H,0
DAD SP
;
;
;
;"CHKAL" TEST TO SEE IF THE DATA STORED THROUGHOUT MEMORY IS THE
;SAME AS THE D&E REGISTERS
;
CHKAL: MOV A,D
MOV D,E
MOV E,A
CMP M
JNZ ERROR
INX H
MOV A,C
SUB L
MOV A,B
SBB H
JNZ CHKAL
;
;
;
;THIS ROUTINE FINDS OUT WHICH PASS THE TEST IS ON,
;AND THEN SETS UP TO DO THE NEXT TEST
;
LXI H,0
DAD SP
LXI D,055AAH
MOV A,M
CPI 0AAH
JZ STOAL
LXI D,0FFFFH
CPI 055H
JZ STOAL
LXI D,0
INR A
JZ STOAL
LHLD MTEST ;GO DO NEXT MEMORY TEST,WERE DONE HERE
PCHL
;
;
;
;THIS ROUTINE PRINTS OUT WHAT IS POINTED TO IN MEMORY BY
;THE B&C REGISTERS UNTIL A ZERO BYTE IS FOUND.
;
MSGOUT: LDAX B
ANA A
JNZ AR1 ;CHECKS FOR '0' END OF MESSAGE FLAG
PCHL
AR1: IN CCTRL
ANI CTRDY
JZ AR1 ;CHECK IF CONSOLE READY
LDAX B
OUT CDATA
INX B ;OUTPUT CHARACTER
JMP MSGOUT
;
;
;
;THE "ERROR" ROUTINE PRINTS OUT THAT THERE HAS BEEN AN ERROR AT
;THE ADDRESS IN THE H&L REGISTERS.IT THEN TELLS THAT THE TEST
;BYTE IS THE BYTE IN THE ACCUMULATOR AND THE ERROR BYTE IS THE
;BYTE POINTED TO BY THE H&L REGISTERS.FINALLY IT PRINTS OUT THE
;BITS THAT ARE IN DISAGREEMENT IN THE TWO BYTES.
;
ERROR: SPHL
MVI A,0FFH ;SET ERROR FLAG
STA ERFLG
LDA ERCNT ;DONE SHOWING 8 ERRORS?
DCR A
JZ ER9
STA ERCNT
LXI H,ER1
MOV D,A
LXI B,MRER1 ;OUTPUT "ERROR AT ADDRESS=" TO CONSOLE
JMP MSGOUT
;
ER1: LXI H,0
DAD SP
MOV B,D
XCHG
LXI H,ER2
JMP OUTER
;
ER2: MOV D,E
LXI H,ER3
JMP OUTER
;
ER3: MOV D,B
LXI B,MER10 ;OUTPUT "PATTERN STORED=" TO CONSOLE
LXI H,ER4
JMP MSGOUT
;
ER4: LXI H,ER5
JMP OUTER
;
ER5: LXI B,MER11 ;OUTPUT "PATTERN READ=" TO CONSOLE
LXI H,ER6
JMP MSGOUT
;
ER6: LXI H,0
DAD SP
MOV E,D
MOV D,M
LXI H,ER7
JMP OUTER
;
ER7: LXI B,MER12 ;OUTPUT "BITS IN ERROR=" TO CONSOLE
LXI H,ER8
JMP MSGOUT
;
ER8: MVI D,0
MVI B,1
LXI H,0
DAD SP
MOV A,E
XRA M
MOV E,A
;
LOP: INR D
MOV A,E
RAR
MOV E,A
JNC NOERR
;
DCR B
JZ LOPE
LUPE: IN CCTRL
ANI CTRDY
JZ LUPE
MVI A,','
OUT CDATA
LOPE: IN CCTRL
ANI CTRDY
JZ LOPE
MOV A,D
ADI 2FH
OUT CDATA
NOERR: MOV A,D
CPI 8
JNZ LOP
ER9: LHLD ECTR ;UPDATE THE ERROR COUNTER
INX H
SHLD ECTR
LHLD MTEST ;RETURN
PCHL
;
;
;
OUTER: IN CCTRL
ANI CTRDY
JZ OUTER
MOV A,D
RLC
RLC
RLC
RLC
ANI 0FH
CPI 0AH
JC OUTR1
ADI 7
OUTR1: ADI '0'
OUT CDATA
OUTR2: IN CCTRL
ANI CTRDY
JZ OUTR2
MOV A,D
ANI 0FH
CPI 0AH
JC OUTR3
ADI 7
OUTR3: ADI '0'
OUT CDATA
PCHL
;
;
;
;
;
;
;ROUTINE TO SHOW THE "DROP LIST" TO THE OPERATOR
;
CDROP: LDA DROPC ;GET THE DROP COUNT
ORA A ;DID WE LOSE ANYBODY?
JNZ PDROP
LXI H,NDMSG ;OUTPUT "NO MEMORY BLOCKS DROPPED" TO CONSOLE
CALL MSG
RET
PDROP: LXI H,DROP ;POINT TO START OF THE DROP LIST
EDROP: PUSH PSW ;SAVE THE DROP COUNT
PUSH H ;SAVE THE DROP POINTER
LXI H,DMMSG ;OUTPUT "DROPPED MEMORY BLOCK(S)=" TO CONSOLE
CALL MSG
POP H ;GET THE DROP POINTER BACK
MOV E,M
INX H
MOV D,M
INX H ;WERE NOW POINTING TO THE NEXT DROP LIST SLOT
XCHG ;GET THE ADDRESS OF THE DROPPED MEMORY BLOCK
CALL HLOUT
XCHG ;SWAP'EM
POP PSW ;GET THE DROP COUNT
DCR A ;DE-BUMP IT
JNZ EDROP ;DO THEM ALL
RET
;
;
;
;"SELECT" MODE ROUTINE (OPERATOR DEFINES ADDRESS RANGE,PATTERN,AND TEST)
;
SELCT: MVI A,0FFH ;SET ERROR DISPLAY COUNT TO 256
STA ERCNT
LXI H,SELCT ;MAKE A RETURN ADDRESS FOR END OF TEST
SHLD MTEST
MENU: LXI H,DFMSG ;OUTPUT "TEST "ALL","SELECT",OR "MONITOR" (Y OR N)?"
; TO CONSOLE
CALL MSG
CALL CECHO ;GET THE ANSWER
CPI 'A' ;"ALL" CHOSEN?
JZ ALL
CPI 'S' ;"SELECT" CHOSEN?
JZ SEL
CPI 'M' ;"MONITOR" CHOSEN?
JZ MNTR
JMP MENU ;OOPS...NONE OF THE ABOVE,TRY AGAIN
ALL: LXI H,01000H ;SET MEMORY "BOTTOM"
SHLD MBOT
LXI H,0C000H ;SET MEMORY "TOP"
SHLD MTOP
JMP SEL1 ;TEST "ALL".....
SEL: LXI H,LMMSG ;OUTPUT "LOW MEMORY ADDRESS=" TO CONSOLE
CALL MSG
CALL PARAM ;GET IT FROM OPERATOR
MOV A,H ;IS THE REQUESTED ADDRESS <1000 HEX?
CPI 010H
JNC SEL0
LXI H,NAMSG ;OOPS...NOT ALLOWED,OUTPUT "INVALID
; MEMORY ADDRESS" TO CONSOLE
CALL MSG
JMP SEL ;GIVE'M ANOTHER CHANCE
SEL0: SHLD MBOT ;SAVE IT AS MEMORY "BOTTOM" ADDRESS
LXI H,HMMSG ;OUTPUT "HIGH MEMORY ADDRESS=" TO CONSOLE
CALL MSG
CALL PARAM ;GET IT FROM OPERATOR
XCHG ;SWAP TO D&E REGS.
MOV A,D ;GET THE HIGH BYTE OF "TOP" MEMORY ADDRESS
LHLD MBOT ;GET MEMORY "BOTTOM" ADDRESS
CMP H ;IS THE TOP < BOTTOM?
JNC STOTOP ;IF NOT,STORE THE "TOP" FOR SAFE KEEPING
LXI H,NAMSG ;ARE YOU POSSIBLY ATTEMPTING TO TRY MY PATIENCE?
CALL MSG
JMP SELCT ;TRY AGAIN,AND AGAIN,AND AGAIN,AND.......
STOTOP: XCHG ;GET THE "TOP" BACK TO H&L REGS.
INX H ;GO ONE PAST THE END,AND SAVE IT
SHLD MTOP
SEL1: LXI H,OPMSG ;OUTPUT "TEST OPTIONS ARE:" TO CONSOLE
CALL MSG
LXI H,TMSG1 ;OUTPUT " 01-GALLOPING PATTERNS TEST" TO CONSOLE
CALL MSG
LXI H,TMSG2 ;OUTPUT " 02-GALLOPING COLUMNS TEST" TO CONSOLE
CALL MSG
LXI H,TMSG3 ;OUTPUT " 03-WALKING PATTERNS TEST" TO CONSOLE
CALL MSG
LXI H,TMSG4 ;OUTPUT " 04-RANDOM PATTERNS TEST" TO CONSOLE
CALL MSG
LXI H,TMSG5 ;OUTPUT " 05-WRITE SATURATION TEST" TO CONSOLE
CALL MSG
LXI H,TMSG6 ;OUTPUT " 06-STATIC CHECK CYCLE TEST" TO CONSOLE
CALL MSG
LXI H,TMSGN ;OUTPUT " ENTER TEST NUMBER(01,02,03,04,05 OR 06)="
CALL MSG
CALL CONI ;GET THE ANSWER
CPI 000H ;HMMMM....DID HE PICK 00 HEX?
JZ SEL1 ;IF SO,START HIM ALL OVER AGAIN
CPI 007H ;TEST NUMBER SELECTED >6?
JNC SEL1 ;IF YES,GIVE THE JERK ANOTHER CHANCE
MOV B,A ;SAVE THE TEST NUMBER IN B REG.
LXI H,EPMSG ;OUTPUT "ENTER PATTERN(00-FF)=" TO CONSOLE
CALL MSG
CALL CONI ;GET THE REQUESTED PATTERN
MOV C,A ;SAVE IT IN C REG.
PUSH B ;EXILE THE TEST NUMBER
LXI H,TPMSG ;OUTPUT " TEST IS IN PROGRESS" TO CONSOLE
CALL MSG
POP B ;FROM WHENCE THY CAME...
LXI D,SELCT ;GO BACK TO "SELECT MODE" AFTER TEST COMPLETION
PUSH D
DCR B ;ADJUST THE TEST NUMBER FOR THE TABLE JUMP
MOV A,B
RLC
ADD B
MOV E,A
MVI D,000H ;MAKE A 16 BIT INDEX
LXI H,BTAB ;GET THE TABLE BASE
MOV A,C ;GET BACK THE SAVED PATTERN
DAD D ;GET H&L REGS. TO EQUAL THE ADRESS OF THE JUMP
PCHL ;GO FOR IT
BTAB: JMP GALPT ;GO DO "GALLOPING PATTERNS TEST"
JMP GALCL ;GO DO "GALLOPING COLUMNS TEST"
JMP WALKT ;GO DO "WALKING PATTERNS TEST"
JMP RNDSL ;GO DO "RANDOM PATTERNS TEST"
JMP WSATT ;GO DO "WRITE SATURATION TEST"
JMP STATT ;GO DO "STATIC CHECK CYCLE TEST"
RET ;THIS SHOULD'NT GET USED
;
;
;
;SUBROUTINE TO INDICATE RETENTION ERROR (GALLOPING PATTERN BAD AFTER 1 MINUTE)
;
RFERR: CMA ;MAKE ERROR FLAG NON-ZERO
STA ERFLG
CMA
PUSH H ;SAVE ERROR BYTE ADDRESS
LHLD ECTR ;UPDATE THE ERROR COUNTER
INX H
SHLD ECTR
LDA ERCNT ;DONE DISPLAYING ALL ERRORS?
DCR A
JZ RFX
STA ERCNT
LXI H,REMSG ;OUTPUT " RETENTION ERROR AT ADDRESS="
CALL MSG
POP H ;GET THE ERROR BYTE ADDRESS
CALL HLOUT
PUSH H ;SAVE ERROR BYTE ADDRESS FOR EXIT
CALL MSG
LXI H,EXMSG ;OUTPUT "EXPECTED "00" DATA,READ BACK " TO CONSOLE
CALL MSG
POP H ;RESTORE POINTER TO BAD BYTE ADDRESS,
; BUT DON'T CHANGE THE STACK
PUSH H
MOV A,M ;GET THE BAD BYTE
CALL BYTEO ;SHOW IT
CALL CRLF
RFX: POP H ;GET THE ERROR ADDRESS BACK FOR EXIT
RET ;EXIT,AND CONTINUE TESTING
;
;
;
;SUBROUTINE TO INDICATE ERROR IN WALKING PATTERN
;
PTERR: PUSH H ;SAVE BAD BYTE ADDRESS
LHLD ECTR ;UPDATE THE ERROR COUNTER
INX H
SHLD ECTR
LDA ERCNT ;DONE DISPLAYING ERRORS?
DCR A
JZ PTX
STA ERCNT
LXI H,MRER1 ;OUTPUT " ERROR AT ADDRESS=" TO CONSOLE
CALL MSG
POP H ;GET THE BAD BYTE ADDRESS ,BUT DON'T
;CHANGE THE STACK
PUSH H
CALL HLOUT
LXI H,MRER2 ;OUTPUT " READ BACK " TO CONSOLE
CALL MSG
POP H ;GET THAT ADDRESS AGAIN
PUSH H
MOV A,M ;GET THE ERROR BYTE
CALL BYTEO ;SHOW IT
LXI H,MRER3 ;OUTPUT " , EXPECTED " TO CONSOLE
CALL MSG
LDA ERPAT ;GET THE "GOOD" DATA BYTE
CALL BYTEO ;SHOW IT ALSO
LXI H,MRER4 ;OUTPUT "LAST ADDRESS WRITTEN WAS" TO CONSOLE
CALL MSG
LHLD LASTW ;GET THE LAST ADDRESS WRITTEN
CALL HLOUT
LXI H,MRER5 ;OUTPUT " PATTERN WAS " TO CONSOLE
SATX: CALL MSG
LDA TPATT ;GET THE TEST PATTERN AND OUTPUT IT TO CONSOLE
CALL BYTEO
CALL CRLF ;KEEP IT NEAT
MVI A,0FFH ;SET THE ERROR FLAG
STA ERFLG
CALL KBINT ;CHECK FOR KEY-BOARD INTERRUPT
PTX: POP H ;RESTORE THE "BAD" ADDRESS
RET ;CONTINUE TESTING
;
;
;
;SUBROUTINE TO HANDLE ERRORS IN "GALLOPING PATTERN/COLUMN TESTS
;
ERR1: PUSH H
LHLD ECTR ;UPDATE THE ERROR COUNTER
INX H
SHLD ECTR
LDA ERCNT ;DONE DISPLAYING ERRORS?
DCR A
JZ COMEX
STA ERCNT
LXI H,MRER6 ;OUTPUT "ERROR READING OTHER CELL" TO CONSOLE
CALL MSG
POP H
JMP COMER ;GO TO COMMON ERROR PROCESSING
;
;
;
ERR2: PUSH H
LHLD ECTR ;UPDATE THE ERROR COUNTER
INX H
SHLD ECTR
LDA ERCNT ;DONE DISPLAYING ERRORS?
DCR A
JZ COMEX
STA ERCNT
LXI H,MRER7 ;OUTPUT "ERROR READING TEST CELL" TO CONSOLE
CALL MSG
POP H
COMER: PUSH H ;PROTECT THE INNOCENT
PUSH D
PUSH B
PUSH PSW
PUSH H
LHLD ECTR ;UPDATE THE ERROR COUNTER
INX H
SHLD ECTR
LXI H,MRER8 ;OUTPUT "TEST CELL=" TO CONSOLE
CALL MSG
POP H
PUSH H
XCHG
CALL HLOUT
XCHG
POP H
PUSH H
LXI H,MRER9 ;OUTPUT ", OTHER CELL=" TO CONSOLE
CALL MSG
POP H
CALL HLOUT
PUSH H
LXI H,MER10 ;OUTPUT "PATTERN STORED=" TO CONSOLE
CALL MSG
POP H ;BLOW-AWAY H&L REGS. TO ADJUST THE STACK
MOV A,B
CALL BYTEO ;SHOW IT
LXI H,MER11 ;OUTPUT "PATTERN READ=" TO CONSOLE
CALL MSG
LDA TPATT
CALL BYTEO ;SHOW IT ALSO
CALL CRLF ;KEEP IT NEAT
MVI A,0FFH ;SET THE ERROR FLAG
STA ERFLG
POP PSW ;EVERYBODY BACK FROM EXILE
POP B
POP D
COMEX: POP H
RET
;
;
;
LOOP1: CALL KBINT ;CHECK FOR KEY-BOARD INTERRUPT
LXI D,10000
LOOP2: DCX D
MOV A,D
ORA E
JNZ LOOP2
DCX B
MOV A,B
ORA C
JNZ LOOP1
RET
;
;
;
;ROUTINES FOR MEMORY TEST
;
GALPT: MOV B,A ;SAVE THE PATTERN
CALL BAKPT ;WRITE THE "BACKGROUND" PATTERN
GALST: LHLD MBOT ;GET THE TEST CELL ADDRESS
XCHG ;SWAP FOR MEMORY TOP INTO H&L REGS.
PNCEL: PUSH D ;SAVE TEST CELL ADDRESS
LHLD MBOT ;GET ADDRESS OF OTHER CELL
LDAX D ;GET CONTENTS OF TEST CELL
CMA ;FLIP IT OVER
STAX D ;STORE IT BACK
GPLOP: CALL KBINT ;CHECK KEY-BOARD INTERRUPT
POP D ;GET BACK ADDRESS OF TEST CELL
PUSH D
CALL COMP ;SEE IF TEST ADDRESS EQUALS OTHER ADDRESS
JZ SKIP ;IF YES,SKIP TESTING
MOV A,M ;GET THE OTHER CELL
STA TPATT ;SAVE IT JUST IN CASE IT'S WRONG
CMP B ;EQUAL TO PATTERN?
LDAX D ;READ BACK THE TEST CELL
CNZ ERR1 ;OOPS....REPORT THE ERROR
CMA ;BACK TO ORIGINAL STATE.........
STA TPATT ;SAVE IT
CMP B ;STILL EQUAL TO PATTERN?
CNZ ERR2 ;OOPS....WRONG HERE ALSO
SKIP: INX H ;BUMP THE OTHER ADDRESS
XCHG ;MEMORY TO D&E REGS.
LHLD MTOP
XCHG
CALL COMP ;AT TOP OF MEMORY BLOCK?
JNZ GPLOP ;IF NOT,CONTINUE "GALLOPING PATTERN" LOOP
POP D ;WHOOPIE...TOP OF MEMORY BLOCK,GET BACK TEST ADDRESS
LDAX D ;GET THE TEST CELL
CMA ;BACK TO ORIGINAL,AND SAVE IT
STAX D
INX D ;BUMP FOR NEXT TEST ADDRESS
CALL COMP ;TOP OF BLOCK YET?
JNZ PNCEL ;IF NOT,GET THE NEXT CELL FOR TEST
RET
;
;
;
GALCL: MOV B,A ;SAVE THE PATTERN
CALL BAKPT ;WRITE BACKGROUND
LHLD MBOT
CNCEL: PUSH H ;SAVE TEST CELL ADDRESS
MOV A,M ;GET CONTENTS OF TEST CELL
CMA ;FLIP IT
MOV M,A ;CRAM IT BACK
CLOOP: CALL KBINT ;CHECK FOR KEY-BOARD INTERRUPT
MVI E,64 ;GOLLY,A DECIMAL NUMBER
MVI D,000H ;SCRUB D REG.
DAD D
XCHG ;NOW D&E REGS. EQUAL H&L REGS.+64
LHLD MTOP
CALL COMP
XCHG
JM CINCR ;BUMP THE TEST CELL ADDRESS IF < MEMORY TOP ADDRESS
JZ CINCR
POP D ;GET AND SAVE THE TEST CELL
PUSH D
LDAX D
CMA ;FLIP IT
STA TPATT ;SAVE IT IN CASE IT'S WRONG
CMP B ;EQUAL TO,PATTERN?
CNZ ERR1 ;IF NOT,REPORT ERROR
MOV A,M ;TEST OTHER CELL
STA TPATT ;SAVE IT
CMP B ;EQUAL TO PATTERN?
CNZ ERR2 ;IF NOT,REPORT ERROR
JMP CLOOP ;TRY NEXT OTHER CELL
CINCR: POP H ;GET TEST CELL ADDRESS
MOV A,M ;GET CONTENTS
CMA ;FLIP BACK TO ORIGINAL
MOV M,A ;RESAVE
CALL INC64 ;BUMP TEST ADDRESS MODULO 64
MOV A,M ;EQUAL TO PATTERN?
STA TPATT ;SAVE IT IN CASE IT'S WRONG
CMP B
CNZ ERR1
CALL INC64
MOV A,M
STA TPATT
CMP B
CNZ ERR1
CALL INC64
ANI 63
RZ ;RETURN IF WRAPPED AROUND TO START ADDRESS
JMP CNCEL
;
;
;
WALKT: CALL BAKPT ;WRITE FULL BACKGROUND PATTERN
LHLD MBOT ;POINT TO FIRST BYTE OF BLOCK ADDRESS
PUSH H ;SAVE FOR INSTANT RESET
CMA ;FLIP BACKGROUND PATTERN FOR TEST PATTERN
STA TPATT ;SAVE IT
WPAT: CALL KBINT ;CHECK FOR KEY-BOARD INTERRUPT
LDA TPATT ;GET THE TEST PATTERN
MOV M,A ;STUFF PATTERN INTO MEMORY
PUSH H ;SAVE "LAST WRITTEN" ADDRESS
SHLD LASTW
INX H
CMA ;FLIP TO BACKGROUND PATTERN
CPAT1: CALL COMP ;TEST BACKGROUND PATTERN FROM "LAST WRITTEN+1",
; TO "END OF BLOCK"
;TESTED ALL REMAINING BACKGROUND?
JZ WKSET ;IF YES,GO TEST PATTERN BYTES
CMP M ;NO...TEST BACKGROUND BYTE
CNZ PTERR ;IF BAD BYTE,REPORT ERROR
INX H ;BUMP THE POINTER
JMP CPAT1 ;GO FOR MORE
WKSET: XCHG ;SET-UP FOR NEXT SECTION,H&L REGS. EQUAL
; LAST ADDRESS IN BLOCK+1
POP D ;D&E REGS. EQUAL "LAST WRITTEN" ADDRESS
XTHL ;H&L REGS. EQUAL FIRST ADDRESS IN BLOCK
PUSH D ;JAM-ON "LAST WRITTEN" TO STACK
CMA ;GET TEST PATTERN BACK
CPAT2: CMP M ;TEST PATTERN BYTES FROM START OF BLOCK,
; TO "LAST WRITTEN"
CNZ PTERR ;ERROR IN "WALKED" BYTE?
CALL COMP ;NO,THEN ARE WE DONE?
INX H
JNZ CPAT2 ;GO FOR MORE IF NOT DONE YET
POP H ;SET-UP FOR NEXT PATTERN BYTE,H&L REGS. EQUAL
; "LAST WRITTEN" ADDRESS
POP D ;D&E REGS. EQUAL LAST ADDRESS IN BLOCK+1
INX H ;BUMP FOR NEXT ADDRESS TO WRITE
CALL COMP ;DONE THE WHOLE THING?
RZ
PUSH H ;NO,PUT A COPY OF MEMORY BOTTOM ON THE STACK
LHLD MBOT
XTHL
JMP WPAT ;GO DO SOME MORE
;
;
;
;SUBROUTINE TO GENERATE BACKGROUND PATTERN AS CONTAINED IN A REG.
;
BAKPT: LHLD MTOP
XCHG
LHLD MBOT ;TOP'S IN D&E REGS.,BOTTOM'S IN H&L REGS.
BAKGR: CALL COMP ;WE DONE?
RZ
MOV M,A ;STORE THE BACKGROUND PATTERN
INX H ;BUMP FOR NEXT ADDRESS
JMP BAKGR ;GO DO MORE 'TILL WE HIT TOP
;
;
;
;SUBROUTINE TO INCREMENT H&L REGS. MODULO 64
;
INC64: INX H ;TEST FOR WRAP-AROUND
MOV A,L
ANI 63
RNZ
MOV A,L
SUI 64
MOV L,A
RNC
DCR H ;BORROW IF NEEDED
RET
;
;
;
;SUBROUTINE TO COMPARE H&L REGS. TO D&E REGS. FOR BLOCK COMPLETION
;
COMP: PUSH B
MOV B,A
MOV A,H
SUB D
JNZ COMP1
MOV A,L
SUB E
COMP1: MOV A,B
POP B
RET
;
;
;
;STORAGE FOR VARIABLES AND STACK POINTERS
;
DS 16 ;16 BYTE STACK POINTER STORAGE AREA
STACK: DS 000H
ERPAT: DS 1 ;STORAGE FOR ERROR PATTERN
ERFLG: DS 1 ;STORAGE FOR BLOCK ERROR FLAG
DROPC: DS 1 ;STORAGE FOR NUMBER OF "DROPPED" BLOCKS
DROP: DS 28 ;DROP BUFFER
DROPP: DS 2 ;POINTER TO NEXT FREE SLOT IN DROP LIST
MBUF: DS 15 ;MEMORY BLOCK BUFFER
DB 080H ;TERMINATOR FOR MEMORY BLOCK BUFFER POINTER
MEMPT: DS 2 ;STORAGE FOR MEMORY BUFFER POINTER
BLKST: DS 2 ;STORAGE FOR MEMORY BLOCK START ADDRESS
MEND: DS 2 ;STORAGE FOR MEMORY BLOCK END ADDRESS
MBOT: DS 2 ;STORAGE FOR 256 "CHUNK" START ADDRESS
MTOP: DS 2 ;STORAGE FOR 256 "CHUNK" END ADDRESS
TPATT: DS 1 ;STORAGE FOR LAST PATTERN WRITTEN
LASTW: DS 2 ;STORAGE FOR LAST ADDRESS WRITTEN
MTEST: DS 2 ;STORAGE FOR MEMORY TEST POINTER
AUTOR: DS 2 ;STORAGE FOR "AUTO1" RETURN ADDRESS FOR LOOPING
PCTR: DS 2 ;STORAGE FOR "PASS" COUNTER
ECTR: DS 2 ;STORAGE FOR "ERROR" COUNTER
ERCNT: DS 1 ;STORAGE FOR ERROR DISPLAY COUNTER
;
;
;
END