;*********************************************************************** ; 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