; 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
�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:
; 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