; FILE: MEMBIT.SRC CREATED 14-NOV-80 ; WRITTEN BY D.A. STEELE ; LAST UPDATE ; ; THIS WILL BE A RAM TEST WHICH WILL TEST 64K OF RAM ; IN 1K BLOCKS. THE TESTS WILL BE DONE WITHOUT DISTROYING ; ANY PORTION OF RAM WITH THE EXCEPTION OF THE 5K BLOCK JUST ; BELOW CP/M THE TOP OF WHICH WILL BE LOCATED BY (LHLD BDOS+1; ; DCR H; DCR H). ; ; THE TEST: ; 1: WILL FILL MEMORY WITH 0FFH THEN CHECK FOR 0FFH AND FILL WITH 0 ; AND THEN CHECK FOR 0. ; 2: WILL START AT THE FIRST TEST BLOCK LOCATION WITH AN 88H TO ; BE WRITTEN. COUNTING UPWARDS IN MEMORY EACH LOCATION IS WRITTEN ; WITH THE VALUE OF THE PROVIOUS LOCATION ROTATED RIGHT WITH ; CARRY WICH WILL CAUSE AN UNEVEN PATTERN IN EACH 8 OR 16 BYTE ; BLOCK OF MEMORY. ; AFTER THIS 4K BLOCK HAS BEEN TESTED THEN THE NEXT ; BLOCK WILL BE TESTED. ; ; ERRORS WILL BE THE NUMBER OF TIMES ; AN ERROR WAS DETECTED. (IE. IF THERE HAVE BEEN 3 PASSES AND ERRORS ; IS EQUAL TO 3 THIS WILL MEAN THAT ONE ERROR OCCURRED IN EACH PASS ; OR 3 ERRORS OCCURREC IN ONE PASS ETC. STATUS: THE BIT SET WILL WILL ; GIVE THE 4K BLOCK LOCATION IN WHICH ERRORS HAVE OCCURRED SENCE THE START ; IF THE TEST. THE HIGH ORDER BIT WILL COROSPOND TO THE F000H BLOCK OF ; MEMORY. ; ; THIS TEST IS WRITTEN TO BE USED WITH A PASCAL/Z MONITOR FOR CONFIDENCE ; TESTS OF THE ATS III. ; ; THE MONITOR PROGRAM SHOULD HAVE THE FALLOWING DECLARATION ; ; FUNCTION MEMTST : INTEGER; EXTERNAL ; ; A STATUS WORD IS RETURNED TO THE CALLING PROGRAM WITH BITS SET ; ACCORDINGLY TO ALL MEMORY LOCATIONS WHICH FAILED. NAME MEMTST ENTRY MEMTST BDOS EQU 5 BEGIN: MEMTST: JR BACK JR BACK2 ;THE JUMP VECTOR AFTER RESTORE INIT: EXX ;GET READY TO SAVE ALTERNATE REGISTERS POP H ;SAVE THE RETURN ADDRESS PUSH D PUSH B PUSH IY PUSH IX PUSH H ;PUT BACK THE RETURN ADDRESS Š EXX ;ALT. BC IS THE ERROR FLAG SO ZERO IT LXI B,0 LIYD STARTA ;THIS IS THE ADDTESS OF THE NEXT BLOCK EXX ;TO BE TESTED LHLD BDOS+1 ;NOW GET THE ADDRESS OF THE SAVE AREA DCR H ;THIS WILL BE 2 PAGES BELOW CP/M DCR H ;TO ALLOW ROOM FOR SID. MVI L,0 ;NOW MAKE SURE ITS AN EVEN BLOCK MOV A,H ANI 0F0H MOV H,A LXI D,1000H ;HL IS NOW POINTING AT THE TOP BUT STC ;WE WANT THE BOTTOM SO SUBTRACT CMC ;1000H FROM IT. DSBC D PUSH H ;THIS STORE THIS VALUE IN IX POP X RET ; ; IX = ADDRESS OF SAVE AREA ; IY ½ FIRSÔ ADDRESÓ OÆ NEXÔ BLOCË TÏ TEST ; ; ; SAVE: PUSH Y ;HL NOW POINTS TO THE START OF THE POP H ;NEXT TEST BLOCK PUSH X ;POINT DE TO THE SAVE AREA POP D LXI B,400H ;MOVE ONE BLOCK LDIR JR BACK22 ;RETURN TO BACKGROUND ; ; ; SAVEME: LXI H,BOTTOM ;GET THE END AND LENGTH OF THIS LXI B,BOTTOM-BEGIN ; ROUTINE PUSH X ;GET THE ADDRESS OF THE SAVE AREA POP D ; IN D PUSH D ; WE WILL GO TO HERE WHEN FINISHED LDDR ;WITH THE MOVE POP H INX H ;GET PAST THE FIRST JUMP VECTOR INX H LXI B,BOTTOM-BEGIN STC CMC DSBC B ;GET TO BOTTOM OF CODE AREA PCHL ; ; Š; UNSAVE: DB 0FFH ; ; ; REST: PUSH Y POP D ;KEEP IN MIND TO MAINTAIN A ;AS THE ERROR FLAG REST1: ;PUT HL BACK TO THE START OF THE ;START OF THE BLOCK ;BLOCK START IN DE PUSH X POP H ;GET SAVE AREA ADDRESS LXI B,400H LDIR JR BACK5 ; ; ; BACK: DB 0,0,0,0,0,0,0,0,0,0,0,0 ;FOR DEBUG LXI H,0 DAD SP ;GET THE OLD STACK POINTER LXI SP,STAK PUSH H ;SAVE OLD STACK POINTER ON NEW STACK CALL ADDRIN ;GET START AND STOP ADDRESSES BACK1: CALL INIT ;INITIALIZE THE NECESSARY STUFF BACK11: JMP SAVEME BACK2: BACK21 JR SAVE BACK22: JR TEST1 BACK3 JR TEST2 BACK4: JR REST BACK5: CPI 0 ;PASSED CNZ FAIL BACK6 LXI D,400H ;MOVE BOTTOM OF BLOCK UP ONE DADY D ; BLOCK PUSH Y POP H ;GET IT IN HL LBCD STOPA ;GET THE STOP ADDRESS MOV A,H ;AND TEST IT AGAINST THE CMP B ;START OF THE NEXT BLOCK JZ DONE ;STOP IF BLOCK > STOP JNC DONE PUSH X POP B ;GET BOTTOM OF SAVE AREA Š MOV A,B SUB H CPI 30H ;IF LESS THAN 3 BLOCKS THEN WE NEED ;TO RETURN TEST TO ITS ORIGIONAL ;POSITION JRZ RESTXFR BACK7 JRC RESTXFR ;IF CARRY THEN WE ARE CLOSER THAN ;WE WANT BACK8 MOV A,H ;IF HL IS NOW 0 WE HAVE GONE 46K CPI 0 ;SO STOP JZ DONE JR BACK21 ; ; ; TEST1: PUSH Y ;GET ADDRESS OF THE AREA TO BE POP H ;TESTED MVI D,0FFH ;WE'LL FILL W/ FF'S FIRST LXI B,400H ;ONE BLOCKS WORTH TEST11: MOV M,D INX H DCX B MOV A,C ORA B JRNZ TEST11 ;NOW TESTS FOR THOSE FF ;AND FILL W/ 0 LXI B,400H TEST12 DCX H ;HL WAS INCREMENTED PAST THE LAST MVI A,0FFH ;WRITE XRA M ;XOR FF W/ FF = 0 JRNZ ERROR ;OOPS MOV M,A ;FILL M W/ 0 DCX B ;COUNTIT MOV A,B ORA C JRNZ TEST12 LXI B,400H ;NOW TEST FOR ZEROS TEST13: XRA A XRA M JRNZ ERROR INX H DCX B MOV A,B ORA C JRNZ TEST13 JR BACK3 ; ; ; ERROR: MVI A,0FFH ;FAILED Š JR BACK4 ; RESTXFR: JR RESTME BACK4XFR: JR BACK4 BACK6XFR: JR BACK6 ; ; ; TEST2 PUSH Y ;POINT H TO BOTTOM OF TEST BLOCK POP H TEST21: LXI B,400H ; MVI A,88H EXAF TEST22: EXAF MOV M,A INX H DCX B RAR ;MAKE THE NEXT PATTERN EXAF ;SAVE IT MOV A,B ORA C ;ARE WE DONE JRNZ TEST22 LXI B,400H TEST23: EXAF ;MEMORY IS FILLED NOW RLA DCX H ;NEXT LOCATION TO TEST DCX B MOV D,A EXAF ;SAVE PATTERN MOV A,D CMP M ;CHECKIT JRNZ ERROR MOV A,B ORA C ;CHECK COUNT TO SEE IF DONE JRNZ TEST23 MVI A,0 ;PASSED JR BACK4XFR ;TEST2 COMPLETED ; ; ; RESTMEº JMP BACK8 ; ; ; INPUT BUFFER FROM CONSOLE CINSIZ EQU 10 BIOS EQU BDOS WBOOT EQU 0 ŠSTARTM: DB 'ENTER START ADDRESS $' STOPM: DB 0AH,0DH,'ENTER STOP ADDRESS $' EVENM: DB 0AH,0DH,'MUST START ON EVEN 1K BLOCK BOUNDRY',0AH,0DH,'$' CRLF: DB 0AH,0DH,'$' CIN: LXI D,INBUF ;GET ADDRESS OF INPUT BUFFER MVI A,CINSIZ STAX D ;LOAD THE BUFFER LENGTH MVI C,10 CALL BIOS ;LET CP/M INPUT BUFFER RET CEND: LDA INBUF+1 ;GET NUMBER OF CHARACTERS LXI H,INBUF+2 ;POINT TO THE FIRST MVI D,0 ;ZERO D MOV E,A ;CHAR COUNT IN E DAD D ;ADD TO FIRST CHAR LOC. MVI M,0 ;AND PUT A 0 THERE HEXIN: LXI D,INBUF+2 ;POINT TO FIRST CHAR IN BUFFER LXI H,0 ;ZERO THE NUMBER IN1: LDAX D ;GET A CHAR SUI '0' ;CHECK FOR < 0 RC ;BUFFER END RETURN ADI '0'-'G' ;CHECK > F RC ;INVALID RETURN ADI 6 JP IN2 ;NO BETWEEN A AND F ADI 7 RC IN2: ADI 10 ORA A ;CLEAR CARRY MOV C,A ;MOVE HEX TO C MVI B,0 ;ZERO B DAD H ;SHIFT NUMBER LEFT 4 DAD H DAD H DAD H DAD B ;AND ADD NEW DIGIT INX D ;INC BUFFER POINTER JMP IN1 ;DO NEXT CHAR NOTEVEN: LXI D,EVENM ;SEND NOT EVEN MESSAGE MVI C,9 CALL BIOS ADDRIN: LXI H,0 SHLD STARTA ;STORE THE START ADDRESS LXI H,0FFFFH SHLD STOPA ;STORE THE STOP ADDRESS RET ŠDONE: CALL CFAIL ;CHECK ALL BLOCKS THAT FAILED AND UPDATE ERROR FLAG JMP PASS ;PRINT OUT THE ERRORS BOTTOM: NOP ; FILE FAIL.SRC 14-DEC-80 ; ; IN THE EVENT OF A TEST FAILURE, THIS ROUTINE WILL MOVE ; THE 4K BLOCK NUMBER INTO A REG. ; AND WILL IN TURN OR IT IN WITH THE ERROR FLAG. ; ; THE PASS COUNT AND ERROR COUNT WILL BE INCREMENTED ; ACCORDINGLY ; ; BECAUSE IT IS NEVER EXECUTED WHILE MEMORY IS DISPLACED, THIS PORTION ; IF THE TEST PROGRAM IS NEVER SAVED, ; ERRFLG: DW 0 ;A STATUS WITH BITS SET CORROSPONDING TO THE 4K BLOCKS THAT HAVE FAILED ERRCNT: DW 0 ;THE NUMBER OF BLOCKS IN WHICH ERRORS HAVE OCCURRED. IE IF TWO ERRORS OCCUR IN ONE PASS ;THEN THIS WILL BE INCREMENTED BY TWO EVEN THOUGH ONLY ONE PASS HAS BEEN MADE ERRM: DB ' ERRORS = $' STATM: DB ' STATUS = $' ERRORS: DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;16 4K BLOCKS WILL INDICATE IN WHICH BLOCKS ERRORS HAVE OCCURED. OUTCHAR: ANI 0FH ;MASK 4 BITS ADI 90H ;ADD OFFSET DAA ;DEC ADJUST ACI 40H ;ADD OFFSET DAA ;DEC ADJUST MOV E,A ;TO FOR OUTPUT MVI C,2 ;CONSOL OUT CALL BDOS RET HEXPRN: PUSH H PUSH PSW RRC RRC RRC RRC CALL OUTCHAR POP PSW CALL OUTCHAR POP H RET OUTIT: MOV A,H ;PUT 2 HIGH ORDER DIGITS IN A CALL HEXPRN MOV A,L CALL HEXPRN RET Š; SET THE PROPER BYTE IN ERRORS TO CORROSPOND TO THE BLOCK OF MEMORY THAT FAILED ; CALLED BY MEMTST AFTER A BLOCK HAS FAILED ; FAIL: PUSH Y POP H ;GET THE BLOCK ADDRESS MOV A,H ;HIGH BYTE OF BLOCK INTO A RRC RRC RRC RRC ANI 0FH ;BLOCK NO. NOW IN A LXI H,ERRORS ;GET ADDRESS OF THE ERROR FLAGS MOV E,A ;GET OFSET OF PROPER FLAG MVI D,0 DAD D ;ADD IN THE OFFSET MVI M,0FFH ;SET THE FLAG RET ; SET THE ERROR FLAG TO CORROSPOND WITH ALL ERROR ARRAY BYTES THAT HAVE BEEN SET ; FAILD: PUSH H ;SAVE POINTER TO ERRORS PUSH B ;SAVE COUNTER MOV A,B ;GET BLOCK NUMBER FOR COMPAIR LXI D,5 ;EACH CASE WILL BE 5 BYTES APART LXI H,A0 ;POINT HL TO FIRST CASE MVI B,0 ;WE'LL TEST FOR 0 FIRST FAIL1: CMP B ;IS B=BLOCK NO.? JZ AX ;IF SO JUMP OUT INR B ;IF NOT PREPAIR TO TEST NEXT NUMBER DAD D ;POINT TO NEXT CASE JR FAIL1 ; CHECK ERROR ARRAY FOR BLOCKS FAILED - CALLED BY MEMTEST AT END OF 64K PASS CFAIL: LXI H,ERRORS MVI B,0 CFAIL1: MVI A,0FFH ;LOOK AT IRST BYTE IN ERROR ARRAY CMP M ;IF SET THEN PROCESS IT CZ FAILD INX H ;INCREMENT POINTER INR B ;COUNT HOW MANY WE'VE LOOKED AT MVI A,10H CMP B ;SEE IF WE'RE DONE RZ JMP CFAIL1 AX: PCHL ;DO THE NECESSARY CASE A0: LXI B,1 JR DOOR A1: LXI B,2 JR DOOR A2: LXI B,4 JR DOOR A3: LXI B,8 JR DOOR A4: LXI B,10H Š JR DOOR A5: LXI B,20H JR DOOR A6: LXI B,40H JR DOOR A7: LXI B,80H JR DOOR A8: LXI B,100H JR DOOR A9: LXI B,200H JR DOOR AA: LXI B,400H JR DOOR AB: LXI B,800H JR DOOR AC: LXI B,1000H JR DOOR AD: LXI B,2000H JR DOOR AE: LXI B,4000H JR DOOR AF: LXI B,8000H JR DOOR DOOR: LDED ERRFLG ;NOW OR INTO THE ERROR FLAG MOV A,D ;THE BLOCK NUMBER IN WHICH THE ORA B ;ERROR JUST OCCURED MOV D,A MOV A,E ORA C MOV E,A SDED ERRFLG ;STORE THE ERROR FLAG LHLD ERRCNT INX H SHLD ERRCNT ;STORE NEW ERROR COUNT POP B ;RESTORE BLOCK NUMBER WE ARE ON POP H ;AND THE POINTER TO ERROR RET ;TO CFAIL: + X ; INCREMENT THE PASSCOUNT CALLED BY MEMTST ; AND PRINT THE STATUS LINE TO THE CRT ; PASS: DPASS: LXI D,ERRM ;PRINT THE ERROR COUNT CALL PRNT LHLD ERRCNT CALL OUTIT LXI D,STATM CALL PRNT LHLD ERRFLG Š CALL OUTIT ; NOW PREPAIR TO RETURN TO PASCAL/Z POP IX ; RESTORE ALL ALTERNATE REG. POP IY POP B POP D EXX XRA A LXI H,ERRFLG ; GET THE ERROR FLAG MOV E,M INX H MOV D,M POP H SPHL ;RESTORE ORIGIONAL STACK POINTER RET PRNT: MVI C,9 CALL BDOS RET INBUF: DS CINSIZ STARTA: DS 2 STOPA: DS 2 DS 30 STAK:  .