00010 ;Z80 00020 ;KAYPRO MEMORY TEST ROUTINE 00030 ;THIS ROUTINE RELOCATES THE MEMORY TEST PROGRAM TO 00040 ;HIGH MEMORY AND INITIALIZES THE KAYPRO FOR THE TEST 00050 ; 00060 ;WRITTEN BY LARRY KRAEMER 09/15/83 00070 ; 00080 ;FIRST MOVE THE PROGRAM TO HIGH MEMORY AND THEN START 00090 ;THE TEST. SELECT THE VIDEO PAGE, TURN OFF THE DRIVES, 00100 ;TURN OFF THE DRIVE LED'S, AND THEN CLEAR THE SCREEN. 00110 ;THE TEST WILL RUN UNTIL POWER IS TURNED OFF OR THE 00120 ;SYSTEM IS REBOOTED. 00130 ;WRITTEN ON A RADIO SHACK MODEL 1. 00140 INIT EQU 4E00H ;INIT ROUTINE HERE 00150 TEST EQU 500DH 00160 DEST EQU 5000H 00170 MSG1 EQU 4E60H 00180 MSG2 EQU 4E7DH 00190 MSG3 EQU 4E95H 00200 DELAY EQU 4ECDH 00210 DELAY0 EQU 4ED0H 00220 DELAY1 EQU 4ED3H 00230 AON EQU 4EB1H 00240 AOFF EQU 4EB8H 00250 BON EQU 4EBFH 00260 BOFF EQU 4EC6H 00270 ORG 0100H ;ORGIN IS 0100H 00280 START LD HL,RAM ;POINT TO SOURCE 00290 LD DE,INIT ;POINT TO DESTINATION 00300 LD BC,ERAM-RAM ;NUMBER OF BYTES 00310 LDIR ;BLOCK MOVE IT HIGH 00320 LD HL,RAM1 ;POINT TO SOURCE 00330 LD DE,DEST ;POINT TO DESTINATION 00340 LD BC,ERAM1-RAM1 ;NUMBER OF BYTES 00350 LDIR ;MOVE IT HIGH 00360 JP INIT ;JUMP HIGH AND INIT 00370 RAM IN A,(01CH) ;READ SYSTEM STATUS PORT 00380 SET 7,A ;TURN ON VIDEO PAGE 00390 SET 6,A ;TURN OFF DRIVES 00400 RES 0,A ;TURN OFF DRIVE LIGHT A 00410 RES 1,A ;TURN OFF DRIVE LIGHT B 00420 OUT (01CH),A ;SEND TO PORT 1CH 00430 LD HL,3000H ;START OF VIDEO PAGE 00440 LD DE,3001H ;NEXT ADDR 00450 LD BC,0BFFH ;TOTAL VIDEO PAGE 00460 LD (HL),20H ;CLEAR SCREEN 00470 LDIR ;BLOCK MOVE 00480 LD HL,MSG1 ;POINT TO MESSAGE 1 00490 LD DE,3419H ;STORE ON SCREEN 00500 LD BC,1DH ;NUMBER OF BYTES 00510 LDIR ;MOVE IT 00520 LD HL,MSG2 ;POINT TO MESSAGE 2 00530 LD DE,351BH ;STORE ON SCREEN 00540 LD BC,18H ;NUMBER OF BYTES 00550 LDIR ;MOVE IT 00560 LD HL,MSG3 ;POINT TO MESSAGE 3 00570 LD DE,3619H ;STORE ON SCREEN 00580 LD BC,1CH ;NUMBER OF BYTES 00590 LDIR ;MOVE IT 00600 LOOP LD BC,08H ;8 TIMES THRU LOOP 00610 PUSH BC ;SAVE COUNT 00620 CALL DELAY ;DELAY SOME 00630 CALL AON ;TURN ON A LED 00640 CALL DELAY ;WAIT 00650 CALL AOFF ;TURN OFF A LED 00660 CALL DELAY ;WAIT 00670 CALL BON ;TURN ON B LED 00680 CALL DELAY ;WAIT 00690 CALL BOFF ;TURN OFF B LED 00700 POP BC ;RESTORE COUNT 00710 DEC BC ;SUBTRACT 1 00720 LD A,B ;CHECK FOR ZERO 00730 OR C ;OR DO AGAIN 00740 JP NZ,4E3DH ;DO AGAIN 00750 JP TEST ;START MEMORY TEST NOW 00760 MSG01 DEFB 4BH ;K 00770 DEFB 41H ;A 00780 DEFB 59H ;Y 00790 DEFB 50H ;P 00800 DEFB 52H ;R 00810 DEFB 4FH ;O 00820 DEFB 20H ;SPACE 00830 DEFB 49H ;I 00840 DEFB 49H ;I 00850 DEFB 20H ;SPACE 00860 DEFB 4DH ;M 00870 DEFB 45H ;E 00880 DEFB 4DH ;M 00890 DEFB 4FH ;O 00900 DEFB 52H ;R 00910 DEFB 59H ;Y 00920 DEFB 20H ;SPACE 00930 DEFB 54H ;T 00940 DEFB 45H ;E 00950 DEFB 53H ;S 00960 DEFB 54H ;T 00970 DEFB 20H ;SPACE 00980 DEFB 50H ;P 00990 DEFB 52H ;R 01000 DEFB 4FH ;O 01010 DEFB 47H ;G 01020 DEFB 52H ;R 01030 DEFB 41H ;A 01040 DEFB 4DH ;M 01050 MSG02 DEFB 54H ;T 01060 DEFB 65H ;E 01070 DEFB 73H ;S 01080 DEFB 74H ;T 01090 DEFB 69H ;I 01100 DEFB 6EH ;N 01110 DEFB 67H ;G 01120 DEFB 20H ;SP 01130 DEFB 34H ;4 01140 DEFB 30H ;0 01150 DEFB 30H ;0 01160 DEFB 30H ;0 01170 DEFB 68H ;H 01180 DEFB 20H ;SP 01190 DEFB 74H ;T 01200 DEFB 68H ;H 01210 DEFB 72H ;R 01220 DEFB 75H ;U 01230 DEFB 20H ;SP 01240 DEFB 46H ;F 01250 DEFB 46H ;F 01260 DEFB 46H ;F 01270 DEFB 46H ;F 01280 DEFB 68H ;H 01290 MSG03 DEFB 54H ;T 01300 DEFB 65H ;E 01310 DEFB 73H ;S 01320 DEFB 74H ;T 01330 DEFB 20H ;SP 01340 DEFB 62H ;B 01350 DEFB 61H ;A 01360 DEFB 64H ;D 01370 DEFB 20H ;SP 01380 DEFB 61H ;A 01390 DEFB 64H ;D 01400 DEFB 64H ;D 01410 DEFB 72H ;R 01420 DEFB 65H ;E 01430 DEFB 73H ;S 01440 DEFB 73H ;S 01450 DEFB 20H ;SP 01460 DEFB 77H ;W 01470 DEFB 69H ;I 01480 DEFB 74H ;T 01490 DEFB 68H ;H 01500 DEFB 20H ;SP 01510 DEFB 42H ;B 01520 DEFB 69H ;I 01530 DEFB 74H ;T 01540 DEFB 63H ;C 01550 DEFB 68H ;H 01560 DEFB 6BH ;K 01570 DAON IN A,(1CH) ;GET STATUS BYTE 01580 SET 0,A ;TURN ON LED 01590 OUT (1CH),A ;OUT TO PORT 01600 RET 01610 DAOFF IN A,(1CH) ;GET STATUS BYTE 01620 RES 0,A ;TURN OFF LED 01630 OUT (1CH),A ;OUT TO PORT 01640 RET 01650 DBON IN A,(1CH) ;GET STATUS BYTE 01660 SET 1,A ;TURN ON LED 01670 OUT (1CH),A ;OUT TO PORT 01680 RET 01690 DBOFF IN A,(1CH) ;GET STATUS BYTE 01700 RES 1,A ;TURN OFF LED 01710 OUT (1CH),A ;OUT TO PORT 01720 RET 01730 DELY LD BC,0002H ;TWO TIMES THRU 01740 DELY0 LD HL,00H ;TIMES FF 01750 DELY1 DEC HL ;SUBTRACT ONE 01760 LD A,H ;CHECK FOR ZERO 01770 OR L ;LOOP AGAIN IF NOT 0 01780 JP NZ,DELAY1 ;JUMP HERE 01790 DEC BC ;DEC BC BY ONE 01800 LD A,B ;CHECK FOR ZERO 01810 OR C ;HERE TO 01820 JP NZ,DELAY0 01830 RET 01840 ERAM DEFB 00H ;END MARKER 01850 NOP 01860 NOP 01870 NOP 01880 NOP 01890 NOP 01900 NOP 01910 NOP 01920 NOP 01930 NOP 01940 NOP 01950 NOP 01960 ;******************************************************** 01970 ;******************************************************** 01980 ;RAM CHECKING PROGRAM -- THIS PROGRAM WILL ROOT THRU ALL 01990 ;MEMORY AND FIND ANY ERRORS. THE BAD ADDRESSES ARE SHOWN 01991 ;IN THE UPPER LEFT OF THE SCREEN. 02000 ;MEMORY TESTED IS FROM 4000H THRU FFFFH. WHEN THE STAR 02001 ;IS DISPLAYED IN THE LOWER RIGHT OF THE SCREEN THE 02010 ;PROGRAM IS LOW AND TESTING FROM 6000H THRU FFFFH. WHEN 02011 ;THE STAR IS OFF THE PROGRAM IS HIGH AND TESTING MEMORY 02020 ;FROM 4000H THRU 7000H. 02030 ;THIS PROGRAM IS SELF RELOCATING - IT MUST START AT 5000H 02040 ;WHEN A BAD ADDRESS IS FOUND IT CAN BE TESTED BY LOADING 02050 ;BITCHECK. THE BAD CHIP WILL THEN BE DISPLAYED WITH AN X 02060 ;******************************************************** 02070 ;******************************************************** 02080 ;WRITTEN BY LARRY KRAEMER FOR THE KAYPRO II 09/14/83 02090 ;******************************************************** 02100 ;******************************************************** 02110 RAM1 DEFB 00H ;START MARKER 02120 NOP 02130 NOP 02140 NOP 02150 NOP 02160 NOP 02170 NOP 02180 NOP 02190 NOP 02200 NOP 02210 NOP 02220 NOP 02230 NOP 02240 ;SET UP A MIDDLE OF PROGRAM POINTER AND DISPLAY A STAR 02250 ;ON THE SCREEN WHICH WILL SHOW WHAT AREA OF MEMORY IS 02260 ;BEING TESTED. BEGINNING AREA OF MEMORY TO BE TESTED 02270 ;IS ALSO SPECIFIED. 02280 BTEST LD IX,5090H ;MIDDLE OF TEST PROGRAM 02290 LD A,(3BCFH) ;LAST SCREEN ADDR. 02300 XOR 0AH ;ALTERNATE SPACE/STAR 02310 LD (3BCFH),A ;DISPLAY ON SCREEN 02320 LD SP,IX ;START STACK POINTER 02330 LD B,7FH ;NUMBER OF MOVES 02340 INC SP ;FOR SP SP=SP+1 02350 DJNZ $-1 ;DO 127 TIMES 02360 LD HL,6001H ;FIRST TESTED MEMORY ADDR 02370 ;TEST BEGINS WITH VALUE OF ZERO THRU FF 02380 ;EACH VALUE IS WRITTEN TO A TRIO OF MEMORY LOCATIONS 02390 ;TO DETERMINE THEIR EFFECT ON EACH OTHER AS VALID 02400 ;ELECTRONIC STORAGE CELLS. 02410 ;THE ADDRESS IS SHOWN ON THE MONITOR IN GRAPHICS MODE. 02420 ;THE LSB(YTE) IS ON THE LEFT AND IS CHANGING FROM 00-256 02430 ;THE MSB(YTE) IS ON THE RIGHT AND IS THE PAGE OF THE 02440 ;ADDTESS BEING TESTED. 02450 ;EX. AB IS SHOWN ON SCREEN 02460 ;A IS BYTE 41 OF PAGE 42 -- ADDRESS BEING TESTED IS 4241H 02470 XOR A ;CLEAR ACCUM 02480 LD (HL),A ;PLACE VALUE IN MEMORY 02490 LD C,A ;PUT VALUE IN C 02500 PUSH AF ;SAVE VALUE 02510 LD A,C ;GET VALUE FROM C 02520 LD (HL),A ;PLACE VALUE IN MEMORY 02530 INC HL ;POINT TO NEXT TEST ADDR 02540 LD (3927H),HL ;DISPLAY TO SCREEN 02550 LD A,H ;GET MSB OF ADDR 02560 CP 00H ;IS IT AT TOP OF MEMORY 02570 ;TABLE FOR MEMORY ADDRESSES FOLLOW: 02580 ; 32K 48K 64K 02590 ; 80H C0H 00H 02600 ;CHANGE THE ABOVE COMPARE FOR THE AMOUNT OF MEMORY AVAIL. 02610 ; 02620 JR Z,$+32H ;IF = THEN RELOCATE 02630 PUSH HL ;SAVE MEMORY ADDR 02640 PUSH IX ;SAVE MIDDLE OF PROGRAM 02650 POP HL ;TO HL REGISTER 02660 CP H ;CHECK AGAINST TOP OF MEM 02670 JR Z,$+2BH ;RELOCATE IF DONE 02680 POP HL ;RESTORE ORIG VALUE 02690 POP AF ;RESTORE ORIG TEST ADDR 02700 LD (HL),A ;PUT VALUE IN MEM 02710 DEC HL ;BACK TO ORIGINAL ADDR 02720 DEC HL ;BACK TO PREVIOUS ADDR 02730 LD (HL),A ;PUT VALUE IN MEMORY 02740 LD B,A ;SAVE VALUE IN B REG 02750 LD A,(HL) ;GET VALUE AT LOC'N HL 02760 CP B ;CHECK AGAINST B 02770 JR Z,$+7 ;GO ON IF IT'S OKAY 02780 LD D,1BH ;GET VALUE OF RELO SUB 02790 PUSH DE ;SAVE IT ON STACK 02800 JR $+1DH ;JUMP SUBROUTINE 02810 INC HL ;GET ORIG TEST ADDR 02820 INC HL ;GO ONE BEYOND ADDR 02830 LD A,(HL) ;GET VALUE AT THAT POS'N 02840 CP B ;CHECK AGAINST B REG 02850 JR Z,$+7 ;GO ON IF IT'S OKAY 02860 LD D,10H ;GET JUMP FOR RELO SUB 02870 PUSH DE ;SAVE VALUE ON STACK 02880 JR $+12H ;JUMP SUBROUTINE 02890 DEC HL ;BACK TO ORIG POSITION 02900 INC (HL) ;INC VALUE IN MEMORY 02910 INC C ;INC TEST VALUE 02920 LD A,(HL) ;GET VALUE IN MEMORY 02930 LD B,A ;SAVE VALUE IN B REG 02940 CP 00 ;CHECK IF 256 BYTES DONE 02950 JR NZ,$-35H ;LOOP BACK AND CONTINUE 02960 INC HL ;GET NEXT MEMORY VALUE 02970 LD C,0 ;RESET TEST VALUE TO ZERO 02980 JR $-3AH ;LOOP BACK FOR NEXT TEST 02990 JR $+66H ;RELO SUB STEPPING STONE 03000 ; 03010 ;******************************************************** 03020 ;THIS SUBROUTINE IS ENTERED IF A BAD MEMORY LOCATION IS 03030 ;FOUND. IT CONVERTS HEX VALUES TO ASCII AND DISPLAYS 03040 ;THEM ON THE SCREEN. 03050 ;******************************************************** 03060 LD A,H ;GET VALUE FROM H REG 03070 AND 0F0H ;MASK OFF LOW BITS 03080 RRCA ;ROTATE RIGHT FOR 03090 RRCA ;CONVERSION 03100 RRCA ;4 TIMES 03110 RRCA ;UNTIL DONE 03120 LD D,22H ;GET VALUE FOR RELO SUB 03130 JR $+24H ;AND JUMP TO IT 03140 LD A,H ;GET VALUE FROM H REG 03150 AND 0FH ;MASK OUT HIGH BITS 03160 LD D,1BH ;GET VALUE FOR RELO SUB 03170 JR $+1DH ;AND JUMP TO IT 03180 LD A,L ;GET VALUE FROM L REG 03190 AND 0F0H ;MASK OFF LOW BITS 03200 RRCA ;ROTATE FOR CONVERSION 03210 RRCA ;DO FOR 4 TIMES 03220 RRCA ;AGAIN 03230 RRCA ;AND IT'S DONE 03240 LD D,10H ;GET VALUE FOR RELO SUB 03250 JR $+12H ;AND JUMP TO SUBROUTINE 03260 LD A,L ;GET VALUE FROM L REG 03270 AND 0FH ;MASK OUT HIGH BITS 03280 LD D,9 ;GET VALUE FOR RELO SUB 03290 JR $+0BH ;AND JUMP TO SUBROUTINE 03300 POP DE ;RESTORE VALUE TOP DE REG 03310 LD A,0D3H ;GET RETURN POS'N VALUE 03320 SUB D ;SUBTRACT RETURN DIFF. 03330 LD (IX+00H),A ;AND MAKE JR OPERAND 03340 JR $+1 ;IRRELEVANT OPERAND 03350 PUSH DE ;SAVE NEXT TWO REG PAIRS 03360 PUSH AF ;ON STACK 03370 LD DE,3000H ;GET TOP LEFT OF SCREEN 03380 LD A,(DE) ;GET VALUE ON SCREEN 03390 CP 20H ;IS IT A SPACE??? 03400 JR Z,$+5 ;IF SO GO AHEAD MORE 03410 INC DE ;INC SCREEN POSITION 03420 JR $-6 ;AND GO AHEAD PAST TEST 03430 LD A,E ;GET SCREEN VALUE 03440 CP 04 ;IS IT FOUR POSITIONS OVER 03450 JR NZ,$+0CH ;IF NOT GO ON AHEAD 03460 LD A,20H ;IF SO GET A SPACE READY 03470 DEC DE ;GO BACK SOME 03480 LD (DE),A ;AND FILL WITH SPACE 03490 DEC DE ;BACK MORE 03500 LD (DE),A ;AND INSERT A SPACE 03510 DEC DE ;BACK MORE 03520 LD (DE),A ;AND INSERT SPACE 03530 DEC DE ;BACK ANOTHER 03540 LD (DE),A ;AND INSERT SPACE 03550 POP AF ;RESTORE VALUE TO AF 03560 CP 0AH ;LESS THAN 10? 03570 JR NC,$+6 ;IF LESS THEN JUMP 03580 ADD A,30H ;CONVERT HEX TO ASCII 03590 JR $+4 ;AND GO PAST REST 03600 ADD A,37H ;CONVERT HEX TO ASCII NOW 03610 LD (DE),A ;AND STORE ON SCREEN 03620 ;******************************************************** 03630 ;THIS IS A DELAY ROUTINE USED AFTER LOCATION IS DISPLAYED 03640 ;******************************************************** 03650 PUSH BC ;SAVE VALUE IN BC REG 03660 LD B,0FFH ;DELAY VALUE IS FF HEX 03670 DJNZ $-0 ;DELAY A LITTLE NOW 03680 POP BC ;RESTORE BC 03690 POP DE ;RESTORE DE 03700 LD A,0C9H ;GET VALUE TO RETURN 03710 SUB D ;SUBTRACT JUMP OFFSET 03720 LD (IX+37H),A ;PLACE AS JR OPERAND 03730 JR $+1 ;IRRELEVANT OPERAND 03740 ;********************************************************* 03750 ;PROGRAM RELOCATION ROUTINE FOLLOWS: 03760 ;HL AND DE REGISTERS ARE LOADED FROM THE IX REGISTER, AND 03770 ;MODIFIED BY EXCLUSIVE-ORING WITH A KNOWN VALUE IN REG A 03780 ;THE NEW PROGRAM BEGINNING CAN BE DETERMINED, AND 03790 ;INTERNAL TEST POSITIONS CAN BE MODIFIED, AND THE IX 03800 ;AND SP POINTERS RESET 03810 ;********************************************************* 03820 PUSH IX ;SAVE POSITION 03830 PUSH IX ;SAVE POSITION 03840 POP HL ;TRANSFER TO HL 03850 POP DE ;TRANSFER TO DE 03860 LD A,D ;GET VALUE FROM D 03870 XOR 20H ;TRANSFER TO HIGH MEMORY 03880 LD D,A ;PUT BACK IN D 03890 PUSH DE ;AND STASH ON STACK 03900 PUSH DE ;SAVE IT AGAIN ON STACK 03910 LD B,90H ;DEC TO PROGRAM START 03920 DEC HL ;AND BEGIN DECREMENTING 03930 DEC DE ;FOR BOTH THE REGISTERS 03940 DJNZ $-2 ;UNTIL DONE 03950 LD BC,00FFH ;GET READY TO TRANSFER 03960 LDIR ;NOW 03970 ;THIS WAS ADDED/CHANGED SO I COULD RUN IT ON A MODEL 3 03980 ;NOW ADD FOR MOD III 03990 POP HL ;TRANSFER VALUE IN DE HERE 04000 POP IX ;TRANSFER VALUE IN DE HERE 04010 LD L,22H ;5022H OR 7022H ADDR 04020 LD A,20H ;MODIFY TO 40XX OR 60XX 04030 XOR (HL) ;ADDR TO START TEST AGAIN 04040 LD (HL),A ;STORE ADDR AT 5022/7022 04050 LD BC,0DH ;ADD OFFSET AND COMPARE 04060 ADD HL,BC ;WITH ADDR FOR TOP OF TEST 04070 LD A,070H ; 04080 ;TABLE FOR MEMORY ADDRESSES FOLLOW: 04090 ; 32K 48K 64K 04100 ; F0H B0H 70H 04110 XOR (HL) ; 04120 LD (HL),A ; 04130 LD L,11H ;7011H OR 5011H ADDR 04140 JP (HL) ;JUMP TO ABOVE ADDR 04150 ERAM1 DEFB 00H 04160 DEFB 00H 04170 END START