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
/
ZDB18C.LBR
/
ZDB18SRC.LYR
/
ZDB18.A
< prev
next >
Wrap
Text File
|
1993-03-31
|
21KB
|
1,053 lines
;;; Mods by Terry Hazen 02/04/92
;; This is ZDB18.A, part of the source code to ZDB18, a continuation of
;; ZDB18.Z80
;; 01/29/92
;;
; output routines
;
output: call clrmnu
dc 1,'F=CDF File W=WordStar File P=Print '
call qquit
call getchar
cp 'F'
jp z,dfile
cp 'W'
jp z,dfile
cp 'P'
jp nz,menu
;
poutput:ld a,(pchkf) ; check bios printer test flag
or a
jr z,prtrdy ; skip bios test
;
pout0: ld a,lstat ; bios list status
call bios ; check for printer ready
or a
jr nz,prtrdy
call clrmnu
db bel
db 1,'Printer Off Line--Check, Then Press Any Key'
dc ' (Q=Quit)',2
call getchar
cp 'Q' ; an escape route, if needed
jr nz,pout0 ; try again
jp menu ;;;
;;; ret
;
prtrdy: call clrmnu
dc 1,'L=Labels E=Envelopes '
call qquit
call getchar
ld de,prttbl
call acase3
jr prtrdy
prttbl: db 3
dw prtrdy
db 'E'
dw envel
db 'L'
dw labels
db 'Q'
dw menu
;
labels: ld a,1 ; initialize the number of copies to 1
ld (copies),a
call clrmnu
dc 1,'F=Find X=Xfind <>=Prev/Nxt P=PrintCurrent K=Key A=All'
call qquit
call getchar
ld de,lbmtbl
call acase3
jr labels
lbmtbl: db 10
dw labels
db 'Q'
dw doff
db 'P'
dw multi
db 'F'
dw find
db 'X'
dw qfind
db '.'
dw next
db '>'
dw next
db '<'
dw prev
db ','
dw prev
db 'K'
dw lblkey
db 'A'
dw fulset
;
; print entire file
;
fulset: call gotop
fullp: call ckeoi
jp c,doff ;
call rread ; read current record
call mxrptr ; increment pointers
call delrec ; check for deleted record
call nz,prlbl ; print if not deleted
jr fullp ; and repeat
;
; input for search
;
getkeyf:ld b,11 ; set length (b=11)
getkey: ld c,0 ; initialize counter
push bc ; save count from gbox
push bc ; save count from pad
call clrmnu
dc 1,'Find >',2
pop bc ; restore count for pad
call pad
pop bc ; restore count
ld hl,1807h ; set cursor to 24,7
ld (cpos),hl ; save it
call gotoxy
ld hl,srch ; point to search string buffer
call curon
ld a,on ; set caps
jp edlp0 ; get search string
; c=length of search string
;
; label output selection keys
;
lblkey: call clrmnu
dc 1,'Key: C=City S=State Z=Zip X=Cmnts1/2'
call qquit
;
keylp: call getchar
ld de,keytbl
call acase3
ld a,(keyflg)
or a
ret nz
jp labels
;
keytbl: db 5
dw keylp
db 'Q'
dw doff
db 'C'
dw keyc
db 'S'
dw keys
db 'Z'
dw keyz
db 'X'
dw keyx
;
keyc: ld hl,city
ld b,cilen
jr getinp
keys: ld hl,state
ld b,stlen
jr getinp
keyz: ld hl,zip
ld b,zilen
getinp: push hl ; save field to search
call getkey ; get input
ld b,c ; make it an exact match
jr keyok
keyx: ld hl,cmnts1 ; point to first comment line
ld b,25 ;
push hl ; save field to search
call getkey ; get input for key
ld b,c1len+c2len ; search both comment lines
;
keyok: ld (keylen),bc ; save key length
pop hl ; get back field to search
ld (prkey),hl ; save it
call gotop ; search from beginning of file
xor a
ld (fndflg),a
ld a,(keyflg) ; is this a search for CDF routine?
or a ; if so, quit here
ret nz
loopk: call ckeoi ; quit at end of index table
jr c,notfnd
call rread ; read record
call mxrptr ; increment pointers
ld hl,srch ; search string
ld de,(prkey) ; search target
push bc
call scanner ; do search
jr nz,noluck
ld a,true
ld (fndflg),a
call prlbl ; on a match, print label
noluck: pop bc
jr loopk ; repeat
notfnd: ld a,(fndflg)
or a ;
jp z,nofind ; give no find message, reset pointer to top
jp firstr
;
qquit:
call vprint
db ' Q=Quit ?',bs,2,0
ret
;
envel: call clrmnu ; find, next, print menu
dc 1,'F=Find X=Xfind <>=Prev/Nxt P=PrintCurrent'
call qquit
call getchar
ld de,envtbl
call acase3
jr envel
envtbl: db 8
dw envel
db 'F'
dw find
db 'X'
dw qfind
db '.'
dw next
db '>'
dw next
db ','
dw prev
db '<'
dw prev
db 'P'
dw prenv
db 'Q'
dw doff
;
; print envelope
;
prenv: ld a,true
ld (envflg),a
call prrta ; print return address
ld a,(addrsp) ; space down to address
ld b,a
ld a,lf
sendlfs:call lout
djnz sendlfs
call pradr
jr resetp
;
; print labels
;
prlbl: xor a
ld (envflg),a ; turn off envelope flag
dec a
ld (prtflg),a ; set print flag
ld a,(copies) ; get number of copies
or a ; if it's zero, quit
ret z
;
ld b,a ; number in b
prlbl1: call condin ; a keypress will interrupt printing
ret nz
push bc ; save number or pradr will lose it
call prrtal
call pradr
pop bc ; get number back
djnz prlbl1 ; loop until b=0
;
resetp: ld hl,reset ; fall thru to reset printer
;
; send counted string to printer
;
clpstr: ld a,(hl)
or a
ret z
ld b,a
clpst0: inc hl
ld a,(hl)
call lout
djnz clpst0
ret
;
; send 0-terminated string to printer
;
elpstr: ld a,(hl)
inc hl
or a
ret z
call lout
jr elpstr
;
lmargin:ld hl,lemarg ; point to envelope left margin string
ld a,(envflg) ; check if label, tho
or a
jr nz,margin
ld hl,llmarg ; if label, use label left margin
;
; send b spaces to printer
;
margin: ld a,(hl) ; get count
margin0:ld b,a ; in b
or a
ret z ; quit if none
ld a,' '
margl: call lout
djnz margl
ret
;
pradr: ld hl,ain ; initialize printer for address
call clpstr
call lmargin ; space over if envelope
ld hl,fieldpanel
ld b,8
;
paloop: push bc ; save field count
push hl ; save field address pointer
call lhlhl ; get field address in hl
ld a,(hl) ; skip empty fields
ld (eflag),a ; set empty flag
or a
jr z,pa00 ; empty, skip printing
;
call elpstr ; print field
ld a,' ' ; and trailing space
call lout
;
pa00: ld de,patbl ; decide about adding new line
ld a,b ; put field number in a
call acase3
pop hl ; restore field address pointer
pop bc ; restore field count
inc hl ; point to next field address
inc hl
djnz paloop
;
formfd: ld a,ff ; send formfeed
jp lout
;
; do formfeed at the end of label printing session
;
doff: ld a,(prtflg) ; if we've done any printing, do ff
or a
jr z,doffd ; no ff required
xor a
ld (prtflg),a ; reset flag
;ld a,(ffflg)
;or a
;jr z,doffr
;call formfd ; do form feed on return to menu
;doffr: call resetp
doffd: jp menu
;
; Add new line if field is not empty
;
neline: ld a,(eflag)
or a
ret z
;
; Add new line
;
nline: call lcrlf ; do new line
jp lmargin
;
nnline: ret ; skip new line
;
; special case table for new lines
;
patbl: db 5 ; number of table entries
dw neline ; default is new line if not empty
db 8 ;
dw nnline ; first name: no new line
db 7
dw nline ; last name: new line always
db 4
dw nnline ; city: no new line
db 3
dw nnline ; state: no new line
db 2
dw nline ; zip: new line always
;
; multiple copy option
;
multi: call curon
call clrmnu
dc 1,'How many copies? ',2
ld c,0
ld hl,xcopy
call cin
cp cr ;
jr nz,getnum0 ;
jr z,cpyfin0 ;
getnum:call cin
cp cr
jr z,cpyfin
getnum0:call cout
ld (hl),a
inc hl
inc c
ld a,c
cp 3 ; maximum 3 digits
jr nz,getnum
cpyfin: ld (hl),0
ld hl,xcopy
call eval10 ; convert to binary
ld (copies),a ; store it
cpyfin0:push af
call curoff
pop af
or a ;
ret z ; no copies
jp prlbl ; print labels
;
; print return address on label
;
prrtal: call resetp
ld hl,labln ; set label form length
call clpstr
ld a,(lra) ; check if return address is desired
or a
ret z ; no
jr prrta0
;
; print return address on envelope
;
prrta: ; reset printer
call resetp
prrta0: ld hl,rin ; initialize printer for return address
call clpstr
ld hl,retadr ; point to return address
jp elpstr ; and print it
;
allorkey: ; do we do whole file or select by key?
call clrmnu
dc 1,'[All]/K=Key ?',2,bs
call getchar
cp 'K' ; by key?
ret
;
findmatch: ; do search for match
ld hl,srch
ld de,(prkey)
ld bc,(keylen)
jp scanner
;
chkmem: ld hl,(order) ; get address of order table
ld de,(recs) ; get number of records
add hl,de ; add to addr of order table
inc h ; start buffer at next page boundary
ld l,0
ld (work),hl ; save as address of file buffer
ex de,hl
call gzmtop ; get top of TPA (hl=1st byte of CCP)
dec h ; safety zone of 256 bytes
jp comphd ; compare
;
; Datafile Output
;
dfile: ld (fflag),a ; save 'F' or 'W' flag
;
; initialize i/o control block
;
ld a,80h ; set 16k buffer
ld (ioctl),a
ld hl,fcb+1 ; get default datafile name
ld de,iocfc+1 ; point to io filename
ld bc,8
ldir ; move name to fcb
ld a,(fflag)
cp 'F'
jr nz,dfil0
ld hl,cdftyp ; make file type 'CDF'
jr dfil1
dfil0: ld hl,wstyp ; make file type 'WSF'
dfil1: ld bc,3
ldir
;
; Check Memory
;
call chkmem
jr c,nomem
and a
sbc hl,de ; hl=space available
ld de,4000h ; need 16K buffer
call comphd ; compare hl and de; if hl<de, carry is set
jr nc,memok
nomem:
call clrmnu
dc bel,1,'Out of Memory...Press Any Key',2
call cin
jp menu
;
memok: call allorkey
jr nz,doall ; no, jump
ld (keyflg),a
call lblkey ; get key for selection
doall: ld de,ioctl ; point to ioctl block
call fxo$open ; open file for output
call gotop ; set file pointer to beginning
call dwf ; display writing file message
ld a,(fflag)
cp 'F'
jr z,reclp
ld hl,today ; get today's date
ld de,wsdatbuf
call mdata1 ; save it in "January 1, 1991" form
ld hl,wsdatbuf
wsdatlp:ld a,(hl)
inc hl
or a
jr z,wsdat0
call fout
jr wsdatlp
wsdat0: ld a,cr
call fout
ld a,lf
call fout
ld a,lf
call fout
reclp: call ckeoi ; check for end of index
jr c,dfdone ; quit when done
call rread ; read input file
call mxrptr ; increment pointers
call delrec ; check for deleted records
jr z,reclp ; and don't write them
ld a,(keyflg) ; check for key flag
or a
jr z,reclp0 ; no, write all records
call findmatch
jr nz,reclp ; if no match, go to next record
ld a,true ; if match, set fndflg to true
ld (fndflg),a
reclp0: ld hl,fieldpanel
ld b,11 ; number of fields to process
ld a,(fflag)
cp 'W'
jr z,reclp1 ; skip over first name field
fldlp: push bc ; save number
push hl
call lhlhl
ld a,(hl)
or a ; is field empty?
jr z,efld
ld a,(fflag)
cp 'W'
jr nz,fldlp0
call wpstr
jr efld
fldlp0: call fpstr ; no, print it
efld: ld a,b ; put field count in a
dec a
jr z,fdone
ld a,(fflag)
cp 'F'
jr nz,efld0
ld a,','
call fout
efld0: pop hl
pop bc
reclp1: inc hl
inc hl
djnz fldlp
fdone: ld a,cr ; yes, append cr & lf
call fout
ld a,lf
call fout
fdone1: pop hl
pop bc
jr reclp
dfdone: ld de,ioctl
call fxo$close
ld a,(keyflg) ; was file selected by key?
or a
jr z,dfdon0 ; no, jump to end
xor a ; yes, reset flag
ld (keyflg),a
ld a,(fndflg) ; any matching records found?
cp true
jp nz,nofind ; no, display message
dfdon0: jp dotop
;
fpstr: call putquote
fpstr1: ld a,(hl)
inc hl
or a
jr z,putquote
call fout
jr fpstr1
putquote:
ld a,'"'
fout: ld de,ioctl
jp fx$put
;
wpstr: ld a,(hl)
inc hl
or a
jr z,wpstr1
call fout
jr wpstr
wpstr1: ld a,b
ld de,wstbl
call acase3
wpstr2: ret
wstbl: db 5
dw deflt
db 10
dw addfst
db 9
dw punct
db 8
dw punct
db 7
dw punct
db 1
dw wpstr2
addfst: call punct
ld hl,fstnm
addfst0:ld a,(hl)
inc hl
or a
jr z,punct
call fout
jr addfst0
punct: ld a,','
call fout
deflt: ld a,' '
jp fout
dwf: call clrmnu
dc 1,'Writing File...',2
ret
;
; support routines
;
; edloop is a fairly complete line editor, using WordStar-like
; editing commands. maximum number of characters is passed in
; b register. esc will exit at any point and take you back
; to the calling routine. ^Q aborts edit.
;
edloop: call curon
xor a
ld (capflag),a ; set cap flag to no
ld c,a ; initialize character count
ld a,b ; get count
cp 3 ; state?
jr nz,edlp1 ; no
edlp0: ld (capflag),a ; set caps flag
;
edlp1: ld a,(capflag) ; check caps flag
or a
jr z,edlp2 ; get exact input
call capin ; get caps input
jr edlp3
edlp2: call cin ; get character
edlp3: call isctrl ; is it a control character?
jr z,edcase ; yes
;
alpha: push af ; no
inc c
ld a,c ; check to see if you've reached the maximum
cp b ; number of characters
jr z,noroom
call stndout
ld a,(insflg) ; check for insert mode
or a
jr z,alpha1 ; no
;
push hl ; save string pointer
push bc ; save counter
ld a,b ; get max characters
sub c ; find number of characters to move
dec a
or a
jr z,alpha0
ld c,a
ld b,0
add hl,bc ; hl = last byte in string
ld d,h ; de points to character destination
ld e,l
dec hl ; hl points to character
lddr ; shift line right
inc hl
call vpstr ; display shifted line
alpha0: pop bc ; restore counter
pop hl ; restore string pointer
call movcur ; restore cursor
;
alpha1: pop af
ld (hl),a ; add to string
inc hl ; update string pointer
call cout ; handle alphanumeric characters normally
call stndend
call currt ; update cursor position
jr edlp1 ; get next character
;
noroom: pop af
call beep
dec c
jr edlp1
;
; parse edloop command table
;
edcase: ld de,edtbl
call acase3
jr edlp1 ; return from match routines
;
eddun: ;;;push af
;;;call curoff
;;;pop af
pop iy ; discard local return address
ret
;
edtbl: db 17 ; number of cases
dw termky ; no other match
db esc ; esc - finish add/edit
dw eddun
db ctrlw ; ^W same as esc
dw eddun
db ctrlq ; ^Q to exit without saving edit
dw eddun
db ctrle ; ^E - move to previous field
dw eddun
db cr ; cr - next field
dw eddun
db tab ; tab - next field
dw eddun
db ctrlx ; ^X - next field
dw eddun
db ctrlg ; ^G - delete character at cursor, shift
dw delchr ; rest of line left
db ctrlt ; ^T - delete word right
dw delwrt
db ctrlv ; ^V - toggle insert character mode
dw insert
db ctrly ; ^Y -- erases from cursor to end of line
dw eralin
db del ; cursor left
dw lcurs
db ctrls ; ^S - cursor left
dw lcurs ; BS - cursor left
db bs ; ^H - cursor left
dw lcurs
db ctrld ; ^D - cursor right
dw rcurs
db ctrla ; ^A - word left
dw wrdlft
db ctrlf ; ^F - word right
dw wrdrt
;
; check for terminal arrow keys
;
termky: push hl ; save pointer
ld hl,(tcap) ; get tcap address
cp (hl) ; is it up arrow?
jr nz,termky0 ; no, jump
ld a,ctrle ; yes, convert to ^E and quit
pop hl
jr eddun
termky0:inc hl ; move to next char in tcap
cp (hl) ; is it down arrow?
jr nz,termky1 ; no, try next one
pop hl ; yes, quit
jr eddun
termky1:inc hl ; move to next char in tcap
cp (hl) ; is it right arrow?
jr nz,termky2 ; now, try next one
pop hl ; yes, jump to rcurs
jr rcurs
termky2:inc hl ; move to next char in tcap
cp (hl) ; is it left arrow?
jr nz,akdun ; no, quit
pop hl ; yes, jump to lcurs
jr lcurs
akdun: pop hl ; restore pointer
ret
;
lcurs: xor a ; move cursor left
cp c ; if c=0, beep
jp z,beep ; and quit
dec c ; else decrement character count
dec hl ; move pointer
jr curlf ; decrement cursor position
;
insert: ld a,(insflg)
cpl
ld (insflg),a
or a ; set?
jr z,delins ; cancel insert msg
call gxymsg
db 01,40,1,'Ins',2,0 ; Insert message
jr movcur ; restore cursor
;
delchr: push hl ; save cursor position
push bc ; save count
call stndout
ld d,h
ld e,l ; position in de
inc hl ; point to next character
dellp: ld a,(hl) ; get next character
ldi ; move it
call cout ; display it
or a ; check for end of field
jr nz,dellp
deldun: ld a,' '
call cout ; cover last moved character
call stndend
pop bc ; restore count
pop hl ; restore cursor position and fall thru
;
movcur: push hl ; move cursor to position stored
ld hl,(cpos) ; in cpos
call gotoxy
pop hl
ret
;
delwrt: ld a,(hl) ; delete word right (^T)
cp ' ' ; if a=space, delete it and quit
jr z,delchr
or a ; quit if a=null
ret z
call delchr ; otherwise delete character and repeat
jr delwrt
;
delins: xor a ; delete insert msg and reset flag
ld (insflg),a
call gxymsg
db 01,40,1,' ',2,0
jr movcur
;
rcurs: ; cursor right
xor a ; check character at pointer (before it's
cp (hl) ; incremented). Is it null (end of string)?
jp z,beep ; yes, so beep and quit
inc c ; no, so bump character count
inc hl ; increment pointer
;
currt: push hl ; increment cursor location in cpos
ld hl,(cpos)
inc l
jr svcur
;
curlf: push hl ; decrement cursor location in cpos
ld hl,(cpos)
dec l
svcur: ld (cpos),hl
pop hl
jr movcur
;
eralin: ; erase from cursor to end of line
push bc ; save bc
ld a,b
sub a,c ; how many spaces to end of field?
ld b,a ; number of spaces to underscore
push bc ; save count
call pad
pop bc ; restore count
push hl ; save field pointer
call clean ; fill remainder of field with 0's
pop hl ; restore field pointer
pop bc
jr movcur ; restore cursor to original position
;
wrdlft: call lcurs ; move one char left
wrdlf0: xor a
cp c ; if count = 0, stop
ret z
call lcurs ; move again until space character found
ld a,' '
cp (hl) ; if char=space, move cursor right one char
jr z,rcurs ; and quit
jr wrdlf0 ; else keep going
;
wrdrt: xor a ; move cursor one word right
cp (hl) ; if char=null, quit
ret z
ld a,' '
cp (hl) ; if char=space, move cursor right one char
jr z,rcurs ; and quit
call rcurs ; else keep going
jr wrdrt
;
iniblk: ld hl,edblk ; zeroes everything in the
ld b,255 ; editing block
clean: ld (hl),0
inc hl
djnz clean
ret
;
ckeoi: ld de,(recptr) ; get current index record pointer
ld hl,(xrecptr) ; get last index record pointer
jp comphd
;
; exit from program if we don't have any non-deleted records
;
ckdel: ld hl,(first) ; first index record
ld de,10 ; offset to deleted record byte
cdloop: add hl,de ; point to deleted record byte
ld de,(order)
call comphd ; end of index without a match?
jp nc,exit ; file has all deleted records or is empty
ld a,(hl) ; get byte
cp on ; good record?
ret nz ; yes, we can continue
ld de,16 ; point to next record
jr cdloop
;
; check to see if record is deleted
;
delrec: ld hl,edblk
ld a,(hl)
inc a
ret
;
wrtinc: call setdma ; hl points to dma
ld de,fcb
call f$write ; writes one 128 byte record
jp nz,wrterr
ld a,(newflg) ; is it a new record?
or a ; if not, don't inc fptr
ret z
jr incfptr ; increment file pointer
;
rwrite: call setdma
ld hl,(fptr)
ld de,fcb
call r$write
jp nz,ermgr1
;
incfptr:ld hl,(fptr)
inc hl
ld (fptr),hl ; increment file pointer
ret
;
; read one data record (two file records)
; increment file record pointer
;
riread: call mvrptr ; increment record pointers
;
; (fptr) has record number
;
rread: ld hl,edblk
call rrdinc ; read first record
ld hl,edblk1 ; reset hl and fall through
;
; read one random record
;
rrdinc: call setdma
ld hl,(fptr)
ld de,fcb
call r$read
jp nz,ermgr1
jr incfptr ; increment file pointer
;
; display b standout spaces
;
pad: call stndout ; set standout
ld a,' ' ; character to pad
padchr equ $-1
pad0: dec b ; b has byte count on entry
;
ploop: call cout
djnz ploop
call stndend
ld a,(termf) ; check for termination character
or a
ret z
jp cout
;
; chkdrv and setua
;
chkdrv: or a ; is it default?
jr nz,gotdrv ; (no)
ld c,25 ; get default
call bdos
inc a ; a=0 changed to a=1
gotdrv: add a,40h ; make it printable
ret
;
setua: ld e,a
ld c,32
call bdos
xor a ; set a to 0
ret
;
clrmnu: call at ; clear menu line
db 24,1
call ereol
jp vprint ; display trailing menu message
;
getchar:call curon ; get keyboard input at prompt/message
call capin
push af
call curoff
pop af
ret
;
;
beep: ld a,bel ; beeps
jp cout
;
; error handlers and messages
;
nogood: call vprint
db 'Can''t open file',0
jp exit
;
noclk: call vprint
db bel,'No clock/bad clock.',cr,lf,lf
db 'Enter today''s date:',cr,lf
dc ' Month (MM): '
ld de,today+1 ; point to month
call getdat
call vprint
dc cr,lf,' Day (DD): '
inc de ; point to day
call getdat
call vprint
dc cr,lf,' Year (YY): '
dec de ; point to year
dec de
getdat: ld hl,datbuf
ld b,2
getdat0:call cin
cp 3
jp z,exit2
call cout
ld (hl),a
inc hl
djnz getdat0
ld (hl),0
dec hl
dec hl
push de
call eval10
pop de
call binbcd
ld (de),a
ret
;
;
wrterr: call errmsg
dc 'Write'
jr errend
;
ermgr1: call errmsg ; random read error handler
dc 'Read'
;
errend: call vprint
dc ' Error'
jp menu
;
errmsg: call gxymsg ; common error message
dc 22,1,bel,0
jp vprint