* REGEN.ASM VERS 1.1 SEPTEMBER 30, 1980 * * BY BRYAN G. MOORE * DESIGN TECHNOLOGY * 4888-H RONSON COURT * SAN DIEGO, CA 92111 * * MODIFIED FOR ALL REVISION DISK JOCKEY 2D'S BY BOBBY DALE GIFFORD * 9/30/80 * * THE PROGRAM IS USED TO CORRECT THE FORMAT ON SINGLE DENSITY * IBM 3740 COMPATIBLE DISKETTES. ATTEMPTS TO USE OTHER DISKETTES * WILL PROBABLY RESULT IN AN ERROR MESSAGE. * * LAST MODIFIED 25 SEP 84 GLH:W6BSK * COMMENTS ADDED TO DAMNED NEAR EVERYTHING. * * 000B = VERNUM EQU 11 ;VERSION NUMBER * 10 E000 = ORIGIN EQU 0E000H ;DISK JOCKEY 2D PROM 0005 = BDOS EQU 5 ;CP/M ENTRY POINT 0000 = WBOOT EQU 0 ;WARM BOOT E3F8 = DISKIO EQU ORIGIN+3F8H ;DISC JOCKEY CONTROL BLOCK ADDRESS E3F9 = DRVSEL EQU DISKIO+1 ;DJ DRIVE SELECT REGISTER E3FA = DJSERP EQU DISKIO+2 ;DJ SERIAL I/O STATUS PORT - NUSED E3FB = CSTALL EQU DISKIO+3 ;DJ STALL ROUTINE ENTRY E3FC = CMDREG EQU DISKIO+4 ;DJ COMMAND REGISTER E3FD = TRKREG EQU DISKIO+5 ;DJ TRACK REGISTER E3FE = SECREG EQU DISKIO+6 ;DJ SECTOR REGISTER E3FF = DATREG EQU DISKIO+7 ;DJ DATA REGISTER 0008 = DSIDE EQU 10Q ;DOUBLE SIDED MASK 0059 = SICMD EQU 131Q ;STEP IN COMMAND 00D0 = IMMIRQ EQU 320Q ;IMMEDIATE INTERRUPT COMMAND 0018 = UNLOADA EQU 30Q ;UNLOAD MASK FOR MODEL A DJ 000F = UNLOADB EQU 17Q ;UNLOAD MASK FOR MODEL B DJ 0009 = RESTOR EQU 11Q ;SEEK TRACK 0 COMMAND 00E4 = RTCMD EQU 0E4H ;READ TRACK COMMAND 00F4 = WTCMD EQU 0F4H ;WRITE TRACK COMMAND 00A0 = WSEC EQU 0A0H ;WRITE SECTOR COMMAND 0080 = RSEC EQU 80H ;READ SECTOR COMMAND 0010 = INDEX EQU 20Q ;INDEX HOLE MASK 0004 = TRKZRO EQU 4 ;TRACK 0 MASK 090D = LHSDENB EQU 90DH ;DJ MODEL B SD LOAD HEAD MASK 080C = LHDDENB EQU 80CH ;DJ MODEL B DD LOAD HEAD MASK 0111 = LHSDENA EQU 111H ;DJ MODEL A SD LOAD HEAD MASK 0010 = LHDDENA EQU 10H ;DJ MODEL A DD LOAD HEAD MASK 000D = ACR EQU 0DH ;CR/LF MASKS, NATURALLY 000A = ALF EQU 0AH 0100 ORG 100H ;CP/M TPA START 0100 313A07 LXI SP,STACK ;STACK POINTER 0103 112B04 LXI D,SRCMSG ;PROMPT THE USER TO SELECT DRIVE 0106 CD6C03 CALL READDRV ;GET A DRIVE DESIGNATOR 0109 32D506 STA SDISK ;SAVE SOURCE DISK 010C 116004 LXI D,DSTMSG ;PROMPT THE USER TO SELECT DRIVE 010F CD6C03 CALL READDRV ;GET DRIVE DESIGNATOR 0112 32D606 STA DDISK ;SAVE DESTINATION DISK MOUNT 0115 119904 LXI D,MNTMSG ;PROMPT THE USER TO 0118 CD9603 CALL PRBUFF ;READ CONSOLE 011B C20001 JNZ START ;IGNORE ANYTHING ELSE REGENA 011E 11D206 LXI D,ACRALF ;DO A CR/LF 0121 CD8203 CALL PBUFF 0124 AF XRA A ;SELECT SOURCE 0125 CD3803 CALL SELECT ;SELECT THE DRIVE 0128 21FCE3 LXI H,CMDREG ;GET THE COMMAND ;LREGISTER 012B 36D0 MVI M,IMMIRQ ;AND LOAD AN IMMEDIATE INTERRUP COMMAND 012D 3E40 MVI A,40H ;SIMPLE DELAY DELAY01 012F 3D DCR A 0130 C22F01 JNZ DELAY01 0133 7E MOV A,M ;CHECK READY 0134 1F RAR 0135 DA6001 JC NOTRDY 0138 17 RAL 0139 17 RAL 013A DA6001 JC NOTRDY 013D 110000 LXI D,0 0140 CD5D03 CALL GTINDX ;GET POLARITY OF INDEX PULSE 0143 CDCF03 CALL GTSTAT ;TEST FOR DOUBLE SIDED 0146 E608 ANI DSIDE 0148 C25101 JNZ INDEX01 ;CONTINUE IF SINGLE SIDED; DBLSIDE 014B 115005 LXI D,SGLSIDE ;DOUBLE SIDED NOT ALLOWED. 014E C36301 JMP NOTRDYX INDEX01 0151 CDCF03 CALL GTSTAT ;WAIT FOR INDEX PULSES 0154 E610 ANI INDEX 0156 A8 XRA B 0157 C28A01 JNZ RESTORA 015A 1B DCX D 015B 7A MOV A,D 015C B7 ORA A 015D C25101 JNZ INDEX01 NOTRDY 0160 113805 LXI D,RMESSG ;" IS NOT READY." NOTRDYX 0163 EB XCHG 0164 114705 LXI D,AMESSG ;CR/LF,"DRIVE " 0167 E5 PUSH H 0168 CD8203 CALL PBUFF ;PRINT DRIVE MESSAGE 016B 3AD706 LDA CDISK 016E A7 ANA A 016F 3AD506 LDA SDISK 0172 CA7801 JZ NOTDRV 0175 3AD606 LDA DDISK ;GET THE DESTINATION DRIVE NOTDRV 0178 C641 ADI 'A' ;AND CONVERT TO ASCII 017A 5F MOV E,A 017B 0E02 MVI C,2 017D CD0500 CALL BDOS ;DISPLAY IT 0180 D1 POP D 0181 CD8203 CALL PBUFF ;COMPLETE THE MESSAGE 0184 CDD303 CALL UNLOAD ;UNLOAD THE HEADS 0187 C31501 JMP MOUNT ;AND LOOP BACK. RESTORA 018A CDC601 CALL RESTORE ;SET TO TRACK 0 OF BOTH DRIVES REGENB 018D 3E01 MVI A,1 ;SELECT DESTINATION 018F CD3803 CALL SELECT ;SELECT THE DRIVE 0192 21FCE3 LXI H,CMDREG 0195 36D0 MVI M,IMMIRQ ;IMMEDIATE INTERUPT REQUEST 0197 3E40 MVI A,40H ;DO A SHORT DELAY TO GIVE TIME FOR DELAY02 0199 3D DCR A ;REQUEST TO BE GRANTED. 019A C29901 JNZ DELAY02 019D 7E MOV A,M ;CHECK READY 019E 1F RAR 019F DA6001 JC NOTRDY ;BUSY OR OTHERWISE DONE IN 01A2 17 RAL 01A3 17 RAL 01A4 DA6001 JC NOTRDY 01A7 112305 LXI D,WMESSG ;" IS WRITE PROTECTED." 01AA 17 RAL ;TEST FOR WRITE PROTECTED- 01AB DA6301 JC NOTRDYX ;IS, SAY SO. 01AE 110000 LXI D,0 ;TAINT, GO AHAID. 01B1 CD5D03 CALL GTINDX ;GET POLARITY OF INDEX PULSE INDEX02 01B4 CDCF03 CALL GTSTAT ;WAIT FOR INDEX PULSES 01B7 E610 ANI INDEX 01B9 A8 XRA B 01BA C2DC01 JNZ REGEN ;READY, JUMP OUT. 01BD 1B DCX D ;NOT FOUND YET, LOOK SOME MORE 01BE 7A MOV A,D 01BF B7 ORA A ;TRY,TRY AGAIN, UNTIL 01C0 C2B401 JNZ INDEX02 01C3 C36001 JMP NOTRDY ;ALL HOPE IS LOST. RESTORE 01C6 21FCE3 LXI H,CMDREG ;POINT TO COMMAND REGISTER 01C9 3609 MVI M,RESTOR ;AND DO A SEEK TRACK 0 COMMAND DELAY03 01CB 7E MOV A,M 01CC 1F RAR ;WAIT FOR BUSY 01CD D2CB01 JNC DELAY03 DELAY04 01D0 7E MOV A,M 01D1 1F RAR ;WAIT FOR NOT BUSY 01D2 DAD001 JC DELAY04 01D5 7E MOV A,M ;GET STATUS BYTE 01D6 E604 ANI TRKZRO ;MASK FOR TRACK 00 01D8 CA6001 JZ NOTRDY ;ERROR IF NOT AT TRACK 00 01DB C9 RET REGEN 01DC CDC601 CALL RESTORE ;SEEK TRACK 0 AND SET THE TRACK COUNTER 01DF AF XRA A ;TO 0 INITIALLY. THIS COUNTER WILL 01E0 32DA06 STA TKNO ;KEEP TRACK OF THE CURRENT TRACK. 01E3 3E0A MVI A,10 ;RESET READ RETRY 01E5 32D806 STA TRCNT ; COUNTER TO 10 DLOOP 01E8 AF XRA A ;SET FOR DRIVE A 01E9 CD3803 CALL SELECT ;EACH READ. 01EC CDC102 CALL WNBUSY ;WAIT UNTIL NOT BUSY 01EF 11FFE3 LXI D,DATREG ;POINTER ACTS AS DATA REGISTER 01F2 210008 LXI H,TKBUF ;TRACK BUFFER 01F5 011800 LXI B,24 ; SET PAGE COUNT 01F8 3EE4 MVI A,RTCMD ;SET IN READ TRACK COMMAND 01FA 32FCE3 STA CMDREG ;AND EXECUTE IT. DATIN 01FD 1A LDAX D ;LOAD A DATA BYTE 01FE 77 MOV M,A ;STORE IN MEMORY 01FF 2C INR L ;BUMP POINTER / COUNTER 0200 C2FD01 JNZ DATIN ;GET NEXT BYTE 0203 24 INR H ;BUMP HIGH ORDER 0204 0D DCR C ;HIT PAGE COUNT 0205 C2FD01 JNZ DATIN ;LOOP TIL TRACK READ IN * TWLOOP 0208 3AD606 LDA DDISK ;GET THE DESTINATION DISK 020B CD3803 CALL SELECT ;AND MAKE IT CURRENT. 020E CDCA02 CALL WINDEX 0211 0000000000 DB 00,00,00,00,00,00 0217 011800 LXI B,24 ;WAIT FOR CONTROLLER READY 021A 11FFE3 LXI D,DATREG ;POINT TO 1791 DATA REGISTER 021D 210008 LXI H,TKBUF 0220 3EF4 MVI A,WTCMD ;DO THE TRACK WRITE OPERATION 0222 32FCE3 STA CMDREG ; NUMBER OF PAGES 0225 EB XCHG ;START OF TRACK BUFFER WLOOP 0226 1A LDAX D ;GET SOURCE BYTE FROM MEMORY 0227 77 MOV M,A ;WRITE THE DATA TO THE CONTROLLER 0228 1C INR E ; GET NEXT BYTE 0229 C22602 JNZ WLOOP ; AND DUMP IT. 022C 14 INR D ; UPDATE PAGE COUNT 022D 0D DCR C ; AND TEST IF DONE. 022E C22602 JNZ WLOOP 0231 21DA06 LXI H,TKNO ;POINT TO TRACK NUMBER 0234 34 INR M ;BUMP IT 0235 7E MOV A,M ;GET NEXT TRACK NUMBER 0236 FE4D CPI 77 ;IS RE-FORMATTING COMPLETE ? 0238 DA5302 JC TKSTEP ;NO - DO NEXT TRACK 023B CDD303 CALL UNLOAD FINISH 023E 11E104 LXI D,FMESSG ;SEND COMPLETION DONE 0241 CD9603 CALL PRBUFF ; MESSAGE TO CONSOLE 0244 FE52 CPI 'R' ;MORE RE-FORMATTING ? 0246 CA0001 JZ START ;YES - JUMP EXIT 0249 AF XRA A 024A CDC601 CALL RESTORE ;DRIVE THE HEAD TO TRACK 0. UNLOAD 024D CDD303 CALL UNLOAD ;THE HEADS AND RETURN TO CP/M VIA 0250 C30000 JMP WBOOT ;A WARM BOOT. ALOHA! * * STEP TO NEXT TRACK * TKSTEP 0253 3AD506 LDA SDISK ;GET THE SOURCE DISK AND SAVE IT 0256 47 MOV B,A ;IN B. GET DESITINATION DISK AND SEE 0257 3AD606 LDA DDISK ;IF THEY ARE THE SAME. IF SO, DO THE 025A B8 CMP B ;SAMEDRV ROUTINE. 025B CA6D02 JZ SAMEDRV 025E 3E2A MVI A,'*' ;WRITE AN ASTERISK TO THE CONSOLE 0260 CD8703 CALL PCHAR ;FOR EACH TRACK PROCESSED. 0263 CD7702 CALL TAKSTEP ;STEP IN TO NEXT TRACK AND BACK UP ONE 0266 3AFDE3 LDA TRKREG ;TRACK TO COMPENSATE FOR NEXT SERIES OF 0269 3D DCR A ;OPERATIONS. 026A 32FDE3 STA TRKREG SAMEDRV 026D AF XRA A ;DEFAULT TO DRIVE A 026E CD3803 CALL SELECT ;AND TEST FOR CURRENT DRIVE- 0271 CD7702 CALL TAKSTEP ;STEP IN ONE TRACK IN PREPARATION 0274 C3E801 JMP DLOOP ;FOR NEXT TRACK MANIPULATION, AND GO. TAKSTEP 0277 11FCE3 LXI D,CMDREG ;POINT TO THE COMMAND REGISTER AND 027A 3E59 MVI A,SICMD ;PERFORM A STEP-IN COMMAND. 027C 12 STAX D DELAY05 027D 1A LDAX D 027E 1F RAR 027F D27D02 JNC DELAY05 DELAY06 0282 1A LDAX D 0283 1F RAR 0284 DA8202 JC DELAY06 0287 C9 RET * * RE-WRITE ERROR, TRACK DID NOT VERIFY * BUMP COUNTER, THEN FLAG PERMANENT ERROR * 0288 21D906 RWERR LXI H,RWCNT ;POINT TO TRACK VERIFY RETRY COUNTER 028B 35 DCR M ;DECREMENT IT 028C 116B06 LXI D,VMSG ;CR/LF'DISKETTE WILL NOT ACCEPT ETC' * * PERMANENT ERROR COMMON ROUTINE * NO ERROR CODES DETERMINED YET * UNLOAD HEAD, THEN ABORT * PERR 028F CD8203 CALL PBUFF ;PRINT THE ERROR MESSAGE 0292 CDD303 CALL UNLOAD ;UNLOAD THE HEADS 0295 3AFDE3 LDA TRKREG ;GET CURRENT TRACK NUMBER 0298 2E2F MVI L,'0'-1 ;PRESET THE L REGISTER PER1 029A 2C INR L ;THIS ROUTINE CONVERTS A BINARY BYTE 029B D60A SUI 10 ;TO ITS ASCII EQUIVALENT. IT DOES IT BY 029D D29A02 JNC PER1 ;BUMPING THE L REGISTER THE 10'S DIGIT 02A0 C63A ADI '0'+10 ;NUMBER OF TIMES AND CONVERTING THE REMAINDER 02A2 67 MOV H,A ;FROM BINARY TO ASCII IN THE H REGISTER. THE 02A3 7D MOV A,L ;TWO-DIGIT ASCII RESULT IS STORED IN MEMORY FOR 02A4 FE30 CPI '0' ;FURTHER USE. 02A6 C2AB02 JNZ PER2 02A9 2E20 MVI L,' ' ;SUPPRESS LEADING ZERO... PER2 02AB 223906 SHLD TDSPLY ;SAVE TRACK NUMBER DISPLAY 02AE 111F06 LXI D,RETMSG ;PROMPT TO PRESS RETURN 02B1 C34102 JMP DONE ;TREAT AS IF DONE * * TRACK READ ERROR - DECREMENT COUNTER AND TRY AGAIN * TERR 02B4 21D806 LXI H,TRCNT ;GET THE NUMBER OF TIMES TO TRY, TRYI AGAIN 02B7 35 DCR M ;AND UPDATE IT. LOOP UNTIL ALL HOPE IS GONE. 02B8 C2E801 JNZ DLOOP 02BB 11C705 LXI D,TMESSG ;'TRACK READ ERROR ETC' 02BE C38F02 JMP PERR ;CONTINUE ERROR ROUTINE * * WAIT UNTIL DRIVE NOT BUSY * WNBUSY 02C1 3AFCE3 LDA CMDREG ;GET THE CONTROLLER STATUS BYTE AND TEST IT 02C4 E601 ANI 1 ;FOR BUSY... IF IT IS INDEED STILL DOING ITS 02C6 C2C102 JNZ WNBUSY ;THING, LOOP UNTIL IT FINISHES. 02C9 C9 RET ;NO LONGER BUSY, HERE WE GO! * * WAIT FOR INDEX HOLE TO GO BY * WINDEX 02CA C5 PUSH B 02CB CD5D03 CALL GTINDX ;GET PROPER POLARITY MASK FOR MODEL ID. WINDXH 02CE CDCF03 CALL GTSTAT ;LOAD DJ DISK STATUS BYTE 02D1 E610 ANI INDEX ;AND MASK FOR INDEX PULSE. 02D3 A8 XRA B ;USE PROPER POLARITY 02D4 CACE02 JZ WINDXH ;AND LOOP UNTIL INDEX COMES UP. WINDXL 02D7 CDCF03 CALL GTSTAT ;INDEX PULSE PRESENT (HIGH), PLAY GAMES UNTIL 02DA E610 ANI INDEX ;IT GOES AWAY (LOW). 02DC A8 XRA B 02DD C2D702 JNZ WINDXL 02E0 CDCF03 WINDXC CALL GTSTAT 02E3 E610 ANI INDEX 02E5 A8 XRA B 02E6 CAE002 JZ WINDXC 02E9 C1 POP B 02EA C9 RET * * SEARCH UP TO (B) BYTES AT HL FOR PATTERN REPRESENTED * BY (C). ASSUMES UPPER 4 BITS ARE 1S. EXIT TO TERR IF * BYTE NOT FOUND. * SEARC 02EB 7E MOV A,M ;LOAD A BYTE 02EC F6F0 ORI 0F0H ;TURN ON UPPER NIBBLE 02EE 77 MOV M,A ;SAVE IN MEMORY 02EF B9 CMP C ;MATCH ? 02F0 C8 RZ ;YES - RETURN 02F1 23 INX H ;BUMP DATA POINTER 02F2 05 DCR B ;HIT BYTE SEARCH COUNT 02F3 C2EB02 JNZ SEARC ;LOOP TIL SEARCH COMPLETE 02F6 F1 POP PSW ;CLEAR STACK 02F7 C3B402 JMP TERR ;GO TO ERROR ROUTINE * * CHECKSUM CHECKER * ADAPTED FROM THE DISK JOCKEY I SHUGART FIRMWARE * PERFORMS THE CYCLIC REDUNDANCY CHECK (CRC) * THE POLYNOMIAL IS G(X) = X^16 + X^12 + X^5 + 1. * * ENTRY SETCRC - POINTER TO DATA BLOCK IN HL, * FIELD LENGTH (IN BYTES) - 1 IN D,E * VERIFY CHECKSUM AT END OF BLOCK * RETURN WITH Z SET IF MATCH * *I HAVEN'T THE FAINTEST IDEA (YET) HOW THIS WORKS. BUT I WILL FIND OUT. SETCRC 02FA E5 PUSH H ;SAVE START ADDRESS POINTER 02FB EB XCHG ;FLIP START ADDR TO DE 02FC 19 DAD D ;HL POINTS TO LAST BYTE 02FD EB XCHG ;SWAP BACK AGAIN CRECH 02FE 01FFFF LXI B,-1 ;INITIAL VALUE PER FORMULA CRECHX 0301 D5 PUSH D ;SAVE TERMINATING POINTER 0302 7E MOV A,M 0303 A9 XRA C 0304 57 MOV D,A 0305 0F RRC 0306 0F RRC 0307 0F RRC 0308 0F RRC 0309 E60F ANI 0FH 030B AA XRA D 030C 5F MOV E,A 030D 0F RRC 030E 0F RRC 030F 0F RRC 0310 57 MOV D,A 0311 E61F ANI 1FH 0313 A8 XRA B 0314 4F MOV C,A 0315 7A MOV A,D 0316 E6E0 ANI 0E0H 0318 AB XRA E 0319 47 MOV B,A ;UPDATE HIGH ORDER CRC WORD 031A 7A MOV A,D 031B 0F RRC 031C E6F0 ANI 0F0H 031E A9 XRA C 031F 4F MOV C,A ;SAVE LOW ORDER CRC WORD 0320 23 INX H ;BUMP POINTER TO NEXT DATA BYTE 0321 D1 POP D ;RESTORE TERMINATING POINTER 0322 7A MOV A,D ;GET HIGH ORDER 0323 BC CMP H ;TEST FOR DONE CRECH 0324 DA2F03 JC CREC1 ;DONE - TEST CRC AND SET FLAGS 0327 C20103 JNZ CRECHX ;CONTINUE - NEXT DATA BYTE 032A 7B MOV A,E ;GET LOW ORDER AND 032B BD CMP L ; TEST TERMINATING POINTER 032C D20103 JNC CRECHX ;LOOP IF MORE BYTES TO SCAN CREC1 032F EB XCHG ;SWAP CRC WORD POINTER TO D,E 0330 E1 POP H ;RESTORE DATA START ADDRESS POINTER 0331 1A LDAX D ;TEST LOW ORDER 0332 B9 CMP C ;CLEAR Z FLAG IF NO MATCH 0333 13 INX D ;NEXT BYTE 0334 C0 RNZ ;DONE IF ERROR 0335 1A LDAX D ;HIGH ORDER 0336 B8 CMP B ;SET FLAGS AND 0337 C9 RET ;RETURN * * SELECT SELECTS THE DISK SPECIFIED BY DRIVE A AND * LOADS THE HEAD * SELECT 0338 47 MOV B,A ;SAVE IN B 0339 3AD706 LDA CDISK ;GET CURRENTLY SELECTED DISK 033C B8 CMP B 033D CA5103 JZ LOADHD ;LOAD APPROPRIATE HEAD. 0340 78 MOV A,B ;RECOVER REQUEST 0341 32D706 STA CDISK ;UPDATE SELECTED DRIVE 0344 4F MOV C,A 0345 3E7F MVI A,7FH ;DRIVE SELECT BITS QLOOP 0347 07 RLC ;ROTATE SELECT BITS 0348 0D DCR C ; TO PROPER DRIVE POSITION 0349 F24703 JP QLOOP 034C E63F ANI 3FH 034E 32F9E3 STA DISKIO+1 LOADHD 0351 010D09 LXI B,LHSDENB 0354 78 MOV A,B ;DUMP CONTENTS OF THE BC REGISTERS INTO THE 0355 32FAE3 STA DISKIO+2 0358 79 MOV A,C ;DENSITY, AND ALL THOSE GOOD THINGS. 0359 32FAE3 STA DISKIO+2 035C C9 RET * * GET INDEX LEVEL * GTINDX 035D CD6603 CALL MODEL ;ESTABLISH POLARITY MASK FOR USE IN OTHER 0360 0600 MVI B,0 ;ROUTINES, TO ALLOW FOR PROPER DJ MODEL. 0362 C8 RZ 0363 0610 MVI B,INDEX 0365 C9 RET * * GET DISK JOCKEY 2D MODEL * MODEL 0366 3AF4E3 LDA DISKIO-4 ;GET THE DJ MODEL ID: 0369 FEC9 CPI (RET) ;00 = MODEL A 036B C9 RET ;C9 = MODEL B * * PROMPT THE CONSOLE FOR A DRIVE, THEN READ AND VERIFY THE DRIVE * SELECTED * READDRV 036C D5 PUSH D ;SAVE PROMPT 036D CD8203 CALL PBUFF ;SEND THE PROMPT 0370 CD9903 CALL RBUFF ;READ THE CONSOLE CHARACTER 0373 D1 POP D ;RECOVER PROMPT 0374 CA4902 JZ EXIT 0377 D641 SUI 'A' ;SUBTRACT ASCII BIAS 0379 DA6C03 JC READDRV ;INVALID INPUT 037C FE04 CPI 4 ;UPPER LIMIT 037E F26C03 JP READDRV ;INVALID INPUT 0381 C9 RET * * PBUFF IS THE CP/M PRINT BUFFER FUNCTION * PBUFF 0382 0E09 MVI C,9 ;STANDARD BDOS CALL ROUTINE. 0384 C30500 JMP BDOS PCHAR 0387 E5 PUSH H ;AND SO IS THIS ONE. 0388 C5 PUSH B 0389 D5 PUSH D 038A F5 PUSH PSW 038B 5F MOV E,A 038C 0E02 MVI C,2 038E CD0500 CALL BDOS 0391 F1 POP PSW 0392 D1 POP D 0393 C1 POP B 0394 E1 POP H 0395 C9 RET * * RBUFF IS THE CP/M READ BUFFER FUNCTION * PRBUFF 0396 CD8203 CALL PBUFF RBUFF 0399 11B203 LXI D,INBUFF 039C 0E0A MVI C,10 ;STANDARD READ-THE-BUFFER AND/OR INPUT 039E CD0500 CALL BDOS ;ROUTINE. 03A1 3AB303 LDA INBUFF+1 03A4 A7 ANA A 03A5 C8 RZ 03A6 3AB403 LDA INBUFF+2 03A9 FE61 CPI 'a' 03AB D8 RC 03AC FE7B CPI 'z'+1 03AE D0 RNC 03AF D620 SUI ' ' 03B1 C9 RET 03B2 0A0A INBUFF DB 10,10 03B4 DS 10 CONIN 03BE 0E01 MVI C,1 ;STANDARD INPUT ROUTINE WITH CONTROL-C 03C0 CD0500 CALL BDOS ;INTERCEPT. 03C3 E67F ANI 7FH 03C5 FE03 CPI 3 03C7 CA3E02 JZ FINISH 03CA C9 RET STBITS 03CB 32FAE3 STA DISKIO+2 ;SET THE STANDARD THINGS. 03CE C9 RET GTSTAT 03CF 3AFAE3 LDA DISKIO+2 ;READ THE 1791 STATUS BYTE. 03D2 C9 RET UNLOAD 03D3 CD6603 CALL MODEL ;JUST WHAT IT SAYS. 03D6 3E18 MVI A,UNLOADA 03D8 CACB03 JZ STBITS 03DB 3E0F MVI A,UNLOADB 03DD C3CB03 JMP STBITS * * MESSAGES AND DATA * 03E0 0D0A PROMPT DB ACR,ALF 03E2 466F726D61 DB 'Format correction program, VERS ' 0402 312E31 DB (VERNUM/10)+'0','.',(VERNUM MOD 10)+'0' 0405 0D0A627920 DB ACR,ALF,'by Design Technology, San Diego, CA$' 042B 0D0A SRCMSG DB ACR,ALF 042D 53656C6563 DB 'Select source drive A,B,C, or D (RETURN to exit): $' 0460 0D0A DSTMSG DB ACR,ALF 0462 53656C6563 DB 'Select destination drive A,B,C or D (RETURN to exit): $' 0499 0D0A MNTMSG DB ACR,ALF 049B 5072657373 DB 'Press RETURN to correct the format' 04BD 0D0A6F6E20 DB ACR,ALF,'on the above specified diskette: $' 04E1 0D0A FMESSG DB ACR,ALF 04E3 46756E6374 DB 'Function Complete' 04F4 0D0A DB ACR,ALF 04F6 5479706520 DB 'Type R to reformat another, RETURN to exit: $' 0523 2069732057WMESSG DB ' is Write Protected.$' 0538 206973204ERMESSG DB ' is Not Ready.$' 0547 0D0A AMESSG DB ACR,ALF 0549 4472697665 DB 'Drive $' 0550 206973206ESGLSIDE DB ' is not single sided.$' 0566 0D0A MNTSRC DB ACR,ALF 0568 496E736572 DB 'Insert source diskette, then press RETURN: $' 0594 0D0A MNTDST DB ACR,ALF 0596 496E736572 DB 'Insert destination diskette, then press RETURN: $' 05C7 0D0A TMESSG DB ACR,ALF 05C9 547261636B DB 'Track read error' 05D9 0D0A DB ACR,ALF 05DB 496E76616C DB 'Invalid CRC, Illegal Density, or' 05FB 0D0A DB ACR,ALF 05FD 496C6C6567 DB 'Illegal track or sector sequence.$' 061F 0D0A RETMSG DB ACR,ALF 0621 4572726F72 DB 'Error occured on Track: ' 0639 20202E TDSPLY DB ' .' 063C 0D0A DB ACR,ALF 063E 5479706520 DB 'Type R to reformat another, RETURN to exit: $' 066B 0D0A VMSG DB ACR,ALF 066D 4469736B65 DB 'Diskette will not accept re-formatting.' 0694 0D0A DB ACR,ALF 0696 5065726D61 DB 'Permanent Verification Error and' 06B6 0D0A DB ACR,ALF 06B8 70726F6261 DB 'probable physical damage.$' 06D2 0D0A24 ACRALF DB ACR,ALF,'$' * * DATA SPACE * 06D5 FF SDISK DB 0FFH 06D6 FF DDISK DB 0FFH 06D7 FF CDISK DB 0FFH 06D8 TRCNT DS 1 ;TRACK READ RETRY COUNTER 06D9 RWCNT DS 1 ;RE-WRITE COUNTER 06DA TKNO DS 1 ;TRACK NUMBER 06DB SECNO DS 1 ;SECTOR NUMBER 06DC SECIX DS 2 ;SECTOR DATA POINTER TABLE POINTER 06DE SECTB DS 2*26 ;SPACE FOR SECTOR ADDRESS TABLE 0712 DS 40 073A = STACK EQU $ 0800 ORG (($+255)SHR 8)SHL 8 ;MUST START ON PAGE 0800 TKBUF DS 1800H ;LOTS OF SPACE FOR TRACK BUFFER 1FFF = NBUF EQU $-1 ;LAST BYTE IN TRACK BUFFER STORAGE AREA 2000 END