home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols200
/
vol210
/
put.aq6
/
PUT.A86
Wrap
Text File
|
1986-02-09
|
19KB
|
954 lines
;****************************************************************
; *
; A UTILITY PROGRAM TO FACILITATE COPYING FILES *
; BETWEEN USER AREAS *
; *
;****************************************************************
;
TITLE 'BUFFERED INTER-USER COPY ROUTINE FOR CP/M-86'
;
; Copyright (C) 1981,1982,1984 by
;
; Angus Bliss Bill Bolton
; P.O. Box 293, Software Tools RCPM
; Hamilton, P.O. Box 357,
; NSW, 2303, Kenmore,
; AUSTRALIA QLD, 4069,
; AUSTRALIA
;
; This program is made available for public distribution
; for NON-COMMERCIAL use only. All commercial rights
; retained by the authors.
;
; ------------------------------------------------------
;
; This program is built on the Intel small memory model
; and uses the operating system 96 byte stack. It
; should be GENCMD with the following command line
;
; GENCMD PUT DATA[M860]
;
; ------------------------------------------------------
;
; VERSION LIST, most recent version first
; ---------------------------------------
;
; 1.8 Added code to close source file for
; Concurrent DOS operation - Bill Bolton, 30/Oct/84
;
; 1.7 Translated to CP/M-86, buffer size fixed
; at 32K (generally no lack of memory in
; 16 bit systems) - Bill Bolton 07/Aug/84
;
; 1.6 Fixed problem with zero length files writing
; a file as large as buffer. Fixed problem of
; large files being truncated to 32K in
; some multifile transfers. Tidied up for
; publication - Angus Bliss 29/Apr/82
;
; 1.5 Initial release version. Large file transfer
; bug fixed and other minor internal changes
; mode - Bill Bolton 3/Feb/82
;
; 1.4 Overwrite options added, user abort added,
; filename show added and lots more comments
; added - Bill Bolton 2/Feb/82
;
; 1.3 Transfer to $$$ file first then rename after
; succesful close (like PIP) added - Bill Bolton
; 1/Feb/82
;
; 1.2 Wildcard file transfer added. - Bill Bolton
; 31/Jan/82
;
; 1.1 Converted to 8080 code for greater portability
; (now that the Godbout 8085/8088 card has given
; 8080 code a new lease of life) and presentation-
; tidied up. - Bill Bolton 30/Jan/82
;
; 1.0 Original code in Xitan Z80 source. - Angus Bliss
; Aug/82
;
VERSION EQU 18 ;VERSION NUMBER
;
CNTRLC EQU 3 ;CP/M 'PANIC' CHARACTER
ACR EQU 0DH
ALF EQU 0AH
;
WBOOT EQU 0 ;CP/M WARM BOOT ENTRY
BDOS EQU 0005H ;CP/M BDOS ENTRY POINT
FCB EQU 05CH ;CP/M FILE CONTROL BLOCK
FCB0 EQU 06CH
TBUF EQU 080H ;CP/M COMMAND LINE BUFFER
;
CI EQU 1 ;BDOS CONSOLE IN
CO EQU 2 ;BDOS CONSOLE OUT
DIRECT EQU 6 ;BDOS DIRECT CONSOLE
B_PRINT EQU 9 ;BDOS CONSOLE MESSAGE
VERS EQU 12 ;BDOS RETURN VERSION NUMBER
B_OPEN EQU 15 ;BDOS OPEN FILE
B_CLOSE EQU 16 ;BDOS CLOSE FILE
SRCH_1ST EQU 17 ;BDOS SEARCH FOR FILE
SRCH_NXT EQU 18 ;BDOS SEARCH FOR NEXT (AMBIG) FILE
DELET EQU 19 ;BDOS DELETE FILE
B_READ EQU 20 ;BDOS SEQUENTIAL READ
B_WRITE EQU 21 ;BDOS SEQUENTIAL WRITE
MAKE EQU 22 ;BDOS CREATE NEW FILE
REN EQU 23 ;BDOS RENAME FILE
DMA EQU 26 ;BDOS SET NEW DMA
ATTRIB EQU 30 ;BDOS SET FILE ATTRIBUTES
USER EQU 32 ;BDOS SET/GET USER
;
BUFSIZ EQU 255 ;Disk buffer in sectors (32K)
M EQU Byte Ptr 0[BX]
;
CSEG
ORG 0
;
START:
MOV DX,(Offset MSG1)
MOV CL,B_PRINT
CALL BDOSE ;ANNOUNCE OURSELF
; MOV CL,VERS ;CHECK VERSION
; INT 224 ;USES BX REGISTER
; MOV AL,BL
; CMP AL,2
; JNB L_1
; JMP ERROR3 ;WRONG CP/M VERSION
;L_1:
MOV AL,Byte Ptr .TBUF ;PARAMETER COUNT
CMP AL,0 ;NO PARAMETER
JNZ START_1
JMP ERROR1
;
START_1:
MOV BX,FCB-1 ;TAKE A COPY OF FCB
MOV DX,(Offset FCB2)-1 ;_ TBUF
MOV CX,33 ;LENGTH OF A FILENAME
LDIR1:
INC BX ;ADJUST POINTERS
INC DX
MOV AL,M ;GET A BYTE
MOV SI,DX ;PUT A BYTE
MOV [SI],AL
DEC CX ;ADJUST COUNT
MOV AL,CH
OR AL,CL ;ZERO YET
JNZ LDIR1 ;NO
MOV BX,TBUF ;YES
MOV CH,0
MOV CL,M ;GET COUNT
INC BX ;STEP OVER ANY SOURCE
DEC CL
INC BX ; DRIVE IDENTIFIER ON
DEC CL
INC BX ; FILE NAME
DEC CL
MOV AL,':' ;DRIVE DELIMITER
CCIR1:
INC BX
CMP AL,M ;MATCH
JZ GO_ON1
DEC CL
JZ NOT_FOUND1 ;YES
JMPS CCIR1
;
GO_ON1:
DEC BX ;ADJUST PTR
MOV AL,M
CMP AL,'G'+1
JNB NOT_FOUND1
CMP AL,'A'
JB NOT_FOUND1
AND AL,7 ;MAKE 0 TO 7
MOV Byte Ptr DEST_DRV,AL
MOV Byte Ptr FCB2,AL
NOT_FOUND1:
MOV BX,FCB
MOV CL,11 ;GET LENGTH OF FILE NAME
MOV AL,'?' ;WILDCARD
CCIR2:
INC BX ;LOOP TO SEARCH FOR WILDCARD
CMP AL,M
JZ GO_ON2
DEC CL
JZ NOT_FOUND2
JMPS CCIR2
;
GO_ON2:
MOV AL,0FFH
MOV Byte Ptr WILD,AL ;SET MULTIFILE FLAG
NOT_FOUND2:
MOV BX,TBUF ;YES
MOV CH,0
MOV CL,M ;GET COUNT
MOV AL,'-' ;OPTION SPECIFIER
CCIR_3:
INC BX ;LOOP TO SEARCH FOR OPTIONS
CMP AL,M
PUSH BX
JNZ CCIR_4
CALL OPTION
CCIR_4:
POP BX
DEC CL
JNZ CCIR_3
JMPS NOT_FOUND3
;
OPTION:
LAHF ;FOUND THE FLAG
XCHG AL,AH
PUSH AX
OPT_1:
INC BX ;NOW LOOK FOR AN OPTION
MOV AL,M
CMP AL,'W'
JZ OVER_WRITE
CMP AL,'N'
JZ NO_QUERY
POP AX
XCHG AL,AH
SAHF
RET
;
OVER_WRITE:
MOV AL,0FFH
MOV Byte Ptr O_W,AL
JMPS OPT_1 ;LOOK FOR ANOTHER ONE
;
NO_QUERY:
MOV AL,0FFH
MOV Byte Ptr N_Q,AL
JMPS OPT_1 ;LOOK FOR ANOTHER ONE
;
NOT_FOUND3:
MOV BX,6DH ;FROM USER
CALL NSCAN ;GET NUMBER
JNB NF_4
JMP ERROR2 ;INVALID USER
NF_4:
MOV Byte Ptr FUSER,AL ;FROM USER
MOV BX,75H ;TO USER
CALL NSCAN
JNB NF_5
JMP ERROR2
NF_5:
MOV Byte Ptr TUSER,AL ;TO USER
MOV DL,0FFH
MOV CL,USER ;GET CURRENT USER
CALL BDOSE
MOV Byte Ptr CUSER,AL ;SAVE IT
MOV AL,Byte Ptr FUSER ;FROM USER
MOV DL,AL ;PUT IN E
MOV CL,USER
CALL BDOSE ;SET THE USER
MOV BX,FCB
MOV AL,Byte Ptr WILD
OR AL,AL ;SINGLE FILE ONLY ?
JZ COPY_FCB ;YES
MOV DX,FCB
MOV CL,SRCH_1ST
CALL BDOSE
CMP AL,0FFH ;FOUND?
JNZ DIR_MATCH
JMP ERROR4 ;NO
;
DIR_MATCH:
ADD AL,AL ;MULTIPLY BY 5
ADD AL,AL
ADD AL,AL
ADD AL,AL
ADD AL,AL
MOV BX,TBUF ;POINT TO DIRECTORY BUFFER
MOV DL,AL
MOV DH,0
ADD BX,DX ;BX <--- POINTER TO MATCHED FILE
COPY_FCB:
PUSH BX
MOV CL,12
MOV DX,(Offset FCB1)
MOV AL,Byte Ptr .FCB
MOV M,AL ;STUFF SRC DRIVE IDENT INTO FCB
C_FCB_1:
MOV AL,M ;COPY FCB TO FCB1 (READ FCB)
MOV SI,DX
MOV [SI],AL
INC BX
INC DX
DEC CL
JNZ C_FCB_1
POP BX
C_FCB_2:
MOV CL,11
MOV DX,(Offset FCB2)
MOV AL,Byte Ptr DEST_DRV
MOV SI,DX ;STUFF DEST DRIVE IDENT INTO FCB
MOV [SI],AL
INC BX
INC DX
C_FCB_3:
MOV AL,M ;COPY FCB TO FCB1 (WRITE FCB)
AND AL,7FH ;RESET ANY FILE ATTRIBUTES
MOV SI,DX
MOV [SI],AL
LAHF
INC BX
SAHF
LAHF
INC DX
SAHF
DEC CL
JNZ C_FCB_3
READ_FILE:
MOV BX,(Offset FCB1)
CALL SHOW
MOV DX,(Offset FCB1) ;CP/M DEFAULT
MOV CL,B_OPEN
CALL BDOSE ;OPEN OUR SOURCE
CMP AL,255
JNZ RD_FILE_1
JMP ERROR4 ;OPEN FAILURE
;
RD_FILE_1:
XOR AL,AL ;INITIALISE REGISTER
MOV Byte Ptr ACOUNT,AL ;SECTOR COUNT
MOV AL,BUFSIZ
MOV CH,AL ;SECTOR COUNT
;
READ:
MOV DX,(Offset BUFSTART) ;CH HAS SECTOR CNT
READ1:
MOV CL,DMA
CALL BDOSE ;SET DMA ADDRESS
PUSH DX ;SAVE DMA ADDR.
MOV DX,(Offset FCB1)
MOV CL,B_READ
CALL BDOSE ;READ A SECTOR
POP DX ;RESTORE DMA
CMP AL,1
JZ FINISH
CMP AL,0
JZ READ2
JMP ERROR5 ;READ ERROR
;
READ2:
MOV AL,DL ;BUMP POINTER
ADD AL,80H
MOV DL,AL
MOV AL,0
ADC AL,DH
MOV DH,AL ;BY 128 BYTES
MOV AL,Byte Ptr ACOUNT
INC AL
MOV Byte Ptr ACOUNT,AL ;SECTORS READ
DEC CH ;ADJUST COUNT
JNZ READ1 ;NO
CALL WRITE ;FULL, SO EMPTY IT
XOR AL,AL ;RESET REGISTERS
MOV Byte Ptr ACOUNT,AL ;SECTOR COUNT
MOV AL,BUFSIZ
MOV CH,AL ;SECTOR COUNT
JMPS READ
;
FINISH:
MOV DX,(Offset FCB1)
MOV CL,B_CLOSE ;CLOSE SOURCE
CALL BDOSE
MOV AL,0FFH
MOV Byte Ptr EOF,AL ;FINISHED THIS FILE
MOV AL,BUFSIZ
SUB AL,CH
MOV CH,AL
CALL WRITE
MOV DX,(Offset FCB2)
MOV CL,B_CLOSE ;CLOSE DESTINATION
CALL BDOSE
CMP AL,255
JNZ FINI_1
JMP ERROR9 ;CLOSE FAILURE
;
FINI_1:
CALL RENAME ;RENAME $$$ TO TYP
MOV AL,Byte Ptr WILD
OR AL,AL ;MORE FILES?
JNZ FINI_2
JMP DONE
;
FINI_2:
MOV BX,(Offset BUFSTART)
MOV Word Ptr BUFPT,BX ;RESET BUFFER POINTER
XOR AL,AL
MOV Byte Ptr OPEN,AL ;RESET FILE OPEN FLAG
MOV Byte Ptr EOF,AL ;WON'T BE EOF ON NEXT FILE
MOV BX,(Offset FCB1) ;POINT TO INTERNAL FCBS
MOV CL,64 ;LENGTH OF 2 * FCB
XOR AL,AL
FCB_FILL1:
MOV M,AL ;RESET MEMORY
LAHF ;ADJUST POINTER
INC BX
SAHF
DEC CL ;DONE ?
JNZ FCB_FILL1 ;NO
MOV AL,Byte Ptr FUSER
MOV DL,AL ;SAVE DIRECTORY POINTER TIL LATER
MOV CL,USER
CALL BDOSE ;RESET TO SOURCE USER
MOV DX,TBUF ;RESET DMA
MOV CL,DMA
CALL BDOSE
MOV DX,FCB
MOV CL,SRCH_1ST ;START SEARCH FOR NEXT
CALL BDOSE ; WILDCARD MATCH (TEDIOUS)
MOV AL,Byte Ptr F_COUNT ;NO FILES DONE SO FAR
INC AL ;JUST DONE ANOTHER ONE
MOV Byte Ptr F_COUNT,AL ;KEEP FOR NEXT TIME
MOV Byte Ptr D_COUNT,AL ;INITIALISE LOOP COUNTER
SEARCH_LOOP:
MOV DX,0
MOV CL,SRCH_NXT ;SEARCH FOR NEXT WILDCARD MATCH
CALL BDOSE
MOV Byte Ptr DIR_POINT,AL
CMP AL,0FFH ;NO MORE MATCH ?
JNZ SRC_LP_1
JMP DONE ;YES
SRC_LP_1:
MOV AL,Byte Ptr D_COUNT ;NO, GET LOOP COUNT
DEC AL ;ONE SEARCH DONE
MOV Byte Ptr D_COUNT,AL
JNZ SEARCH_LOOP ;SEARCH AGAIN
MOV CL,DIRECT
MOV DL,0FFH
CALL BDOSE
CMP AL,CNTRLC ;USER WANTS ABORT ?
JNZ SRC_LP_2
JMP U_ABORT ;YES
;
SRC_LP_2:
MOV AL,Byte Ptr DIR_POINT ;NO, A = POINTER INTO DIR SECTOR
JMP DIR_MATCH ;FOUND THE ONE WE NEEDED
;
WRITE:
MOV AL,Byte Ptr TUSER
MOV DL,AL
MOV CL,USER
CALL BDOSE ;SET DESTINATION USER
MOV AL,Byte Ptr OPEN
CMP AL,0 ;FILE ALREADY OPEN ?
JZ WRITE_M
JMP WRITE2 ;YES
;
WRITE_M:
NOT AL ;NO
MOV Byte Ptr OPEN,AL ;INDICATE FILE OPEN
MOV DX,(Offset FCB2)
MOV CL,B_OPEN
CALL BDOSE ;ATTEMPT OPEN
CMP AL,255
JZ WRITE0 ;NOT PRESENT
MOV AL,Byte Ptr FCB2+9 ;PRESENT, CHECK R/O
AND AL,80H ;ISOLATE BIT
RCL AL,1 ;PUT IN CARRY
JNB NOT_RO ;NOT R/O
MOV AL,Byte Ptr O_W
OR AL,AL ;OVER WRITE R/O FILE ?
JNZ REMOVE_RO
JMP ERR6A ;IS R/O
;
REMOVE_RO:
MOV DX,(Offset FCB2)
MOV CL,B_CLOSE
CALL BDOSE ;CLOSE FILE TO CHANGE ATTRIBUTES
MOV BX,(Offset FCB2)+12 ;FCB2 HAS GROUP 'GARBAGE'
XOR AL,AL ; FROM OPEN CALL WHICH
MOV CL,21 ; NEEDS TO BE CLEANED OUT
CALL FILL_BLOCK ; FOR ATTRIBUTE CALL
MOV BX,(Offset FCB2)
MOV CL,12
R_RO:
MOV AL,M ;RESET ATTRIBUTES IN FILE NAME
AND AL,7FH
MOV M,AL
LAHF
INC BX
SAHF
DEC CL
JNZ R_RO
MOV DX,(Offset FCB2)
MOV CL,ATTRIB
CALL BDOSE
CMP AL,0FFH ;THIS SHOULD NEVER HAPPEN
JNZ OPEN_RW
JMP ERROR11 ; BUT JUST IN CASE
;
OPEN_RW:
MOV DX,(Offset FCB2)
MOV CL,B_OPEN
CALL BDOSE ;OPEN, we already know it exists
NOT_RO:
MOV AL,Byte Ptr N_Q
OR AL,AL ;NO FILE EXISTS QUERY?
JNZ WRITE0 ;YES
CALL ERROR6 ;CHECK BEFORE DELETE
CMP AL,'Y'
JZ WRITE1 ;CONTINUE
CMP AL,'y'
JZ WRITE1 ;CONTINUE
JMP ABORT ;ANSWER NOT 'Y' OR 'y'
WRITE1:
CALL CRLF
WRITE0:
MOV BX,(Offset FCB2)+9 ;POINT TO SECONDARY FILENAME
MOV DX,(Offset F_TYPE)
MOV CL,3 ;LENGTH OF SECONDARY FILENAME
MOV CH,'$' ;TEMPORARY FILE TYPE MARKER
FILL_TYPE1:
MOV AL,M ;GET SECONDARY FILE NAME
MOV SI,DX ;SAVE IT FOR LATER
MOV [SI],AL
MOV M,CH ;STUFF IN TEMP MARKERS
INC BX
INC DX
DEC CL
JNZ FILL_TYPE1
MOV BX,(Offset FCB2)+12 ;ZERO FILL REST OF FCB
MOV CL,24
XOR AL,AL
CALL FILL_BLOCK
MOV DX,(Offset FCB2)
MOV CL,MAKE
CALL BDOSE ;CREATE DESTINATION FILE
CMP AL,255
JNZ WRITE2
JMP ERROR7 ;DIRECTORY FULL
;
WRITE2:
MOV AL,Byte Ptr ACOUNT
OR AL,AL ;ZERO LENGTH FILE?
JZ ZEXIT ;YES, DONT WRITE TO DESTINATION
MOV CH,AL ;ACTUAL SECTOR COUNT
PUSH BX
MOV BX,(Offset BUFSTART)
MOV Word Ptr BUFPT,BX ;SAVE BUFFER POINTER
POP BX
WRITE3:
PUSH BX
MOV BX,Word Ptr BUFPT ;GET BUFFER POINTER
XCHG BX,DX ;DE <---- BUFFER POINTER
POP BX
PUSH DX
MOV AL,DL
ADD AL,80H
MOV DL,AL
MOV AL,0
ADC AL,DH ;16 BIT ADD OF 1 SECTOR
MOV DH,AL
PUSH BX
XCHG BX,DX
MOV Word Ptr BUFPT,BX ;SAVE NEW BUFFER POINTER
POP BX
POP DX
MOV CL,DMA
CALL BDOSE ;CHANGE DMA ADDRESS
MOV DX,(Offset FCB2)
MOV CL,B_WRITE
CALL BDOSE ;WRITE A SECTOR
CMP AL,0
JZ WRITE4
JMP ERROR8 ;WRITE ERROR
;
WRITE4:
DEC CH ;DONE YET?
JNZ WRITE3 ;NO
ZEXIT: ;(COME IN HERE IF ZERO LENGTH FILE)
MOV AL,Byte Ptr EOF
CMP AL,0
JZ ZEXIT_1
RET ;END
;
ZEXIT_1:
MOV AL,Byte Ptr FUSER
MOV DL,AL
MOV CL,USER ;SET SOURCE USER
CALL BDOSE
RET
;
FILL_BLOCK:
MOV M,AL ;GENERAL BLOCK FILLER
LAHF ; WITH A CONSTANT
INC BX
SAHF
DEC CL
JNZ FILL_BLOCK
RET
;
;
RENAME:
MOV BX,(Offset FCB2)+9 ;START POINT
MOV CL,27 ;LENGTH TO FILL
XOR AL,AL ;ZERO A
CALL FILL_BLOCK
MOV BX,(Offset F_TYPE) ;POINT TO FILE TYPE
MOV DX,(Offset FCB2)+9 ;SECONDARY FILE NAME
MOV CL,3 ;LENGTH TO MOVE
REN_LOOP1:
MOV AL,M ;STUFF FILE TYPE BACK INTO FCB
MOV SI,DX
MOV [SI],AL
LAHF
INC BX
SAHF
LAHF
INC DX
SAHF
DEC CL
JNZ REN_LOOP1
MOV DX,(Offset FCB2)
MOV CL,DELET
CALL BDOSE ;KILL ORIGINAL DESTINATION FILE
MOV BX,(Offset FCB2)+9
MOV CL,27
XOR AL,AL
CALL FILL_BLOCK ;ZERO FILL WRITE FCB YET AGAIN
MOV BX,(Offset FCB2)
MOV DX,(Offset FCB2)+16
MOV CL,9
REN_LOOP2:
MOV AL,M ;COPY WRITE FCB TO MAKE THE
MOV SI,DX ; SPECIAL RENAME FORMAT FCB
MOV [SI],AL
LAHF
INC BX
SAHF
LAHF
INC DX
SAHF
DEC CL
JNZ REN_LOOP2
MOV AL,'$' ;HL = POINTER TO FCB2 +9
MOV CL,3
REN_LOOP3:
MOV M,AL ;STUFF TEMP FILE MARKERS IN
LAHF ; THE 'FROM' PART OF FCB
INC BX
SAHF
DEC CL
JNZ REN_LOOP3
MOV BX,(Offset F_TYPE) ;DE = FCB2+9+16
MOV CL,3
REN_LOOP4:
MOV AL,M ;STUFF FILE TYPE IN THE
MOV SI,DX ; 'TO' PART OF FCB
MOV [SI],AL
LAHF
INC BX
SAHF
LAHF
INC DX
SAHF
DEC CL
JNZ REN_LOOP4
MOV DX,(Offset FCB2)
MOV CL,REN ;DO THE RENAME
CALL BDOSE
CMP AL,0FFH ;AGAIN, THIS SHOULD NEVER HAPPEN
JZ ERROR10 ; BUT.......
RET
;
;ERROR AND MESSAGE HANDLING
;
ERROR1:
MOV DX,(Offset MSG3)
CALL PRINT
MOV DX,(Offset MSG2)
CALL PRINT
JMP ABORT
;
ERROR2:
MOV DX,(Offset MSG4)
CALL PRINT
MOV DX,(Offset MSG2)
CALL PRINT
JMP ABORT
;
ERROR3:
MOV DX,(Offset MSG5)
CALL PRINT
JMPS ABORT
;
ERROR4:
MOV DX,(Offset MSG6)
CALL PRINT
JMPS ABORT
;
ERROR5:
MOV DX,(Offset MSG7)
CALL PRINT
JMPS ABORT
;
ERROR6:
MOV DX,(Offset MSG8)
MOV CL,B_PRINT
CALL BDOSE ;PROMPT QUESTION
MOV CL,CI
CALL BDOSE
RET ;RETURN WITH INPUT
;
ERR6A:
MOV DX,(Offset MSG8A)
CALL PRINT
JMPS ABORT
;
ERROR7:
MOV DX,(Offset MSG9)
CALL PRINT
MOV DX,(Offset MSG10)
CALL PRINT
JMPS ABORT
;
ERROR8:
MOV DX,(Offset MSG11)
CALL PRINT
JMPS ABORT
;
ERROR9:
MOV DX,(Offset MSG12)
CALL PRINT
JMPS ABORT
;
ERROR10:
MOV DX,(Offset MSG16)
CALL PRINT
JMPS ABORT
;
ERROR11:
MOV DX,(Offset MSG17)
CALL PRINT
JMPS ABORT
;
;
;GENERAL PURPOSE SUBROUTINES
;
PRINT:
PUSH DX
CALL CRLF
POP DX
MOV CL,B_PRINT
CALL BDOSE ;PRINT MESSAGE
RET
;
U_ABORT:
MOV DX,(Offset MSG18)
CALL PRINT
JMPS EOJ
;
ABORT:
MOV DX,(Offset MSG13)
CALL PRINT
JMPS EOJ
;
CRLF:
MOV DL,ACR
MOV CL,CO
CALL BDOSE
MOV DL,ALF
MOV CL,CO
CALL BDOSE
RET
;
DONE:
CALL CRLF ;NORMAL EOJ MSG
MOV DX,(Offset MSG14)
MOV CL,B_PRINT
CALL BDOSE
;
EOJ:
MOV AL,Byte Ptr CUSER ;RESET USER
MOV DL,AL
MOV CL,USER
CALL BDOSE
MOV CX,0
MOV DX,0
INT 224
;
SHOW:
CALL CRLF
MOV DX,(Offset MSG15)
MOV CL,B_PRINT
CALL BDOSE
MOV DH,9
SHOW1: ;DISPLAY FILENAME IN READ FCB
LAHF
INC BX
SAHF
DEC DH
JNZ SHOW2
MOV DL,'.' ;PRINT THE SEPARATOR
MOV CL,CO
CALL BDOSE
SHOW2:
MOV AL,M
CMP AL,0
JNZ SHOW3
RET
;
SHOW3:
CMP AL,' ' ;SKIP BLANKS
JZ SHOW1
MOV DL,AL
MOV CL,CO
CALL BDOSE
JMPS SHOW1
;
;
BDOSE:
PUSH CX ;BDOS ENTRY
PUSH DX
PUSH BX
INT 224
POP BX
POP DX
POP CX
RET
;
NSCAN:
MOV DX,0 ;CLEAR WORK
MOV AL,M ;GET CHAR
CMP AL,'9'+1 ;IS IT A DIGIT
JNB NSCAN2 ;> 9
CMP AL,'0'
JB NSCAN2 ;< 0
NSCAN0:
SUB AL,'0' ;REMOVE ASCII BIAS
PUSH BX ;SAVE PTR
XCHG BX,DX ;GET WORK IN BX
PUSH BX
POP DX
SHL BX,1
SHL BX,1
ADD BX,DX
SHL BX,1 ;BX = BX * 10
MOV DH,0
MOV DL,AL ;NEW DIGIT
ADD BX,DX ;ADD IT IN
XCHG BX,DX ;PUT WORK BACK
POP BX ;RESTORE PTR
INC BX ;AND STEP IT
MOV AL,M
CMP AL,'9'+1
JNB NSCAN1
CMP AL,'0'
JB NSCAN1
JMPS NSCAN0 ;LOOP
;
NSCAN1: MOV AL,DL ;GET NUMBER
CMP AL,16 ;<= 15
JNB NSCAN2
OR AL,AL ;CLEAR CARRY
JMPS NSCAN3
;
NSCAN2:
STC ;SET CARRY
NSCAN3:
RET ;EXIT HERE
;
DSEG
ORG 100H
;
MSG1 DB 'PUT, CP/M-86 Version ',VERSION/10 + '0','.'
DB VERSION MOD 10 + '0'
DB ', by Angus Bliss and Bill Bolton',ACR,ALF,'$'
;
MSG2 DB 'Usage:',ACR,ALF
DB ' A>put [d:]filename f.t [d:] [-NW] <cr>'
DB ACR,ALF
DB 'Where:',ACR,ALF
DB ' filename - is any valid CP/M file '
DB 'specifier',ACR,ALF
DB ' f - is source user area',ACR,ALF
DB ' t - is destination user area'
DB ACR,ALF
DB ' d: - is optional drive specifier'
DB ACR,ALF
DB ' - - is an option flag',ACR,ALF
DB ' N - is no query to overwrite '
DB 'existing file',ACR,ALF
DB ' W - is force overwrite of R/O '
DB 'file',ACR,ALF,ALF
DB ' Will prompt if destination '
DB 'file is already present',ACR,ALF,'$'
;
MSG3 DB 'No parameters given',ACR,ALF,'$'
;
MSG4 DB 'Invalid user number(s)',ACR,ALF,'$'
;
MSG5 DB 'Sorry - you need CP/M 2.x',ACR,ALF,'$'
;
MSG6 DB 'Open fail on source file.',ACR,ALF,'$'
;
MSG7 DB 'Read failure on source file.',ACR,ALF,'$'
;
MSG8 DB ' Destination file is present.',ACR,ALF
DB ' Continue (y) or Abort (n)?$'
;
MSG8A DB 'Destination is present and R/O.$'
;
MSG9 DB 'Open failure on destination file.$'
;
MSG10 DB 'Destination directory probably full.$'
;
MSG11 DB 'Write error on destination.$'
;
MSG12 DB 'Close fail on destination.$'
;
MSG13 DB 'ABORT - returning to CP/M.',ACR,ALF,'$'
;
MSG14 DB '**** Normal end-of-job ****',ACR,ALF,'$'
;
MSG15 DB ' Putting file : $'
;
MSG16 DB 'Rename error on destination.$'
;
MSG17 DB 'Rename error on R/O file.$'
;
MSG18 DB 'ABORT, Control C typed at console - '
DB 'returning to CP/M',ACR,ALF,'$'
;
CUSER DB 0 ;INITIATING USER
FUSER DB 0 ;FILE FROM USER
TUSER DB 0 ;FILE TO USER
SIZEB DW 0 ;BUFFER IN BYTES
BUFPT DW 0 ;DMA POINTER
ACOUNT DB 0 ;ACTUAL SECTOR COUNT
OPEN DB 0 ;FILE OPEN SWITCH
EOF DB 0 ;END OF SOURCE SWITCH
WILD DB 0 ;WILDCARD SWITCH
O_W DB 0 ;OVER WRITE SWITCH
N_Q DB 0 ;NO QUERY SWITCH
DEST_DRV DB 0 ;DESTINATION DRIVE
F_COUNT DB 0 ;FILES TRANSFERED COUNTER
D_COUNT DB 0 ;FILES TO SEARCH COUNTER
DIR_POINT DB 0 ;TEMP STORAGE FOR SEARCH NEXT
;
F_TYPE DB ' ' ;SECONDARY FILE TYPE
;
; FOR RENAME AFTER WRITE
;
FCB1 DB 0,0,0,0,0,0,0,0,0 ;SOURCE FCB
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
;
FCB2 DB 0,0,0,0,0,0,0,0,0 ;Destination FCB
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0
;
BUFSTART RB (BUFSIZ + 1) * 128 ;Disk buffer
;
BUFEND EQU $ ;Generate symbol for SID
;
END