; Program: W - Wildcard Processing Shell ; Author: Steve Cohen ; ; VERSION 2.2 ; DATE November 9, 1987 by Rob Wood ; ; Add code for W to use the external FCB to find the name it was invoked with ; and build the shell/reinvokation command using this name. ; Added Z33 option in program configuration bytes. This option is set to TRUE ; if running in ZCPR 3.3 and the DU: from the external FCB is to be included in ; the shell/reinvokation command line. If running on ZCPR 3.0 or the DU: is ; not wanted then set Z33 to FALSE. ; ; Added INSERT option in program configuration bytes. If this option is TRUE ; then W will insert it's reinvokation command, which is stored in the first ; shell stack entry, into the multiple command line buffer after the command ; line W builds using the AFN. Any commands pending in the multiple command ; line buffer are then appended to the end of the reinvokation command. This ; causes W to be reinvoked from the command line and not as a shell. The two ; shell stack entries are still used. ; If the INSERT option is FALSE, then W functions as a shell and will be ; reinvoked after all commands have been processed from the multiple command ; line buffer. ; ; Corrected problem in next filename selection. The compare routine compares ; all eight bits of each byte of the filename. If any of the file attributes, ; the msb's of the filename, are set then files were being skipped. ; Added code that clears the msb of the directory filenames while searching ; for the next filename. ; ; Added internal QUIET flag support. If the IQUIET flag is TRUE then only ; install, finish, and abort messages will be displayed. Added IQUIET in ; configuration bytes. ; ; The AND of the SYS and NONSYS flags is now kept in word 31 of the second ; shell stack entry for easy use when W is reinvoked. WTOKEN is also moved to ; word 30 of the second shell stack entry. ; ; M80 and L80 were used for this revision. The []'s were changed to ()'s. ; ; VERSION 2.1 (Jay Sage personal version) ; DATE: December 27, 1986 ; 1) Added an extra message and check for abort at each shell invokation to ; keep up user's patience. ; 2) Fixed a bug in the code that set up the initial value for the previously ; matched file. Since it only replaced '?' with ' ' before, the program ; would not work when the ambiguous file spec happened to be unambiguous, a ; overlook a file named "JUNK." with no type. The new code just ; initializes the previously matched file to all ' '. ; 3) Fixed errors in the code for delay. Value is now put in directly in ; millisecs. ; 4) Put SYS, NONSYS, and QSEC (now MSEC) parameters into configuration ; and patch bytes at start of program. ; ; Changed code is marked with . ; ; VERSION 2.0 ; DATE FEB. 10, 1986 ; Passage of DU: now works as follows: ; If Logged user <> file user then ; Pass du:filename.typ ; Else ; If Logged Drive <> file drive then ; Pass d:filename.typ ; Else ; Pass filename.typ ; ; Added reset of command status byte so that flow control can work ; Corrected results when no files matched wildcard, ; Now no trailing spaces follow commands. ; Made delay user settable. ; Indication now given if no files match wildcard ; ; VERSION 1.1 ; date: Jan 29, 1986 ; improved command line control of user areas: ; user area only passed if different from current. ; This way only progs that can use user area info get it. ; removed conditional assembly HELP equate ; ; previous version: 1.0 ; date: Jan 26, 1986 ; ; .z80 ; for m80 compatiblity ; aseg ; also for M80/L80 compatiblity VERS EQU 22 Z3ENV ASET 0FE00H ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; W.COM may be used freely by the ZCPR3 community ; and is released to the ZCPR3 community through the ; new NAOG/ZSIG user's group. ; ; W.COM is a ZCPR3 shell which stores an afn and a ufn on the ; shell stack. It merely finds the next instance matching the afn ; which is larger than the ufn, stores the find as a new ufn and inserts ; it into whatever command line it is storing, allowing wildcard capability ; to programs that do not accept afn parameters. W.COM then passes the rest ; of the command line to the command processor for action. ; If no suitable match is found, W.COM removes itself from the shell ; stack and control reverts to the OS. ; ; W.COM is installed by Z3INS. ; ; W.COM works with all z80 ZCPR3 systems with at least a ; 2-entry shell stack whose entries are at least 32 bytes ; The ZCPR3 "standard" shell stack is 4 32-byte entries. ; ; Z80ASM is required for assembly of this file. ; It should also be adaptible to M80 without much difficulty. ; ; Usage: W COMMAND AFN [parm,parm,...,parm] ; or W ZEX COMMAND AFN [Parm,parm...,parm] ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; routines here need vlib, z3lib and syslib ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; EXT GETEFCB ; z3lib EXT Z3INIT,ZPRSFN,GETSH1,GETSH2 ; z3lib EXT SHPOP,PUTCL,Z3LOG ; z3lib EXT WAIT1MS,PUTZEX,GETCL1,PUTCST ; z3lib EXT GETZRUN,GETSHM,PUTSHM,GETMSG ; z3lib EXT MAFDC,ARGV,CODEND,COMPB,DIRF ; syslib EXT FILLB,INITFCB,MFN2,SKNSP,SKSP ; syslib EXT RETUD,PSTR ; syslib EXT GETUD,PUTUD,CONDIN ; syslib ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; basic definitions ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; CR EQU 0DH LF EQU 0AH ESC EQU 1BH BDOS EQU 5 RDBUF EQU 10 TAILB EQU 80H ; FALSE EQU 0 TRUE EQU NOT FALSE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; user selectable equates ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Z33 EQU FALSE ; true if running on a ZCPR3.3 system and include DU: SYS EQU TRUE ; true to see system type files NONSYS EQU TRUE ; true to see non-system type files SECHO EQU TRUE ; true for command line echo IQUIET EQU FALSE ; true for only install, finish, and abort messages INSERT EQU TRUE ; true for W reinvokation command to be inserted in ; the mult cmd line buf, false to execute as a shell MSEC EQU 0000 ; delay in milliseconds ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; MAIN PROGRAM BODY ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ORG 100H ; ; environment definition ; IF Z3ENV NE 0 ; ; external ZCPR3 environment descriptor ; JP START DB 'Z3ENV' ; this is a ZCPR3 utility DB 1 ; external environment descriptor Z3EADR: DW Z3ENV ; ELSE ; ; internal ZCPR3 environment descriptor ; MACLIB Z3BASE.LIB MACLIB SYSENV.LIB Z3EADR: JP START SYSENV ; ENDIF ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; configurataion and patch area ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; DB 'Z33=' ; marker in code AZ33: DB Z33 ; FFH if ZCPR3.3, else 00H for ZCPR3.0 ; DB 'SYS=' ; marker in code ASYS: DB SYS ; FFH to allow SYS type files, else 00H ; DB 'NONSYS=' ; marker in code ANONSYS: DB NONSYS ; FFH to allow non-SYS type files, else 00H ; DB 'SECHO=' ; marker in code ASECHO: DB SECHO ; FFH to have command line echoed ; DB 'IQUIET=' ; marker in code AIQUIET: DB IQUIET ; FFH for only install, finish and abort msgs ; DB 'INSERT=' ; marker in code for easy patching AINSERT: DB INSERT ; FF to insert W reinvoke cmd in cmd line, ; else 00H to execute as a shell DB 'MSEC=' ; marker in code DELAY: DW MSEC ; number of milliseconds to wait between files ; ; start of program ; START: IF Z3ENV NE 0 LD HL,(Z3EADR) ; pt to ZCPR3 environment if external env desc ELSE LD HL,Z3EADR ; pt to ZCPR3 environment if internal env desc ENDIF ; ; initialize ZCPR3 environment ; CALL Z3INIT ; ; get shell data ; CALL GETSH2 ; is there a shell stack? JR NZ,SHFINE ; yes SHBAD: LD HL,SHERR ; no, so error and abort JP PSTR ; SHFINE: LD (SHLSTK),HL ; save this pointer LD (SHSIZE),DE ; save shell size ADD HL,DE ; hl points to 2nd entry on shell stack LD (SHLSTK2),HL ; save 2nd entry on shell stack ; ; determine what name invoked with from the external FCB, if it doesn't exist ; then use the compiled defaults. ; if using ZCPR 3.3 and the Z33 flag is true (FFH) then the drive and user (DU) ; where the com file is located can also be found from the external FCB. ; CALL GETEFCB ; get EXT FCB address JP Z,NOFCB ; if no EXT FCB, use default SHNAME PUSH HL ; save EXT FCB address LD DE,SHNAME ; point to SHNAME LD A,(AZ33) ; get Z33 flag OR A JP Z,NODU ; if 0 then not Z33, thus can't determine DU: POP IX ; get EXT FCB address PUSH IX ; save it again for later use LD A,(IX+14) ; get Drive from EXT FCB byte 14 CALL DPASS ; decode and put in SHNAME LD A,(IX+13) ; get User from EXT FCB byte 13 CALL MAFDC ; decode and put in SHNAME LD A,':' ; append ':' to DU in SHNAME LD (DE),A INC DE ; point to next byte in SHNAME NODU: POP HL ; get EXT FCB address INC HL ; point to filename LD BC,8 ; move first 8 bytes of the filename to SHNAME LDIR LD A,' ' ; LD (DE),A ; insure filename is terminated with a space LD HL,SHNAME ; point to start of SHNAME CALL SKNSP ; move pointer to first space in SHNAME INC HL ; point to next byte LD DE,SHNAME ; calculate length of reinvokation name OR A ; clear carry SBC HL,DE ; subtract start from end LD (SHNLEN),HL ; save length ; NOFCB: ; ; determine whether to install or just run ; LD HL,(SHNLEN) LD B,L LD HL,(SHLSTK) ; compare first entry in the shell stack with LD DE,SHNAME ; shell name to see if we are installed CALL COMPB ; compare JP Z,RUNSH ; if the same don't install, just run ; ; install by putting information in shell stack ; LD BC,(SHSIZE) ; get shell stack size LD A,C CP 32 JR NC,STD ; shell stack size must be at least 32 LD HL,SHERR ; give message that won't work and abort JP PSTR ; STD: XOR A ; don't mess with command line LD DE,TKNTBL LD HL,TAILB+1 CALL ARGV ; split command line into tokens ; LD A,(NFND) ; no of tokens in command line CP 2 ; must be at least 2 JR NC,CHEKZEX ; it is, go on NENUF: LD HL,HLPMSG ; it isn't so print help msg and JP PSTR ; abort ; CHEKZEX: LD HL,(TKN1) ; compare first cmd line token LD DE,ZEXNAME ; with "ZEX " LD B,4 CALL COMPB JR NZ,ENUFTOK LD HL,WTOKEN ; this flag holds either 2 (default) or 3 (ZEX) ; indicating wildcard location LD (HL),3 ENUFTOK: LD BC,(WTOKEN) LD A,(NFND) CP C JR C,NENUF ; if ZEX now need 3 tokens JR NZ,GT2 ; if exactly 2 tokens must find end of tail CALL HLTOKEN PUSH HL POP DE ; copy token address to de DEC HL CNTR: INC HL ; look at each character in 2nd token LD A,(HL) OR A ; is it 0? JR NZ,CNTR ; no, get next JR TSTLNG GT2: LD BC,(WTOKEN) CALL HLTOKEN EX DE,HL ; de has addr of wildcard token INC BC CALL HLTOKEN ; hl has addr of following token TSTLNG: SBC HL,DE ; derive length of wildcard token LD A,(TAILB) ; length of the command tail SBC A,L ; subtract length of wildcard token LD HL,(SHNLEN) ; get length of reinvokation name ADD A,L ; add it to the reinvokation command tail CP 32 ; too long for the shell stack? JR C,SMLENUF ; no, small enough JR Z,SMLENUF ; LD HL,TOOLRG ; yes, error and abort JP PSTR ; SMLENUF: LD DE,(TKN1) ; beginning of command in de LD BC,(WTOKEN) CALL HLTOKEN ; beginning of wildcard token in hl SBC HL,DE ; length of tokens before wildcard in hl PUSH HL POP BC ; move to bc LD HL,SHNAME ; get start address of SHNAME buffer LD DE,(SHNLEN) ; get length of shell name ADD HL,DE ; calc where to append rest of cmd line LD DE,(TKN1) ; get address for start of cmd line EX DE,HL LDIR ; copy PUSH DE ; save next load address in ntail buffer LD BC,(WTOKEN) LD A,(NFND) INC C ; bump it CP C ; and compare with no of tokens found JR NC,DOMOVE ; c <= # of tokens, so more to move POP HL ; c > # of tokens so LD (HL),0 ; put a zero at end of ntail JR STARTCONT DOMOVE: LD BC,(WTOKEN) INC C ; we want the token after the wild card CALL HLTOKEN POP DE ; de has dest addr in ntail buffer XOR A ; we're looking for a zero CALL CPUNTL ; copy bytes until we find one ; STARTCONT: LD BC,(WTOKEN) CALL HLTOKEN ; convert second token LD DE,AMBIGFCB ; to a proper z3 fcb CALL INITFCB XOR A ; a=0 scan dir: first ; INC A ; a=1 scan du: first CALL ZPRSFN LD A,(DE) OR A ; was a drive specified? JR NZ,COPYFCB ; yes, don't bother changing it CALL RETUD ; get current du: INC B ; b is drive code -1 LD A,B LD (DE),A ; store it in fcb ; COPYFCB: ; following code modified to initialize to blanks LD HL,AMBIGFCB+16 LD (HL),' ' ; fill starting filename with blanks LD DE,AMBIGFCB+17 LD BC,11 LDIR ; FORMSHL: LD HL,AMBIGFCB LD A,1 ; no null termination in SHPUSH2 CALL SHPUSH2 JP NZ,SHBAD LD HL,SHNAME XOR A ; null termination okay here CALL SHPUSH2 ; store the shell name JR Z,RUNSH0 ; push okay, then skip next CALL SHPOP ; get rid of the fcb's just placed on stack JP SHBAD ; and abort RUNSH0: LD HL,HELLO ; tell user that W has been installed CALL PSTR ; ; LD IX,(SHLSTK2) ; get address of second shell stack ; ; Store the value at WTOKEN in the second shell stack entry word 30 so ; on reinvokation we can easily tell if we are processing a ZEX command ; LD A,(WTOKEN) ; get value at WTOKEN, 2=normal, 3=ZEX LD (IX+29),A ; store in second shell stack word 30 ; ; Store the system and non-system file use flags in the second shell stack ; entry word 31 ; LD A,(ASYS) ; get use system file flag AND 01000000B ; mask to get flag LD B,A ; save value LD A,(ANONSYS) ; get use non-system file flag AND 10000000B ; mask to get flag OR B ; combine flags LD (IX+30),A ; store in second shell stack word 31 ; ; Store the current shell control byte in the second shell stack ; entry word 32 and set this byte for echo of command line ; LD B,0 ; byte is at Z3MSG+13 CALL GETSHM LD (IX+31),A ; store it at word 32 of 2nd shell stack LD A,(ASECHO) ; get shell echo command flag AND 00000010B ; value to echo command lines built CALL PUTSHM ; put it ; ; here is where the normal processing after initial installation begins ; RUNSH: ; ; the need to check for ZEX running is only when using ZCPR30, ZEX processes ; all pending command lines in ZCPR33 before returning to the shell ; CALL GETZRUN ; check ZEX message byte JP NZ,ZEXRUN ; process ZEX command line if ZEX running LD HL,WAITMSG ; remind user that W is running CALL LQPSTR ; if quiet flag is not set LD BC,(DELAY) ; Delay value in milliseconds DLOOP: LD A,B OR C JR Z,XLOOP ; BC = 0 delay finished CALL WAIT1MS ; delay to give chance for abort DEC BC JR DLOOP ; loop XLOOP: CALL CONDIN JR Z,RUNSH1 ; no key hit, go ahead CP ESC ; is it ? JR NZ,RUNSH1 ; no so go ahead LD HL,ABORTMSG ; yes CALL PSTR ; print msg and JP QUIT1 ; quit ; RUNSH1: LD IX,(SHLSTK2) ; point to second shell stack entry LD A,(IX+29) ; get WTOKEN value from word 30 LD (WTOKEN),A ; store value in local WTOKEN CALL PUTUD ; save current du: LD A,(IX+13) ; store user num from second shell entry in a OR (IX+30) ; system and non-system file usage flags LD B,A ; user area to search CALL CODEND ; hl points to beginning of dir buffer LD DE,(SHLSTK2) ; de points to ambiguous fcb in shell stack CALL Z3LOG CALL DIRF ; load directory entries CALL GETUD ; restore du: JP Z,TPAOVFL ; just in case LD A,B ; bc holds number of matching entries OR C JP Z,ZQUIT ; end operation if no matching entries PUSH BC ; # of dir entries matching ambigfcb LD DE,15 ; so, when 16 is added in the loop, hl SBC HL,DE ; will point to the directory buffer + 1 PUSH HL ; ; loop compares sorted directory with last filename processed in ; previous runs ; CMPLOOP: LD DE,(SHLSTK2) LD HL,17 ADD HL,DE ; hl holds 1st byte of last file name ; in shell stack fcb POP DE ; de holds current directory file name PUSH HL LD HL,16 ADD HL,DE ; hl holds next entry in dir buffer POP DE ; de holds 1st byte of last file selected ; ; reset file attributes so that the ascii compare works properly ; PUSH HL ; save pointer to next entry in dir buffer LD B,11 ; reset MSB on the 11 bytes of file name RLOOP: RES 7,(HL) ; reset MSB (file flag) in dir file name INC HL ; next byte DEC B ; JR NZ,RLOOP ; do for 11 bytes POP HL ; hl holds next entry in dir buffer LD B,11 ; compare 11 bytes CALL COMPB JR C,BUMPB ; if dir < last one, not one we want JR Z,BUMPB ; if dir = last one, not one we want JP DOIT ; dir > last one, we want that one BUMPB: POP BC DEC BC LD A,C OR B JP Z,QUIT ; none found, time to exit shell PUSH BC PUSH HL JR CMPLOOP ; try again ; ; the 'next' file name is entered into the command line ; DOIT: ; check again for abort CALL CONDIN POP BC ; restore BC regs pushed above JR Z,DOIT0 ; no key hit - continue CP ESC ; is it ? JR NZ,DOIT0 ; no - continue LD HL,ABORTMSG ; yes - point to abort message CALL PSTR ; display it JP QUIT1 ; quit ; DOIT0: PUSH HL ; saving addrss in dir buffer for mfn2 LD HL,(SHLSTK2) LD DE,17 ADD HL,DE EX DE,HL ; de points to filename field of fcb on ; level 2 of shell stack POP HL ; hl points to chosen filename in dir PUSH HL ; we're still gonna need it LD BC,11 LDIR ; shell stack now updated for next runthrough ; ; parse the pseudo - command line in the shell stack ; ; 1: eliminate the first argument as it is W and pass the second to ; the temporary buffer ; DOIT1: LD HL,(SHLSTK) ; point to command line in shell stack CALL SKNSP ; move pointer to first space INC HL ; now point to second token in command line LD A,(WTOKEN) ; get value from local WTOKEN CP 3 ; if =3 then ZEX command LD A,' ' ; stop on a space LD DE,TEMPBUF JR NZ,ONCE ; not ZEX, copy only one token CALL CPUNTL ; copy token to temporary buffer ONCE: CALL CPUNTL ; copy token to temporary buffer ; ; 2: process the fcb that cmploop stopped on, converting it ; to a string with d: and u: if different from current ; add it to the temporary buffer ; Note: DE still has address in temporary file name buffer ; DOIT2: POP BC ; address in directory buffer PUSH HL ; hl = address in shell stack buffer to move PUSH BC LD B,17 LD A,' ' EX DE,HL CALL FILLB ; fill next 17 bytes of tempbuf with ' ' ; drive: 1 ; user: 2 ; colon: 1 ; filename: 8 ; period: 1 ; file type: 3 ; trail. space 1 ; total 17 EX DE,HL LD IX,(SHLSTK2) CALL RETUD ; Current DU in BC LD A,(IX+13) ; File U in A CP C ; Same? JR Z,USRSAME ; Yes LD A,(IX) ; No so must pass DU: CALL DPASS ; Pass Drive LD A,(IX+13) CALL MAFDC ; Pass User JR COLON ; add the ':' USRSAME: LD A,(IX) ; A has drive code of afn in shell stack INC B ; B has Current D from RETUD, must add 1 CP B ; Current Drive = File Drive? JR Z,FILENM ; Yes, pass no DU: at all CALL DPASS ; Pass Drive COLON: LD A,':' LD (DE),A ; add the colon INC DE ; de points to next byte of temp buffer FILENM: POP HL ; hl = address in directory buffer to process EX DE,HL ; switch em CALL MFN2 ; adds it to the temp buffer CALL SKNSP ; hl points to first space ; ; 3: move the rest of the pseudo command line in the shell stack ; buffer into the temporary buffer. this buffer now contains the ; command line we will pass to the ccp. ; DOIT3: POP DE ; de = address in shell stack buffer to move EX DE,HL ; switch 'em LD A,(HL) ; next byte to write OR A ; is it a zero? (EOL) JR NZ,DOIT3A ; No. LD (DE),A ; Yes, Zero last byte of command line JR DOIT3B DOIT3A: INC DE ; leave space alone and add rest of CL XOR A ; lookin for a zero CALL CPUNTL ; copy rest of command line to buffer DOIT3B: LD B,0 ; look at shell msg 0 CALL GETSHM AND 00000010B ; echo byte on? OR A ; JR Z,DOIT5 ; no so don't print cmdline LD HL,INFORM1 CALL LQPSTR ; print abbreviated message if quiet ; flag is not set LD HL,TEMPBUF CALL LQPSTR ; print if quiet flag is not set ; ; turn off command status byte so IF's will work right ; DOIT5: CALL GETMSG INC HL INC HL INC HL ; HL points to command status byte LD (HL),0 ; ; put our generated command and reinvokation command in the mult cmd buf ; ; Note: the command lines are moved to a scratch buffer in unused memory and ; then moved to the mult cmd line buf because the PUTCL routine ; will append any pending commands in the mult cmd buf to the command ; line being added, then copy the new command line back to the start ; of the mult cmd line buf ; DOIT6: CALL CODEND ; hl = start of scratch buffer/memory PUSH HL ; save start address for later use LD DE,TEMPBUF ; address of generated command EX DE,HL ; swap so hl = command, de = buffer XOR A ; set end of copy character to null word CALL CPUNTL ; copy command to scratch buffer LD A,(AINSERT) ; get INSERT W reinvokation flag OR A JP Z,DOIT7 ; if FALSE, go add just generated cmd to cmd buf LD A,(WTOKEN) ; get local WTOKEN value CP 3 ; if = 3 then processing a ZEX command JP Z,DOIT7 ; if ZEX, go add just generated cmd to cmd buf EX DE,HL ; DEC HL ; point to null word LD (HL),';' ; add multiple command seperator in buffer INC HL ; LD DE,(SHLSTK) ; get address of reinvokation command EX DE,HL ; swap so hl = command, de = buffer LD A,' ' ; copy only W, rest of tail not needed CALL CPUNTL ; copy command to scratch buffer EX DE,HL ; swap so hl = buffer, de = command DEC HL ; point to space copied to buffer LD (HL),0 ; mark end of command with null DOIT7: POP HL ; get start address of scratch buffer back CALL PUTCL ; put commands in mult cmd buf JP Z,MCLOVFL ; jump if mult cmd buf overflow RET ; to ccp ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; EXIT ROUTINES ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; dump the shell and exit ; ZQUIT: LD HL,STRIKEOUT ; no matching files message CALL LQPSTR ; print if quiet flag not set QUIT: LD HL,GOODBYE CALL PSTR QUIT1: ; land here on aborts LD B,0 LD IX,(SHLSTK2) LD A,(IX+31) ; get old shell message byte CALL PUTSHM ; restore it CALL SHPOP ; take our name off CALL SHPOP ; get rid of fcb's on shell stack RET ; to ccp ; ; not enuf memory for directory (just in case) ; TPAOVFL: CALL SHPOP ; reset shell stack to prior condition LD HL,TPAMSG JP PSTR ; ; not enuf room in multiple command line buffer ; MCLOVFL: LD HL,MCLMSG CALL PSTR JP QUIT1 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; UTILITY ROUTINES ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Convert drive code in A to a letter, move it to location ; in DE pointer and bump the pointer ; DPASS: ADD A,'@' ; convert drive code to a letter LD (DE),A INC DE ; bump pointer to temp buffer RET ; ; this routine takes a value in c and returns in hl an address to the ; c'th token in a string which has been parsed by argv. ; HLTOKEN: PUSH DE LD A,C ADD A,C ; double this value to get offset LD D,0 ; transfer to de LD E,A LD HL,TKNTBL ; add to beginning of table ADD HL,DE ; hl now has pointer to beginning addr of token LD E,(HL) INC HL LD D,(HL) EX DE,HL ; hl now points to beginning of token POP DE RET ; ; copy bytes upto and including a given byte ; inputs: ; a : byte to stop on ; hl : source ; de : dest ; outputs : ; hl and de point to byte following the last byte copied ; CPUNTL: CP (HL) LDI ; copy byte from hl to de JR NZ,CPUNTL RET ; ; local quiet print string - uses AIQUIET flag ; inputs: ; hl : point to null terminated string to print ; (AIQUIET) : internal quiet flag; 00h=print, FFh=don't print ; outputs: ; none ; LQPSTR: PUSH PSW ; save reg a LD A,(AIQUIET) ; get W internal quiet flag OR A CALL Z,PSTR ; if FALSE, print string POP PSW ; restore reg a RET ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; module SHPUSH2 ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; The following code is derived from and is in fact, almost identical ; to R. Conn's Z3SHPUSH.MAC, the only differences being ; 1> z80 code and ; 2> the fact that Conn's code ; quite sensibly stops copying the new entry onto the stack once a ; zero byte is encountered. This program introduces a non- ; standard use of a shell stack entry to hold an FCB, so needs ; to copy the full number of bytes regardless of content. Therefore ; we introduce an input flag in the a register. When zero the ; normal SHPUSH null terminated copy is performed. When non-zero, ; the full number of bytes is copied. Obviously, be very careful ; with this sort of thing. ; ; macros ; PUTRG MACRO PUSH HL PUSH DE PUSH BC ENDM GETRG MACRO POP BC POP DE POP HL ENDM ; ; SHPUSH pushes the string (incl ending 0) pted to by hl onto ; the shell stack if possible. SHPUSH returns with a=0 and zero flag ; set (z) if push is successful, else SHPUSH returns with a<>0 and ; zero flag clear (nz) if an error occurred. the following error ; codes are returned: ; 1 - no shell stack available ; 2 - shell stack is full ; 3 - string is too long for shell stack entry ; SHPUSH2: PUTRG ;save registers ; ; get shell data for later use ; LD (NULTRM),A ;store a into null termination flag PUSH HL ;save ptr to string CALL GETSH2 ;get ptr to shell stack ; POP HL ;get ptr to string JP Z,NOSHELL ;error if no shell stack ; ; see if string is too long (only if null-termination in effect); ; PUSH HL ;save ptr to string LD A,(NULTRM) ;following check unnecessary in event OR A ;null termination disabled JR NZ,CKS1 ; CKSIZE: LD A,(HL) ;get elt INC HL ;pt to next OR A ;end of string? JR Z,CKS1 DEC E ;count down JR NZ,CKSIZE JP TOOBIG ;string is too long CKS1: ; ; check to see if shell stack is full ; CALL GETSH2 ;get values for copy FCHK: LD A,(HL) ;get next element OR A ;last element on stack? JR Z,FCHK1 ;stack ok ADD HL,DE ;pt to next element DEC B ;count down JR NZ,FCHK JP NOROOM ;shell is full FCHK1: ; ; copy current shell stack up ; CALL GETSH2 ;get shell stack values ; ; point to end of new top element ; PUSH BC MOVE0: LD A,B ;check for done CP 1 JR Z,MOVE1 ADD HL,DE ;pt to next DEC B ;count down JR MOVE0 MOVE1: POP BC LD C,E ;get count of elements in c DEC HL ;pt to first byte to copy EX DE,HL ;de pts to source ADD HL,DE ;hl pts to destination ; ; copy stack up one entry size ; MOVE2: LD A,B ;check for copy done CP 1 ;one less element JP Z,MOVE4 DEC B ;count down PUSH BC ;b=number of elements left to copy, c=size of each MOVE3: LD A,(DE) ;get LD (HL),A ;put DEC HL ;back up DEC DE DEC C ;count down JR NZ,MOVE3 POP BC ;get values JR MOVE2 MOVE4: LD A,(NULTRM) ;the null termination flag is evaluated OR A JR NZ,FULLCOPY CALL GETSH2 ;get ptr to shell stack POP DE ;get ptr to string ; ; copy new shell entry from de to hl ; COPY: LD A,(DE) ;get byte LD (HL),A ;put byte INC HL ;pt to next INC DE OR A ;done? JR NZ,COPY JR WELLDONE FULLCOPY: CALL GETSH1 ;get ptr to shell stack, and # of bytes in b LD C,B LD B,0 POP DE ;get ptr to string EX DE,HL ;reverse em for ldir LDIR WELLDONE: GETRG ;restore registers XOR A ;ok return RET NULTRM: DS 1 ; null termination flag ; ; no shell stack available ; NOSHELL: POP HL ;restore hl GETRG ;restore registers LD A,1 ;error code OR A RET ; ; no room on shell stack ; NOROOM: POP HL ;restore hl GETRG ;restore registers LD A,2 ;error code OR A RET ; ; string is too large ; TOOBIG: POP HL ;restore hl GETRG ;restore registers LD A,3 ;error code OR A RET ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; Run ZEX on top of W ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Command line is currently empty and ZEX is active. ; Accept new command line from ZEX and pass it to ZCPR3. ; This code unasheamedly cribbed from Al Dunsmuir's VFILER. ; ZEXRUN: LD HL,WSTR CALL LQPSTR ; print if quiet flag not set JR ZEXR1 WSTR: DEFB CR,LF,'W> ',0 ZEXR1: LD A,1 ;tell ZEX that it is prompted CALL PUTZEX CALL GETCL1 ;pt to command line buffer LD D,H ;copy pointer LD E,L INC DE ;pt to 1st char INC DE INC DE INC DE LD (HL),E ;set ptr to first character. INC HL LD (HL),D INC HL ;pt to char count EX DE,HL ;... in de PUSH DE ;save ptr LD C,RDBUF ;input line via bdos CALL BDOS POP HL ;pt to char count INC HL LD E,(HL) ;get char count INC HL ;pt to first char PUSH HL ;save ptr LD D,0 ;de=char count ADD HL,DE LD (HL),0 ;store ending 0 POP HL ;pt to first char CALL SKSP ;skip over leading spaces LD A,(HL) ;check for comment CP ';' ;if comment, JR Z,ZEXRUN ;loop until real command is found XOR A ;a=0 CALL PUTZEX ;resume ZEX (a=0) JP PUTCST ;set command status to normal (a=0), ;... then return to opsys ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; Miscellaneous Buffers ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WTOKEN: DW 2 ; default is that 2nd token is wildcard ZEXNAME: DB 'ZEX ' ; check to see if a ZEX command AMBIGFCB: DS 36 TEMPBUF: DS 64 SHLSTK: DS 2 SHLSTK2: DS 2 SHSIZE: DW 32 SHNLEN: DW NTAIL-SHNAME SHNAME: DB 'W ' NTAIL: DS 32-($-SHNAME) ; 32 spaces in shell stack entry ; ; table of pointers to command line tokens created by argv ; TKNTBL: DB 6 NFND: DS 1 TKN1: DS 2 TKN2: DS 2 TKN3: DS 2 TKN4: DS 2 TKN5: DS 2 TKN6: DS 2 ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ; Miscellaneous Messages ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SHERR: DB 'Shell Stack Error.',0 TOOLRG: DB 'W Command Line Overflow.',0 TPAMSG: DB CR,LF,'Not Enough Memory. Aborting.',0 MCLMSG: DB CR,LF,'Multiple Command Line Buffer Overflow. Aborting.',0 HELLO: DB '',CR,LF,0 INFORM1: DB CR,LF,' ',0 WAITMSG: DB CR,LF DB ' W Scanning for Next Matching File',CR,LF DB ' Please wait or ESC to abort ... ' DB CR,LF,0 STRIKEOUT: DB CR,LF,' No files match wildcard. ',0 GOODBYE: DB CR,LF,'',0 ABORTMSG: DB CR,LF,' ',0 HLPMSG: DB CR,LF,' -- THE WILDCARD PROCESSOR' DB CR,LF DB CR,LF,'SYNTAX:' DB CR,LF,' W COMMAND AFN [parm,parm...parm]' DB CR,LF,' where COMMAND is any executable ZCPR3 command' DB CR,LF,' and AFN is an ambiguous filename upon which' DB CR,LF,' COMMAND is to act, with optional parameters' DB CR,LF,' OR --' DB CR,LF,' W ZEX COMMAND AFN [parm,parm...parm]' DB CR,LF,' where COMMAND is a ZEX command script file' DB CR,LF DB CR,LF,'W is used to add wildcard capability for commands that' DB CR,LF,'do not normally accept wildcards.' DB CR,LF DB CR,LF,'To abort W type several times.' DB CR,LF,0 ; END