;************************************************************ ;* * ;* SINGLE DRIUE FILECOPY V80.1 11 FEB 80 * ;* WILL COPY FILES UP TO (11 K BYTES + BIAS) IN LENGTH * ;* ALL CONSOLE AND DISC I/O IS THROUGH BDOS CALL AT LOC 5 * ;* * ;************************************************************ ;* CP/M BDOS ADDRESSES 0000 = RBOOT EQU 0 ; RE-BOOT CP/M 0005 = BDOS EQU 5 ; BDOS CALL ENTRY 005C = FCB EQU 5CH ; DEFAULT FILE CONTROL BLOCK 0080 = INBUF EQU 80H ; DEFAULT DMA ADDRESS ;* CP/M BDOS FUNCTIONS 0001 = READF EQU 1 ; READ CONSOLE INTO (A) 0002 = TYPEF EQU 2 ; WRITE CONSOLE FROM (E) 000D = INIT EQU 13 ; INITIALIZE DISC IN DRIUE A: 000F = OPEN EQU 15 ; OPEN FILE 0010 = CLOS EQU 16 ; CLOSE FILE 0011 = FIND EQU 17 ; FIND FILE IN DIRECTORY 0013 = DELE EQU 19 ; DELETE FILE 0014 = READ EQU 20 ; READ FILE 0015 = WRIT EQU 21 ; WRITE FILE 0016 = MAKE EQU 22 ; CREATE FILE OIRECTORY ENTRY 0100 ORG 0100H ; TPA PROGRAM START ADDRESS 0100 C33402 JMP START ; GO TO PROGRAM START ;*CONSOLE I/O THROUGH BOOS CALL 0103 E5 CI PUSH H ; SAVE REGISTERS 0104 D5 PUSH D 0105 C5 PUSH B 0106 0E01 MVI C,READF ; READ FUNCTION 0108 CD0500 CALL BDOS ; RETURN CHAR IN (A) 010B C1 POP B ; RESTORE OTHER REGISTERS 010C D1 POP D 010D E1 POP H 010E C9 RET 010F E5 CO PUSH H 0110 D5 PUSH D 0111 C5 PUSH B 0112 5F MOV E,A ; MOVE PRINT CHAR TO (E) 0113 0E02 MVI C,TYPEF 0115 CD0500 CALL BDOS 0118 C1 POP B 0119 D1 POP D 011A E1 POP H 011B C9 RET 011C 3E0D CCRLF MVI A,0DH ; CR LF TO CONSOLE 011E CD0F01 CALL CO 0121 3E0A MVI A,0AH 0123 C30F01 JMP CO 0126 E1 MSGXP POP H ; OUTPUT MESSAGE AND RETURN 0127 7E MSGX1 MOV A,M ; THROUGH INDEX (H,L) 0128 FE00 CPI 0 ; TEXT TERMINATOR = 0 012A CA3401 JZ MSGEX 012D CD0F01 CALL CO 0130 23 INX H 0131 C32701 JMP MSGX1 0134 23 MSGEX INX H ; POINT TO TEXT + 1 0135 E9 PCHL ; AND RETURN THERE ;* FILECOPY CONSOLE MESSAGE SUBROUTINES 0136 CD1C01 RDMSG CALL CCRLF ; PROMPT FOR READ DISC 0139 CD2601 CALL MSGXP 013C 5245414420 DB 'READ DISC IN DRIVE. THEN CR ' 0158 00 DB 0 0159 CD0301 RDMS1 CALL CI ; GET RESPONSE 015C FE58 CPI 'X' ; ALLOW EXIT 015E CA0000 JZ RBOOT ; BACK TO CP/M 0161 FE0D CPI 0DH ; ACCEPT CR ONLY 0163 C25901 JNZ RDMS1 0166 CD1C01 CALL CCRLF ; ACKNOWLEDGE 0169 C9 RET ; AND RETURN 016A CD1C01 WRMSG CALL CCRLF ; PROMPT FOR WRITE DISC 016D CD2601 CALL MSGXP 0170 5752495445 DB 'WRITE DISC IN DRIVE. THEN CR ' 018D 00 DB 0 018E CD0301 WRMS1 CALL CI 0191 FE58 CPI 'X' 0193 CA0000 JZ RBOOT 0196 FE0D CPI 0DH 0198 C28E01 JNZ WRMS1 019B CD1C01 CALL CCRLF 019E C9 RET 019F CD1C01 RDERR CALL CCRLF ; SHOW READ ERROR 01A2 CD2601 CALL MSGXP 01A5 5245414420 DB 'READ ERROR! ENTER X TO ABORT ' 01C3 0D0A DB 0DH,0AH 01C5 2020202020 DB ' CR TO IGNORE ' 01E5 00 DB 0 01E6 CD0301 RDER1 CALL CI ; ACCEPT CR OR X 01E9 FE58 CPI 'X' 01EB CA1202 JZ EXIT 01EE FE0D CPI 0DH 01F0 C8 RZ ; RETURN MEANS IGNORE 01F1 C3E601 JMP RDER1 ; READ ERROR 01F4 CD1C01 WRERR CALL CCRLF ; SHOW WRITE ERROR 01F7 CD2601 CALL MSGXP 01FA 5045524D41 DB 'PERMANENT WRITE ERROR! ' 0211 00 DB 0 0212 CD2601 EXIT CALL MSGXP 0215 4241434B20 DB 'BACK TO CP/M? ' 0223 00 DB 0 0224 CD0301 WRER1 CALL CI ; WAIT FOR CR OR X 0227 FE0D CPI 0DH 0229 CA0000 JZ RBOOT 022C FE58 CPI 'X' 022E CA0000 JZ RBOOT 0231 C22402 JNZ WRER1 ; AS ONLY LEGAL RESPONSE ;* BEGIN FILECOPY PROGRAM 0234 CD1C01 START CALL CCRLF ; SIGN ON MESSAGE 0237 CD2601 CALL MSGXP 023A 53494E474C DB 'SINGLE DRIVE FILECOPY V80.1 11 FEB 80' 0261 0D0A DB 0DH,0AH 0263 00 DB 0 0264 CD3601 CALL RDMSG ; PROMT FOR READ DISC 0267 115C00 LXI D,FCB ; LOOK FOR FILE 026A 0E11 MVI C,FIND ; BEFORE GOING AHEAD 026C CD0500 CALL BDOS 026F FEFF CPI 255 ; DOES FILE EXIST? 0271 C29302 JNZ RUN ; YES. READ IT 0274 CD1C01 CALL CCRLF ; NO. GIVE UP 0277 CD2601 CALL MSGXP 027A 46494C4520 DB 'FILE DOES NOT EXIST! ' 028F 00 DB 0 0290 C31202 JMP EXIT ; REBOOT CP/M 0293 215C00 RUN LXI H,FCB ; SET UP FCB'S FOR 0296 114504 LXI D,RFCB ; READ AND WRITE 0299 0E10 MVI C,16 029B 7E RUN1 MOV A,M 029C 12 STAX D 029D 23 INX H 029E 13 INX D 029F 0D DCR C 02A0 C29B02 JNZ RUN1 02A3 215C00 LXI H,FCB 02A6 116604 LXI D,WFCB 02A9 0E10 MVI C,16 02AB 7E RUN2 MOV A,M 02AC 12 STAX D 02AD 23 INX H 02AE 13 INX D 02AF 0D DCR C 02B0 C2AB02 JNZ RUN2 02B3 218704 LXI H,BUFFR ; INITIALIZE POINTER 02B6 224204 SHLD HSAVE ; INTO BUFFER 02B9 AF XRA A ; ZERO RECORD COUNTS 02BA 324404 STA ASAVE 02BD 326504 STA RFCBN 02C0 328604 STA WFCBN ;* READ THE FILE INTO RAM 02C3 114504 RFILE LXI D,RFCB ; USE READ FCB 02C6 0E0F MVI C,OPEN ; AND OPEN THE FILE 02C8 CD0500 CALL BDOS 02CB FEFF CPI 255 ; ERROR? 02CD C2EF02 JNZ RFIL1 02D0 CD1C01 CALL CCRLF 02D3 CD2601 CALL MSGXP ; YES. SHOW IT 02D6 554E41424C DB 'UNABLE TO OPEN FILE! ' 02EB 00 DB 0 02EC C31202 JMP EXIT ; AND ABORT 02EF 114504 RFIL1 LXI D,RFCB ; READ A RECORD 02F2 0E14 MVI C,READ 02F4 CD0500 CALL BDOS 02F7 FE00 CPI 0 ; GOOD READ? 02F9 CA0403 JZ RFIL2 ; YES. STORE IT 02FC FE01 CPI 1 ; OR END OF FILE? 02FE CA4103 JZ WFILE ; YES. WRITE IT 0301 CD9F01 CALL RDERR ; NO. SHOW ERROR 0304 2A4204 RFIL2 LHLD HSAVE ; STORE THE RECORD 0307 118000 LXI D,INBUF 030A 0E80 MVI C,80H 030C 1A RFIL3 LDAX D 030D 77 MOV M,A 030E 23 INX H 030F 13 INX D 0310 0D DCR C 0311 C20C03 JNZ RFIL3 0314 224204 SHLD HSAVE ; AND NEXT ADDRESS 0317 3A4404 LDA ASAVE ; COUNT THE RECORO 031A 3C INR A 031B 324404 STA ASAVE 031E 3A0700 LDA 7 ; ANY MEMORY LEFT? 0321 3D DCR A 0322 BC CMP H 0323 C2EF02 JNZ RFIL1 ; YES. KEEP READING 0326 CD1C01 CALL CCRLF ; NO. ABORT 0329 CD2601 CALL MSGXP 032C 46494C4520 DB 'FILE IS TOO BIG! ' 033D 00 DB 0 033E C31202 JMP EXIT ;* WRITE THE FILE ONTO DISC 0341 CD6A01 WFILE CALL WRMSG ; PROMPT FOR WRITE DISC 0344 0E0D MVI C,INIT ; INITIALIZE DISC FOR WRITE 0346 CD0500 CALL BDOS 0349 116604 LXI D,WFCB ; SEE IF FILE EXITS 034C 0E11 MVI C,FIND 034E CD0500 CALL BDOS ; WE CAN'T WRITE TWO! 0351 FEFF CPI 255 0353 CAC703 JZ WFIL1 ; NO. CONTINUE 0356 CD1C01 CALL CCRLF 0359 CD2601 CALL MSGXP ; YES. ERASE OR ABORT? 035C 46494C4520 DB 'FILE ALREADY EXISTS. ENTER: X TO ABORT' 0383 0D0A DB 0DH,0AH 0385 2020202020 DB ' CR TO ERASE IT ' 03B1 00 DB 0 03B2 CD0301 WAIT1 CALL CI 03B5 FE58 CPI 'X' 03B7 CA0000 JZ RBOOT 03BA FE0D CPI 0DH 03BC C2B203 JNZ WAIT1 03BF 116604 LXI D,WFCB ; ERASE THE OLD FILE 03C2 0E13 MVI C,DELE 03C4 CD0500 CALL BDOS 03C7 116604 WFIL1 LXI D,WFCB ; OPEN FILE FOR WRITE 03CA 0E16 MVI C,MAKE 03CC CD0500 CALL BDOS 03CF FEFF CPI 255 ; OPEN OK? 03D1 C2F603 JNZ WFIL2 ; YES. CONTINUE 03D4 CD1C01 CALL CCRLF 03D7 CD2601 CALL MSGXP ; SHOW UNABLE TO OPEN 03DA 4F5554204F DB 'OUT OF DIRECTORY SPACE !' 03F2 00 DB 0 03F3 C31202 JMP EXIT 03F6 218704 WFIL2 LXI H,BUFFR ; INITIALIZE POINTER 03F9 224204 SHLD HSAVE 03FC 2A4204 WFIL3 LHLD HSAVE ; MOVE RECORD TO OUTPUT 03FF 118000 LXI D,INBUF ; BUFFER (SAME AS INPUT) 0402 0E80 MVI C,80H 0404 7E WFIL4 MOV A,M 0405 12 STAX D 0406 23 INX H 0407 13 INX D 0408 0D DCR C 0409 C20404 JNZ WFIL4 040C 224204 SHLD HSAVE ; SAVE NEXT ADDRESS 040F 116604 LXI D,WFCB ; WRITE THE RECORD 0412 0E15 MVI C,WRIT 0414 CD0500 CALL BDOS 0417 FE00 CPI 0 0419 C4F401 CNZ WRERR ; SHOW WRITE ERROR 041C 3A4404 LDA ASAVE ; COUNT RECORD WRITTEN 041F 3D DCR A 0420 324404 STA ASAVE 0423 C2FC03 JNZ WFIL3 ; AND WRITE ANOTHER 0426 116604 LXI D,WFCB ; DONE. CLOSE THE FILE 0429 0E10 MVI C,CLOS 042B CD0500 CALL BDOS 042E CD1C01 CALL CCRLF 0431 CD2601 CALL MSGXP ; PROMPT FOR RE-BOOT 0434 414C4C2044 DB 'ALL DONE! ' 043E 00 DB 0 043F C31202 JMP EXIT ; AND WE ARE ALL DONE! ;* RAM BUFFERS 0442 HSAVE DS 2 ; BUFFER ADDRESS STORE 0444 ASAVE DS 1 ; RECORD COUNT 0445 RFCB DS 33 ; READ FILE CONTROL BLOCK 0466 WFCB DS 33 ; WRITE FILE CONTROL BLOCK 0487 00 BUFFR DB 0 ; DATA BUFFER START 0465 = RFCBN EQU RFCB+32 ; RECORD COUNTS. READ 0486 = WFCBN EQU WFCB+32 ; AND WRITE 0488 END