home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol074
/
copy.asm
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
8KB
|
503 lines
; 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