home *** CD-ROM | disk | FTP | other *** search
- ; COPY - CP/M SINGLE DISK COPY UTILITY
- ;
- ORG 0100H
- JMP COPY
- DB '(C) 1979 - N D H HAMMOND'
- PRGNAME DB 'COPY VSN 2.1 OF 3JAN80',0DH,0AH,'$'
- ;
- ;
- ;SYSTEM ADDRESSES
- WBOOTE EQU 0000H ;REBOOT ADDRESS
- SFCB EQU 005CH ;SOURCE FILE CONTROL BLOCK
- SFCBEX EQU SFCB+12 ;CURRENT FILE EXTENT NO
- SFCBCR EQU SFCB+32 ;NEXT RECORD COUNTER
- TBUF EQU 0080H ;SYSTEM DEFAULT BUFFER
- ;CONSTANTS
- CCPL EQU (3200H-2900H) SHR 8 ;PAGES IN CCP
- TRUE EQU 0FFH
- ETX EQU 03H
- LF EQU 0AH
- CR EQU 0DH
- EOM EQU '$'
- ;
- ; MAIN PROGRAM
- ;
- COPY LXI H,0 ;SAVE OLD STACK POINTER
- DAD SP
- SHLD OLDSP
- LXI SP,STACK
- LXI D,PRGNAME
- CALL WRITESTRING
- CALL SETMODE
- COPYLP CALL GETARGS
- CALL INITVAR
- CALL SOURCEDISK
- CALL OPENSOURCE
- CALL LOADBUF
- CALL DESTDISK
- CALL MAKETEMP
- REPEAT CALL DUMPBUF
- LDA FINISH
- CPI TRUE
- JZ ENDCOPY
- CALL SOURCEDISK
- CALL LOADBUF
- CALL DESTDISK
- JMP REPEAT
- ENDCOPY CALL TERMINATE
- LDA MULTI
- CPI TRUE
- JNZ EXIT
- CALL PROMPT
- JMP COPYLP
- EXIT LHLD OLDSP
- SPHL
- RET ;RETURN TO CP/M
- ;
- ; SUBROUTINBS
- ;
- SETMODE ;SET SINGLE/MULTIPLE COPY MODE
- XRA A
- STA MULTI
- LDA TBUF ;WAS A FILE NAME SPECIFIED?
- CPI 0
- JNZ SM1
- ;NO - SET MULTIPLE MODE
- MVI A,TRUE
- STA MULTI
- CALL PROMPT
- RET
- SM1 ;YES - SINGLE MODE, MOVE COMMAND LINE TO RBUF
- LXI H,TBUF
- LXI D,RBUF+1
- MVI B,30
- CALL COPYSTRING
- ;LIMIT TO 29 CHARACTERS
- LDA RBUF+1
- CPI 30
- RM
- MVI A,29
- STA RBUF+1
- RET
- ;
- ;
- INITVAR ;INITIALIZE VARIABLES
- XRA A
- STA FINISH
- ;SET EXTENT TO CP/M CBASE
- LHLD ENTRY+1 ;HL:=FBASE
- MOV A,H
- SBI CCPL
- MOV H,A ;HL:=CBASE
- MOV A,L ;ENSURE EXTENT IS AT
- ANI 80H ; A PAGE BOUNDARY
- MOV L,A
- SHLD EXTENT
- ;ZERO EXTENT BIT IN SOURCE FCB
- XRA A
- STA SFCBEX
- RET
- ;
- ;
- GETARGS ;GET FILE NAMES FROM BUFFER
- LXI H,RBUF+1 ;HL:=^BUFFER LGTH
- MOV A,M ;A:=BUFFER LGTH
- CPI 0 ;CHECK FOR EMPTY
- JZ EXIT
- INX H ;HL:=^BUFFER
- ;SET <ETX> SENTINEL AT END OF BUFFER
- PUSH H
- MOV C,A
- MVI B,0
- DAD B
- MVI M,ETX
- ;GET SOURCE FILE NAME
- POP H
- CALL DEBLANK
- CPI ETX
- JZ ARGERR
- LXI D,SFCB+1
- CALL GETFILE
- JC ARGERR
- ;GET DEST FILE NAME
- CALL DEBLANK
- CPI ETX
- JZ NODEST
- LXI D,DFCB+1
- CALL GETFILE
- JC ARGERR
- CALL DEBLANK
- CPI ETX
- JNZ ARGERR
- RET
- NODEST ;SET DEST FILE = SOURCE FILE NAME
- LXI D,DFCB+1
- LXI H,SFCB+1
- MVI B,11
- CALL COPYSTRING
- RET
- ARGERR ;REPORT ERROR AND RETRY
- LXI D,AEMSG
- CALL WRITESTRING
- CALL PROMPT
- JMP GETARGS
- ;
- ;
- DEBLANK ;SKIP BLANKS IN RBUF
- ;ENTRY: HL=^POSITION IN RBUF
- ;EXIT: HL=^FIRST NONBLANK
- ; A=HL^
- MOV A,M
- CPI ' '
- RNZ
- INX H
- JMP DEBLANK
- ;
- ;
- GETFILE ;GET FILE NAME FROM RBUF
- ;ENTRY: HL=^POSITION IN RBUF
- ; DE=^FCB FOR FILE
- ;EXIT: HL,DE=^UPDATED POSITION
- ; A=HL^ (<SPACE> OR <CONTROL CHAR>)
- ; CYF=ERROR FLAG
- MVI C,8
- CALL GETNAME
- RC
- CPI '.'
- JNZ NOEXT
- INX H
- MVI C,3
- CALL GETNAME
- RET
- ;FILL FILE TYPE FIELD WITH BLANKS
- NOEXT MVI A,' '
- STAX D
- INX D
- STAX D
- INX D
- STAX D
- MOV A,M
- ORA A ;CLEAR CYF
- RET
- ;
- ;
- GETNAME ;GET NAME FROM RBUF
- ;ENTRY: HL=^POSITION IN RBUF
- ; DE=^FCB POSITION
- ; C=MAX NO OF CHARACTERS
- ;EXIT: HL,DE=^UPDATED POSITION
- ; A=DELIMITER (HL^)
- ; CYF=ERROR FLAG
- MVI B,0
- INR C
- ;TRANSFER NAME TO FCB
- NXTCH MOV A,M
- CPI ' '+1
- JM CKBLK
- CPI '.'
- JZ CKBLK
- CALL UPCASE
- STAX D
- INX H
- INR B
- INX D
- MOV A,B
- CMP C
- JNZ NXTCH
- STC ;TOO MANY CHARS
- RET
- ;BLANK FILL IF REQD
- CKBLK DCR C
- BLKFL MOV A,B
- CMP C
- JZ GOTNM
- MVI A,' '
- STAX D
- INR B
- INX D
- JMP BLKFL
- ;EXIT
- GOTNM MOV A,M
- ORA A ;CLEAR CYF
- RET
- ;
- ;
- UPCASE ;CONVERT ACC TO UPPER CASE
- CPI 61H ;'a'
- RM
- CPI 7BH ;'z'+1
- RP
- ANI 5FH
- RET
- ;
- ;
- OPENSOURCE ;OPEN SOURCE FILE
- LXI D,SFCB
- CALL OPENFILE
- CPI 0FFH
- JNZ OPEN$OK
- MVI B,1
- JMP ERROR
- OPEN$OK XRA A
- STA SFCBCR
- RET
- ;
- ;
- LOADBUF ;LOAD BUFFER FROM SOURCE FILE
- LXI D,BUFFER
- RDNXT PUSH D
- CALL SETDMA
- LXI D,SFCB
- CALL READREC
- POP D
- ORA A
- JZ RD$OK
- CPI 1
- JZ EOF
- MVI B,3
- JMP ERROR
- RD$OK LXI B,80H ;UPDATE BUFFER
- XCHG
- DAD B
- LXI B,EXTENT
- CALL COMPARE
- XCHG
- JNZ RDNXT
- RET
- EOF MVI A,TRUE
- STA FINISH
- XCHG
- SHLD EXTENT
- RET
- ;
- ;
- MAKETEMP ;CREATE TEMPORARY FILE COPY.$$$
- LXI D,TFCB
- CALL MAKEFILE
- CPI 0FFH
- JNZ MAKE$OK
- MVI B,2
- JMP ERROR
- MAKE$OK XRA A
- STA TFCBCR
- STA TFCBEX
- RET
- ;
- ;
- DUMPBUF ;DUMP BUFFER TO TEMP FILE
- LXI D,BUFFER
- WRNXT PUSH D
- CALL SETDMA
- LXI D,TFCB
- CALL WRITEREC
- POP D
- ORA A
- JZ WR$OK
- MVI B,2
- JMP ERROR
- WR$OK LXI B,80H ;UPDATE BUFFER POSITION
- XCHG
- DAD B
- LXI B,EXTENT
- CALL COMPARE
- XCHG
- JNZ WRNXT
- RET
- ;
- ;
- TERMINATE ;CLOSE TEMP FILE
- LXI D,TFCB
- CALL CLOSEFILE
- ;DELETE OLD COPY OF DEST FILE (IF ANY)
- LXI D,DFCB
- CALL DELETEFILE
- ;RENAME DEST FILE = COPY.$$$
- LXI H,DFCB+1
- LXI D,TFCB+17
- MVI B,11
- CALL COPYSTRING
- LXI D,TFCB
- CALL RENAMEFILE
- ;ADVISE OPERATOR
- LXI D,TERMSG
- CALL WRITESTRING
- RET
- ;
- ;
- COPYSTRING ;COPY STRING OF LENGTH B
- ;FROM HL^ TO DE^
- MOV A,M
- STAX D
- INX H
- INX D
- DCR B
- JNZ COPYSTRING
- RET
- ;
- ;
- ERROR ;PRINT ERROR MESSAGE
- LXI D,OPMSG
- MOV A,B
- CPI 1
- JZ EPRINT
- LXI D,CRMSG
- CPI 2
- JZ EPRINT
- LXI D,REMSG
- EPRINT CALL WRITESTRING
- ;EXIT (OR RESTART IF MULTIPLE COPY MODE)
- LDA MULTI
- CPI TRUE
- JNZ EXIT
- LXI SP,STACK
- CALL PROMPT
- JMP COPYLP
- ;
- ;
- COMPARE ;COMPARE BC^ AND HL - SET FLAGS
- INX B
- LDAX B
- DCX B
- CMP H
- RNZ
- LDAX B
- CMP L
- RET
- ;
- ;
- SOURCEDISK ;ADVISE OPERATOR, WAIT FOR RESPONSE,
- LXI D,SDMSG
- CALL WRITESTRING
- CALL WAIT
- RET
- ;
- ;
- DESTDISK ;ADVISE OPERATOR, WAIT FOR RESPONSE
- LXI D,DDMSG
- CALL WRITESTRING
- CALL WAIT
- ;RESET BDOS TO AVOID 'R/O ERROR'
- CALL INITBDOS
- RET
- ;
- ;
- PROMPT ;ISSUE PROMPT AND GET PARAMETERS
- MVI E,'*'
- CALL WRITECHAR
- LXI D,RBUF
- CALL READSTRING
- RET
- ;
- ;
- WAIT ;WAIT FOR OPERATOR TO TYPE RETURN
- CALL READCHAR
- CPI 03H
- JZ WBOOTE
- CPI CR
- JNZ WAIT
- RET
- ;
- ; CP/M COMMUNICATION ROUTINES
- ;
- ;
- ENTRY EQU 0005H ; BDOS ENTRY POINT
- ;
- ;
- READCHAR ; READ A CHARACTER FROM CONSOLE
- MVI C,1
- JMP ENTRY
- ;
- ;
- WRITECHAR ; WRITE A CHARACTER TO CONSOLE
- MVI C,2
- JMP ENTRY
- ;
- ;
- WRITESTRING ; WRITE A STRING ON CONSOLE
- MVI C,9
- JMP ENTRY
- ;
- ;
- READSTRING ; READ STRING FROM CONSOLE
- MVI C,10
- JMP ENTRY
- ;
- ;
- INITBDOS ;INITIALIZE BDOS, LOG IN DISK A
- MVI C,13
- JMP ENTRY
- ;
- ;
- OPENFILE ; OPEN A NEW FILE
- MVI C,15
- JMP ENTRY
- ;
- ;
- CLOSEFILE ; CLOSE FILE
- MVI C,16
- JMP ENTRY
- ;
- ;
- DELETEFILE ; DELETE DIRECTORY ENTRY FOR FILE
- MVI C,19
- JMP ENTRY
- ;
- ;
- READREC ; READ NEXT 128 BYTE RECORD
- MVI C,20
- JMP ENTRY
- ;
- ;
- WRITEREC ; WRITE NEXT 128 BYTE RECORD
- MVI C,21
- JMP ENTRY
- ;
- ;
- MAKEFILE ; CREATE NEW DIRECTORY ENTRY
- MVI C,22
- JMP ENTRY
- ;
- ;
- RENAMEFILE ; CHANGE NAME IN DIRECTORY
- MVI C,23
- JMP ENTRY
- ;
- ;
- SETDMA ; SET DMA ADDRESS FOR READ OR WRITE
- MVI C,26
- JMP ENTRY
- ;
- ;
- ;
- ; DATA AREA
- ;
- OLDSP DS 2
- RBUF DB 28 ;COMMAND INPUT BUFFER
- DS 31
- TFCB DB 0 ;TEMP FCB
- DB 'COPY $$$'
- TFCBEX DB 0
- DB 0,0,0
- DS 16
- TFCBCR DS 1
- DFCB DB 0 ;DEST FCB
- DS 32
- EXTENT DS 2 ;EXTENT OF COPY BUFFER
- MULTI DS 1 ;MULTIPLE COPY MODE FLAG
- FINISH DS 1 ;LAST BUFFER FLAG
- SDMSG DB LF,'INSERT SOURCE DISK, <CR> TO CONTINUE'
- DB CR,LF,EOM
- DDMSG DB 'INSERT DEST DISK, <CR> TO CONTINUE'
- DB CR,LF,EOM
- TERMSG DB 'COPY COMPLETE',CR,LF,EOM
- AEMSG DB LF,'WHAT?',CR,LF,EOM
- OPMSG DB LF,'SOURCE FILE NOT FOUND',CR,LF,EOM
- CRMSG DB LF,'DISK OR DIRECTORY FULL',CR,LF,EOM
- REMSG DB 'READ ERROR ON SOURCE',CR,LF,EOM
- DS 20H ;MINIMUM STACK SPACE
- ;SET START OF BUFFER TO MULTIPLE OF SECTOR SIZE
- ORG (($ + 7FH) / 80H) * 80H
- STACK EQU $ ;GROWS DOWN
- BUFFER EQU $ ;FILLS REST OF MEMORY TO CBASE
- END
-