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
/
CPM
/
ZCPR33
/
S-Z
/
W22.LBR
/
W22.ZZ0
/
W22.Z80
Wrap
Text File
|
2000-06-30
|
32KB
|
1,121 lines
; 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 <JPS>.
;
; 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 ; <JPS> true to see system type files
NONSYS EQU TRUE ; <JPS> 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 ; <JPS> 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 <JPS> ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
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 <JPS - commented out>
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: ; <JPS> 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 ; <JPS> 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 <escape>?
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: ; <JPS> check again for abort
CALL CONDIN
POP BC ; restore BC regs pushed above
JR Z,DOIT0 ; no key hit - continue
CP ESC ; is it <escape>?
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 <w> 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 '<W Vers. '
DB (VERS/10)+30h,'.'
DB (VERS mod 10)+30h
DB ' Installed>',CR,LF,0
INFORM1:
DB CR,LF,'<W> ',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,'<W Finished>',0
ABORTMSG:
DB CR,LF,'<W Aborted> ',0
HLPMSG:
DB CR,LF,'<W Vers. '
DB (VERS/10)+30h,'.'
DB (VERS mod 10)+30h
DB '> -- 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 <ESCAPE> several times.'
DB CR,LF,0
;
END