; ; Program: SHVAR ; Author: Richard Conn ; Version: 1.0 ; Date: 5 Mar 84 ; version equ 10 ; ; SHVAR is used to define a shell variable for the Shell SH. ; It makes entries into the file SH.VAR in the ROOT directory. The ; syntax of its use is: ; SHVAR variable text <-- define/redefine variable ; SHVAR variable <-- delete variable ; SHVAR <-- list variables ; ; ; Equates for Key Values ; z3env SET 0f400h ;address of ZCPR3 environment backup equ 0 ;backup old file? 1 for yes, 0 for no ctrlz equ 'Z'-'@' ;^Z for EOF fcb equ 5ch tbuff equ 80h cr equ 0dh lf equ 0ah ; ; External Z3LIB and SYSLIB Routines ; ext cout,qcout,getquiet,sort,crlf ext sksp,fillb,moveb ext initfcb,f$open,f$read,f$close,f$make,f$delete,f$write,f$rename ext z3init,qprint,codend,hmovb,root,logud,getwhl,print ext getfn1,pfn1,cline ; ; Environment Definition ; if z3env ne 0 ; ; External ZCPR3 Environment Descriptor ; jmp start db 'Z3ENV' ;This is a ZCPR3 Utility db 1 ;External Environment Descriptor z3eadr: dw z3env start: lhld z3eadr ;pt to ZCPR3 environment ; else ; ; Internal ZCPR3 Environment Descriptor ; MACLIB Z3BASE.LIB MACLIB SYSENV.LIB z3eadr: jmp start SYSENV start: lxi h,z3eadr ;pt to ZCPR3 environment endif ; ; Start of Program -- Initialize ZCPR3 Environment ; call z3init ;initialize the ZCPR3 Environment call banner ;print banner ; ; Check for Wheel ; call getwhl ;get wheel byte jnz start0 call print db cr,lf,' Not Wheel - Aborting',0 ret ; ; Try to Load Variables ; start0: ; ; Check for Help ; lda fcb+1 ;get first char of FCB cpi '/' ;also help? jnz start0x ; ; Print Help Message ; call print db cr,lf,'SHVAR - Define/Redefine/Delete a Shell Variable' db cr,lf,'Syntax:' db cr,lf,' SHVAR variable text <-- to Define/Redefine' db cr,lf,' SHVAR variable <-- to Delete' db cr,lf,' SHVAR <-- to List Variable Names' db 0 ret ; ; Define File to Work With ; start0x: call getfn1 ;get name of shell lxi d,shvfcb+1 ;variable FCB mvi b,11 ;11 chars mov a,m ;any name given? cpi ' ' ;space if none cnz moveb ;set name ; ; Define $$$ and BAK Files ; lxi h,shvfcb+1 lxi d,shvtmp+1 ;set $$$ name mvi b,8 ;8 chars call moveb ; if backup lxi d,shvbak+1 ;set BAK name call moveb endif ; ; ; Save Command Line ; lxi h,tbuff ;save line call cline shld lineptr ;set ptr to line ; ; Load Variables ; call varload jnz start1 ; ; Initialize Shell Variables if File Not Found ; call print db cr,lf,' Shell Variable File ',0 lxi d,shvfcb+1 call pfn1 call print db ' Not Found',0 ret ; ; Process User Command ; start1: lda fcb+1 ;check for list option cpi ' ' ;no args = list jz list call doit ;process command call varsave ;save new shell variables ret ; ; Print Names of Variables ; list: call lpack ;pack just names xchg ;set ptr to ptr table inx h shld ptrbuf ;ptr buffer for sort lhld vcount ;run sort? mov a,h ora l cnz lsort ;sort names call print db cr,lf,' Shell Variables --',cr,lf,0 mvi c,0 ;set counter call codend ;pt to first variable mov a,m ;empty? cpi ctrlz jnz list1 call print db ' -- No Variables Defined --',0 ret ; ; Print Next Variable ; list1: mov a,m ;end of list? cpi ctrlz jz list3 call print db ' ',0 mvi b,8 ;print 8 chars list2: mov a,m ;get char inx h ;pt to next call cout ;print it dcr b ;count down jnz list2 inr c ;increment count mov a,c ;new line? ani 3 cz crlf jmp list1 list3: mov a,c ;new line to end? ani 3 cnz crlf ret ; ; Sort Variables ; lsort: call codend ;pt to first variable shld ssb ;set ptr lxi d,ssb ;pt to SSB jmp sort ;perform sort ; ; Compare Routine ; compare: push h ;save regs push d push b mvi b,8 ;8 chars comp1: ldax d ;get char cmp m ;compare jnz comp2 inx h ;pt to next inx d dcr b ;count down jnz comp1 comp2: pop b ;restore regs pop d pop h ret ; ; Pack Variables Down to a Minimum (Just 8-char Names) ; lpack: lxi h,0 ;set count shld vcount call codend ;pt to first variable mov d,h ;DE=HL mov e,l lpack1: mov a,m ;get next char stax d ;set possible EOF cpi ctrlz ;done? rz push h ;increment variable count lhld vcount inx h shld vcount pop h mvi b,8 ;save 8 chars lpack2: mov a,m ;get next char stax d ;store it inx h ;pt to next inx d dcr b ;count down jnz lpack2 lpack3: mov a,m ;skip to next variable inx h ora a ;done? jnz lpack3 jmp lpack1 ;resume ; ; Input and Process User Commands ; doit: call nadd ;add/delete/redefine variable ; ; Pack Names ; pack: call codend ;pack entries in table mov d,h ;HL=DE mov e,l ; ; Check Next Entry ; pack1: mov a,m ;get next char stax d ;put it cpi ctrlz ;done? rz cpi ' ' ;deleted? jz pack3 ; ; Copy Entry ; pack2: mov a,m ;get char stax d ;put it inx h ;pt to next inx d ora a ;done? jnz pack2 jmp pack1 ;resume ; ; Skip Entry ; pack3: mov a,m ;get char inx h ;pt to next ora a ;done? jnz pack3 jmp pack1 ;resume ; ; Add Names to Table ; nadd: lhld lineptr ;pt to user line call sksp ;skip to first non-blank ora a ;done? rz ;exit if no change call qprint db cr,lf,' Shell Variable ',0 ; ; Copy Input Name into Shell Buffer SHVAR ; push h ;save ptr to name lxi h,shvar ;init name buffer mvi a,' ' ;space fill mvi b,8 ;8 chars call fillb xchg ;pt to buffer in DE pop h ;pt to name mvi b,8 ;8 chars max nadd1: mov a,m ;get name char call delck ;check for delimiter jz nadd3 stax d ;store char call qcout ;print chars of variable name inx h ;pt to next inx d dcr b ;count down jnz nadd1 nadd2: mov a,m ;flush to delimiter inx h call delck ;check for delimiter jnz nadd2 dcx h ;pt to delimiter ; ; Search for Name ; nadd3: shld lineptr ;set ptr to rest of line call codend ;pt to first element ; ; Check for End of Entries ; nadd4: mov a,m ;get first char of next string cpi ctrlz jz addit ;add name at HL ; ; Compare Names ; lxi d,shvar ;pt to variable mvi b,8 ;compare shld curname ;save ptr to current name in case of delete nadd5: ldax d ;check for duplicate cmp m jnz nadd6 inx h ;pt to next inx d dcr b ;count down jnz nadd5 jmp nadd7 ; ; No Match, so Skip Rest of String ; nadd6: mov a,m ;skip to end of string inx h ;pt to next ora a ;done? jnz nadd6 jmp nadd4 ;resume ; ; Match - Determine What User Wants to Do ; nadd7: lhld lineptr ;see if any text follows name call sksp ;skip to text ora a ;EOL? jz delete ;delete name ; ; Redefine Name ; lhld curname ;pt to name in buffer mvi b,8 ;space fill it mvi a,' ' call fillb jmp nadd6 ;resume in case another duplicate ; ; Delete Name ; delete: call qprint db ' Deleted',0 lhld curname ;pt to name in buffer mvi b,8 ;space fill it mvi a,' ' call fillb ret ; ; Add Name ; addit: call qprint db ' = ',0 shld curname ;save ptr to new name xchg ;dest in DE lxi h,shvar ;pt to name mvi b,8 ;8 chars call hmovb ;copy name into buffer xchg ;pt to after name with HL push h ;save ptr mvi m,0 ;store ending 0 and ^Z in case of abort inx h mvi m,ctrlz ;store ^Z lhld lineptr ;point to user text call sksp ;skip to non-space pop d ;pt to destination ; ; Copy User Input into Buffer ; addit1: mov a,m ;get char stax d ;put char ani 7FH ;done? cnz qcout ;print chars of definition inx h ;pt to next inx d ora a ;done? jnz addit1 mvi a,ctrlz ;mark end stax d ret ; ; Print Banner ; banner: call qprint db 'SHVAR, Version ' db (version/10)+'0','.',(version mod 10)+'0' db 0 ret ; ; Check to see if char in A is a delimiter ; Return with Z if so ; delck: push h ;pt to table push b ;save BC mov b,a ;char in B lxi h,dtable ;pt to delimiter table delck1: mov a,m ;get delimiter ora a ;done? jz notdel cmp b ;compare jz yesdel inx h ;pt to next jmp delck1 notdel: mov a,b ;get char ora a ;set Z if null, else NZ yesdel: mov a,b ;restore char pop b ;restore regs pop h ret ; ; Delimiter Table ; dtable: db '<>;:,.=-_ ',0 ; ; Save Shell Variable List ; Return with Z if Error ; varsave: call getquiet ;get quiet flag jnz vars0 call print db cr,lf,' Writing Shell Variable File ',0 lxi d,shvfcb+1 call pfn1 ;print file name vars0: lxi d,shvtmp ;open temp call initfcb call f$delete ;delete if any exists call f$make ;create new file inr a ;error? rz call codend ;pt to scratch area ; ; Save Loop ; vars1: lxi d,tbuff ;copy into buffer mvi b,128 ;128 bytes call hmovb lxi d,shvtmp ;write block call f$write jnz werr ;write error lxi d,tbuff ;check for done mvi b,128 ;128 bytes ; ; Check for Done ; vars2: ldax d ;look for ^Z cpi ctrlz jz varsx inx d ;pt to next dcr b ;count down jnz vars2 jmp vars1 ; ; Done ; varsx: lxi d,shvtmp ;close temp file call f$close ; ; Delete Old Backup File SH.BAK ; if backup ; lxi d,shvbak ;delete any old backups call initfcb call f$delete ; ; Create New Backup File SH.BAK=SH.VAR ; lxi h,shvbak ;new name lxi d,shvfcb ;old name call f$rename ;create backup file ; else ; ; Delete Original File ; lxi d,shvfcb ;pt to FCB call initfcb call f$delete ; endif ;backup ; ; Create New Shell Variable File SH.VAR=SH.$$$ ; lxi h,shvfcb ;new name lxi d,shvtmp ;old name call f$rename ;create new file xra a ;return OK dcr a ;NZ ret ; ; File Write Error ; werr: call print db cr,lf,'Error in Writing File - Aborting',0 xra a ;error code ret ; ; Load Shell Variable List ; Return with Z if Error ; varload: ; ; Look for Variable File ; call root ;determine DU of root call logud ;goto root call codend ;pt to scratch area mvi m,ctrlz ;prep for no file lxi d,shvfcb ;try to open file call initfcb ;init FCB call f$open rnz ;file not found ; ; Read in Variable File ; varl1: lxi d,shvfcb ;read in file call f$read jnz varl2 lxi d,tbuff ;pt to data xchg ;copy into memory mvi b,128 ;128 bytes call hmovb xchg jmp varl1 varl2: lxi d,shvfcb ;close file call f$close ; ; Say List is Already Loaded ; xra a ;return NZ for OK dcr a ret ; ; Buffers ; lineptr: ds 2 ;ptr to next char in line curname: ds 2 ;ptr to current variable name shvar: ds 8 ;shell variable name ; if backup shvbak: db 0 db 'SH ' ;name of shell variable file db 'BAK' ds 24 ;36 bytes total endif ;backup ; shvtmp: db 0 db 'SH ' ;name of shell variable file db '$$$' ds 24 ;36 bytes total shvfcb: db 0 db 'SH ' ;name of shell variable file db 'VAR' ds 24 ;36 bytes total ; ; Sort Specification Block ; ssb: ds 2 ;address of first record vcount: ds 2 ;number of records to sort dw 8 ;size of each record in bytes dw compare ;compare routine ptrbuf: ds 2 ;address of pointer buffer dw 0ffh ;use pointers end