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 / A-R / LX19.LBR / LX19.ZZ0 / LX19.Z80
Text File  |  2000-06-30  |  26KB  |  982 lines

  1.     title    'LX VERSION 1.8 - RUN PROGRAM FROM COMMAND.LBR'
  2.  
  3. ;  PROGRAM: LX
  4. ;  AUTHOR: RICHARD CONN
  5. ;  VERSION: 1.0
  6. ;  DATE: 10 Aug 85
  7. ;  PREVIOUS VERSIONS: None
  8.  
  9. vers    equ    19    ; Corrected help screen, safety header added,
  10.             ; restored Royce Shofner's wheel byte idea in
  11.             ; a simpler way.  An option byte at 102h
  12.             ; controls LX19's wheel byte response.    If it
  13.             ; is patched to a zero (0FFh in distributed
  14.             ; COM/CIM files), LX19 will test the wheel
  15.             ; byte and use ROOT:USERCMD.LBR instead of
  16.             ; ROOT:COMMAND.LBR if not wheel (wheel byte
  17.             ; is reset, zeroed).  Otherwise LX19 will
  18.             ; work like LX18 did - very nicely.  Both
  19.             ; Default LBR names remain patchable to
  20.             ; preference.
  21.             ; April 1, 1988     Bruce Morgen
  22.  
  23. ;vers    equ    18    ; Rewrote the ADJCML routine.  IT NOW ADJUSTS
  24.             ; THE COMMAND LINE PROPERLY WHEN A LIBRARY
  25.             ; NAME WAS INCLUDED IN THE COMMAND.
  26.             ;
  27.             ; Howard Goldstein, November 29, 1987
  28.  
  29. ;vers    equ    17    ; Added code to parse file names via
  30.             ; resident CPR code if ZCPR33 is present.
  31.             ; This makes LX completely Z33 compatible.
  32.             ; Removed Bruce Morgen's in-line PUTER3
  33. ;            ; code since Z33LIB's version works properly
  34.             ; now.
  35.             ;
  36.             ; Howard Goldstein, November 21, 1987
  37.  
  38. ;vers    equ    16    ; Deleted vestigial buffer set-up code via
  39.             ; DSEGed buffer definitions.  LX now does
  40.             ; a better simulation of the 3.3 CPR by
  41.             ; passing the environment descriptor pointer
  42.             ; in HL as well as poking ORG+9 in Z3 tools.
  43.             ; Added detection code for LX running under
  44.             ; WordStar.  A new alternate syntax has been
  45.             ; introduced especially for chaining to LX
  46.             ; from ARUNZ's "default alias" feature:
  47.             ; :DEFAULT [dir or du:]LX / $0 $*
  48.             ; Under that condition, or whenever LX is
  49.             ; called with the intervening "/" parameter,
  50.             ; LX will declare itself an ECP and, if there
  51.             ; is an error, adjust the command line to
  52.             ; eliminate its own verb.  If running under
  53.             ; Z33, LX follows the CPR's DUFIRST flag.
  54.             ; All errors (except under WordStar) now abort
  55.             ; to the error handler with the ECP bit set
  56.             ; on return to the CPR.  While we were at it,
  57.             ; replaced the internal COUT routine with a
  58.             ; simple JP to BOUT to accomodate BIOS's
  59.             ; that (legitimately) do not bother to preserve
  60.             ; the HL register through CONOUT calls. The
  61.             ; BOUT approach ALWAYS (famous last words)
  62.             ; works, and is shorter to "bout" (grin).  The
  63.             ; reason there is a hand-coded PUTER3 routine
  64.             ; in LX is that Z33LIB's fails to preserve the
  65.             ; incoming A register against GETMSG's return.
  66.             ; In other words, it doesn't work.
  67.             ;
  68.             ; Bruce Morgen @23:55:56 June 4, 1987
  69.  
  70. ;vers    equ    15    ; Adapted to coexist as an ECP with error
  71.             ; handling under ZCPR 3.3 and BGii 1.13 or
  72.             ; later.  Also extended Michael's auto-
  73.             ; install code to properly initialize the
  74.             ; copy routine for Z33 type 2 COMfiles
  75.             ; (origin other than 100H).  Bumped versions
  76.             ; past 1.3 & 1.4, which seem to be of interest
  77.             ; mainly to Z-Node sysops (no offense, Royce,
  78.             ; just a personal opinion - b/m).  Note that
  79.             ; there is a problem regarding SYSLIB's
  80.             ; CODEND routine and the use of DSEG as
  81.             ; recommended for the upcoming Z80 versions
  82.             ; of the Conn *LIBs.  The old approach (the
  83.             ; $MEMRY buffer in CSEG) has been recommended
  84.             ; to the LIBs revision team.  All modifiable
  85.             ; LX data buffers are now in DSEG, including
  86.             ; the (now runtime-initialized) ARGV argument
  87.             ; table.  While I was at  it, I got rid of the
  88.             ; unecessary self-modifying code at COPY$CODE.
  89.             ; Remember, we won't be able to get away with
  90.             ; such kludges with the Z280, so we might as
  91.             ; well start getting rid of our bad habits now.
  92.             ; Note that LX now carries its own COUT routine
  93.             ; to enable showing an error or a help screen
  94.             ; under the WordStar "R" command without
  95.             ; crashing anyone's system to a fare-thee-well.
  96.             ; Bruce Morgen @15:03:03 April 24, 1987
  97.  
  98. ;vers    equ    12    ; Auto-installs ZCPR3 utilities.  There is no
  99.             ; need to run Z3INS on utilities run by LX
  100.             ; since, after loading and before executing,
  101.             ; LX looks for "Z3ENV" at the beginning.  If
  102.             ; present, LX inserts the address of the
  103.             ; environment descriptor.  Both concept and
  104.             ; code are based on Jay Sage's experimental CCP.
  105.             ; 3 September 1986 - Michael Bate
  106.  
  107. ;vers    equ    11    ; Extracted ARGV from syslib36 and included
  108.             ; it here, modified so that '=' is also an
  109.             ; argument delimiter if it occurs after
  110.             ; a non-space (sknsp:).  27 Feb 86  jww
  111.  
  112. ;vers    equ    10    ; Release version
  113.  
  114. z3env    defl    0fe00h    ; My Z3 environment location
  115.  
  116.  
  117. ;    LX is like the old LRUN tools in that it looks at its arguments
  118. ; as a command line to be executed.  LX locks onto a library file, searches
  119. ; for the command verb COM file in it, extracts the COM file into memory
  120. ; at 100H, and sets up the various buffers to look like the COM file was
  121. ; executed by the ZCPR3 command processor.
  122.  
  123. ;    Unlike the other LRUN tools I've seen and heard of (with the
  124. ; possible exception of LRUNZ), LX truly acts as the ZCPR3 command
  125. ; processor, parsing the command line as ZCPR3 itself would.  Named
  126. ; directory references are allowed, the External FCB is loaded if
  127. ; available, etc.  Any ZCPR3 tool executed by LX sees the environment
  128. ; as it would if ZCPR3 itself executed the tool.
  129.  
  130. ;    For security, no directory references are allowed (they are
  131. ; ignored) for any arguments if the wheel byte is not set.
  132.  
  133.  
  134.  
  135.     public    cout        ; b/m, April 24, 1987
  136.  
  137. ;  Externals
  138.  
  139.     extrn    z3init,codend
  140.     extrn    eprint,retud,putud,logud,getud;,pfn1
  141.     extrn    initfcb,f$exist
  142.     extrn    getefcb,zprsfn,z3log,pfind,getwhl
  143.     extrn    luinit,luopen,luread
  144.     extrn    getcst,putcst                ; b/m April 24, 1987
  145.     extrn    getcl1,clrcl,putcl,getquiet,bout,pfn2    ; b/m June 3, 1987
  146.     extrn    z33chk,geter3,getmsg; Z33LIB, etc. b/m June 4, 1987
  147.     extrn    z33fname,puter3; h/g Nov. 21, 1987
  148.  
  149. ;  Equates
  150.  
  151. cr    equ    0dh
  152. lf    equ    0ah
  153. bdose    equ    5
  154. fcb1    equ    5ch
  155. fcb2    equ    6ch
  156. tbuff    equ    80h
  157. tpa    equ    100h
  158. lnsize    equ    22        ; Number of chars allowed for library name
  159.  
  160.  
  161. ; External ZCPR3 Environment Descriptor
  162.  
  163. ; TYPE 3 HEADER
  164.  
  165. ; Code modified as suggested by Charles Irvine to function correctly with
  166. ; interrupts enabled.  Program will abort with an error message when not
  167. ; loaded to the correct address (attempt to run it under CP/M or Z30).
  168.  
  169. entry:
  170.     jr    start0            ; Must use relative jump
  171. option:    db    0ffh            ; Make zero for wheel byte
  172.                     ; control of default LBR
  173. z3ename:
  174.     db    'Z3ENV',3        ; Type-3 environment
  175. z3eadr:
  176.     dw    z3env            ; Filled in by Z33
  177.     dw    entry            ; Intended load address
  178.  
  179. start0:
  180.     ld    hl,0            ; Point to warmboot entry
  181.     ld    a,(hl)            ; Save the byte there
  182.     di                ; Protect against interrupts
  183.     ld    (hl),0c9h        ; Replace warmboot with a return opcode
  184.     rst    0            ; Call address 0, pushing RETADDR
  185.                     ; onto stack
  186. retaddr:
  187.     ld    (hl),a            ; Restore byte at 0
  188.     dec    sp            ; Get stack pointer to point
  189.     dec    sp            ; To the value of RETADDR
  190.     pop    hl            ; Get it into HL and restore stack
  191.     ei                ; We can allow interrupts again
  192.     ld    de,retaddr        ; This is where we should be
  193.     xor    a            ; Clear carry flag
  194.     push    hl            ; Save address again
  195.     sbc    hl,de            ; Subtract -- we should have 0 now
  196.     pop    hl            ; Restore value of RETADDR
  197.     jr    z,start            ; If addresses matched, begin real code
  198.  
  199.     ld    de,notz33msg-retaddr    ; Offset to message
  200.     add    hl,de
  201.     ex    de,hl            ; Switch pointer to message into DE
  202.     ld    c,9
  203.     jp    0005h            ; Return via BDOS print string function
  204. notz33msg:
  205.     db    'Not Z33+$'        ; Abort message if not Z33-compatible
  206.  
  207.  
  208. ;  Names of Library Files
  209.  
  210. libnam1:
  211.     db    'ROOT:COMMAND.LBR',0
  212.     ds    lnsize-[$-libnam1]
  213. libnam2:
  214.     db    'ROOT:USERCMD.LBR',0
  215.     ds    lnsize-[$-libnam2]
  216. ;  Beginning of code; set buffer definitions here
  217.  
  218. start:
  219.     ld    hl,(z3eadr)    ; Pt to zcpr3 environment
  220.     call    z3init        ; Init zcpr3 environment
  221. start1:
  222.     ld    a,(bdose+2)    ; Get bdos base page
  223.     sub    a,9        ; 9 pages below bdos is 1 page below ccp
  224.     ld    (tpaend),a    ; Set end of tpa
  225.     call    codend        ; Get free space ptr
  226.     ld    (scratch),hl    ; Free space ptr
  227.     ld    hl,tpa        ; Default COMfile starting addr.
  228.     ld    (cpytpa),hl
  229.     ld    hl,argv2    ; Usual command tail start ptr.
  230.     ld    (tailst),hl
  231.     ld    hl,libnam1
  232.     ld    a,(option)
  233.     or    a
  234.     call    z,getwhl
  235.     jr    nz,nogwhl
  236.     ld    hl,libnam2
  237. nogwhl:    ld    (libname),hl
  238.     ld    de,clineb    ; Point to local buffer for MCL.
  239.     ld    a,(1)        ; Test for WordStar BIOS table.
  240.     sub    a,3
  241.     jr    nz,savocl    ; Skip MCL if WS is running.
  242.     ld    (de),a        ; Init. local MCL buffer to 0.
  243.     ld    b,a        ; Make sure B=0.
  244.     call    getcst        ; Get Command Status Flag.
  245.     bit    2,a        ; Test ECP bit.
  246.     jr    nz,savocl    ; Skip MCL stuff if we're ECP.
  247.     ld    a,'/'        ; Check for help and forced ECP.
  248.     ld    hl,(fcb1+1)    ; Help "/" in H, ECP "/" in L.
  249.     cp    h        ; Test for help query
  250.     jr    z,help
  251.     sub    l        ; Test for forced ECP request.
  252.     jr    nz,savocl
  253.     call    getcl1        ; Find MCL buffer (B=0).
  254.     ld    c,a        ; MCL size is now in BC.
  255.     ld    a,l        ; Test for no MCL buffer.
  256.     or    h
  257.     jr    z,savocl    ; No MCL?  Then branch ahead...
  258.     inc    hl        ; Otherwise bump to MCL start.
  259.     inc    hl
  260.     inc    hl
  261.     inc    hl
  262.     ldir            ; Move MCL to local buffer.
  263.  
  264. ;  Save original command line
  265.  
  266. savocl:    ld    hl,tbuff+1    ; Copy from tbuff
  267.     ld    de,cmdline
  268.     ld    bc,128        ; 128 bytes
  269.     ldir
  270.  
  271. ;  Save home directory
  272.  
  273.     call    putud
  274.  
  275. ;  First parse of command line to determine if help needed, name of library
  276.  
  277.     ld    hl,cmdline    ; Pt to command line
  278.     ld    de,args        ; Pt to argument table
  279.     ld    a,5        ; Init. for five arguments
  280.     ld    (de),a        ; so table can be in DSEG
  281.     xor    a        ; Do not delimit tokens (A=0)
  282.     call    argv        ; Generate vector
  283.     ld    a,(argc)    ; Check count
  284.     ld    b,a        ; Save arg count in b
  285.     or    a        ; Help if no args
  286.     jr    z,help
  287.     ld    hl,(argv1)    ; Get ptr to first arg
  288.     ld    a,(hl)        ; Get first char of first arg
  289.     cp    '/'
  290.     jp    nz,go1        ; Skip help if not /
  291.     djnz    goecp        ; Should ALWAYS jump, but W.T.H.
  292.  
  293.  
  294. ;  Print Help Message
  295.  
  296. help:
  297.     call    eprint
  298.     db    'LX, Version '
  299.     db    [vers/10]+'0','.',[vers    mod 10]+'0'
  300.     db    cr,lf,' Syntax: LX [/] [-[dir:]library] command_line'
  301.     db    cr,lf,' (Use "/" option when chaining from ARUNZ'
  302.     db    ' default alias)',0
  303.     ret
  304.  
  305. ; Adjust vectors for forced-ECP mode
  306.  
  307. goecp:    ld    de,argv2
  308.     ld    hl,argv3
  309.     ld    (tailst),hl
  310.     ld    hl,(argv2)
  311.     ld    a,(hl)
  312.     jr    goecp1
  313.  
  314. ;  Continue processing; check for and process library reference
  315.  
  316. go1:
  317.     ld    de,argv1    ; Set pointer for first token
  318. goecp1:
  319.     cp    '-'        ; Library reference?
  320.     jr    nz,go2
  321.     dec    b        ; Reduce argument count by 1
  322.     jp    z,help        ; Library name by itself is not enough
  323.  
  324. ;  Extract and store library reference
  325.  
  326.     push    bc        ; Save arg count
  327.     ld    de,(libname)    ; Set library name
  328.     push    de        ; Save on stack
  329.     inc    hl        ; Pt to name
  330.     ld    bc,lnsize    ; Size of buffer
  331.     ldir            ; BC=00
  332.     pop    hl        ; Terminate name with zero
  333. lnscan:
  334.     ld    a,(hl)        ; Get next char
  335.     cp    ' '        ; Done?
  336.     jr    z,lnscan1
  337.     or    a
  338.     jr    z,lnscan1
  339.     inc    hl        ; Pt to next
  340.     jr    lnscan
  341. lnscan1:
  342.     ld    (hl),b        ; B=0
  343.     ld    de,(tailst)    ; Set ptr to first token
  344.     pop    bc        ; Get arg count
  345.  
  346. ;  DE pts to first token of command line
  347. ;  Store command line (next token) into TBUFF
  348.  
  349. go2:
  350.     push    de        ; Save ptr to first token
  351.     djnz    go3        ; See if any tokens follow the command name
  352.                 ; If no more tokens, then zero gbuff
  353.     ld    hl,gbuff    ; Store empty command line into gbuff
  354.     ld    (hl),b        ; B=0.
  355.     inc    hl
  356.     ld    (hl),b
  357.     jr    gcline
  358.  
  359. ;  Save command line tail into GBUFF
  360.  
  361. go3:
  362.     inc    de        ; Pt to next token
  363.     inc    de
  364.     ld    a,(de)        ; Get address
  365.     ld    l,a
  366.     inc    de
  367.     ld    a,(de)
  368.     ld    h,a        ; Hl pts to first token of command line tail
  369.     ld    de,gbuff+1    ; Pt to command line buffer (char after)
  370.     ld    a,' '
  371.     ld    (de),a        ; Store leading space
  372.     inc    de
  373.     ld    b,1        ; Set char count to 1
  374. cltsave:
  375.     ld    a,(hl)        ; Get next char
  376.     ld    (de),a        ; Store it
  377.     or    a        ; Eol?
  378.     jr    z,cltsdone
  379.     inc    hl        ; Pt to next
  380.     inc    de
  381.     inc    b        ; Increment count
  382.     jr    cltsave
  383. cltsdone:
  384.     ld    a,b        ; Get count
  385.     ld    (gbuff),a    ; Set count in local buffer.
  386. gcline:
  387.     call    retud        ; C=current user
  388.     call    getefcb        ; Clear external fcb
  389.     call    nz,clrfcb
  390.     ld    hl,fcb1        ; Clear fcb1
  391.     call    clrfcb
  392.     ld    hl,fcb2        ; Clear fcb2
  393.     call    clrfcb
  394.     pop    hl        ; Get ptr to first token
  395.     ld    a,(hl)        ; Get address
  396.     inc    hl
  397.     ld    h,(hl)
  398.     ld    l,a        ; Hl pts to first token
  399.     ld    de,args        ; Use same argument vector table
  400.     ld    a,0ffh        ; Null-terminate arguments
  401.     call    argv
  402.     ld    c,0        ; Up to 3 tokens to obtain
  403.     ld    de,argv1    ; Pt to first token
  404.     ld    a,(argc)    ; Get argument count
  405.     cp    4        ; Range?
  406.     jr    c,go4
  407.     ld    a,3        ; Set 3 tokens
  408. go4:
  409.     ld    b,a        ; In c
  410.  
  411. ;  There are three tokens (max) to be extracted:
  412. ;    Program name (external FCB)
  413. ;    FCB 1
  414. ;    FCB 2
  415.  
  416. go5:
  417.     push    bc        ; Save counters
  418.     call    namebld        ; Build token
  419.     pop    bc        ; Get counters
  420.     inc    c        ; Increment token id
  421.     djnz    go5
  422.     call    getefcb        ; Set file type to com for external fcb
  423.     jr    z,go6        ; No external fcb
  424.     ld    de,9        ; Offset
  425.     add    hl,de
  426.     ld    de,comtyp    ; File type
  427.     ex    de,hl
  428.     ld    bc,3        ; 3 bytes
  429.     ldir
  430.  
  431. ;  Locate LBR file
  432.  
  433. go6:
  434.     call    find$lf
  435.     jr    nz,chekws    ; Abort if not found
  436.  
  437. ;  Load Command from Library into Memory Above LRUN
  438.  
  439.     call    loadcom        ; Extract and load to high RAM.
  440.     jr    nz,autoin    ; Do Z3 install if successful.
  441.  
  442. chekws:    ld    a,(1)        ; Test for the WordStar kludge.
  443.     cp    3
  444.     jp    nz,getud    ; Reassert orig. DU and exit.
  445.     ld    hl,clineb    ; Point at local MCL copy start.
  446.     ld    a,(hl)        ; Get first character.
  447.     or    a        ; Were we forced ECP (/)?
  448.     jr    nz,adjmcl    ; Then adjust MCL bffr.
  449.     call    getcst        ; Get Command Status Flag.
  450.     ld    b,a
  451.     bit    2,a        ; Real ECP?
  452.     jr    nz,exterr    ; Then just set CSF error bit.
  453.     call    z33chk        ; Running ZCPR 3.3?
  454.     jr    nz,goter3    ; Then just set ECP, error bits.
  455.     set    3,b        ; Otherwise external source...
  456.     call    geter3        ; Get current Z33 error #.
  457.     cp    7        ; Higher than "default" (#6)?
  458.     jr    nc,goter3    ; Then use it.
  459.     ld    a,10        ; Otherwise set error #10.
  460.     call    puter3        ; Stuff it.
  461. goter3:    ld    a,b        ; Get back CSF.
  462.     jr    errext        ; Set ECP, error bits and stuff.
  463.  
  464. adjmcl:    ld    de,args        ; Pt to ARGV table
  465.     xor    a        ; Don't delimit tokens
  466.     call    argv        ; Get vector of tokens in MCL
  467.     ld    hl,(argv3)    ; Pt to 3rd token
  468.     ld    a,(hl)        ; Get first char
  469.     cp    '-'        ; '-' means LBR name
  470.     jr    nz,foundl    ; If not, MCL begins here
  471.     ld    hl,(argv4)    ; else, get next token
  472. foundl:    call    clrcl        ; Otherwise clear it.
  473.     call    putcl        ; Replace it, sans the LX verb and
  474.                 ; ..possible LBR name.
  475.     call    getcst        ; Get Cmd. Status Flag (again).
  476. errext:    set    2,a        ; Set ECP bit.
  477. exterr:    set    1,a        ; Set error bit.
  478.     jp    putcst        ; Put 'em in CSF and we're done,
  479.                 ; return via Z3LIB routine
  480.  
  481.  
  482. ;  Perform Auto-Install if this is a ZCPR3 utility
  483.  
  484.  
  485. autoin:    ld    ix,(scratch)
  486.     ld    de,z3ename    ; DE -> "Z3ENV" in this program
  487.     ld    b,5        ; compare 5 bytes
  488. instal0:
  489.     ld    a,(de)        ; Compare "Z3ENV" with location in
  490.     cp    (ix+3)        ; the loaded program that would have it
  491.     jr    nz,install    ; jump if no match - NOT a ZCPR3 utility
  492.     inc    de
  493.     inc    ix        ; index through the 5 bytes
  494.     djnz    instal0
  495.     ld    de,(z3eadr)    ; This is a ZCPR3 utility
  496.     ld    (ix+4),e    ; Store the environment address
  497.     ld    (ix+5),d
  498.     ld    a,(ix+3)    ; Get environment type byte
  499.     cp    3        ; Check for type < 2
  500.     jr    c,install    ; Branch if standard-TPA tool
  501.     ld    e,(ix+6)    ; Runtime address into DE
  502.     ld    d,(ix+7)
  503.     ld    (cpytpa),de    ; Initialize data for copy
  504.                 ; routine and fall through
  505.  
  506. install:
  507.  
  508. ;  Set up TBUFF area
  509.  
  510.     push    hl        ; save address of next block after load
  511.     ld    hl,gbuff    ; Ptr to local buffer
  512.     ld    de,tbuff    ; Ptr to tbuff
  513.     ld    bc,128        ; 128 bytes
  514.     ldir
  515.     pop    de        ; Get address of next block after load
  516.  
  517. ;  Set up to Copy command down and execute
  518. ;  DE = next block after load
  519.  
  520.     call    copyset        ; Place copy routine in high memory
  521.     call    getud        ; Return to home directory
  522.     ld    hl,tbuff    ; Set default dma address
  523.     call    setdma
  524.  
  525.  
  526. ;  Ready to copy program down and transfer to it
  527. ;  The original return address is on the top of the stack
  528.  
  529.     ld    a,(tpaend)    ; Get address in hl
  530.     ld    h,a
  531.     ld    l,0
  532.     jp    (hl)        ; Process copy command
  533.  
  534.  
  535. ;  Clear FCB pted to by HL
  536. ;  Current user area is in C
  537.  
  538. clrfcb:
  539.     ld    (hl),0        ; Current disk
  540.     inc    hl        ; Pt to name
  541.     ld    b,11        ; 11 bytes
  542.     ld    a,' '        ; Space fill
  543.     call    fill
  544.     ld    (hl),0        ; Null
  545.     inc    hl
  546.     ld    (hl),c        ; User area (byte 13)
  547.     inc    hl
  548.     ld    b,4        ; Number of bytes
  549.     xor    a        ; Fill with zeroes and
  550.                 ; fall through to FILL
  551.  
  552. ;  Fill B bytes pted to by HL with A
  553.  
  554. fill:
  555.     ld    (hl),a        ; Fill
  556.     inc    hl        ; Pt to next
  557.     djnz    fill
  558.     ret
  559.  
  560. ;  Build name of token whose address is pted to by DE
  561. ;  On input, C=flag:
  562. ;    0    Name of program
  563. ;    1    FCB 1
  564. ;    2    FCB 2
  565.  
  566. namebld:
  567.     ld    a,(de)        ; Get address of token in hl
  568.     ld    l,a
  569.     inc    de
  570.     ld    a,(de)
  571.     ld    h,a
  572.     inc    de
  573.     push    de        ; Save ptr to next
  574.     ld    a,c        ; Check flag
  575.     cp    1        ; Middle value
  576.     jr    c,namexfcb    ; External fcb if 0
  577.     ld    de,fcb1        ; Assume fcb
  578.     jr    z,nameb1    ; Fcb 1 if 1
  579.     ld    de,fcb2        ; Else fcb2
  580.     jr    nameb1
  581. namexfcb:
  582.     ex    de,hl        ; Save hl
  583.     call    getefcb        ; Get ptr to external fcb
  584.     ex    de,hl        ; Hl pts to token, de pts to external fcb
  585.     jr    nz,nameb1    ; Proceed if external fcb exists
  586.     pop    de        ; External fcb does not exist, so quit
  587.     ret
  588.  
  589. ;  DE pts to FCB to build into, HL pts to token
  590.  
  591. nameb1:
  592.     push    de        ; Save fcb ptr
  593.     ld    de,lfcb        ; Pt to local fcb
  594.     call    parse        ; Parse into local fcb
  595.     call    getwhl        ; Check wheel byte
  596.     jr    nz,nameb2    ; Continue with name build if wheel
  597.  
  598. ;  User is not a wheel, so force all directory references to current dir
  599.  
  600.     call    retud        ; Get current user in c
  601.     ld    hl,lfcb        ; Pt to fcb
  602.     ld    (hl),0        ; Set current disk
  603.     ld    de,13        ; Offset to user
  604.     add    hl,de
  605.     ld    (hl),c        ; Set current user into lfcb
  606.  
  607. ;  Store FCB data into FCB
  608.  
  609. nameb2:
  610.     pop    de        ; Get ptr to target fcb
  611.     ld    hl,lfcb        ; Pt to fcb
  612.     ld    bc,17        ; Copy 17 bytes
  613.     ldir
  614.     pop    de        ; Get ptr to next token
  615.     ret
  616.  
  617. ;  Place copy routine in high memory
  618. ;  COM file runs from (SCRATCH) to DE
  619.  
  620. copyset:
  621.     ld    hl,(scratch)    ; Get start
  622.     ex    de,hl
  623.     or    a        ; Clear carry
  624.     sbc    hl,de        ; Hl=hl-de=size of load
  625.     ld    (copy$count),hl    ; Set count for copy routine
  626.     ld    a,(tpaend)    ; Set de to location of copy routine
  627.     ld    d,a
  628.     ld    e,0        ; Page boundary
  629.     ld    hl,copy$code    ; Copy code
  630.     ld    bc,copy$size    ; Number of bytes
  631.     ldir            ; Place copy routine
  632.     ret
  633.  
  634. ;  Copy routine - this will be placed in High Memory
  635. ;  The 2-byte values at COPY$STRT, COPY$DEST, COPY$COUNT
  636. ;  and COPY$TPA are set by COPYSET (above) and AUTOIN
  637.  
  638. copy$code:
  639.     ld    hl,(z3eadr)
  640.     push    hl
  641.     ld    hl,(scratch)    ; Start address
  642.     ld    de,(cpytpa)    ; Destination address
  643.     push    de
  644.     pop    ix
  645.     ld    bc,(copy$count)    ; Number of bytes
  646.     ldir            ; Do copy
  647.     pop    hl        ; Environment pointer in HL.
  648.     jp    (ix)        ; Jump to the program.
  649. copy$size equ    $-copy$code
  650.  
  651.  
  652. ;  Locate Library File
  653. ;  On exit, A=0 if library file found
  654.  
  655. find$lf:
  656.     ld    hl,(libname)    ; Parse library file name
  657.     ld    de,lud$fcb
  658.     call    parse
  659.     ld    de,lud$fcb+9    ; Set library file type
  660.     ld    hl,lbrtyp    ; Default file type
  661.     ld    bc,3        ; 3 bytes
  662.     ldir
  663.  
  664. ;  Set specified directory as default
  665.  
  666.     ld    de,lud$fcb    ; Pt to fcb
  667.     call    z3log        ; Log into it for default
  668.  
  669. ;  Look into directory pted to by user (or current if user did not spec one)
  670.  
  671.     ld    de,lud$fcb    ; Pt to fcb
  672.     call    initfcb        ; Reset fcb
  673.     call    retud        ; Get home location
  674.     call    f$exist        ; Is file there?
  675.     jr    nz,find$lf2
  676.  
  677. ;  Look along path from current dir (not including current)
  678.  
  679.     ld    de,lud$fcb    ; Pt to fcb
  680.     xor    a        ; Don't search current dir also
  681.     call    pfind        ; Search for file
  682.     jr    nz,find$lf2    ; File found, so process
  683.  
  684. ;  File not found
  685.  
  686. find$lf1:
  687.     call    getquiet    ; Are we muzzled?
  688.     ret    nz        ; Return NZ if so (A=FFh).
  689.     call    eprint
  690.     db    ' Library File ',0
  691.     ld    de,lud$fcb+1    ; Print file name
  692.     call    pfn2;1
  693.     call    eprint
  694.     db    ' Not Found',0
  695.     or    0ffh        ; Error code (NZ & A=FFh)
  696.     ret
  697.  
  698.  
  699. ;  File found
  700.  
  701. find$lf2:
  702.     call    logud        ; Log into directory
  703.     ld    de,lud        ; Pt to lud
  704.     call    luinit        ; Read to use library
  705.     jr    nz,find$lf1    ; Error
  706.     ret
  707.  
  708.  
  709. ;  Load COM file into memory
  710. ;  on exit, NZ if OK and HL = next block
  711.  
  712. loadcom:
  713.     ld    de,argv1    ; Pt to command name string
  714.     ld    a,(de)        ; Get address in hl
  715.     ld    l,a
  716.     inc    de
  717.     ld    a,(de)
  718.     ld    h,a
  719.     ld    de,lfcb        ; Pt to fcb
  720.     call    parse        ; Parse into fcb
  721.     ld    hl,9        ; Set type of file to 'com'
  722.     add    hl,de
  723.     ld    de,comtyp    ; File type
  724.     ex    de,hl
  725.     ld    bc,3        ; 3 bytes
  726.     ldir
  727.     ld    de,lud        ; Pt to lud
  728.     ld    hl,lfcb        ; Pt to fcb
  729.     inc    hl        ; Pt to file name
  730.     call    luopen        ; Open file
  731.     ld    hl,(scratch)    ; Pt to buffer
  732.     jr    z,lcom        ; Load command if no error
  733.     call    getquiet    ; Muzzled?
  734.     jr    nz,noprnt    ; Skip msg. if so
  735.     call    eprint        ; Otherwise fall through
  736.     db    ' File ',0
  737.     ld    de,lfcb+1    ; Pt to FBC's file name ASCII.
  738.     call    pfn2
  739.     call    eprint
  740.     db    ' Not Found in Library ',0
  741.     ld    de,lud$fcb+1    ; Pt to library file name
  742.     call    pfn2
  743. noprnt:    xor    a        ; Error
  744.     ret
  745. lcom:
  746.     call    setdma        ; Set dma address
  747.     ld    a,(tpaend)    ; Check against end page of tpa
  748.     cp    h        ; If at same page, yes
  749.     jr    z,lcomerror
  750.     ld    de,lud        ; Pt to lud
  751.     call    luread        ; Read block
  752.     ret    nz
  753.     ld    de,128        ; Pt to next block
  754.     add    hl,de
  755.     jr    lcom
  756. lcomerror:
  757.     call    getquiet
  758.     jr    nz,qlcom
  759.     call    eprint
  760.     db    ' Memory Full',0
  761. qlcom:    call    z33chk
  762.     jr    nz,notz33
  763.     ld    a,12
  764.     call    puter3
  765. notz33:    xor    a        ; Error code
  766.     ret
  767.  
  768.  
  769. ;  Set DMA Address to that pted to by HL
  770. ;
  771. setdma:
  772.     push    hl        ; Save hl
  773.     ex    de,hl
  774.     ld    c,26        ; Set dma function
  775.     call    bdose
  776.     pop    hl        ; Restore hl
  777.     ret
  778.  
  779.  
  780. ; SYSLIB Module Name: SARGV
  781. ; Author: Richard Conn
  782. ; SYSLIB Version Number: 3.6
  783. ; Module Version Number: 1.1
  784.  
  785. ;    public    argv
  786.  
  787.  
  788. ;    ARGV is a UNIX-style ARGC/ARGV string parser.  It is passed
  789. ; a null-terminated string in HL and the address of a token pointer
  790. ; table in DE as follows:
  791.  
  792. ;        LXI    H,STRING
  793. ;        LXI    D,ARGV$TABLE
  794. ;        MVI    A,0        ; do not mark token end
  795. ;        CALL    ARGV
  796. ;        JNZ    TOKEN$OVFL    ; indicates more tokens than allowed
  797. ;        ...
  798. ;    ARGV$TABLE:
  799. ;        DB    MAX$ENT ; max number of entries permitted
  800. ;        DS    1    ; number of entries stored by ARGV
  801. ;        DS    2    ; pointer to token 1
  802. ;        DS    2    ; pointer to token 2
  803. ;        ...
  804. ;        DS    2    ; pointer to token MAX$ENT
  805.  
  806. ;    Tokens are delimited by spaces and tabs.
  807. ;    As well as '='.  27 Feb 86  jww
  808. ;    On input, if A=0, the end of each token is not marked with a null.
  809. ; If A<>0, a null is placed after the last byte of each token.
  810. ;    If all went well, return with A=0 and Zero Flag set.  If there
  811. ; are possibly more tokens than pointers, return with A=0FFH and NZ.
  812.  
  813. argv:
  814.     push    bc    ; save regs
  815.     push    de
  816.     push    hl
  817.     ld    c,a    ; save mark flag
  818.     ex    de,hl
  819.     ld    b,(hl)    ; get max entry count
  820.     push    hl    ; save address of max entry count
  821.     inc    hl    ; pt to token count
  822.     inc    hl    ; pt to first pointer
  823.  
  824. ; On each loop, DE = address of next char in string and HL = address of
  825. ; next pointer buffer; B = number of pointer buffers remaining and C =
  826. ; mark flag (0 = no mark)
  827.  
  828. loop:
  829.     call    sksp    ; skip spaces and tabs in string pted to by DE
  830.     or    a    ; end of string?
  831.     jr    z,done
  832.     ld    (hl),e    ; store low
  833.     inc    hl
  834.     ld    (hl),d    ; store high
  835.     inc    hl
  836.     dec    b    ; count down
  837.     jr    z,loop2
  838.     call    sknsp    ; skip until end of token
  839.     or    a    ; done?
  840.     jr    z,done
  841.     ld    a,c    ; get mark flag
  842.     or    a    ; 0=no mark
  843.     jr    z,loop1
  844.     xor    a    ; mark with null
  845.     ld    (de),a    ; store null
  846.     inc    de    ; pt to next char
  847. loop1:
  848.     ld    a,b    ; check count
  849.     or    a
  850.     jr    nz,loop    ; continue on
  851. loop2:
  852.     call    sknsp    ; skip over token
  853.     call    sksp    ; any tokens left?
  854.     or    a
  855.     jr    z,done    ; none if EOL
  856.     or    0ffh    ; make A = 0FFH to indicate more to come
  857. done:
  858.     pop    hl    ; get address of max token count
  859.     push    af    ; save return flags
  860.     ld    a,(hl)    ; get max token count
  861.     sub    b    ; subtract counter
  862.     inc    hl    ; pt to return count
  863.     ld    (hl),a    ; set return count
  864.     pop    af    ; get return flag
  865.     pop    hl    ; restore regs
  866.     pop    de
  867.     pop    bc
  868.     ret
  869.  
  870. ;  Skip over space or tab characters
  871.  
  872. sksp:
  873.     ld    a,(de)    ; get char
  874.     and    7fh    ; mask
  875.     inc    de    ; pt to next
  876.     cp    ' '    ; continue if space
  877.     jr    z,sksp
  878.     cp    9    ; continue if tab
  879.     jr    z,sksp
  880.     dec    de    ; pt to character
  881.     ret
  882.  
  883. ;  Skip over non-space and non-tab characters
  884. ;  Added '=' so that A:=B: construct yields two arguments.  v1.1  jww
  885.  
  886. sknsp:
  887.     ld    a,(de)    ; get char
  888.     and    7fh    ; mask
  889.     ret    z        ; done if null
  890.     cp    ' '
  891.     ret    z        ; done if space
  892.     cp    9
  893.     ret    z        ; done if tab
  894.     cp    '='
  895.     ret    z    ; new delimiter
  896.     inc    de    ; pt to next
  897.     jr    sknsp
  898.  
  899. ;    end
  900. ;  End of argv inclusion
  901.  
  902.  
  903. ; Console character output "routine".
  904. ; Unlike SYSLIB's COUT, this one will
  905. ; work under WordStar's "R" option.
  906. ;        b/m, June 3, 1987
  907.  
  908. cout:    jp    bout        ; PUBLIC label for EPRINT, etc.
  909.  
  910.  
  911. ; Parses token pointed to by HL into FCB pointed to
  912. ; by DE.  If Z33 running, uses resident CPR code, otherwise
  913. ; uses ZPRSFN.    This ensures full ZCPR33 compatibility.
  914.  
  915. parse:    call    z33chk
  916.     ld    a,0        ; DIR first for ZPRSFN
  917.     jp    nz,zprsfn
  918.     jp    z33fname
  919.  
  920.  
  921. ;    Filetype strings
  922.  
  923. lbrtyp:
  924.     db    'LBR'        ; Default lbr file type
  925. comtyp:
  926.     db    'COM'        ; Default com file type
  927.  
  928.  
  929. ;    Data Area
  930.  
  931.     dseg            ; To minimize COMfile size
  932.  
  933. args:                ; ARGV argument table
  934. ;    db    4
  935.     ds    1        ; Will init. to allow up to 4
  936. argc:
  937.     ds    1        ; Argument count
  938. argv1:
  939.     ds    2        ; First argument
  940. argv2:
  941.     ds    2        ; Second argument
  942. argv3:
  943.     ds    2        ; Third argument
  944. argv4:
  945.     ds    2*3        ; 3 more arguments
  946.  
  947. tailst:
  948.     ds    2        ; Start of actual command tail
  949.  
  950. lud:
  951.     ds    6        ; Dummy used by lu* routines
  952.     ds    11        ; Not of concern here
  953. lud$fcb:
  954.     ds    36        ; Fcb containing library file data
  955.  
  956.  
  957. ;    General-purpose LX Buffers & Pointers.
  958.  
  959. tpaend:
  960.     ds    1        ; Top page of tpa (msb)
  961.  
  962. gbuff:
  963.     ds    128        ; Command line save area
  964. lfcb:
  965.     ds    36        ; Local fcb
  966. cmdline:
  967.     ds    128        ; Saved command line buffer
  968.  
  969. clineb:    ds    256        ; Saved MCL buffer
  970.  
  971. scratch:
  972.     ds    2        ; Free space start
  973. libname:
  974.     ds    2
  975. ;    For relocated COPY$CODE routine
  976. cpytpa:
  977.     ds    2        ; COMfile runtime origin
  978. copy$count:
  979.     ds    2        ; COMfile length in bytes
  980.  
  981.     end
  982.