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 / RCPM / LUXI80.LBR / LUXI80.MZC / LUXI80.MAC
Text File  |  2000-06-30  |  51KB  |  2,026 lines

  1. ; LUXI80 - A Library extension system - Version 10 as of 03/22/88
  2. ;
  3. ;              Supports CPM v2.2 and CPM v3.0
  4. ;
  5. ; Allows the user to peer into .ARC, .ARK and .LBR file groups.  With
  6. ; appropriate peripheral files which accompany this program (or are
  7. ; already on most RCPM systems) can type .LBR member files whether
  8. ; crunched, squeezed or normal.  Can also type files in .ARC or .ARK
  9. ; libraries.  If using KMD or a comparable program, can easily extract
  10. ; member files from .ARC, .ARK or .LBR groups.  Options included to use
  11. ; KMD clones such as MBKMD and NUKMD.
  12. ;
  13. ;-----------------------------------------------------------------------
  14. ;
  15. ; 03/22/88  This is LUXI80. It is basically LUX100 rewritten for the
  16. ;  v10        Intel 8080 processor. You must use M80, L80 and MAKELUX.COM
  17. ;        to assemble it. I decided to rename it to LUXI80 and start
  18. ;        out with version 10 inorder to separate it from other
  19. ;        versions of LUX being done by Irv Hoff and Tom Brady.
  20. ;        This code is basically Irv's LUX100 code slightly modified
  21. ;        for the 8080. LUX100 is a fine piece of software and we all
  22. ;        owe Irv a large debt of gratitude for it. I'd also like to
  23. ;        thank Donald Phillips and Douglas Coatney for writing LUX43.
  24. ;        It was from LUX43 that I got most of the inspiration for 
  25. ;        doing this revision.
  26. ;                        -- Bill Weinel
  27. ;                           Capitol RCP/M
  28. ;
  29. ; 03/05/87  This is LUX77 renamed to LUX100.  It has numerous features
  30. ;  v100     which make it far more desireable for many RCPM operators
  31. ;        than Tom Brady's versions called LUX54, LUX75 and LUX80,
  32. ;        all of which are virtually identical and none of which work
  33. ;        on CPM v3.0 systems that many of us have.  LUX70, LUX77 and
  34. ;        this LUX100 work great on CPM v3.0 as well as on CPM v2.2
  35. ;        systems.  Irv had version LUX54 ready in October of 1986 but
  36. ;        never released it while waiting for Bob Freed to finish NOAH
  37. ;        since LUX52 already supported both .LBR and .ARC files.
  38. ;        Tom Brady put out his version called LUX54 so Irv didn't have
  39. ;        much choice except to skip to LUX70 for his version in a
  40. ;        courteous way to allow Tom Brady to continue developing his
  41. ;        LUX54 with LUX55 - should any additional things of merit be
  42. ;        added.  Such has not been the case.  Tom has taken a personal
  43. ;        vendetta to prevent the rest of us from using Irv's version
  44. ;        which took me all of 5 minutes to install on my CPM v3.0
  45. ;        system.  This was the first I had been able to even use LUX
  46. ;        on my system and I for one greatly appreciate what Irv has
  47. ;        contributed to this excellent program.  I don't care for Tom
  48. ;        Brady trying to play God and dictate to me what I should use
  49. ;        on my system.  I know many of you will agree with me.  Tom
  50. ;        also included UNARC142 in his version, without permission
  51. ;        from Bob Freed.  He specifically distributed that with the
  52. ;        distinct admonition that it was a beta test version for sysops
  53. ;        use only.  Tom Brady totally ignored this warning and made the
  54. ;        program public as though it were his to do with as he wished.
  55. ;        This has upset Bob Freed to the point he may never issue any
  56. ;        source code to any of his programs, again.    He was already
  57. ;        upset with Tom Brad's stealing the copyrighted routines he
  58. ;        had given to Irv for exclusive use in KMD.  If you never see
  59. ;        NOAH for CPM it may well be because of Tom Brady's antics.
  60. ;        (I got some of this information from direct personal calls.
  61. ;        The rest was already well known in many parts of the country.)
  62. ;                    - Earl Crocket
  63. ;                      Earl's Corner RCPM
  64. ;
  65. ; 03/04/87  (By Tom Brady, who again totally substituted his version of
  66. ;   v80     LUX54 in place of LUX77 then put an .ARK extention on it.
  67. ;        It is an obvious effort to again totally discredit the efforts
  68. ;        of Irv Hoff to simpifly and adapt the LUX program to use
  69. ;        normal programs already on most RCPM systems.)
  70. ;
  71. ; 03/01/87  NOTICE TO TOM BRADY:  LEAVE YOUR FINGERS OFF THIS PROGRAM.
  72. ;   v77     IF YOU WANT TO CONTINUE MUCKING WITH LUX, SUGGEST YOU USE
  73. ;        THE NUMBER LUX55 TO FOLLOW YOUR OWN LUX54.    I INTENTIONALLY
  74. ;        SKIPPED TO LUX70 SO AS TO NOT PROHIBIT YOU FROM DOING JUST
  75. ;        THAT, BUT WILL NOT TOLERATE YOUR USING THIS SERIES IN AN
  76. ;        OBVIOUS ATTEMPT TO PREVENT ME FROM CONTRIBUTING TO THE DE-
  77. ;        VELOPMENT OF THIS PROGRAM.
  78. ;
  79. ;        Restored LUX v77 to the original intent of the LUX 7x ver-
  80. ;        sion.  I had already skipped to LUX70 to not place Tom Brady
  81. ;        in a position where he could not continue working with his
  82. ;        LUX54, calling any subsequent version LUX55.  Instead he
  83. ;        elected to try to totally obliterate any work I had put into
  84. ;        this program.  I will not allow that to occur.  Many people
  85. ;        prefer my version to his, since it can be installed on any
  86. ;        RCPM as fast as you can extract the files from the libaray.
  87. ;                    - Irv Hoff
  88. ;
  89. ; 02/28/87  (Tom Brady totally replaced everything in the LUX70A version
  90. ;   v75     including all auxiliary programs in the library with his own
  91. ;        LUX54 version.  He further decided to jump to LUX75.  This
  92. ;        was done in an obvious attempt to force people to use only
  93. ;        his version.)
  94. ;
  95. ; 02/27/87  Added an equate to select MBKMD120 which came out about the
  96. ;   v70A    same time that LUX70 was being released.  LUX70A supports
  97. ;        KMD, MBKMD and NUKMD.  Be sure to make the proper selection.
  98. ;                    - Irv Hoff
  99. ;
  100. ; 02/22/87  MAJOR CHANGE... Rewrote program to use conventional files
  101. ;   v70     normally found on A0:
  102. ;
  103. ;           LCHEK.COM  (Current is LCHEK11.COM)
  104. ;           DIR.COM      (Renamed SD.COM with $L option)
  105. ;           TYPE.COM   (Should handle both squeezed and crunched)
  106. ;           UNARC.COM  (Combination DIR and TYPE for .ARC/.ARK files)
  107. ;
  108. ;        Special files such as LUXCHK, LUXDIR, LUXTYPE, etc. on
  109. ;        a special drive/user area (usually A15:) no longer needed.
  110. ;        This greatly simplifies the installation and use of LUX.
  111. ;        Wheel byte, MAXDRV and MAXUSR bytes no longer used or even
  112. ;        needed - LUX can be only be called up in whatever drive/user
  113. ;        area you are currently in, which in itself is the limiting
  114. ;        factor.  This is a radical departure from previous versions
  115. ;        so the version number has been significantly advanced.  This
  116. ;        allows additional updates of conventional versions if others
  117. ;        want an additional choice.    This makes one universal version
  118. ;        possible for any size system from small floppies to immense
  119. ;        hard drives of 100 Mb and more.
  120. ;
  121. ;        Option added to support KMD, MB-KMD or NUKMD added as the
  122. ;        latter two must have must have both 'A' and 'L' capability
  123. ;        for various functions.  (KMD needs only the 'A', however it
  124. ;        accepts 'L' interchangeably since versions prior to .ARC or
  125. ;        .ARK files used 'L' for .LBR files.)  Can now exit LUX with
  126. ;        CTL-C, CTL-K or CTL-X.  This standardizes exit with other
  127. ;        similar programs.        - Irv Hoff
  128. ;
  129. ; 09/09/86  None of the previous LUX files protected its start address,
  130. ;   v54     allowing long programs to overrun LUX itself.  It would then
  131. ;        lock up the system until reset by the Sysop.  This happened
  132. ;        most often when using the TYPE command to look at lengthy
  133. ;        .DOC files but was not limited to such files.  Reformatted
  134. ;        and simplified.        - Irv Hoff
  135. ;
  136. ; 08/25/86  Modified for .ARK file support in addition to .ARC and .LBR.
  137. ;   v53                 - Norman Beeler
  138. ;
  139. ; 06/02/86  Modified for .ARC file support, using UNARCxx for DIR and
  140. ;   v52     TYPE commands....fully automatic determination of .ARC or
  141. ;        .LBR file extents, (extent not necessary).    Supports .ARC
  142. ;        member transfer.        - Norman Beeler
  143. ;
  144. ; 06/26/85  Modified for KMD support throughout.  Other cosmetic changes.
  145. ;   v51     KMD offers total automatic protocol detect.  (It also offers
  146. ;        YMODEM-type batch transfers but this is not used with LUX.)
  147. ;                    - Tom Brady
  148. ;
  149. ; 07/21/85  Added SENDK and SK options for use with 1k blocks which are
  150. ;   v50     needed for MEX114 and MS-DOS program with YMODEM protocol.
  151. ;        (1k blocks are fully automatic with IMP.  The 'SK' need not
  152. ;        be manually inserted for 1k protocol.)
  153. ;                    - Steve Sanders
  154. ;
  155. ; 11/26/83  Original release.  Adapted from ATTACH program.
  156. ;   v12B                - Steven Holtzclaw
  157. ;
  158. ;-----------------------------------------------------------------------
  159. ;
  160. ;
  161. YES    EQU    0FFH
  162. NO    EQU    0
  163. ;
  164. KMD    EQU    YES
  165. MBKMD    EQU    NO
  166. NUKMD    EQU    NO
  167. ;
  168. ;-----------------------------------------------------------------------
  169. ;
  170. ; Equates
  171. ;
  172. CR    EQU    0DH
  173. LF    EQU    0AH
  174. ;
  175. ;-----------------------------------------------------------------------
  176. ;
  177. ;
  178. ; If RCPM is Yes, change the BYECMD equate at end of this file if your
  179. ; logoff program is not called BYE.COM.
  180. ;
  181. RCPM    EQU    YES        ; Yes, if being used with a RCPM system
  182. HLPMSG    EQU    YES        ; Yes, if helpful messages are wanted
  183. AUTODR    EQU    YES        ; Yes, if initial auto-directory wanted
  184. HLPERS    EQU    2        ; Give auto-help after this many errors
  185. ;
  186. ;
  187. ;-----------------------------------------------------------------------
  188. ;
  189. ; The following files are normally on A0: and are for general purpose as
  190. ; well as for use with LUX.
  191. ;
  192. ;     NOTE:    The DIR.COM file must be a SD-xx.COM type
  193. ;        having the $L option (to show library member
  194. ;        contents).  This is normally placed on A0:
  195. ;        for general use in displaying the directory.
  196. ;        When choosing a drive, use:  0=A, 1=B, etc.
  197. ;
  198. CHKDRV    EQU    0        ; Drive number for LCHEK.COM (LCHEK11.COM)
  199. CHKUSR    EQU    0        ; User number  for LCHEK.COM
  200. ;
  201. DIRDRV    EQU    0        ; Drive number for DIR.COM  (SD.COM)
  202. DIRUSR    EQU    0        ; User number  for DIR.COM  (SD.COM)
  203. ;
  204. KMDRV    EQU    0        ; Drive number for KMD, MB-KMD or NUKMD
  205. KMDUSR    EQU    0        ; User number  for KMD, MB-KMD or NUKMD
  206. ;
  207. TYPDRV    EQU    0        ; Drive number for TYPE.COM
  208. TYPUSR    EQU    0        ; User number  for TYPE.COM
  209. ;
  210. UNADRV    EQU    0        ; Drive number for UNARC.COM
  211. UNAUSR    EQU    0        ; User number  for UNARC.COM
  212. ;
  213. ;-----------------------------------------------------------------------
  214. ;
  215. BDOS    EQU    0005H        ; Jumper vector for BDOS calls
  216. TPA    EQU    0100H        ; CP/M program area
  217. FCB1    EQU    005CH        ; First file control block
  218. FCB2    EQU    006CH        ; Second file control block
  219. REBOOT    EQU    0000H        ; Cold reboot address
  220. TBUFF    EQU    0080H        ; Default command buffer
  221. ;
  222. ;
  223. ; Macros used
  224. ;
  225. DRVUSR     MACRO    DRIVNO,USERNO,FNCNAM,RTN1,RTN2,RTN3,RTN4
  226.     CALL    FILTYP
  227.     DB    DRIVNO+'A'
  228. ;
  229. USERN1    SET    USERNO
  230. ;
  231.      IF    USERN1 GT 9
  232.     DB    (USERN1 /10)+'0'
  233. ;
  234. USERN1    SET    USERN1-10
  235.      ENDIF            ; USERN1 GT 9
  236. ;
  237.     DB    USERN1+'0'
  238.     DB    ':'
  239.     DB    FNCNAM
  240.     DB    0
  241. ;
  242.      IF    NOT NUL RTN1
  243.     CALL    RTN1
  244.      ENDIF            ; NOT NUL RTN1
  245. ;
  246.      IF    NOT NUL RTN2
  247.     CALL    RTN2
  248.      ENDIF            ; NOT NUL RTN2
  249. ;
  250.      IF    NOT NUL RTN3
  251.     CALL    RTN3
  252.      ENDIF            ; NOT NUL RTN3
  253. ;
  254.      IF    NOT NUL RTN4
  255.     CALL    RTN4
  256.      ENDIF
  257.     JMP    PROCES        ; NOT NUL RTN4
  258.      ENDM
  259. ;
  260. DVUS     MACRO    DRIVNO,USERNO,FNCNAM,RTN1,RTN2,RTN3,RTN4
  261.     CALL    FILTYP
  262.     DB    DRIVNO+'A'
  263. ;
  264. USERN2    SET    USERNO
  265. ;
  266.      IF    USERN2 GT 9
  267.     DB    (USERN2 /10)+'0'
  268.     USERN2    SET USERN2-10
  269.      ENDIF            ; USERN2 GT 9
  270. ;
  271.     DB    USERN2+'0'
  272.     DB    ':'
  273.     DB    FNCNAM
  274.     DB    0
  275.      ENDM
  276. ;
  277. CMDJMP     MACRO    VERB,VECTOR
  278.     CALL    ILCMP
  279.     DB    VERB
  280.     DB    0
  281.     JNC    VECTOR
  282.      ENDM
  283. ;
  284. ; Z80 DJNZ code replacement macro
  285. ;
  286. DJNZ    MACRO    DJADR
  287.     DCR    B        ; DJNZ replacement
  288.     JNZ    DJADR
  289.     ENDM
  290. ;
  291. ; Z80 CPIR replacement macro
  292. ;
  293. CPIR    MACRO    nm
  294. Cp&nm:    cmp    m        ; CPIR replacement code begins
  295.     push    psw
  296.     inx    h
  297.     dcr    c
  298.     jnz    C1&nm
  299.     pop    psw
  300.     jmp    C2&nm
  301. C1&nm:    pop    psw
  302.     jnz    Cp&nm        ;; CPIR replacement code ends
  303. C2&nm    equ    $
  304.     ENDM
  305. ;
  306. ;
  307. ;=======================================================================
  308. ;
  309. ;            Program starts here
  310. ;
  311. ;=======================================================================
  312. ;
  313. START:    LXI    SP,SSTACK    ; Starting stack
  314.     CALL    ILPRT
  315.     DB    CR,LF,'LUXI80 v10'
  316.     DB    CR,LF,0
  317. ;
  318. ;
  319. ; Check for a blank or null command line
  320. ;
  321.     LDA    TBUFF+1        ; Get byte from default command buffer
  322.     ORA    A        ; If non-zero then there is a possible
  323.     JNZ    GTDVUS        ; File specified
  324. ;
  325. SPCERR:    CALL    ILPRT        ; Print the error message
  326.     DB    CR,LF
  327.     DB    '++ Examples of valid LUX commands ++',CR,LF,LF
  328.     DB    '   LUX HELLO.ARC',CR,LF
  329.     DB    '   LUX HELLO.ARK',CR,LF
  330.     DB    '   LUX HELLO.LBR',CR,LF,LF
  331.     DB    '   The extent is not needed if no other ',CR,LF
  332.     DB    '   library files have a similar name.'
  333.     DB    CR,LF,0
  334.     JMP    REBOOT        ; Reboot since we have overwritten CCP
  335. ;
  336. ;.....
  337. ;
  338. ;
  339. GTDVUS:    LXI    H,TBUFF+2    ; Index default key buffer
  340.     CALL    DRUSR        ; Get requested drive/user
  341.     JC    SPCERR
  342. ;
  343. ;
  344. ; Test for drive/user within range
  345. ;
  346. ;
  347.     push    h        ; save command line pointer
  348.     push    b        ; save drive/user spec
  349.     pop    h
  350.     shld    rqddrv        ; set the requested drive/user
  351.     pop    h
  352.     XCHG            ; DE is source address to create new FCB
  353.     LXI    H,FCB1        ; Index FCB
  354.     CALL    SCANR1        ; Create the new FCB
  355. ;
  356. ;
  357. ; Force the default file type
  358. ;
  359.     LXI    H,'RA'        ; Set 'AR' into first two bytes of file type
  360.     SHLD    FCB1+9
  361.     MVI    A,'K'        ; Set 'K' into last byte of file type
  362.     STA    FCB1+11
  363. ;
  364. ;
  365. ; Get the library name from the FCB and store it
  366. ;
  367.     LXI    H,FCB1        ; Source for move
  368.     LXI    D,LBRNAM-1    ; Destination for move
  369.     LXI    B,9        ; Max 8 character filename
  370.     call    LDIRs        ; Move to local name
  371.     LXI    H,FCB1+1    ; First byte of filename
  372.     MVI    A,'?'        ; Character to look for
  373.     LXI    B,11        ; Search thru 11 bytes
  374.     CPIR    1        ; Do search macro
  375.     JNZ    LOOKUP        ; No ? found - continue
  376.     CALL    ILPRT        ; Print the error message
  377.     DB    CR,LF
  378.     DB    '++ Ambiguous filenames are not allowed ++',CR,LF,0
  379.     JMP    SPCERR
  380. ;.....
  381. ;
  382. ;
  383. ; Look for the filename on directory
  384. ;
  385. LOOKUP:    CALL    GETOLD        ; Get the current drive/user
  386.     CALL    SETNEW        ; Set requested drive/user
  387.     LXI    D,080H        ; Default DMA address
  388.     MVI    C,26
  389.     CALL    BDOS        ; Set the DMA address
  390.     LXI    D,FCB1        ; Index filename specified
  391.     MVI    C,17
  392.     CALL    BDOS        ; Search for first
  393.     INR    A        ; Does file exist?
  394.     JNZ    SETARK        ; Jump to start of LUX
  395.     LXI    H,'RA'        ; Try .ARC file
  396.     SHLD    FCB1+9
  397.     MVI    A,'C'        ; Set .ARC
  398.     STA    FCB1+11
  399.     LXI    D,FCB1
  400.     MVI    C,17        ; See if it exists
  401.     CALL    BDOS
  402.     INR    A
  403.     JNZ    SETARC        ; Yes so go
  404.     LXI    H,'BL'        ; Try .LBR file
  405.     SHLD    FCB1+9
  406.     MVI    A,'R'        ; Set .LBR
  407.     STA    FCB1+11
  408.     LXI    D,FCB1
  409.     MVI    C,17        ; See if it exists
  410.     CALL    BDOS
  411.     INR    A
  412.     JZ    NOFILE        ; No, error off
  413.     JMP    PRESTR
  414. ;.....
  415. ;
  416. ;
  417. SETARC:    MVI    A,0FFH        ; Yes, set ARCFLG
  418.     STA    ARCFLG
  419.     JMP    PRESTR
  420. ;.....
  421. ;
  422. ;
  423. SETARK:    MVI    A,7FH        ; Yes, set ARCFLG and .ARK
  424.     STA    ARCFLG
  425. ;
  426. PRESTR:    LXI    H,FCB1
  427.     LXI    D,LBRNAM-1    ; Update library name (.ARC)
  428.     LXI    B,12
  429.     call    LDIRs
  430.     JMP    PGMSTR        ; Go do it
  431. ;.....
  432. ;
  433. ;
  434. NOFILE:    CALL    SETOLD
  435.     CALL    ILPRT        ; Print the error message
  436.     DB    CR,LF,'Can''t find ',0
  437.     CALL    DVUPRT
  438.     CALL    NAMPRT        ; Print the filename
  439.     CALL    ILPRT
  440.     DB    ' - check the DIR',CR,LF,0
  441.     JMP    0000H        ; Reboot since we have destroyed the ccp
  442. ;.....
  443. ;
  444. ;
  445.     DS    64        ; 32 level stack for here
  446. ;
  447. SSTACK    EQU    $
  448. ;
  449. FINIS    EQU    $        ; Finish of program loader
  450. ;
  451. LODLEN    EQU    FINIS-START    ; Length of loader
  452.                 ; Keep the program in line
  453.     DS    300H-LODLEN    ; Add extra bytes here to make
  454.                 ; 'PGMSTR' start on a 100h byte boundary
  455. ;
  456. ;-----------------------------------------------------------------------
  457. ; This is the start of the relocated program - all of the code from
  458. ; 'START' to here is thrown away once LUX begins execution.
  459. ;-----------------------------------------------------------------------
  460. ;
  461. ; set up the BDOS and BIOS patches
  462. ;
  463. PGMSTR:    JMP    INIT        ; Jump to start of this module
  464.     DB    'LUXI80 v10'    ; The name 'LUX' is a clue to other
  465.                 ;   programs that enables them to deter-
  466.                 ;   mine if LUX is resident. 'L' is at
  467.                 ;   BDOS+3 when LUX is resident.
  468. ;
  469. ; This is the LUX removal routine, jumped to by the BYE command.  It is
  470. ; accessable to external programs and is defined to exist at LUX+12
  471. ; (looks like BDOS+12 when LUX is resident).
  472. ;
  473. REMOVE:
  474.      IF    RCPM
  475.     LXI    SP,TPA+100H    ; Use the TPA for a stack
  476.     LXI    B,0        ; First select A0:
  477.     CALL    RESET
  478.     LXI    D,80H        ; Clear the DMA buffer
  479.     PUSH    D
  480.     PUSH    D
  481.     MVI    B,128        ; Bytes to clear
  482.     XRA    A        ; Easy way to make A=0
  483. ;
  484. RZRLP:    STAX    D        ; Null the location
  485.     INX    D        ; Next address
  486.     DJNZ    RZRLP        ; Loop until 'B' is zero
  487. ;
  488.     MVI    A,BYELEN    ; Store away the length of the command
  489.     LXI    H,BYECMD    ; Now move the commands to the DMA
  490.     MOV    M,A
  491.     POP    D        ; Restore the DMA address
  492.     LXI    B,BYELEN
  493.     call    LDIRs
  494. ;
  495.     POP    D        ; Restore it again
  496.     MVI    C,26        ; Reset the DMA
  497.     CALL    BDOS
  498.     LXI    D,SUBFCB    ; Address the .SUB file FCB
  499.     MVI    C,22        ; Make the file
  500.     CALL    BDOS
  501.     INR    A        ; Check for errors
  502.     JZ    EXITER        ; Oops, no directory space
  503.     LXI    D,SUBFCB    ; Else write the data
  504.     MVI    C,21
  505.     CALL    BDOS
  506.     INR    A
  507.     JZ    EXITER        ; Oops, no space left
  508.     LXI    D,SUBFCB
  509.     MVI    C,16        ; Now close the file
  510.     CALL    BDOS
  511.     LXI    H,0        ; Now make the exit routine go to A0:
  512.     SHLD    OLDDRV
  513.      ENDIF            ; RCPM
  514. ;
  515.     JMP    UNPATH        ; Unpatch the jump table, and warm boot
  516. ;.....
  517. ;
  518. ;
  519. ; Error handler for REMOVE routine
  520. ;
  521.      IF    RCPM
  522. EXITER:    CALL    ILPRT        ; An error when making the .SUB file
  523.     DB    CR,LF,'+ Error: Can''t remove LUX! Please +'
  524.     DB    CR,LF,'+        type CTRL-C to exit LUX, +'
  525.     DB    CR,LF,'+        then type BYE to logoff. +',0
  526.     LXI    SP,STACK
  527.     JMP    GETCMD
  528.      ENDIF            ; RCPM
  529. ;.....
  530. ;
  531. ;
  532. ; This is the LUX intialization
  533. ;
  534. INIT:    LHLD    0005H+1        ; Get BDOS start
  535.     SHLD    PGMSTR+1    ; Set new jump to BDOS
  536.     LXI    H,PGMSTR    ; Get local bdos vector
  537.     SHLD    0005H+1        ; Set it in low memory
  538.     LXI    SP,STACK    ; Reset stack
  539.     LHLD    0000H+1        ; Get BIOS warm boot vector
  540.     SHLD    BIOS3        ; Save old warm boot vector
  541. ;
  542. ;
  543. ; Save the old BIOS vectors
  544. ;
  545.     LHLD    BIOS3        ; BIOS warm boot address
  546.     LXI    D,OWBOOT    ; Local warm boot address
  547.     LXI    B,12        ; 12 bytes to move
  548.     call    LDIRs        ; Move the block
  549. ;
  550. ;
  551. ; Set up the new BIOS vectors
  552. ;
  553.     LXI    H,WBOOT        ; Source is local table
  554.     lhld    bios3        ; destination is old bios
  555.     xchg
  556.     LXI    B,12        ; 12 bytes to move
  557.     call    LDIRs        ; Move the block
  558.     MVI    A,0FFH        ; Set the auto-directory byte
  559.     STA    DOADIR
  560.     XRA    A        ; Reset the error count
  561.     STA    HLPCNT        ; 
  562.     JMP    ENTRY        ; Initialize
  563. ;.....
  564. ;
  565. ;
  566. OWBOOT:    DB    0,0,0        ; Old WBOOT vector is moved to here
  567. OCONST:    DB    0,0,0        ; Old CONSTAT vector is moved to here
  568. OCONIN:    DB    0,0,0        ; Old cONIN vector is moved to here
  569. OCONOU:    DB    0,0,0        ; Old CONOUT vector is moved to here
  570. ;
  571. WBOOT:    JMP    ENTRY        ; Vector warm boot to entry
  572. CONST:    JMP    VCONST        ; Check for carrier
  573. CONIN:    JMP    VCONIN        ; Vector conin to CONIN
  574. CONOU:    JMP    VCONOU        ; Vector to CONOUT
  575. ;
  576. VCONST:    JMP    OCONST        ; Jump to old CONSTAT routine
  577. ;
  578. VCONOU:    JMP    OCONOU        ; Jump to old CONOUT routine
  579. ;
  580. VCONIN:    CALL    OCONIN        ; Get a byte
  581.     CPI    'C'-40H        ; CTL-C?
  582.     JZ    VCON1
  583.     CPI    'K'-40H        ; CTL-K?
  584.     JZ    VCON1
  585.     CPI    'X'-40H        ; CTL-X?
  586.     RNZ            ; Nope - let BIOS have it
  587. ;
  588. VCON1:    LDA    ACTIVE        ; Is LUX segment active?
  589.     ORA    A
  590.     MVI    A,3
  591.     RZ            ; Not active - let BIOS have it
  592. ;
  593.     LXI    SP,TPA        ; Re initialize the stack
  594.     CALL    ILPRT        ; Print the following
  595.     DB    ' Exiting LUX',CR,LF,0
  596. ;
  597. UNPATH:    LXI    d,OWBOOT    ; Index old warm boot vector
  598.     lhld    bios3        ; bios jump table
  599.     xchg
  600.     LXI    B,12        ; 12 bytes to move
  601.     call    LDIRs        ; Move the old table back
  602.     CALL    SETOLD        ; Set old drive/user
  603.     JMP    0000H        ; Warm boot - end of program
  604. ;.....
  605. ;
  606. ;
  607. ; This is the LUX entry point
  608. ;
  609. ENTRY:    LXI    SP,STACK    ; Set up local stack
  610.     LXI    H,PGMSTR    ; Dummy BDOS vector
  611.     SHLD    6        ; Set it
  612.     LHLD    BIOS3        ; BIOS warm boot vector
  613.     SHLD    1        ; Set it
  614.     MVI    A,0C3H        ; (JMP)
  615.     STA    0        ; Reset warm boot jump
  616.     STA    5        ; And BDOS jump
  617.     CALL    OCONST        ; See if character waiting
  618.     ORA    A        ; Test result
  619.     JZ    ENTR1        ; If no character is waiting
  620.     CALL    OCONIN        ; Get the console character
  621.                 ; This is done to gobble any
  622.                 ; Possible garbage character
  623. ;
  624. ENTR1:    MVI    A,0FFH
  625.     STA    ACTIVE        ; Set LUX active
  626. ;
  627. GETCMD:    CALL    SETNEW        ; Reset drive/user
  628.     lxi    h,tbuff+1    ; Place to put command string
  629.     shld    cptrix
  630.     XRA    A        ; Length of command
  631.     sta    tbuff
  632. ;
  633.      IF    AUTODR
  634.     LDA    DOADIR        ; Shall we do a directory?
  635.     ORA    A
  636.     JZ    PROMPT        ; Guess not
  637.     XRA    A        ; Else zap the byte
  638.     STA    DOADIR
  639.     MVI    A,3        ; Fake a DIR command
  640.     STA    CMDLEN
  641.     LXI    H,'ID'
  642.     SHLD    CMDLIN+2
  643.     MVI    L,'R'
  644.     MVI    H,0
  645.     SHLD    CMDLIN+4
  646.     JMP    GOCNV        ; And do it
  647.      ENDIF            ; AUTODR
  648. ;.....
  649. ;
  650. ;
  651. PROMPT:
  652.      IF    HLPMSG
  653.     CALL    ILPRT        ; Print the entry message
  654.     DB    CR,LF,'LUXI80 v10 - ^C, ^K or ^X to exit, ? for menu'
  655.     DB    CR,LF,0
  656.      ENDIF            ; HLPMSG
  657. ;
  658. PRMPT2:    CALL    CRLF
  659.     CALL    DVUPRT        ; Print the LUX prompt
  660.     CALL    NAMPRT        ; Drive/user, library name
  661.     CALL    ILPRT
  662.     DB    ' -->',0
  663.     LXI    D,CMDLIN    ; Index command line
  664.     MVI    C,10
  665.     CALL    BDOS        ; Read console buffer
  666.     LDA    CMDLEN        ; Get command length
  667.     ORA    A        ; Test it
  668.     JZ    GETCMD        ; If null command
  669.     LDA    CMDLIN+2    ; Get first character
  670.     CPI    ';'        ; Semicolon ok
  671.     JZ    PRMPT2
  672. ;
  673. GOCNV:    CALL    CNVBUF        ; Convert the command line to upper case
  674.     LXI    D,CMDLIN+2    ; Index data from the command line
  675.     LDA    ARCFLG        ; Are we looking at .ARC files?
  676.     ORA    A
  677.     JZ    LBRCMD        ; Nope, do .LBR commands
  678.     ani    10000000b
  679.     ora    a
  680.     JZ    ARKFL
  681.     CMDJMP 'FILES',ACFILES
  682.     JMP    REST
  683. ;
  684. ARKFL:    CMDJMP 'FILES',AKFILES
  685. ;
  686. REST:    CMDJMP 'TYPE',ATYPE
  687.     CMDJMP 'DIR',UNARC
  688.     CMDJMP 'D',UNARC
  689.     CMDJMP 'SD',UNARC
  690.     CMDJMP 'CHEK',NOARC1
  691.     JMP    HLP
  692. ;
  693. LBRCMD:    CMDJMP 'TYPE',TIPE    ; File type command process
  694.     CMDJMP 'DIR',DIR    ; Directory command process
  695.     CMDJMP 'D',DIR        ; Alternate for DIR
  696.     CMDJMP 'SD',DIR        ; Alternate for DIR
  697.     CMDJMP 'FILES',FILES    ; Run DIR.COM in "$L" (.LBR) mode
  698.     CMDJMP 'CHEK',LCHEK    ; Run LCHEK
  699. ;
  700. HLP:    CMDJMP '?',QKHELP    ; Alternate for HELP
  701.     CMDJMP 'LUX',LUX    ; LUX command process
  702. ;
  703. ;
  704. ; If there are other commands a user may use on your system, and you
  705. ; want to tell him to exit LUX first, then enter below:
  706. ;
  707. ;     CMDJMP  'CMD',NOGOT.
  708. ;
  709. ; Place your command in 'CMD' and it will tell the user that that com-
  710. ; mand is only available outside of LUX.
  711. ;
  712.      IF    RCPM AND KMD
  713.     CMDJMP 'KMD',KKMD    ; KMD command process
  714.      ENDIF            ; RCPM AND KMD
  715. ;
  716.      IF    RCPM AND MBKMD
  717.     CMDJMP 'MBKMD',KKMD    ; NUKMD command process
  718.      ENDIF            ; RCPM and MBKMD
  719. ;
  720.      IF    RCPM AND NUKMD
  721.     CMDJMP 'NUKMD',KKMD    ; NUKMD command process
  722.      ENDIF            ; RCPM and NUKMD
  723. ;
  724.      IF    RCPM
  725.     CMDJMP 'SEND',SEND    ; Synonym for KMD S, MBKMD S or NUKMD S
  726.     CMDJMP 'SENDK',SENDK    ; Synonym for KMD SK, MBkMD SK or NUKMD SK
  727.     CMDJMP 'CHAT',NOGOT    ; Tell user NOGOT here
  728.     CMDJMP 'BYE',NOGOT    ; Tell user NOGOT here
  729.      ENDIF            ; RCPM
  730. ;
  731. ;
  732. ; This will actually print the command in error like this
  733. ;
  734. ;   ERROR, DUR is not a valid LUX command.
  735. ;
  736.     CALL    ILPRT
  737.     DB    CR,LF,LF,'ERROR, ',0 ; Point at command error
  738.     CALL    PRTERR        ; Print the command just entered
  739.     MVI    A,' '        ; And a space
  740.     CALL    CTYPE
  741.     LXI    H,HLPCNT    ; Address the error count
  742.     INR    M        ; Bump it
  743.     MVI    A,HLPERS    ; Have we reached the limit?
  744.     CMP    M        ; 
  745.     JNZ    KPTRYN        ; No, jump around the rest
  746.     MVI    M,0        ; Else reset the count
  747.     JMP    QKHELP        ; And give him help anyway
  748. ;.....
  749. ;
  750. ;
  751. KPTRYN:    CALL    ILPRT        ; Tell them it's no good
  752.     DB    ' is not a valid LUX command.',CR,LF,0
  753.     JMP    GETCMD
  754. ;.....
  755. ;
  756. ;
  757. PRTERR:    LXI    H,CMDLIN+2    ; Index command just entered
  758.     LDA    CMDLEN        ; Get the length
  759.     MOV    B,A        ; Into 'B'
  760. ;
  761. GETCM5:    MOV    A,M        ; Get a byte
  762.     CPI    020H        ; Space ?
  763.     JZ    GETCM6        ; Yes - dont print it
  764.     CPI    000H        ; Null
  765.     JZ    GETCM6        ; Yes - all done
  766.     CALL    CTYPE        ; Print the character
  767.     INX    H        ; Next character
  768.     DJNZ    GETCM5        ; Loop for the rest
  769. ;
  770. GETCM6:    RET
  771. ;
  772. ;
  773. ; 'COMMAND TRANSLATION VECTORS
  774. ;
  775. ; 'SUMMARY OF AUX ROUTINES:
  776. ;
  777. ; 'FILTYP' installs the following 'DEFB' into new command line
  778. ;       specify the drive and user area for each command as in
  779. ;       the vectors below.  remember each 'DEFB' must end with a
  780. ;       zero.
  781. ;
  782. ; 'FILNAM' installs the current .LBR name into the new command line
  783. ;
  784. ; 'FILSPC' installs a space character into the new command line
  785. ;
  786. ; 'FILMEM' installs the requested member name into the new command line
  787. ;
  788. ;
  789. ACFILES:DRVUSR DIRDRV,DIRUSR,'DIR *.ARC'
  790. AKFILES:DRVUSR DIRDRV,DIRUSR,'DIR *.ARK'
  791. FILES:    DRVUSR DIRDRV,DIRUSR,'DIR *.LBR'
  792. ;
  793. ATYPE:    DRVUSR UNADRV,UNAUSR,'UNARC ',FILNAM,FILSPC,FILMEM
  794. DIR:    DRVUSR DIRDRV,DIRUSR,'DIR ',FILNAM,FILDIR,FILMEM
  795. LCHEK:    DRVUSR CHKDRV,CHKUSR,'LCHEK ',FILNAM,FILSPC,FILMEM
  796. TIPE:    DRVUSR TYPDRV,TYPUSR,'TYPE ',FILNAM,FILSPC,FILMEM
  797. UNARC:    DRVUSR UNADRV,UNAUSR,'UNARC ',FILNAM
  798. ;
  799.      IF    RCPM AND KMD
  800. SEND:    DRVUSR KMDRV,KMDUSR,'KMD A ',FILNAM,FILSPC,FILMEM
  801. SENDK:    DRVUSR KMDRV,KMDUSR,'KMD AK ',FILNAM,FILSPC,FILMEM
  802. SENDA:    DRVUSR KMDRV,KMDUSR,'KMD A ',FILNAM,FILSPC,FILMEM
  803. SENDAK:    DRVUSR KMDRV,KMDUSR,'KMD AK ',FILNAM,FILSPC,FILMEM
  804.      ENDIF            ; RCPM AND KMD
  805. ;
  806.      IF    RCPM AND NUKMD OR MBKMD
  807. SEND:    LDA    ARCFLG        ; Are we in an .ARC file?
  808.     ORA    A
  809.     JNZ    SENDA        ; Yes, use 'A' for .ARC
  810.     JMP    SEND1        ; No, use 'L' for .LBR
  811. ;
  812. SENDK:    LDA    ARCFLG        ; Are we in an .ARC file?
  813.     ORA    A
  814.     JNZ    SENDA        ; Yes, use 'A' for .ARC
  815.     JMP    SENDK1        ; No, use 'L' for .LBR
  816.      ENDIF            ; RCPM AND MBKMD OR NUKMD
  817. ;
  818.      IF    RCPM AND MBKMD
  819. SEND1:    DRVUSR KMDRV,KMDUSR,'MBKMD L ',FILNAM,FILSPC,FILMEM
  820. SENDK1:    DRVUSR KMDRV,KMDUSR,'MBKMD LK ',FILNAM,FILSPC,FILMEM
  821. SENDA:    DRVUSR KMDRV,KMDUSR,'MBKMD A ',FILNAM,FILSPC,FILMEM
  822. SENDAK:    DRVUSR KMDRV,KMDUSR,'MBKMD AK ',FILNAM,FILSPC,FILMEM
  823.      ENDIF            ; RCPM AND MBKMD
  824. ;
  825.      IF    RCPM AND NUKMD
  826. SEND1:    DRVUSR KMDRV,KMDUSR,'NUKMD L ',FILNAM,FILSPC,FILMEM
  827. SENDK1:    DRVUSR KMDRV,KMDUSR,'NUKMD LK ',FILNAM,FILSPC,FILMEM
  828. SENDA:    DRVUSR KMDRV,KMDUSR,'NUKMD A ',FILNAM,FILSPC,FILMEM
  829. SENDAK:    DRVUSR KMDRV,KMDUSR,'NUKMD AK ',FILNAM,FILSPC,FILMEM
  830.      ENDIF            ; RCPM AND NUKMD
  831. ;
  832. ;
  833. ; Quick help summary
  834. ;
  835. QKHELP:    CALL    ILPRT
  836.     DB    CR,LF,LF
  837.     DB    'You are using the LUX utility to work with an archive '
  838.     DB    CR,LF
  839.     DB    'or library file.  These are the available commands:'
  840.     DB    CR,LF,LF
  841.     DB    'CHEK HELLO.EXT     - Runs LCHEK on requested member '
  842.     DB    'file',CR,LF
  843.     DB    'DIR                - Display member files '
  844.     DB    'in this library',CR,LF
  845.     DB    'FILES              - Display other .ARC/.ARK/.LBR '
  846.     DB    'files available',CR,LF
  847.     DB    'LUX NEWNAME        - Attach to another '
  848.     DB    'LBR/ARC file ',CR,LF
  849. ;
  850.      IF    RCPM AND KMD
  851.     DB    CR,LF
  852.     DB    'KMD S HELLO.EXT    - Sends member file '
  853.     DB    'via auto-protocol detect',CR,LF
  854.     DB    'KMD SK HELLO.EXT   - Sends member file '
  855.     DB    'with manual 1k setting',CR,LF
  856.      ENDIF            ; RCPM AND KMD
  857. ;
  858.      IF    RCPM AND MBKMD
  859.     DB    'MBKMD S HELLO.EXT  - Sends member file '
  860.     DB    'via auto-protocol detect',CR,LF
  861.     DB    'MBKMD SK HELLO.EXT - Sends member file '
  862.     DB    'with manual 1k setting',CR,LF
  863.      ENDIF            ; RCPM AND MBKMD
  864. ;
  865.      IF    RCPM AND NUKMD
  866.     DB    'NUKMD S HELLO.EXT  - Sends member file '
  867.     DB    'via auto-protocol detect',CR,LF
  868.     DB    'NUKMD SK HELLO.EXT - Sends member file '
  869.     DB    'with manual 1k setting',CR,LF
  870.      ENDIF            ; RCPM AND NUKMD
  871. ;
  872.      IF    RCPM
  873.     DB    'SEND HELLO.EXT     - Same as ''S'' command',CR,LF
  874.     DB    'SENDK HELLO.EXT    - Same as ''SK'' command',CR,LF
  875.      ENDIF            ; RCPM
  876. ;
  877.     DB    CR,LF
  878.     DB    'TYPE HELLO.EXT     - Display ASCII file contents'
  879.     DB    CR,LF,CR,LF
  880.     DB    '?                  - Displays this menu'
  881.     DB    CR,LF,LF,'(Abort to CP/M with ^C, ^K or ^X)',CR,LF
  882.     DB    0
  883.     JMP    GETCMD
  884. ;.....
  885. ;
  886. ;
  887. ; Tried entering CHAT - tell him to exit LUX first.  Add other commands
  888. ; as you wish.
  889. ;
  890. NOGOT:    CALL    CRLF
  891.     CALL    CRLF
  892.     CALL    PRTERR        ; Print the command
  893.     CALL    ILPRT        ; And then this
  894.     DB    '  <<== Exit LUX with ^C, ^K or ^C',CR,LF,0
  895.     JMP    GETCMD        ; Go back for another command
  896. ;.....
  897. ;
  898. ;
  899. NOARC1:    CALL    CRLF
  900.     CALL    CRLF
  901.     CALL    ILPRT
  902.     DB    'Use DIR command for CRC values',CR,LF,0
  903.     JMP    GETCMD
  904. ;.....
  905. ;
  906. ;
  907. ; KMD is a special case since the 'A' and 'R' options are invalid here
  908. ;
  909.      IF    RCPM
  910. KKMD:    CALL    ADVANC        ; Go to next character
  911.     MOV    A,M        ; Get the character
  912.     CPI    'S'        ; If 'S' check for
  913.     JZ    KKMD1        ; Following 'K'
  914.     CPI    'R'        ; Not legal here
  915.     JZ    KKMD2        ; Execute error routine
  916.     CPI    'A'        ; Not legal here
  917.     JZ    KKMD3        ; Execute error routine
  918.     CPI    'L'        ; Not legal here
  919.     JZ    KKMD3        ; Execute error routine
  920.      ENDIF            ; RCPM
  921. ;
  922.      IF    RCPM AND KMD
  923.     DRVUSR KMDRV,KMDUSR,'KMD'
  924.      ENDIF            ; RCPM AND KMD
  925. ;
  926.      IF    RCPM AND MBKMD
  927.     DRVUSR KMDRV,KMDUSR,'MBKMD'
  928.      ENDIF            ; RCPM AND MBKMD
  929. ;
  930.      IF    RCPM AND NUKMD
  931.     DRVUSR KMDRV,KMDUSR,'NUKMD'
  932.      ENDIF            ; RCPM AND NUKMD
  933. ;
  934.      IF    RCPM
  935. KKMD1:    INX    H        ; Get next chacter
  936.     MOV    A,M
  937.     CPI    020H        ; Is it a space?
  938.     JZ    KKMD1A
  939.     CPI    'K'        ; Or packet request?
  940.     JZ    KKMDK
  941. ;
  942. KKMD1A:    CALL    NXTSPC
  943.     LDA    ARCFLG        ; Are we in an .ARC file?
  944.     ORA    A
  945.     JZ    SEND        ; Nope, send regular
  946.     JMP    SENDA        ; Yes, send .ARC
  947. ;.....
  948. ;
  949. ;
  950. KKMDK:    CALL    NXTSPC
  951.     LDA    ARCFLG        ; Are we in an .ARC file?
  952.     ORA    A
  953.     JZ    SENDK        ; Nope, send regular
  954.     JMP    SENDAK        ; Yes, send .ARC
  955. ;.....
  956. ;
  957. ;
  958. KKMD2:    CALL    CRLF
  959.     CALL    PRTERR        ; Print the command
  960.     CALL    ILPRT        ; Print the following
  961.     DB    ' can''t (R)eceive while in LUX',CR,LF,0
  962.     JMP    GETCMD        ; Return to command
  963. ;.....
  964. ;
  965. ;
  966. KKMD3:    CALL    CRLF
  967.     CALL    PRTERR        ; Print the command
  968.     CALL    ILPRT        ; Print the following
  969.     DB    ' uses S or SK options while in LUX',CR,LF,0
  970.     JMP    GETCMD
  971.      ENDIF            ; RCPM
  972. ;.....
  973. ;
  974. ;
  975. ; 'LUX' command process
  976. ;
  977. LUX:    LDA    CMDLEN        ; Get the length of the command line
  978.     CPI    3        ; Was input only 'LUX'
  979.     JZ    LUX04        ; Error...
  980.     CALL    FNDSPC        ; Find a space in command line
  981.     JC    LUX05        ; Error if no space found
  982.     CALL    ADVANC        ; Search for the next non-blank character
  983.     JC    LUX05        ; Error if no more characters left
  984.     CALL    DRUSR        ; Get drive/user
  985.     JC    LUX05        ; If drive/user specification error
  986.     push    h        ; save command pointer
  987.     mov    h,b
  988.     mov    l,c
  989.     shld    tmpdrv        ; save the temporary drive/user
  990.     pop    h        ; get cmd pointer back
  991.     XCHG            ; De is source address to create new fcb
  992.     LXI    H,TMPFCB    ; Index temporary fcb
  993.     CALL    SCANR1        ; Create the new fcb
  994.     LXI    H,'BL'        ; Set 'LB' into first two bytes of file type
  995.     SHLD    TMPFCB+9
  996.     MVI    A,'R'        ; Set 'R' into last byte of file type
  997.     STA    TMPFCB+11
  998.     CALL    SETTMP        ; Log into the requested drive/user
  999.     LXI    D,080H
  1000.     MVI    C,26        ; BDOS set DMA function
  1001.     CALL    5        ; Set DMA address to 80h
  1002.     LXI    D,TMPFCB    ; Index temporary FCB
  1003.     MVI    C,17        ; Bdos search first function
  1004.     CALL    5
  1005.     INR    A        ; Test for existence
  1006.     JNZ    LUX01        ; OK, go
  1007.     LXI    H,'RA'        ; Check for .ARC file
  1008.     SHLD    TMPFCB+9
  1009.     MVI    A,'C'
  1010.     STA    TMPFCB+11
  1011.     LXI    D,080H
  1012.     MVI    C,26
  1013.     CALL    5
  1014.     LXI    D,TMPFCB
  1015.     MVI    C,17
  1016.     CALL    5
  1017.     INR    A
  1018.     JNZ    SETFLG        ; Set ARCFLG
  1019.     LXI    H,'RA'        ; Check for .ARK file
  1020.     SHLD    TMPFCB+9
  1021.     MVI    A,'K'
  1022.     STA    TMPFCB+11
  1023.     LXI    D,080H
  1024.     MVI    C,26
  1025.     CALL    5
  1026.     LXI    D,TMPFCB
  1027.     MVI    C,17
  1028.     CALL    5
  1029.     INR    A
  1030.     JZ    LUX05        ; Cant find file
  1031.     MVI    A,07FH
  1032.     STA    ARCFLG        ; Set .ARK flag true
  1033.     JMP    LUX02
  1034. ;
  1035. SETFLG:    MVI    A,0FFH        ; Set .ARC flag true
  1036.     STA    ARCFLG
  1037.     JMP    LUX02
  1038. ;.....
  1039. ;
  1040. ;
  1041. LUX01:    MVI    A,0        ; Set .ARC flag false
  1042.     STA    ARCFLG
  1043. ;
  1044. LUX02:    LHLD    TMPDRV        ; Get temporary drive/user
  1045.     SHLD    RQDDRV        ; Set new drive/user
  1046.     LXI    H,TMPFCB+1    ; Source address of new name
  1047.     LXI    D,LBRNAM    ; Current .lbr name
  1048.     LXI    B,12        ; 8 character file name
  1049.     call    LDIRs        ; Move it
  1050.     CALL    ILPRT        ; For display neatness
  1051.     DB    CR,LF,0
  1052.     MVI    A,0FFH        ; Set the auto-directory flag
  1053.     STA    DOADIR
  1054.     JMP    GETCMD
  1055. ;.....
  1056. ;
  1057. ;
  1058. LUX04:    CALL    ILPRT
  1059.     DB    CR,LF,'++ Invalid drive/user number ++',CR,LF,0
  1060.     JMP    GETCMD
  1061. ;.....
  1062. ;
  1063. ;
  1064. LUX05:    CALL    ILPRT
  1065.     DB    CR,LF,LF,'Can''t find ',0
  1066.     CALL    DVUPR1
  1067.     MVI    B,8
  1068.     LXI    H,TMPFCB+1
  1069.     CALL    NAMPR1        ; Print the file name
  1070.     CALL    ILPRT
  1071.     DB    ' - check your spelling',CR,LF,0
  1072.     JMP    GETCMD
  1073. ;.....
  1074. ;
  1075. ;
  1076. PROCES:    XRA    A        ; Zero last byte of new command line
  1077.     lhld    cptrix
  1078.     mov    m,a
  1079.     LXI    H,TBUFF+1
  1080.     STA    HLPCNT        ; Reset the error count
  1081.     CALL    DRUSR        ; Get drive/user
  1082.     push    h
  1083.     mov    h,b
  1084.     mov    l,c
  1085.     shld    comdrv
  1086.     pop    h
  1087.     XCHG            ; De is source address to create new FCB
  1088.     CALL    SCANER        ; Create the new FCB
  1089.     XCHG            ; Into 'HL'
  1090.     LXI    D,TBUFF+1    ; Start of command buffer
  1091.     PUSH    H
  1092.     PUSH    D
  1093.     ORA    A        ; Clear any carry
  1094.     mov    a,h
  1095.     sbb    d
  1096.     mov    h,a
  1097.     mov    a,l
  1098.     sbb    e
  1099.     mov    l,a        ; Replace Z80 SBC HL,DE
  1100.     LDA    TBUFF        ; Get command line length
  1101.     SUB    L        ; Calculate new length
  1102.     STA    TBUFF        ; Put new length
  1103.     MVI    A,07EH        ; Calculate length of block move
  1104.     SUB    L
  1105.     MOV    C,A        ; Set into C
  1106.     MVI    B,0        ; 'B' gets zero
  1107.     POP    D        ; Restore destination
  1108.     POP    H        ; And source
  1109.     call    LDIRs        ; Move the block down
  1110.     LXI    H,FCB1        ; Set up first FCB
  1111.     LXI    D,TBUFF+1
  1112.     CALL    SCANR1
  1113.     LXI    H,FCB2        ; Set up second FCB
  1114.     CALL    SCANR1
  1115. ;
  1116. ;
  1117. ; Force the default file type (.COM)
  1118. ;
  1119.     LXI    H,'OC'        ; 'CO'
  1120.     SHLD    DEFFCB+9
  1121.     MVI    A,'M'        ; 'M'
  1122.     STA    DEFFCB+11
  1123.     XRA    A        ; Zero the record count and
  1124.     STA    DEFFCB+15    ;   the extent number
  1125.     STA    DEFFCB+32
  1126.     CALL    SETCOM        ; Set .COM drive/user
  1127.     LXI    D,TPA
  1128.     MVI    C,01AH
  1129.     CALL    BDOS        ; Set DMA to TPA
  1130.     LXI    D,DEFFCB
  1131.     MVI    C,011H
  1132.     CALL    BDOS        ; Search for first
  1133.     INR    A
  1134.     JNZ    PROCE1        ; File found
  1135.     CALL    ILPRT
  1136.     DB    CR,LF,'Can''t find ',0
  1137.     MVI    B,8
  1138.     LXI    H,DEFFCB+1
  1139.     CALL    NAMPR1        ; Print the file name
  1140.     CALL    ILPRT        ; CR/LF
  1141.     DB    CR,LF,0
  1142.     JMP    ENTRY        ; Go for more commands
  1143. ;.....
  1144. ;
  1145. ;
  1146. PROCE1:    LXI    D,TPA
  1147.     MVI    C,01AH
  1148.     CALL    BDOS        ; Set DMA to TPA
  1149.     LXI    D,DEFFCB
  1150.     MVI    C,00FH
  1151.     CALL    BDOS        ; Open file
  1152.     INR    A
  1153.     JNZ    PROCE2
  1154.     CALL    ILPRT
  1155.     DB    CR,LF,'.COM File error - notify SYSOP',CR,LF,0
  1156.     JMP    ENTRY
  1157. ;.....
  1158. ;
  1159. ;
  1160. ; Load the .COM file into memory at 100h and call it
  1161. ;
  1162. PROCE2:    LXI    H,080H
  1163.     LXI    D,080H
  1164. ;
  1165. LODCOM:    DAD    D        ; Add record size offset
  1166.     XCHG            ; Get DMA address into 'DE'
  1167.     PUSH    D        ; Save 'DE' and 'HL'
  1168.     PUSH    H
  1169.     MVI    C,01AH
  1170.     CALL    BDOS        ; Set DMA
  1171.     LXI    D,DEFFCB    ; Index .com file name
  1172.     MVI    C,014H
  1173.     CALL    BDOS        ; Read a record
  1174.     POP    H        ; Restore 'DE' and 'HL'
  1175.     POP    D
  1176.     XCHG            ; 'HL' is dma address again
  1177.     ORA    A        ; End of file ?
  1178.     JZ    LODCOM        ; No - read another record
  1179.     MVI    C,13
  1180.     CALL    BDOS        ; Reset drive system
  1181.     CALL    SETNEW        ; Set new drive/user
  1182.     XRA    A
  1183.     STA    ACTIVE        ; Clear command mode active
  1184.     CALL    CRLF
  1185.     CALL    TPA        ; Call the loaded file @100h
  1186.     LXI    D,35        ; Zero out FCB1
  1187.     LXI    H,FCB1
  1188. ;
  1189. ZEROFCB:MVI    M,0
  1190.     INX    H
  1191.     DJNZ    ZEROFCB
  1192.     JMP    ENTRY        ; Go for more commands
  1193. ;.....
  1194. ;
  1195. ;
  1196. NAMPRT:    MVI    B,8        ; 8 character file name
  1197.     LXI    H,LBRNAM    ; Index .LBR name
  1198. ;
  1199. NAMPR1:    MOV    A,M        ; Get a byte
  1200.     CPI    020H        ; Space?
  1201.     JZ    NAMPR2        ; Yes - dont print
  1202.     CALL    CTYPE        ; Else print the character
  1203. ;
  1204. NAMPR2:    INX    H        ; Next character
  1205.     DJNZ    NAMPR1        ; Process 8 characters
  1206.     MVI    A,'.'        ; Print a seperator
  1207.     CALL    CTYPE
  1208.     MVI    B,3        ; 3 character file type
  1209. ;
  1210. NAMPR3:    MOV    A,M        ; Get a character
  1211.     CALL    CTYPE        ; Print it
  1212.     INX    H        ; Next character
  1213.     DJNZ    NAMPR3        ; Process 3 characters
  1214.     RET
  1215. ;.....
  1216. ;
  1217. ;
  1218. ; Write a string of characters to the crt
  1219. ;
  1220. ILPRT:    XTHL            ; Save return address/get character pointer
  1221. ;
  1222. ILPRT1:    MOV    A,M        ; Get a byte
  1223.     ORA    A        ; Test it
  1224.     JZ    ILPRT2        ; Null - end of string
  1225.     CALL    CTYPE        ; Else type the character
  1226.     INX    H        ; Next character
  1227.     JMP    ILPRT1        ; Loop for more
  1228. ;
  1229. ILPRT2:    INX    H
  1230.     XTHL            ; Restore return address
  1231.     RET            ; Return to caller
  1232. ;.....
  1233. ;
  1234. ;
  1235. ; Write a string of characters to the command line
  1236. ;
  1237. ; (works like ILPRT above)
  1238. ;
  1239. FILTYP:    XTHL
  1240. ;
  1241. FILTY1:    MOV    A,M
  1242.     ORA    A
  1243.     JZ    FILTY2
  1244.     CALL    PUTIN
  1245.     INX    H
  1246.     JMP    FILTY1
  1247. ;
  1248. FILTY2:    XTHL
  1249.     RET
  1250. ;.....
  1251. ;
  1252. ;
  1253. ; Puts ' $L' on command line
  1254. ;
  1255. FILDIR:    CALL    FILSPC
  1256.     MVI    A,'$'
  1257.     CALL    PUTIN
  1258.     MVI    A,'L'
  1259.     CALL    PUTIN
  1260. ;
  1261. ;
  1262. ; Fill command line with a space
  1263. ;
  1264. FILSPC:    MVI    A,20H        ; Space character
  1265.     JMP    PUTIN        ; Fill in
  1266. ;.....
  1267. ;
  1268. ;
  1269. ; Fill command line with .LBR name
  1270. ;
  1271. FILNAM:    MVI    B,8        ; 8 character file name
  1272.     LXI    H,LBRNAM    ; Index .LBR name
  1273. ;
  1274. FILNA1:    MOV    A,M        ; Get a character
  1275.     CPI    020H        ; Space ?
  1276.     JZ    FILNA2        ; Yes - dont add to command line
  1277.     CALL    PUTIN        ; Put character into command line
  1278. ;
  1279. FILNA2:    INX    H        ; Next character
  1280.     DJNZ    FILNA1        ; Process 8 characters
  1281.     MVI    A,'.'        ; Put in a seperator character
  1282.     CALL    PUTIN
  1283.     MVI    B,3        ; 3 character file type
  1284. ;
  1285. FILNA3:    MOV    A,M        ; Get a character
  1286.     CALL    PUTIN        ; Put in command line
  1287.     INX    H        ; Next character
  1288.     DJNZ    FILNA3        ; Process 3 characters
  1289.     RET            ; Return to caller
  1290. ;.....
  1291. ;
  1292. ;
  1293. ; Fill command line with member name
  1294. ;
  1295. FILMEM:    CALL    PARSER        ; Parse member name
  1296.     LXI    H,MEMBER    ; Index member name
  1297.     MVI    B,12        ; 12 character max
  1298. ;
  1299. FILME1:    MOV    A,M        ; Get a byte
  1300.     ORA    A        ; End of input
  1301.     RZ            ; Yes - return
  1302.     CALL    PUTIN        ; Fill in one character
  1303.     INX    H        ; Next character
  1304.     DJNZ    FILME1        ; Continue looping
  1305.     RET            ; Done
  1306. ;
  1307. Putin:    push    h        ; Stuff the character into command line
  1308.     lhld    cptrix
  1309.     mov    m,a
  1310.     inx    h        ; Get ready for next character
  1311.     shld    cptrix
  1312.     lxi    h,tbuff        ; Bump command line length
  1313.     inr    m
  1314.     pop    h
  1315.     RET            ; Return to caller
  1316. ;.....
  1317. ;
  1318. ;
  1319. ; Parse out a member name
  1320. ;
  1321. PARSER:    LXI    H,MEMBER    ; Index member name
  1322.     MVI    B,12        ; Max 12 character filename
  1323. ;
  1324. PARSE1:    MVI    M,0        ; Zero character
  1325.     INX    H        ; Next character
  1326.     DJNZ    PARSE1        ; Clear the entire member name
  1327.     CALL    ADVANC        ; Advance to the next non blank character
  1328.     RC            ; If at the end of the line
  1329.     LXI    D,MEMBER    ; DE is index to member, HL set by ADVANC
  1330.     LHLD    NXTWRD
  1331. ;
  1332. PARSE2:    MOV    A,M        ; Get source byte
  1333.     ORA    A        ; End of input line ?
  1334.     RZ            ; Yes - return
  1335. ;
  1336.     STAX    D        ; Put byte
  1337.     INX    H        ; Next source
  1338.     INX    D        ; Next destination
  1339.     JMP    PARSE2        ; Continue looping
  1340. ;.....
  1341. ;
  1342. ;
  1343. ; Advance the word at NXTWRD to the next non-blank address of the com-
  1344. ; mand line.  Set carry if no more characters available.
  1345. ;
  1346. ADVANC:    LHLD    NXTWRD        ; Get pointer to next word
  1347. ;
  1348. ADVAN1:    MOV    A,M        ; Get a byte
  1349.     ORA    A        ; Test flags
  1350.     JZ    ADVAN3        ; Error - null character
  1351.     CPI    020H        ; Space ?
  1352.     JNZ    ADVAN2        ; Yes - done
  1353.     INX    H
  1354.     SHLD    NXTWRD        ; Put pointer back
  1355.     JMP    ADVAN1        ; Loop for more
  1356. ;
  1357. ADVAN2:    ORA    A        ; Clear any carry
  1358.     RET
  1359. ;
  1360. ADVAN3:    STC            ; Set error condition
  1361.     RET
  1362. ;.....
  1363. ;
  1364. ;
  1365. FNDSPC:    LXI    H,CMDLIN+2    ; Index command line
  1366. ;
  1367. FND01:    MOV    A,M        ; Get a byte from command line
  1368.     ORA    A        ; Eol ?
  1369.     JZ    FNDER        ; Error...
  1370.     CPI    020H        ; Space?
  1371.     JZ    FNDEX        ; Yes - go find requested file name
  1372.     INX    H        ; Next character
  1373.     JMP    FND01        ; Else continue the search
  1374. ;
  1375. FNDER:    STC            ; All chars. scanned and no space found
  1376.     RET
  1377. ;
  1378. FNDEX:    SHLD    NXTWRD        ; Set character location
  1379.     ORA    A        ; Assure carry reset
  1380.     RET            ; 
  1381. ;
  1382. NXTSPC:    LHLD    NXTWRD        ; Get pointer to next word
  1383. ;
  1384. NXTSP1:    MOV    A,M        ; Get a byte
  1385.     ORA    A        ; Is it a null?
  1386.     JZ    NXTSP2        ; Yes - return
  1387.     CPI    020H        ; If at a space?
  1388.     JZ    NXTSP2        ; Yes - return
  1389.     INX    H        ; Next character
  1390.     JMP    NXTSP1        ; And continue looking
  1391. ;
  1392. NXTSP2:    SHLD    NXTWRD
  1393.     RET
  1394. ;.....
  1395. ;
  1396. ;
  1397. ; In-line compare.  Compares string addressed by 'DE' to string after
  1398. ; call (ends with zero).  Return with carry set means strings not the
  1399. ; same.  All registers except 'A'-reg are unaffected.
  1400. ;
  1401. ILCMP:    XTHL
  1402.     PUSH    D
  1403. ;
  1404. ILCMP1:    MOV    A,M        ; Get a byte from source
  1405.     ORA    A        ; Null
  1406.     JZ    SAME1        ; Yes - same so far - test next char
  1407.     LDAX    D        ; Get a byte from command string
  1408.     CMP    M        ; Same as source
  1409.     JNZ    NOTSAM        ; No - not the same
  1410.     INX    H        ; Next source
  1411.     INX    D        ; Next compare
  1412.     JMP    ILCMP1        ; Loop again
  1413. ;
  1414. NOTSAM:    XRA    A        ; Zero for the test
  1415. ;
  1416. NSLP:    INX    H        ; Next immediate byte
  1417.     CMP    M        ; Null yet ?
  1418.     JNZ    NSLP        ; No - continue
  1419. ;
  1420. SAME2:    STC            ; Set error condition
  1421. ;
  1422. SAME:    XCHG            ; Get command string pointer
  1423.     SHLD    NXTWRD        ; Store it
  1424.     XCHG            ; Restore return address
  1425.     POP    D        ; Restore source address
  1426.     INX    H        ; Adjust to stack
  1427.     XTHL            ; Replace return address
  1428.     RET            ; Return
  1429. ;
  1430. SAME1:    LDAX    D        ; Get the next byte from command line
  1431.     ORA    A        ; Null ?
  1432.     JZ    SAME        ; Yes - its ok
  1433.     CPI    20H        ; Space ?
  1434.     JZ    SAME        ; Yes - thats ok too...
  1435.     JMP    SAME2        ; Not ok- must be another character
  1436. ;.....
  1437. ;
  1438. ;
  1439. CTYPE:    PUSH    PSW        ; Save all registers
  1440.     PUSH    B
  1441.     PUSH    D
  1442.     PUSH    H
  1443.     ANI    7FH        ; Be sure its ASCII
  1444.     MOV    E,A        ; Into 'E'
  1445.     MVI    C,2        ; Cpm console function
  1446.     CALL    BDOS
  1447.     POP    H        ; Restore all registers
  1448.     POP    D
  1449.     POP    B
  1450.     POP    PSW
  1451.     RET            ; Return to caller
  1452. ;.....
  1453. ;
  1454. ;
  1455. CRLF:    MVI    A,13
  1456.     CALL    CTYPE
  1457.     MVI    A,10
  1458.     JMP    CTYPE
  1459. ;.....
  1460. ;
  1461. ;
  1462. ; Get the drive and user number for a file from command string index by
  1463. ; 'HL'
  1464. ;
  1465. ; On entry:
  1466. ;
  1467. ;    'HL' points to first byte of the command string
  1468. ;
  1469. ; on exit:
  1470. ;
  1471. ;    'HL' points to the byte following ':' in the command string if
  1472. ;      the ':' was found in the first 4 character positions.
  1473. ;    -or-
  1474. ;    'HL' points to the first byte of the command string if no ':'
  1475. ;      was found.
  1476. ;
  1477. ;    'C'  contains the requested drive number (0-15)
  1478. ;
  1479. ;    'B'  contains the requested user number (0-15)
  1480. ;
  1481. ;    'AF' the number of characters thru the ':' in the command string.
  1482. ;
  1483. ;    'CY' is set if drive or user number is out of range (0-15)
  1484. ;
  1485. ;-----------------------------------------------------------------------
  1486. ;
  1487. DRUSR:    SHLD    TEMPHL        ; Save the pointer address
  1488.     shld    cptrix        ; 'IX' get the pointer address
  1489.     LXI    B,5        ; 
  1490.     MVI    A,':'
  1491.     CPIR    2        ; Search for the ':' macro
  1492.     MOV    A,C        ; Get 'B' result from 'CPIR' instruction
  1493.     STA    LENGTH        ; Keep for possible adjust
  1494.     XCHG            ; De points to the byte following ':'
  1495.     LXI    H,VTABLE    ; Index address table
  1496.     DAD    B        ; Add word offset
  1497.     DAD    B
  1498.     MOV    A,M        ; Get routine lsb
  1499.     INX    H
  1500.     MOV    H,M        ; Get routine msb
  1501.     MOV    L,A
  1502.     LXI    B,0        ; Set up drive/user storage
  1503.     PCHL            ; Execute
  1504. ;.....
  1505. ;
  1506. ;
  1507. VTABLE:    DW    DRUS0        ; B=0 -     FILENAME.EXT
  1508.     DW    DRUS1        ; B=1 - A15:FILENAME.EXT
  1509.     DW    DRUS2        ; B=2 -  A1:FILENAME.EXT
  1510.     DW    DRUS3        ; B=3 -   A:FILENAME.EXT
  1511.     DW    DRUS4        ; B=4 -    :FILENAME.EXT
  1512. ;
  1513. ;
  1514. ; Format was - FILENAME.EXT
  1515. ;
  1516. DRUS0:    CALL    GETDFU        ; Get the default user
  1517.     CALL    GETDFD        ; Get the default drive
  1518.     LHLD    TEMPHL        ; Get old buffer pointer back
  1519.     XRA    A        ; Zero move length
  1520.     RET            ; All done
  1521. ;.....
  1522. ;
  1523. ;
  1524. ; Format was - DUU:FILENAME.EXT
  1525. ;
  1526. DRUS1:    CALL    GETDRV        ; Get the drive parameter
  1527.     push    h
  1528.     lhld    cptrix
  1529.     mov    a,m
  1530.     pop    h
  1531.     CPI    '0'
  1532.     JC    ERROR
  1533.     CPI    '9'+1
  1534.     JNC    ERROR
  1535.     SUI    '0'
  1536.     MOV    B,A        ; Put in drive number
  1537.     ADD    B
  1538.     MOV    B,A
  1539.     push    h        ; Skip the tens digit
  1540.     lhld    cptrix
  1541.     inx    h
  1542.     shld    cptrix
  1543.     pop    h
  1544.     JMP    GETUSR        ; Get the user number
  1545. ;.....
  1546. ;
  1547. ;
  1548. ; Format was - DU:FILENAME.EXT
  1549. ;
  1550. DRUS2:    CALL    GETDRV        ; Get the drive parameter
  1551.     JMP    GETUSR        ; Get the user number
  1552. ;.....
  1553. ;
  1554. ;
  1555. ; Format was - D:FILENAME.EXT
  1556. ;
  1557. DRUS3:    CALL    GETDRV        ; Get the drive parameter
  1558.     CALL    GETDFU        ; Get the default user
  1559. ;
  1560. ;
  1561. ; Format was - :FILENAME.EXT
  1562. ;
  1563. DRUS4:    JMP    DRUS5
  1564. ;
  1565. Getdrv:    push    h
  1566.     lhld    cptrix
  1567.     mov    a,m
  1568.     pop    h
  1569.     CPI    'A'
  1570.     JC    ERROR1
  1571.     CPI    'Q'
  1572.     JNC    ERROR1
  1573.     SUI    'A'
  1574.     MOV    C,A        ; Put in drive number
  1575.     push    h
  1576.     lhld    cptrix
  1577.     inx    h
  1578.     shld    cptrix
  1579.     pop    h
  1580.     RET
  1581. ;.....
  1582. ;
  1583. ;
  1584. Getusr:    push    h
  1585.     lhld    cptrix
  1586.     mov    a,m
  1587.     pop    h
  1588.     CPI    '0'
  1589.     JC    ERROR
  1590.     CPI    '9'+1
  1591.     JNC    ERROR
  1592.     SUI    '0'
  1593.     ADD    B
  1594.     MOV    B,A
  1595. ;
  1596. ;
  1597. ; Adjust the byte in 'LENGTH'
  1598. ;
  1599. DRUS5:    XCHG            ; Hl points to byte following ':' if any
  1600.     LDA    LENGTH        ; Get length of move
  1601.     ORA    A        ; Test it
  1602.     RZ            ; Return if null/ clear carry
  1603.     MOV    E,A
  1604.     MVI    A,5
  1605.     SUB    E
  1606.     STA    LENGTH
  1607.     ORA    A        ; Clear any error
  1608.     RET
  1609. ;.....
  1610. ;
  1611. ;
  1612. ERROR1:    POP    D        ; Kill return address from subroutine
  1613. ERROR:    STC            ; Set error condition
  1614.     RET
  1615. ;.....
  1616. ;
  1617. ;
  1618. ; Get default user
  1619. ;
  1620. GETDFU:    PUSH    B
  1621.     PUSH    D
  1622.     PUSH    H
  1623.     MVI    C,020H
  1624.     MVI    E,0FFH
  1625.     CALL    BDOS
  1626.     POP    H
  1627.     POP    D
  1628.     POP    B
  1629.     MOV    B,A        ; Set 'B' register to current user
  1630.     RET
  1631. ;.....
  1632. ;
  1633. ;
  1634. ; Get default drive
  1635. ;
  1636. GETDFD:    PUSH    B
  1637.     PUSH    D
  1638.     PUSH    H
  1639.     MVI    C,19H
  1640.     CALL    BDOS
  1641.     POP    H
  1642.     POP    D
  1643.     POP    B
  1644.     MOV    C,A        ; Set 'C' register to current drive
  1645.     RET
  1646. ;.....
  1647. ;
  1648. ;
  1649. ; Extract token from command line and place it into DEFFCB;
  1650. ;   format DEFFCB FCB if token resembles file name and type
  1651. ;   (FILENAME.TYP);
  1652. ;   on input, CIBPTR points to character at which to start scan
  1653. ;   on output, CIBPTR points to character at which to continue
  1654. ;   and zero flag is reset if '?' is in token
  1655. ;
  1656. ; Entry points:
  1657. ;    scaner - load token into first FCB
  1658. ;    scanr1 - load token into FCB poibted to by HL
  1659. ;
  1660. ;
  1661. SCANER:    LXI    H,DEFFCB    ; Point to DEFFCB
  1662. ;
  1663. SCANR1:    XRA    A        ; Set temporary drive number to default
  1664.     STA    TEMPDR
  1665.     CALL    ADVNCE        ; Skip to non-blank or end of line
  1666.     xchg            ; Set pointer to non-blank or end of line
  1667.     shld    ciptr
  1668.     xchg
  1669.     LDAX    D
  1670.     ORA    A
  1671.     JZ    SCANR2
  1672.     SBI    'A'-1
  1673.     MOV    B,A
  1674.     INX    D
  1675.     LDAX    D
  1676.     CPI    ':'
  1677.     JZ    SCANR3
  1678.     DCX    D
  1679. ;
  1680. SCANR2:    LDA    TDRIVE        ; Set 1st byte of deffcb as default drive
  1681.     MOV    M,A
  1682.     JMP    SCANR4
  1683. ;
  1684. SCANR3:    MOV    A,B
  1685.     STA    TEMPDR
  1686.     MOV    M,B
  1687.     INX    D
  1688. ;
  1689. SCANR4:    XRA    A        ; A=0
  1690.     STA    QMCNT        ; Init count of # of question marks in FCB
  1691.     MVI    B,8        ; Max of 8 characters in file name
  1692.     CALL    SCANF        ; Fill FCB file name
  1693. ;
  1694. ;
  1695. ; Extract file type from possible FILENAME.TYP
  1696. ;
  1697.     MVI    B,3        ; Prepare to extract type
  1698.     CPI    '.'        ; If (de) delimiter is a '.', we have a type
  1699.     JNZ    SCANR5        ; Fill file type bytes with <sp>
  1700.     INX    D        ; Pt to char in command line after '.'
  1701.     CALL    SCANF        ; Fill FCB file type
  1702.     JMP    SCANR6        ; Skip to next processing
  1703. ;
  1704. SCANR5:    CALL    SCANF4        ; Space fill
  1705. ;
  1706. ;
  1707. ; Fill in ex, s1, s2, and rc with zeroes
  1708. ;
  1709. SCANR6:    MVI    B,4        ; 4 bytes
  1710. ;
  1711. SCANR7:    INX    H        ; Point to next byte in DEFFCB
  1712.     MVI    M,0
  1713.     DJNZ    SCANR7
  1714. ;
  1715. ;
  1716. ; Scan complete -- DE points to delimiter byte after token
  1717. ;
  1718.     xchg
  1719.     shld    cibptr
  1720.     xchg
  1721. ;
  1722. ;
  1723. ; Set zero flag to indicate presence of '?' in FILENAME.TYP
  1724. ;
  1725.     LDA    QMCNT        ; Get number of question marks
  1726.     ORA    A        ; Set zero flag to indicate any '?'
  1727.     RET
  1728. ;
  1729. ;
  1730. ;  Scan token pointed to by DE for a maximum of B bytes; place it into
  1731. ;  file name field pointed to by HL; expand and interpret wild cards of
  1732. ;  '*' and '?'; on exit, DE points to terminating delimiter
  1733. ;
  1734. SCANF:    CALL    SDELM        ; Done if delimiter encountered - <sp> fill
  1735.     JZ    SCANF4
  1736.     INX    H        ; Pt to next byte in deffcb
  1737.     CPI    '*'        ; Is (de) a wild card?
  1738.     JNZ    SCANF1        ; Continue if not
  1739.     MVI    M,'?'        ; Place '?' in deffcb and dont advance de if so
  1740.     CALL    SCQ        ; Scanner count question marks
  1741.     JMP    SCANF2
  1742. ;
  1743. SCANF1:    MOV    M,A        ; Store filename char in deffcb
  1744.     INX    D        ; Pt to next char in command line
  1745.     CPI    '?'        ; Check for question mark (wild)
  1746.     CZ    SCQ        ; Scanner count question marks
  1747. ;
  1748. SCANF2:    DJNZ     SCANF        ; Decrement char count until 8 elapsed
  1749. ;
  1750. SCANF3:    CALL    SDELM        ; 8 chars or more - skip until delimiter
  1751.     RZ            ; Zero flag set if delimiter found
  1752.     INX    D        ; Pt to next char in command line
  1753.     JMP    SCANF3
  1754. ;
  1755. ;
  1756. ; Fill memory pointed to by HL with spaces for B bytes
  1757. ;
  1758. SCANF4:    INX    H        ; Pt to next byte in deffcb
  1759.     MVI    M,' '        ; Fill filename part with <sp>
  1760.     DJNZ    SCANF4
  1761.     RET
  1762. ;.....
  1763. ;
  1764. ;
  1765. ; Increment question mark count for scanner - this routine increments
  1766. ; the count of the number of question marks in the current FCB entry
  1767. ;
  1768. SCQ:    LDA    QMCNT        ; Get count
  1769.     INR    A        ; Increment
  1770.     STA    QMCNT        ; Put count
  1771.     RET
  1772. ;.....
  1773. ;
  1774. ;
  1775. ; Check to see if DE points to delimiter; if so, return with zero flag
  1776. ; set.
  1777. ;
  1778. SDELM:    LDAX    D
  1779.     ORA    A        ; 0=delimiter
  1780.     RZ
  1781.     CPI    ' '        ; Error if < <sp>
  1782.     RZ            ; <sp>=delimiter
  1783.     CPI    '='        ; '='=delimiter
  1784.     RZ
  1785.     CPI    5FH        ; Underscore=delimiter
  1786.     RZ
  1787.     CPI    '.'        ; '.'=delimiter
  1788.     RZ
  1789.     CPI    ':'        ; ':'=delimiter
  1790.     RZ
  1791.     CPI    ';'        ; ';'=delimiter
  1792.     RZ
  1793.     CPI    '<'        ; '<'=delimiter
  1794.     RZ
  1795.     CPI    '>'        ; '>'=delimiter
  1796.     RET
  1797. ;.....
  1798. ;
  1799. ;
  1800. ; Advance input pointr to first non-blank and fall through to SBLANK
  1801. ;
  1802. Advnce:    xchg
  1803.     shld    cibptr
  1804.     xchg
  1805. ;
  1806. ; Skip string pointed to by DE (string ends in 0) until end of string
  1807. ; or non-blank encountered (beginning of token)
  1808. ;
  1809. SBLANK:    LDAX    D
  1810.     ORA    A
  1811.     RZ
  1812.     CPI    ' '
  1813.     RNZ
  1814.     INX    D
  1815.     JMP    SBLANK
  1816. ;.....
  1817. ;
  1818. ;
  1819. ; Capitalize string (ending in 0) in cmdlin and set pointr for parsing
  1820. ;
  1821. CNVBUF:    LXI    H,CMDLIN+1    ; Point to users command
  1822.     MOV    B,M        ; Character count in 'B'
  1823.     INR    B        ; Add 1 in case of zero
  1824. ;
  1825. CNVBF1:    INX    H        ; Point to 1st valid character
  1826.     MOV    A,M        ; Capitalize command character
  1827.     CALL    UCASE
  1828.     MOV    M,A
  1829.     DJNZ     CNVBF1        ; Continue to end of command line
  1830. ;
  1831. CNVBF2:    MVI    M,0        ; Store ending <null>
  1832.     LXI    H,CMDLIN+2    ; Set command line pointer to 1st char
  1833.     SHLD    CIBPTR
  1834.     RET
  1835. ;.....
  1836. ;
  1837. ;
  1838. ; Convert character in 'A' to upper case
  1839. ;
  1840. UCASE:    CPI    61H        ; Lower-case a
  1841.     RC
  1842.     CPI    7BH        ; Greater than lower-case z?
  1843.     RNC
  1844.     ANI    5FH        ; Capitalize
  1845.     RET
  1846. ;.....
  1847. ;
  1848. ;
  1849. GETOLD:    CALL    GETDFU        ; Get current user into 'B'
  1850.     CALL    GETDFD        ; Get current drive into 'C'
  1851.     push    h
  1852.     mov    h,b        ; Get the parameters
  1853.     mov    l,c
  1854.     shld    olddrv
  1855.     pop    h
  1856.     RET
  1857. ;.....
  1858. ;
  1859. ;
  1860. Settmp:    push    h
  1861.     lhld    tmpdrv
  1862.     mov    b,h
  1863.     mov    c,l
  1864.     pop    h
  1865.     JMP    RESET
  1866. ;.....
  1867. ;
  1868. ;
  1869. Setold:    push    h
  1870.     lhld    olddrv
  1871.     mov    b,h
  1872.     mov    c,l
  1873.     pop    h
  1874.     JMP    RESET
  1875. ;.....
  1876. ;
  1877. ;
  1878. Setnew:    push    h
  1879.     lhld    rqddrv        ; get the old drive number
  1880.     mov    b,h
  1881.     mov    c,l
  1882.     pop    h
  1883.     JMP    RESET
  1884. ;.....
  1885. ;
  1886. ;
  1887. Setcom:    push    h
  1888.     lhld    comdrv        ; Get the old drive number
  1889.     mov    b,h
  1890.     mov    c,l
  1891.     pop    h
  1892. ;
  1893. RESET:    PUSH    B        ; Save drive/user
  1894.     PUSH    B
  1895.     MOV    E,C        ; Get selected drive
  1896.     MVI    C,14        ; Bdos function
  1897.     CALL    BDOS
  1898.     POP    B        ; Restore drive/user
  1899.     MOV    E,B        ; Get selected user
  1900.     MVI    C,32        ; Bdis set user function
  1901.     CALL    BDOS
  1902. ;
  1903. ;
  1904. ; Set up byte at 0004h - some programs may look at it
  1905. ;
  1906.     POP    B
  1907.     MOV    A,B        ; Get user number
  1908.     RAL
  1909.     RAL
  1910.     RAL
  1911.     RAL
  1912.     ANI    0F0H
  1913.     ORA    C
  1914.     STA    4
  1915.     RET
  1916. ;
  1917. DVUPR1:    LDA    TMPUSR
  1918.     PUSH    PSW
  1919.     LDA    TMPDRV
  1920.     JMP    DVUPR3
  1921. ;
  1922. DVUPRT:    LDA    RQDUSR        ; Get requested drive
  1923.     PUSH    PSW
  1924.     LDA    RQDDRV        ; Get the requested user
  1925. ;
  1926. DVUPR3:    ADI    'A'
  1927.     CALL    CTYPE        ; Print the drive 'A'-'P'
  1928.     POP    PSW
  1929.     CPI    10        ; Less that 10?
  1930.     JC    DVUPR2        ; Yes - dont print the '1'
  1931.     PUSH    PSW
  1932.     MVI    A,'1'
  1933.     CALL    CTYPE
  1934.     POP    PSW
  1935.     SUI    10
  1936. ;
  1937. DVUPR2:    ADI    '0'
  1938.     CALL    CTYPE
  1939.     MVI    A,':'
  1940.     JMP    CTYPE
  1941. ;.....
  1942. ;-----------------------------------------------------------------------
  1943. ;
  1944. ; This subroutine is a substitute for the Z80 LDIR instruction. 
  1945. ; Borrowed from ZCMD8080.ASM
  1946. ;
  1947. LDIRS:    PUSH    PSW        ; Save flags
  1948. LDIR1:    MOV    A,M        ; Fetch the byte
  1949.     STAX    D        ; Poke it
  1950.     INX    H        ; Increment pointers
  1951.     INX    D
  1952.     DCX    B        ; Decrement counter
  1953.     MOV    A,B        ; Check the counter to
  1954.     ORA    C        ;   see if we are done
  1955.     JNZ    LDIR1        ; Not done?
  1956.     POP    PSW        ; Finished
  1957.     RET            ; End of LDIR replacement subroutine
  1958. ;
  1959. ;-----------------------------------------------------------------------
  1960. ;
  1961. ;
  1962.      IF    RCPM
  1963. SUBFCB:    DB    0        ; Use current drive
  1964.     DB    '$$$     SUB'
  1965.     DB    0,0,0,0,0,0,0,0    ; Rest of the FCB
  1966.     DB    0,0,0,0,0,0,0,0    ; 
  1967.     DB    0,0,0,0,0
  1968.     DB    0,0,0,0        ; RFU
  1969. ;
  1970. ;
  1971. ; Edit this to contain the console commands necessary to execute the
  1972. ; logoff sequence for your system.
  1973. ;
  1974. BYECMD:    DB    0        ; <====== do not touch
  1975.     DB    'BYE',CR,LF    ; <====== put any number of cmds here
  1976.     DB    'Z'-40H        ; <====== do not touch
  1977. ;
  1978. BYELEN    EQU    $-BYECMD-1
  1979.      ENDIF            ; RCPM
  1980. ;
  1981. ;
  1982. ARCFLG:    DB    0
  1983. DOADIR:    DB    0
  1984. HLPCNT:    DB    0
  1985. BIOS3:    DW    0
  1986. TEMPDR:    DB    0
  1987. CIPTR:    DW    0
  1988. TDRIVE:    DB    0
  1989. QMCNT:    DB    0
  1990. CIBPTR:    DW    0
  1991. TEMPHL:    DW    0
  1992. LENGTH:    DB    0
  1993. OLDDRV:    DB    0
  1994. OLDUSR:    DB    0
  1995. RQDDRV:    DB    0        ; Requested drive
  1996. RQDUSR:    DB    0        ; Requested user
  1997. COMDRV:    DB    0        ; Drive to load .COM file
  1998. COMUSR:    DB    0        ; User to load .COM file
  1999. TMPDRV:    DB    0        ; Temporary drive number
  2000. TMPUSR:    DB    0        ; Temporary user number
  2001. ACTIVE:    DB    0        ; Attach command mode active
  2002. NXTWRD:    DW    0
  2003.     DW    0
  2004. CMDLIN:    DB    79
  2005. CMDLEN:    DB    0
  2006.     DS    79
  2007.     DB    0
  2008. ;
  2009. MEMBER:    DB    '            '
  2010.     DB    0
  2011.     DB    0
  2012. LBRNAM:    DB    '        '    ; Library file name
  2013.     DB    'LBR'
  2014. ;
  2015. Cptrix:    ds    2        ; <IX> points to command line
  2016. ;
  2017. TMPFCB:    DS    36
  2018. DEFFCB:    DS    36
  2019. ;
  2020.     DS    80        ; Area for stack
  2021. ;
  2022. STACK    EQU    $
  2023. ;
  2024. ;
  2025.     END
  2026.