home *** CD-ROM | disk | FTP | other *** search
- TITLE 'BUFFERED INTER-USER COPY ROUTINE FOR CP/M'
- *****************************************************************
- * *
- * A UTILITY PROGRAM TO FACILITATE COPYING FILES *
- * BETWEEN USER AREAS *
- * *
- *****************************************************************
- ;
- ; First publication data:
- ;
- ; Electronic publication by :- "Software Tools" RCPM System
- ; Sydney, Australia
- ;
- ; Print publication by :- Dr Dobbs Journal, Palo Alto, USA
- ;
- ; Copyright (c) 1981/82
- ;
- ; Angus Bliss Bill Bolton
- ; P.O. Box 293, Software Tools
- ; Hamilton, P.O. Box 80,
- ; NSW, 2303, Newport Beach,
- ; AUSTRALIA NSW, 2106,
- ; AUSTRALIA
- ;
- ; This program is made available for public distribution
- ; for NON-COMMERCIAL use only. All commercial rights
- ; retained by the authors.
- ;
- ; Version list (latest version first)
- ; -----------------------------------
- ; 1.6 Fix problem with zero length files writing
- ; a file as large as buffer. Fix problem of
- ; large files being truncated to 32K in
- ; some multifile transfers. Tidy 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 16 ;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
-
- ;
- ORG 100H ;FOR CP/M
- ;
- START:
- LXI SP,STACK ;SET A STACK
- LXI D,MSG1
- MVI C,B$PRINT
- CALL BDOSE ;ANNOUNCE OURSELF
- MVI C,VERS ;CHECK VERSION
- CALL BDOS ;USES HL REGISTER
- MOV A,L
- CPI 2
- JC ERROR3 ;WRONG CP/M VERSION
- LDA TBUF ;PARAMETER COUNT
- CPI 0 ;NO PARAMETER
- JZ ERROR1
- LXI H,FCB-1 ;TAKE A COPY OF FCB
- LXI D,FCB2-1 ;@ TBUF
- LXI B,33 ;LENGTH OF A FILENAME
- LDIR1:
- INX H ;ADJUST POINTERS
- INX D
- MOV A,M ;GET A BYTE
- STAX D ;PUT A BYTE
- DCX B ;ADJUST COUNT
- MOV A,B
- ORA C ;ZERO YET
- JNZ LDIR1 ;NO
- LXI H,TBUF ;YES
- MVI B,0
- MOV C,M ;GET COUNT
- INX H ;STEP OVER ANY SOURCE
- DCR C
- INX H ; DRIVE IDENTIFIER ON
- DCR C
- INX H ; FILE NAME
- DCR C
- MVI A,':' ;DRIVE DELIMITER
- CCIR1:
- INX H
- CMP M ;MATCH
- JZ GO$ON1
- DCR C
- JZ NOT$FOUND1 ;YES
- JMP CCIR1
- ;
- GO$ON1:
- DCX H ;ADJUST PTR
- MOV A,M
- CPI 'G'+1 ; A >= CHAR <= G
- JNC NOT$FOUND1
- CPI 'A'
- JC NOT$FOUND1
- ANI 7 ;MAKE 0 TO 7
- STA DEST$DRV
- STA FCB2
- NOT$FOUND1:
- LXI H,FCB
- MVI C,11 ;GET LENGTH OF FILE NAME
- MVI A,'?' ;WILDCARD
- CCIR2:
- INX H ;LOOP TO SEARCH FOR WILDCARD
- CMP M
- JZ GO$ON2
- DCR C
- JZ NOT$FOUND2
- JMP CCIR2
- ;
- GO$ON2:
- MVI A,0FFH
- STA WILD ;SET MULTIFILE FLAG
- NOT$FOUND2:
- LXI H,TBUF ;YES
- MVI B,0
- MOV C,M ;GET COUNT
- MVI A,'-' ;OPTION SPECIFIER
- CCIR3:
- INX H ;LOOP TO SEARCH FOR OPTIONS
- CMP M
- PUSH H
- CZ OPTION
- POP H
- DCR C
- JNZ CCIR3
- JMP NOT$FOUND3
- ;
- OPTION:
- PUSH PSW ;FOUND THE FLAG
- OPT$1:
- INX H ;NOW LOOK FOR AN OPTION
- MOV A,M
- CPI 'W'
- JZ OVER$WRITE
- CPI 'N'
- JZ NO$QUERY
- POP PSW
- RET
- ;
- OVER$WRITE:
- MVI A,0FFH
- STA O$W
- JMP OPT$1 ;LOOK FOR ANOTHER ONE
- ;
- NO$QUERY:
- MVI A,0FFH
- STA N$Q
- JMP OPT$1 ;LOOK FOR ANOTHER ONE
- ;
- NOT$FOUND3:
- LXI H,6DH ;FROM USER
- CALL NSCAN ;GET NUMBER
- JC ERROR2 ;INVALID USER
- STA FUSER ;FROM USER
- LXI H,75H ;TO USER
- CALL NSCAN
- JC ERROR2
- STA TUSER ;TO USER
- MVI E,0FFH
- MVI C,USER ;GET CURRENT USER
- CALL BDOSE
- STA CUSER ;SAVE IT
- LDA FUSER ;FROM USER
- MOV E,A ;PUT IN E
- MVI C,USER
- CALL BDOSE ;SET THE USER
- LXI H,FCB
- LDA WILD
- ORA A ;SINGLE FILE ONLY ?
- JZ COPY$FCB ;YES
- LXI D,FCB
- MVI C,SRCH$1ST
- CALL BDOSE
- CPI 0FFH ;FOUND?
- JZ ERROR4 ;NO
- DIR$MATCH:
- ADD A ;MULTIPLY BY 5
- ADD A
- ADD A
- ADD A
- ADD A
- LXI H,TBUF ;POINT TO DIRECTORY BUFFER
- MOV E,A
- MVI D,0
- DAD D ;HL < POINTER TO MATCHED FILE
- COPY$FCB:
- PUSH H
- MVI C,12
- LXI D,FCB1
- LDA FCB
- MOV M,A ;STUFF SRC DRIVE IDENT INTO FCB
- C$FCB$1:
- MOV A,M ;COPY FCB TO FCB1 (READ FCB)
- STAX D
- INX H
- INX D
- DCR C
- JNZ C$FCB$1
- POP H
- C$FCB$2:
- MVI C,11
- LXI D,FCB2
- LDA DEST$DRV
- STAX D ;STUFF DEST DRIVE IDENT INTO FCB
- INX H
- INX D
- C$FCB$3:
- MOV A,M ;COPY FCB TO FCB1 (WRITE FCB)
- ANI 7FH ;RESET ANY FILE ATTRIBUTES
- STAX D
- INX H
- INX D
- DCR C
- JNZ C$FCB$3
- READ$FILE:
- LXI H,FCB1
- CALL SHOW
- LXI D,FCB1 ;CP/M DEFAULT
- MVI C,B$OPEN
- CALL BDOSE ;OPEN OUR SOURCE
- CPI 255
- JZ ERROR4 ;OPEN FAILURE
- CALL BUFSIZ ;CALCULATE BUFFER SIZE
- XRA A ;INITIATE REGISTERS
- STA ACOUNT ;SECTOR COUNT
- LDA COUNT
- MOV B,A ;SECTOR COUNT
- ;
- READ: LXI D,BUFSTART ;B HAS SECTOR CNT
- READ1: MVI C,DMA
- CALL BDOSE ;SET DMA ADDRESS
- PUSH D ;SAVE DMA ADDR.
- LXI D,FCB1
- MVI C,B$READ
- CALL BDOSE ;READ A SECTOR
- POP D ;RESTORE DMA
- CPI 1
- JZ FINISH
- CPI 0
- JNZ ERROR5 ;READ ERROR
- MOV A,E ;BUMP POINTER
- ADI 80H
- MOV E,A
- MVI A,0
- ADC D
- MOV D,A ;BY 128 BYTES
- LDA ACOUNT
- INR A
- STA ACOUNT ;SECTORS READ
- DCR B ;ADJUST COUNT
- JNZ READ1 ;NO
- CALL WRITE ;FULL, SO EMPTY IT
- XRA A ;RESET REGISTERS
- STA ACOUNT ;SECTOR COUNT
- LDA COUNT
- MOV B,A ;SECTOR COUNT
- JMP READ
- ;
- FINISH:
- MVI A,0FFH
- STA EOF ;FINISHED THIS FILE
- LDA COUNT
- SUB B
- MOV B,A
- CALL WRITE
- LXI D,FCB2
- MVI C,B$CLOSE ;CLOSE DESTINATION
- CALL BDOSE
- CPI 255
- JZ ERROR9 ;CLOSE FAILURE
- CALL RENAME ;RENAME $$$ TO TYP
- LDA WILD
- ORA A ;MORE FILES?
- JZ DONE
- LXI H,BUFSTART
- SHLD BUFPT ;RESET BUFFER POINTER
- XRA A
- STA OPEN ;RESET FILE OPEN FLAG
- STA EOF ;WON'T BE EOF ON NEXT FILE
- LXI H,FCB1 ;POINT TO INTERNAL FCBS
- MVI C,64 ;LENGTH OF 2 * FCB
- XRA A
- FCB$FILL1:
- MOV M,A ;RESET MEMORY
- INX H ;ADJUST POINTER
- DCR C ;DONE ?
- JNZ FCB$FILL1 ;NO
- LDA FUSER
- MOV E,A ;SAVE DIRECTORY POINTER TIL LATER
- MVI C,USER
- CALL BDOSE ;RESET TO SOURCE USER
- LXI D,TBUF ;RESET DMA
- MVI C,DMA
- CALL BDOSE
- LXI D,FCB
- MVI C,SRCH$1ST ;START SEARCH FOR NEXT
- CALL BDOSE ; WILDCARD MATCH (TEDIOUS)
- LDA F$COUNT ;NO FILES DONE SO FAR
- INR A ;JUST DONE ANOTHER ONE
- STA F$COUNT ;KEEP FOR NEXT TIME
- STA D$COUNT ;INITIALISE LOOP COUNTER
- SEARCH$LOOP:
- LXI D,0
- MVI C,SRCH$NXT ;SEARCH FOR NEXT WILDCARD MATCH
- CALL BDOSE
- STA DIR$POINT
- CPI 0FFH ;NO MORE MATCH ?
- JZ DONE ;YES
- LDA D$COUNT ;NO, GET LOOP COUNT
- DCR A ;ONE SEARCH DONE
- STA D$COUNT
- JNZ SEARCH$LOOP ;SEARCH AGAIN
- MVI C,DIRECT
- MVI E,0FFH
- CALL BDOSE
- CPI CNTRLC ;USER WANTS ABORT ?
- JZ U$ABORT ;YES
- LDA DIR$POINT ;NO, A = POINTER INTO DIR SECTOR
- JMP DIR$MATCH ;FOUND THE ONE WE NEEDED
- ;
- WRITE:
- LDA TUSER
- MOV E,A
- MVI C,USER
- CALL BDOSE ;SET DESTINATION USER
- LDA OPEN
- CPI 0 ;FILE ALREADY OPEN ?
- JNZ WRITE2 ;YES
- CMA ;NO
- STA OPEN ;INDICATE FILE OPEN
- LXI D,FCB2
- MVI C,B$OPEN
- CALL BDOSE ;ATTEMPT OPEN
- CPI 255
- JZ WRITE0 ;NOT PRESENT
- LDA FCB2+9 ;PRESENT, CHECK R/O
- ANI 80H ;ISOLATE BIT
- RAL ;PUT IN CARRY
- JNC NOT$RO ;NOT R/O
- LDA O$W
- ORA A ;OVER WRITE R/O FILE ?
- JNZ REMOVE$RO
- JMP ERR6A ;IS R/O
- ;
- REMOVE$RO:
- LXI H,FCB2+12 ;FCB2 HAS GROUP 'GARBAGE'
- XRA A ; FROM OPEN CALL WHICH
- MVI C,21 ; NEEDS TO BE CLEANED OUT
- CALL FILL$BLOCK ; FOR ATTRIBUTE CALL
- LXI H,FCB2
- MVI C,12
- R$RO:
- MOV A,M ;RESET ATTRIBUTES IN FILE NAME
- ANI 7FH
- MOV M,A
- INX H
- DCR C
- JNZ R$RO
- LXI D,FCB2
- MVI C,ATTRIB
- CALL BDOSE
- CPI 0FFH ;THIS SHOULD NEVER HAPPEN
- JZ ERROR11 ; BUT JUST IN CASE
- NOT$RO:
- LDA N$Q
- ORA A ;NO FILE EXISTS QUERY?
- JNZ WRITE0 ;YES
- CALL ERROR6 ;CHECK BEFORE DELETE
- CPI 'Y'
- JZ WRITE1 ;CONTINUE
- CPI 'y'
- JZ WRITE1 ;CONTINUE
- JMP ABORT ;ANSWER NOT 'Y' OR 'y'
- WRITE1:
- CALL CRLF
- WRITE0:
- LXI H,FCB2+9 ;POINT TO SECONDARY FILENAME
- LXI D,TYPE
- MVI C,3 ;LENGTH OF SECONDARY FILENAME
- MVI B,'$' ;TEMPORARY FILE TYPE MARKER
- FILL$TYPE1:
- MOV A,M ;GET SECONDARY FILE NAME
- STAX D ;SAVE IT FOR LATER
- MOV M,B ;STUFF IN TEMP MARKERS
- INX H
- INX D
- DCR C
- JNZ FILL$TYPE1
- LXI H,FCB2+12 ;ZERO FILL REST OF FCB
- MVI C,24
- XRA A
- CALL FILL$BLOCK
- LXI D,FCB2
- MVI C,MAKE
- CALL BDOSE ;CREATE DESTINATION FILE
- CPI 255
- JZ ERROR7 ;DIRECTORY FULL
- ;
- WRITE2:
- LDA ACOUNT
- ORA A ;ZERO LENGTH FILE?
- JZ ZEXIT ;YES, DONT WRITE TO DESTINATION
- MOV B,A ;ACTUAL SECTOR COUNT
- PUSH H
- LXI H,BUFSTART
- SHLD BUFPT ;SAVE BUFFER POINTER
- POP H
- WRITE3:
- PUSH H
- LHLD BUFPT ;GET BUFFER POINTER
- XCHG ;DE <---- BUFFER POINTER
- POP H
- PUSH D
- MOV A,E
- ADI 80H
- MOV E,A
- MVI A,0
- ADC D ;16 BIT ADD OF 1 SECTOR
- MOV D,A
- PUSH H
- XCHG
- SHLD BUFPT ;SAVE NEW BUFFER POINTER
- POP H
- POP D
- MVI C,DMA
- CALL BDOSE ;CHANGE DMA ADDRESS
- LXI D,FCB2
- MVI C,B$WRITE
- CALL BDOSE ;WRITE A SECTOR
- CPI 0
- JNZ ERROR8 ;WRITE ERROR
- DCR B ;DONE YET?
- JNZ WRITE3 ;NO
- ZEXIT: ;(COME IN HERE IF ZERO LENGTH FILE)
- LDA EOF
- CPI 0
- RNZ ;END
- LDA FUSER
- MOV E,A
- MVI C,USER ;SET SOURCE USER
- CALL BDOSE
- RET
- ;
- FILL$BLOCK:
- MOV M,A ;GENERAL BLOCK FILLER
- INX H ; WITH A CONSTANT
- DCR C
- JNZ FILL$BLOCK
- RET
- ;
- ;
- RENAME:
- LXI H,FCB2+9 ;START POINT
- MVI C,27 ;LENGTH TO FILL
- XRA A ;ZERO A
- CALL FILL$BLOCK
- LXI H,TYPE ;POINT TO FILE TYPE
- LXI D,FCB2+9 ;SECONDARY FILE NAME
- MVI C,3 ;LENGTH TO MOVE
- REN$LOOP1:
- MOV A,M ;STUF FILE TYPE BACK INTO FCB
- STAX D
- INX H
- INX D
- DCR C
- JNZ REN$LOOP1
- LXI D,FCB2
- MVI C,DELET
- CALL BDOSE ;KILL ORIGINAL DESTINATION FILE
- LXI H,FCB2+9
- MVI C,27
- XRA A
- CALL FILL$BLOCK ;ZERO FILL WRITE FCB YET AGAIN
- LXI H,FCB2
- LXI D,FCB2+16
- MVI C,9
- REN$LOOP2:
- MOV A,M ;COPY WRITE FCB TO MAKE THE
- STAX D ; SPECIAL RENAME FORMAT FCB
- INX H
- INX D
- DCR C
- JNZ REN$LOOP2
- MVI A,'$' ;HL = POINTER TO FCB2 +9
- MVI C,3
- REN$LOOP3:
- MOV M,A ;STUFF TEMP FILE MARKERS IN
- INX H ; THE 'FROM' PART OF FCB
- DCR C
- JNZ REN$LOOP3
- LXI H,TYPE ;DE = FCB2+9+16
- MVI C,3
- REN$LOOP4:
- MOV A,M ;STUFF FILE TYP IN THE
- STAX D ; 'TO' PART OF FCB
- INX H
- INX D
- DCR C
- JNZ REN$LOOP4
- LXI D,FCB2
- MVI C,REN ;DO THE RENAME
- CALL BDOSE
- CPI 0FFH ;AGAIN, THIS SHOULD NEVER HAPPEN
- JZ ERROR10 ; BUT.......
- RET
- ;
- ;ERROR AND MESSAGE HANDLING
- ;
- ERROR1:
- LXI D,MSG3
- CALL PRINT
- LXI D,MSG2
- CALL PRINT
- JMP ABORT
- ;
- ERROR2:
- LXI D,MSG4
- CALL PRINT
- LXI D,MSG2
- CALL PRINT
- JMP ABORT
- ;
- ERROR3:
- LXI D,MSG5
- CALL PRINT
- JMP ABORT
- ;
- ERROR4:
- LXI D,MSG6
- CALL PRINT
- JMP ABORT
- ;
- ERROR5:
- LXI D,MSG7
- CALL PRINT
- JMP ABORT
- ;
- ERROR6:
- LXI D,MSG8
- MVI C,B$PRINT
- CALL BDOSE ;PROMPT QUESTION
- MVI C,CI
- CALL BDOSE
- RET ;RETURN WITH INPUT
- ;
- ERR6A:
- LXI D,MSG8A
- CALL PRINT
- JMP ABORT
- ;
- ERROR7:
- LXI D,MSG9
- CALL PRINT
- LXI D,MSG10
- CALL PRINT
- JMP ABORT
- ;
- ERROR8:
- LXI D,MSG11
- CALL PRINT
- JMP ABORT
- ;
- ERROR9:
- LXI D,MSG12
- CALL PRINT
- JMP ABORT
- ;
- ERROR10:
- LXI D,MSG16
- CALL PRINT
- JMP ABORT
- ;
- ERROR11:
- LXI D,MSG17
- CALL PRINT
- JMP ABORT
- ;
- ;
- ;GENERAL PURPOSE SUBROUTINES
- ;
- PRINT:
- PUSH D
- CALL CRLF
- POP D
- MVI C,B$PRINT
- CALL BDOSE ;PRINT MESSAGE
- RET
- ;
- U$ABORT:
- LXI D,MSG18
- CALL PRINT
- JMP EOJ
- ;
- ABORT:
- LXI D,MSG13
- CALL PRINT
- JMP EOJ
- ;
- CRLF:
- MVI E,ACR
- MVI C,CO
- CALL BDOSE
- MVI E,ALF
- MVI C,CO
- CALL BDOSE
- RET
- ;
- DONE:
- CALL CRLF ;NORMAL EOJ MSG
- LXI D,MSG14
- MVI C,B$PRINT
- CALL BDOSE
- ;
- EOJ:
- LDA CUSER ;RESET USER
- MOV E,A
- MVI C,USER
- CALL BDOSE
- JMP WBOOT
- ;
- SHOW:
- CALL CRLF
- LXI D,MSG15
- MVI C,B$PRINT
- CALL BDOSE
- MVI D,9
- SHOW1: ;DISPLAY FILENAME IN READ FCB
- INX H
- DCR D
- JNZ SHOW2
- MVI E,'.' ;PRINT THE SEPARATOR
- MVI C,CO
- CALL BDOSE
- SHOW2:
- MOV A,M
- CPI 0
- RZ
- CPI ' ' ;SKIP BLANKS
- JZ SHOW1
- MOV E,A
- MVI C,CO
- CALL BDOSE
- JMP SHOW1
- ;
- ;
- BUFSIZ:
- LHLD BDOS+1
- LXI D,-6
- DAD D ;HL = POINTER TO BASE OF BDOS
- LXI D,BUFSTART
- ORA A ;CY=0
- MOV A,L
- SBB E ;SUBTRACT E FROM L
- MOV L,A
- MOV A,H
- SBB D ;SUBTRACT D FROM H
- MOV H,A
- SHLD SIZEB
- MVI B,7
- ORA A ;RESET CARRY
- BUFSIZ0:
- MOV A,H ;DIVIDE HL BY 128 (WHICH
- RAR ; JUST HAPPENS TO BE THE
- MOV H,A ; SIZE OF A CP/M LOGICAL
- MOV A,L ; SECTOR
- RAR
- MOV L,A
- ORA A ;RESET CARRY
- DCR B
- JNZ BUFSIZ0
- MOV A,H ;> 255 ?
- CPI 0
- JZ BUFSIZ1 ;NO
- MVI A,255 ;YES, BIGGEST BUFFER
- JMP BUFSIZ2
- ;
- BUFSIZ1:
- MOV A,L
- BUFSIZ2:
- STA COUNT ;NO SECTORS IN BUFFER
- RET
- ;
- BDOSE:
- PUSH B ;BDOS ENTRY
- PUSH D
- PUSH H
- CALL BDOS
- POP H
- POP D
- POP B
- RET
- ;
- NSCAN:
- LXI D,0 ;CLEAR WORK
- MOV A,M ;GET CHAR
- CPI '9'+1 ;IS IT A DIGIT
- JNC NSCAN2 ;> 9
- CPI '0'
- JC NSCAN2 ;< 0
- NSCAN0:
- SUI '0' ;REMOVE ASCII BIAS
- PUSH H ;SAVE PTR
- XCHG ;GET WORK IN HL
- PUSH H
- POP D
- DAD H
- DAD H
- DAD D
- DAD H ;HL=HL*10
- MVI D,0
- MOV E,A ;NEW DIGIT
- DAD D ;ADD IT IN
- XCHG ;PUT WORK BACK
- POP H ;RESTORE PTR
- INX H ;AND STEP IT
- MOV A,M
- CPI '9'+1
- JNC NSCAN1
- CPI '0'
- JC NSCAN1
- JMP NSCAN0 ;LOOP
- ;
- NSCAN1: MOV A,E ;GET NUMBER
- CPI 16 ;<= 15
- JNC NSCAN2
- ORA A ;CLEAR CY
- JMP NSCAN3
- ;
- NSCAN2:
- STC ;SET CARRY
- NSCAN3:
- RET ;EXIT HERE
- ;
- MSG1 DB 'PUT 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
- COUNT DB 0 ;BUFFER SIZE IN SECTORS
- 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
- ;
- TYPE:
- DB ' ' ;SECONDARY FILE TYPE
- ; FOR RENAME AFTER WRITE
- FCB1: ;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
- DB 0,0,0,0,0,0,0,0,0
- ;
- FCB2: ;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
- DB 0,0,0,0,0,0,0,0,0
- ;
- DS 32 ;16 LEVEL STACK
- STACK EQU $ ;SOME STACK SPACE
- ;
- BUFSTART EQU $+10 ;SOME LEEWAY
- ;
- END START
-