home *** CD-ROM | disk | FTP | other *** search
- ;SDCOPY.ASM
- ;V1.0
- ;*************************************************************
- ; THIS PROGRAM IS USED TO COPY A FILE FROM
- ; ONE DISKETTE TO ANOTHER ON A CP/M SYSTEM
- ; WHICH HAS ONLY ONE DISK DRIVE.
- ;
- ; IF FILE IS LARGER THAN AVAILABLE MEMORY IT IS
- ; COPIED IN MULTIPLE PASSES - EACH PASS READS
- ; AS MUCH AS WILL FIT IN MEMORY, WRITES IT OUT AFTER
- ; ASKING FOR DESTINATION DISK, THEN ASKS FOR SOURCE AGAIN.
- ;*************************************************************
- ;
- ;
- ; WARD'S BDOS/CBIOS EQUATES (VERSION 6)
- ;
- RDCON EQU 1
- WRCON EQU 2
- PRINT EQU 9
- RESETDK EQU 13
- SELDK EQU 14
- OPEN EQU 15
- CLOSE EQU 16
- SRCHF EQU 17
- SRCHN EQU 18
- ERASE EQU 19
- READ EQU 20
- WRITE EQU 21
- MAKE EQU 22
- RENAME EQU 23
- STDMA EQU 26
- BDOS EQU 5
- FCB EQU 5CH
- ;
- ;******************************************
- ;
- ORG 100H
- ;
- ;******************************************
- ; SAVE THE LOCAL STACK
- ;******************************************
- LXI H,0
- DAD SP
- SHLD STACK
- LXI SP,STACK
- ;******************************************
- ; CREATE DUPLICATE FCB FOR OUTPUT FILE
- ;******************************************
- LXI D,FCB
- LXI H,FCB2
- MVI B,33
- CALL MOVER
- ;
- CALL ILPRT
- DB 'SINGLE-DRIVE COPY 3/10/81',0DH,0AH,0
- CALL OPNSRC
- ;
- OPENOK: LXI D,BUFF ;POINT TO BUFFER
- READLP: PUSH D ;SAVE BUFFER ADDRESS
- ; SET THE DMA ADDR
- MVI C,STDMA
- CALL BDOS
- ;
- ;******************************************
- ; READ A SECTOR
- ;******************************************
- LXI D,FCB
- MVI C,READ
- CALL BDOS
- ;
- ORA A ;OK?
- JNZ EOF ;NOT OK, MUST BE EOF
- LHLD FCT ;LOAD SECTOR COUNT FOR FILE
- INX H ;BUMP BY 1
- SHLD FCT ;SAVE IT BACK
- POP D ;GET DMA ADDR
- LXI H,80H
- DAD D ;CALC NEXT BUFF ADDR
- XCHG ;PUT IT BACK IN DE
- ;******************************************
- ; OUT OF MEMORY?
- ;******************************************
- LDA 7 ;GET BDOS PAGE POINTER
- SUI 0AH ;SUBTRACT OFFSET TO BELOW CCP
- CMP D ;ABOUT TO HIT CCP?
- JZ FULL ;YES - WRITE WHAT WE HAVE
- JNC READLP ;NO, LOOP
- ;******************************************
- ;FILE IS TOO BIG - WRITE FIRST PART
- ;******************************************
- FULL: JMP DESTMSG
- ;******************************************
- ;GOT RETURN CODE ON READ, SEE IF ERROR OR EOF
- ;******************************************
- EOF: POP D ;POP BUFF ADDR OFF STACK
- DCR A ;EOF?
- JNZ RERROR ;NO, READ ERROR
- XRA A ;SET DONE FLAG
- STA DONEF ;SAVE FLAG FOR CHECKING LATER
- JMP DESTMSG ;GO TO OUTPUT ROUTINE
- ;******************************************
- ;FILE READ INTO MEMORY. ASK FOR DEST. DISK
- ;******************************************
- DESTMSG:CALL ILPRT
- DB 'MOUNT DESTINATION DISK, TYPE D: ',0
- ;
- ; GET CHARACTER FROM CONSOLE
- MVI C,RDCON
- CALL BDOS
- ;
- ANI 5FH ;MAKE IT UPPER CASE
- CPI 'D' ;IS IT A D?
- JZ RESET ;YES, RESET R/O STATUS
- CPI 03H ;IS IT CTL-C
- JZ DONE ;YES - REBOOT
- JMP DESTMSG ;NO - GO ASK AGAIN
- ;******************************************
- ; RESET DISK TO DISABLE R/O STATUS
- ;******************************************
- RESET: MVI C,RESETDK
- CALL BDOS
- ;
- CALL LOGIN
- ;
- OUTOPN: LDA OPNOUT ;HAS OUTPUT FILE BEEN CREATED?
- ORA A
- JNZ CREATE ;NO-CREATE IT
- ;******************************************
- ; OPEN THE OUTPUT FILE
- ;******************************************
- LXI D,FCB2 ;YES-JUST OPEN IT
- MVI C,OPEN
- CALL BDOS
- ;
- INR A ;WAS OPEN OK?
- JNZ WRTFIL ;YES-GO WRITE IT
- CALL ILPRT ;LOOKS LIKE THE WRONG DISKETTE
- DB 0DH,0AH,'** WRONG DISKETTE **',0DH,0AH,0
- JMP DESTMSG ;GO ASK FOR OUTPUT DISK AGAIN
- CREATE: XRA A ;SET FLAG
- STA OPNOUT
- STA FCB2+12 ;ZERO EXTENT #
- STA FCB2+32 ;ZERO SECTOR #
- ;******************************************
- ; ERASE EXISTING FILE WITH SAME NAME (IF ANY)
- ;******************************************
- LXI D,FCB2
- MVI C,ERASE
- CALL BDOS
- ;
- ;******************************************
- ; CREATE THE OUTPUT FILE
- ;******************************************
- LXI D,FCB2
- MVI C,MAKE
- CALL BDOS
- ;
- INR A
- JZ BADMAKE ;MAYBE DIRECTORY IS FULL?
- ;******************************************
- ; WRITE THE FILE TO DISK
- ;******************************************
- WRTFIL: LHLD FCT ;ANYTHING TO WRITE?
- MOV A,H
- ORA L
- JZ CLOSEF ;NO - CLOSE OUTPUT FILE
- LXI D,BUFF ;POINT TO BUFFER
- WRLP: PUSH D ;SAVE THE DMA ADDR
- MVI C,STDMA ;SET DMA ADDRESS
- CALL BDOS
- ;******************************************
- ; WRITE THE SECTOR
- ;******************************************
- LXI D,FCB2
- MVI C,WRITE
- CALL BDOS
- ;
- ORA A ;WAS THE WRITE SUCCESSFUL?
- JNZ WRERR ;NO, EXIT W/ERROR MSG
- POP D ;GET DMA ADDR
- LXI H,80H ;GET BUFFER LENGTH
- DAD D ;CALC NEXT DISK WRITE ADDR
- XCHG ;SAVE IN DE
- LHLD FCT ;GET FILE'S SECTOR COUNT
- DCX H ;DECREMENT IT
- SHLD FCT ;SAVE IT BACK
- MOV A,H ;IS IT ZERO?
- ORA L
- JNZ WRLP ;IF MORE, LOOP
- ;******************************************
- ; CLOSE THE FILE
- ;******************************************
- CLOSEF: LXI D,FCB2
- MVI C,CLOSE
- CALL BDOS
- ;
- LDA DONEF ;DONE ?
- ORA A
- JZ DONE ;YES - CLOSE FILE
- LXI H,0 ;NO - CONTINUE
- SHLD FCT
- CALL OPNSRC
- CALL LOGIN
- JMP OPENOK
- ;******************************************
- DONE EQU $ ;FILE HAS BEEN COPIED
- ;******************************************
- ; RESET DMA ADDR T0 80H
- ;******************************************
- LXI D,80H
- MVI C,STDMA
- CALL BDOS
- ;
- CALL MSGEXIT ;EXIT PRINTING FOLLOWING:
- DB '++DONE++',0DH,0AH,'$'
- ;******************************************
- ; READ ERROR - EXIT WITH MSG
- ;******************************************
- RERROR: CALL MSGEXIT
- DB '++READ ERROR++$'
- ;******************************************
- ; GOT A WRITE ERROR - EXIT W/ERROR MSG.
- ;******************************************
- WRERR: CALL MSGEXIT
- DB '++WRITE ERROR++$'
- ;******************************************
- ; COULDN'T MAKE THE FILE, EXIT W/ERROR MSG.
- ;******************************************
- BADMAKE:CALL MSGEXIT
- DB '++CAN''T MAKE OUTPUT FILE$'
- ;******************************************
- ; INLINE PRINT ROUTINE - CALL ILPRT FOLLOWED
- ; BY MESSAGE (ENDING IN 0)
- ;******************************************
- ILPRT: MVI A,0DH ;CR..
- CALL TYPE
- MVI A,0AH ;LF FIRST.
- CALL TYPE
- XTHL ;SAVE HL, GET MSG ADDR
- ILPLP: MOV A,M ;GET CHAR OF MSG
- PUSH H ;SAVE H
- CALL TYPE ;TYPE CHAR
- POP H ;GET H AGAIN
- INX H ;POINT TO NEXT CHAR
- MOV A,M ;GET IT
- ORA A ;IS IT END OF MSG?
- JNZ ILPLP ;NO, LOOP
- INX H ;SKIP THE 0
- XTHL ;RESTORE HL, STACK RET ADDR
- RET ;..AND RETURN
- ;******************************************
- ; TYPE CHAR IN A
- ;******************************************
- TYPE:
- ; WRITE TO CONSOLE
- MOV E,A
- MVI C,WRCON
- CALL BDOS
- ;
- RET
- ;******************************************
- ; CHAR MOVE ROUTINE, (DE) -> (HL) LEN IN B
- ;******************************************
- MOVER: LDAX D ;GET SOURCE CHAR
- MOV M,A ;STORE IN DEST. LOCATION
- INX D ;POINT TO NEXT SOURCE
- INX H ;POINT TO NEXT DEST.
- DCR B ;DECREMENT COUNT
- JNZ MOVER ;LOOP UNTIL ZERO
- RET ;..THEN RETURN
- ;******************************************
- ; EXIT WITH ERROR MESSAGE
- ;******************************************
- MSGEXIT:MVI A,0DH
- CALL TYPE
- MVI A,0AH
- CALL TYPE
- POP D ;GET MSG ADDRESS
- ; PRINT A MESSAGE
- MVI C,PRINT
- CALL BDOS
- ;******************************************
- ; EXIT, RESTORING STACK AND RETURN
- ;******************************************
- EXIT: CALL ILPRT
- DB 0DH,0AH,'RE-BOOTING '
- DB 'VIA "JMP 0000", '
- DB 'PRESS RETURN',0
- ; READ A CHARACTER
- MVI C,RDCON
- CALL BDOS
- ;
- CPI 0DH
- JNZ EXIT
- LHLD STACK ;GET ORIGINAL STACK POINTER
- SPHL ;AND RELOAD
- JMP 0000H ;REBOOT CP/M
- ;******************************************
- ; REQUEST SOURCE DISKETTE + OPEN FILE
- ;******************************************
- OPNSRC: CALL ILPRT
- DB 'MOUNT SOURCE DISK, TYPE S: ',0
- ; GET THE CHARACTER
- MVI C,RDCON
- CALL BDOS
- ;
- ANI 5FH ;MAKE UPPER CASE
- CPI 'S'
- JZ OPENIN ;YES - OPEN INPUT FILE
- CPI 03H ;IS IT CTL-C?
- JZ DONE ;YES - REBOOT
- JMP OPNSRC ;NO - GO ASK AGAIN
- ;******************************************
- ;'S' WAS TYPED, OPEN THE INPUT FILE
- ;******************************************
- OPENIN EQU $
- ; OPEN THE FILE
- LXI D,FCB
- MVI C,OPEN
- CALL BDOS
- ;
- INR A ;WAS THE OPEN OK?
- RNZ ;YES - RETURN
- ;******************************************
- ; OPEN WAS BAD ON SOURCE DISKETTE
- ;******************************************
- CALL ILPRT ;LOOKS LIKE THE WRONG DISKETTE
- DB 0DH,0AH,'** WRONG DISKETTE **',0DH,0AH,0
- JMP OPNSRC ;GO ASK FOR INPUT DISK AGAIN
- ;******************************************
- ; LOG IN THE MOUNTED DISK
- ;******************************************
- LOGIN EQU $
- LXI D,0
- MVI C,SELDK
- CALL BDOS
- ;
- RET
- ;
- ;****************************************
- ; DATA AREA STARTS HERE
- ;****************************************
- ;
- DONEF: DB 0FFH ;COPY DONE FLAG
- OPNOUT: DB 0FFH ;OUTPUT OPEN FLAG
- FCT: DW 0 ;FILE COUNT
- ;FOLLOWING FROM WARD'S "EQU5.LIB"---->
- DS 40H ;STACK AREA
- STACK: DS 2
- ;******************************************
- ; SECOND FCB (FOR OUTPUT FILE)
- ;******************************************
- FCB2: DS 33
- ;******************************************
- ; BUFFER AREA STARTS RIGHT AFTER PROGRAM CODE
- ; AND DATA, AND EXTENDS TO JUST BELOW CCP
- ;******************************************
- BUFF EQU $
- END
-