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
/
A
/
CONCAT11.LBR
/
CONCAT11.ZZ0
/
CONCAT11.Z80
Wrap
Text File
|
2000-06-30
|
8KB
|
543 lines
;FILE CONCATENATION UTILITY V1.1
;
;Guy Cousineau
;1059 Hindley Street
;OTTAWA Canada
;K2B 5L9 Ottawa RCPM (613) 952-2289
;
;SYNTAX: CONCAT [du:]ufn=[du:]ufn1[,[du:]ufn2,[du:]ufn3...]
;
; The '=' must be supplied along with at least
; One source file name
; WARNING!! all file read abort on ^Z
; not for use on OBJECT files
;
;1990-02-03 V1.1 Fixed exit user bug
;
;1990-01-?? unnumbered First release
;
MACLIB DOSCALLS
;
MAXUSER EQU 16
MAXDSK EQU 'P'+1
;
START:
LD (OLDSP),SP
LD SP,STACK
;
LD A,(PRET)
LD (START),A ;disable GO
LD DE,HELLO
CALL PRINTS
LD C,GETDSK
CALL BDOS
LD (CDRIVE),A
LD C,SGTUSR
LD E,0FFH
CALL BDOS
LD (CUSER),A
;
LD DE,COMMAND
LD HL,DMA
LD BC,82H
LDIR ;save user command line
LD HL,COMMAND
LD A,(HL)
OR A
JR NZ,GOTINPUT
SYNERR:
LD DE,SYNTAX
JP PRTERR
;
;get destination file name
;
GOTINPUT:
INC HL
LD (NXTCHR),HL
CALL SETWRF
LD (DSTUSR),A ;save destination user
LD HL,(NXTCHR)
LD A,(HL)
CP '='
JR NZ,SYNERR
INC HL
LD A,(HL)
OR A
JR Z,SYNERR ;no second file name
LD DE,CFCB+1
LD A,(DE)
CP ' '
JR Z,SYNERR
PUSH DE ;save FCB+1
CALL SETDSTUSR
POP DE
PUSH DE ;adjust to FCB
DEC DE
CALL MAKEFILE ;destination file
POP DE ;get FCB+1 back
CALL PRINTF
LD DE,EQUAL
CALL PRINTS
JR SKIPPLUS
;
;check for source file name(s)
;
READMORE:
LD DE,PLUS
CALL PRINTS
SKIPPLUS:
CALL SETWRF ;Decode a source file
LD (SRCUSR),A
LD DE,CFCB+1
LD A,(DE)
CP ' '
JR Z,CLOSEFILE
CALL PRINTF
LD DE,CFCB
CALL CREAD
JR READMORE
CLOSEFILE:
LD DE,BACKSPACE
CALL PRINTS
XOR A
LD (CHECKPATCH),A ;Fix PUT_CHR to abort on EOF
LD BC,401H
ZFILL:
PUSH BC
LD A,EOF
CALL PUT_CHR
POP BC
DEC BC
LD A,B
OR C
JR NZ,ZFILL ;^Z to end of K
;
CLOSE1:
LD DE,DFCB
LD C,CLOSEF
CALL BDOS
INC A
JR NZ,GETBACK
LD DE,BADCLOSE
JP PRTERR
GETBACK:
LD E,0
CUSER EQU $-1
LD C,SGTUSR
CALL BDOS
LD E,0
CDRIVE EQU $-1
LD C,SETDSK
CALL BDOS
LD SP,(OLDSP)
PRET: RET
;
;********************************************************************
;*
;* SUBROUTINE AREA
;*
;********************************************************************
;
;look for a source file
;
CREAD:
LD A,0FFH
LD (IN_POS),A ;force read on first pass
CALL OPENFCB
JP Z,NFERR ;not found
COPYLOOP:
CALL GET_CHR
RET Z ;was EOF
CALL PUT_CHR
JR COPYLOOP
;
;get character from CFCB file
;
GET_CHR:
LD A,0
IN_POS EQU $-1
CP 80H
JR C,GET_CHR1 ;still in buffer
CALL SETSRCUSR
LD DE,INBUFFER
LD C,SETDMA
CALL BDOS
LD DE,CFCB
LD C,RDSEQ
CALL BDOS
OR A
JR NZ,BAD_READ
GET_CHR1:
LD HL,INBUFFER
CALL ADDAHL
INC A
LD (IN_POS),A
LD A,(HL)
CP EOF
RET
;
;write character to DFCB file
;take advantage of buffering (1K)
;
PUT_CHR:
PUSH AF ;save character
LD HL,OUTBUFFER
OUT_POS EQU $-2
PUSH HL
LD BC,OUTBUFFER+400H
OR A
SBC HL,BC
POP HL
JR C,PUT_CHR1 ;still in buffer
CALL SETDSTUSR
LD B,8
LD DE,OUTBUFFER ;start at buffer top
WRTLOOP:
PUSH BC
PUSH DE
LD C,SETDMA
CALL BDOS
LD C,WRTSEQ
LD DE,DFCB
CALL BDOS
OR A
JR NZ,BAD_WRITE
POP HL
LD DE,80H
ADD HL,DE
PUSH HL
POP DE ;new buffer
JR NOCHECK
CHECKPATCH EQU $-1
DEC HL ;check last record
LD A,(HL)
CP EOF ;have we written enough?
JP Z,CLOSE1
NOCHECK:
POP BC
DJNZ WRTLOOP
LD HL,OUTBUFFER
PUT_CHR1:
POP AF ;get out character back
LD (HL),A
INC HL
LD (OUT_POS),HL
RET
;
;assorted errors
;
BAD_READ:
LD DE,READERR
JR PRTERR
BAD_WRITE:
LD DE,WRTERR
JR PRTERR
NFERR:
LD DE,NOTFND
JR PRTERR
ERR3: LD DE,SYNMSG
JR PRTERR
;
MAKEFILE:
LD C,DELF
CALL DOS
LD C,MAKEF
CALL DOS
JR Z,ERR4
LD DE,DFCB
LD HL,CFCB
LD BC,36
LDIR ;copy FCB to dest FCB
RET
;
ERR4: LD DE,DSKERR
;
;print error message
;
PRTERR: PUSH DE
CALL CRLF
POP DE
CALL PRINTS
JP GETBACK
;
;****************************************************
;
;CHARACTER I/O ROUTINES
;
;****************************************************
;
CRLF:
LD DE,CRLFMSG
CALL PRINTS
RET
;
;print file name in DE
;
PRINTF:
PUSH BC
PUSH HL
PUSH DE
EX DE,HL
LD B,8
CALL PRINTB
LD E,'.'
LD C,CONOUT
PUSH HL
CALL BDOS
POP HL
LD B,3
CALL PRINTB
POP DE
POP HL
POP BC
RET
PRINTB:
LD C,CONOUT
PRINTB1:
LD A,(HL)
CP ' '
JR Z,SKIPSPC
LD E,A
PUSH BC
PUSH HL
CALL BDOS
POP HL
POP BC
SKIPSPC:
INC HL
DJNZ PRINTB1
RET
;
;print string in DE
;
PRINTS:
LD C,PRTSTR
CALL BDOS
RET
;
;**********************************************
;
;PARSING ROUTINES
;
;**********************************************
;
;Decode a decimal number from the command line
;On return, the number is in HL.
;
DECODE: EX DE,HL
LD HL,0
DECOD1: LD A,(DE)
CALL CHECK
LD (NXTCHR),DE
RET Z
INC DE
SUB '0' ;make binary from ascii.
JP C,ERR3
CP 10
JP NC,ERR3
LD B,H
LD C,L
ADD HL,HL ;x2
ADD HL,HL ;x4
ADD HL,BC ;x5
ADD HL,HL ;x10
CALL ADDAHL
JR DECOD1
;
ADDAHL:
PUSH BC
LD B,0
LD C,A
ADD HL,BC
POP BC
RET
;
CHECK: PUSH BC
PUSH HL
LD HL,SEPR
LD BC,9
CPIR
POP HL
POP BC
RET ;to caller
SEPR: DB 0,' =,.:;<>'
;
OPENFCB:
LD C,OPENF
;
LD DE,CFCB
DOS: PUSH DE
CALL BDOS
CP 0FFH
POP DE
RET
;
;set user number
;
SETSRCUSR:
LD A,0
SRCUSR EQU $-1
JR GETSETUC
SETDSTUSR:
LD A,0
DSTUSR EQU $-1
;
;get/set user number
;
GETSETUC: LD E,A
LD C,SGTUSR
JR DOS
;
;PARSE A FILE NAME FROM COMMAND LINE<
;
SETWRF: LD HL,(NXTCHR)
LD DE,CFCB
XOR A
LD (DE),A
LD (QMCNT),A
LD A,(CUSER)
LD (TUSER),A
CALL NONDELIM
LD B,11
JR Z,SETINC
PUSH HL
CP 'A'
JR C,SET1
CP MAXDSK
JR C,SET2
SET1: CP '0'
JR C,SET3
CP '9'+1
JR NC,SET3
SET2: INC HL
LD A,(HL)
JR SET1
SET3: POP HL
CP ':'
JR NZ,SET7
LD A,(HL)
SUB 'A'-1
JR C,SET5
LD (DE),A
INC HL
LD A,(HL)
CP ':'
JR Z,SET6
SET5: PUSH DE
CALL DECODE
LD A,L
EX DE,HL
POP DE
CP MAXUSER
JP NC,ERR3
LD (TUSER),A
SET6: INC HL
SET7: INC DE
LD B,8
CALL SETPART
LD B,3
LD A,(HL)
CP '.'
JR NZ,SET8
INC HL
CALL SETPART
JR SET9
SETINC: INC DE
SET8: CALL SPACE
SET9: LD B,4
XOR A
LD (CFCB+32),A
CALL FILL
LD (NXTCHR),HL
LD A,0
QMCNT EQU $-1
OR A ;check syntax
LD A,0
TUSER EQU $-1 ;get user just in case
RET Z
LD DE,NOWILD
JP PRTERR
;
;Check character at (DE) for legal command input. Note that the
;zero flag is set if the character is a delimiter.
;
SETPART: LD A,(HL)
CALL CHECK
JR Z,SPACE
CP '*'
JR NZ,SETPT1
LD A,'?'
DEC HL
SETPT1: CP '?'
JR NZ,SETPT2
PUSH HL
LD HL,QMCNT
INC (HL)
POP HL
SETPT2: LD (DE),A
INC DE
INC HL
DJNZ SETPART
LD A,(HL)
CP '*'
RET NZ
INC HL
RET
SPACE: LD A,' '
FILL: LD (DE),A
INC DE
DJNZ FILL
RET
NONDELIM: LD HL,0
NXTCHR EQU $-2
NONDL1: LD A,(HL)
OR A
RET Z
CALL CHECK
RET NZ
INC HL
JR NONDL1
;
;********************************************************************
;*
;* STACK AND DATA AREA
;*
;********************************************************************
;
HELLO: DB LF,'File Concatenation Utility V1.0',CR,LF
DB ' By Guy Cousineau',CR,LF,LF,'$'
SYNTAX: DB 'SYNTAX: concat [du:]ufn=[du:]ufn1,[[du:]ufn2,[du:]ufn3,...'
DB CR,LF,'where the first file name is the destination file'
DB CR,LF,'and all other names are source files',CR,LF,'$'
DSKERR: DB 'I/O Error$'
SYNMSG: DB 'Bad Syntax$'
NOWILD: DB 'No Wild Cards Allowed$'
NOTFND: DB 'File Not Found$'
READERR: DB 'Bad File Read$'
WRTERR: DB 'Bad File Write$'
BADCLOSE: DB 'Cannot Close Target$'
BACKSPACE: DB BS,BS,BS,' $'
CRLFMSG: DB CR,LF,'$'
EQUAL: DB ' = $'
PLUS: DB ' + $'
COMMAND DS 82H ;copy command buffer here
;
;FCB for source files
;
CFCB: DB 0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0,0,0
;
;FCB for destination file
;
DFCB: DB 0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0,0,0,0,0,0,0,0,0,0
;
OLDSP: DS 2
DS 100H
STACK:
INBUFFER: DS 80H
OUTBUFFER: DS 400H
END