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 / ZSYS / SIMTEL20 / ZCPR3 / ZCPR3.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  67KB  |  2,907 lines

  1.  
  2. *************************************************************************
  3. *                                    *
  4. *  Z C P R 3 -- Z80-Based Command Processor Replacement, Version 3.0    *
  5. *                                    *
  6. *  Copyright (c) 1984 by Richard Conn                    *
  7. *  Copyright US Government                        *
  8. *  All Rights Reserved                            *
  9. *                                    *
  10. *  ZCPR3 was written by Richard Conn, who assumes no responsibility    *
  11. *  or liability for its use.  ZCPR3 is released to the CP/M user    *
  12. *  community for non-commercial use only.                *
  13. *                                    *
  14. *  All registered users of CP/M are encouraged to freely copy and use    *
  15. *  ZCPR3 and its associated utilities on their registered systems for    *
  16. *  non-commercial purposes.                        *
  17. *                                    *
  18. *  Any commercial use of ZCPR3 is prohibited unless approved by the    *
  19. *  author, Richard Conn, or his authorized agent, Echelon, Inc, in    *
  20. *  writing.                                *
  21. *                                    *
  22. *  This is the RELEASE VERSION of ZCPR3.  Dated: 21 Apr 84        *
  23. *                                    *
  24. *************************************************************************
  25.  
  26. ;
  27. ;  ZCPR3 -- CP/M Z80 Command Processor Replacement (ZCPR) Version 3.0
  28. ;
  29. ;    ZCPR3 is based upon ZCPR2
  30. ;
  31. ;******** Structure Notes ********
  32. ;
  33. ;    ZCPR3 is divided into a number of major sections.  The following
  34. ; is an outline of these sections and the names of the major routines
  35. ; located therein.
  36. ;
  37. ; Section    Function/Routines
  38. ; -------    -----------------
  39. ;
  40. ;   --        Opening Comments, Equates, and Macro Definitions
  41. ;
  42. ;    0        JMP Table into ZCPR3
  43. ;            ENTRY
  44. ;
  45. ;    1        Buffers
  46. ;            1. Input Command Line and Default Command
  47. ;            2. File Type of COM File
  48. ;            3. SUBMIT File Control Block
  49. ;            4. Command File Control Block
  50. ;            5. Line Count Buffer
  51. ;            6. Resident Command Table
  52. ;
  53. ;    2        CPR Starting Modules
  54. ;            CPR1    CPR    RESTRT    RS0    RS1
  55. ;            RS2    PARSER    SCANNER    DUSCAN    DIRSCAN
  56. ;            PASSCK    SKSP    TSTEOL    INITFCB    IFCB
  57. ;            FILL    PRNNF
  58. ;
  59. ;    3        Utilities
  60. ;            CONIN    CRLF    CONOUT    LCOUT    LSTOUT
  61. ;            PAGER    READF    READ    BDOSB    NOTE
  62. ;            PRINTC    PRINT    PRIN1    GETDRV    DEFDMA
  63. ;            DMASET    RESET    BDOSJP    LOGIN    OPENF
  64. ;            OPEN    GRBDOS    CLOSE    SEARF    SEAR1
  65. ;            SEARN    SUBKIL    DELETE    GETUSR    SETUSR
  66. ;
  67. ;     4        CPR Utilities
  68. ;            SETUD    UCASE    PROMPT    READBUF    BREAK
  69. ;            SDELM    ADDAH    LDIR    NUMBER    NUMERR
  70. ;            HEXNUM    FCBLOG    SLOGIN    WHLCHK    CMDSER
  71. ;
  72. ;     5        CPR-Resident Commands and Functions
  73. ;     5A        DIR    DIRPR    PRFN    DIRPTR    GETSBIT
  74. ;     5B        ERA
  75. ;     5C        LIST
  76. ;     5D        TYPE
  77. ;     5E        SAVE    AMBCHK    EXTEST
  78. ;     5F        REN
  79. ;     5G        JUMP
  80. ;     5H        GO
  81. ;     5I        COMDIR    COM    CALLPROG
  82. ;     5J        GET    MLOAD    DLOGIN    PRNLE    PATH
  83. ;            MPATH    STACK    PWLIN
  84. ;
  85.  
  86. ;
  87. ;    The following MACLIB statements load all the user-selected equates
  88. ; which are used to customize ZCPR3 for the user's working environment.
  89. ;
  90.     MACLIB    Z3BASE
  91.     MACLIB    Z3HDR
  92. ;
  93. CTRLC    EQU    03H
  94. TAB    EQU    09H
  95. LF    EQU    0AH
  96. CR    EQU    0DH
  97. ;
  98. WBOOT    EQU    BASE+0000H        ;CP/M WARM BOOT ADDRESS
  99. UDFLAG    EQU    BASE+0004H        ;USER NUM IN HIGH NYBBLE, DISK IN LOW
  100. BDOS    EQU    BASE+0005H        ;BDOS FUNCTION CALL ENTRY PT
  101. TFCB    EQU    BASE+005CH        ;DEFAULT FCB BUFFER
  102. TFCB2    EQU    TFCB+16            ;2ND FCB
  103. TBUFF    EQU    BASE+0080H        ;DEFAULT DISK I/O BUFFER
  104. TPA    EQU    BASE+0100H        ;BASE OF TPA
  105. BIOS    EQU    CCP+0800H+0E00H        ;BIOS Location
  106. ;
  107. $-MACRO         ;FIRST TURN OFF THE EXPANSIONS
  108. ;
  109. ; MACROS TO PROVIDE Z80 EXTENSIONS
  110. ;   MACROS INCLUDE:
  111. ;
  112. ;    JR    - JUMP RELATIVE
  113. ;    JRC    - JUMP RELATIVE IF CARRY
  114. ;    JRNC    - JUMP RELATIVE IF NO CARRY
  115. ;    JRZ    - JUMP RELATIVE IF ZERO
  116. ;    JRNZ    - JUMP RELATIVE IF NO ZERO
  117. ;    DJNZ    - DECREMENT B AND JUMP RELATIVE IF NO ZERO
  118. ;    PUTRG    - SAVE REGISTERS
  119. ;    GETRG    - RESTORE REGISTERS
  120. ;
  121. ;    @GENDD MACRO USED FOR CHECKING AND GENERATING
  122. ;    8-BIT JUMP RELATIVE DISPLACEMENTS
  123. ;
  124. @GENDD    MACRO    ?DD    ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS
  125.     IF (?DD GT 7FH) AND (?DD LT 0FF80H)
  126.     DB    100H,?DD    ;Displacement Range Error
  127.     ELSE
  128.     DB    ?DD
  129.     ENDIF        ;;RANGE ERROR
  130.     ENDM
  131. ;
  132. ;
  133. ; Z80 MACRO EXTENSIONS
  134. ;
  135. JR    MACRO    ?N    ;;JUMP RELATIVE
  136.     IF    I8080    ;;8080/8085
  137.     JMP    ?N
  138.     ELSE        ;;Z80
  139.     DB    18H
  140.     @GENDD    ?N-$-1
  141.     ENDIF        ;;I8080
  142.     ENDM
  143. ;
  144. JRC    MACRO    ?N    ;;JUMP RELATIVE ON CARRY
  145.     IF    I8080    ;;8080/8085
  146.     JC    ?N
  147.     ELSE        ;;Z80
  148.     DB    38H
  149.     @GENDD    ?N-$-1
  150.     ENDIF        ;;I8080
  151.     ENDM
  152. ;
  153. JRNC    MACRO    ?N    ;;JUMP RELATIVE ON NO CARRY
  154.     IF    I8080    ;;8080/8085
  155.     JNC    ?N
  156.     ELSE        ;;Z80
  157.     DB    30H
  158.     @GENDD    ?N-$-1
  159.     ENDIF        ;;I8080
  160.     ENDM
  161. ;
  162. JRZ    MACRO    ?N    ;;JUMP RELATIVE ON ZERO
  163.     IF    I8080    ;;8080/8085
  164.     JZ    ?N
  165.     ELSE        ;;Z80
  166.     DB    28H
  167.     @GENDD    ?N-$-1
  168.     ENDIF        ;;I8080
  169.     ENDM
  170. ;
  171. JRNZ    MACRO    ?N    ;;JUMP RELATIVE ON NO ZERO
  172.     IF    I8080    ;;8080/8085
  173.     JNZ    ?N
  174.     ELSE        ;;Z80
  175.     DB    20H
  176.     @GENDD    ?N-$-1
  177.     ENDIF        ;;I8080
  178.     ENDM
  179. ;
  180. DJNZ    MACRO    ?N    ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
  181.     IF    I8080    ;;8080/8085
  182.     DCR    B
  183.     JNZ    ?N
  184.     ELSE        ;;Z80
  185.     DB    10H
  186.     @GENDD    ?N-$-1
  187.     ENDIF        ;;I8080
  188.     ENDM
  189. ;
  190. PUTRG    MACRO
  191.     PUSH    H    ;;SAVE REGISTERS IN ORDER
  192.     PUSH    D
  193.     PUSH    B
  194.     ENDM
  195. ;
  196. GETRG    MACRO
  197.     POP    B    ;;RESTORE REGISTERS IN ORDER
  198.     POP    D
  199.     POP    H
  200.     ENDM
  201. ;
  202. ; END OF Z80 MACRO EXTENSIONS
  203. ;
  204. ;
  205. ;**** Section 0 ****
  206. ;
  207.     ORG    CPRLOC
  208. ;
  209. ;  ENTRY POINTS INTO ZCPR3
  210. ;
  211. ;  IF MULTCMD (MULTIPLE COMMANDS ON ONE LINE) is FALSE:
  212. ;    If ZCPR3 is entered at location CPRLOC (at the JMP to CPR), then
  213. ; the default command in CMDLIN will be processed.  If ZCPR3 is entered
  214. ; at location CPRLOC+3 (at the JMP to CPR1), then the default command in
  215. ; CMDLIN will NOT be processed.
  216. ;    NOTE:  Entry into ZCPR3 at CPRLOC is permitted, but in order for this
  217. ; to work, CMDLIN MUST be initialized to contain the command line (ending in 0)
  218. ; and the C register MUST contain a valid User/Disk Flag
  219. ; (the most significant nybble contains the User Number and the least
  220. ; significant nybble contains the Disk Number).
  221. ;
  222. ;  IF MULTCMD is TRUE:
  223. ;    Entry at CPR or CPR1 has the same effect.  Multiple command processing
  224. ; will still continue.
  225. ;
  226. ;    If MULTCMD is FALSE, a user program need only load the buffer
  227. ; CMDLIN with the desired command line, terminated by a zero, in order to
  228. ; have this command line executed.  If MULTCMD is TRUE, a user program must
  229. ; load this buffer as before, but he must also set the NXTCHR pointer to
  230. ; point to the first character of the command line.
  231. ;
  232. ;    NOTE:  ***** (BIG STAR) ***** Programs such as SYNONYM3 will fail if
  233. ; multiple commands are enabled, but this feature is so very useful that I
  234. ; feel it is worth the sacrifice.  Some ZCPR3 utilities, like ALIAS and MENU,
  235. ; require multiple commands, and this feature also permits simple chaining
  236. ; of programs to be possible under the ZCPR3 environment.
  237. ;
  238. ;    Enjoy using ZCPR3!
  239. ;            Richard Conn
  240. ;
  241. ENTRY:
  242.     JMP    CPR    ; Process potential default command
  243.     JMP    CPR1    ; Do NOT process potential default command
  244. ;
  245. ;**** Section 1 ****
  246. ; BUFFERS ET AL
  247. ;
  248. ;  **** 1. INPUT COMMAND LINE AND DEFAULT COMMAND
  249. ;
  250.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  251. ;
  252. ; For Multiple Commands, the command line buffer (CMDLIN) is located external
  253. ; to ZCPR3 so that it is not overlayed during Warm Boots; the same is true
  254. ; for NXTCHR, the 2nd key buffer.  BUFSIZ and CHRCNT are not important and
  255. ; are provided so the BDOS READLN function can load CMDLIN directly and
  256. ; a user program can see how much space is available in CMDLIN for its text.
  257. ;
  258. NXTCHR    EQU    Z3CL        ;NXTCHR STORED EXTERNALLY (2 bytes)
  259. BUFSIZ    EQU    NXTCHR+2    ;BUFSIZ STORED EXTERNALLY (1 byte)
  260. CHRCNT    EQU    BUFSIZ+1    ;CHRCNT STORED EXTERNALLY (1 byte)
  261. CMDLIN    EQU    CHRCNT+1    ;CMDLIN STORED EXTERNALLY (long)
  262. BUFLEN    EQU    Z3CLS        ;LENGTH OF BUFFER
  263. ;
  264.     ELSE
  265. ;
  266. ; If no multiple commands are permitted, these buffers are left internal
  267. ; to ZCPR3 so that the original CCP command line facility (as used by
  268. ; programs like SYNONYM3) can be left intact.
  269. ;
  270. BUFLEN    EQU    80        ;MAXIMUM BUFFER LENGTH
  271. BUFSIZ:
  272.     DB    BUFLEN        ;MAXIMUM BUFFER LENGTH
  273. CHRCNT:
  274.     DB    0        ;NUMBER OF VALID CHARS IN COMMAND LINE
  275. CMDLIN:
  276.     DB    '               '    ;DEFAULT (COLD BOOT) COMMAND
  277.     DB    0            ;COMMAND STRING TERMINATOR
  278.     DS    BUFLEN-($-CMDLIN)+1    ;TOTAL IS 'BUFLEN' BYTES
  279. ;
  280. NXTCHR:
  281.     DW    CMDLIN        ;POINTER TO COMMAND INPUT BUFFER
  282. ;
  283.     ENDIF        ;MULTCMD
  284. ;
  285.  
  286. ;
  287. ;  **** 2. FILE TYPE FOR COMMAND
  288. ;
  289. COMMSG:
  290.     COMTYP            ;USE MACRO FROM Z3HDR.LIB
  291. ;
  292.     IF    SUBON        ;IF SUBMIT FACILITY ENABLED ...
  293. ;
  294. ;  **** 3. SUBMIT FILE CONTROL BLOCK
  295. ;
  296. SUBFCB:
  297.     DB    1        ;DISK NAME SET TO DEFAULT TO DRIVE A:
  298.     DB    '$$$'        ;FILE NAME
  299.     DB    '     '
  300.     SUBTYP            ;USE MACRO FROM Z3HDR.LIB
  301.     DB    0        ;EXTENT NUMBER
  302.     DB    0        ;S1
  303. SUBFS2:
  304.     DS    1        ;S2
  305. SUBFRC:
  306.     DS    1        ;RECORD COUNT
  307.     DS    16        ;DISK GROUP MAP
  308. SUBFCR:
  309.     DS    1        ;CURRENT RECORD NUMBER
  310. ;
  311.     ENDIF        ;SUBON
  312. ;
  313. ;  **** 4. COMMAND FILE CONTROL BLOCK
  314. ;
  315.     IF    EXTFCB NE 0    ;MAY BE PLACED EXTERNAL TO ZCPR3
  316. ;
  317. FCBDN    EQU    EXTFCB        ;DISK NAME
  318. FCBFN    EQU    FCBDN+1        ;FILE NAME
  319. FCBFT    EQU    FCBFN+8        ;FILE TYPE
  320. FCBDM    EQU    FCBFT+7        ;DISK GROUP MAP
  321. FCBCR    EQU    FCBDM+16    ;CURRENT RECORD NUMBER
  322. ;
  323.     ELSE            ;OR INTERNAL TO ZCPR3
  324. ;
  325. FCBDN:
  326.     DS    1        ;DISK NAME
  327. FCBFN:
  328.     DS    8        ;FILE NAME
  329. FCBFT:
  330.     DS    3        ;FILE TYPE
  331.     DS    1        ;EXTENT NUMBER
  332.     DS    2        ;S1 AND S2
  333.     DS    1        ;RECORD COUNT
  334. FCBDM:
  335.     DS    16        ;DISK GROUP MAP
  336. FCBCR:
  337.     DS    1        ;CURRENT RECORD NUMBER
  338. ;
  339.     ENDIF        ;EXTFCB
  340. ;
  341.  
  342. ;
  343. ;  **** 5. LINE COUNT BUFFER
  344. ;
  345.     IF    LTON
  346. PAGCNT:
  347.     DB    NLINES-2    ;LINES LEFT ON PAGE
  348.     ENDIF        ;LTON
  349. ;
  350. ;  **** 6. RESIDENT COMMAND TABLE
  351. ;   EACH TABLE ENTRY IS STRUCTURED AS FOLLOWS:
  352. ;    DB    'NAME'    ;NCHARS LONG
  353. ;    DW    ADDRESS    ;ADDRESS OF COMMAND
  354. ;
  355. CMDTBL:
  356.     DB    NCHARS    ;SIZE OF TEXT IN COMMAND TABLE
  357.     CTABLE        ;DEFINE COMMAND TABLE VIA MACRO IN Z3HDR FILE
  358.     DB    0    ;END OF TABLE
  359. ;
  360.  
  361. ;
  362. ;**** Section 2 ****
  363. ; ZCPR3 STARTING POINTS
  364. ;
  365. ; START ZCPR3 AND DON'T PROCESS DEFAULT COMMAND STORED IF MULTIPLE COMMANDS
  366. ; ARE NOT ALLOWED
  367. ;
  368. CPR1:
  369. ;
  370.     IF    NOT MULTCMD    ;IF MULTIPLE COMMANDS NOT ALLOWED
  371. ;
  372.     XRA    A        ;SET END OF COMMAND LINE SO NO DEFAULT COMMAND
  373.     STA    CMDLIN        ;FIRST CHAR OF BUFFER
  374. ;
  375.     ENDIF        ;NOT MULTCMD
  376. ;
  377. ; START ZCPR3 AND POSSIBLY PROCESS DEFAULT COMMAND
  378. ;
  379. ; NOTE ON MODIFICATION BY Ron Fowler:  BDOS RETURNS 0FFH IN
  380. ; ACCUMULATOR WHENEVER IT LOGS IN A DIRECTORY, IF ANY
  381. ; FILE NAME CONTAINS A '$' IN IT.  THIS IS NOW USED AS
  382. ; A CLUE TO DETERMINE WHETHER OR NOT TO DO A SEARCH
  383. ; FOR SUBMIT FILE, IN ORDER TO ELIMINATE WASTEFUL SEARCHES.
  384. ;
  385. CPR:
  386.     LXI    SP,STACK    ;RESET STACK
  387. ;
  388.     IF    NOT MULTCMD    ;ONLY ONE COMMAND PERMITTED
  389.     LXI    H,CMDLIN    ;SET PTR TO BEGINNING OF COMMAND LINE
  390.     SHLD    NXTCHR
  391.     ENDIF        ;NOT MULTCMD
  392. ;
  393.     PUSH    B
  394.     MOV    A,C        ;C=USER/DISK NUMBER (SEE LOC 4)
  395.     RAR            ;EXTRACT USER NUMBER
  396.     RAR
  397.     RAR
  398.     RAR
  399.     ANI    0FH
  400.     STA    CURUSR        ;SET USER
  401.     CALL    SETUSR        ;SET USER NUMBER
  402.     CALL    RESET        ;RESET DISK SYSTEM
  403. ;
  404.     IF    SUBON        ;IF SUBMIT FACILITY ENABLED
  405. ;
  406.     STA    RNGSUB        ;SAVE SUBMIT CLUE FROM DRIVE A:
  407. ;
  408.     ENDIF        ;SUBON
  409. ;
  410.     POP    B
  411.     MOV    A,C        ;C=USER/DISK NUMBER (SEE LOC 4)
  412.     ANI    0FH        ;EXTRACT CURRENT DISK DRIVE
  413.     STA    CURDR        ;SET IT
  414.     CNZ    LOGIN        ;LOG IN DEFAULT DISK IF NOT ALREADY LOGGED IN
  415.     CALL    SETUD        ;SET USER/DISK FLAG
  416.     CALL    DEFDMA        ;SET DEFAULT DMA ADDRESS
  417. ;
  418.     IF    SUBON        ;CHECK FOR $$$.SUB IF SUBMIT FACILITY IS ON
  419. ;
  420.     LXI    D,SUBFCB    ;CHECK FOR $$$.SUB ON CURRENT DISK
  421. RNGSUB    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  422.     MVI    A,0        ;2ND BYTE (IMMEDIATE ARG) IS THE RNGSUB FLAG
  423.     ORA    A        ;SET FLAGS ON CLUE
  424.     CNZ    SEAR1
  425.     STA    RNGSUB        ;SET FLAG (0=NO $$$.SUB)
  426. ;
  427.     ENDIF        ;SUBON
  428. ;
  429.     JR    RS1        ;CHECK COMMAND LINE FOR CONTENT
  430. ;
  431. ; PROMPT USER AND INPUT COMMAND LINE FROM HIM
  432. ;
  433. RESTRT:
  434.     LXI    SP,STACK    ;RESET STACK
  435. ;
  436. ; READ INPUT LINE FROM USER OR $$$.SUB
  437. ;
  438. RS0:
  439. ;
  440.     IF    Z3MSG NE 0
  441.     XRA    A        ;SET NO OUTPUT MESSAGE
  442.     STA    Z3MSG+3        ;ZCPR3 COMMAND STATUS
  443.     INR    A        ;SET ZCPR3 INPUT PROMPT
  444.     STA    Z3MSG+7        ;ZEX MESSAGE BYTE
  445.     ENDIF        ;Z3MSG NE 0
  446. ;
  447.     LXI    H,CMDLIN    ;SET POINTER TO FIRST CHAR IN COMMAND LINE
  448.     SHLD    NXTCHR        ;POINTER TO NEXT CHARACTER TO PROCESS
  449.     MVI    M,0        ;ZERO OUT COMMAND LINE IN CASE OF WARM BOOT
  450.     PUSH    H        ;SAVE PTR
  451.     CALL    READBUF        ;INPUT COMMAND LINE FROM USER (OR $$$.SUB)
  452. ;
  453.     IF    Z3MSG NE 0
  454.     XRA    A        ;NORMAL PROCESSING RESUMED
  455.     STA    Z3MSG+7        ;ZEX MESSAGE BYTE
  456.     ENDIF
  457. ;
  458.     POP    H        ;GET PTR
  459.     MOV    A,M        ;CHECK FOR COMMENT LINE
  460.     CPI    COMMENT        ;BEGINS WITH COMMENT CHAR?
  461.     JRZ    RS0        ;INPUT ANOTHER LINE IF SO
  462. ;
  463. ; PROCESS INPUT LINE; NXTCHR PTS TO FIRST LETTER OF COMMAND
  464. ;
  465. RS1:
  466.     LXI    SP,STACK    ;RESET STACK
  467. ;
  468. ; RETURN TO CURRENT DIRECTORY AND POINT TO NEXT CHAR IN COMMAND LINE
  469. ;
  470.     CALL    DLOGIN        ;RETURN TO CURRENT DIRECTORY
  471.     LHLD    NXTCHR        ;PT TO FIRST CHAR OF NEXT COMMAND
  472.     PUSH    H        ;SAVE PTR
  473. ;
  474. ; CAPITALIZE COMMAND LINE
  475. ;
  476. CAPBUF:
  477.     MOV    A,M        ;CAPITALIZE COMMAND CHAR
  478.     CALL    UCASE
  479.     MOV    M,A
  480.     INX    H        ;PT TO NEXT CHAR
  481.     ORA    A        ;EOL?
  482.     JRNZ    CAPBUF
  483.     POP    H        ;GET PTR TO FIRST CHAR IN LINE
  484. ;
  485. ; SET POINTER FOR MULTIPLE COMMAND LINE PROCESSING TO FIRST CHAR OF NEW CMND
  486. ;
  487. RS2:
  488.     CALL    SKSP        ;SKIP OVER SPACES
  489.     ORA    A        ;END OF LINE?
  490.     JRZ    RESTRT
  491.     CPI    CTRLC        ;ABORT CHAR?
  492.     JRZ    RESTRT
  493. ;
  494.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  495.     MOV    A,M        ;GET FIRST CHAR OF COMMAND
  496.     CPI    CMDSEP        ;IS IT A COMMAND SEPARATOR?
  497.     JRNZ    RS3
  498.     INX    H        ;SKIP IT IF IT IS
  499.     JR    RS2
  500.     ENDIF        ;MULTCMD
  501. ;
  502. RS3:
  503.     SHLD    NXTCHR        ;SET PTR TO FIRST CHAR OF NEW COMMAND LINE
  504.     SHLD    CURCMD        ;SAVE PTR TO COMMAND LINE FOR ERROR RETURN
  505. ;
  506. ; PARSE COMMAND LINE PTED TO BY HL
  507. ;
  508.     CALL    PARSER        ;PARSE ENTIRE COMMAND LINE
  509. ;
  510. ; CHECK FOR SHELL INVOCATION AND RUN IT IF SO
  511. ;
  512.     IF    Z3MSG NE 0
  513.     LDA    Z3MSG+3        ;GET COMMAND STATUS
  514.     CPI    1        ;SHELL?
  515.     JZ    RS4
  516.     ENDIF        ;Z3MSG NE 0
  517. ;
  518. ; IF IFON AND FCP AVAILABLE, TRY TO RUN FROM FCP
  519. ;
  520.     IF    IFON AND (FCP NE 0)
  521.     LXI    H,FCP+5        ;PT TO COMMAND TABLE
  522.     CALL    CMDSCAN        ;SCAN TABLE
  523.     JZ    CALLP        ;RUN IF FOUND (NO LEADING CRLF)
  524.     ENDIF        ;IFON AND (FCP NE 0)
  525. ;
  526. ; IF IFON, THEN CHECK FOR RUNNING IF AND FLUSH COMMAND LINE IF ENABLED
  527. ;
  528.     IF    IFON
  529.     LXI    H,Z3MSG+1    ;PT TO IF BYTE
  530.     MOV    A,M        ;GET IT
  531.     ORA    A        ;SEE IF ANY IF
  532.     JRZ    RS4        ;CONTINUE IF NOT
  533.     INX    H        ;PT TO IF ACTIVE BYTE
  534.     ANA    M        ;SEE IF CURRENT IF IS ACTIVE
  535.     JRZ    RS1        ;SKIP IF NOT
  536.     ENDIF        ;IFON
  537. RS4:
  538. ;
  539. ; IF DIR: PREFIX, HANDLE AS COM FILE
  540. ;
  541. COLON    EQU    $+1        ;FLAG FOR IN-THE-CODE MODIFICATION
  542.     MVI    A,0        ;COMMAND OF THE FORM 'DIR:COMMAND'?
  543.     ORA    A        ;0=NO
  544.     JNZ    COMDIR        ;PROCESS AS COM FILE IF DIR: FORM
  545. ;
  546. ; CHECK FOR RESIDENT COMMAND
  547. ;
  548.     CALL    CMDSER        ;SCAN FOR CPR-RESIDENT COMMAND
  549.     JZ    CALLP        ;RUN CPR-RESIDENT COMMAND WITH NO LEADING CRLF
  550. ;
  551. ; CHECK FOR RESIDENT COMMAND PACKAGE
  552. ;
  553.     IF    RCP NE 0
  554.     LXI    H,RCP+5        ;PT TO RCP COMMAND TABLE
  555.     CALL    CMDSCAN        ;CHECK FOR RCP
  556.     JZ    CALLPROG
  557.     ENDIF
  558. ;
  559. ; PROCESS AS COM FILE
  560. ;
  561.     JMP    COM        ;PROCESS COM FILE
  562.  
  563. ;
  564. ; ERROR PROCESSOR
  565. ;
  566. ERROR:
  567. ;
  568.     IF    SUBON        ;IF SUBMIT FACILITY IS ON
  569. ;
  570.     CALL    SUBKIL        ;TERMINATE ACTIVE $$$.SUB IF ANY
  571. ;
  572.     ENDIF        ;SUBON
  573. ;
  574.     CALL    CRLF        ;NEW LINE
  575. ;
  576.     IF    Z3MSG NE 0    ;MESSAGES ENABLED?
  577. ;
  578.     LDA    Z3MSG+3        ;WAS ERROR CAUSED BY NO SHELL?
  579.     ANI    1        ;BIT 0 SAYS ZCPR3 TRIED TO RUN A SHELL
  580.     JRNZ    ERRSH        ;ABORT SHELL
  581.     LDA    Z3MSG        ;GET ERROR HANDLER MESSAGE
  582.     MOV    B,A        ;... IN B
  583.     ORA    A        ;FLUSH AND RESUME?
  584.     JRZ    ERR0
  585.     MVI    A,2        ;SET ERROR FLAG
  586.     STA    Z3MSG+3        ;IN SHELL STATUS BUFFER
  587.     LHLD    CURCMD        ;PT TO BEGINNING OF ERROR
  588.     SHLD    Z3MSG+4        ;SAVE IN MESSAGE
  589.     LXI    H,Z3MSG+10H    ;PT TO COMMAND LINE
  590.     SHLD    NXTCHR        ;NEXT CHARACTER TO EXECUTE
  591.     JMP    RS1        ;RUN CONTENTS OF BUFFER
  592. ;
  593. ; CLEAR SHELL STACK AND RESTART COMMAND PROCESSING
  594. ;
  595. ERRSH:
  596. ;
  597.     IF    SHSTK NE 0    ;IF SHELL STACK AVAILABLE
  598.     XRA    A        ;CLEAR SHELL STACK
  599.     STA    SHSTK
  600.     ENDIF
  601. ;
  602.     JMP    RESTRT        ;RESTART PROCESSING
  603. ERR0:
  604. ;
  605.     ENDIF        ;Z3MSG NE 0
  606. ;
  607. CURCMD    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  608.     LXI    H,0        ;PT TO BEGINNING OF COMMAND LINE
  609. ERR1:
  610.     MOV    A,M        ;GET CHAR
  611.     ORA    A        ;END OF LINE?
  612.     JRZ    ERR2
  613.     CALL    CONOUT        ;PRINT COMMAND CHAR
  614.     INX    H        ;PT TO NEXT CHAR
  615.     JR    ERR1        ;CONTINUE
  616. ERR2:
  617.     CALL    PRINT        ;PRINT '?'
  618.     DB    '?'+80H
  619. ERR3:
  620.     JMP    RESTRT        ;RESTART CPR
  621.  
  622. ;
  623. ; PARSE COMMAND LINE PTED TO BY HL
  624. ;   RETURN WITH NZ IF ERROR IN COMMAND NAME
  625. ;
  626. PARSER:
  627. ;
  628. ; INITIALIZE THE COMMAND AND TOKEN FCBS
  629. ;
  630.     LXI    D,FCBDN        ;PT TO COMMAND FCB
  631.     CALL    INITFCB        ;INIT IT
  632.     LXI    D,TFCB        ;PT TO TOKEN FCB
  633.     CALL    INITFCB        ;INIT IT
  634. ;
  635. ; EXTRACT COMMAND NAME
  636. ;
  637.     LXI    D,FCBDN        ;PLACE COMMAND NAME INTO COMMAND FCB
  638.     CALL    SCANNER        ;EXTRACT COMMAND NAME
  639.     JRNZ    ERROR        ;ERROR RETURN
  640. ;
  641. ; CHECK FOR ERROR IN COMMAND NAME (FILE TYPE GIVEN)
  642. ;
  643.     LXI    D,FCBFT        ;PT TO FILE TYPE
  644.     LDAX    D        ;GET FIRST CHAR OF FILE TYPE
  645.     CPI    ' '        ;MUST BE BLANK, OR ERROR
  646.     JRNZ    ERROR        ;ERROR RETURN
  647. ;
  648. ; SET TYPE OF COMMAND
  649. ;
  650.     PUSH    H        ;SAVE PTR TO NEXT BYTE
  651.     LXI    H,COMMSG    ;PLACE DEFAULT FILE TYPE (COM) INTO FCB
  652.     MVI    B,3        ;3 BYTES
  653.     CALL    LDIR
  654.     POP    H        ;GET PTR TO NEXT BYTE
  655. ;
  656. ; SET DIR: PREFIX FLAG
  657. ;
  658. MYCOLON    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  659.     MVI    A,0        ;PREVIOUS TOKEN CONTAINED A COLON?
  660.     STA    COLON
  661. ;
  662. ; SAVE POINTER TO COMMAND TAIL FOR LATER COPY INTO TBUFF AND FIND END OF
  663. ;   COMMAND LINE; THIS IS ALSO THE ENTRY POINT FOR CMDRUN FACILITY TO
  664. ;   PARSE THE ENTIRE COMMAND LINE AS A TAIL
  665. ;
  666. PARSET:
  667.     SHLD    TAILSV        ;SAVE PTR TO COMMAND TAIL
  668.     PUSH    H        ;SAVE PTR
  669. CTAIL:
  670.     MOV    A,M        ;GET CHAR
  671.     CALL    TSTEOL        ;AT EOL?
  672.     JRZ    CTAIL1
  673.     INX    H        ;PT TO NEXT
  674.     JR    CTAIL
  675. CTAIL1:
  676.     SHLD    NXTCHR        ;SAVE PTR TO NEXT LINE
  677.     POP    H        ;GET PTR TO COMMAND TAIL
  678. ;
  679. ;  EXTRACT FIRST TOKEN
  680. ;
  681.     CALL    SKSP        ;SKIP OVER SPACES
  682.     RZ            ;DONE IF EOL OR END OF COMMAND
  683.     LXI    D,TFCB        ;STORE FIRST TOKEN IN TFCB
  684.     CALL    SCANNER        ;EXTRACT TOKEN
  685. ;
  686. ;  EXTRACT SECOND TOKEN
  687. ;
  688.     CALL    SKSP        ;SKIP OVER SPACES
  689.     RZ            ;DONE IF EOL OR END OF COMMAND
  690.     LXI    D,TFCB+16    ;PT TO 2ND FCB AND FALL THRU TO SCANNER
  691. ;
  692. ; EXTRACT TOKEN FROM COMMAND LINE AND PLACE IT INTO FCB PTED TO BY DE
  693. ;   FORMAT FCBDN FCB IF TOKEN RESEMBLES FILE NAME AND TYPE (FILENAME.TYP)
  694. ;     ON INPUT, HL PTS TO NEXT CHAR AND DE PTS TO FCB
  695. ;     ON OUTPUT, HL PTS TO DELIMITER AFTER TOKEN AND ZERO FLAG IS RESET
  696. ;       IF '?' IS IN TOKEN
  697. ;
  698. ; ENTRY POINTS:
  699. ;    SCANNER - LOAD TOKEN INTO FCB PTED TO BY DE
  700. ;
  701. SCANNER:
  702.     XRA    A        ;A=0
  703.     STAX    D        ;SET DEFAULT DRIVE
  704.     STA    MYCOLON        ;SET NO COLON
  705.     STA    TEMPDR        ;SET TEMPORARY DRIVE NUMBER TO DEFAULT
  706.     STA    QMCNT        ;ZERO QUESTION MARK COUNTER
  707.     LDA    CURUSR        ;GET CURRENT USER
  708.     STA    TEMPUSR        ;SET TEMPUSR
  709.     PUSH    D        ;SAVE PTR TO FIRST BYTE OF FCB
  710.     MVI    B,8        ;8 CHARS MAX
  711.     CALL    SCANF        ;PLACE FIRST TOKEN INTO FILE NAME FIELD
  712.     POP    D        ;GET PTR TO FIRST BYTE OF FCB
  713.     MOV    A,M        ;GET TERMINATING CHAR
  714.     STA    ENDCHAR        ;SET ENDING CHAR
  715.     CPI    ':'        ;COLON?
  716.     JRNZ    SCAN1        ;NO, WE HAVE A FILE NAME
  717.     STA    MYCOLON        ;SET COLON
  718.     INX    H        ;PT TO CHAR AFTER COLON
  719. ;
  720. ;  SCAN TOKEN FOR DIR: FORM, WHICH MEANS WE HAVE A USER/DISK SPECIFICATION
  721. ;    HL PTS TO CHAR AFTER COLON
  722. ;
  723.     IF    (Z3NDIR NE 0) AND NDINCP    ;NAMED DIRS AVAILABLE
  724. ;
  725.     IF    DUFIRST    ;DU: BEFORE DIR:
  726. ;
  727. ; CHECK FOR DU: FORM
  728. ;
  729.     IF    ACCPTDU    ;PERMIT DU: FORM
  730.     PUSH    D        ;SAVE PTR TO FCB DN
  731.     PUSH    H        ;SAVE PTR TO NEXT CHAR IN LINE
  732.     CALL    DUSCAN        ;CHECK FOR DU: FORM
  733.     POP    H        ;GET PTR TO NEXT CHAR
  734.     POP    D        ;GET PTR TO FCB
  735.     JRZ    SUD1        ;GOT IT
  736.     ENDIF        ;ACCPTDU
  737. ;
  738. ; CHECK FOR DIR: FORM
  739. ;
  740.     IF    ACCPTND    ;PERMIT DIR: FORM
  741.     PUSH    D        ;SAVE PTR TO FCB
  742.     PUSH    H        ;SAVE PTR TO NEXT CHAR
  743.     CALL    DIRSCAN        ;CHECK FOR DIR: FORM
  744.     POP    H        ;GET PTR TO NEXT CHAR
  745.     POP    D        ;GET PTR TO FCB
  746.     JRNZ    SCAN1        ;ERROR IN PREFIX
  747.     ENDIF        ;ACCPTND
  748. SUD1:
  749. ;
  750.     ELSE        ;DIR: BEFORE DU:
  751. ;
  752. ; CHECK FOR DIR: FORM
  753. ;
  754.     IF    ACCPTND    ;PERMIT DIR: FORM
  755.     PUSH    D        ;SAVE PTR TO FCB
  756.     PUSH    H        ;SAVE PTR TO NEXT CHAR
  757.     CALL    DIRSCAN        ;CHECK FOR DIR: FORM
  758.     POP    H        ;GET PTR TO NEXT CHAR
  759.     POP    D        ;GET PTR TO FCB
  760.     JRZ    SUD1        ;GOT IT
  761.     ENDIF        ;ACCPTND
  762. ;
  763. ; CHECK FOR DU: FORM
  764. ;
  765.     IF    ACCPTDU    ;PERMIT DU: FORM
  766.     PUSH    D        ;SAVE PTR TO FCB DN
  767.     PUSH    H        ;SAVE PTR TO NEXT CHAR IN LINE
  768.     CALL    DUSCAN        ;CHECK FOR DU: FORM
  769.     POP    H        ;GET PTR TO NEXT CHAR
  770.     POP    D        ;GET PTR TO FCB
  771.     JRNZ    SCAN1        ;ERROR IN PREFIX
  772.     ENDIF        ;ACCPTDU
  773. SUD1:
  774. ;
  775.     ENDIF        ;DUFIRST
  776. ;
  777.     ELSE        ;DU ONLY
  778. ;
  779. ; CHECK FOR DU: FORM
  780. ;
  781.     IF    ACCPTDU    ;ALLOW DU: FORM
  782.     PUSH    D        ;SAVE PTR TO FCB DN
  783.     PUSH    H        ;SAVE PTR TO NEXT CHAR IN LINE
  784.     CALL    DUSCAN        ;CHECK FOR DU: FORM
  785.     POP    H        ;GET PTR TO NEXT CHAR
  786.     POP    D        ;GET PTR TO FCB
  787.     JRNZ    SCAN1        ;ERROR IN PREFIX
  788.     ENDIF        ;ACCPTDU
  789. ;
  790.     ENDIF        ;(Z3NDIR NE 0) AND NDINCP
  791. ;
  792. ; SET DRIVE REFERENCED
  793. ;
  794.     LDA    TEMPDR        ;SET DRIVE
  795.     STAX    D        ;... IN FCB
  796. ;
  797. ; REINIT FCB PTED TO BY DE
  798. ;
  799.     PUSH    D        ;SAVE PTR
  800.     INX    D        ;PT TO FN FIELD
  801.     CALL    IFCB        ;ONLY PARTIAL INIT (17 BYTES TOTAL)
  802.     POP    D
  803. ;
  804. ; EXTRACT FILENAME FIELD
  805. ;
  806.     XRA    A
  807.     STA    QMCNT        ;ZERO QUESTION MARK COUNTER
  808.     PUSH    D        ;SAVE PTR TO FIRST BYTE OF FCB
  809.     MVI    B,8        ;8 CHARS MAX
  810.     CALL    SCANF        ;STORE FILE NAME
  811.     POP    D        ;GET PTR TO FIRST BYTE OF FCB
  812.     MOV    A,M        ;GET OFFENDING CHAR
  813.     STA    ENDCHAR        ;SET ENDING CHAR
  814. ;
  815. ; SKIP TO FILE TYPE FIELD
  816. ;   HL PTS TO NEXT CHAR, DE PTS TO DN FIELD OF FCB
  817. ;
  818. SCAN1:
  819. ENDCHAR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  820.     MVI    A,0        ;GET ENDING CHAR
  821.     XCHG
  822.     LXI    B,8        ;PT TO BEFORE FILE TYPE FIELD OF FCB
  823.     DAD    B
  824.     XCHG
  825. ;
  826. ; EXTRACT FILETYPE FIELD
  827. ;
  828.     MVI    B,3        ;PREPARE TO EXTRACT FILE TYPE
  829.     CPI    '.'        ;IF '.', WE HAVE A TYPE
  830.     JRNZ    SCAN2
  831.     INX    H        ;PT TO CHAR AFTER '.'
  832.     PUSH    D
  833.     CALL    SCANF        ;GET FCB FILE TYPE
  834.     POP    D
  835. SCAN2:
  836. ;
  837. ; SET USER NUMBER REFERENCED
  838. ;   HL PTS TO NEXT CHAR, DE PTS TO BEFORE FCB FT
  839. ;
  840.     XCHG
  841.     LXI    B,5        ;PT TO S1 FIELD
  842.     DAD    B
  843.     XCHG
  844.     LDA    TEMPUSR        ;STORE USER NUMBER HERE
  845.     STAX    D
  846. ;
  847. ; SKIP TO SPACE, CHAR AFTER =,  OR EOL
  848. ;   HL PTS TO NEXT CHAR IN LINE
  849. ;
  850. SCAN3:
  851.     MOV    A,M        ;GET NEXT CHAR
  852.     CPI    ' '+1        ;DONE IF LESS THAN SPACE
  853.     JRC    SCAN4
  854.     CALL    TSTEOL        ;EOL?
  855.     JRZ    SCAN4
  856.     INX    H        ;PT TO NEXT
  857.     CPI    '='        ;EQUATE?
  858.     JRNZ    SCAN3
  859. SCAN4:
  860. ;
  861. ; SET ZERO FLAG TO INDICATE PRESENCE OF '?' IN DIR:FILENAME.TYP
  862. ;
  863. QMCNT    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  864.     MVI    A,0        ;NUMBER OF QUESTION MARKS
  865.     ORA    A        ;SET ZERO FLAG
  866.     RET
  867. ;
  868. ;  SCANF -- SCAN TOKEN PTED TO BY HL FOR A MAX OF B BYTES; PLACE IT INTO
  869. ;    FILE NAME FIELD PTED TO BY DE; EXPAND AND INTERPRET WILD CARDS OF
  870. ;    '*' AND '?'; ON EXIT, DE PTS TO TERMINATING DELIMITER
  871. ;
  872. SCANF:
  873.     CALL    SDELM        ;DONE IF DELIMITER ENCOUNTERED
  874.     RZ
  875.     INX    D        ;PT TO NEXT BYTE IN FCB
  876.     CPI    '*'        ;IS (DE) A WILD CARD?
  877.     JRNZ    SCANF1        ;CONTINUE IF NOT
  878.     MVI    A,'?'        ;PLACE '?' IN FCB AND DON'T ADVANCE HL IF SO
  879.     STAX    D
  880.     CALL    SCQ        ;SCANNER COUNT QUESTION MARKS
  881.     JR    SCANF2
  882. SCANF1:
  883.     STAX    D        ;STORE FILENAME CHAR IN FCB
  884.     INX    H        ;PT TO NEXT CHAR IN COMMAND LINE
  885.     CPI    '?'        ;CHECK FOR QUESTION MARK (WILD)
  886.     CZ    SCQ        ;SCANNER COUNT QUESTION MARKS
  887. SCANF2:
  888.     DJNZ    SCANF        ;DECREMENT CHAR COUNT UNTIL 8 ELAPSED
  889. SCANF3:
  890.     CALL    SDELM        ;8 CHARS OR MORE - SKIP UNTIL DELIMITER
  891.     RZ            ;ZERO FLAG SET IF DELIMITER FOUND
  892.     INX    H        ;PT TO NEXT CHAR IN COMMAND LINE
  893.     JR    SCANF3
  894. ;
  895. ;  INCREMENT QUESTION MARK COUNT FOR SCANNER
  896. ;    THIS ROUTINE INCREMENTS THE COUNT OF THE NUMBER OF QUESTION MARKS IN
  897. ;    THE CURRENT FCB ENTRY
  898. ;
  899. SCQ:
  900.     PUSH    H        ;SAVE HL
  901.     LXI    H,QMCNT        ;GET COUNT
  902.     INR    M        ;INCREMENT
  903.     POP    H        ;GET HL
  904.     RET
  905. ;
  906. ;  SCAN FOR AND EXTRACT DISK/USER INFO ASSUMING DU: FORM
  907. ;    ON ENTRY, DE PTS TO FIRST BYTE OF FCB CONTAINING POSSIBLE DU FORM
  908. ;    ON EXIT, ZERO FLAG SET MEAN OK AND TEMPDR AND TEMPUSR SET
  909. ;
  910.     IF    ACCPTDU    ;ALLOW DU: FORM
  911. DUSCAN:
  912.     XCHG            ;PTR IN HL
  913.     INX    H        ;PT TO FIRST BYTE OF FN
  914.     MOV    A,M        ;GET FIRST CHAR
  915.     CPI    'A'        ;CONVERT POSSIBLE DRIVE SPEC TO NUMBER
  916.     JRC    DUS1        ;IF LESS THAN 'A', MUST BE DIGIT
  917. ;
  918. ;  SET DISK NUMBER (A=1)
  919. ;
  920.     SUI    'A'-1        ;CONVERT DRIVE NUMBER TO 1-16
  921.     CPI    MAXDISK+1    ;WITHIN RANGE?
  922.     JRNC    DUSE1        ;INVALID DISK NUMBER
  923.     STA    TEMPDR        ;SET TEMPORARY DRIVE NUMBER
  924.     INX    H        ;PT TO NEXT CHAR
  925.     MOV    A,M        ;SEE IF IT IS A SPACE
  926.     CPI    ' '
  927.     RZ
  928.     CALL    DIGCK        ;CHECK FOR DIGIT
  929.     RC
  930. ;
  931. ;  SET USER NUMBER
  932. ;
  933. DUS1:
  934.     PUSH    H        ;SAVE PTR TO DIGITS
  935.     MVI    B,2        ;UP TO 2 DIGITS
  936. DUS1A:
  937.     MOV    A,M        ;CHECK FOR DIGIT OR SPACE
  938.     CPI    ' '        ;IF SPACE, THEN NO DIGIT
  939.     JRZ    DUS2
  940.     CALL    DIGCK        ;CHECK FOR DIGIT
  941.     JRC    DUSE
  942.     INX    H
  943.     DJNZ    DUS1A        ;COUNT DOWN
  944.     MOV    A,M        ;3RD CHAR
  945.     CPI    ' '        ;MUST BE SPACE
  946.     JRNZ    DUSE
  947. DUS2:
  948.     POP    H
  949.     CALL    NUM0A        ;GET NUMBER
  950.     CPI    MAXUSR+1    ;WITHIN LIMIT?
  951.     JRNC    DUSE1
  952.     STA    TEMPUSR        ;SAVE USER NUMBER
  953.     XRA    A        ;SET OK
  954.     RET
  955. DUSE:
  956.     POP    H        ;CLEAR STACK
  957. DUSE1:
  958.     XRA    A
  959.     DCR    A
  960.     RET
  961. ;
  962.     ENDIF        ;ACCPTDU
  963. ;
  964.     IF    (Z3NDIR NE 0) AND NDINCP AND ACCPTND
  965. ;
  966. ;  SCAN FOR DIR FORM
  967. ;    ON ENTRY, DE PTS TO FCB CONTAINING NAME TO CHECK FOR
  968. ;    ON EXIT, IF FOUND, Z AND TEMPUSR AND TEMPDR SET
  969. ;
  970. DIRSCAN:
  971.     XCHG            ;PTR IN HL
  972.     INX    H        ;PT TO FN
  973.     LXI    D,Z3NDIR    ;PT TO FIRST ENTRY IN MEMORY-BASED DIR
  974. DIRS1:
  975.     LDAX    D        ;GET NEXT CHAR
  976.     ORA    A        ;ZERO IF END OF DIR
  977.     JRZ    DIRSERR
  978.     INX    D        ;PT TO DIR NAME
  979.     INX    D
  980.     PUSH    H        ;SAVE PTR TO FILE NAME
  981.     PUSH    D        ;SAVE PTR TO DIR ENTRY
  982.     MVI    B,8        ;MATCH?
  983. DIRS2:
  984.     LDAX    D        ;GET BYTE
  985.     CMP    M        ;COMPARE
  986.     JRNZ    DIRS3
  987.     INX    H        ;PT TO NEXT
  988.     INX    D
  989.     DJNZ    DIRS2        ;COUNT DOWN
  990. DIRS3:
  991.     POP    D        ;RESTORE REGS
  992.     POP    H
  993.     JRZ    DIRS4
  994.     XCHG            ;ADVANCE TO NEXT ENTRY
  995.     LXI    B,16        ;8 BYTES FOR NAME + 8 BYTES FOR PASSWORD
  996.     DAD    B
  997.     XCHG
  998.     JR    DIRS1
  999. ;
  1000. ; NO DIR match
  1001. ;
  1002. DIRSERR:
  1003.     XRA    A        ;RETURN NZ
  1004.     DCR    A
  1005.     RET
  1006. ;
  1007. ; DIR match
  1008. ;
  1009. DIRS4:
  1010. ;
  1011.     IF    PWCHECK
  1012.     PUSH    D        ;SAVE PTR TO DE
  1013.     LXI    B,8        ;PT TO PW
  1014.     XCHG            ;HL PTS TO ENTRY
  1015.     DAD    B
  1016.     CALL    PASSCK        ;CHECK FOR PW
  1017.     POP    D        ;GET PTR
  1018.     JNZ    DIRSERR
  1019.     ENDIF        ;PWCHECK
  1020. ;
  1021.     DCX    D        ;PT TO USER
  1022.     LDAX    D        ;GET USER
  1023.     STA    TEMPUSR
  1024.     DCX    D        ;PT TO DISK
  1025.     LDAX    D        ;GET IT
  1026.     STA    TEMPDR        ;A=1
  1027.     XRA    A        ;SET Z
  1028.     RET
  1029. ;
  1030.     ENDIF        ;(Z3NDIR NE 0) AND NDINCP AND ACCPTND
  1031. ;
  1032.     IF    PWCHECK
  1033. ;
  1034. ; CHECK FOR PASSWORD PTED TO BY HL
  1035. ;   RETURN WITH ZERO FLAG SET IF MATCH
  1036. ;
  1037. PASSCK:
  1038.     MOV    A,M    ;CHECK FOR NO PW
  1039.     CPI    ' '
  1040.     RZ
  1041.     PUSH    H    ;SAVE PTR
  1042.     CALL    PRINT
  1043.     DB    CR,LF,'PW?',' '+80H
  1044.     LXI    D,PWLIN
  1045.     MVI    A,9    ;SET CHAR COUNT
  1046.     STAX    D
  1047.     MVI    C,10    ;BDOS READLN
  1048.     PUSH    D
  1049.     CALL    BDOS
  1050.     POP    H    ;GET PTR TO BUFFER
  1051.     INX    H    ;PT TO CHAR COUNT
  1052.     MOV    A,M    ;GET CHAR COUNT
  1053.     INX    H    ;PT TO FIRST CHAR
  1054.     PUSH    H    ;SAVE PTR
  1055.     CALL    ADDAH    ;HL PTS TO AFTER LAST CHAR
  1056.     MVI    M,' '    ;PLACE SPACE
  1057.     POP    D    ;PT TO USER INPUT
  1058.     POP    H    ;PT TO PASSWORD
  1059.     MVI    B,8    ;8 CHARS MAX
  1060. PWCK:
  1061.     LDAX    D    ;GET NEXT CHAR
  1062.     CALL    UCASE    ;CAPITALIZE USER INPUT
  1063.     CMP    M    ;COMPARE FOR MATCH
  1064.     RNZ        ;NO MATCH
  1065.     CPI    ' '    ;DONE?
  1066.     RZ
  1067.     INX    H    ;PT TO NEXT
  1068.     INX    D
  1069.     DJNZ    PWCK
  1070.     XRA    A    ;SET ZERO FLAG
  1071.     RET
  1072. ;
  1073.     ENDIF        ;PWCHECK
  1074.  
  1075. ;
  1076. ; SKIP OVER SPACES PTED TO BY HL
  1077. ;   ON RETURN, ZERO FLAG SET MEANS WE HIT EOL OR CMDSEP
  1078. ;
  1079. SKSP:
  1080.     MOV    A,M    ;GET NEXT CHAR
  1081.     INX    H    ;PT TO NEXT
  1082.     CPI    ' '    ;SPACE?
  1083.     JRZ    SKSP
  1084.     DCX    H    ;PT TO NON-SPACE
  1085. ;
  1086. ; CHECK TO SEE IF CHAR IN A IS EOL OR CMDSEP
  1087. ;
  1088. TSTEOL:
  1089.     ORA    A    ;EOL?
  1090. ;
  1091.     IF    MULTCMD    ;MULTIPLE COMMANDS SUPPORTED?
  1092.     RZ        ;RETURN WITH FLAG
  1093.     CPI    CMDSEP    ;COMMAND SEPARATOR?
  1094.     ENDIF        ;MULTCMD
  1095. ;
  1096.     RET
  1097.  
  1098. ;
  1099. ; INIT FCB PTED TO BY DE
  1100. ;
  1101. INITFCB:
  1102.     XRA    A
  1103.     STAX    D    ;SET DEFAULT DISK (DN BYTE IS 0)
  1104.     INX    D    ;PT TO FILE NAME FIELD
  1105.     CALL    IFCB    ;FILL 1ST PART OF FCB; FALL THRU TO IFCB TO RUN AGAIN
  1106. ;
  1107. ; FILL FN, FT, EX, S1, S2, RC, AND FOLLOWING CR (OR DN) FIELDS
  1108. ;
  1109. IFCB:
  1110.     MVI    B,11    ;STORE 11 SPACES
  1111.     MVI    A,' '
  1112.     CALL    FILL
  1113.     XRA    A
  1114.     STAX    D    ;SET EX TO ZERO
  1115.     INX    D
  1116.     LDA    CURUSR
  1117.     STAX    D    ;SET S1 TO CURRENT USER
  1118.     INX    D
  1119.     MVI    B,3    ;STORE 3 ZEROES
  1120.     XRA    A    ;FALL THRU TO FILL
  1121. ;
  1122. ; FILL MEMORY POINTED TO BY DE WITH CHAR IN A FOR B BYTES
  1123. ;
  1124. FILL:
  1125.     STAX    D        ;FILL WITH BYTE IN A
  1126.     INX    D        ;PT TO NEXT
  1127.     DJNZ    FILL
  1128.     RET
  1129. ;
  1130. ; No File Error Message
  1131. ;
  1132. PRNNF:
  1133.     CALL    PRINTC        ;NO FILE MESSAGE
  1134.     DB    'No Fil','e'+80H
  1135.     RET
  1136. ;
  1137. ;**** Section 3 ****
  1138. ; I/O UTILITIES
  1139. ;
  1140. ; OUTPUT CHAR IN REG A TO CONSOLE AND DON'T CHANGE BC
  1141. ;
  1142. CONIN:
  1143.     MVI    C,1    ;INPUT CHAR
  1144.     CALL    BDOS    ;GET INPUT CHAR WITH ^S PROCESSING AND ECHO
  1145.     JMP    UCASE    ;CAPITALIZE
  1146. ;
  1147. ; OUTPUT <CRLF>
  1148. ;
  1149. CRLF:
  1150.     MVI    A,CR
  1151.     CALL    CONOUT
  1152.     MVI    A,LF    ;FALL THRU TO CONOUT
  1153. ;
  1154. CONOUT:
  1155.     PUTRG        ;SAVE REGS
  1156.     MVI    C,2
  1157. OUTPUT:
  1158.     MOV    E,A
  1159.     CALL    BDOS
  1160.     GETRG        ;GET REGS
  1161.     RET
  1162. ;
  1163. LCOUT:
  1164.     PUSH    PSW    ;OUTPUT CHAR TO CON: OR LST: DEP ON PRFLG
  1165. PRFLG    EQU    $+1    ;POINTER FOR IN-THE-CODE MODIFICATION
  1166.     MVI    A,0    ;2ND BYTE (IMMEDIATE ARG) IS THE PRINT FLAG
  1167.     ORA    A    ;0=TYPE
  1168.     JRZ    LC1
  1169.     POP    PSW    ;GET CHAR
  1170. ;
  1171. ; OUTPUT CHAR IN REG A TO LIST DEVICE
  1172. ;
  1173. LSTOUT:
  1174.     PUTRG        ;SAVE REGISTERS
  1175.     MVI    C,5
  1176.     JR    OUTPUT
  1177. LC1:
  1178.     POP    PSW    ;GET CHAR
  1179.     PUSH    PSW
  1180.     CALL    CONOUT    ;OUTPUT TO CON:
  1181.     POP    PSW
  1182. ;
  1183.     IF    LTON
  1184.     CPI    LF    ;CHECK FOR PAGING
  1185.     RNZ
  1186. ;
  1187. ; PAGING ROUTINES
  1188. ;   PAGER COUNTS DOWN LINES AND PAUSES FOR INPUT (DIRECT) IF COUNT EXPIRES
  1189. ;   PAGSET SETS LINES/PAGE COUNT
  1190. ;
  1191. PAGER:
  1192.     PUSH    H
  1193.     LXI    H,PAGCNT    ;COUNT DOWN
  1194.     DCR    M
  1195.     JRNZ    PAGER1        ;JUMP IF NOT END OF PAGE
  1196.     MVI    M,NLINES-2    ;REFILL COUNTER
  1197. ;
  1198. PGFLG    EQU    $+1        ;POINTER TO IN-THE-CODE BUFFER PGFLG
  1199.     MVI    A,0        ;0 MAY BE CHANGED BY PGFLG EQUATE
  1200.     CPI    PGDFLG        ;PAGE DEFAULT OVERRIDE OPTION WANTED?
  1201. ;
  1202.     IF    PGDFLT        ;IF PAGING IS DEFAULT
  1203.     JRZ    PAGER1        ;  PGDFLG MEANS NO PAGING
  1204.     ELSE            ;IF PAGING NOT DEFAULT
  1205.     JRNZ    PAGER1        ;  PGDFLG MEANS PLEASE PAGINATE
  1206. ;
  1207.     ENDIF        ;PGDFLG
  1208. ;
  1209.     PUSH    B        ;SAVE REG
  1210.     CALL    BIOS+9        ;BIOS CONSOLE INPUT ROUTINE
  1211.     POP    B        ;GET REG
  1212.     CPI    'C'-'@'     ;^C
  1213.     JZ    RS1        ;RESTART CPR
  1214. PAGER1:
  1215.     POP    H        ;RESTORE HL
  1216.  
  1217.     ENDIF        ;LTON
  1218. ;
  1219.     RET            ;RETURN FOR LC1 IF NOT LTON
  1220. ;
  1221. ; READ FILE BLOCK FUNCTION
  1222. ;
  1223. READF:
  1224.     LXI    D,TFCB    ;FALL THRU TO READ
  1225. READ:
  1226.     MVI    C,14H    ;FALL THRU TO BDOSB
  1227. ;
  1228. ; CALL BDOS AND SAVE BC
  1229. ;
  1230. BDOSB:
  1231.     PUSH    B
  1232.     CALL    BDOS
  1233.     POP    B
  1234.     ORA    A
  1235. ;
  1236. ; THIS RETURN IS FOR BDOSB AND FOR THE NULL FUNCTION CALLED NOTE
  1237. ;
  1238. NOTE:
  1239.     RET
  1240. ;
  1241. ; PRINT STRING (ENDING IN CHAR WITH MSB SET) PTED TO BY RET ADR
  1242. ; START WITH <CRLF>
  1243. ;
  1244. PRINTC:
  1245.     CALL    CRLF        ;NEW LINE
  1246. ;
  1247. PRINT:
  1248.     XTHL            ;GET PTR TO STRING
  1249.     CALL    PRIN1        ;PRINT STRING
  1250.     XTHL            ;RESTORE HL AND RET ADR
  1251.     RET
  1252. ;
  1253. ; PRINT STRING (ENDING IN 0 OR BYTE WITH MSB SET) PTED TO BY HL
  1254. ;
  1255. PRIN1:
  1256.     MOV    A,M        ;GET NEXT BYTE
  1257.     INX    H        ;PT TO NEXT BYTE
  1258.     ORA    A        ;END OF STRING?
  1259.     RZ            ;STRING TERMINATED BY BINARY 0
  1260.     PUSH    PSW        ;SAVE FLAGS
  1261.     ANI    7FH        ;MASK OUT MSB
  1262.     CALL    CONOUT        ;PRINT CHAR
  1263.     POP    PSW        ;GET FLAGS
  1264.     RM            ;STRING TERMINATED BY MSB SET
  1265.     JR    PRIN1
  1266. ;
  1267. ; BDOS FUNCTION ROUTINES
  1268. ;
  1269. ;
  1270. ; RETURN NUMBER OF CURRENT DISK IN A
  1271. ;
  1272. GETDRV:
  1273.     MVI    C,19H
  1274.     JR    BDOSJP
  1275. ;
  1276. ; SET 80H AS DMA ADDRESS
  1277. ;
  1278. DEFDMA:
  1279.     LXI    D,TBUFF     ;80H=TBUFF
  1280. DMASET:
  1281.     MVI    C,1AH
  1282.     JR    BDOSJP
  1283. ;
  1284. RESET:
  1285.     MVI    C,0DH
  1286. BDOSJP:
  1287.     JMP    BDOS
  1288. ;
  1289. LOGIN:
  1290.     MOV    E,A
  1291.     MVI    C,0EH
  1292.     JR    BDOSJP    ;SAVE SOME CODE SPACE
  1293. ;
  1294. OPENF:
  1295.     XRA    A
  1296.     STA    FCBCR
  1297.     LXI    D,FCBDN ;FALL THRU TO OPEN
  1298. ;
  1299. OPEN:
  1300.     MVI    C,0FH    ;FALL THRU TO GRBDOS
  1301. ;
  1302. GRBDOS:
  1303.     CALL    BDOS
  1304.     INR    A    ;SET ZERO FLAG FOR ERROR RETURN
  1305.     RET
  1306. ;
  1307. CLOSE:
  1308.     MVI    C,10H
  1309.     JR    GRBDOS
  1310. ;
  1311. SEARF:
  1312.     LXI    D,TFCB    ;SPECIFY FCB
  1313. SEAR1:
  1314.     MVI    C,11H
  1315.     JR    GRBDOS
  1316. ;
  1317. SEARN:
  1318.     MVI    C,12H
  1319.     JR    GRBDOS
  1320. ;
  1321. ; CHECK FOR SUBMIT FILE IN EXECUTION AND ABORT IT IF SO
  1322. ;
  1323.     IF    SUBON        ;ENABLE ONLY IF SUBMIT FACILITY IS ENABLED
  1324. ;
  1325. SUBKIL:
  1326.     LXI    H,RNGSUB    ;CHECK FOR SUBMIT FILE IN EXECUTION
  1327.     MOV    A,M
  1328.     ORA    A        ;0=NO
  1329.     RZ
  1330.     MVI    M,0        ;ABORT SUBMIT FILE
  1331.     LXI    D,SUBFCB    ;DELETE $$$.SUB
  1332. ;
  1333.     ENDIF        ;SUBON
  1334. ;
  1335. DELETE:
  1336.     MVI    C,13H
  1337.     JR    BDOSJP    ;SAVE MORE SPACE
  1338. ;
  1339. ;  GET/SET USER NUMBER
  1340. ;
  1341. GETUSR:
  1342.     MVI    A,0FFH        ;GET CURRENT USER NUMBER
  1343. SETUSR:
  1344.     MOV    E,A        ;USER NUMBER IN E
  1345.     MVI    C,20H        ;SET USER NUMBER TO VALUE IN E (GET IF E=FFH)
  1346.     JR    BDOSJP        ;MORE SPACE SAVING
  1347. ;
  1348. ; END OF BDOS FUNCTIONS
  1349. ;
  1350. ;
  1351. ;**** Section 4 ****
  1352. ; ZCPR3 UTILITIES
  1353. ;
  1354. ; SET USER/DISK FLAG TO CURRENT USER AND DEFAULT DISK
  1355. ;
  1356. SETUD:
  1357.     CALL    GETUSR        ;GET NUMBER OF CURRENT USER
  1358.     ANI    0FH        ;MASK SURE 4 BITS
  1359.     ADD    A        ;PLACE IT IN HIGH NYBBLE
  1360.     ADD    A
  1361.     ADD    A
  1362.     ADD    A
  1363.     LXI    H,CURDR        ;MASK IN CURRENT DRIVE NUMBER (LOW NYBBLE)
  1364.     ORA    M        ;MASK IN
  1365.     STA    UDFLAG        ;SET USER/DISK NUMBER
  1366.     RET
  1367. ;
  1368. ; CONVERT CHAR IN A TO UPPER CASE
  1369. ;
  1370. UCASE:
  1371.     ANI    7FH        ;MASK OUT MSB
  1372.     CPI    61H        ;LOWER-CASE A
  1373.     RC
  1374.     CPI    7BH        ;GREATER THAN LOWER-CASE Z?
  1375.     RNC
  1376.     ANI    5FH        ;CAPITALIZE
  1377.     RET
  1378. ;
  1379. ; PRINT DU (DIR) PROMPT
  1380. ;
  1381. PROMPT:
  1382. ;
  1383. ; PRINT PROMPT (DU>)
  1384. ;
  1385.     CALL    CRLF        ;PRINT PROMPT
  1386. ;
  1387.     IF    INCLDU        ;IF DRIVE IN PROMPT
  1388.     LDA    CURDR        ;CURRENT DRIVE IS PART OF PROMPT
  1389.     ADI    'A'        ;CONVERT TO ASCII A-P
  1390.     CALL    CONOUT
  1391.     LDA    CURUSR        ;GET USER NUMBER
  1392. ;
  1393.     IF    SUPRES        ;IF SUPPRESSING USR # REPORT FOR USR 0
  1394.     ORA    A
  1395.     JRZ    PRMPT2
  1396.     ENDIF        ;SUPRES
  1397. ;
  1398.     CPI    10        ;USER < 10?
  1399.     JRC    PRMPT1
  1400.     SUI    10        ;SUBTRACT 10 FROM IT
  1401.     PUSH    PSW        ;SAVE IT
  1402.     MVI    A,'1'        ;OUTPUT 10'S DIGIT
  1403.     CALL    CONOUT
  1404.     POP    PSW
  1405. PRMPT1:
  1406.     ADI    '0'        ;OUTPUT 1'S DIGIT (CONVERT TO ASCII)
  1407.     CALL    CONOUT
  1408. PRMPT2:
  1409.     ENDIF        ;INCLDU
  1410. ;
  1411. ; PRINT NDIR ENTRY IF ANY
  1412. ;
  1413.     IF    INCLNDR AND (Z3NDIR NE 0)
  1414. ;
  1415.     LDA    CURDR        ;GET CURRENT DU IN BC
  1416.     INR    A
  1417.     MOV    B,A
  1418.     LDA    CURUSR
  1419.     MOV    C,A
  1420.     LXI    H,Z3NDIR    ;SCAN DIRECTORY FOR MATCH
  1421. ;
  1422. ; MAIN LOOP FOR SCANNING NDR FOR DU IN BC
  1423. ;
  1424. PRMPT3:
  1425.     MOV    A,M        ;END OF NDR?
  1426.     ORA    A
  1427.     RZ
  1428.     INX    H        ;PT TO USER
  1429.     CMP    B        ;COMPARE DISK
  1430.     JRNZ    PRMPT5
  1431.     MOV    A,M        ;COMPARE USER
  1432.     CMP    C
  1433.     JRNZ    PRMPT5
  1434. ;
  1435. ; MATCH OF DU
  1436. ;
  1437.     IF    INCLDU        ;SEPARATE DU AND NDR WITH COLON
  1438.     MVI    A,':'        ;PRINT SEPARATOR
  1439.     CALL    CONOUT
  1440.     ENDIF        ;INCLDU
  1441. ;
  1442.     MVI    B,8        ;8 CHARS MAX
  1443. PRMPT4:
  1444.     INX    H        ;PT TO NEXT CHAR
  1445.     MOV    A,M        ;GET NEXT CHAR
  1446.     CPI    ' '        ;DONE IF SPACE
  1447.     RZ
  1448.     CALL    CONOUT        ;PRINT CHAR
  1449.     DJNZ    PRMPT4        ;COUNT DOWN
  1450.     RET
  1451. ;
  1452. ; ADVANCE TO NEXT DU
  1453. ;
  1454. PRMPT5:
  1455.     LXI    D,16+1        ;SKIP USER (1 BYTE) AND NAME/PW (16 BYTES)
  1456.     DAD    D
  1457.     JR    PRMPT3        ;CONTINUE SCAN
  1458. ;
  1459.     ENDIF        ;INCLNDR AND (Z3NDIR NE 0)
  1460. ;
  1461.     RET
  1462. ;
  1463. ; INPUT NEXT COMMAND TO CPR
  1464. ;    This routine determines if a SUBMIT file is being processed
  1465. ; and extracts the command line from it if so or from the user's console
  1466. ;
  1467. READBUF:
  1468. ;
  1469.     IF    SUBON        ;IF SUBMIT FACILITY IS ENABLED, CHECK FOR IT
  1470. ;
  1471.     LDA    RNGSUB        ;SUBMIT FILE CURRENTLY IN EXECUTION?
  1472.     ORA    A        ;0=NO
  1473.     JRZ    RB1        ;GET LINE FROM CONSOLE IF NOT
  1474.     LXI    D,SUBFCB    ;OPEN $$$.SUB
  1475.     PUSH    D        ;SAVE DE
  1476.     CALL    OPEN
  1477.     POP    D        ;RESTORE DE
  1478.     JRZ    RB1        ;ERASE $$$.SUB IF END OF FILE AND GET CMND
  1479.     LDA    SUBFRC        ;GET VALUE OF LAST RECORD IN FILE
  1480.     DCR    A        ;PT TO NEXT TO LAST RECORD
  1481.     STA    SUBFCR        ;SAVE NEW VALUE OF LAST RECORD IN $$$.SUB
  1482.     CALL    READ        ;DE=SUBFCB
  1483.     JRNZ    RB1        ;ABORT $$$.SUB IF ERROR IN READING LAST REC
  1484.     LXI    D,CHRCNT     ;COPY LAST RECORD (NEXT SUBMIT CMND) TO CHRCNT
  1485.     LXI    H,TBUFF     ;  FROM TBUFF
  1486.     MVI    B,BUFLEN    ;NUMBER OF BYTES
  1487.     CALL    LDIR
  1488.     LXI    H,SUBFS2    ;PT TO S2 OF $$$.SUB FCB
  1489.     MVI    M,0        ;SET S2 TO ZERO
  1490.     INX    H        ;PT TO RECORD COUNT
  1491.     DCR    M        ;DECREMENT RECORD COUNT OF $$$.SUB
  1492.     LXI    D,SUBFCB    ;CLOSE $$$.SUB
  1493.     CALL    CLOSE
  1494.     JRZ    RB1        ;ABORT $$$.SUB IF ERROR
  1495.     CALL    PROMPT        ;PRINT PROMPT
  1496.     MVI    A,SPRMPT    ;PRINT SUBMIT PROMPT TRAILER
  1497.     CALL    CONOUT
  1498.     LXI    H,CMDLIN    ;PRINT COMMAND LINE FROM $$$.SUB
  1499.     CALL    PRIN1
  1500.     CALL    BREAK        ;CHECK FOR ABORT (ANY CHAR)
  1501.     RNZ            ;IF NO ^C, RETURN TO CALLER AND RUN
  1502.     CALL    SUBKIL        ;KILL $$$.SUB IF ABORT
  1503.     JMP    RESTRT        ;RESTART CPR
  1504. ;
  1505. ; INPUT COMMAND LINE FROM USER CONSOLE
  1506. ;
  1507. RB1:
  1508.     CALL    SUBKIL        ;ERASE $$$.SUB IF PRESENT
  1509. ;
  1510.     ENDIF        ;SUBON
  1511. ;
  1512. ;  IF SHELL STACKS ARE IMPLEMENTED, CHECK FOR CONTENT AT THIS TIME
  1513. ;
  1514.     IF    SHSTK NE 0
  1515. ;
  1516.     LXI    H,SHSTK        ;PT TO STACK
  1517.     MOV    A,M        ;CHECK FIRST BYTE
  1518.     CPI    ' '+1        ;SEE IF ANY ENTRY
  1519.     JRC    RB2        ;GET USER INPUT IF NONE
  1520. ;
  1521.     ENDIF        ;SHSTK NE 0
  1522. ;
  1523.     IF    (SHSTK NE 0) OR (Z3MSG NE 0)
  1524. ;
  1525. RUNBUF:
  1526.     LXI    D,CMDLIN    ;PT TO FIRST CHAR OF COMMAND LINE
  1527.     MVI    B,SHSIZE    ;COPY SHELL LINE INTO COMMAND LINE BUFFER
  1528.     CALL    LDIR        ;DO COPY
  1529.     XCHG            ;HL PTS TO END OF LINE
  1530.     MVI    A,1        ;SAY SHELL WAS INVOKED
  1531.     STA    Z3MSG+3        ;Z3 OUTPUT MESSAGE
  1532.     JR    RB3        ;STORE ENDING ZERO AND EXIT
  1533. RB2:
  1534. ;
  1535.     ENDIF        ;(SHSTK NE 0) OR (Z3MSG NE 0)
  1536. ;
  1537.     CALL    PROMPT        ;PRINT PROMPT
  1538.     MVI    A,CPRMPT    ;PRINT PROMPT TRAILER
  1539.     CALL    CONOUT
  1540.     MVI    C,0AH        ;READ COMMAND LINE FROM USER
  1541.     LXI    D,BUFSIZ    ;PT TO BUFFER SIZE BYTE OF COMMAND LINE
  1542.     CALL    BDOS
  1543. ;
  1544. ; STORE ZERO AT END OF COMMAND LINE
  1545. ;
  1546.     LXI    H,CHRCNT    ;PT TO CHAR COUNT
  1547.     MOV    A,M        ;GET CHAR COUNT
  1548.     INX    H        ;PT TO FIRST CHAR OF COMMAND LINE
  1549.     CALL    ADDAH        ;PT TO AFTER LAST CHAR OF COMMAND LINE
  1550. RB3:
  1551.     MVI    M,0        ;STORE ENDING ZERO
  1552.     RET
  1553. ;
  1554. ; CHECK FOR ANY CHAR FROM USER CONSOLE; RET W/ZERO SET IF NONE
  1555. ;
  1556. BREAK:
  1557.     PUTRG            ;SAVE REGISTERS
  1558.     CALL    BIOS+6        ;CONSOLE STATUS CHECK
  1559.     ORA    A        ;SET FLAGS
  1560.     CNZ    BIOS+9        ;GET INPUT CHAR WITH ^S PROCESSING
  1561.     CPI    'S'-'@'        ;PAUSE IF ^S
  1562.     CZ    BIOS+9        ;GET NEXT CHAR
  1563.     GETRG            ;RESTORE REGISTERS
  1564.     CPI    'C'-'@'        ;CHECK FOR ABORT
  1565.     RET
  1566.  
  1567. ;
  1568. ; CHECK TO SEE IF HL PTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET
  1569. ;
  1570. SDELM:
  1571.     MOV    A,M        ;GET NEXT CHAR FROM LINE
  1572.     CPI    ' '+1        ;DELIM IF <= <SP>
  1573.     JRC    ZERO
  1574.     CPI    '='        ;'='=DELIMITER
  1575.     RZ
  1576.     CPI    5FH        ;UNDERSCORE=DELIMITER
  1577.     RZ
  1578.     CPI    '.'        ;'.'=DELIMITER
  1579.     RZ
  1580.     CPI    ':'        ;':'=DELIMITER
  1581.     RZ
  1582.     CPI    ','        ;','=DELIMITER
  1583.     RZ
  1584. ;
  1585.     IF    CMDSEP NE ';'
  1586.     CPI    ';'        ;';'=DELIMITER
  1587.     RZ
  1588.     ENDIF
  1589. ;
  1590.     CPI    '<'        ;'<'=DELIMITER
  1591.     RZ
  1592.     CPI    '>'        ;'>'=DELIMITER
  1593.     RZ
  1594.     JMP    TSTEOL        ;CHECK FOR EOL
  1595. ZERO:
  1596.     XRA    A    ;SET ZERO FLAG
  1597.     RET
  1598. ;
  1599. ; ADD A TO HL (HL=HL+A)
  1600. ;
  1601. ADDAH:
  1602.     ADD    L
  1603.     MOV    L,A
  1604.     RNC
  1605.     INR    H
  1606.     RET
  1607. ;
  1608. ; COPY FROM HL TO DE FOR B BYTES
  1609. ;
  1610. LDIR:
  1611.     MOV    A,M    ;GET BYTE
  1612.     STAX    D    ;PUT BYTE
  1613.     INX    H    ;PT TO NEXT
  1614.     INX    D
  1615.     DJNZ    LDIR
  1616.     RET
  1617. ;
  1618. ; EXTRACT DECIMAL NUMBER FROM COMMAND LINE
  1619. ;   RETURN WITH VALUE IN REG A; ALL REGISTERS MAY BE AFFECTED
  1620. ;
  1621. NUMBER:
  1622.     LXI    H,TFCB+8     ;PT TO END OF TOKEN FOR CONVERSION
  1623.     MVI    B,8        ;8 CHARS MAX
  1624. ;
  1625. ; CHECK FOR SUFFIX FOR HEXADECIMAL NUMBER
  1626. ;
  1627. NUMS:
  1628.     MOV    A,M        ;GET CHARS FROM END, SEARCHING FOR SUFFIX
  1629.     DCX    H        ;BACK UP
  1630.     CPI    ' '        ;SPACE?
  1631.     JRNZ    NUMS1        ;CHECK FOR SUFFIX
  1632.     DJNZ    NUMS        ;COUNT DOWN
  1633.     JR    NUM0        ;BY DEFAULT, PROCESS
  1634. NUMS1:
  1635.     CPI    NUMBASE        ;CHECK AGAINST BASE SWITCH FLAG
  1636.     JRZ    HEXNUM
  1637. ;
  1638. ; PROCESS DECIMAL NUMBER
  1639. ;
  1640. NUM0:
  1641.     LXI    H,TFCB+1    ;PT TO BEGINNING OF TOKEN
  1642. NUM0A:
  1643.     LXI    B,1100H        ;C=ACCUMULATED VALUE, B=CHAR COUNT
  1644.                 ; (C=0, B=11)
  1645. NUM1:
  1646.     MOV    A,M        ;GET CHAR
  1647.     CALL    SDELM        ;DONE IF DELIMITER
  1648.     JRZ    NUM2
  1649.     INX    H        ;PT TO NEXT CHAR
  1650.     CALL    DIGCK        ;CHECK FOR DIGIT IN A
  1651.     JRC    NUMERR
  1652.     MOV    D,A        ;DIGIT IN D
  1653.     MOV    A,C        ;NEW VALUE = OLD VALUE * 10
  1654.     RLC            ;*2
  1655.     JRC    NUMERR
  1656.     RLC            ;*4
  1657.     JRC    NUMERR
  1658.     ADD    C        ;*5
  1659.     JRC    NUMERR
  1660.     RLC            ;*10
  1661.     JRC    NUMERR
  1662.     ADD    D        ;NEW VALUE = OLD VALUE * 10 + DIGIT
  1663.     JRC    NUMERR        ;CHECK FOR RANGE ERROR
  1664.     MOV    C,A        ;SET NEW VALUE
  1665.     DJNZ    NUM1        ;COUNT DOWN
  1666. ;
  1667. ; RETURN FROM NUMBER
  1668. ;
  1669. NUM2:
  1670.     MOV    A,C        ;GET ACCUMULATED VALUE
  1671.     RET
  1672. ;
  1673. ; NUMBER ERROR ROUTINE FOR SPACE CONSERVATION
  1674. ;
  1675. NUMERR:
  1676.     JMP    ERROR        ;USE ERROR ROUTINE - THIS IS RELATIVE PT
  1677. ;
  1678. ; CHECK TO SEE IF A IS A DIGIT
  1679. ;   IF SO, RETURN ITS VALUE
  1680. ;   IF NOT, RETURN WITH CARRY SET
  1681. ;
  1682. DIGCK:
  1683.     SUI    '0'        ;DIGIT?
  1684.     RC            ;ERROR
  1685.     CPI    10        ;RANGE?
  1686.     JRNC    DIGCK1
  1687.     CMC            ;FLIP CARRY
  1688.     RET
  1689. DIGCK1:
  1690.     STC            ;SET CARRY
  1691.     RET
  1692. ;
  1693. ; EXTRACT HEXADECIMAL NUMBER FROM COMMAND LINE
  1694. ;   RETURN WITH VALUE IN REG A; ALL REGISTERS MAY BE AFFECTED
  1695. ;
  1696. HEXNUM:
  1697.     LXI    H,TFCB+1    ;PT TO TOKEN FOR CONVERSION
  1698.     LXI    D,0        ;DE=ACCUMULATED VALUE
  1699.     MVI    B,11        ;B=CHAR COUNT
  1700. HNUM1:
  1701.     MOV    A,M        ;GET CHAR
  1702.     CPI    ' '        ;DONE?
  1703.     JRZ    HNUM3        ;RETURN IF SO
  1704.     CPI    NUMBASE        ;DONE IF NUMBASE SUFFIX
  1705.     JRZ    HNUM3
  1706.     SUI    '0'        ;CONVERT TO BINARY
  1707.     JRC    NUMERR        ;RETURN AND DONE IF ERROR
  1708.     CPI    10        ;0-9?
  1709.     JRC    HNUM2
  1710.     SUI    7        ;A-F?
  1711.     CPI    10H        ;ERROR?
  1712.     JRNC    NUMERR
  1713. HNUM2:
  1714.     INX    H        ;PT TO NEXT CHAR
  1715.     MOV    C,A        ;DIGIT IN C
  1716.     MOV    A,D        ;GET ACCUMULATED VALUE
  1717.     RLC            ;EXCHANGE NYBBLES
  1718.     RLC
  1719.     RLC
  1720.     RLC
  1721.     ANI    0F0H        ;MASK OUT LOW NYBBLE
  1722.     MOV    D,A
  1723.     MOV    A,E        ;SWITCH LOW-ORDER NYBBLES
  1724.     RLC
  1725.     RLC
  1726.     RLC
  1727.     RLC
  1728.     MOV    E,A        ;HIGH NYBBLE OF E=NEW HIGH OF E,
  1729.                 ;  LOW NYBBLE OF E=NEW LOW OF D
  1730.     ANI    0FH        ;GET NEW LOW OF D
  1731.     ORA    D        ;MASK IN HIGH OF D
  1732.     MOV    D,A        ;NEW HIGH BYTE IN D
  1733.     MOV    A,E
  1734.     ANI    0F0H        ;MASK OUT LOW OF E
  1735.     ORA    C        ;MASK IN NEW LOW
  1736.     MOV    E,A        ;NEW LOW BYTE IN E
  1737.     DJNZ    HNUM1        ;COUNT DOWN
  1738. ;
  1739. ; RETURN FROM HEXNUM
  1740. ;
  1741. HNUM3:
  1742.     XCHG            ;RETURNED VALUE IN HL
  1743.     MOV    A,L        ;LOW-ORDER BYTE IN A
  1744.     RET
  1745. ;
  1746. ; LOG INTO DU CONTAINED IN FCB PTED TO BY DE
  1747. ;
  1748. FCBLOG:
  1749.     PUSH    D        ;SAVE PTR TO FCB
  1750.     XCHG
  1751.     MOV    A,M        ;GET DRIVE
  1752.     STA    TEMPDR        ;SET TEMP DRIVE
  1753.     LXI    B,13        ;PT TO S1 FIELD
  1754.     DAD    B
  1755.     MOV    A,M        ;GET USER
  1756.     STA    TEMPUSR        ;SET TEMP USER
  1757.     CALL    SLOGIN        ;LOG IN
  1758.     POP    D        ;GET PTR TO FCB
  1759.     RET
  1760. ;
  1761. ; CHECK FOR SPECIFIED DRIVE AND LOG IT IN
  1762. ;
  1763. SLOGIN:
  1764. TEMPDR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1765.     MVI    A,0        ;2ND BYTE (IMMEDIATE ARG) IS TEMPDR
  1766.     ORA    A        ;0=CURRENT DRIVE
  1767.     JRNZ    SLOG1
  1768.     LDA    CURDR        ;LOG IN CURRENT DRIVE
  1769.     INR    A        ;ADD 1 FOR NEXT DCR
  1770. SLOG1:
  1771.     DCR    A        ;ADJUST FOR PROPER DISK NUMBER (A=0)
  1772.     CALL    LOGIN        ;LOG IN NEW DRIVE
  1773. TEMPUSR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1774.     MVI    A,0        ;2ND BYTE IS USER TO BE SELECTED
  1775.     JMP    SETUSR        ;LOG IN NEW USER
  1776. ;
  1777. ;  ROUTINE TO CHECK FOR A WHEEL BYTE AS NON-ZERO
  1778. ;    IF WHEEL BYTE IS ZERO, THEN ABORT (POP STACK AND RETURN)
  1779. ;
  1780. ;
  1781.     IF    WHEEL        ;WHEEL FACILITY?
  1782. WHLCHK:
  1783.     LDA    Z3WHL        ;GET WHEEL BYTE
  1784.     ORA    A        ;ZERO?
  1785.     RNZ            ;OK IF NOT
  1786.     JMP    ERROR        ;PROCESS AS ERROR
  1787.     ENDIF        ;WHEEL
  1788. ;
  1789.  
  1790. ;
  1791. ; CMDTBL (COMMAND TABLE) SCANNER
  1792. ;   ON RETURN, HL CONTAINS ADDRESS OF COMMAND IF CPR-RESIDENT
  1793. ;   ON RETURN, ZERO FLAG SET MEANS CPR-RESIDENT COMMAND
  1794. ;
  1795. CMDSER:
  1796.     LXI    H,CMDTBL    ;PT TO COMMAND TABLE
  1797. ;
  1798. ; ENTRY POINT TO PERMIT RCP TABLE TO BE SCANNED
  1799. ;
  1800. CMDSCAN:
  1801.     MOV    B,M        ;GET SIZE OF COMMAND TEXT
  1802.     INX    H        ;PT TO FIRST COMMAND
  1803. CMS1:
  1804.     MOV    A,M        ;CHECK FOR END OF TABLE
  1805.     ORA    A
  1806.     JRZ    CMS5
  1807.     LXI    D,FCBFN     ;PT TO STORED COMMAND NAME
  1808.     PUSH    B        ;SAVE SIZE OF COMMAND TEXT
  1809. CMS2:
  1810.     LDAX    D        ;COMPARE AGAINST TABLE ENTRY
  1811.     CMP    M
  1812.     JRNZ    CMS3        ;NO MATCH
  1813.     INX    D        ;PT TO NEXT CHAR
  1814.     INX    H
  1815.     DJNZ    CMS2        ;COUNT DOWN
  1816.     LDAX    D        ;NEXT CHAR IN INPUT COMMAND MUST BE <SP>
  1817.     CPI    ' '
  1818.     JRNZ    CMS4
  1819.     POP    B        ;CLEAR STACK
  1820.     MOV    A,M        ;GET ADDRESS FROM TABLE INTO HL
  1821.     INX    H
  1822.     MOV    H,M
  1823.     MOV    L,A        ;HL CONTAINS ADDRESS
  1824.     XRA    A        ;ZERO FLAG SET FOR COMMAND FOUND
  1825.     RET            ;COMMAND IS RESIDENT (ZERO FLAG SET)
  1826. CMS3:
  1827.     INX    H        ;SKIP TO NEXT COMMAND TABLE ENTRY
  1828.     DJNZ    CMS3
  1829. CMS4:
  1830.     POP    B        ;GET SIZE OF COMMAND TEXT
  1831.     INX    H        ;SKIP ADDRESS
  1832.     INX    H
  1833.     JR    CMS1
  1834. CMS5:
  1835.     XRA    A        ;SET NZ
  1836.     DCR    A        ;COMMAND NOT FOUND IF NZ
  1837.     RET
  1838.  
  1839. ;
  1840. ;**** Section 5 ****
  1841. ; CPR-Resident Commands
  1842. ;
  1843. ;
  1844. ;Section 5A
  1845. ;Command: DIR
  1846. ;Function:  To display a directory of the files on disk
  1847. ;Forms:
  1848. ;    DIR <afn>    Displays the DIR files
  1849. ;    DIR <afn> S    Displays the SYS files
  1850. ;    DIR <afn> A    Display both DIR and SYS files
  1851. ;Notes:
  1852. ;    The flag SYSFLG defines the letter used to display both DIR and
  1853. ;        SYS files (A in the above Forms section)
  1854. ;    The flag SOFLG defines the letter used to display only the SYS
  1855. ;        files (S in the above Forms section)
  1856. ;    The flag WIDE determines if the file names are spaced further
  1857. ;        apart (WIDE=TRUE) for 80-col screens
  1858. ;    The flag FENCE defines the character used to separate the file
  1859. ;        names
  1860. ;
  1861.     IF    DIRON        ;DIR ENABLED
  1862. ;
  1863. DIR:
  1864.     LXI    D,TFCB        ;PT TO TARGET FCB
  1865.     PUSH    D        ;SAVE PTR
  1866.     INX    D        ;PT TO FILE NAME
  1867.     LDAX    D        ;GET FIRST CHAR
  1868.     CPI    ' '        ;IF <SP>, MAKE ALL WILD
  1869.     JRNZ    DIR1
  1870.     MVI    B,11        ;11 BYTES
  1871.     MVI    A,'?'        ;WILD
  1872.     CALL    FILL
  1873. DIR1:
  1874.     POP    D        ;GET PTR TO FCB
  1875.     LXI    D,TFCB        ;PT TO TARGET FCB
  1876.     CALL    FCBLOG        ;LOG IN TEMP DISK/USER
  1877.     LDA    TFCB2+1        ;LOOK AT NEXT INPUT CHAR
  1878.     MVI    B,80H        ;PREPARE FOR DIR-ONLY SELECTION
  1879.     CPI    ' '
  1880.     JRZ    DIRPR        ;THERE IS NO FLAG, SO DIR ONLY
  1881.     MVI    B,1        ;SET FOR BOTH DIR AND SYS FILES
  1882.     CPI    SYSFLG        ;SYSTEM AND DIR FLAG SPECIFIER?
  1883.     JRZ    DIRPR        ;GOT SYSTEM SPECIFIER
  1884.     CPI    SOFLG        ;SYS ONLY?
  1885.     JRNZ    DIRPR
  1886.     DCR    B        ;B=0 FOR SYS FILES ONLY
  1887.                 ;DROP INTO DIRPR TO PRINT DIRECTORY
  1888.                 ; THEN RESTART CPR
  1889. ;
  1890.     ENDIF            ;DIRON
  1891. ;
  1892. ; DIRECTORY PRINT ROUTINE; ON ENTRY, B REG IS SET AS FOLLOWS:
  1893. ;    0 FOR ONLY SYSTEM FILES, 80H FOR ONLY DIR FILES, 1 FOR BOTH
  1894. ;
  1895.     IF    DIRON OR ERAON
  1896. ;
  1897. DIRPR:
  1898.     MOV    A,B        ;GET FLAG
  1899.     STA    SYSTST        ;SET SYSTEM TEST FLAG
  1900.     MVI    E,0        ;SET COLUMN COUNTER TO ZERO
  1901.     PUSH    D        ;SAVE COLUMN COUNTER (E)
  1902.     CALL    SEARF        ;SEARCH FOR SPECIFIED FILE (FIRST OCCURRENCE)
  1903.     JRNZ    DIR3
  1904.     CALL    PRNNF        ;PRINT NO FILE MSG; REG A NOT CHANGED
  1905.     XRA    A        ;SET ZERO FLAG IN CASE CALLED BY ERA
  1906.     POP    D        ;RESTORE DE
  1907.     RET
  1908. ;
  1909. ; ENTRY SELECTION LOOP; ON ENTRY, A=OFFSET FROM SEARF OR SEARN
  1910. ;
  1911. DIR3:
  1912.     CALL    GETSBIT        ;GET AND TEST FOR TYPE OF FILES
  1913.     JRZ    DIR6
  1914.     POP    D        ;GET ENTRY COUNT (=<CR> COUNTER)
  1915.     MOV    A,E        ;GET ENTRY COUNTER
  1916.     INR    E        ;INCREMENT ENTRY COUNTER
  1917.     PUSH    D        ;SAVE IT
  1918.     ANI    03H        ;OUTPUT <CRLF> IF 4 ENTRIES PRINTED IN LINE
  1919.     JRNZ    DIR4
  1920.     CALL    CRLF        ;NEW LINE
  1921.     JR    DIR5
  1922. DIR4:
  1923.     CALL    PRINT
  1924. ;
  1925.     IF    WIDE
  1926. ;
  1927.     DB    '  '        ;2 SPACES
  1928.     DB    FENCE        ;THEN FENCE CHAR
  1929.     DB    ' ',' '+80H    ;THEN 2 MORE SPACES
  1930. ;
  1931.     ELSE
  1932. ;
  1933.     DB    ' '        ;SPACE
  1934.     DB    FENCE        ;THEN FENCE CHAR
  1935.     DB    ' '+80H        ;THEN SPACE
  1936. ;
  1937.     ENDIF            ;WIDE
  1938. ;
  1939. DIR5:
  1940. ;    MVI    B,01H        ;PT TO 1ST BYTE OF FILE NAME
  1941. ;    MOV    A,B        ;A=OFFSET
  1942.     MVI    A,1        ;PT TO 1ST BYTE OF FILE NAME
  1943.     CALL    DIRPTR        ;HL NOW PTS TO 1ST BYTE OF FILE NAME
  1944.     CALL    PRFN        ;PRINT FILE NAME
  1945. DIR6:
  1946.     CALL    BREAK        ;CHECK FOR ABORT
  1947.     JRZ    DIR7
  1948.     CALL    SEARN        ;SEARCH FOR NEXT FILE
  1949.     JRNZ    DIR3        ;CONTINUE IF FILE FOUND
  1950. DIR7:
  1951.     POP    D        ;RESTORE STACK
  1952.     MVI    A,0FFH        ;SET NZ FLAG
  1953.     ORA    A
  1954.     RET
  1955. ;
  1956.     ENDIF            ;DIRON OR ERAON
  1957. ;
  1958. ;  PRINT FILE NAME PTED TO BY HL
  1959. ;
  1960. PRFN:
  1961.     MVI    B,8    ;8 CHARS
  1962.     CALL    PRFN1
  1963.     MVI    A,'.'    ;DOT
  1964.     CALL    CONOUT
  1965.     MVI    B,3    ;3 CHARS
  1966. PRFN1:
  1967.     MOV    A,M    ; GET CHAR
  1968.     INX    H    ; PT TO NEXT
  1969.     CALL    CONOUT    ; PRINT CHAR
  1970.     DCR    B    ; COUNT DOWN
  1971.     JRNZ    PRFN1
  1972.     RET
  1973. ;
  1974. ; PT TO DIRECTORY ENTRY IN TBUFF WHOSE OFFSET IS SPECIFIED BY A AND C
  1975. ;
  1976. DIRPTR:
  1977.     LXI    H,TBUFF     ;PT TO TEMP BUFFER
  1978.     ADD    C        ;PT TO 1ST BYTE OF DIR ENTRY
  1979.     CALL    ADDAH        ;PT TO DESIRED BYTE IN DIR ENTRY
  1980.     MOV    A,M        ;GET DESIRED BYTE
  1981.     RET
  1982. ;
  1983. ; AFTER A SEARCH, RETURN NZ SET IF DESIRED TYPE OF FILE FOUND, Z IF NOT
  1984. ;   THIS ALGORITHM LOOKS AT THE SYSTEM BIT OF THE LOCATED FILE; THIS
  1985. ;   BIT IS SET TO 1 IF THE FILE IS A SYSTEM FILE AND 0 IF NOT A SYSTEM
  1986. ;   FILE.  THE FOLLOWING EXCLUSIVE OR MASKS ARE APPLIED TO RETURN Z OR NZ
  1987. ;   AS REQUIRED BY THE CALLING PROGRAM:
  1988. ;
  1989. ;    SYSTEM BYTE: X 0 0 0  0 0 0 0   (AFTER 80H MASK, X=1 IF SYS, 0 IF DIR)
  1990. ;
  1991. ;    SYS-ONLY   : 0 0 0 0  0 0 0 0   (XOR 0 = 0 if X=0, = 80H if X=1)
  1992. ;    DIR-ONLY   : 1 0 0 0  0 0 0 0   (XOR 80H = 80h if X=0, = 0 if X=1)
  1993. ;    BOTH       : 0 0 0 0  0 0 0 1   (XOR 1 = 81H or 1H, NZ in both cases)
  1994. ;
  1995. GETSBIT:
  1996.     DCR    A        ;ADJUST TO RETURNED VALUE
  1997.     RRC            ;CONVERT NUMBER TO OFFSET INTO TBUFF
  1998.     RRC
  1999.     RRC
  2000.     ANI    60H
  2001.     MOV    C,A        ;OFFSET INTO TBUFF IN C (C=OFFSET TO ENTRY)
  2002.     MVI    A,10        ;ADD 10 TO PT TO SYSTEM FILE ATTRIBUTE BIT
  2003.     CALL    DIRPTR        ;A=SYSTEM BYTE
  2004.     ANI    80H        ;LOOK AT ONLY SYSTEM BIT
  2005. SYSTST    EQU    $+1        ;IN-THE-CODE VARIABLE
  2006.     XRI    0        ; IF SYSTST=0, SYS ONLY; IF SYSTST=80H, DIR
  2007.                 ; ONLY; IF SYSTST=1, BOTH SYS AND DIR
  2008.     RET            ;NZ IF OK, Z IF NOT OK
  2009. ;
  2010. ;Section 5B
  2011. ;Command: ERA
  2012. ;Function:  Erase files
  2013. ;Forms:
  2014. ;    ERA <afn>    Erase Specified files and print their names
  2015. ;    ERA <afn> V    Erase Specified files and print their names, but ask
  2016. ;                for verification before Erase is done
  2017. ;Notes:
  2018. ;    Several Key Flags affect this command:
  2019. ;        ERAV - If TRUE, the V option is enabled, and the character
  2020. ;            which turns it on (the V) is defined by ERDFLG
  2021. ;        ERAOK - If TRUE, the OK? prompt is enabled
  2022. ;    If ERAOK is FALSE, the verification feature is disabled regardless
  2023. ;        of what value ERAV has
  2024. ;    If ERAOK is TRUE, then:
  2025. ;        If ERAV is TRUE, verification is requested only if the V
  2026. ;            flag (actual letter defined by ERDFLG) is in the
  2027. ;            command line
  2028. ;        If ERAV is FALSE, verification is always requested, and a
  2029. ;            V flag in the command line will cause an error
  2030. ;            message to be printed (V?) after the ERA is completed
  2031. ;
  2032.     IF    ERAON        ;ERA ENABLED?
  2033. ;
  2034. ERA:
  2035. ;
  2036.     IF    WERA        ;WHEEL FACILITY ENABLED?
  2037.     CALL    WHLCHK        ;CHECK FOR IT
  2038.     ENDIF        ;WERA
  2039. ;
  2040.     IF    ERAV AND ERAOK    ;V FLAG AND OK? ENABLED?
  2041.     LDA    TFCB2+1        ;GET ERAFLG IF IT'S THERE
  2042.     STA    ERAFLG        ;SAVE IT AS A FLAG
  2043.     ENDIF            ;ERAV
  2044. ;
  2045.     LXI    D,TFCB        ;PT TO TARGET FCB
  2046.     CALL    FCBLOG        ;LOG INTO DU IN FCB
  2047.     MVI    B,1        ;DISPLAY ALL MATCHING FILES
  2048.     CALL    DIRPR        ;PRINT DIRECTORY OF ERASED FILES
  2049.     RZ            ;ABORT IF NO FILES
  2050. ;
  2051.     IF    ERAOK        ;PRINT PROMPT
  2052. ;
  2053.     IF    ERAV        ;TEST VERIFY FLAG
  2054. ;
  2055. ERAFLG    EQU    $+1        ;ADDRESS OF FLAG
  2056.     MVI    A,0        ;2ND BYTE IS FLAG
  2057.     CPI    ERDFLG        ;IS IT A VERIFY OPTION?
  2058.     JRNZ    ERA2        ;SKIP PROMPT IF IT IS NOT
  2059. ;
  2060.     ENDIF            ;ERAV
  2061. ;
  2062.     CALL    PRINTC
  2063.     DB    'OK to Erase','?'+80H
  2064.     CALL    CONIN        ;GET REPLY
  2065.     CPI    'Y'        ;YES?
  2066.     RNZ            ;ABORT IF NOT
  2067. ;
  2068.     ENDIF            ;ERAOK
  2069. ;
  2070. ERA2:
  2071.     LXI    D,TFCB         ;DELETE FILE SPECIFIED
  2072.     JMP    DELETE        ;DELETE FILE AND REENTER CCP
  2073. ;
  2074.     ENDIF            ;ERAON
  2075. ;
  2076. ;Section 5C
  2077. ;Command: LIST
  2078. ;Function:  Print out specified file on the LST: Device
  2079. ;Forms:
  2080. ;    LIST <ufn>    Print file (NO Paging)
  2081. ;Notes:
  2082. ;    The flags which apply to TYPE do not take effect with LIST
  2083. ;
  2084.     IF    LTON        ;LIST AND TYPE ENABLED?
  2085. ;
  2086. LIST:
  2087.     MVI    A,0FFH        ;TURN ON PRINTER FLAG
  2088.     JR    TYPE0
  2089. ;
  2090. ;Section 5D
  2091. ;Command: TYPE
  2092. ;Function:  Print out specified file on the CON: Device
  2093. ;Forms:
  2094. ;    TYPE <ufn>    Print file
  2095. ;    TYPE <ufn> P    Print file with paging flag    
  2096. ;Notes:
  2097. ;    The flag PGDFLG defines the letter which toggles the paging
  2098. ;        facility (P in the forms section above)
  2099. ;    The flag PGDFLT determines if TYPE is to page by default
  2100. ;        (PGDFLT=TRUE if TYPE pages by default); combined with
  2101. ;        PGDFLG, the following events occur --
  2102. ;            If PGDFLT = TRUE, PGDFLG turns OFF paging
  2103. ;            If PGDFLT = FALSE, PGDFLG turns ON paging
  2104. ;
  2105. TYPE:
  2106.     XRA    A        ;TURN OFF PRINTER FLAG
  2107. ;
  2108. ; ENTRY POINT FOR CPR LIST FUNCTION (LIST)
  2109. ;
  2110. TYPE0:
  2111.     STA    PRFLG        ;SET FLAG
  2112. ;
  2113.     IF    WLT    ;WHEEL ON?
  2114.     CALL    WHLCHK        ;CHECK WHEEL BYTE
  2115.     ENDIF        ;WLT
  2116. ;
  2117.     LDA    TFCB2+1        ;GET PGDFLG IF IT'S THERE
  2118.     STA    PGFLG        ;SAVE IT AS A FLAG
  2119.     LXI    D,TFCB        ;PT TO TARGET FILE FCB
  2120.     CALL    AMBCHK        ;CHECK FOR QUESTION MARKS IN TFCB
  2121.     RZ            ;ERROR IF ANY QUESTION MARKS
  2122.     CALL    FCBLOG        ;LOG INTO DU IN FCB
  2123.     LXI    D,TFCB        ;PT TO SELECT FILE
  2124.     CALL    OPEN        ;OPEN SELECTED FILE
  2125.     JZ    PRNNF        ;ABORT IF ERROR
  2126.     CALL    CRLF        ;NEW LINE
  2127.     MVI    A,NLINES-1    ;SET LINE COUNT
  2128.     STA    PAGCNT
  2129.     LXI    B,080H        ;SET CHAR POSITION AND TAB COUNT
  2130.                 ;  (B=0=TAB, C=080H=CHAR POSITION)
  2131. ;
  2132. ;  MAIN LOOP FOR LOADING NEXT BLOCK
  2133. ;
  2134. TYPE2:
  2135.     MOV    A,C        ;GET CHAR COUNT
  2136.     CPI    80H
  2137.     JRC    TYPE3
  2138.     PUSH    H        ;READ NEXT BLOCK
  2139.     PUSH    B
  2140.     CALL    READF
  2141.     POP    B
  2142.     POP    H
  2143.     RNZ            ;ERROR?
  2144.     MVI    C,0        ;SET CHAR COUNT
  2145.     LXI    H,TBUFF        ;PT TO FIRST CHAR
  2146. ;
  2147. ;  MAIN LOOP FOR PRINTING CHARS IN TBUFF
  2148. ;
  2149. TYPE3:
  2150.     MOV    A,M        ;GET NEXT CHAR
  2151.     ANI    7FH        ;MASK OUT MSB
  2152.     CPI    1AH        ;END OF FILE (^Z)?
  2153.     RZ            ;RESTART CPR IF SO
  2154. ;
  2155. ; OUTPUT CHAR TO CON: OR LST: DEVICE WITH TABULATION
  2156. ;
  2157.     CPI    CR        ;RESET TAB COUNT?
  2158.     JRZ    TYPE4
  2159.     CPI    LF        ;RESET TAB COUNT?
  2160.     JRZ    TYPE4
  2161.     CPI    TAB        ;TAB?
  2162.     JRZ    TYPE5
  2163. ;
  2164. ;  OUTPUT CHAR AND INCREMENT CHAR COUNT
  2165. ;
  2166.     CALL    LCOUT        ;OUTPUT CHAR
  2167.     INR    B        ;INCREMENT TAB COUNT
  2168.     JR    TYPE6
  2169. ;
  2170. ;  OUTPUT <CR> OR <LF> AND RESET TAB COUNT
  2171. ;
  2172. TYPE4:
  2173.     CALL    LCOUT        ;OUTPUT <CR> OR <LF>
  2174.     MVI    B,0        ;RESET TAB COUNTER
  2175.     JR    TYPE6
  2176. ;
  2177. ;  TABULATE
  2178. ;
  2179. TYPE5:
  2180.     MVI    A,' '        ;<SP>
  2181.     CALL    LCOUT
  2182.     INR    B        ;INCR POS COUNT
  2183.     MOV    A,B
  2184.     ANI    7
  2185.     JRNZ    TYPE5
  2186. ;
  2187. ; CONTINUE PROCESSING
  2188. ;
  2189. TYPE6:
  2190.     INR    C        ;INCREMENT CHAR COUNT
  2191.     INX    H        ;PT TO NEXT CHAR
  2192.     CALL    BREAK        ;CHECK FOR ABORT
  2193.     RZ            ;RESTART IF SO
  2194.     JR    TYPE2
  2195. ;
  2196.     ENDIF            ;LTON
  2197. ;
  2198. ;Section 5E
  2199. ;Command: SAVE
  2200. ;Function:  To save the contents of the TPA onto disk as a file
  2201. ;Forms:
  2202. ;    SAVE <Number of Pages> <ufn>
  2203. ;                Save specified number of pages (start at 100H)
  2204. ;                from TPA into specified file; <Number of
  2205. ;                Pages> is in DEC
  2206. ;    SAVE <Number of Sectors> <ufn> S
  2207. ;                Like SAVE above, but numeric argument specifies
  2208. ;                number of sectors rather than pages
  2209. ;Notes:
  2210. ;    The MULTCMD flag (Multiple Commands Allowed) expands the code slightly,
  2211. ;        but is required to support multiple commands with SAVE
  2212. ;    The SECTFLG defines the letter which indicates a sector count
  2213. ;        (S in the Forms section above)
  2214. ;
  2215.     IF    SAVEON        ;SAVE ENABLED?
  2216. ;
  2217. SAVE:
  2218. ;
  2219.     IF    WSAVE    ;WHEEL FACILITY?
  2220.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  2221.     ENDIF        ;WSAVE
  2222. ;
  2223.     CALL    NUMBER        ;EXTRACT NUMBER FROM COMMAND LINE
  2224.     MOV    L,A        ;HL=PAGE COUNT
  2225.     MVI    H,0
  2226.     PUSH    H        ;SAVE PAGE COUNT
  2227.     LXI    H,TFCB2        ;COPY 2ND FCB INTO POSITION OF FIRST
  2228.     LXI    D,TFCB
  2229.     PUSH    D        ;SAVE PTR TO FCB
  2230.     MVI    B,14        ;14 BYTES
  2231.     CALL    LDIR
  2232.     POP    D        ;GET PTR TO FCB
  2233.     CALL    AMBCHK        ;CHECK FOR AMBIGUOUS
  2234.     POP    H
  2235.     RZ            ;ABORT IF SO
  2236.     PUSH    H
  2237.     CALL    EXTEST        ;TEST FOR EXISTENCE OF FILE AND ABORT IF SO
  2238.     MVI    C,16H        ;BDOS MAKE FILE
  2239.     CALL    GRBDOS
  2240.     POP    H        ;GET PAGE COUNT
  2241.     JRZ    SAVE3        ;ERROR?
  2242.     LXI    D,TPA-128    ;PT TO START OF SAVE AREA (TPA)
  2243.     DAD    H        ;DOUBLE 256-BYTE BLOCK COUNT FOR SECTOR COUNT
  2244.     XCHG            ;DE IS COUNT, HL IS NEXT BLOCK - 128 BYTES
  2245. SAVE1:
  2246.     MOV    A,D        ;DONE WITH SAVE?
  2247.     ORA    E        ;DE=0 IF SO
  2248.     JRZ    SAVE2
  2249.     DCX    D        ;COUNT DOWN ON SECTORS
  2250.     PUSH    D        ;SAVE PTR TO BLOCK TO SAVE
  2251.     LXI    D,128        ;128 BYTES PER SECTOR
  2252.     DAD    D        ;PT TO NEXT SECTOR
  2253.     PUSH    H        ;SAVE ON STACK
  2254.     XCHG            ;DE IS ADDRESS
  2255.     CALL    DMASET        ;SET DMA ADDRESS FOR WRITE (ADDRESS IN DE)
  2256.     LXI    D,TFCB        ;WRITE SECTOR
  2257.     MVI    C,15H        ;BDOS WRITE SECTOR
  2258.     CALL    BDOSB        ;SAVE BC
  2259.     POP    H        ;GET PTR TO NEXT SECTOR IN HL
  2260.     POP    D        ;GET SECTOR COUNT IN DE
  2261.     JRNZ    SAVE3        ;WRITE ERROR?
  2262.     JR    SAVE1        ;CONTINUE
  2263. SAVE2:
  2264.     LXI    D,TFCB        ;CLOSE SAVED FILE
  2265.     CALL    CLOSE
  2266.     INR    A        ;ERROR?
  2267.     JRNZ    SAVE4
  2268. SAVE3:
  2269.     CALL    PRNLE        ;PRINT 'NO SPACE' ERROR
  2270. SAVE4:
  2271.     JMP    DEFDMA        ;SET DMA TO 0080 AND RESTART CPR
  2272. ;
  2273.     ENDIF            ;SAVEON
  2274. ;
  2275.     IF    LTON OR SAVEON OR RENON    ;FOR LIST/TYPE, SAVE, AND REN FCTS
  2276. ;
  2277. ; TEST FCB PTED TO BY DE TO SEE IF ANY ? CHARS IN IT
  2278. ;   RETURN WITH Z IF SO, NZ IF NOT; DON'T AFFECT DE
  2279. ;
  2280. AMBCHK:
  2281.     PUSH    D
  2282.     INX    D        ;PT TO FIRST CHAR
  2283.     MVI    B,11        ;11 CHARS
  2284. AMB1:
  2285.     LDAX    D        ;GET CHAR
  2286.     CPI    '?'        ;ERROR?
  2287.     JRZ    AMB2
  2288.     INX    D        ;PT TO NEXT
  2289.     DJNZ    AMB1
  2290.     DCR    B        ;SET NZ
  2291.     POP    D        ;RESTORE PTR
  2292.     RET
  2293. AMB2:
  2294.     CALL    PRINT
  2295.     DB    CR,LF,'AFN Erro','r'+80H
  2296.     XRA    A        ;SET ZERO FLAG
  2297.     POP    D        ;RESTORE PTR
  2298.     RET
  2299. ;
  2300.     ENDIF        ;LTON OR SAVEON
  2301. ;
  2302. ; Test File in FCB for existence, ask user to delete if so, and abort if he
  2303. ;  choses not to
  2304. ;
  2305.     IF    SAVEON OR RENON    ;FOR SAVE AND REN FUNCTIONS
  2306. ;
  2307. EXTEST:
  2308.     LXI    D,TFCB        ;PT TO FCB
  2309.     PUSH    D        ;SAVE PTR
  2310.     CALL    FCBLOG        ;LOG INTO DU
  2311.     CALL    SEARF        ;LOOK FOR SPECIFIED FILE
  2312.     POP    D        ;GET PTR TO FCB
  2313.     RZ            ;OK IF NOT FOUND
  2314.     PUSH    D        ;SAVE PTR TO FCB
  2315.     CALL    PRINTC
  2316.     DB    'Erase',' '+80H
  2317.     LXI    H,TFCB+1    ;PT TO FILE NAME FIELD
  2318.     CALL    PRFN        ;PRINT IT
  2319.     MVI    A,'?'        ;PRINT QUESTION
  2320.     CALL    CONOUT
  2321.     CALL    CONIN        ;GET RESPONSE
  2322.     POP    D        ;GET PTR TO FCB
  2323.     CPI    'Y'        ;KEY ON YES
  2324.     JNZ    ERR3        ;RESTART AS ERROR IF NO
  2325.     PUSH    D        ;SAVE PTR TO FCB
  2326.     CALL    DELETE        ;DELETE FILE
  2327.     POP    D        ;GET PTR TO FCB
  2328.     RET
  2329. ;
  2330.     ENDIF            ;SAVEON OR RENON
  2331. ;
  2332. ;Section 5F
  2333. ;Command: REN
  2334. ;Function:  To change the name of an existing file
  2335. ;Forms:
  2336. ;    REN <New ufn>=<Old ufn>    Perform function
  2337. ;
  2338.     IF    RENON        ;REN ENABLED?
  2339. ;
  2340. REN:
  2341. ;
  2342.     IF    WREN        ;WHEEL FACILITY?
  2343.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  2344.     ENDIF        ;WREN
  2345. ;
  2346.     LXI    D,TFCB        ;CHECK FOR AMBIGUITY IN FIRST FILE NAME
  2347.     CALL    AMBCHK
  2348.     RZ
  2349.     LXI    D,TFCB2        ;CHECK FOR AMBIGUITY IN SECOND FILE NAME
  2350.     CALL    AMBCHK
  2351.     RZ
  2352.     CALL    EXTEST        ;TEST FOR FILE EXISTENCE AND RETURN
  2353.                 ; IF FILE DOESN'T EXIST; ABORT IF IT DOES
  2354.     MVI    B,16        ;EXCHANGE NEW AND OLD FILE NAMES
  2355.     LXI    H,TFCB        ;PT TO NEW
  2356.     LXI    D,TFCB2        ;PT TO OLD
  2357. REN0:
  2358.     LDAX    D        ;GET OLD
  2359.     MOV    C,A
  2360.     MOV    A,M        ;GET NEW
  2361.     STAX    D        ;PUT NEW
  2362.     MOV    M,C        ;PUT OLD
  2363.     INX    H        ;ADVANCE
  2364.     INX    D
  2365.     DJNZ    REN0
  2366. ;
  2367. ;  PERFORM RENAME FUNCTION
  2368. ;
  2369.     LXI    D,TFCB        ;RENAME FILE
  2370.     XRA    A
  2371.     STAX    D        ;SET CURRENT DISK
  2372.     MVI    C,17H        ;BDOS RENAME FCT
  2373.     CALL    GRBDOS
  2374.     RNZ
  2375.     JMP    PRNNF        ;PRINT NO FILE MSG
  2376. ;
  2377.     ENDIF            ;RENON
  2378. ;
  2379. ;Section 5G
  2380. ;Command: JUMP
  2381. ;Function:  To Call the program (subroutine) at the specified address
  2382. ;         without loading from disk
  2383. ;Forms:
  2384. ;    JUMP <adr>        Call at <adr>;<adr> is in HEX
  2385. ;
  2386.     IF    JUMPON        ;JUMP ENABLED?
  2387. ;
  2388. JUMP:
  2389.  
  2390. ;
  2391.     IF    WJUMP    ;WHEEL FACILITY?
  2392.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  2393.     ENDIF        ;WJUMP
  2394. ;
  2395.     CALL    HEXNUM        ;GET LOAD ADDRESS IN HL
  2396.     JR    CALLPROG    ;PERFORM CALL
  2397. ;
  2398.     ENDIF            ;JUMPON
  2399. ;
  2400. ;Section 5H
  2401. ;Command: GO
  2402. ;Function:  To Call the program in the TPA without loading
  2403. ;         loading from disk. Same as JUMP 100H, but much
  2404. ;         more convenient, especially when used with
  2405. ;         parameters for programs like STAT. Also can be
  2406. ;         allowed on remote-access systems with no problems.
  2407. ;
  2408. ;Form:
  2409. ;    GO <parameters like for COMMAND>
  2410. ;
  2411.     IF    GOON        ;GO ENABLED?
  2412. ;
  2413. GO:
  2414.  
  2415. ;
  2416.     IF    WGO    ;WHEEL FACILITY?
  2417.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  2418.     ENDIF        ;WGO
  2419. ;
  2420.     LXI    H,TPA        ;Always to TPA
  2421.     JR    CALLPROG    ;Perform call
  2422. ;
  2423.     ENDIF            ;GOON
  2424. ;
  2425. ;Section 5I
  2426. ;Command: COM file processing
  2427. ;Function:  To load the specified COM file from disk and execute it
  2428. ;Forms:  <command line>
  2429. ;Notes:
  2430. ;    COM files are processed as follows --
  2431. ;        1. File name buffers are initialized and a preliminary
  2432. ;            error check is done
  2433. ;        2. MLOAD is used to search for the file along the Path
  2434. ;            and load it into the TPA
  2435. ;        3. CALLPROG is used to set up the buffers to be used by
  2436. ;            the transient (FCB at 5CH, FCB at 6CH, BUFF at 80H)
  2437. ;            and run the program
  2438. ;    The flag MULTCMD comes into play frequently here; it mainly serves
  2439. ;        to save space if MULTCMD is FALSE and enables Multiple
  2440. ;        Commands on the same line if MULTCMD is TRUE
  2441. ;
  2442. COMDIR:
  2443.     IF    DRVPREFIX
  2444. ;
  2445.     LDA    FCBFN        ;ANY COMMAND?
  2446.     CPI    ' '        ;' ' MEANS COMMAND WAS 'DIR:' TO SWITCH
  2447.     JRNZ    COM        ;NOT <SP>, SO MUST BE TRANSIENT OR ERROR
  2448. ;
  2449. ;  ENTRY POINT TO SELECT USER/DISK VIA DIR: PREFIX
  2450. ;
  2451.     IF    WDU    ;WHEEL FACILITY?
  2452.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  2453.     ENDIF        ;WDU
  2454. ;
  2455.     LDA    FCBDN+13    ;GET SELECTED USER
  2456.     CPI    16        ;OUT OF RANGE?
  2457.     JNC    ERROR
  2458.     LXI    D,FCBDN        ;PT TO FCB
  2459.     CALL    FCBLOG        ;LOG INTO DU
  2460.     LDA    TEMPUSR        ;GET TEMPORARY USER
  2461.     STA    CURUSR        ;SET CURRENT USER (MAKE PERMANENT)
  2462.     LDA    TEMPDR        ;GET SELECTED DISK
  2463.     ORA    A        ;IF 0 (DEFAULT), NO CHANGE
  2464.     JRZ    COMDR
  2465.     DCR    A        ;ADJUST FOR LOGIN
  2466.     STA    CURDR        ;SET CURRENT DRIVE
  2467. COMDR:
  2468.     CALL    SETUD        ;SET UD BYTE
  2469.     JMP    RS1        ;RESUME COMMAND LINE PROCESSING
  2470. ;
  2471.     ENDIF        ;DRVPREFIX
  2472. ;
  2473. ;  PROCESS COMMAND
  2474. ;
  2475. COM:
  2476. ;
  2477.     IF    CMDRUN        ;COMMAND RUN FACILITY AVAILABLE?
  2478.     MVI    A,0FFH        ;USE IT IF AVAILABLE (MLOAD INPUT)
  2479.     ENDIF        ;CMDRUN
  2480. ;
  2481.  
  2482. ;
  2483. ; SET EXECUTION AND LOAD ADDRESS
  2484. ;
  2485.     LXI    H,TPA        ;TRANSIENT PROGRAM AREA
  2486.     PUSH    H        ;SAVE TPA ADDRESS FOR EXECUTION
  2487.     CALL    MLOAD        ;LOAD MEMORY WITH FILE SPECIFIED IN CMD LINE
  2488.     POP    H        ;GET EXECUTION ADDRESS; FALL THRU TO CALLPROG
  2489. ;
  2490. ; CALLPROG IS THE ENTRY POINT FOR THE EXECUTION OF THE LOADED
  2491. ;   PROGRAM; ON ENTRY TO THIS ROUTINE, HL MUST CONTAIN THE EXECUTION
  2492. ;   ADDRESS OF THE PROGRAM (SUBROUTINE) TO EXECUTE
  2493. ;
  2494. CALLPROG:
  2495.     CALL    CRLF        ;LEADING NEW LINE
  2496. CALLP:
  2497.     SHLD    EXECADR        ;PERFORM IN-LINE CODE MODIFICATION
  2498. ;
  2499. ; COPY COMMAND TAIL INTO TBUFF
  2500. ;
  2501. TAILSV    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  2502.     LXI    H,0        ;ADDRESS OF FIRST CHAR OF COMMAND TAIL
  2503.     LXI    D,TBUFF        ;PT TO TBUFF
  2504.     PUSH    D        ;SAVE PTR
  2505.     MVI    B,0        ;SET COUNTER
  2506.     INX    D        ;PT TO FIRST CHAR
  2507. TAIL:
  2508.     MOV    A,M        ;GET CHAR
  2509.     CALL    TSTEOL        ;CHECK FOR EOL
  2510.     JRZ    TAIL1
  2511.     STAX    D        ;PUT CHAR
  2512.     INX    H        ;PT TO NEXT
  2513.     INX    D
  2514.     INR    B        ;INCREMENT COUNT
  2515.     JR    TAIL
  2516. TAIL1:
  2517.     XRA    A        ;STORE ENDING ZERO
  2518.     STAX    D
  2519.     POP    H        ;GET PTR
  2520.     MOV    M,B        ;SAVE COUNT
  2521. ;
  2522. ; RUN LOADED TRANSIENT PROGRAM
  2523. ;
  2524.     CALL    DEFDMA        ;SET DMA TO 0080
  2525. ;
  2526. ; EXECUTION (CALL) OF PROGRAM (SUBROUTINE) OCCURS HERE
  2527. ;
  2528. EXECADR    EQU    $+1        ;CHANGE ADDRESS FOR IN-LINE CODE MODIFICATION
  2529.     CALL    TPA        ;CALL TRANSIENT
  2530. ;
  2531. ; RETURN FROM EXECUTION
  2532. ;
  2533.     CALL    DEFDMA        ;SET DMA TO 0080, IN CASE PROG CHANGED IT
  2534.     JMP    RS1        ;RESTART CPR AND CONTINUE COMMAND PROCESSING
  2535. ;
  2536. ;Section 5J
  2537. ;Command: GET
  2538. ;Function:  To load the specified file from disk to the specified address
  2539. ;Forms:
  2540. ;    GET <adr> <ufn>    Load the specified file at the specified page;
  2541. ;            <adr> is in HEX
  2542. ;
  2543.     IF    GETON        ;GET ENABLED?
  2544. ;
  2545. GET:
  2546. ;
  2547.     IF    WGET    ;WHEEL ON?
  2548.     CALL    WHLCHK        ;CHECK WHEEL BYTE
  2549.     ENDIF        ;WGET
  2550. ;
  2551.     LXI    H,TFCB2        ;COPY TFCB2 TO FCBDN FOR LOAD
  2552.     LXI    D,FCBDN
  2553.     MVI    B,14        ;14 BYTES (INCLUDES DU)
  2554.     CALL    LDIR
  2555.     CALL    HEXNUM        ;GET LOAD ADDRESS IN HL
  2556. ;
  2557. ; FALL THRU TO MLOAD
  2558. ;
  2559.     IF    CMDRUN        ;COMMAND RUN FACILITY AVAILABLE?
  2560.     XRA    A        ;NO CMDRUN IF FACILITY IS THERE (MLOAD INPUT)
  2561.     ENDIF        ;CMDRUN
  2562. ;
  2563.     ENDIF        ;GETON
  2564.  
  2565. ;
  2566. ;  MEMORY LOAD SUBROUTINE
  2567. ;
  2568. ; LOAD MEMORY WITH THE FILE WHOSE NAME IS SPECIFIED IN THE COMMAND LINE
  2569. ;   ON INPUT, HL CONTAINS STARTING ADDRESS TO LOAD
  2570. ;
  2571. ;    EXIT POINTS ARE A RETURN AND LOG IN CURRENT USER/DISK IF NO ERROR,
  2572. ; A JMP TO ERROR IF COM FILE NOT FOUND OR A MESSAGE AND ABORT IF MEMORY FULL
  2573. ;
  2574. MLOAD:
  2575. ;
  2576.     IF    CMDRUN    ;CMDRUN FACILITY?
  2577.     STA    CRFLAG    ;SAVE FLAG
  2578.     ENDIF        ;CMDRUN
  2579. ;
  2580.     SHLD    LOADADR        ;SET LOAD ADDRESS
  2581.     XCHG            ;LOAD ADDRESS IN DE
  2582.     CALL    DMASET        ;SET DMA ADDRESS
  2583. ;
  2584. ;   MLA is a reentry point for a non-standard CP/M Modification
  2585. ; The PATH command-search is implemented by this routine
  2586. ;
  2587. MLA:
  2588. ;
  2589. ;  Set attributes of COM files which match search
  2590. ;
  2591.     MVI    A,COMATT    ;CUSTOMIZER-SPECIFIED ATTRIBUTES
  2592.     STA    SYSTST        ;SET FLAG
  2593.  
  2594. ;
  2595. ; Analyze current path, generating a minimal, optimal absolute
  2596. ;   path equivalent in the buffer MPATH
  2597. ;
  2598.     IF    MINPATH        ;IF MINIMUM PATH SEARCH EMPLOYED
  2599.     XRA    A
  2600.     STA    MPATH        ;SET EMPTY PATH
  2601. ;
  2602.     IF    DRVPREFIX    ;PAY ATTENTION TO DU:COM PREFIX?
  2603. ;
  2604. ; Convert DU in FCBDN into absolute expression in MPATH
  2605. ;
  2606.     LXI    D,MPATH        ;BUILD MPATH BUFFER
  2607.     LXI    H,FCBDN        ;HL PTS TO FCB, DE PTS TO MPATH
  2608.     MOV    A,M        ;GET DRIVE
  2609.     ORA    A        ;SELECT CURRENT
  2610.     JRNZ    MLAMPD
  2611.     LDA    CURDR        ;SET CURRENT DRIVE
  2612.     INR    A        ;ADJUST FOR PATH
  2613. MLAMPD:
  2614.     STAX    D        ;SET DRIVE
  2615.     INX    D        ;PT TO USER
  2616.     LXI    B,13        ;PT TO USER
  2617.     DAD    B
  2618.     MOV    A,M        ;GET USER
  2619.     STAX    D        ;SAVE USER
  2620.     INX    D        ;PT TO NEXT
  2621.     XRA    A        ;A=0
  2622.     STAX    D        ;STORE ENDING 0 IN MPATH
  2623.     ENDIF        ;DRVPREFIX
  2624. ;
  2625.     IF    SCANCUR        ;SCAN CURRENT DU AT ALL TIMES?
  2626.     LDA    CURDR        ;GET CURRENT DRIVE
  2627.     INR    A        ;ADD 1 FOR A=1
  2628.     MOV    B,A
  2629.     LDA    CURUSR        ;GET CURRENT USER
  2630.     MOV    C,A        ;BC=DU
  2631.     LXI    H,PATH        ;PT TO FIRST PATH ELEMENT
  2632.     JR    MPATHBC        ;PLACE ENTRY INTO MPATH
  2633.     ENDIF        ;SCANCUR
  2634. ;
  2635. ; Convert symbolic path at PATH into absolute path at MPATH
  2636. ;
  2637.     LXI    H,PATH        ;PT TO SYMBOLIC PATH
  2638. MPATH1:
  2639.     MOV    A,M        ;CHECK FOR END OF SYMBOLIC PATH
  2640.     ORA    A        ;0=END OF PATH
  2641.     JRZ    MPATH7
  2642. ;
  2643. ; Place absolute form for current path element in BC
  2644. ;
  2645.     ANI    7FH        ;MASK OUT SYSTEM BIT
  2646.     CPI    CURIND        ;CHECK FOR CURRENT DRIVE
  2647.     JRNZ    MPATH2
  2648.     LDA    CURDR        ;GET CURRENT DRIVE
  2649.     INR    A        ;ADJUST FOR A=1
  2650. MPATH2:
  2651.     MOV    B,A        ;DRIVE IN B (1=A)
  2652.     INX    H        ;PT TO USER
  2653.     MOV    A,M        ;GET USER
  2654.     INX    H        ;PT TO NEXT ELEMENT
  2655.     ANI    7FH        ;MASK OUT SYSTEM BIT
  2656.     CPI    CURIND        ;CHECK FOR CURRENT USER
  2657.     JRNZ    MPATH3
  2658.     LDA    CURUSR        ;GET CURRENT USER
  2659. MPATH3:
  2660.     MOV    C,A        ;SET USER IN C
  2661. ;
  2662. ; Scan MPATH for DU element in BC
  2663. ;
  2664. MPATHBC:
  2665.     PUSH    H        ;SAVE PTR TO NEXT PATH ELEMENT
  2666.     LXI    H,MPATH        ;PT TO MINIMUM PATH
  2667. MPATH4:
  2668.     MOV    A,M        ;CHECK FOR END OF PATH
  2669.     ORA    A
  2670.     JRZ    MPATH6
  2671.     INX    H        ;PT TO USER
  2672.     CMP    B        ;CHECK FOR DISK MATCH
  2673.     JRNZ    MPATH5
  2674.     MOV    A,M        ;GET USER
  2675.     CMP    C        ;CHECK FOR USER MATCH
  2676.     JRNZ    MPATH5
  2677.     POP    H        ;MATCH, SO BC IS DUPLICATE
  2678.     JR    MPATH1        ;CONTINUE
  2679. MPATH5:
  2680.     INX    H        ;PT TO NEXT ELEMENT
  2681.     JR    MPATH4
  2682. ;
  2683. ; No match, so BC is a unique DU and store it in path
  2684. ;
  2685. MPATH6:
  2686.     MOV    M,B        ;STORE DRIVE
  2687.     INX    H
  2688.     MOV    M,C        ;STORE USER
  2689.     INX    H
  2690.     MVI    M,0        ;STORE ENDING 0
  2691.     POP    H        ;PT TO NEXT ENTRY
  2692.     JR    MPATH1        ;CONTINUE
  2693. ;
  2694. ; MPATH now contains the minimal path
  2695. ;
  2696. MPATH7:
  2697. ;
  2698.     ENDIF        ;MINPATH
  2699. ;
  2700. ; Non-MINPATH Processing:
  2701. ;    If DRVPREFIX or SCANCUR are TRUE, look in DU in FCBDN
  2702. ;
  2703.     IF    (NOT MINPATH) AND (DRVPREFIX OR SCANCUR)
  2704.     LXI    D,FCBDN        ;LOOK FOR FILE
  2705.     CALL    FCBLOG        ;LOG INTO FCB
  2706.     CALL    SEAR1
  2707.     JNZ    MLA4
  2708.     ENDIF        ;(NOT MINPATH) AND (DRVPREFIX OR SCANCUR)
  2709. ;
  2710. ; Select current disk at all times
  2711. ;
  2712.     XRA    A
  2713.     STA    FCBDN        ;SET CURRENT DISK
  2714. MLARUN:
  2715. ;
  2716. ; The following selects the path to be followed; if the Minimal Path is
  2717. ;   available, it is followed; else, the Symbolic Path is followed
  2718. ;
  2719.     IF    MINPATH        ;IF MINIMAL PATH USED
  2720.     LXI    H,MPATH        ;PT TO MINIMAL PATH
  2721.  
  2722.     ELSE        ;NOT MINPATH
  2723.     LXI    H,PATH        ;PT TO SYMBOLIC PATH
  2724.  
  2725.     ENDIF        ;MINPATH
  2726. ;
  2727. ; This is the main path search loop; HL pts to the next path element
  2728. ;
  2729. MLA0:
  2730.     MOV    A,M        ;GET DRIVE
  2731.     ORA    A        ;0=DONE=COMMAND NOT FOUND
  2732. ;
  2733.     IF    NOT CMDRUN    ;ERROR ABORT IF NO COMMAND RUN FACILITY
  2734.     JZ    ERROR        ;PATH EXHAUSTED
  2735. ;
  2736.     ELSE            ;CONTINUE PROCESSING FOR COMMAND RUN
  2737. ;
  2738. ; CMDRUN Facility
  2739. ;
  2740.     JRNZ    NOCRUN        ;NOT READY FOR CMD RUN YET
  2741. CRFLAG    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  2742.     MVI    A,0        ;CHECK CRFLAG
  2743.     ORA    A        ;0=NO
  2744.     JZ    ERROR        ;PROCESS AS ERROR IF CMD RUN EXHAUSTED
  2745. ;
  2746.     IF    ROOTONLY    ;ONLY LOOK FOR EXT COMMAND PROCESSOR AT ROOT
  2747.     PUSH    H        ;SAVE PTR TO PATH END
  2748.     ENDIF        ;ROOTONLY
  2749. ;
  2750.     XRA    A        ;DO NOT REENTER THIS CODE
  2751.     STA    CRFLAG        ;SET ZERO FOR NO ENTRY
  2752.     LXI    H,CFCB        ;SET CFCB AS COMMAND
  2753.     LXI    D,FCBDN        ;... BY COPYING IT INTO FCBDN
  2754.     MVI    B,12        ;ONLY 12 BYTES REQUIRED
  2755.     CALL    LDIR
  2756.     LHLD    CURCMD        ;GET PTR TO CURRENT COMMAND LINE
  2757.     CALL    PARSET        ;PARSE AS COMMAND TAIL
  2758. ;
  2759.     IF    ROOTONLY    ;LOOK FOR EXT COMMAND PROCESSOR AT ROOT ONLY?
  2760.     JR    MLA3RT        ;PROCESS FROM PATH END
  2761.     ELSE            ;FOLLOW PATH LOOKING FOR EXT COMMAND PROCESSOR
  2762. ;
  2763.     JR    MLARUN        ;NOW TRY THE RUN FROM THE PATH
  2764. ;
  2765.     ENDIF        ;ROOTONLY
  2766. ;
  2767. CFCB:
  2768.     CMDFCB            ;FCB DEFINING INITIAL COMMAND
  2769. NOCRUN:
  2770.     ENDIF        ;CMDRUN
  2771. ;
  2772. ; LOOK FOR COMMAND IN DIRECTORY PTED TO BY HL; DRIVE IN A
  2773. ;
  2774.     IF    NOT MINPATH
  2775.     CPI    CURIND        ;CURRENT DRIVE SPECIFIED?
  2776.     JRNZ    MLA1        ;SKIP DEFAULT DRIVE SELECTION IF SO
  2777.     LDA    CURDR        ;GET CURRENT DRIVE
  2778.     INR    A        ;SET A=1
  2779.     ENDIF        ;NOT MINPATH
  2780. ;
  2781. MLA1:
  2782.     STA    TEMPDR        ;SELECT DIFFERENT DRIVE IF NOT CURRENT
  2783.     INX    H        ;PT TO USER NUMBER
  2784.     MOV    A,M        ;GET USER NUMBER
  2785.     INX    H        ;PT TO NEXT ENTRY IN PATH
  2786.     PUSH    H        ;SAVE PTR
  2787. ;
  2788.     IF    NOT MINPATH
  2789.     ANI    7FH        ;MASK OUT SYSTEM BIT
  2790.     CPI    CURIND        ;CURRENT USER SPECIFIED?
  2791.     JRNZ    MLA2        ;DO NOT SELECT CURRENT USER IF SO
  2792.     LDA    CURUSR        ;GET CURRENT USER NUMBER
  2793. MLA2:
  2794.     ENDIF        ;NOT MINPATH
  2795. ;
  2796.     STA    TEMPUSR        ;SET TEMPORARY USER NUMBER
  2797.     CMA            ;FLIP BITS SO SYSTEM BIT IS 0 IF SYS-ONLY
  2798.     ANI    80H        ;MASK FOR ONLY NOT OF SYSTEM BIT TO SHOW
  2799.     JRNZ    MLA3        ;DON'T SET FLAG IF ORIGINALLY SYSTEM BIT=0
  2800.     STA    SYSTST        ;TEST FLAG IS 0 FOR SYS-ONLY, 1 FOR BOTH
  2801. MLA3:
  2802.     CALL    SLOGIN        ;LOG IN PATH-SPECIFIED USER/DISK
  2803. MLA3RT:
  2804.     LXI    D,FCBDN        ;PT TO FCB
  2805.     CALL    SEAR1        ;LOOK FOR FILE
  2806.     POP    H        ;GET PTR TO NEXT PATH ENTRY
  2807.     JRZ    MLA0        ;CONTINUE PATH SEARCH IF SEARCH FAILED
  2808.                 ;LOAD IF SEARCH SUCCEEDED
  2809. ;
  2810. ; FILE FOUND -- PERFORM SYSTEM TEST AND PROCEED IF APPROVED
  2811. ;
  2812. MLA4:
  2813.     PUSH    H        ;SAVE PTR
  2814.     CALL    GETSBIT        ;CHECK SYSTEM BIT
  2815.     POP    H        ;GET PTR
  2816.     JRZ    MLA0        ;CONTINUE IF NO MATCH
  2817.     CALL    OPENF        ;OPEN FILE FOR INPUT
  2818. LOADADR    EQU    $+1        ;MEMORY LOAD ADDRESS (IN-LINE CODE MOD)
  2819.     LXI    H,TPA        ;SET START ADDRESS OF MEMORY LOAD
  2820. MLA5:
  2821.     MVI    A,ENTRY/256-1    ;GET HIGH-ORDER ADR OF JUST BELOW CPR
  2822.     CMP    H        ;ARE WE GOING TO OVERWRITE THE CPR?
  2823.     JRC    PRNLE        ;ERROR IF SO
  2824.     PUSH    H        ;SAVE ADDRESS OF NEXT SECTOR
  2825.     XCHG            ;... IN DE
  2826.     CALL    DMASET        ;SET DMA ADDRESS FOR LOAD
  2827.     LXI    D,FCBDN        ;READ NEXT SECTOR
  2828.     CALL    READ
  2829.     POP    H        ;GET ADDRESS OF NEXT SECTOR
  2830.     JRNZ    MLA6        ;READ ERROR OR EOF?
  2831.     LXI    D,128        ;MOVE 128 BYTES PER SECTOR
  2832.     DAD    D        ;PT TO NEXT SECTOR IN HL
  2833.     JR    MLA5
  2834. ;
  2835. MLA6:
  2836.     DCR    A        ;LOAD COMPLETE
  2837.     JRNZ    PRNLE        ;MEMORY FULL IF NZ
  2838. ;
  2839. ; RETURN TO CURRENT DIRECTORY
  2840. ;
  2841. DLOGIN:
  2842. CURDR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  2843.     MVI    A,0        ;PREP TO LOG IN CURRENT DRIVE
  2844.     CALL    LOGIN        ;LOGIN CURRENT DRIVE
  2845. CURUSR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  2846.     MVI    A,0        ;PREP TO LOG IN CURRENT USER NUMBER
  2847.     JMP    SETUSR        ;LOG IN NEW USER
  2848.  
  2849. ;
  2850. ; LOAD ERROR
  2851. ;
  2852. PRNLE:
  2853.     CALL    PRINTC
  2854.     DB    'Ful','l'+80H
  2855.     JMP    RESTRT        ;RESTART ZCPR
  2856.  
  2857. ;*****
  2858.  
  2859. ;
  2860. ;  DEFAULT PATH USED FOR PATH COMMAND-SEARCH
  2861. ;
  2862.     IF    EXPATH EQ 0        ;USE THIS PATH?
  2863. ;
  2864. PATH:
  2865.     IPATH            ;PATH DEFINED IN Z3HDR.LIB
  2866. ;
  2867.     ENDIF        ;INTPATH
  2868. ;
  2869.  
  2870. ;*****
  2871.  
  2872. ;
  2873. ;  INTERNAL MINIMUM PATH
  2874. ;
  2875.     IF    MINPATH
  2876. MPATH:
  2877.     DS    EXPATHS+3    ;SIZE OF PATH, MAX
  2878.                 ;  (+2 FOR DU:COM PREFIX, +1 FOR ENDING 0)
  2879.     ENDIF        ;MINPATH
  2880.  
  2881. ;*****
  2882.     IF    EXTSTK NE 0    ;EXTERNAL STACK
  2883.  
  2884. STACK    EQU    EXTSTK+48    ;SET TOP-OF-STACK ADDRESS
  2885.  
  2886.     ELSE
  2887. ;
  2888. ;  STACK AREA
  2889. ;
  2890.     DS    48        ;STACK AREA
  2891. STACK    EQU    $        ;TOP OF STACK
  2892. ;
  2893.     ENDIF        ;INTSTACK
  2894. ;
  2895.     IF    PWCHECK
  2896. PWLIN    EQU    STACK-48    ;PLACE LINE AT BOTTOM OF STACK
  2897.     ENDIF        ;PWCHECK
  2898. ;
  2899. ;    The following will cause an error message to appear if
  2900. ; the size of ZCPR3 is over 2K bytes.
  2901. ;
  2902.     IF    ($ GT CPRLOC+800H)
  2903. ZCPR3ER    EQU    NOVALUE        ;ZCPR3 IS LARGER THAN 2K BYTES
  2904.     ENDIF
  2905.  
  2906.     END
  2907.