title 'LX VERSION 1.8 - RUN PROGRAM FROM COMMAND.LBR' ; PROGRAM: LX ; AUTHOR: RICHARD CONN ; VERSION: 1.0 ; DATE: 10 Aug 85 ; PREVIOUS VERSIONS: None vers equ 19 ; Corrected help screen, safety header added, ; restored Royce Shofner's wheel byte idea in ; a simpler way. An option byte at 102h ; controls LX19's wheel byte response. If it ; is patched to a zero (0FFh in distributed ; COM/CIM files), LX19 will test the wheel ; byte and use ROOT:USERCMD.LBR instead of ; ROOT:COMMAND.LBR if not wheel (wheel byte ; is reset, zeroed). Otherwise LX19 will ; work like LX18 did - very nicely. Both ; Default LBR names remain patchable to ; preference. ; April 1, 1988 Bruce Morgen ;vers equ 18 ; Rewrote the ADJCML routine. IT NOW ADJUSTS ; THE COMMAND LINE PROPERLY WHEN A LIBRARY ; NAME WAS INCLUDED IN THE COMMAND. ; ; Howard Goldstein, November 29, 1987 ;vers equ 17 ; Added code to parse file names via ; resident CPR code if ZCPR33 is present. ; This makes LX completely Z33 compatible. ; Removed Bruce Morgen's in-line PUTER3 ; ; code since Z33LIB's version works properly ; now. ; ; Howard Goldstein, November 21, 1987 ;vers equ 16 ; Deleted vestigial buffer set-up code via ; DSEGed buffer definitions. LX now does ; a better simulation of the 3.3 CPR by ; passing the environment descriptor pointer ; in HL as well as poking ORG+9 in Z3 tools. ; Added detection code for LX running under ; WordStar. A new alternate syntax has been ; introduced especially for chaining to LX ; from ARUNZ's "default alias" feature: ; :DEFAULT [dir or du:]LX / $0 $* ; Under that condition, or whenever LX is ; called with the intervening "/" parameter, ; LX will declare itself an ECP and, if there ; is an error, adjust the command line to ; eliminate its own verb. If running under ; Z33, LX follows the CPR's DUFIRST flag. ; All errors (except under WordStar) now abort ; to the error handler with the ECP bit set ; on return to the CPR. While we were at it, ; replaced the internal COUT routine with a ; simple JP to BOUT to accomodate BIOS's ; that (legitimately) do not bother to preserve ; the HL register through CONOUT calls. The ; BOUT approach ALWAYS (famous last words) ; works, and is shorter to "bout" (grin). The ; reason there is a hand-coded PUTER3 routine ; in LX is that Z33LIB's fails to preserve the ; incoming A register against GETMSG's return. ; In other words, it doesn't work. ; ; Bruce Morgen @23:55:56 June 4, 1987 ;vers equ 15 ; Adapted to coexist as an ECP with error ; handling under ZCPR 3.3 and BGii 1.13 or ; later. Also extended Michael's auto- ; install code to properly initialize the ; copy routine for Z33 type 2 COMfiles ; (origin other than 100H). Bumped versions ; past 1.3 & 1.4, which seem to be of interest ; mainly to Z-Node sysops (no offense, Royce, ; just a personal opinion - b/m). Note that ; there is a problem regarding SYSLIB's ; CODEND routine and the use of DSEG as ; recommended for the upcoming Z80 versions ; of the Conn *LIBs. The old approach (the ; $MEMRY buffer in CSEG) has been recommended ; to the LIBs revision team. All modifiable ; LX data buffers are now in DSEG, including ; the (now runtime-initialized) ARGV argument ; table. While I was at it, I got rid of the ; unecessary self-modifying code at COPY$CODE. ; Remember, we won't be able to get away with ; such kludges with the Z280, so we might as ; well start getting rid of our bad habits now. ; Note that LX now carries its own COUT routine ; to enable showing an error or a help screen ; under the WordStar "R" command without ; crashing anyone's system to a fare-thee-well. ; Bruce Morgen @15:03:03 April 24, 1987 ;vers equ 12 ; Auto-installs ZCPR3 utilities. There is no ; need to run Z3INS on utilities run by LX ; since, after loading and before executing, ; LX looks for "Z3ENV" at the beginning. If ; present, LX inserts the address of the ; environment descriptor. Both concept and ; code are based on Jay Sage's experimental CCP. ; 3 September 1986 - Michael Bate ;vers equ 11 ; Extracted ARGV from syslib36 and included ; it here, modified so that '=' is also an ; argument delimiter if it occurs after ; a non-space (sknsp:). 27 Feb 86 jww ;vers equ 10 ; Release version z3env defl 0fe00h ; My Z3 environment location ; LX is like the old LRUN tools in that it looks at its arguments ; as a command line to be executed. LX locks onto a library file, searches ; for the command verb COM file in it, extracts the COM file into memory ; at 100H, and sets up the various buffers to look like the COM file was ; executed by the ZCPR3 command processor. ; Unlike the other LRUN tools I've seen and heard of (with the ; possible exception of LRUNZ), LX truly acts as the ZCPR3 command ; processor, parsing the command line as ZCPR3 itself would. Named ; directory references are allowed, the External FCB is loaded if ; available, etc. Any ZCPR3 tool executed by LX sees the environment ; as it would if ZCPR3 itself executed the tool. ; For security, no directory references are allowed (they are ; ignored) for any arguments if the wheel byte is not set. public cout ; b/m, April 24, 1987 ; Externals extrn z3init,codend extrn eprint,retud,putud,logud,getud;,pfn1 extrn initfcb,f$exist extrn getefcb,zprsfn,z3log,pfind,getwhl extrn luinit,luopen,luread extrn getcst,putcst ; b/m April 24, 1987 extrn getcl1,clrcl,putcl,getquiet,bout,pfn2 ; b/m June 3, 1987 extrn z33chk,geter3,getmsg; Z33LIB, etc. b/m June 4, 1987 extrn z33fname,puter3; h/g Nov. 21, 1987 ; Equates cr equ 0dh lf equ 0ah bdose equ 5 fcb1 equ 5ch fcb2 equ 6ch tbuff equ 80h tpa equ 100h lnsize equ 22 ; Number of chars allowed for library name ; External ZCPR3 Environment Descriptor ; TYPE 3 HEADER ; Code modified as suggested by Charles Irvine to function correctly with ; interrupts enabled. Program will abort with an error message when not ; loaded to the correct address (attempt to run it under CP/M or Z30). entry: jr start0 ; Must use relative jump option: db 0ffh ; Make zero for wheel byte ; control of default LBR z3ename: db 'Z3ENV',3 ; Type-3 environment z3eadr: dw z3env ; Filled in by Z33 dw entry ; Intended load address start0: ld hl,0 ; Point to warmboot entry ld a,(hl) ; Save the byte there di ; Protect against interrupts ld (hl),0c9h ; Replace warmboot with a return opcode rst 0 ; Call address 0, pushing RETADDR ; onto stack retaddr: ld (hl),a ; Restore byte at 0 dec sp ; Get stack pointer to point dec sp ; To the value of RETADDR pop hl ; Get it into HL and restore stack ei ; We can allow interrupts again ld de,retaddr ; This is where we should be xor a ; Clear carry flag push hl ; Save address again sbc hl,de ; Subtract -- we should have 0 now pop hl ; Restore value of RETADDR jr z,start ; If addresses matched, begin real code ld de,notz33msg-retaddr ; Offset to message add hl,de ex de,hl ; Switch pointer to message into DE ld c,9 jp 0005h ; Return via BDOS print string function notz33msg: db 'Not Z33+$' ; Abort message if not Z33-compatible ; Names of Library Files libnam1: db 'ROOT:COMMAND.LBR',0 ds lnsize-[$-libnam1] libnam2: db 'ROOT:USERCMD.LBR',0 ds lnsize-[$-libnam2] ; Beginning of code; set buffer definitions here start: ld hl,(z3eadr) ; Pt to zcpr3 environment call z3init ; Init zcpr3 environment start1: ld a,(bdose+2) ; Get bdos base page sub a,9 ; 9 pages below bdos is 1 page below ccp ld (tpaend),a ; Set end of tpa call codend ; Get free space ptr ld (scratch),hl ; Free space ptr ld hl,tpa ; Default COMfile starting addr. ld (cpytpa),hl ld hl,argv2 ; Usual command tail start ptr. ld (tailst),hl ld hl,libnam1 ld a,(option) or a call z,getwhl jr nz,nogwhl ld hl,libnam2 nogwhl: ld (libname),hl ld de,clineb ; Point to local buffer for MCL. ld a,(1) ; Test for WordStar BIOS table. sub a,3 jr nz,savocl ; Skip MCL if WS is running. ld (de),a ; Init. local MCL buffer to 0. ld b,a ; Make sure B=0. call getcst ; Get Command Status Flag. bit 2,a ; Test ECP bit. jr nz,savocl ; Skip MCL stuff if we're ECP. ld a,'/' ; Check for help and forced ECP. ld hl,(fcb1+1) ; Help "/" in H, ECP "/" in L. cp h ; Test for help query jr z,help sub l ; Test for forced ECP request. jr nz,savocl call getcl1 ; Find MCL buffer (B=0). ld c,a ; MCL size is now in BC. ld a,l ; Test for no MCL buffer. or h jr z,savocl ; No MCL? Then branch ahead... inc hl ; Otherwise bump to MCL start. inc hl inc hl inc hl ldir ; Move MCL to local buffer. ; Save original command line savocl: ld hl,tbuff+1 ; Copy from tbuff ld de,cmdline ld bc,128 ; 128 bytes ldir ; Save home directory call putud ; First parse of command line to determine if help needed, name of library ld hl,cmdline ; Pt to command line ld de,args ; Pt to argument table ld a,5 ; Init. for five arguments ld (de),a ; so table can be in DSEG xor a ; Do not delimit tokens (A=0) call argv ; Generate vector ld a,(argc) ; Check count ld b,a ; Save arg count in b or a ; Help if no args jr z,help ld hl,(argv1) ; Get ptr to first arg ld a,(hl) ; Get first char of first arg cp '/' jp nz,go1 ; Skip help if not / djnz goecp ; Should ALWAYS jump, but W.T.H. ; Print Help Message help: call eprint db 'LX, Version ' db [vers/10]+'0','.',[vers mod 10]+'0' db cr,lf,' Syntax: LX [/] [-[dir:]library] command_line' db cr,lf,' (Use "/" option when chaining from ARUNZ' db ' default alias)',0 ret ; Adjust vectors for forced-ECP mode goecp: ld de,argv2 ld hl,argv3 ld (tailst),hl ld hl,(argv2) ld a,(hl) jr goecp1 ; Continue processing; check for and process library reference go1: ld de,argv1 ; Set pointer for first token goecp1: cp '-' ; Library reference? jr nz,go2 dec b ; Reduce argument count by 1 jp z,help ; Library name by itself is not enough ; Extract and store library reference push bc ; Save arg count ld de,(libname) ; Set library name push de ; Save on stack inc hl ; Pt to name ld bc,lnsize ; Size of buffer ldir ; BC=00 pop hl ; Terminate name with zero lnscan: ld a,(hl) ; Get next char cp ' ' ; Done? jr z,lnscan1 or a jr z,lnscan1 inc hl ; Pt to next jr lnscan lnscan1: ld (hl),b ; B=0 ld de,(tailst) ; Set ptr to first token pop bc ; Get arg count ; DE pts to first token of command line ; Store command line (next token) into TBUFF go2: push de ; Save ptr to first token djnz go3 ; See if any tokens follow the command name ; If no more tokens, then zero gbuff ld hl,gbuff ; Store empty command line into gbuff ld (hl),b ; B=0. inc hl ld (hl),b jr gcline ; Save command line tail into GBUFF go3: inc de ; Pt to next token inc de ld a,(de) ; Get address ld l,a inc de ld a,(de) ld h,a ; Hl pts to first token of command line tail ld de,gbuff+1 ; Pt to command line buffer (char after) ld a,' ' ld (de),a ; Store leading space inc de ld b,1 ; Set char count to 1 cltsave: ld a,(hl) ; Get next char ld (de),a ; Store it or a ; Eol? jr z,cltsdone inc hl ; Pt to next inc de inc b ; Increment count jr cltsave cltsdone: ld a,b ; Get count ld (gbuff),a ; Set count in local buffer. gcline: call retud ; C=current user call getefcb ; Clear external fcb call nz,clrfcb ld hl,fcb1 ; Clear fcb1 call clrfcb ld hl,fcb2 ; Clear fcb2 call clrfcb pop hl ; Get ptr to first token ld a,(hl) ; Get address inc hl ld h,(hl) ld l,a ; Hl pts to first token ld de,args ; Use same argument vector table ld a,0ffh ; Null-terminate arguments call argv ld c,0 ; Up to 3 tokens to obtain ld de,argv1 ; Pt to first token ld a,(argc) ; Get argument count cp 4 ; Range? jr c,go4 ld a,3 ; Set 3 tokens go4: ld b,a ; In c ; There are three tokens (max) to be extracted: ; Program name (external FCB) ; FCB 1 ; FCB 2 go5: push bc ; Save counters call namebld ; Build token pop bc ; Get counters inc c ; Increment token id djnz go5 call getefcb ; Set file type to com for external fcb jr z,go6 ; No external fcb ld de,9 ; Offset add hl,de ld de,comtyp ; File type ex de,hl ld bc,3 ; 3 bytes ldir ; Locate LBR file go6: call find$lf jr nz,chekws ; Abort if not found ; Load Command from Library into Memory Above LRUN call loadcom ; Extract and load to high RAM. jr nz,autoin ; Do Z3 install if successful. chekws: ld a,(1) ; Test for the WordStar kludge. cp 3 jp nz,getud ; Reassert orig. DU and exit. ld hl,clineb ; Point at local MCL copy start. ld a,(hl) ; Get first character. or a ; Were we forced ECP (/)? jr nz,adjmcl ; Then adjust MCL bffr. call getcst ; Get Command Status Flag. ld b,a bit 2,a ; Real ECP? jr nz,exterr ; Then just set CSF error bit. call z33chk ; Running ZCPR 3.3? jr nz,goter3 ; Then just set ECP, error bits. set 3,b ; Otherwise external source... call geter3 ; Get current Z33 error #. cp 7 ; Higher than "default" (#6)? jr nc,goter3 ; Then use it. ld a,10 ; Otherwise set error #10. call puter3 ; Stuff it. goter3: ld a,b ; Get back CSF. jr errext ; Set ECP, error bits and stuff. adjmcl: ld de,args ; Pt to ARGV table xor a ; Don't delimit tokens call argv ; Get vector of tokens in MCL ld hl,(argv3) ; Pt to 3rd token ld a,(hl) ; Get first char cp '-' ; '-' means LBR name jr nz,foundl ; If not, MCL begins here ld hl,(argv4) ; else, get next token foundl: call clrcl ; Otherwise clear it. call putcl ; Replace it, sans the LX verb and ; ..possible LBR name. call getcst ; Get Cmd. Status Flag (again). errext: set 2,a ; Set ECP bit. exterr: set 1,a ; Set error bit. jp putcst ; Put 'em in CSF and we're done, ; return via Z3LIB routine ; Perform Auto-Install if this is a ZCPR3 utility autoin: ld ix,(scratch) ld de,z3ename ; DE -> "Z3ENV" in this program ld b,5 ; compare 5 bytes instal0: ld a,(de) ; Compare "Z3ENV" with location in cp (ix+3) ; the loaded program that would have it jr nz,install ; jump if no match - NOT a ZCPR3 utility inc de inc ix ; index through the 5 bytes djnz instal0 ld de,(z3eadr) ; This is a ZCPR3 utility ld (ix+4),e ; Store the environment address ld (ix+5),d ld a,(ix+3) ; Get environment type byte cp 3 ; Check for type < 2 jr c,install ; Branch if standard-TPA tool ld e,(ix+6) ; Runtime address into DE ld d,(ix+7) ld (cpytpa),de ; Initialize data for copy ; routine and fall through install: ; Set up TBUFF area push hl ; save address of next block after load ld hl,gbuff ; Ptr to local buffer ld de,tbuff ; Ptr to tbuff ld bc,128 ; 128 bytes ldir pop de ; Get address of next block after load ; Set up to Copy command down and execute ; DE = next block after load call copyset ; Place copy routine in high memory call getud ; Return to home directory ld hl,tbuff ; Set default dma address call setdma ; Ready to copy program down and transfer to it ; The original return address is on the top of the stack ld a,(tpaend) ; Get address in hl ld h,a ld l,0 jp (hl) ; Process copy command ; Clear FCB pted to by HL ; Current user area is in C clrfcb: ld (hl),0 ; Current disk inc hl ; Pt to name ld b,11 ; 11 bytes ld a,' ' ; Space fill call fill ld (hl),0 ; Null inc hl ld (hl),c ; User area (byte 13) inc hl ld b,4 ; Number of bytes xor a ; Fill with zeroes and ; fall through to FILL ; Fill B bytes pted to by HL with A fill: ld (hl),a ; Fill inc hl ; Pt to next djnz fill ret ; Build name of token whose address is pted to by DE ; On input, C=flag: ; 0 Name of program ; 1 FCB 1 ; 2 FCB 2 namebld: ld a,(de) ; Get address of token in hl ld l,a inc de ld a,(de) ld h,a inc de push de ; Save ptr to next ld a,c ; Check flag cp 1 ; Middle value jr c,namexfcb ; External fcb if 0 ld de,fcb1 ; Assume fcb jr z,nameb1 ; Fcb 1 if 1 ld de,fcb2 ; Else fcb2 jr nameb1 namexfcb: ex de,hl ; Save hl call getefcb ; Get ptr to external fcb ex de,hl ; Hl pts to token, de pts to external fcb jr nz,nameb1 ; Proceed if external fcb exists pop de ; External fcb does not exist, so quit ret ; DE pts to FCB to build into, HL pts to token nameb1: push de ; Save fcb ptr ld de,lfcb ; Pt to local fcb call parse ; Parse into local fcb call getwhl ; Check wheel byte jr nz,nameb2 ; Continue with name build if wheel ; User is not a wheel, so force all directory references to current dir call retud ; Get current user in c ld hl,lfcb ; Pt to fcb ld (hl),0 ; Set current disk ld de,13 ; Offset to user add hl,de ld (hl),c ; Set current user into lfcb ; Store FCB data into FCB nameb2: pop de ; Get ptr to target fcb ld hl,lfcb ; Pt to fcb ld bc,17 ; Copy 17 bytes ldir pop de ; Get ptr to next token ret ; Place copy routine in high memory ; COM file runs from (SCRATCH) to DE copyset: ld hl,(scratch) ; Get start ex de,hl or a ; Clear carry sbc hl,de ; Hl=hl-de=size of load ld (copy$count),hl ; Set count for copy routine ld a,(tpaend) ; Set de to location of copy routine ld d,a ld e,0 ; Page boundary ld hl,copy$code ; Copy code ld bc,copy$size ; Number of bytes ldir ; Place copy routine ret ; Copy routine - this will be placed in High Memory ; The 2-byte values at COPY$STRT, COPY$DEST, COPY$COUNT ; and COPY$TPA are set by COPYSET (above) and AUTOIN copy$code: ld hl,(z3eadr) push hl ld hl,(scratch) ; Start address ld de,(cpytpa) ; Destination address push de pop ix ld bc,(copy$count) ; Number of bytes ldir ; Do copy pop hl ; Environment pointer in HL. jp (ix) ; Jump to the program. copy$size equ $-copy$code ; Locate Library File ; On exit, A=0 if library file found find$lf: ld hl,(libname) ; Parse library file name ld de,lud$fcb call parse ld de,lud$fcb+9 ; Set library file type ld hl,lbrtyp ; Default file type ld bc,3 ; 3 bytes ldir ; Set specified directory as default ld de,lud$fcb ; Pt to fcb call z3log ; Log into it for default ; Look into directory pted to by user (or current if user did not spec one) ld de,lud$fcb ; Pt to fcb call initfcb ; Reset fcb call retud ; Get home location call f$exist ; Is file there? jr nz,find$lf2 ; Look along path from current dir (not including current) ld de,lud$fcb ; Pt to fcb xor a ; Don't search current dir also call pfind ; Search for file jr nz,find$lf2 ; File found, so process ; File not found find$lf1: call getquiet ; Are we muzzled? ret nz ; Return NZ if so (A=FFh). call eprint db ' Library File ',0 ld de,lud$fcb+1 ; Print file name call pfn2;1 call eprint db ' Not Found',0 or 0ffh ; Error code (NZ & A=FFh) ret ; File found find$lf2: call logud ; Log into directory ld de,lud ; Pt to lud call luinit ; Read to use library jr nz,find$lf1 ; Error ret ; Load COM file into memory ; on exit, NZ if OK and HL = next block loadcom: ld de,argv1 ; Pt to command name string ld a,(de) ; Get address in hl ld l,a inc de ld a,(de) ld h,a ld de,lfcb ; Pt to fcb call parse ; Parse into fcb ld hl,9 ; Set type of file to 'com' add hl,de ld de,comtyp ; File type ex de,hl ld bc,3 ; 3 bytes ldir ld de,lud ; Pt to lud ld hl,lfcb ; Pt to fcb inc hl ; Pt to file name call luopen ; Open file ld hl,(scratch) ; Pt to buffer jr z,lcom ; Load command if no error call getquiet ; Muzzled? jr nz,noprnt ; Skip msg. if so call eprint ; Otherwise fall through db ' File ',0 ld de,lfcb+1 ; Pt to FBC's file name ASCII. call pfn2 call eprint db ' Not Found in Library ',0 ld de,lud$fcb+1 ; Pt to library file name call pfn2 noprnt: xor a ; Error ret lcom: call setdma ; Set dma address ld a,(tpaend) ; Check against end page of tpa cp h ; If at same page, yes jr z,lcomerror ld de,lud ; Pt to lud call luread ; Read block ret nz ld de,128 ; Pt to next block add hl,de jr lcom lcomerror: call getquiet jr nz,qlcom call eprint db ' Memory Full',0 qlcom: call z33chk jr nz,notz33 ld a,12 call puter3 notz33: xor a ; Error code ret ; Set DMA Address to that pted to by HL ; setdma: push hl ; Save hl ex de,hl ld c,26 ; Set dma function call bdose pop hl ; Restore hl ret ; SYSLIB Module Name: SARGV ; Author: Richard Conn ; SYSLIB Version Number: 3.6 ; Module Version Number: 1.1 ; public argv ; ARGV is a UNIX-style ARGC/ARGV string parser. It is passed ; a null-terminated string in HL and the address of a token pointer ; table in DE as follows: ; LXI H,STRING ; LXI D,ARGV$TABLE ; MVI A,0 ; do not mark token end ; CALL ARGV ; JNZ TOKEN$OVFL ; indicates more tokens than allowed ; ... ; ARGV$TABLE: ; DB MAX$ENT ; max number of entries permitted ; DS 1 ; number of entries stored by ARGV ; DS 2 ; pointer to token 1 ; DS 2 ; pointer to token 2 ; ... ; DS 2 ; pointer to token MAX$ENT ; Tokens are delimited by spaces and tabs. ; As well as '='. 27 Feb 86 jww ; On input, if A=0, the end of each token is not marked with a null. ; If A<>0, a null is placed after the last byte of each token. ; If all went well, return with A=0 and Zero Flag set. If there ; are possibly more tokens than pointers, return with A=0FFH and NZ. argv: push bc ; save regs push de push hl ld c,a ; save mark flag ex de,hl ld b,(hl) ; get max entry count push hl ; save address of max entry count inc hl ; pt to token count inc hl ; pt to first pointer ; On each loop, DE = address of next char in string and HL = address of ; next pointer buffer; B = number of pointer buffers remaining and C = ; mark flag (0 = no mark) loop: call sksp ; skip spaces and tabs in string pted to by DE or a ; end of string? jr z,done ld (hl),e ; store low inc hl ld (hl),d ; store high inc hl dec b ; count down jr z,loop2 call sknsp ; skip until end of token or a ; done? jr z,done ld a,c ; get mark flag or a ; 0=no mark jr z,loop1 xor a ; mark with null ld (de),a ; store null inc de ; pt to next char loop1: ld a,b ; check count or a jr nz,loop ; continue on loop2: call sknsp ; skip over token call sksp ; any tokens left? or a jr z,done ; none if EOL or 0ffh ; make A = 0FFH to indicate more to come done: pop hl ; get address of max token count push af ; save return flags ld a,(hl) ; get max token count sub b ; subtract counter inc hl ; pt to return count ld (hl),a ; set return count pop af ; get return flag pop hl ; restore regs pop de pop bc ret ; Skip over space or tab characters sksp: ld a,(de) ; get char and 7fh ; mask inc de ; pt to next cp ' ' ; continue if space jr z,sksp cp 9 ; continue if tab jr z,sksp dec de ; pt to character ret ; Skip over non-space and non-tab characters ; Added '=' so that A:=B: construct yields two arguments. v1.1 jww sknsp: ld a,(de) ; get char and 7fh ; mask ret z ; done if null cp ' ' ret z ; done if space cp 9 ret z ; done if tab cp '=' ret z ; new delimiter inc de ; pt to next jr sknsp ; end ; End of argv inclusion ; Console character output "routine". ; Unlike SYSLIB's COUT, this one will ; work under WordStar's "R" option. ; b/m, June 3, 1987 cout: jp bout ; PUBLIC label for EPRINT, etc. ; Parses token pointed to by HL into FCB pointed to ; by DE. If Z33 running, uses resident CPR code, otherwise ; uses ZPRSFN. This ensures full ZCPR33 compatibility. parse: call z33chk ld a,0 ; DIR first for ZPRSFN jp nz,zprsfn jp z33fname ; Filetype strings lbrtyp: db 'LBR' ; Default lbr file type comtyp: db 'COM' ; Default com file type ; Data Area dseg ; To minimize COMfile size args: ; ARGV argument table ; db 4 ds 1 ; Will init. to allow up to 4 argc: ds 1 ; Argument count argv1: ds 2 ; First argument argv2: ds 2 ; Second argument argv3: ds 2 ; Third argument argv4: ds 2*3 ; 3 more arguments tailst: ds 2 ; Start of actual command tail lud: ds 6 ; Dummy used by lu* routines ds 11 ; Not of concern here lud$fcb: ds 36 ; Fcb containing library file data ; General-purpose LX Buffers & Pointers. tpaend: ds 1 ; Top page of tpa (msb) gbuff: ds 128 ; Command line save area lfcb: ds 36 ; Local fcb cmdline: ds 128 ; Saved command line buffer clineb: ds 256 ; Saved MCL buffer scratch: ds 2 ; Free space start libname: ds 2 ; For relocated COPY$CODE routine cpytpa: ds 2 ; COMfile runtime origin copy$count: ds 2 ; COMfile length in bytes end