; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ; * * ; * ZDT * ; * * ; * The Z-System Day Timer * ; * * ; * (C) 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 ; ; ; Assembler/Linker: ZMAC/ZML or Z80ASM/SLRNKP ; ; vers equ 13 ; version suffix equ ' ' ; suffix character or ' ' if none month equ 02 ; revision month rday equ 08 ; day year equ 92 ; year ; ; the usual equates ; ctrla equ 'A'-40h ; move cursor one word left ctrlc equ 'C'-40h ; ^C 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 ; archive command 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 ctrlz equ 'Z'-40h ; 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 eof equ 1ah ; row equ 1 col equ 51 ; jthlib routines .request jthlib ext fnamz ; zplib routines .request zplib ext vprint,vpstr,gxymsg ; zslib routines .request zslib ext prdat1,ptimf3,mdat1,wday0,pwday2 ext binbcd,jbcd2bn ; .request dslib ext timini,rclock ; vlib routines .request vlib ext stndout,stndend ;,gxymsg,vprint,vpstr ext at,cls,ereol,gotoxy,gz3init ext tinit,dinit,@goxy,grxon,grxoff,curon,curoff ext @ghl,@gvl,@gulc,@gurc,@gllc,@glrc ext @gui,@gli,@grti,@glti,@gis ; ; z3lib routines .request z3lib ext zsyschk ; ; syslib routines .request syslib ext f$make,f$open,f$close,f$write,getfs;,fname ext f$exist,r$write,r$read,setdma,mfn2,f$rename,f$delete ext codend,logud,divhd,mulhd,sdiv,bios ext isctrl,isdigit,compb,acase1,acase3,ssbini,sort ext capin,cin,cout,padc,pafdc,pa2hc,phldc,phlfdc,mafdc ext lout,lcrlf,caps,comphd,eval10 ; jp start db 'Z3ENV' ; standard z3 header db 1 ; type 1 program z3addr: dw 0 ; ; Configuration Bytes ; prbios: db 0ffh ; printer status check byte, 00h if none ; ; 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 'ZDT',vers/10+ '0',vers mod 10 + '0' db suffix,' ' db 0 ; termination ; ; Default data file name (16 characters - fill unused positions with ; spaces -- drive/user spec optional): ; 'duu:filename.typ' deffn: db 'ZDT.DTA ' ; default data file name db 0 ; termination ; ; printer codes counted character strings ; first byte is length byte ; prinit: db 7 ; length byte db ESC,'@',ESC,'M',ESC,'l',12 ; reset, elite ds 3 ; left margin 12 ; prdinit:db 2 ; length byte db ESC,'@' ; reset ds 3 ; extras ; ; command line help message ; hlpmsg: call vprint db 'ZDT vers ',vers/10+ '0','.',vers mod 10 + '0' db suffix db ' Z-System Day Timer' db cr,lf db ' Syntax: ZDT [[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 ;ld hl,timebuf call gettim ; get time from ZSDOS clock jr z,clkok ; nclk: call noclk ; if no clock, get date from manual entry clkok: ld a,(fcb) ; get drive call chkdrv ld (fdrv),a ; store it ; 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 ; fname ; parse filename to fcb ; ; 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 ; ; 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 ; ld de,fcb call getfs ; get file size in records ld (recs),hl ; save call index ; create index refscr: xor a ld (date+1),a call curoff call frame ; do frame and screen layout call docal ; make the calendar call menu1 ; display main menu ; ; main program loop ; menu: call timdat call at db 22,75 call getchar ld de,cmdtbl ; run command thro' command table call acase3 jr menu ; ; end of main loop ; ; command table ; cmdtbl: db 25 ; no. of entries in command table dw menu db 'Q' dw exit db esc dw exit db 'A' dw archive db 'E' dw edit db 'F' dw find db 'G' dw gotoda db 'P' dw print db ctrlt ; ^T display today's calendar dw docal db '\'-40h ; refresh screen dw refscr db ctrle dw lastwk db 'K'-40h dw lastwk db 'J'-40h dw nextwk db ctrlx dw nextwk db ctrls dw prvday db 'H'-40h dw prvday db ctrld dw nxtday db 'L'-40h dw nxtday db ctrlr dw lastmo db ctrlc dw nextmo db '.' dw nxtnrst db '>' dw nxtnrst db ',' dw prev db '<' dw prev db 'T' dw firstr db 'B' dw last ; ; 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 cls call stndend call grxon ld hl,2*256+1 call gotoxy call ulc ; print upper left corner ld b,45 call hseg ; print top line 46 spaces wide call usec ; print upper intersection ld b,3 call hseg ; three more spaces of line ld l,77 call gotoxy ld b,2 ; skip to right side of screen call hseg ; print two more spaces of line call urc ; print upper right corner ld l,1 inc h ld b,16 ; print 16 rows of vertical line at left call vseg ; of screen call gotoxy call lsec ; print left intersect -- line 19 ld b,45 ; print horizontal line 46 spaces wide call hseg call bsec ; print bottom intersect ld b,31 ; print more horizontal line call hseg call rsec ; print right intersect ld hl,3*256+47 ld b,8 call vseg call gotoxy call lsec ld b,31 call hseg call rsec inc h ld l,47 ld b,7 call vseg ld hl,256*3+79 ld b,8 call vseg inc h ld b,7 call vseg ld hl,256*20+1 call gotoxy ld a,(@gvl) call cout push af ld l,79 call gotoxy pop af call cout inc h ld l,1 call gotoxy call llc ld b,77 call hseg call lrc ld hl,row*256+col call gotoxy call ulc ld b,24 call hseg call urc inc h ld b,8 call vseg call gotoxy call llc ld b,24 call hseg call lrc ld h,row+1 ld l,col+25 ld b,8 call vseg call grxoff ; ld hl,panel ld b,(hl) ; enter with hl=panel pointer inc hl ; scrnloop: call @goxy call vpstr djnz scrnloop ; fall through ; ; 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 ; ; menu1: call clrmnu ; main menu line db 1,'^S/^D=Day ^E/^X=Wk <>=Prv/Nxt G=GoToDate P=Print' dc ' F=Find E=Ed A=Arc Q=Quit ?',2,bs ret ; ; ; 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 ret ; ; file movement routines ; next: call ckeoi jr nz,oknxt ; firstr: call gotop ; set pointer to beginning of file current:call rread ; read current record curren0:ld hl,today jp docal0 ; oknxt: call riread ld hl,today jr curren0 ; last: ld hl,(xrecptr) call savptr jr current ; prev: ld hl,(recs) ld a,h or l ret z call getnext ld de,3 add hl,de call backup0 jr current ; ; get first index record number ; gotop: ld hl,(first) ; get start of index table getpt0: ld de,3 ; 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) backup0:or a ld de,5 sbc hl,de ld de,(first) call comphd jr nc,savit ld hl,(xrecptr) savit: jr savptr ; ; Increment record pointers ; mvrptr: call ckeoi jr z,gotop ; mxrptr: ld hl,(recptr) ; get index record pointer ld de,5 ; point to next jr getptr ; ; get next record in file nearest current date ; nxtnrst:ld hl,(first) ld de,(count) ; if no records, return ld a,d or e ret z dec de ld (xcount),de nxtnr0: ld (inxptr),hl ld de,date ex de,hl ld b,3 call compb ex de,hl jp z,next jr c,fndnxt nxtnr1: ld de,(xcount) ld a,d or e ret z dec de ld (xcount),de ld hl,(inxptr) ld de,5 add hl,de jr nxtnr0 fndnxt: call getpt0 jp current ; ; get index pointer of record nearest to current day ; getnext:ld hl,(first) ld (inxptr),hl ld de,(count) dec de ld (xcount),de getlp: ld de,date ld b,3 ex de,hl call compb ex de,hl jr c,getlp1 ret z ld de,(xcount) ld a,d or e jr z,getlp1 dec de ld (xcount),de ld hl,(inxptr) ld de,5 add hl,de ld (inxptr),hl jr getlp getlp1: ld (inxptr),hl ret ; ; 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 dec hl dec hl ld (fptr),hl ret ; sort routines ; ; 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 hl,fields ; ld bc,3 ; index on first 3 bytes -- the date ldir ret ; ; Archiving routines ; archive:call showmsg dc 1,'Archive Records Before (^C=Abort)',2 call at db 24,25 ld hl,gotobuf call inplp ld hl,gotobuf call convrt0 ld (arcdate+1),a call convrt ld (arcdate+2),a call convrt ld (arcdate),a 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,arcfil ld de,arcfcb call fnamz ; fname ld a,(fusr) ld (afusr),a ld a,(arcfcb) call chkdrv ld (afdrv),a ld a,(afusr) call setua ld (arcfcb+12),a ld (arcfcb+32),a ld de,arcfcb call f$make jp nz,nogood ld hl,(first) ld (inxptr),hl ld de,(count) dec de ld (xcount),de ; arclp: ld de,arcdate ; compare dates ld b,3 call compb jr c,wrtarc ; if less, write to archive file ld de,srtfcb jr wrtsrt ; otherwise to sort file wrtarc: ld de,arcfcb wrtsrt: call wrtfil ld de,(xcount) ld a,d or e jr z,finsrt dec de ld (xcount),de ld hl,(inxptr) ld de,5 add hl,de ld (inxptr),hl jr arclp wrtfil: push de ; save address of file control block call getpt0 ; get file pointer call rread ; read the record ld hl,fields ; ld de,0 ; zero de ld b,4 ; set counter wrloop: add hl,de ; add de to hl pop de ; de = fcb call setdma ; set dma call f$write ; write 128 bytes push de ; save fcb address ld de,128 ; increment dma address djnz wrloop pop de ; forgot this one with bad results ret ; finsrt: ld de,arcfcb ; close archive file call f$close 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 ; xor a ld (date+1),a 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 call compb ex de,hl ret ; ; convrt: inc hl ; convert ASCII to BCD for date convrt0:call eval10 jp binbcd ; file split because of ZDE's ; memory limitations include zdt.a ; support routines include zdt.b ; calendar routines include zdt.c ; search routines include zdt.e ; edloop include zdt.f ; adding, editing, saving to file include zdt.g ; graphics routines include zdt.d ; string & data storage, dseg end