home *** CD-ROM | disk | FTP | other *** search
- ;BBBB RRRR AAA III N N W W AAA SSS H H
- ;B B R R A A I NN N W W A A S S H H
- ;B B R R A A I N N N W W A A S H H
- ;BBBB RRRR A A I N NN W W W A A S HHHHH
- ;B B R R AAAAA I N N W W W AAAAA S H H
- ;B B R R A A I N N W W W A A S S H H
- ;BBBB R R A A III N N WWW A A SSS H H
- ;
- ;
- ;A Z80 PROGRAM TO TEST MEMORY RIGOROUSLY AND QUICKLY
- ;RUN WITH NO M1 WAIT STATES TO FIND SLOW CHIPS
- ;
- ;last modified 8 jun 1981 at nosc hawaii to configure for that system
-
- ;
- ;A SERIALIZED CIPHER IS HIDDEN IN THIS PROGRAM BY WHICH IT MAY BE
- ;TRACED TO THE SOURCE OF ITS RELEASE.
- ;
- ;
- ORG 0100H
- CR EQU 0DH
- LF EQU 0AH
- TCR EQU 8DH ;WITH BIT 7 SET FOR TERMINATING STRINGS
- TLF EQU 8AH
- TSP EQU 0A0H
- MAXADR EQU 0FFFFH ;64K IF NO MEMORY MAPPED IO
- START JR ST1 ;JUMP AROUND DATA AREA
-
- GIL equ 1 ;home system configuration
- ZOBEX equ 0 ;nosc configuration
-
- ;USER'S JUMP TABLE GOES HERE
-
- ORG 106H
-
- INIT: JP INITX
- CHKIN: JP CHKINX
- CRTO: JP CRTOX
- PRTO: JP PRTOX
- FREEMEM:DEFW ENDOFIT
-
- PBYTE: JP CRTOX ;SWITCH FOR PRINTER OR CRT
-
- FIRST DEFW 0 ;FIRST ADDR TO TEST
- LAST DEFW 0 ;LAST ADR TO TEST
- NEX1K DEFW 0 ;NEXT 1K CHUNK FOR XTALK
- END1K DEFW 0 ;END OF 1K CHUNK
- NBYTES DEFW 0 ;LAST - FIRST +1
- ITER DEFB 0 ;NO OF TIMES TO DO TEST
- CTR DEFB 0 ;COUNTER FOR ITERATIONS
- ERCTR DEFW 0 ;ERROR COUNTER
- TYCTR DEFB 0 ;COUNTS ADDRESS TYPEOUTS IN XTALK
- TESTAD DEFW 0 ;CURRENT ADR FOR IBUS TEST
- BYTCNT DEFW 0 ;# BYTES LEFT TO TEST
- LONGI: DEFB 0FFH ;FF IF LONG TEST NOT WANTED, 0 IF IT IS
- XTLK: DEFB 0FFH ;FF IF XTALK TESTS NOT WANTED
- CONTMD: DEFB 0FFH ;FF IF CONTINUOUS MODE NOT WANTED
-
- ST1 LD SP,STACK ;GIVE STACK 64 BYTES OF ROOM
- XOR A ;CLEAR A
- LD DE,STAKBAK
- LD HL,STACK-3 ;LEAVE ROOM FOR THE CALL
- CALL SADEHL ;ZERO STACK AREA
- CALL INIT ;DO WHATEVER HOUSEKEEPING IS NEEDED
- LD HL,HITHERE
- CALL GETANS
- JP NZ,ST2
- LD HL,(PRTO+1) ;GET PRINTER ADDRESS
- JP ST3
- ST2: LD HL,(CRTO+1) ;GET CRT ADDRESS
- ST3: LD (PBYTE+1),HL ;PUT CRT OR PRT ADR IN VECTOR
- LD HL,NOTMSG
- CALL TYPMSG
- LD HL,START
- CALL TYPSHL ;TYPE BEGIN OF PROGRAM
- LD HL,(FREEMEM) ;DON'T TEST BELOW END PROGRAM
- CALL TYPSHL
- LD HL,ENTMSG
- CALL TYPMSG ;TYPE ENTRY MESSAGE
- CALL GETHEX ;GET FIRST ADDRESS
- LD (FIRST),HL ;STORE FIRST ADDRESS
- CALL GETHEX ;GET LAST ADDRESS
- LD (LAST),HL ;STORE LAST ADDRESS
- LD HL,(LAST) ;COMPUTE NBYTES
- LD BC,(FIRST)
- AND A ;CLEAR CARRY FLAG
- SBC HL,BC ;DO SUBTRACT
- INC HL ;ADD ONE
- LD (NBYTES),HL ;STORE NBYTES TO TEST
- ;
- LD HL,ITMSG
- CALL TYPMSG ;TYPE ITERATIONS MESSAGE
- CALL GETHEX ;GET FROM TERMINAL
- LD A,L
- LD (ITER),A ;MAX IS FF
- LD HL,LNGMSG
- CALL GETANS ;ASK IF WANT LONG IBUS TEST
- LD (LONGI),A ;STORE 0 IF YES, FF IF NO
- LD HL,XTKMSG
- CALL GETANS ;ASK IF WANT CROSSTALK TESTS
- LD (XTLK),A
- LD HL,CONMSG
- CALL GETANS ;ASK IF WANT TO TEST FOREVER
- LD (CONTMD),A
- LD HL,0
- LD (ERCTR),HL ;CLEAR ERROR COUNTER
- ;NOW BEGIN TESTING
- ;
- ; ZEROES AND ONES TEST
- ;
- ;
- ; STORE ALL ZEROES THRU AREA
- ;
- ; READ BACK AND TEST
- ;
- ;
- ; STORE ALL ONES THRU AREA
- ;
- ; READ BACK AND TEST
- ;
- ;
- ; RECYCLE N ITERATIONS
- ;
- ;
- ;DO ZEROES AND ONES TEST FIRST
- BIGLP: CALL SETCNT ;SET CTR TO ITERATIONS
- LD HL,ZMSG
- CALL TYPMSG
- T1 LD A,0 ;START WITH ZEROES
- CALL STR ;STORE IN WHOLE AREA
- CALL RD ;CHECK FOR ERRORS
- LD A,0FFH ;NOW DO ALL ONES
- CALL STR
- CALL RD
- CALL NTERUP ;SEE IF ANYTHING TYPED
- CALL CKCNT ;SEE IF CTR IS ZERO YET
- JR NZ,T1 ;GO BACK AND DO IT AGAIN
- ;
- ; INCREMENTING BYTE TEST
- ;
- ;
- ; STORE 1 TO FF (NEVER 00) IN CONSECUTIVE BYTES
- ;
- ; (USE CPI TO VERIFY STORED CORRECTLY)
- ;
- ; REPEAT TIL END OF AREA
- ;
- ;
- ; READ BACK AND TEST FOR KNOWN VALUES
- ;
- ; RECYCLE N ITERATIONS
- ;
- ;
- ;DO ROTATING PATTERN TEST
- CALL SETCNT ;SET CTR FOR INCREMENTING PATTERN TEST
- LD HL,INCMSG ;NOW DO INCREMENTING PATTERN
- CALL TYPMSG ;TYPE INCREMENTING PATTERN TEST
- T2 CALL STRROT ;STORE PATTERNS
- CALL RDROT ;TEST THEM
- CALL NTERUP ;SEE IF BOSS WANTS TO STOP
- CALL CKCNT ;SEE IF ITERATIONS DONE
- JR NZ,T2 ;NOT YET
- ;
- ;
- ; PART A: (NOP TEST)
- ;
- ; STORE FF EVERYWHERE EXCEPT PROGRAM
- ;
- ; SET UP 38H TO JP XYZ
- ;
- ; STORE NO-OP (00 BYTE)
- ;
- ; STORE RST 38H (FF BYTE) IN NEXT BYTE
- ;
- ; LOAD REGISTERS WITH KNOWN PATTERN
- ;
- ; JP NO-OP
- ;
- ;
- ; XYZ: TEST TO SEE IF CAME FROM RIGHT PLACE
- ;
- ; TEST TO SEE IF REGISTERS CHANGED
- ;
- ; SET 00 BYTE TO FF (UNLESS DOING LONG MODE)
- ;
- ; INDEX UP ONE BYTE AND REPEAT
- ;
- ;
- ;
- ; PART B: (INSTRUCTION TEST)
- ;
- ; SET UP AS FOR PART A
- ;
- ;
- ; STORE SHORT PROGRAM THAT TRANSFERS DATA AND SHIFTS
- ;
- ; SET UP REGISTERS WITH KNOWN PATTERNS
- ;
- ; CALL PROGRAM
- ;
- ;
- ; SEE IF CAME BACK PROPERLY
- ;
- ; TEST REGISTERS FOR PROPER VALUES
- ;
- ; INDEX TO NEXT BYTE AND REPEAT TO END OF AREA
- ;
- ; RECYCLE N ITERATIONS
- ;
- ;
- ;DO INSTRUCTION READUP TESTS
- ;THIS TEST IS DEATH ON SLOW MEMORY CHIPS BECAUSE THE Z80 WITH
- ;NO M1 WAIT STATES NEEDS MEMORY ACCESS TIME UP TO 130 NS FASTER
- ;ON INSTRUCTION READUP THAN IT DOES FOR OPERAND READ/WRITE.
- ;THIS TEST WRITES IN ALL RAM MEMORY EXCEPT THE PROGRAM AREA
- ;IN ORDER TO DEFEND AGAINST WHAT BAD INSTRUCTION READUP CAN
- ;DO TO A PROGRAM. VERY VERY BAD CHIPS CAN STILL WIPE OUT
- ;THE PROGRAM THEORETICALLY, ALTHOUGH IT HAS NOT BEEN OBSERVED
- ;SINCE THE LATEST BULLETPROOF STACK CODE HAS BEEN ADDED.
- ;
- SLOCHIP XOR A ;CLEAR TYPEOUT COUNTER
- LD (TYCTR),A
- CALL SETCNT ;PRESET COUNT OF ITERATIONS
- LD HL,IBUSMS ;TYPE TEST WE'RE DOING
- CALL TYPMSG
- LD A,0FFH ;STORE FF EVERYWHERE
- LD DE,0
- LD HL,START-1
- CALL SADEHL ;STORES FF FROM ZERO TO BASE
- LD DE,(FREEMEM) ;FIRST BYTE OF FREE MEMORY
- LD HL,MAXADR ;END OF ALLOWED RAM SPACE
- CALL SADEHL ;FROM END OF PROGRAM TO END OF MEMORY
- IBUS: LD DE,(FIRST)
- LD HL,(LAST)
- LD A,0FFH
- CALL SADEHL ;STORE FF IN TEST MEMORY
- LD HL,(NBYTES)
- LD BC,LNGTH
- AND A ;CLEAR CARRY
- SBC HL,BC ;LEAVE ROOM FOR TEST PROGRAM
- LD (BYTCNT),HL ;SAVE BYTES LEFT TO TEST
- LD HL,(FIRST)
- LD (TESTAD),HL ;SAVE CURRENT TEST ADDRESS
- LD (GOTHAR+1),HL ;IN CASE DO LONG TEST ALWAYS JUMP TO BEGIN
- NOPFF: LD (HL),00H ;NO OP
- INC HL
- LD (HL),0FFH ;RESTART 38H
- DEC HL
- LD A,(LONGI) ;GET LONG TEST FLAG
- OR A ;IF 0 WE'LL DO IT
- JR Z,YLI ;JUMP AROUND STORE OF PLACE TO JUMP
- LD (GOTHAR+1),HL ;PRESET JSR
- YLI: LD A,0C3H ;JP INST
- LD (38H),A ;STORE AT RESTART 38H LOCATION
- LD HL,TESTO ;PLACE TO GO
- LD (39H),HL ;STORE IT
- CALL LDEM ;LOAD UP REGS WITH KNOWN PATTERN
- GOTHAR: JP 0 ;PLACE TO GO GETS STORED HERE
- ;
- ;
- TESTO: LD IX,NOPMSG ;MESSAGE OF WHICH TEST FAILED
- CALL ICHECK ;SEE IF REGS ARE OK
- POP HL ;GET RETURN ADR FROM STACK
- DEC HL
- DEC HL
- PUSH HL ;SAVE WHERE CAME FROM
- LD DE,(TESTAD) ;WHERE WE SHOULD HAVE COME FROM
- AND A
- SBC HL,DE
- JR Z,REAL ;IF CAME FROM RIGHT PLACE
- LD HL,LOSTMSG
- CALL LOSTIT ;OOPS
- ;
- ;NOW TRY A FEW REAL INSTRUCTIONS
- ;
- REAL:
- LD SP,STACK
- LD DE,(TESTAD)
- LD HL,TESTCOD
- LD BC,LNGTH
- LDIR ;BLOCK MOVE PROGRAM TO TEST AREA
- LD HL,(TESTAD)
- LD (CALLIT+1),HL ;THIS TIME WE'LL DO A CALL
- LD A,0C3H ;JP
- LD (38H),A
- LD HL,WILDBLUE
- LD (39H),HL ;IN CASE FLY OFF THE HANDLE SOMEWHERE
- CALL LDEM ;LOAD UP REGISTERS
- CALLIT CALL 0 ;HERE WE GO - I HOPE
-
- ;SHOULD COME BACK HERE IF CODE IS EXECUTED ANYTHING LIKE RIGHT
-
- CUMBAK: LD SP,STACK ;IN CASE STACK GOT CLOBBERED BY BAD MEM
- LD IX,EXMSG ;TEST THAT FAILED MESSAGE
- CALL ICHECK ;SEE IF REGS ARE WHAT THEY SHOULD BE
- LD HL,(TESTAD)
- LD A,(HL)
- CP 0AAH ;SEE IF SWAP GOT DONE RIGHT
- CALL NZ,ERR9
- INC HL ;POINT TO NEXT BYTE
- LD A,(HL)
- CP 0AAH
- CALL NZ,ERR9
-
- DUNONE: CALL NTERUP ;SEE IF OP WANTS ANYTHING
- LD HL,(TESTAD) ;GET HL BACK
- LD BC,(BYTCNT) ;GET BC BACK
- LD A,(LONGI) ;0 IF LONG TEST WANTED
- LD (HL),A ;SET 00 OR FF WHERE INST WAS
- CPI ;HL UP, BC DOWN
- LD (TESTAD),HL ;UPDATE TEST ADDRESS
- LD (BYTCNT),BC ;UPDATE # BYTES LEFT TO TEST
- JP PE,NOPFF ;GO BACK FOR MORE
- THRU1: CALL NTERUP
- LD A,(TYCTR) ;UPDATE TIMES TYPED
- INC A
- LD (TYCTR),A
- AND 1FH ;USE 5 BITS TO COUNT TO 32
- CALL Z,CRLF ;THAT'S ENOUGH
- LD HL,SPIMSG ;TYPE SPACE I TO INDICATE ONE PASS
- CALL TYPMSG
- CALL CKCNT
- JP NZ,IBUS ;GO BACK FOR ANOTHER PASS
- JP GWRT ;GO TO CROSSTALK TESTS
-
- RDYGO: DEFM 'READY TO LEAP?',CR,LF
-
- TESTCOD:NOP
- NOP
- LD A,E
- RLA
- LD IX,5555H
- LD HL,0AAAAH
- LD SP,(TESTAD)
- INC SP
- INC SP ;SO WILL PUSH TO FIRST TWO BYTES
- PUSH IX
- EX (SP),HL ;HL_5555, (TESTAD)_AAAA
- LD SP,STACK-2
- TESTND: RET ;RETURN TO CALLER
-
- LNGTH: EQU TESTND-TESTCOD+1
-
- ;
- ;STORES A FROM ADR IN DE THRU ADR IN HL
- SADEHL: AND A ;CLEAR CARRY
- SBC HL,DE
- INC HL ;#BYTES TO STORE
- LD B,H
- LD C,L ;TO BYTE COUNTER
- EX DE,HL ;GET WHAT WAS IN DE
- PUTIT: LD (HL),A
- CPI
- JP PE,PUTIT ;LOOP BACK TIL DONE
- RET
- ;
- ;LOADS REGISTERS WITH KNOWN PATTERN
- ;
- LDEM LD A,0B4H ;AS GOOD A NUMBER AS ANY
- LD BC,0BBCCH
- LD DE,0DD5AH
- LD HL,5555H
- OR A ;CLEAR CARRY BIT
- RET
- ;
- ;CHECKS CONTENTS OF REGISTERS TO SEE THEY ARE WHAT SHOULD BE
- ;
- ICHECK: JR C,ERR1 ;CARRY SHOULD NOT BE SET
- CP 0B4H
- JR NZ,ERR2 ;A SHOULD BE B4
- LD A,B
- CP 0BBH
- JR NZ,ERR3
- LD A,C
- CP 0CCH
- JR NZ,ERR4
- LD A,D
- CP 0DDH
- JR NZ,ERR5
- LD A,E
- CP 5AH
- JR NZ,ERR6
- LD A,H
- CP 55H
- JR NZ,ERR7
- LD A,L
- CP 55H
- JR NZ,ERR8
- RET ;NO ERRORS IF GOT THIS FAR
-
- ERR1 LD HL,CBIT
- JR TYERR
- ERR2 LD HL,ACHNG
- JR TYERR
- ERR3 LD HL,BCHNG
- JR TYERR
- ERR4 LD HL,CCHNG
- JR TYERR
- ERR5 LD HL,DCHNG
- JR TYERR
- ERR6 LD HL,ECHNG
- JR TYERR
- ERR7 LD HL,HCHNG
- JR TYERR
- ERR8 LD HL,LCHNG
- JR TYERR
- ERR9: LD HL,EXSP
-
- ;ENTERED WITH IX POINTING AT MESSAGE ABOUT WHICH TEST FAILED
- ;HL POINTS TO ERROR MESSAGE
- ;
- TYERR: CALL CRLF
- PUSH HL
- PUSH IX
- POP HL ;GET WHICH TEST FAILED IN HL
- CALL TYPMSG ;TYPE IT
- LD HL,(ERCTR) ;GET NO OF ERRORS SO FAR
- INC HL
- LD (ERCTR),HL ;UPDATE IT
- CALL TYPSHL ;TYPE NO OF ERRORS
- CALL SPACE
- POP HL
- CALL TYPMSG ;HL POINTS TO MESSAGE
- CALL SPACE
- LD A,'@'
- CALL PBYTE
- LD HL,(TESTAD) ;WHERE WE WERE TESTING WHEN THINGS GOT BAD
- CALL TYPSHL ;TYPE THIS ADDRESS
- CALL NTERUP ;SEE IF STOP AFTER THIS ERROR
- RET
- ;
- ;TYPES WHERE WE WERE WHEN WE GOT LOST, AND MAYBE
- ;WHERE WE GOT TO MORE OR LESS
- LOSTIT: CALL TYERR
- LD HL,TOMSG ;TYPE "TO"
- CALL TYPMSG
- POP HL ;PASS BY RETURN ADR ON STACK
- POP HL ;GET FROM WHENCE WE WENT TO 38H
- DEC SP
- DEC SP
- DEC SP
- DEC SP ;GET STACK BACK IN SHAPE
- CALL TYPSHL ;TYPE IT
- CALL NTERUP
- RET
- ;
- ;COME HERE FROM INSTRUCTION TEST IF DIDN'T DO NORMAL RETURN
- WILDBLUE: LD IX,EXMSG ;TEST WHICH FAILED
- CALL ICHECK
- LD HL,LOSTMSG
- CALL LOSTIT ;TYPE WHAT LITTLE WE KNOW ABOUT IT
- POP HL ;STACK CLEANUP
- POP HL ;STACK CLEANUP
- JP DUNONE ;GIVE UP ON THIS ADDRESS, GO TO NEXT
- ;
- ;BEGIN CROSSTALK TESTS (RUNNING TIME GOES UP EXPONENTIALLY)
- ;
- ;ONLY EXECUTES THESE TWO TESTS ONCE, REGARDLESS OF INTERATION COUNTER
- ;BECAUSE THEY ARE SO LONG RUNNING. WILL NOT DO TEST AT ALL UNLESS AREA
- ;IS AT LEAST 400H (1024) IN SIZE.
- ;
- ; EXPONENTIAL WRITE TEST
- ;
- ;
- ; ZERO THE AREA
- ;
- ; CLEAR INDEX 1
- ;
- ;
- ; LOOP1: STORE FF BYTE (INDEX 1)
- ;
- ; CLEAR INDEX 2
- ;
- ;
- ; LOOP2: STORE 00 (INDEX 2)
- ;
- ; SEE IF FF STILL OK
- ;
- ; BUMP INDEX 2
- ;
- ; LOOP2 TIL END OF AREA
- ;
- ;
- ; BUMP INDEX 1
- ;
- ; LOOP1 TIL END OF AREA
- ;
- ; EXIT TO EXPONENTIAL READ TEST
- ;
- ;
- GWRT: XOR A ;CLEAR TYPEOUT COUNTER
- LD (TYCTR),A
- LD A,(XTLK) ;SEE IF WANT TO DO THESE TESTS AT ALL
- OR A ;SET FLAGS
- JP NZ,DONE ;NOT WANTED
- T3 LD HL,GWRMSG
- CALL SETUP ;GET AREA DEFINED, ETC
- WLP0: CALL COMCOD ;LOOP HOUSEKEEPING SUBR
- JP C,STRD ;DONE IF MINUS
- LD DE,(NEX1K) ;DE KEEPS TRACK OF WHERE THE FF IS
- WLP2: CALL TYPEAD ;TYPE ADDRESS IF MULTIPLE OF 100H
- LD HL,(NEX1K) ;STARTING ADR OF 1K CHUNK
- LD BC,03FFH ;ALWAYS 1 K CHUNKS
- LD A,0FFH
- LD (DE),A ;STORE THE FF BYTE
- WMLP XOR A ;CLEAR A
- LD (HL),A ;STORE A ZERO BYTE WHERE HL IS
- LD A,(DE) ;GET SUPPOSED FF BYTE
- CP 0FFH ;SEE IF IT STILL IS FF
- JR NZ,WOOPS ;MAYBE OK, MAYBE NOT
- XOR A ;CLEAR A AGAIN
- WLP1 CPI ;COMPARE A & (HL), DEC BC
- JP PO,WEND1 ;THRU AREA?
- JR Z,WMLP ;CHECK NEXT ADDRESS
- CALL ERR ;BYTE WASN'T ZERO
- JR WMLP
- ;
- WOOPS AND A ;CLEAR CARRY FLAG
- PUSH HL ;SAVE ADDRESS POINTER
- SBC HL,DE ;COMPARE TO WHERE FF SUPPOSED TO BE
- POP HL ;GET POINTER BACK
- JR NZ,WERR ;REAL ERROR, IT WASN'T HERE
- LD A,0FFH ;NOW RESTORE THE CLOBBERED FF
- LD (DE),A
- JR WLP1 ;KEEP GOING
- ;
- WERR INC HL ;SIMULATE ACTION OF CPI ON HL
- CALL ERR ;TYPE OUT THE ERROR
- JR WMLP
- ;
- WEND1 LD HL,(END1K) ;SEE IF WE'RE THRU THE AREA YET
- AND A ;CLEAR CARRY
- SBC HL,DE ;COMPARE
- JR NZ,KG1 ;NOT DONE YET
- CALL UPDATE ;SET NEXT 1K CHUNK
- JR WLP0 ;CONTINUE TESTING WITH NEXT CHUNK
- KG1: INC DE ;UP POINTER TO FF BYTE
- JR WLP2
- ;
- ;
- ; EXPONENTIAL READ TEST
- ;
- ;
- ; ZERO THE AREA
- ;
- ;
- ; LOOP1: STORE FF (INDEX 1)
- ;
- ; CLEAR INDEX 2
- ;
- ;
- ; LOOP2: READ BYTE (INDEX 2)
- ;
- ; TEST FOR CORRECTNESS
- ;
- ; SEE IF FF STILL OK
- ;
- ; BUMP INDEX 2
- ;
- ; LOOP2 TIL END OF AREA
- ;
- ;
- ; BUMP INDEX 1
- ;
- ; LOOP1 TIL END OF AREA
- ;
- ; EXIT
- ;
- ;
- ;EXPONENTIAL READ CROSSTALK TEST
- ;
- STRD LD HL,GRDMSG
- CALL SETUP
- RDLP0: CALL COMCOD
- JR C,DONE ;YES
- LD DE,(NEX1K) ;DE KEEPS TRACK OF FF BYTE
- STLP: CALL TYPEAD ;TYPE ADDRESS EVERY 100H
- LD HL,(NEX1K) ;BEGIN PASS AT FIRST BYTE
- LD BC,03FFH ;ALWAYS TEST 1K
- LD A,0FFH ;ALL ONES
- LD (DE),A ;STORE FF IN (DE)
- XOR A ;CLEAR A
- MLP CPI ;SEE IF THIS BYTE IS ZERO
- JP PO,END1 ;AT END OF AREA IF PO
- JR Z,MLP ;KEEP LOOKING FOR FF OR END OF AREA
- MAYBE PUSH HL ;SAVE NEXT BYTE TO TEST
- DEC HL ;TO GET BACK TO BYTE JUST TESTED
- AND A ;CLEAR CARRY FLAG
- SBC HL,DE ;SEE IF WHERE FF WAS SUPPOSED TO BE
- JR NZ,ERROR ;NO, THIS IS AN ERROR FOR SURE!
- POP HL
- JR MLP ;FF WAS SUPPOSED TO BE HERE
- END1: LD HL,(END1K)
- AND A ;CLEAR CARRY FLAG
- SBC HL,DE
- JR NZ,KG2 ;IF NOT DONE WITH 1K CHUNK YET
- CALL UPDATE
- JR RDLP0
- KG2: LD A,(DE) ;GET THE SUPPOSED FF BYTE
- CP 0FFH ;SEE IF IT STILL IS FF
- JR NZ,ERROR ;LOST THE FF
- XOR A ;CLEAR A
- LD (DE),A ;CLEAR THE FORMER FF BYTE
- INC DE
- JR STLP ;END OF ONE LOOK, GO STORE FF IN NEXT BYTE
- ;
- ;
- ;END OF ONE PASS OF SAND DUNE TESTS
- DONE LD HL,DUNMSG
- CALL TYPMSG
- LD HL,ERCTR
- LD A,(ERCTR+1)
- ADD A,(HL)
- OR A
- JR Z,MEMOK ;ERROR COUNTER WAS ZERO
- LD HL,BADMSG
- D1: CALL TYPMSG
- LD HL,(ERCTR)
- CALL TYPSHL
- LD HL,ERSMSG
- CALL TYPMSG ;TYPE TOTAL NO OF ERRORS
- LD A,(CONTMD) ;SEE IF WANT TO TEST FOREVER
- OR A
- JP Z,BIGLP ;YES, GO ANOTHER ROUND OF INTERATIONS
- JP START ;GO BACK AND ASK FOR MORE
- MEMOK: LD HL,OKMSG
- JR D1 ;TYPE GOOD MESSAGE
- ERROR POP HL
- CALL ERR
- JP MLP
- ; TYPES TEST NAME, CLEARS AREA, SETS FIRST 1K CHUNK ADDRESS
- SETUP: CALL TYPMSG ;TYPE TEST NAME
- CALL CLAREA ;ZERO THE TEST AREA
- LD HL,(FIRST) ;STARTING ADDRESS
- LD (NEX1K),HL ;PRESET
- RET
- ;CONTROLS TEST AREA IN 1K CHUNKS AT A TIME TO KEEP
- ;RUNNING TIME REASONABLE SINCE IT GOES UP AS THE SQUARE
- ;OF THE NUMBER OF BYTES TESTED. RETURNS NEGATIVE FLAG
- ;WHEN TOTAL AREA FINISHED.
- COMCOD: LD HL,(NEX1K) ;GET START OF 1K CHUNK TO TEST
- LD DE,03FFH
- ADD HL,DE ;COMPUTE LAST ADR OF 1K CHUNK
- LD (END1K),HL ;SAVE IT
- EX DE,HL ;END1K TO DE
- LD HL,(LAST)
- AND A ;CLEAR CARRY
- SBC HL,DE ;SEE IF THROUGH TOTAL AREA YET
- RET ;RETURN C IF DONE
- CLAREA LD A,0 ;CLEARS THE TEST AREA TO ZEROES
- CALL STR
- RET
- SETCNT LD A,(ITER) ;GET ITERATIONS DESIRED
- LD (CTR),A ;STORE IN CTR
- RET
- ;
- CKCNT LD HL,CTR ;POINT AT CTR
- DEC (HL) ;DECREMENT THE COUNT
- RET ;WITH THE FLAGS SET
- ;STORE A PATTERN ROUTINE
- STR LD DE,(FIRST) ;GET BEGINNING
- LD HL,(LAST)
- CALL SADEHL
- RET
- ;READ AND TEST PATTERN
- RD LD HL,(FIRST)
- LD BC,(NBYTES)
- RD1 CPI ;SEE IF SAME AS A
- CALL NZ,ERR
- JP PE,RD1
- RET
- ;TYPE OUT ERROR
- ;HL HAS ADDRESS OF FAILURE
- ;A HAS GOOD BYTE
- ERR PUSH HL ;SAVE WHERE WE'RE AT
- PUSH AF ;SAVE A AND FLAGS
- DEC HL ;GET ACTUAL ADR WHERE FAILED
- PUSH HL
- CALL CRLF
- LD HL,(ERCTR) ;# SO FAR
- INC HL ;ADD THIS ONE
- LD (ERCTR),HL ;STORE IT BACK
- CALL TYPSHL ;TYPE # OF ERRORS SO FAR
- POP HL ;GET ADDRESS OF FAILURE
- CALL TYPSHL
- CALL SPACE
- LD A,(HL) ;GET BAD BYTE
- CALL P2HEX
- LD HL,SHDBE
- CALL TYPMSG ;TYPE SHOULD BE
- POP AF ;GET A BACK
- PUSH AF
- CALL P2HEX ;TYPE GOOD BYTE
- CALL NTERUP ;SEE IF WANT TO STOP A WHILE
- POP AF
- POP HL
- RET
- ;STORE INCREMENTING PATTERN
- STRROT LD A,0
- LD HL,(FIRST)
- LD BC,(NBYTES)
- ROT1 INC A
- JR Z,ROT1 ;NEVER USE ZERO
- LD (HL),A ;STORE BYTE
- CPI ;CK IT ALREADY
- CALL NZ,ERR ;WOOPS
- JP PE,ROT1
- RET
- ;CHECK INCREMENTING PATTERNS
- RDROT LD A,0
- LD HL,(FIRST)
- LD BC,(NBYTES)
- RDROT1 INC A ;NEXT PATTERN
- JR Z,RDROT1 ;NEVER ALLOWED ZERO
- CPI
- CALL NZ,ERR
- JP PE,RDROT1
- RET
- ;UPDATE POINTER TO NEXT 1K CHUNK OF MEMORY TO TEST
- ;
- UPDATE: LD HL,(END1K) ;UPDATE FOR NEXT 1K CHUNK
- INC HL
- LD (NEX1K),HL
- RET
- ;
- ;ROUTINE TO TYPE ADDRESS EVERY 100H (FROM DE)
- TYPEAD: LD A,E
- CP 0 ;SEE IF A MULTIPLE OF 100H
- RET NZ ;NO, DON'T BOTHER TO TYPE ADDRESS YET
- CALL NTERUP ;SEE IF WANT TO WAIT A BIT
- LD H,D ;GET NEXT ADDRESS IN HL
- LD L,E
- CALL TYPSHL
- LD A,(TYCTR) ;GET NUMBER OF TIMES THIS LINE
- INC A
- LD (TYCTR),A ;UPDATE IT
- AND 0FH ;ONLY USE LOWER 4 BITS
- RET NZ ;LESS THAN 16 TIMES
- CALL CRLF ;16 X 5 = 80 AND THAT'S ENUF PER LINE
- RET
- ;
- ;ROUTINE TO SEE IF ANYTHING BEEN TYPED FROM KEYBOARD.
- ;RETURNS IMMEDIATELY IF NOT. IF C/R, RESTART PROGRAM
- ;FROM SQUARE ONE. IF ?, TYPE LOCATION CURRENTLY TESTING,
- ;IF ANYTHING ELSE, JUST DELAY TIL
- ;ANOTHER KEY STRUCK.
- NTERUP: CALL CHKIN ;SEE IF ANYTHING BEEN TYPED?
- RET Z ;NO
- AND 7FH ;GET RID OF PARITY BIT IF ANY
- CP '?' ;SEE IF WANT TO FIND OUT WHERE
- JP Z,WHRWE
- CP 0DH ;SEE IF C/R
- JP Z,START ;START ALLL OVER
- LD HL,INTMSG ;TYPE "INTERRUPTED"
- CALL TYPMSG
- NTW CALL CHKIN ;WAIT FOR ANOTHER CHARACTER
- RET NZ ;GOT ONE
- JR NTW ;UNTIL WE GET ANY CHARACTER TO RESTART
- WHRWE: LD HL,WHRMSG
- CALL TYPMSG
- LD HL,(TESTAD) ;GET ADDRESS CURRENTLY TESTING
- CALL TYPSHL
- RET
-
- ;TYPES MESSAGE POINTED BY HL, GETS A CHARACTER FROM KBD,
- ; AND RETURNS WITH A REG =0 IF CHAR WAS A Y, ELSE A=FF
- ; Z FLAG WILL BE SET IF YES, NZ SET IF NOT YES
-
- GETANS: CALL TYPMSG ;TYPE MESSAGE
- CALL GCHR ;GET ANSWER FROM KBD
- PUSH AF ;SAVE IT
- CALL CRLF ;FOR NEATNESS
- POP AF
- CP 'Y' ;DID OP TYPE A Y
- JR Z,GOTYES
- CP 'y' ;CK FOR LOWER CASE TOO
- GOTYES: LD A,0
- RET Z ;ANSWER WAS Y
- LD A,0FFH
- RET ;ANSWER WAS NOT Y
-
- ;
- ; GET CHARACTER FROM INPUT.
- ;
- GBYTE: CALL CHKIN
- JR Z,GBYTE ;NOT READY YET
- AND 7FH ;STRIP OFF BIT 7?????
- RET
- ;
- SPACE: LD A,20H ;FALLS THRU TO PCHR
- ;
- ;PRINTS CHARACTER IN A, PLUS LINEFEED AND 2 NULLS IF
- ;CHAR IS A CARRIAGE RETURN. PRESERVES ALL REGISTERS
- ;
- PCHR: PUSH AF
- PUSH HL
- AND 7FH
- CALL PBYTE ;PRINT THE CHAR
- LD HL,LFNN
- CP CR ;WAS IT A C/R?
- CALL Z,TYPMSG ;PRINT LINE FEED AND 2 NULLS
- POP HL
- POP AF
- RET
- ;
- LFNN: DEFB 8AH
- ;
- ; GET CHARACTER. RETURNS IT IN A.
- ; ALTERS F.
- ;
- GCHR: CALL GBYTE
- CALL PCHR
- JR Z,GCHR ;IF NULL DON'T RETURN
- CP 61H ;SEE IF LOWER CASE
- JR C,SK2 ;LESS THAN LC A
- CP 7BH ;SEE IF MORE THAN Z
- JR NC,SK2 ;NOT A LOWER CASE
- SUB 20H ;CONVERT TO UPPER CASE
- SK2 RET
- ;
- ;
- ; CRLF. ALTERS A ONLY.
- ;
- CRLF: LD A,CR
- JR PCHR
- ;
- ;
- ; GETS A 4 DIGIT (OR LESS) HEX NUMBER FROM
- ; KEYBOARD INTO HL. IGNORES LEADING SPACES
- ; CONTINUES UNTIL A NON-HEX CHARACTER IS TYPED.
- ; RETURNS WITH THE LATTER IN A, AND HL SET TO
- ; THE LAST 4 HEX DIGITS (OR LESS) TYPED.
- ; LOSES AF AND HL
- ;
- ;
- GETHEX: SUB A
- ;
- GNHL: PUSH BC ;SAVE
- LD HL,0 ;CLR BUFFER
- ; STRIP LEADING SPACES & GET CHAR
- CALL SKSG
- ; FIRST CHAR MUST BE HEX
- CALL HEXSH ;IF HEX, SHIFT INTO HL
- JP C,HEXERR ;O/W, HEXERR
- GN1: CALL GCHR
- CALL HEXSH ;IF HEX SHIFT INTO HL
- LD A,B ;RESTORE CHAR
- JR NC,GN1 ;IF HEX, CONTINUE
- POP BC ;IF NON-HEX, DONE
- RET
- HEXERR LD A,'?'
- CALL PBYTE
- CALL CRLF
- JR GETHEX ;RESTART
- ;
- ;
- ; IF A CONTAINS HEX CHAR, SHIFTS BINARY EQUIVALENT
- ; INTO HL. IF NOT HEX, RET WITH CY SET. SAVES
- ; ORIGINAL CHAR IN B
- ;
- HEXSH: LD B,A
- SUB '0' ; < '0'?
- RET C
- ADD A,'0'-'G'
- RET C
- SUB 'A'-'G'
- JR NC,HX1 ;OK IF >= 'A'
- ADD A,07H; 'A'-'9'+1
- RET C
- HX1: ADD A,'9'+1-'0'
- ; THE A-REG NOW CONTAINS THE HEX DIGIT IN BINARY.
- ; (THE HIGH-ORDER NIBBLE OF A IS 0.)
- HXSH4: ADD HL,HL ;SHIFT 4 BITS INTO HL
- ADD HL,HL
- ADD HL,HL
- ADD HL,HL
- OR L
- LD L,A
- RET
- ;
- ;
- ; RETURNS WITH A NON-SPACE IN THE A-REG.
- ; IF ENTERED WITH A-REG CONTAINING A NULL
- ; OR A SPACE, GETS NEW CHARS UNTIL FIRST
- ; NON-SPACE OCCURS. ALTERS AF.
- ;
- SKSG0: SUB A
- ;
- SKSG: OR A ;DOES A CONTAIN NULL?
- SK1: CALL Z,GCHR ;YES
- CP 20H ;SPACE?
- JR Z,SK1 ;YES, KEEP LOOKING
- CP ',' ;PASS BY COMMAS TOO
- JR Z,SK1
- CP CR ;RETURNS ZFLAG IF CR
- RET
- ;
- ;
- ; PRINT THE NUMBER IN HL.
- ; PRESERVES ALL BUT A.
- ;
- TYPSHL: CALL SPACE
- ;
- PNHL: LD A,H
- CALL P2HEX
- LD A,L
- ; ;(CONTINUE BELOW)
- ;
- ; PRINT THE NUMBER IN THE A-REGISTER.
- ; PRESERVES ALL REGISTERS.
- ;
- P2HEX: CALL P1HEX
- RRA
- P1HEX: RRA
- RRA
- RRA
- RRA
- PUSH AF
- AND 0FH ;MASK
- CP 10D ; <= 9?
- JR C,PH1
- ADD A,7 ;A THRU F
- PH1: ADD A,30H ;ASCII BIAS
- CALL PCHR ;PRINT IT
- POP AF
- RET
- ;
- ;
- ; PRINT MESSAGE. ENTER WITH ADDR OF MSG
- ; IN HL. THE MESSAGE IS TERMINATED
- ; AFTER PRINTING A NULL (00) CHARACTER OR ONE WHOSE
- ; BIT 7 WAS SET.
- ; PRESERVES FLAGS, INCREMENTS HL.
- ;
- ;
- ;
- TYPMSG: PUSH AF ;SAVE
- PS1: LD A,(HL)
- INC HL
- CALL PCHR
- OR A ;SET FLAGS
- JR Z,PS2 ;NULL CHARACTER, EXIT
- RLA ;LAST CHARACTER?
- JR NC,PS1 ;IF NOT, LOOP
- PS2: POP AF
- RET
- ;
- DUNMSG DEFB LF
- DEFB CR
- DEFB ' FINISHED'
- DEFB CR
- DEFB TLF
- ERSMSG: DEFB ' TOTAL ERRORS'
- DEFB CR
- DEFB TLF
- SHDBE DEFB ' SHOULD BE'
- DEFB TSP
- ENTMSG DEFB LF
- DEFB CR
- DEFB '"FIRST LAST" ? ?'
- DEFB TSP
- ZMSG DEFB 'TESTING ZEROES, THEN ONES'
- DEFB LF
- DEFB TCR
- INCMSG DEFB 'INCREMENTING BYTE TEST'
- DEFB LF
- DEFB TCR
- IBUSMS: DEFB LF
- DEFB CR
- DEFB 'IBUS TEST'
- DEFB CR
- DEFB TLF
- NOPMSG: DEFB 'FAILED NOP TEST'
- DEFB TSP
- EXMSG: DEFB 'FAILED INST TEST'
- DEFB TSP
- GRDMSG DEFB LF
- DEFB CR
- DEFB 'CROSSTALK READ TEST'
- DEFB LF
- DEFB TCR
- GWRMSG DEFB LF
- DEFB CR
- DEFB 'CROSSTALK WRITE TEST'
- DEFB LF
- DEFB TCR
- ITMSG DEFB 'ITERATIONS? (1 TO FF)'
- DEFB TSP
- HITHERE:DEFB CR
- DEFB LF
- DEFB 'BRAINWASH 2.3 - Copyright 1979 by Jim Gilbreath'
- DEFB CR
- DEFB LF
- DEFM 'OUTPUT TO PRINTER?',CR,LF
- NOTMSG: DEFB 'DONT TEST 38-3A OR FRO'
- DEFB 0CDH
- INTMSG: DEFB LF
- DEFB CR
- DEFB 'INTERRUPTED'
- DEFB CR
- DEFB TLF
- LOSTMSG DEFB ' FLEW AWA'
- DEFB 0D9H
- CBIT: DEFB 'CARRY GOT SE'
- DEFB 0D4H
- ACHNG: DEFB 'A CHANGE'
- DEFB 0C4H
- BCHNG: DEFB 'B CHANGE'
- DEFB 0C4H
- CCHNG: DEFB 'C CHANGE'
- DEFB 0C4H
- DCHNG: DEFB 'D CHANGE'
- DEFB 0C4H
- ECHNG: DEFB 'E CHANGE'
- DEFB 0C4H
- HCHNG: DEFB 'H CHANGE'
- DEFB 0C4H
- LCHNG: DEFB 'L CHANGE'
- DEFB 0C4H
- EXSP: DEFM 'EX (SP),HL failed'
- TOMSG: DEFB ' T'
- DEFB 0CFH
- LNGMSG: DEFB 'LONG INST TEST? (Y/N)'
- DEFB TSP
- XTKMSG: DEFB 'DO CROSSTALK TESTS? (Y/N)'
- DEFB TSP
- CONMSG: DEFB 'TEST FOREVER? (Y/N)'
- DEFB TSP
- BADMSG DEFB 'POOR MEMORY!'
- DEFB 0ACH ;COMMA
- OKMSG DEFB 'GOOD MEMORY'
- DEFB 0ACH ;COMMA
- SPIMSG: DEFB ' '
- DEFB 0C9H ;I+80H
- WHRMSG: DEFM CR,LF,'Testing'
- STAKBAK DEFS 64 ;STACK BETTER NOT GET ANY LOWER THAN THIS
- STACK: DEFB 0
-
-
- ; I/O PACKAGE
-
-
- IF GIL ;home configuration
- STAT EQU 1 ;STATUS PORT
- DATA EQU 0
- DAV EQU 2
- TBE EQU 1
- PRSTAT EQU 3
- PRDAT EQU 2
- PRTBE EQU 1
-
- INITX: ;DO HOUSEKEEPING
- DI ;TURN OFF INTERRUPTS
- LD A,1 ;TO DISABLE ROM SO ALL RAM CAN BE TESTED
- OUT (1FH),A ;FOR GILBREATH CPU
- OUT (7FH),A ;FOR SSM ROM BOARD
- RET
- ENDIF ;gil
-
- IF ZOBEX ;nosc system
- stat equ 1 ;crt status port
- data equ 0 ;crt data port
- dav equ 1 ;bit mask for kbd input active
- tbe equ 4 ;bit mask for tx buffer empty
- prstat equ 3 ;printer status port
- prdat equ 2 ;printer data port
- prdav equ 1 ;printer input mask
- prtbe equ 4 ;printer tx buffer empty bit mask
-
- initx: ;do housekeeping
- ld a,1 ;to disable rom so all ram can be tested
- out (0ch),a ;for zobex cpu board
- ret
- ENDIF ;zobex
-
- ; CHECK INPUT & RETURN WITH DATA IF READY. ONLY REG CHANGE IS A.
- ;
- CHKINX: IN A,(STAT)
- AND DAV
- RET Z ;DATA NOT READY, RETURN WITH Z FLAG SET
- IN A,(DATA) ;RETURN WITH DATA AND Z FLAG CLEARED
- RET
- ;
-
- ; TYPE CHARACTER. CHANGE NO REGISTERS.
- ;
- CRTOX: PUSH AF
- PBY1: IN A,(STAT)
- AND TBE
- JR Z,PBY1
- POP AF
- OUT (DATA),A
- RET
-
-
- PRTOX: ;PRINT CHARACTER, CHANGE NO REGISTERS
-
- IF ZOBEX
-
- push af ;save char
- in a,(prstat) ;get printer port status
- and prdav ;see if got char
- jr z,list1 ;no
- in a,(prdat)
- and 7fh
- cp 'S'-40h ;see if stop code
- jr nz,list1
- plist2: in a,(prstat) ;got a stop, wait til next one
- and prdav
- jr z,plist2 ;loop til get char
- in a,(prdat)
- and 7fh
- cp 'Q'-40h ;see if go code
- jr nz,plist2 ;loop til get it right
- list1: in a,(prstat)
- and prtbe ;ck busy bit
- jr z,list1 ;loop til bit goes hi meaning ready
- pop af ;get char to print
- out (prdat),a ;send character
- ret
- ENDIF ;zobex
-
- IF GIL
- ret ;no printer in here as yet
- ENDIF; gil
-
-
- ENDOFIT:DEFB 0 ;FIRST MEMORY AVAILABLE TO TEST
-
- SIZE EQU ENDOFIT-START ;NUMBER OF TOTAL BYTE IN PROGRAM
-
- END