home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-12 | 25.8 KB | 1,128 lines |
- ;;; Mods by Al Hawley/Terry Hazen 02/05/92
-
- ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; * *
- ; * ZDB *
- ; * *
- ; * The Z-System Database *
- ; * Name/Address File Manager *
- ; * *
- ; * (C) 1990, 1991 by Joseph I. Mortensen *
- ; * *
- ; * *
- ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;
- ;
- ; Original Author: Joseph I. Mortensen
- ; 4214 Chelsea Ct.
- ; Midland, MI
- ; 517-835-6923
- ; Compuserve 70037,3161
- ; GEnie J.MORTENSEN3
- ; Ladera Z-Node
- ;
- ; Major Collaborator
- ; and Co-Author: Terry Hazen
- ;
- ; Assembler/Linker: ZMAC/ZML or Z80ASM/SLRNKP
- ;
- ; For documentation see ZDBxx.HLP
- ;
- vers equ 18 ; version
- suffix equ 'C' ; suffix character or ' ' if none
- month equ 04 ; revision month
- day equ 12 ; day
- year equ 92 ; year
- ;
- ; the usual equates
- ;
- ctrla equ 'A'-40h ; move cursor one word left
- ctrld equ 'D'-40h ; move cursor right
- ctrle equ 'E'-40h ; move cursor up one field
- ctrlf equ 'F'-40h ; move cursor one word right
- ctrlg equ 'G'-40h ; delete character
- ctrlq equ 'Q'-40h ; quit add/edit without saving changes
- ctrlr equ 'R'-40h ; refresh screen
- ctrls equ 'S'-40h ; move cursor left
- ctrlt equ 'T'-40h ; delete word right
- ctrlv equ 'V'-40h ; insert character mode
- ctrlw equ 'W'-40h ; quit add/edit and save changes
- ctrlx equ 'X'-40h ; move cursor down one field
- ctrly equ 'Y'-40h ; delete from cursor to end of field
- ;
- bdos equ 05h
- bel equ 07h
- bs equ 08h
- tab equ 09h
- lf equ 0ah
- ff equ 0ch
- cr equ 0dh
- esc equ 1bh
- del equ 7fh
- fcb equ 5ch
- false equ 00h
- true equ 0ffh
- on equ true
- lstat equ 15
- ;
- ; jthlib routines
- .request jthlib
- ext fnamz
- ;
- ; zplib routines
- .request zplib
- ext vprint,vpstr,gxymsg,gotoxy
- ;
- ; zslib routines
- .request zslib
- ext mdata1,binbcd
- ;
- ; dslip routines
- .request dslib
- ext timini,rclock
- ;
- ; vlib routines
- .request vlib
- ext stndout,stndend,at ;,gxymsg,vprint,vpstr
- ext cls,ereol,gz3init,@ghl ;gotoxy
- ext tinit,dinit,@goxy,curon,curoff,grxon,grxoff
-
- ;
- ; z3lib routines
- .request z3lib
- ext zsyschk,gzmtop,waitp1s
- ;
- ; syslib routines
- .request syslib
- ext fxo$open,fxo$close,fx$put
- ext f$make,f$open,f$close,f$write,getfs
- ext f$exist,r$write,r$read,setdma,mfn2,f$rename,f$delete
- ext codend,condin,logud,bios ; fname,
- ext isctrl,compb,acase3,ssbini,sort
- ext capin,cin,cout,pa2hc,phldc,phlfdc,mafdc
- ext lout,lcrlf,comphd,eval10,pout
- ;
- ; Program begins here
- ;
- jp start
- db 'Z3ENV' ; standard z3 header
- db 1 ; type 1 program
- z3addr: dw 0
- ;
- ; Bios printer ready check flag. Normally set to on (0ffh) to call the
- ; bios list status routine to check for printer ready. If your system
- ; hangs on a call to the bios list status routine, set this flag to 0:
- ;
- pchkf: db on ; set to 0 to skip bios printer check
- ;
- ; Character used to terminate data fields
- ;
- termf: db '<' ; char to terminate fields, 00h if none
- ;
- ; Default implied CFG filename at 010Dh for use with ZCFNG (8 characters):
- ;
- db 'ZDB',vers/10+ '0',vers mod 10 + '0'
- db suffix
- db ' '
- db 0 ; termination
- ;
- ; Default data file name (16 characters - fill unused positions with
- ; spaces):
- ; 'duu:filename.typ'
- deffn: db 'ZDB.DTA ' ; default data file name
- db 0 ; termination
- ;
- ;; Formfeed Flag -- set to zero for no form feed at end of label printing
- ;; session
- ;;ffflg: db on ; eliminated in V. 1.8
- ;
- ; Spare configuration patch space
- ;
- ds 2 ; spare configuration patch bytes
- ;
- ; Printer string patches go here. Each string must have a length byte.
- ; Extra space is provided for longer printer codes. To eliminate any
- ; of these strings, make the first byte 0. The following are epson
- ; fx-85 compatible codes.
- ;
- ; Printer reset string, sent at start and end of each label/envelope
- ; printing session (4 characters maximum):
- ;
- reset: db 2 ; length byte
- db esc,'@' ; printer reset string
- ds 2 ; extra space
- ;
- ; Set printer for printing return address. This string is sent to the
- ; printer after it is reset each time the return address is printed
- ; (12 characters maximum):
- ;
- rin: db 7
- db 0fh ; set condensed print
- db esc,'x',1 ; set nlq mode
- db esc,'p',1 ; set proportional print
- ds 5 ; extra space
- ;
- ; Set printer for printing main address. Cancel any return address
- ; settings that may require it. Do NOT use reset, as it will cancel
- ; the label form length (12 characters maximum):
- ;
- ain: db 9
- db 12h ; cancel condensed print
- db esc,'E' ; set emphasized print
- db esc,'x',1 ; set nlq mode
- db esc,'p',1 ; set proportional print
- ds 3 ; extra space
- ;
- ; Set column for envelope address left margin:
- ;
- lemarg: db 40 ; start address at column 40
- ;
- ; Set column for label address left margin:
- ;
- llmarg: db 0 ; 0 for flush left
- ;
- ; Use return address in label (only if labels are large enough):
- ;
- lra: db 0 ; 0 if no return address is desired
- ;
- ; Set number of lines per label (8 characters maximum):
- ;
- labln: db 3
- db esc,'C',6 ; set lines per label
- ds 5 ; extra space
- ;
- ; Return address patch goes here. Space is provided for up to 80
- ; characters. If you plan on using a return address on your labels,
- ; add enough line feeds at the end of the return address to bring
- ; you to the first line of the label address. The rest of the
- ; line feeds required for an envelope are at 'addrsp'. For
- ; normal business size envelopes, the total number of line feeds
- ; must remain 14 and the string must be 0-terminated. To
- ; eliminate the return address, change retadr to a terminating
- ; null (00h) and put 14 line feeds at 'addrsp'.
- ;
- retadr:
- line1: db 'Joseph I. Mortensen'
- db cr,lf
- line2: db '4214 Chelsea Ct.'
- db cr,lf
- line3: db 'Midland, MI 48640'
- db cr,lf,lf
- ;
- ; Pad the remainder of the address space with 0's
- ;
- rept 80-($-retadr)
- db 0
- endm
- ;
- ; Space from return address to address. For normal business
- ; envelopes, the total number of line feeds in the return address
- ; and addrsp should be 14. If the number of line feeds in the
- ; return address -> first label address line is the normal three
- ; lines, addrsp should be set to 10 line feeds.
- ;
- addrsp: db 10
- ;
- ; command line help message
- ;
- hlpmsg: call vprint
- db 'ZDB vers ',vers/10+ '0','.',vers mod 10 + '0'
- db suffix
- db ' Name/Addr Database'
- db cr,lf
- db ' Syntax: ZDB [[dir:]datafile.typ] ',cr,lf
- dc ' Default datafile: '
- ld hl,deffn ; display default filename
- call vpstr
- call vprint
- dc cr,lf
- jp exit2
- ;
- ; program starts here
- ;
- start: ld (stack),sp
- ld sp,stack ; set up internal stack
- ;
- xor a
- ld hl,data ; initialize data area
- ld de,data+1
- ld (hl),a
- ld bc,datalen
- ldir
- ;
- ld hl,(z3addr) ; check for z3 system
- call zsyschk
- jp nz,exit2 ; not present, exit
- call gz3init ; initialize vlib stuff
- ld de,90h ; add TCAP offset from env
- add hl,de ; and
- ld (tcap),hl ; store it for use by edloop
- call tinit ; initialize terminal
- ;
- ld a,(fcb+1) ; check command tail
- cp '/' ; asking for help?
- jp z,hlpmsg ; yes, print help message
- call gettim ; get the time
- jr z,clkok ; if ok, jump
- nclk: call noclk ; otherwise get date from manual entry
- clkok: ld a,(fcb) ; get drive
- call chkdrv
- ld (fdrv),a ; store it
- ld (datafil),a ; and in header
- ;
- ld a,(fcb+13) ; get user for file
- ld (fusr),a ; store it
- ;
- ; if no data file specified, use default datafile name
- ;
- ld a,(fcb+1) ; check first filename character
- cp ' '
- jr nz,reopen ; filename specified
- ld de,fcb ; no filename, use default
- ld hl,deffn
- call fnamz ; parse filename to fcb
- jr clkok ;;;aeh
- ;
- ; after writing a new sorted file, program loops to reopen
- ;
- reopen: ld a,(fusr) ; set user area for file
- call setua
- ld (fcb+12),a ; set extent to 0
- ld (fcb+32),a ; likewise w/ current record
- ld a,(fdrv)
- sub a,41h
- ld b,a
- ld a,(fusr)
- ld c,a
- call logud
- ld de,datafil+1 ; save user in header
- call mafdc
- ex de,hl
- ld a,':'
- ld (hl),a ; store colon
- inc hl
- push hl ; save header pointer
- ;
- ; open file
- ;
- ld de,fcb
- call f$exist ; check to see if it exists
- jr nz,open
- call f$make ; if not, create and open it
- inc a
- jp z,nogood
- open: call f$open
- jp nz,nogood
- ld de,fcb+1 ; save original name in buffer
- ld hl,nambuf
- call mfn2
- pop hl ; restore header pointer
- call mfn2 ; save filename
- ;
- ld de,fcb
- call getfs ; get file size in records
- ld (recs),hl
- call frame ; do frame and screen layout
- call index ; create index
- ;
- ld hl,(recs) ; save it
- ld a,h ; check for empty file
- or l
- jr nz,dotop ; not empty
- ;
- doadd: call curtim ; display time and date
- ld a,'A' ; empty file, so adding new record
- jr menua ; is the only choice!
- ;
- dotop: call firstr ; display first record and wait for cmd
- ;
- menu: call clrmnu ; main menu line
- db 1,'A=Add C=Call D=Del E=Ed F=Find X=Xfind <>=Prv/Nxt '
- dc 'O=Outp I=Idx ^S=Sort'
- call qquit
- ;
- ; main program loop
- ;
- main: call curtim ; display current time & date
- call at
- db 24,79 ; position cursor at '?' in menu line
- call getchar ; wait for command
- menua: ld de,cmdtbl ; run command thro' command table
- call acase3
- jr main
- ;
- ; end of main loop
- ;
- ;
- ; command table
- ;
- cmdtbl: db 18 ; no. of entries in command table
- dw menu
- db 'Q'
- dw exit
- db esc
- dw exit
- db 'A'
- dw new
- db 'E'
- dw edit
- db 'D'
- dw delete
- db 'F'
- dw find
- db ','
- dw prev
- db '<'
- dw prev
- db '.'
- dw next
- db '>'
- dw next
- db 'O'
- dw output
- db ctrlr ; ^r to refresh screen if it gets out of whack
- dw refscr
- db ctrls ; ^s for sort
- dw asksrt
- db 'I'
- dw settyp
- db 'T'
- dw firstr
- db 'X'
- dw qfind
- db 'B'
- dw last
- db 'C'
- dw dial
- ;
- ; exit routines
- ;
- exit: ld de,fcb
- call f$close
- call curon
- call dinit
- exit2: ld sp,(stack)
- ret
- ;
- ; main subroutines
- ;
- ; screen display routines
- ;
- frame: call curoff ; turn off cursor
- call cls ; clear screen
- call at ; do standout header
- db 1,1
- ld b,66 ; do standout bar
- call pad
- call at
- db 2,1
- call grxon
- ld b,79
- ld a,(@ghl)
- frloop: call cout
- djnz frloop
- call at
- db 23,1
- ld b,79
- frlp0: call cout
- djnz frlp0
- call grxoff
- ;
- ld hl,panel
- ld b,(hl) ; enter with hl=panel pointer
- inc hl
- ;
- scrnloop:
- call @goxy
- call vpstr
- djnz scrnloop
- ret
- ;
- refscr: call frame ; refreshes entire screen
- call currec
- jp menu
- ;
- ; display current record number and total
- ;
- bldisp:
- currec: ld hl,(recptr)
- call lhlhl ; get record number of current record
- call divhl2 ; divide by 2
- inc hl ; make it rel 1
- currec0:call gxymsg
- db 1,45,1,0
- call phldc
- call vprint
- dc ' of '
- ld hl,(recs) ; get total number of records
- call divhl2 ; divide by 2
- call phlfdc
- call vprint ; terminate field and end standout
- dc ' ',2
- call clrdis ; and fall through to displa
- ;
- ; display current record
- ;
- displa: ld hl,pospanel ; point to cursor position panel
- ld de,fieldpanel ; point to field panel
- ld b,(hl)
- inc hl
- displaloop:
- call @goxy ; position cursor to field start
- inc hl ; point to next field
- call stndout
- ex de,hl ; hl=field address
- push hl ; save field address pointer
- call lhlhl ; get field addr in hl
- call vpstr ; display field
- call stndend
- pop hl
- inc hl ; point to next field
- inc hl
- ex de,hl
- djnz displaloop
- ;
- newdat: call gxymsg ; displays date
- db 3,66,1,0 ; date location
- ld hl,datmod+1 ; get month
- call paslsh
- inc hl ; get day
- call paslsh
- dec hl
- dec hl ; get year
- ld a,(hl)
- call pa2hc
- jp stndend
- ;
- divhl2: srl h ; divide hl by 2, result in hl
- rr l
- ret
- ;
- curtim: call gxymsg ; displays current date and time
- db 1,63,1,0
- ld hl,today+1
- call paslsh
- inc hl
- call paslsh
- dec hl
- dec hl
- ld a,(hl)
- call pa2hc
- call gettim
- jr nz,notime
- ld a,' '
- call cout
- inc hl
- inc hl
- inc hl
- ld a,(hl)
- call pa2hc
- ld a,':'
- call cout
- inc hl
- ld a,(hl)
- call pa2hc
- notime: jp stndend
- ;
- gettim: call timini ; see if there is a clock
- jr nz,clkfnd
- inc a
- ret
- clkfnd: push hl
- ld hl,today ; point to clock buffer
- call rclock
- pop hl
- ret
- ;
- paslsh: ld a,(hl)
- call pa2hc ; print date with slash
- ld a,'/'
- jp cout
- ;
- ; fill record display fields with blanks
- ;
- clrdis: ld hl,pospanel ; point to cursor position panel
- ld b,(hl)
- inc hl
- clrloop:
- call @goxy ; position cursor to field start
- push bc ; save count
- ld b,(hl) ; get field length
- call pad ; pad field with blanks
- pop bc ; restore count
- inc hl ; point to next field
- djnz clrloop
- ret
- ;
- ;
- ; routines for adding, editing, and deleting records
- ;
- edit: xor a ; edit existing data record
- ld (newflg),a
- call decfptr
- call edita
- jp wrecs ; write data record and resort index
- ;
- new: ; adding a new record
- call chkmem ; check to see if enough memory left
- jp c,nomem ; out of memory, jump to out of memory message
- call clrdis ; ok, continue
- call iniblk ; initialize edblk
- ld a,true ; set "new" flag
- ld (newflg),a
- ;
- edita: ld hl,today ; get date from "today"
- ld de,datmod ; and move to datmod
- ld bc,3
- ldir
- call newdat ; get the date and display it
- call clrmnu
- db 1,'^X/TAB/RET=nxt fld ^E=prv fld ^S/^D=char l/r'
- dc ' ^Y=era cursor rt ESC=exit',2
- ;
- edfields:
- ld hl,pospanel ; point to cursor position panel
- ld de,fieldpanel ; point to field address panel
- ld b,(hl) ; number of fields
- inc hl
- ;
- efloop: ld a,(hl) ; save row position
- ld (lpos),a
- call @goxy ; position cursor
- push bc ; save count
- ld b,(hl) ; get field length
- dec hl ; save column position
- ld a,(hl)
- ld (cpos),a
- inc hl ; point to next field
- inc hl
- ex de,hl ; hl=field address
- push hl
- call lhlhl ; get field pointer in hl
- push de
- call edloop ; edit field
- pop de
- pop hl
- inc hl ; point to next field address
- inc hl
- ex de,hl ; hl=next field cursor position
- pop bc
- cp esc ; quit edloop?
- jr z,term ; yes, go to end
- cp ctrlw ; ^W same as esc
- jr z,term
- cp ctrlq ; ^Q to quit without saving edit
- jr z,term
- cp ctrle ; if ^e, go to previous field
- jr z,prevf
- djnz efloop ; else do next field
- jr term ; done
- ;
- prevf: or a ; clear carry
- push bc ; save count
- ld bc,6 ; back up to previous field cursor pos
- sbc hl,bc
- ex de,hl
- ld bc,4 ; back up to previous field
- sbc hl,bc
- ex de,hl
- pop bc ; restore count
- inc b ; back up one field
- ld a,(pospanel) ; get number of fields
- cp b ; test for first field
- jr nc,efloop ; loop or fall thru if past first field
- ;
- term: push af
- call delins ; delete insert msg
- pop af
- cp ctrlq ; exit without saving?
- jr nz,term1
- ;
- ld a,(newflg) ; editing an existing record?
- or a
- jr nz,xadd ; add abort
- pop hl ; if edit abort, discard return address
- jr xedit
- xadd: call ckdel ; quit if no non-deleted records
- call decfptr ; if add abort, back up one
- xedit: call current ; redisplay current record
- jp menu
- ;
- term1:
- call clrmnu
- dc 1,'TAB=restart/[SAVE] ?',2,bs
- call cin
- cp tab
- jp z,edita
- call curoff ;;;jth
- ld a,(newflg) ; editing an existing record?
- or a
- ret z ; yes, we're done here
- ;
- ld hl,(recs) ; get number of index records
- ld (xfptr),hl ; save it for updinx and to
- ld (fptr),hl ; keep track of appended records
- ld hl,(n)
- ld (count),hl ; save number of index records
- call rwrtblk
-
- call updinx ; add new key to index table
- call inxsrt ; rebuild order table and sort index
- ld hl,(recs) ; increment record count
- inc hl
- inc hl
- ld (recs),hl
- ;
- call clrmnu
- dc 1,'Add another record? [Y]/n ?',2,bs
- call getchar
- cp 'N'
- jp nz,new
- ;
- ; since the index may have been resorted and we only know the
- ; current fptr, we need to find the corresponding recptr to properly
- ; redisplay the current record at its new location in the index
- ;
- getrp: call decfptr ; back up one
- getrp0: ld hl,(first) ; start of index
- ld de,14 ; record number offset
- ;
- recplp: add hl,de ; hl=recptr
- push hl ; save recptr
- call lhlhl ; hl=fptr for index record
- ld de,(fptr) ; de=fptr
- call comphd ; does this record have the right fptr?
- pop hl ; restore recptr
- ld de,16 ; offset to next
- jr nz,recplp ; not this index record, check next
- ld (recptr),hl ; save record pointer
- call current ; display record
- jp menu
- ;
- ; write 256 bytes to random record
- ;
- rwrtblk:ld hl,edblk
- call rwrite ; write new record
- ld hl,edblk1
- jp rwrite
-
- ; delete record
- ;
- delete:
- call clrmnu
- dc bel,1,'Are you sure? y/[N] ?',2,bs
- call getchar
- cp 'Y'
- jp nz,menu
- ;
- ld a,'D'
- ld (newflg),a
- call iniblk ; fill current record w/ nulls
- ld hl,edblk
- ld (hl),on ; make first byte 0ffh
- call decfptr ; decrement file record
- ;
- wrecs: call rwrtblk ; write 256 bytes to file
- ld hl,(recptr) ; get record pointer
- ld de,14
- sbc hl,de ; back up to index pointer
- ex de,hl ; pointer in de for movkey
- call movkey ; update index key
- ld de,ssb
- call sort ; sort index
- ;
- ld a,(newflg) ; deleting a record?
- cp 'D'
- jp nz,getrp ; exit from edit, so get record pointer
- call ckdel ; quit if no non-deleted records
- call next
- jp menu
- ;
- ; file movement routines
- ;
- ; find and display next record
- ;
- next: call ckeoi ; check for end of index
- jr nz,oknxt ; not eoi
- ;
- firstr: call gotop ; set pointer to beginning of file
- current:call rread ; read current record
- jr ckrec
- ;
- oknxt: call riread ; increment pointers, read next record
- ckrec: call delrec ; check for deleted record
- jp nz,bldisp ; ok, display it
- jr next ; deleted, so get next record
- ;
- ; move to and display last record
- ;
- last: ld hl,(xrecptr) ; get last index record pointer in hl
- call savptr
- jr current
- ;
- ; move to and display previous record
- ;
- prev: call backup ; move pointer back
- call rread ; read a record
- ld hl,edblk ; check first byte to see if it's a
- ld a,(hl) ; valid record. 0ffh = deleted record.
- inc a
- jr z,prev ; if deleted, try the previous one
- jp bldisp
- ;
- ; get first index record number
- ;
- gotop: ld hl,(first) ; get start of index table
- getpt0: ld de,14 ; offset to record number
- getptr: add hl,de
- savptr: ld (recptr),hl ; save record pointer
- call lhlhl
- ld (fptr),hl ; save record number
- ret
- ;
- ; back up to previous record
- ;
- backup: ld hl,(recptr) ; get current index record
- or a ; clear carry
- ld de,16 ; back up one index record
- sbc hl,de ; get new record pointer
- ld de,(first) ; check if past first
- call comphd
- jr nc,savit
- ld hl,(xrecptr) ; point to last record pointer
- savit: jr savptr ; save pointers
- ;
- ; Increment record pointers
- ;
- mvrptr: call ckeoi ; check for end of index table
- jr z,gotop ; yes, start over
- ;
- mxrptr: ld hl,(recptr) ; get index record pointer
- ld de,16 ; point to next
- jr getptr
- ;
- ; get contents of hl in hl
- ;
- lhlhl: ld a,(hl) ; get record number
- inc hl
- ld h,(hl)
- ld l,a
- ret
- ;
- ; decrement record pointer
- ;
- decfptr:ld hl,(fptr)
- dec hl
- dec hl
- ld (fptr),hl
- ret
- ;
- ; search routines. uses a revised 'scanner' from syslib which eliminates
- ; case sensitivity. QFIND uses an index in RAM to find file pointers for
- ; last names or zip codes, depending on which index is selected. FIND
- ; runs through the file, top to bottom, to do its search.
- ;
- scanner:
- ; main loop
- ;
- scan: ld a,b ; done if b<c
- cp c ; done?
- ret c
- ;
- ; scan hl for de for c bytes
- ;
- push bc ; save registers
- push de
- push hl
- ;
- scanl: ld a,(de) ; get field byte
- cp 'a' ; capitalize if necessary
- jr c,scanx
- cp 'z'+1
- jr nc,scanx
- and 05fh
-
- scanx: cp (hl) ; compare with search string character
- jp nz,nexthl ; no match
- ;
- scan2: inc de ; pt to next
- inc hl
- dec c ; count down
- jp nz,scanl
- ;
- ; match
- ;
- pop hl ; restore registers
- pop de
- pop bc ; old bc
- ret ; zero flag is set
- ;
- ; not found yet
- ;
- nexthl: pop hl ; restore registers
- pop de
- pop bc ; get count
- inc de ; point to next in scanned vector
- djnz scan ; continue scanning
- ;
- ; no match!
- ;
- not$found:
- or 0ffh
- ret
- ;
- keeplk:
- call clrmnu
- dc 1,'Continue search? y/[N] ?',2,bs
- call getchar
- cp 'Y'
- ret z
- cp 'C' ; also allow C for continue
- ret
- ;
- ; Express search routine
- ;
- qfind: call getkeyf
- ld hl,(first) ; point to index base address
- ld (inxptr),hl ; store in index pointer
- ld de,(count) ; get count
- dec de ; subtract one
- ld (xcount),de ; save it
- ;
- qloop:
- push bc ; save c=length of search string
- ld b,14 ; b=length of index key first/last names
- ld de,srch ; get search string
- push hl ; save index pointer
- ex de,hl
- call scanner ; scan the target
- pop hl ; restore index pointer
- jr nz,nomatch ; jump if no match
- call getpt0 ; get file pointer
- call rread ; read the record
- call bldisp ; display it
- call keeplk ; keep looking?
- jr z,nomatch
- pop bc
- jp menu
- ;
- nomatch:pop bc
- ld de,(xcount) ; get count of records
- ld a,d
- or e ; zero? quit if xcount = 0
- jr z,nofind ; no, go again
- ;
- dec de
- ld (xcount),de ; decrement record count
- ld hl,(inxptr) ; increment index pointer
- ld de,16
- add hl,de
- ld (inxptr),hl ; save new pointer
- jr qloop
- ;
- ; scans the entire record for a match
- ;
- find: call getkeyf
- ld hl,0 ; set to top of file
- ld (fptr),hl
- ;
- rloop: ; check for end of file
- ld hl,(recs)
- ld de,(fptr)
- call comphd
- jr nz,okgo
- ;
- nofind: call clrmnu
- dc bel,1,'Not Found....Press Any Key',2
- call cin
- call firstr
- jp menu
- ;
- okgo: call rread ; b=no. of bytes to search
- push bc
- ld b,253 ; c=length of target
- ld hl,srch ; hl points to search string
- ld de,edblk ; de points to target
- call scanner ; scanner does the job
- jr nz,lloop ; z=match
- ld hl,(fptr) ; get file pointer
- call divhl2 ; divide by 2
- call currec0 ; display record
- call keeplk ; continue search?
- jr nz,loopnd ; no, quit
- lloop: pop bc ; yes, go on
- jr rloop
- ;
- loopnd: pop bc
- jp getrp
- ;
- ; sort routines
- ;
- ; set index type ; do index type as toggle function
- ;
- settyp: ld a,(srttyp) ; get original type
- or a ; is it null (name)?
- cpl ; toggle it
- ld (srttyp),a ; Save new type
- ld hl,lntyp ; name index msg
- jr nz,set0 ; zip, make name
- ld hl,ziptyp ; zip index msg
- set0: ld de,inxtyp ; move index type to header message
- ld bc,9
- ldir
- ld hl,inxmsg ; point to index message
- call @goxy ; position cursor
- call vpstr ; display message
- call index ; do new index
- jp firstr ; and display new first record
- ;
- ; create index
- ;
- index: call codend ; get end of code
- ld (order),hl ; save in ssb as start of order table
- ld (first),hl ; and as address of first record
- ld hl,0 ; start with first file record
- ld (fptr),hl
- ld (count),hl ; zero the counter
- ;
- inxlp: ld hl,(recs) ; get number of records
- ld de,(fptr) ; check for end of file
- call comphd
- jr z,inxsrt ; we're done, so sort index
- ;
- ex de,hl
- ld (xfptr),hl ; save it as last record
- call rread ; read next record and increment pointer
- call updinx ; update index
- jr inxlp ; repeat until done
- ;
- ; Add new record to index table
- ;
- updinx: ld de,(order) ; point to end of index table
- call movkey ; add key
- ld (xrecptr),de ; save last record number pointer
- ld hl,xfptr
- ld bc,2 ; move record number to index
- ldir
- ld (order),de ; save start of next index entry
- ;
- inccnt: ld hl,(count) ; bump counter
- inc hl
- ld (count),hl
- ret
- ;
- ; create sorted index
- ;
- inxsrt: ld hl,(count) ; get count
- ld (n),hl ; store in ssb as total
- ld hl,(order) ; pointer to end of index table
- ld de,ssb ; pointer to ssb
- call ssbini ; create order table
- jp sort ; sort index
- ;
- ; Add new key to index table.
- ; On entry, de points to start of next index entry
- ;
- movkey: ld a,(srttyp) ; check index type
- or a ; zip?
- jr nz,movzip ; yes
- ;
- ld hl,lname ; de automatically increments in hmovb
- ld bc,9 ; index on first 9 bytes of lname
- ldir
- ld hl,fstnm
- mov5: ld bc,5 ; then on first 5 bytes of fstnm
- ldir
- ret
- ;
- movzip: ld hl,zip
- ld bc,9 ; index on 9 zip bytes
- ldir
- ld hl,lname ; then on first 5 bytes of last name
- jr mov5
- ;
- ; Ask if we want to write sorted file
- ;
- asksrt:
- call clrmnu
- dc 1,'Write Sorted File? y/[N] ?',2,bs
- call getchar
- cp 'Y'
- jp nz,menu
- call dwf ; display writing file message
- ld hl,srtfnm ; get sort file name into its fcb
- ld de,srtfcb
- call fnamz ;fname
- ld a,(fusr) ; get user for file
- ld (sfusr),a ; store it
- ld a,(srtfcb) ; get drive
- call chkdrv
- ld (sfdrv),a ; store it
- ld a,(sfusr) ; set user area for file
- call setua
- ld (srtfcb+12),a ; set extent to 0
- ld (srtfcb+32),a ; likewise w/ current record
- ld de,srtfcb ; open sort output file
- call f$make
- jp nz,nogood
- ld hl,0
- ld (count),hl ; zero the count
- call gotop ; get starting record number
- ;
- getrec: call rread ; read record
- call mxrptr ; increment pointers
- ld hl,edblk
- call setdma
- ld a,(hl) ; skip deleted records
- inc a ; if first byte = 0ffh it's an erased
- jr z,nowrt ; record.
- ld de,srtfcb ; write a record
- call f$write
- ld hl,edblk1
- call setdma
- ld de,srtfcb
- call f$write ; write a record
- nowrt: call inccnt ; increment the count
- ld de,(n)
- call comphd
- jr nz,getrec
- ;
- finsrt: ld de,srtfcb ; close sorted file
- call f$close
- ld de,fcb ; close original file
- call f$close
- ;
- ld de,bakfcb ; check to see if there's a previous
- ld hl,bakfil ; backup file
- call fnamz ; fname
- call f$delete
- ;
- ld de,fcb ; give original file the name
- ld hl,bakfcb ; 'backup.dta'
- call f$rename
- ;
- ld de,fcb ; put original file name back into
- ld hl,nambuf ; fcb
- call fnamz ; fname
- ex de,hl ; rename the sorted file with the
- ld de,srtfcb ; original file name
- call f$rename
- ;
- jp reopen ; reopen the newly sorted file
- ;
- ; compare de.vector to hl.vector for b bytes
- ; return C if de.vector < hl.vector
- ;
- compv: ex de,hl
- ld b,16
- call compb
- ex de,hl
- ret
- ;
- ; file split in two because of ZDE's
- ; memory limitations
- include zdb18.a ; remainder of source code
- include zdb18.b ; phone dialer module
- include zdb18.d ; data area
-
- end