home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
ENTERPRS
/
CPM
/
UTILS
/
S
/
SPLIT13.LBR
/
SPLIT13.ZZ0
/
SPLIT13.Z8°
Wrap
Text File
|
2000-06-30
|
11KB
|
573 lines
; File Splitter
;
;By Guy Cousineau 1988-02-02
;
;This utility has no copyright and is
;being released to the public domain. It
;has been thouroughly tested and should
;behave as advertized. The author,
;however, will assume no responsibility
;for loss or damage resulting from the
;use of the program. The source code
;only is being released; it should
;assemble easily with any Z80 assembler.
;
;comments or suggestions?
;
; Guy Cousineau
; 1059 Hindley Street
; Ottawa Ontario
; K2B 5L9
; 613-829-6354
; Ottawa RCPM (613) 829-2530
;
;Syntax SPLIT [d:]ufn [d:]nn [/n]
;
;Drive spec optional.
;If source and destination are the same,
;swap prompts will be given unless the
;'/n' option is used to create the split
;files on the same media.
;
;files are split in 16k segments unless
;overriden by 'nn'
;
;e.g. SPLIT long.doc 20 /n
;will split long.doc in 20k segments
;on the default drive with no disk swaps
;
; Warning I
;The output files will have the same name
;except that the last 2 characters of the
;file type will have the section number
;starting at 01. For example, splitting
;LONG.DOC would yield files LONG.D01
;LONG.D02, etc. Be Sure Your Input File
;Does Not Have A Number In The Last Two
;Position.
;
; Warning Ii
;
;The utility will not work with Wordstar
;type files with high bit set on <LF>.
;
;
;Revision History:
;
; 1.0 ??-?? first release
; 1.1 ??-?? introduced the noswap option
; 1.2 92-06 fixed split bug on files over 144k
; added variable output file size
; 1.3 92-07 fixed write bug for generic CP/M
;
;System Equates
;
GETKEY EQU 1 ;Read keyboard
PRINTC EQU 2 ;Print character
PRINT EQU 9 ;Print string
RESET EQU 13 ;Log in drive for R/W
OPEN EQU 15 ;Open file
CLOSE EQU 16 ;Close file
DELETE EQU 19 ;Delete file
READ EQU 20 ;Read sequential
WRITE EQU 21 ;Write sequential
MAKE EQU 22 ;Make file
GETDSK EQU 25 ;Get current disk
SETDMA EQU 26 ;Set memory address for R/W
;
FCB EQU 5CH
FCB2 EQU 6CH
BDOS EQU 5
DMA EQU 80H
;
ORG 100H
LD (OLDSP),SP
LD SP,STACK
;
LD HL,FCB+1
LD A,(HL)
LD DE,SYNTAX
CP ' '
JP Z,QUIT ;No file given, show syntax
;
;Check For Wild Cards
;
LD BC,11
LD A,'?'
CPIR
LD DE,WILD
JP Z,QUIT
;
;Check For Invalid Type
;
LD DE,NUMERR
LD A,(FCB+11)
CP '1' ;'0' is Ok
JR C,NONUM
CP '9'+1
JP C,QUIT ;if last digit between 1 and 9
;
NONUM
XOR A
LD (FCB+12),A ;extent
LD (FCB+14),A ;S2
LD (FCB+32),A ;record count
;
LD HL,FCB ;input file
LD DE,WFCB ;store it here for write
LD BC,12
LDIR
;
LD A,(FCB2)
OR A ;if none specified then same
JR Z,SAMEDISK
LD HL,FCB
CP (HL) ;if same as source drive
JR Z,SAMEDISK
LD (WFCB),A
LD (SAMEDSK),A
XOR A
LD (SWAPFLG),A ;if different clear swap flag
JR SETDISK
;
;Check For Noswap
;
SAMEDISK
LD HL,DMA
LD C,(HL)
LD B,0
LD A,'/' ;option delimiter
CPIR
JR NZ,SETDISK
LD A,(HL)
AND 5FH
SUB 'N'
LD (SWAPFLG),A ;Will be zero only if 'n' or 'n'
;
;Set Default Drive To Actual
;Since Disk Reset Will Interfere
;
SETDISK
LD C,GETDSK
CALL BDOS
LD B,A
INC B ;adjust to drive code
LD HL,FCB
LD A,(HL)
OR A
JR NZ,SETD1
LD (HL),B
SETD1
LD HL,WFCB
LD A,(HL)
OR A
JR NZ,CHECKSIZE
LD (HL),B
;
;check for override of default split size
;
CHECKSIZE:
LD HL,FCB+17 ;byte 1 of FCB 2
LD A,(HL) ;check to see
CP ' ' ;if it is empty
JR Z,SETLAST ;then use default 16k
CP '/' ;or option character
JR Z,SETLAST ;
SUB '0' ;is it a number
JP C,BADNUM ;abort program
CP 10 ;make sure less than 10
JP NC,BADNUM
LD B,A ;save a times 1
RLCA ;2*a
RLCA ;4*a
ADD A,B ;5*a
RLCA ;10*a
LD B,A ;save in B temporarily
INC HL ;next byte
LD A,(HL) ;get it and check vailidity
SUB '0'
JP C,BADNUM
CP 10
JP NC,BADNUM
ADD A,B ;add Tens to units just retrieved
CP 33
JP NC,BADNUM ;set max to 32k
;
;now turn it into records
;
LD H,0
LD L,A
ADD HL,HL
ADD HL,HL
ADD HL,HL ;*8
LD A,L
LD (PATCH1),A
LD (PATCH2),A
LD (PATCH3),A
ADD HL,HL ;*16
ADD HL,HL ;*32
ADD HL,HL ;*64
ADD HL,HL ;*128
ADD HL,HL ;*256
ADD HL,HL ;*512
ADD HL,HL ;*1024
LD DE,BUFFER
ADD HL,DE ;get offset to end of buffer
LD (PATCH4),HL
DEC HL
DEC HL
LD (PATCH5),HL
;
;Set Last Character Of File Type To '0'
;
SETLAST
LD HL,WFCB+11 ;Last Digit Of File Type
LD B,'0'
LD (HL),B ;Set Count To 0
DEC HL
LD (HL),B
DEC HL
LD A,(HL) ;set first of fle type to '0' if blank
CP ' '
JR NZ,GO
LD (HL),B
;
GO
LD DE,START
CALL PROMPT ;in case we need a swap to start
;
;Find File And Open It
;
LD DE,FCB
LD C,OPEN
CALL BDOS
LD DE,NOFL ;error message just in case
INC A ;255+1=0 on error
JP Z,QUIT ;show error and exit
;
;Zero Record Count
;
READAGAIN
XOR A
LD (IRCNUM),A
;
LD DE,FCB
PUSH DE
;
;Set Up DMA For Read
;
LD HL,BUFFER
LD DE,(OBUFF) ;Get read-in offset
ADD HL,DE ;write in file here
CALL INCB1 ;set DMA and buffer
;
;Read Next Record Of File
;
LD B,16*8 ;read 16k at a time
PATCH1 EQU $-1
READF
POP DE ;FCB
PUSH DE
PUSH BC
LD C,READ
CALL BDOS
OR A ;=0 if good read and not EOF
JR NZ,XDISK ;get ready to write
CALL INCBUF ;increment DMA for next record
LD HL,IRCNUM
LD A,(HL) ;In record count
INC A
LD (HL),A
CALL DUMPIT ;print value in A
POP BC
DJNZ READF
;
;Prompt For Disk Change
;
XDISK
POP DE ;Clean up stack
LD A,(SWAPFLG)
OR A
JR Z,NOSWAP
LD DE,DDISK ;Swap disk message
CALL PROMPT
LD C,RESET
CALL BDOS
;
;Increment File Type
;
NOSWAP
LD HL,WFCB+11 ;Last digit of file type
LD A,(HL)
INC A
CP '9'+1
JR NZ,GOODNUMBER ;just increment last digit
DEC HL ;move to previous
INC (HL) ;bump it up
INC HL ;back to last
LD A,'0' ;make it Zero
GOODNUMBER:
LD (HL),A
XOR A
LD (ORCNUM),A ;output record count
LD (WFCB+12),A ;extent
LD (WFCB+14),A ;S2
LD (WFCB+32),A ;record number
;
;Delete File Name From Destination Disk
;
LD DE,WFCB
PUSH DE
LD C,DELETE
CALL BDOS
;
;Create New File
;
POP DE
PUSH DE
LD C,MAKE
CALL BDOS
LD DE,BADIR ;error message
INC A ;255+1=0 on error
JR Z,QUIT
;
;Find Last <LF> In File
;
LD A,(IRCNUM)
CP 16*8 ;Read a full extent?
PATCH2 EQU $-1
JP NZ,LASTWRITE
LD HL,SAFEREC ;safety buffer to read all of last extent
INC (HL) ;write one more record for each split
;
;Start At The End Of The Buffer -2 Characters
;If Either Of The Last 2 Characters Are <LF>
;We Will Get A Negative Offset Later.
;
LD HL,BUFFER+16*1024-2
PATCH5 EQU $-2
LD A,10 ;<LF>
LD BC,-1 ;Make sure we find one
CPDR
;Presume One Is Found
INC HL ;Move back to last <LF>
INC HL ;Use next character after <LF>
LD (LASTLF),HL ;Save the address
LD A,(HL)
LD (LASTC),A ;Save character
LD (HL),26 ;Write EOF
;
;Set Up DMA For Write
;
WRITE1
LD HL,BUFFER ;Write file from start of buffer
CALL INCB1 ;set DMA
;
;Start To Write File
;
WRITEF
POP DE ;FCB
PUSH DE
LD C,WRITE
CALL BDOS
LD DE,BADFL ;Write error message
OR A
JP NZ,QUIT
CALL INCBUF ;Get next DMA
LD HL,ORCNUM ;Records written
LD A,(HL)
INC A
LD (HL),A
LD B,A ;Save count in B
CALL DUMPIT
LD A,(IRCNUM) ;Amount to copy
SUB B ;Write as many as we read?
JR NZ,WRITEF ;Not done yet
;
;Close File
;
POP DE ;FCB
LD C,CLOSE
CALL BDOS
LD DE,BDCLOSE ;Error message
INC A ;255+1=0 on error
JR Z,QUIT
;
;Write Output File Name To Screen
;
LD A,32 ;Start with a space
CALL PRCHR
LD HL,WFCB+1 ;Name starts here
LD B,11 ;Length of name
FNAME1
LD A,(HL)
CALL PRCHR
INC HL
DJNZ FNAME1
;
;Check If Last Read
;
LD A,(ORCNUM)
CP 16*8 ;Did we write 16k?
PATCH3 EQU $-1
JR Z,NOTYET
LD DE,DONE
QUIT
LD C,PRINT
CALL BDOS
QUIT1
LD SP,(OLDSP)
RET
;
;bad number specification in output file size
;
BADNUM:
LD DE,BADSIZE
JR QUIT
;
;*** End Of Program ***
;
;Not Done Yet
;
NOTYET
LD DE,SDISK ;Swap disk message
LD A,(SWAPFLG)
OR A
CALL NZ,PROMPT
;
;Restore Old Character
;
LD HL,(LASTLF)
LD A,(LASTC)
LD (HL),A
;
;Move From This Byte To End Of Read Buffer
;To Beginning Of Read Buffer
;And Calculate New Offset
;
EX DE,HL ;DE=last character
LD HL,BUFFER+1024*16 ;Normal buffer end
PATCH4 EQU $-2
LD BC,(OBUFF) ;Get read offset
ADD HL,BC ;Current end of data
XOR A
SBC HL,DE ;New offset and bytes to relocate
LD (OBUFF),HL
PUSH HL
POP BC ;Bytes to move
EX DE,HL ;Start at last character
LD DE,BUFFER ;Move to here
LDIR
JP READAGAIN
;
;Get Extra Record Count For Last Write
;
LASTWRITE
LD A,(SAFEREC) ;Extra records to write
LD B,A
LD HL,ORCNUM ;Output record number=0
SAFE
DEC (HL) ;Set to -1, -2, Etc
DJNZ SAFE
JP WRITE1 ;Write out last segment
;
;
;*** Subroutines ***
;
;Print Message In DE
;Get Keypress And Abort On ^c
;
PROMPT LD C,PRINT
CALL BDOS
LD C,GETKEY
CALL BDOS ;Wait for keypress
CP 3 ;^c
JR Z,QUIT1 ;if aborted
RET
;
;Advance DMA By 1 Record
;
INCBUF LD HL,(TDMA) ;Where it was
LD DE,80H ;Add 1 record
ADD HL,DE
INCB1 LD (TDMA),HL
EX DE,HL
LD C,SETDMA
CALL BDOS
RET
;
;Display A In Hex
;
DUMPIT
PUSH AF
LD A,13 ;<CR>
CALL PRCHR
POP AF
PUSH AF
RRCA
RRCA
RRCA
RRCA ;Get high nibble
CALL DUMP
POP AF ;Get low nibble
DUMP
AND 0FH ;Mask off top bits
ADD A,'0' ;Ascii offset
CP '9'+1
JR C,PRCHR ;Not a hex digit
ADD A,7 ;Offset for A-f display
;
;Falls Through To Print Routine
;
PRCHR
PUSH BC
PUSH DE
PUSH HL
LD E,A ;Character To Print
LD C,PRINTC ;Function
CALL BDOS
POP HL
POP DE
POP BC
RET
;
;Messages
;Note Wild Message Links To Syntax
;
WILD DB 7,'No Wild Cards Allowed',13,10
SYNTAX DB 'SYNTAX: SPLIT [d:]ufn [d:]nn [/N]'
DB 13,10,'Where /N means no disk swap'
DB 13,10,'and nn is the split size (default 16K)$'
NUMERR DB 7,'No numbers allowed in last character$'
START DB 12,9,'FILE SPLITTER V1.3',13,10
DB 9,'BY Guy Cousineau',13,10,10
DB 7,'Insert source (^C ABORTS)',13,10,10,'$'
NOFL DB 13,10,'Can''t find source$'
DDISK DB 7,' Records read--insert dest',10,'$'
SDISK DB 7,' written',13,10,9,' Insert source',10,'$'
BADIR DB 13,10,'No directory space$'
BADFL DB 13,10,'Bad write$'
DONE DB 13,10,7,9,'--ALL DONE--',13,10,'$'
BDCLOSE DB 13,10,'Can''t close file$'
BADSIZE DB 13,10,'Bad split size specification'
DB 13,10,'Must be between 10 and 32$'
;
;Data Storage Area
;
SAMEDSK DB 0 ;Source and destination same
SWAPFLG DB 1 ;Print Swap message
SAFEREC DB 0 ;Number of extra records to write at end
IRCNUM DB 0 ;Input record number count
ORCNUM DB 0 ;Output record number count
OBUFF DW 0 ;Offset between read and write buffers
TDMA DS 2 ;Save DMA address here
OLDSP DS 2
LASTLF DS 2 ;Save address of last found <LF>
LASTC DS 1 ;Save last charcater at EOF
WFCB DS 33
DS 20H ;Generous stack space
STACK
BUFFER EQU $ ;Copy buffer starts here
END
;