home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol098 / zcpr2.asm < prev    next >
Assembly Source File  |  1984-04-29  |  55KB  |  2,380 lines

  1.  
  2. *************************************************************************
  3. *                                    *
  4. *  Z C P R 2 -- Z80-Based Command Processor Replacement, Version 2.0    *
  5. *                                    *
  6. *  Copyright (c) 1982 by Richard Conn                    *
  7. *  All Rights Reserved                            *
  8. *                                    *
  9. *  ZCPR2 is Copyright (c) 1982 by Richard Conn, who assumes no respons- *
  10. *  ibility or liability for its use.  ZCPR2 is released to the public   *
  11. *  domain for non-commercial use only.                    *
  12. *                                    *
  13. *  The public is encouraged to freely copy and use this program for    *
  14. *  non-commercial purposes.  Any commercial use of ZCPR2 is prohibited    *
  15. *  unless approved by the author, Richard Conn, in writing.        *
  16. *                                    *
  17. *  This is Mod 0.1 to the RELEASE VERSION of ZCPR2.            *
  18. *                                    *
  19. *************************************************************************
  20.  
  21. ;
  22. ;  ZCPR2 -- CP/M Z80 Command Processor Replacement (ZCPR) Version 2.0
  23. ;
  24. ;    ZCPR2 is based upon ZCPR
  25. ;
  26. ;    ZCPR2 was an individual effort by Richard Conn, with comments,
  27. ; recommendations, and some beta testing by the following people:
  28. ;        Frank Wancho
  29. ;        Charlie Strom
  30. ;        Hal Carter
  31. ;
  32. ;    Extensive documentation on ZCPR2 and the utilities in the ZCPR2
  33. ; System can be found in the following manuals:
  34. ;        ZCPR2 Concepts Manual
  35. ;        ZCPR2 Installation Manual
  36. ;        ZCPR2 User's Guide
  37. ;        ZCPR2 Rationale
  38. ;
  39. ;******** Structure Notes ********
  40. ;
  41. ;    ZCPR2 is divided into a number of major sections.  The following
  42. ; is an outline of these sections and the names of the major routines
  43. ; located therein.
  44. ;
  45. ; Section    Function/Routines
  46. ; -------    -----------------
  47. ;
  48. ;   --        Opening Comments, Equates, and Macro Definitions
  49. ;
  50. ;    0        JMP Table into ZCPR2
  51. ;
  52. ;    1        Buffers
  53. ;
  54. ;    2        CPR Starting Modules
  55. ;            CPR1    CPR    CONT    RESTRT    RS1
  56. ;            CAPBUF    RSTCPR    RCPRNL    ERROR    PRNNF
  57. ;
  58. ;    3        Utilities
  59. ;            CRLF    CONOUT    CONIN    LCOUT    LSTOUT
  60. ;            PAGER    READF    READ    BDOSB    PRINTC
  61. ;            PRINT    PRIN1    GETDRV    DEFDMA    DMASET
  62. ;            RESET    BDOSJP    LOGIN    OPENF    OPEN
  63. ;            GRBDOS    CLOSE    SEARF    SEAR1    SEARN
  64. ;            SUBKIL    DELETE    GETUSR    SETUSR
  65. ;
  66. ;     4        CPR Utilities
  67. ;            SETUD    UCASE    REDBUF    BREAK    SDELM
  68. ;            ADVAN    SBLANK    ADDAH    NUMBER    NUMERR
  69. ;            HEXNUM    DIRPTR    SLOGIN    DLOGIN    SCANLOG
  70. ;            SCANER    SCANX    SCANF    CMDSER
  71. ;
  72. ;     5        CPR-Resident Commands and Functions
  73. ;     5A        DIR    DIRPR    PRFN    GETSBIT    FILLQ
  74. ;     5B        ERA
  75. ;     5C        LIST
  76. ;     5D        TYPE
  77. ;     5E        SAVE    EXTEST
  78. ;     5F        REN
  79. ;     5G        JUMP
  80. ;     5H        GO
  81. ;     5I        COM    CALLPROG
  82. ;     5J        GET    MLOAD    PRNLE    PATH
  83. ;
  84. ;
  85. FALSE    EQU    0
  86. TRUE    EQU    NOT FALSE
  87. ;
  88. ;  The following MACLIB statement loads all the user-selected equates
  89. ; which are used to customize ZCPR2 for the user's working environment.
  90. ;
  91.     MACLIB    ZCPRHDR
  92. ;
  93. CR    EQU    0DH
  94. LF    EQU    0AH
  95. TAB    EQU    09H
  96. ;
  97. WBOOT    EQU    BASE+0000H        ;CP/M WARM BOOT ADDRESS
  98. UDFLAG    EQU    BASE+0004H        ;USER NUM IN HIGH NYBBLE, DISK IN LOW
  99. BDOS    EQU    BASE+0005H        ;BDOS FUNCTION CALL ENTRY PT
  100. TFCB    EQU    BASE+005CH        ;DEFAULT FCB BUFFER
  101. TBUFF    EQU    BASE+0080H        ;DEFAULT DISK I/O BUFFER
  102. TPA    EQU    BASE+0100H        ;BASE OF TPA
  103. ;
  104. ;
  105. ; MACROS TO PROVIDE Z80 EXTENSIONS
  106. ;   MACROS INCLUDE:
  107. ;
  108. $-MACRO         ;FIRST TURN OFF THE EXPANSIONS
  109. ;
  110. ;    JR    - JUMP RELATIVE
  111. ;    JRC    - JUMP RELATIVE IF CARRY
  112. ;    JRNC    - JUMP RELATIVE IF NO CARRY
  113. ;    JRZ    - JUMP RELATIVE IF ZERO
  114. ;    JRNZ    - JUMP RELATIVE IF NO ZERO
  115. ;    DJNZ    - DECREMENT B AND JUMP RELATIVE IF NO ZERO
  116. ;    LDIR    - MOV @HL TO @DE FOR COUNT IN BC
  117. ;    LXXD    - LOAD DOUBLE REG DIRECT
  118. ;    SXXD    - STORE DOUBLE REG DIRECT
  119. ;    EXX    - EXCHANGE BC, DE, HL WITH BC', DE', HL'
  120. ;
  121. ;
  122. ;
  123. ;    @GENDD MACRO USED FOR CHECKING AND GENERATING
  124. ;    8-BIT JUMP RELATIVE DISPLACEMENTS
  125. ;
  126. @GENDD    MACRO    ?DD    ;;USED FOR CHECKING RANGE OF 8-BIT DISPLACEMENTS
  127.     IF (?DD GT 7FH) AND (?DD LT 0FF80H)
  128.     DB    100H    ;Displacement Range Error on Jump Relative
  129.     ELSE
  130.     DB    ?DD
  131.     ENDIF        ;;RANGE ERROR
  132.     ENDM
  133. ;
  134. ;
  135. ; Z80 MACRO EXTENSIONS
  136. ;
  137. JR    MACRO    ?N    ;;JUMP RELATIVE
  138.     DB    18H
  139.     @GENDD    ?N-$-1
  140.     ENDM
  141. ;
  142. JRC    MACRO    ?N    ;;JUMP RELATIVE ON CARRY
  143.     DB    38H
  144.     @GENDD    ?N-$-1
  145.     ENDM
  146. ;
  147. JRNC    MACRO    ?N    ;;JUMP RELATIVE ON NO CARRY
  148.     DB    30H
  149.     @GENDD    ?N-$-1
  150.     ENDM
  151. ;
  152. JRZ    MACRO    ?N    ;;JUMP RELATIVE ON ZERO
  153.     DB    28H
  154.     @GENDD    ?N-$-1
  155.     ENDM
  156. ;
  157. JRNZ    MACRO    ?N    ;;JUMP RELATIVE ON NO ZERO
  158.     DB    20H
  159.     @GENDD    ?N-$-1
  160.     ENDM
  161. ;
  162. DJNZ    MACRO    ?N    ;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
  163.     DB    10H
  164.     @GENDD    ?N-$-1
  165.     ENDM
  166. ;
  167. LDIR    MACRO        ;;LDIR
  168.     DB    0EDH,0B0H
  169.     ENDM
  170. ;
  171. LDED    MACRO    ?N    ;;LOAD DE DIRECT
  172.     DB    0EDH,05BH
  173.     DW    ?N
  174.     ENDM
  175. ;
  176. LBCD    MACRO    ?N    ;;LOAD BC DIRECT
  177.     DB    0EDH,4BH
  178.     DW    ?N
  179.     ENDM
  180. ;
  181. SDED    MACRO    ?N    ;;STORE DE DIRECT
  182.     DB    0EDH,53H
  183.     DW    ?N
  184.     ENDM
  185. ;
  186. SBCD    MACRO    ?N    ;;STORE BC DIRECT
  187.     DB    0EDH,43H
  188.     DW    ?N
  189.     ENDM
  190. ;
  191. EXX    MACRO        ;;EXCHANGE PRIMARY AND ALTERNATE REGISTERS
  192.     DB    0D9H
  193.     ENDM
  194. ;
  195. ; END OF Z80 MACRO EXTENSIONS
  196. ;
  197. ;
  198. ;**** Section 0 ****
  199. ;
  200.     ORG    CPRLOC
  201. ;
  202. ;  ENTRY POINTS INTO ZCPR2
  203. ;
  204. ;    IF MULTCMD (MULTIPLE COMMANDS ON ONE LINE) is FALSE:
  205. ;    If ZCPR2 is entered at location CPRLOC (at the JMP to CPR), then
  206. ; the default command in CMDLIN will be processed.  If ZCPR2 is entered
  207. ; at location CPRLOC+3 (at the JMP to CPR1), then the default command in
  208. ; CMDLIN will NOT be processed.
  209. ;    NOTE:  Entry into ZCPR2 at CPRLOC is permitted, but in order for this
  210. ; to work, CMDLIN MUST be initialized to contain the command line (ending in 0)
  211. ; and the C register MUST contain a valid User/Disk Flag
  212. ; (the most significant nybble contains the User Number and the least
  213. ; significant nybble contains the Disk Number).
  214. ;    Some user programs (such as SYNONYM3) attempt to use the default
  215. ; command facility.  Under the original CPR, it was necessary to initialize
  216. ; the pointer after the reserved space for the command buffer to point to
  217. ; the first byte of the command buffer.  The NXTCHR (NeXT CHaRacter pointer)
  218. ; is located to be compatable with such programs (if they determine the buffer
  219. ; length from the byte at BUFSIZ [CPRLOC + 6]), but under ZCPR2
  220. ; this is no longer necessary.  ZCPR2 automatically initializes
  221. ; this buffer pointer in all cases if MULTCMD is not enabled.
  222. ;
  223. ;    IF MULTCMD is TRUE:
  224. ;    Entry at CPR or CPR1 has the same effect.  Multiple command processing
  225. ; will still continue.
  226. ;    Hence, 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. ;    NOTE:  ***** (BIG STAR) ***** Programs such as SYNONYM3 will fail if
  232. ; multiple commands are enabled, but this feature is so very useful that I
  233. ; feel it is worth the sacrifice.  The ZCPR2 utilities of STARTUP and MENU
  234. ; require multiple commands, and this feature also permits simple chaining
  235. ; of programs to be possible under the ZCPR2 environment.
  236. ;
  237. ;    Enjoy using ZCPR2!
  238. ;            Richard Conn
  239. ;
  240. ENTRY:
  241.     JMP    CPR    ; Process potential default command
  242.     JMP    CPR1    ; Do NOT process potential default command
  243. ;
  244. ;**** Section 1 ****
  245. ; BUFFERS ET AL
  246. ;
  247. ; INPUT COMMAND LINE AND DEFAULT COMMAND
  248. ;   The command line to be executed is stored here.  This command line
  249. ; is generated in one of three ways:
  250. ;    (1) by the user entering it through the BDOS READLN function at
  251. ; the du> prompt [user input from keyboard]
  252. ;    (2) by the SUBMIT File Facility placing it there from a $$$.SUB
  253. ; file
  254. ;    (3) by an external program or user placing the required command
  255. ; into this buffer
  256. ;   In all cases, the command line is placed into the buffer starting at
  257. ; CMDLIN.  This command line is terminated by a binary zero.  ZCPR2 then
  258. ; parses, interprets, and executes the command line.
  259. ;   Case is not significant in the command line.  ZCPR2 converts all lower-case
  260. ; letters to upper-case.
  261. ;   If MULTCMD is TRUE, then the user must set a pointer to the first
  262. ; character of the command line into the buffer NXTCHR.  If MULTCMD is FALSE,
  263. ; no action other than placing a zero-terminated command line into the buffer
  264. ; starting at CMDLIN is required on the part of the user.
  265. ;
  266.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  267. ;
  268. ; For Multiple Commands, the command line buffer (CMDLIN) is located external
  269. ; to ZCPR2 so that it is not overlayed during Warm Boots; the same is true
  270. ; for NXTCHR, the 2nd key buffer.  BUFSIZ and CHRCNT are not important and
  271. ; are provided so the BDOS READLN function can load CMDLIN directly and
  272. ; a user program can see how much space is available in CMDLIN for its text.
  273. ;
  274. NXTCHR    EQU    CLBASE        ;NXTCHR STORED EXTERNALLY (2 bytes)
  275. BUFSIZ    EQU    NXTCHR+2    ;BUFSIZ STORED EXTERNALLY (1 byte)
  276. CHRCNT    EQU    BUFSIZ+1    ;CHRCNT STORED EXTERNALLY (1 byte)
  277. CMDLIN    EQU    CHRCNT+1    ;CMDLIN STORED EXTERNALLY (long)
  278. ;
  279.     ELSE
  280. ;
  281. ; If no multiple commands are permitted, these buffers are left internal
  282. ; to ZCPR2 so that the original CCP command line facility (as used by
  283. ; programs like SYNONYM3) can be left intact.
  284. ;
  285. BUFLEN    EQU    80        ;MAXIMUM BUFFER LENGTH
  286. BUFSIZ:
  287.     DB    BUFLEN        ;MAXIMUM BUFFER LENGTH
  288. CHRCNT:
  289.     DB    0        ;NUMBER OF VALID CHARS IN COMMAND LINE
  290. CMDLIN:
  291.     DB    '               '    ;DEFAULT (COLD BOOT) COMMAND
  292.     DB    0            ;COMMAND STRING TERMINATOR
  293.     DS    BUFLEN-($-CMDLIN)+1    ;TOTAL IS 'BUFLEN' BYTES
  294. ;
  295. NXTCHR:
  296.     DW    CMDLIN        ;POINTER TO COMMAND INPUT BUFFER
  297. ;
  298.     ENDIF        ;MULTCMD
  299. ;
  300.  
  301. ;
  302. ; FILE TYPE FOR COMMAND
  303. ;
  304. COMMSG:
  305.     COMTYP            ;USE MACRO FROM ZCPRHDR.LIB
  306. ;
  307.     IF    SUBON        ;IF SUBMIT FACILITY ENABLED ...
  308. ;
  309. ; SUBMIT FILE CONTROL BLOCK
  310. ;
  311. SUBFCB:
  312.     DB    1        ;DISK NAME SET TO DEFAULT TO DRIVE A:
  313.     DB    '$$$'        ;FILE NAME
  314.     DB    '     '
  315.     SUBTYP            ;USE MACRO FROM ZCPRHDR.LIB
  316.     DB    0        ;EXTENT NUMBER
  317.     DB    0        ;S1
  318. SUBFS2:
  319.     DS    1        ;S2
  320. SUBFRC:
  321.     DS    1        ;RECORD COUNT
  322.     DS    16        ;DISK GROUP MAP
  323. SUBFCR:
  324.     DS    1        ;CURRENT RECORD NUMBER
  325. ;
  326.     ENDIF        ;SUBON
  327. ;
  328. ; COMMAND FILE CONTROL BLOCK
  329. ;
  330.     IF    EXTFCB        ;MAY BE PLACED EXTERNAL TO ZCPR2
  331. ;
  332. FCBDN    EQU    FCBADR        ;DISK NAME
  333. FCBFN    EQU    FCBDN+1        ;FILE NAME
  334. FCBFT    EQU    FCBFN+8        ;FILE TYPE
  335. FCBDM    EQU    FCBFT+7        ;DISK GROUP MAP
  336. FCBCR    EQU    FCBDM+16    ;CURRENT RECORD NUMBER
  337. ;
  338.     ELSE            ;OR INTERNAL TO ZCPR2
  339. ;
  340. FCBDN:
  341.     DS    1        ;DISK NAME
  342. FCBFN:
  343.     DS    8        ;FILE NAME
  344. FCBFT:
  345.     DS    3        ;FILE TYPE
  346.     DS    1        ;EXTENT NUMBER
  347.     DS    2        ;S1 AND S2
  348.     DS    1        ;RECORD COUNT
  349. FCBDM:
  350.     DS    16        ;DISK GROUP MAP
  351. FCBCR:
  352.     DS    1        ;CURRENT RECORD NUMBER
  353. ;
  354.     ENDIF        ;EXTFCB
  355. ;
  356.  
  357. ;
  358. ; LINE COUNT BUFFER
  359. ;
  360. PAGCNT:
  361.     DB    NLINES-2    ;LINES LEFT ON PAGE
  362.  
  363. ;
  364. ; CPR COMMAND NAME TABLE
  365. ;   EACH TABLE ENTRY IS COMPOSED OF THE 4-BYTE COMMAND AND 2-BYTE ADDRESS
  366. ;
  367. CMDTBL:
  368.     CTABLE        ;DEFINE COMMAND TABLE VIA MACRO IN ZCPRHDR FILE
  369. ;
  370. NCMNDS    EQU    ($-CMDTBL)/(NCHARS+2)
  371. ;
  372.  
  373. ;
  374. ;**** Section 2 ****
  375. ; ZCPR2 STARTING POINTS
  376. ;
  377. ; START ZCPR2 AND DON'T PROCESS DEFAULT COMMAND STORED IF MULTIPLE COMMANDS
  378. ; ARE NOT ALLOWED
  379. ;
  380. CPR1:
  381. ;
  382.     IF    NOT MULTCMD    ;IF MULTIPLE COMMANDS NOT ALLOWED
  383. ;
  384.     XRA    A        ;SET END OF COMMAND LINE SO NO DEFAULT COMMAND
  385.     STA    CMDLIN        ;FIRST CHAR OF BUFFER
  386. ;
  387.     ENDIF        ;NOT MULTCMD
  388. ;
  389. ; START ZCPR2 AND POSSIBLY PROCESS DEFAULT COMMAND
  390. ;
  391. ; NOTE ON MODIFICATION BY Ron Fowler:  BDOS RETURNS 0FFH IN
  392. ; ACCUMULATOR WHENEVER IT LOGS IN A DIRECTORY, IF ANY
  393. ; FILE NAME CONTAINS A '$' IN IT.  THIS IS NOW USED AS
  394. ; A CLUE TO DETERMINE WHETHER OR NOT TO DO A SEARCH
  395. ; FOR SUBMIT FILE, IN ORDER TO ELIMINATE WASTEFUL SEARCHES.
  396. ;
  397. CPR:
  398.     LXI    SP,STACK    ;RESET STACK
  399. ;
  400.     IF    NOT MULTCMD    ;ONLY ONE COMMAND PERMITTED
  401. ;
  402.     LXI    H,CMDLIN    ;SET PTR TO BEGINNING OF COMMAND LINE
  403.     SHLD    NXTCHR
  404. ;
  405.     ENDIF        ;NOT MULTCMD
  406. ;
  407.     PUSH    B
  408.     MOV    A,C        ;C=USER/DISK NUMBER (SEE LOC 4)
  409.     RAR            ;EXTRACT USER NUMBER
  410.     RAR
  411.     RAR
  412.     RAR
  413.     ANI    0FH
  414.     STA    CURUSR        ;SET USER
  415.     CALL    SETUSR        ;SET USER NUMBER
  416.     CALL    RESET        ;RESET DISK SYSTEM
  417. ;
  418.     IF    SUBON        ;IF SUBMIT FACILITY ENABLED
  419. ;
  420.     STA    RNGSUB        ;SAVE SUBMIT CLUE FROM DRIVE A:
  421. ;
  422.     ENDIF        ;SUBON
  423. ;
  424.     POP    B
  425.     MOV    A,C        ;C=USER/DISK NUMBER (SEE LOC 4)
  426.     ANI    0FH        ;EXTRACT CURRENT DISK DRIVE
  427.     STA    CURDR        ;SET IT
  428.     CNZ    LOGIN        ;LOG IN DEFAULT DISK IF NOT ALREADY LOGGED IN
  429.     CALL    SETUD        ;SET USER/DISK FLAG
  430.     CALL    DEFDMA        ;SET DEFAULT DMA ADDRESS
  431. ;
  432.     IF    SUBON        ;CHECK FOR $$$.SUB IF SUBMIT FACILITY IS ON
  433. ;
  434.     LXI    D,SUBFCB    ;CHECK FOR $$$.SUB ON CURRENT DISK
  435. RNGSUB    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  436.     MVI    A,0        ;2ND BYTE (IMMEDIATE ARG) IS THE RNGSUB FLAG
  437.     ORA    A        ;SET FLAGS ON CLUE
  438.     CMA            ;PREPARE FOR COMING 'CMA'
  439.     CNZ    SEAR1
  440.     CMA            ;0FFH IS RETURNED IF NO $$$.SUB, SO COMPLEMENT
  441.     STA    RNGSUB        ;SET FLAG (0=NO $$$.SUB)
  442. ;
  443.     ENDIF        ;SUBON
  444. ;
  445.     IF    MULTCMD
  446. ;
  447. ;  TEST FOR NEXT COMMAND IN CONT LOOP IF MULTIPLE COMMAND LINE BUFFER
  448. ;    IS ENABLED
  449. ;
  450. CONT:
  451. ;
  452.     ENDIF        ;MULTCMD
  453. ;
  454.     LHLD    NXTCHR        ;PT TO NEXT CHARACTER TO PROCESS
  455.     MOV    A,M        ;GET IT
  456.     CPI    3        ;RESTART IF ^C
  457.     JRZ    RESTRT
  458.     ORA    A        ;0 IF NO COMMAND LINE PRESENT
  459.     JRNZ    RS1
  460. ;
  461.     IF    NOT MULTCMD
  462. ;
  463. ;  TEST FOR ANY DEFAULT COMMAND BEFORE CONT LOOP IS
  464. ;    ENTERED IF MULTIPLE COMMAND LINE BUFFER IS DISABLED
  465. ;
  466. CONT:
  467. ;
  468.     ENDIF        ;NOT MULTCMD
  469. ;
  470. ; PROMPT USER AND INPUT COMMAND LINE FROM HIM
  471. ;
  472. RESTRT:
  473.     LXI    SP,STACK    ;RESET STACK
  474. ;
  475. ; PRINT PROMPT (DU>)
  476. ;
  477.     CALL    CRLF        ;PRINT PROMPT
  478. ;
  479.     IF    DUPRMPT        ;IF DRIVE IN PROMPT
  480.     LDA    CURDR        ;CURRENT DRIVE IS PART OF PROMPT
  481.     ADI    'A'        ;CONVERT TO ASCII A-P
  482.     CALL    CONOUT
  483. ;
  484.     LDA    CURUSR        ;GET USER NUMBER
  485. ;
  486.     IF    SUPRES        ;IF SUPPRESSING USR # REPORT FOR USR 0
  487. ;
  488.     ORA    A
  489.     JRZ    RS000
  490. ;
  491.     ENDIF        ;SUPRES
  492. ;
  493.     CPI    10        ;USER < 10?
  494.     JRC    RS00
  495.     SUI    10        ;SUBTRACT 10 FROM IT
  496.     PUSH    PSW        ;SAVE IT
  497.     MVI    A,'1'        ;OUTPUT 10'S DIGIT
  498.     CALL    CONOUT
  499.     POP    PSW
  500. RS00:
  501.     ADI    '0'        ;OUTPUT 1'S DIGIT (CONVERT TO ASCII)
  502.     CALL    CONOUT
  503. ;
  504.     ENDIF        ;DUPRMPT
  505. ;
  506. ; READ INPUT LINE FROM USER OR $$$.SUB
  507. ;
  508. RS000:
  509.     LXI    H,CMDLIN    ;SET POINTER TO FIRST CHAR IN COMMAND LINE
  510.     SHLD    NXTCHR        ;POINTER TO NEXT CHARACTER TO PROCESS
  511.     MVI    M,0        ;ZERO OUT COMMAND LINE IN CASE OF WARM BOOT
  512.     PUSH    H        ;SAVE PTR
  513.     CALL    REDBUF        ;INPUT COMMAND LINE FROM USER (OR $$$.SUB)
  514.     POP    H        ;GET PTR
  515.     MOV    A,M        ;CHECK FOR COMMENT LINE
  516.     CPI    COMMENT        ;BEGINS WITH COMMENT CHAR?
  517.     JRZ    RESTRT        ;INPUT ANOTHER LINE IF SO
  518.     ORA    A        ;NO INPUT?
  519.     JRZ    RESTRT
  520. ;
  521. ; PROCESS INPUT LINE; HL PTS TO FIRST LETTER OF COMMAND
  522. ;
  523. RS1:
  524.     LXI    SP,STACK    ;RESET STACK
  525. ;
  526.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  527. ;
  528.     MOV    A,M        ;GET FIRST CHAR OF COMMAND
  529.     CPI    CMDSEP        ;IS IT A COMMAND SEPARATOR?
  530.     JRNZ    RS2
  531.     INX    H        ;SKIP IT IF IT IS
  532.     SHLD    NXTCHR        ;SET PTR BACK
  533. ;
  534.     ENDIF        ;MULTCMD
  535. ;
  536. ; SET POINTER FOR MULTIPLE COMMAND LINE PROCESSING TO FIRST CHAR OF NEW CMND
  537. ;
  538. RS2:
  539.     SHLD    CMDCH1        ;SET PTR TO FIRST CHAR OF NEW COMMAND LINE
  540. ;
  541. ; CAPITALIZE COMMAND LINE
  542. ;
  543. CAPBUF:
  544.     MOV    A,M        ;CAPITALIZE COMMAND CHAR
  545.     CALL    UCASE
  546.     MOV    M,A
  547.     INX    H        ;PT TO NEXT CHAR
  548.     ORA    A        ;EOL?
  549.     JRNZ    CAPBUF
  550.     CALL    SCANER        ;PARSE COMMAND NAME FROM COMMAND LINE
  551.     JRNZ    ERROR        ;ERROR IF COMMAND NAME CONTAINS A '?'
  552.     LXI    D,RSTCPR    ;PUT RETURN ADDRESS OF COMMAND
  553.     PUSH    D        ;ON THE STACK
  554. COLON    EQU    $+1        ;FLAG FOR IN-THE-CODE MODIFICATION
  555.     MVI    A,0        ;COMMAND OF THE FORM 'DU:COMMAND'?
  556.     ORA    A        ;0=NO
  557.     JNZ    COM        ;PROCESS AS COM FILE IF NOT
  558.     CALL    CMDSER        ;SCAN FOR CPR-RESIDENT COMMAND
  559.     JNZ    COM        ;NOT CPR-RESIDENT
  560.     MOV    A,M        ;FOUND IT:  GET LOW-ORDER PART
  561.     INX    H        ;GET HIGH-ORDER PART
  562.     MOV    H,M        ;STORE HIGH
  563.     MOV    L,A        ;STORE LOW
  564.     PCHL            ;EXECUTE CPR ROUTINE
  565. ;
  566. ; ENTRY POINT FOR RESTARTING CPR AND LOGGING IN DEFAULT DRIVE
  567. ;
  568. RSTCPR:
  569.     CALL    DLOGIN        ;LOG IN CURRENT USER/DISK
  570. ;
  571. ; ENTRY POINT FOR RESTARTING CPR WITHOUT LOGGING IN DEFAULT DRIVE
  572. ;
  573. RCPRNL:
  574.     CALL    SCANER        ;EXTRACT NEXT TOKEN FROM COMMAND LINE
  575.     LDA    FCBFN        ;GET FIRST CHAR OF TOKEN
  576.     CPI    ' '        ;ANY CHAR?
  577.     JZ    CONT        ;CONTINUE WITH NEXT COMMAND IF NO ERROR
  578.  
  579. ;
  580. ; INVALID COMMAND -- PRINT IT
  581. ;
  582. ERROR:
  583.     CALL    CRLF        ;NEW LINE
  584. CURTOK    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  585.     LXI    H,0        ;PT TO BEGINNING OF COMMAND LINE
  586. ERR1:
  587.     MOV    A,M        ;GET CHAR
  588.     CPI    ' '+1        ;SIMPLE '?' IF <SP> OR LESS
  589.     JRC    ERR2
  590.     CALL    CONOUT        ;PRINT COMMAND CHAR
  591.     INX    H        ;PT TO NEXT CHAR
  592.     JR    ERR1        ;CONTINUE
  593. ERR2:
  594.     CALL    PRINT        ;PRINT '?'
  595.     DB    '?'+80H
  596. ERR3:
  597.     CALL    DLOGIN        ;PANIC RESTORE OF DEFAULT USER/DISK
  598. ;
  599.     IF    SUBON        ;IF SUBMIT FACILITY IS ON
  600. ;
  601.     CALL    SUBKIL        ;TERMINATE ACTIVE $$$.SUB IF ANY
  602. ;
  603.     ENDIF        ;SUBON
  604. ;
  605.     JMP    RESTRT        ;RESTART CPR
  606.  
  607. ;
  608. ; No File Error Message
  609. ;
  610. PRNNF:
  611.     CALL    PRINTC        ;NO FILE MESSAGE
  612.     DB    'No Fil','e'+80H
  613.     RET
  614. ;
  615. ;**** Section 3 ****
  616. ; I/O UTILITIES
  617. ;
  618. ; OUTPUT CHAR IN REG A TO CONSOLE AND DON'T CHANGE BC
  619. ;
  620. ;
  621. ; OUTPUT <CRLF>
  622. ;
  623. CRLF:
  624.     MVI    A,CR
  625.     CALL    CONOUT
  626.     MVI    A,LF
  627.     JR    CONOUT
  628. ;
  629. CONIN:
  630.     CALL    BIOS+9    ;GET INPUT CHAR
  631.     CALL    UCASE    ;CAPITALIZE AND FALL THRU TO ECHO
  632. ;
  633. CONOUT:
  634.     PUSH    PSW    ;SAVE CHAR
  635.     EXX
  636.     MVI    C,02H
  637. OUTPUT:
  638.     MOV    E,A
  639.     CALL    BDOS
  640.     EXX
  641.     POP    PSW    ;GET CHR
  642.     RET
  643. ;
  644. LCOUT:
  645.     PUSH    PSW    ;OUTPUT CHAR TO CON: OR LST: DEP ON PRFLG
  646. PRFLG    EQU    $+1    ;POINTER FOR IN-THE-CODE MODIFICATION
  647.     MVI    A,0    ;2ND BYTE (IMMEDIATE ARG) IS THE PRINT FLAG
  648.     ORA    A    ;0=TYPE
  649.     JRZ    LC1
  650.     POP    PSW    ;GET CHAR
  651. ;
  652. ; OUTPUT CHAR IN REG A TO LIST DEVICE
  653. ;
  654. LSTOUT:
  655.     PUSH    PSW    ;SAVE CHAR
  656.     EXX        ;SAVE REGS
  657.     MVI    C,05H
  658.     JR    OUTPUT
  659. LC1:
  660.     POP    PSW    ;GET CHAR
  661.     PUSH    PSW
  662.     CALL    CONOUT    ;OUTPUT TO CON:
  663.     POP    PSW
  664.     CPI    LF    ;CHECK FOR PAGING
  665.     RNZ
  666. ;
  667. ; PAGING ROUTINES
  668. ;   PAGER COUNTS DOWN LINES AND PAUSES FOR INPUT (DIRECT) IF COUNT EXPIRES
  669. ;   PAGSET SETS LINES/PAGE COUNT
  670. ;
  671. PAGER:
  672.     PUSH    H
  673.     LXI    H,PAGCNT    ;COUNT DOWN
  674.     DCR    M
  675.     JRNZ    PAGER1        ;JUMP IF NOT END OF PAGE
  676.     MVI    M,NLINES-2    ;REFILL COUNTER
  677. ;
  678. PGFLG    EQU    $+1        ;POINTER TO IN-THE-CODE BUFFER PGFLG
  679.     MVI    A,0        ;0 MAY BE CHANGED BY PGFLG EQUATE
  680.     CPI    PGDFLG        ;PAGE DEFAULT OVERRIDE OPTION WANTED?
  681. ;
  682.     IF    PGDFLT        ;IF PAGING IS DEFAULT
  683. ;
  684.     JRZ    PAGER1        ;  PGDFLG MEANS NO PAGING, PLEASE
  685. ;
  686.     ELSE            ;IF PAGING NOT DEFAULT
  687. ;
  688.     JRNZ    PAGER1        ;  PGDFLG MEANS PLEASE PAGINATE
  689. ;
  690.     ENDIF        ;PGDFLG
  691. ;
  692.     PUSH    B
  693.     CALL    BIOS+9        ;BIOS CONSOLE INPUT ROUTINE
  694.     POP    B        ;GET REGS
  695.     CPI    'C'-'@'     ;^C
  696.     JZ    RSTCPR        ;RESTART CPR
  697. PAGER1:
  698.     POP    H        ;RESTORE HL
  699.     RET
  700. ;
  701. ; READ FILE BLOCK FUNCTION
  702. ;
  703. READF:
  704.     LXI    D,FCBDN ;FALL THRU TO READ
  705. READ:
  706.     MVI    C,14H    ;FALL THRU TO BDOSB
  707. ;
  708. ; CALL BDOS AND SAVE BC
  709. ;
  710. BDOSB:
  711.     PUSH    B
  712.     CALL    BDOS
  713.     POP    B
  714.     ORA    A
  715.     RET
  716. ;
  717. ; PRINT STRING (ENDING IN CHAR WITH MSB SET) PTED TO BY RET ADR
  718. ; START WITH <CRLF>
  719. ;
  720. PRINTC:
  721.     CALL    CRLF        ;NEW LINE
  722. ;
  723. PRINT:
  724.     XTHL            ;GET PTR TO STRING
  725.     CALL    PRIN1        ;PRINT STRING
  726.     XTHL            ;RESTORE HL AND RET ADR
  727.     RET
  728. ;
  729. ; PRINT STRING (ENDING IN 0 OR BYTE WITH MSB SET) PTED TO BY HL
  730. ;
  731. PRIN1:
  732.     MOV    A,M        ;GET NEXT BYTE
  733.     INX    H        ;PT TO NEXT BYTE
  734.     ORA    A        ;END OF STRING?
  735.     RZ            ;STRING TERMINATED BY BINARY 0
  736.     PUSH    PSW        ;SAVE FLAGS
  737.     ANI    7FH        ;MASK OUT MSB
  738.     CALL    CONOUT        ;PRINT CHAR
  739.     POP    PSW        ;GET FLAGS
  740.     RM            ;STRING TERMINATED BY MSB SET
  741.     JR    PRIN1
  742. ;
  743. ; BDOS FUNCTION ROUTINES
  744. ;
  745. ;
  746. ; RETURN NUMBER OF CURRENT DISK IN A
  747. ;
  748. GETDRV:
  749.     MVI    C,19H
  750.     JR    BDOSJP
  751. ;
  752. ; SET 80H AS DMA ADDRESS
  753. ;
  754. DEFDMA:
  755.     LXI    D,TBUFF     ;80H=TBUFF
  756. DMASET:
  757.     MVI    C,1AH
  758.     JR    BDOSJP
  759. ;
  760. RESET:
  761.     MVI    C,0DH
  762. BDOSJP:
  763.     JMP    BDOS
  764. ;
  765. LOGIN:
  766.     MOV    E,A
  767.     MVI    C,0EH
  768.     JR    BDOSJP    ;SAVE SOME CODE SPACE
  769. ;
  770. OPENF:
  771.     XRA    A
  772.     STA    FCBCR
  773.     LXI    D,FCBDN ;FALL THRU TO OPEN
  774. ;
  775. OPEN:
  776.     MVI    C,0FH    ;FALL THRU TO GRBDOS
  777. ;
  778. GRBDOS:
  779.     CALL    BDOS
  780.     INR    A    ;SET ZERO FLAG FOR ERROR RETURN
  781.     RET
  782. ;
  783. CLOSE:
  784.     MVI    C,10H
  785.     JR    GRBDOS
  786. ;
  787. SEARF:
  788.     LXI    D,FCBDN ;SPECIFY FCB
  789. SEAR1:
  790.     MVI    C,11H
  791.     JR    GRBDOS
  792. ;
  793. SEARN:
  794.     MVI    C,12H
  795.     JR    GRBDOS
  796. ;
  797. ; CHECK FOR SUBMIT FILE IN EXECUTION AND ABORT IT IF SO
  798. ;
  799.     IF    SUBON        ;ENABLE ONLY IF SUBMIT FACILITY IS ENABLED
  800. ;
  801. SUBKIL:
  802.     LXI    H,RNGSUB    ;CHECK FOR SUBMIT FILE IN EXECUTION
  803.     MOV    A,M
  804.     ORA    A        ;0=NO
  805.     RZ
  806.     MVI    M,0        ;ABORT SUBMIT FILE
  807.     LXI    D,SUBFCB    ;DELETE $$$.SUB
  808. ;
  809.     ENDIF        ;SUBON
  810. ;
  811. DELETE:
  812.     MVI    C,13H
  813.     JR    BDOSJP    ;SAVE MORE SPACE
  814. ;
  815. ;  GET/SET USER NUMBER
  816. ;
  817. GETUSR:
  818.     MVI    A,0FFH        ;GET CURRENT USER NUMBER
  819. SETUSR:
  820.     MOV    E,A        ;USER NUMBER IN E
  821.     MVI    C,20H        ;SET USER NUMBER TO VALUE IN E (GET IF E=FFH)
  822.     JR    BDOSJP        ;MORE SPACE SAVING
  823. ;
  824. ; END OF BDOS FUNCTIONS
  825. ;
  826. ;
  827. ;**** Section 4 ****
  828. ; ZCPR2 UTILITIES
  829. ;
  830. ; SET USER/DISK FLAG TO CURRENT USER AND DEFAULT DISK
  831. ;
  832. SETUD:
  833.     CALL    GETUSR        ;GET NUMBER OF CURRENT USER
  834.     ANI    0FH        ;MASK SURE 4 BITS
  835.     ADD    A        ;PLACE IT IN HIGH NYBBLE
  836.     ADD    A
  837.     ADD    A
  838.     ADD    A
  839.     LXI    H,CURDR        ;MASK IN CURRENT DRIVE NUMBER (LOW NYBBLE)
  840.     ORA    M        ;MASK IN
  841.     STA    UDFLAG        ;SET USER/DISK NUMBER
  842.     RET
  843. ;
  844. ; CONVERT CHAR IN A TO UPPER CASE
  845. ;
  846. UCASE:
  847.     ANI    7FH        ;MASK OUT MSB
  848.     CPI    61H        ;LOWER-CASE A
  849.     RC
  850.     CPI    7BH        ;GREATER THAN LOWER-CASE Z?
  851.     RNC
  852.     ANI    5FH        ;CAPITALIZE
  853.     RET
  854. ;
  855. ; INPUT NEXT COMMAND TO CPR
  856. ;    This routine determines if a SUBMIT file is being processed
  857. ; and extracts the command line from it if so or from the user's console
  858. ;
  859. REDBUF:
  860. ;
  861.     IF    SUBON        ;IF SUBMIT FACILITY IS ENABLED, CHECK FOR IT
  862. ;
  863.     LDA    RNGSUB        ;SUBMIT FILE CURRENTLY IN EXECUTION?
  864.     ORA    A        ;0=NO
  865.     JRZ    RB1        ;GET LINE FROM CONSOLE IF NOT
  866.     LXI    D,SUBFCB    ;OPEN $$$.SUB
  867.     PUSH    D        ;SAVE DE
  868.     CALL    OPEN
  869.     POP    D        ;RESTORE DE
  870.     JRZ    RB1        ;ERASE $$$.SUB IF END OF FILE AND GET CMND
  871.     LDA    SUBFRC        ;GET VALUE OF LAST RECORD IN FILE
  872.     DCR    A        ;PT TO NEXT TO LAST RECORD
  873.     STA    SUBFCR        ;SAVE NEW VALUE OF LAST RECORD IN $$$.SUB
  874.     CALL    READ        ;DE=SUBFCB
  875.     JRNZ    RB1        ;ABORT $$$.SUB IF ERROR IN READING LAST REC
  876.     LXI    D,CHRCNT     ;COPY LAST RECORD (NEXT SUBMIT CMND) TO CHRCNT
  877.     LXI    H,TBUFF     ;  FROM TBUFF
  878.     LXI    B,BUFLEN    ;NUMBER OF BYTES
  879.     LDIR
  880.     LXI    H,SUBFS2    ;PT TO S2 OF $$$.SUB FCB
  881.     MVI    M,0        ;SET S2 TO ZERO
  882.     INX    H        ;PT TO RECORD COUNT
  883.     DCR    M        ;DECREMENT RECORD COUNT OF $$$.SUB
  884.     LXI    D,SUBFCB    ;CLOSE $$$.SUB
  885.     CALL    CLOSE
  886.     JRZ    RB1        ;ABORT $$$.SUB IF ERROR
  887.     MVI    A,SPRMPT    ;PRINT SUBMIT PROMPT
  888.     CALL    CONOUT
  889.     LXI    H,CMDLIN    ;PRINT COMMAND LINE FROM $$$.SUB
  890.     CALL    PRIN1
  891.     CALL    BREAK        ;CHECK FOR ABORT (ANY CHAR)
  892.     RZ            ;IF <NULL> (NO ABORT), RETURN TO CALLER AND RUN
  893.     CALL    SUBKIL        ;KILL $$$.SUB IF ABORT
  894.     JMP    RESTRT        ;RESTART CPR
  895. ;
  896. ; INPUT COMMAND LINE FROM USER CONSOLE
  897. ;
  898. RB1:
  899.     CALL    SUBKIL        ;ERASE $$$.SUB IF PRESENT
  900. ;
  901.     ENDIF        ;SUBON
  902. ;
  903.     MVI    A,CPRMPT    ;PRINT PROMPT
  904.     CALL    CONOUT
  905.     MVI    C,0AH        ;READ COMMAND LINE FROM USER
  906.     LXI    D,BUFSIZ
  907.     CALL    BDOS
  908. ;
  909. ; STORE ZERO AT END OF COMMAND LINE
  910. ;
  911.     LXI    H,CHRCNT    ;PT TO CHAR COUNT
  912.     MOV    A,M        ;GET CHAR COUNT
  913.     INX    H        ;PT TO FIRST CHAR OF COMMAND LINE
  914.     CALL    ADDAH        ;PT TO AFTER LAST CHAR OF COMMAND LINE
  915.     MVI    M,0        ;STORE ENDING ZERO
  916.     RET
  917. ;
  918. ; CHECK FOR ANY CHAR FROM USER CONSOLE; RET W/ZERO SET IF NONE
  919. ;
  920. BREAK:
  921.     PUSH    D        ;SAVE DE
  922.     CALL    BIOS+6        ;CONSOLE STATUS CHECK
  923.     ORA    A        ;SET FLAGS
  924.     CNZ    BIOS+9        ;GET INPUT CHAR
  925.     POP    D
  926.     RET
  927.  
  928. ;
  929. ; CHECK TO SEE IF DE PTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET
  930. ;
  931. SDELM:
  932.     LDAX    D
  933.     ORA    A        ;0=DELIMITER
  934.     RZ
  935.     CPI    ' '+1        ;DELIM IF <= <SP>
  936.     JRC    ZERO
  937.     CPI    '='        ;'='=DELIMITER
  938.     RZ
  939.     CPI    5FH        ;UNDERSCORE=DELIMITER
  940.     RZ
  941.     CPI    '.'        ;'.'=DELIMITER
  942.     RZ
  943.     CPI    ':'        ;':'=DELIMITER
  944.     RZ
  945.     CPI    ','        ;','=DELIMITER
  946.     RZ
  947.     CPI    ';'        ;';'=DELIMITER
  948.     RZ
  949.     CPI    '<'        ;'<'=DELIMITER
  950.     RZ
  951.     CPI    '>'        ;'>'=DELIMITER
  952. ;
  953.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  954. ;
  955.     RZ
  956.     CPI    CMDSEP        ;COMMAND SEPARATOR
  957. ;
  958.     ENDIF        ;MULTCMD
  959. ;
  960.     RET
  961. ZERO:
  962.     XRA    A    ;SET ZERO FLAG
  963.     RET
  964.  
  965. ;
  966. ; ADVANCE INPUT PTR TO FIRST NON-BLANK AND FALL THROUGH TO SBLANK
  967. ;
  968. ADVAN:
  969.     LDED    NXTCHR    ;PT TO NEXT CHAR
  970. ;
  971. ; SKIP STRING PTED TO BY DE (STRING ENDS IN 0 OR CMDSEP) UNTIL END OF STRING
  972. ;   OR NON-DELIM ENCOUNTERED (BEGINNING OF TOKEN)
  973. ;
  974. SBLANK:
  975.     LDAX    D    ;GET CHAR
  976.     ORA    A    ;ZERO?
  977.     RZ
  978. ;
  979.     IF    MULTCMD    ;MULTIPLE COMMANDS ALLOWED?
  980. ;
  981.     CPI    CMDSEP    ;COMMAND SEPARATOR?
  982.     RZ
  983. ;
  984.     ENDIF        ;MULTCMD
  985. ;
  986.     CALL    SDELM    ;SKIP OVER DELIMITER
  987.     RNZ
  988.     INX    D    ;ADVANCE TO NEXT CHAR
  989.     JR    SBLANK
  990. ;
  991. ; ADD A TO HL (HL=HL+A)
  992. ;
  993. ADDAH:
  994.     ADD    L
  995.     MOV    L,A
  996.     RNC
  997.     INR    H
  998.     RET
  999. ;
  1000. ; EXTRACT DECIMAL NUMBER FROM COMMAND LINE
  1001. ;   RETURN WITH VALUE IN REG A; ALL REGISTERS MAY BE AFFECTED
  1002. ;
  1003. NUMBER:
  1004.     CALL    SCANER        ;PARSE NUMBER AND PLACE IN FCBFN
  1005.     LXI    H,FCBFN+10     ;PT TO END OF TOKEN FOR CONVERSION
  1006.     MVI    B,11        ;11 CHARS MAX
  1007. ;
  1008. ; CHECK FOR SUFFIX FOR HEXADECIMAL NUMBER
  1009. ;
  1010. NUMS:
  1011.     MOV    A,M        ;GET CHARS FROM END, SEARCHING FOR SUFFIX
  1012.     DCX    H        ;BACK UP
  1013.     CPI    ' '        ;SPACE?
  1014.     JRNZ    NUMS1        ;CHECK FOR SUFFIX
  1015.     DJNZ    NUMS        ;COUNT DOWN
  1016.     JR    NUM0        ;BY DEFAULT, PROCESS
  1017. NUMS1:
  1018.     CPI    NUMBASE        ;CHECK AGAINST BASE SWITCH FLAG
  1019.     JRZ    HNUM0
  1020. ;
  1021. ; PROCESS DECIMAL NUMBER
  1022. ;
  1023. NUM0:
  1024.     LXI    H,FCBFN        ;PT TO BEGINNING OF TOKEN
  1025. NUM0A:
  1026.     LXI    B,1100H        ;C=ACCUMULATED VALUE, B=CHAR COUNT
  1027.                 ; (C=0, B=11)
  1028. NUM1:
  1029.     MOV    A,M        ;GET CHAR
  1030.     CPI    ' '        ;DONE IF <SP>
  1031.     JRZ    NUM2
  1032.     CPI    ':'        ;DONE IF COLON
  1033.     JRZ    NUM2
  1034.     INX    H        ;PT TO NEXT CHAR
  1035.     SUI    '0'        ;CONVERT TO BINARY (ASCII 0-9 TO BINARY)
  1036.     CPI    10        ;ERROR IF >= 10
  1037.     JRNC    NUMERR
  1038.     MOV    D,A        ;DIGIT IN D
  1039.     MOV    A,C        ;NEW VALUE = OLD VALUE * 10
  1040.     RLC            ;*2
  1041.     JRC    NUMERR
  1042.     RLC            ;*4
  1043.     JRC    NUMERR
  1044.     RLC            ;*8
  1045.     JRC    NUMERR
  1046.     ADD    C        ;*9
  1047.     JRC    NUMERR
  1048.     ADD    C        ;*10
  1049.     JRC    NUMERR
  1050.     ADD    D        ;NEW VALUE = OLD VALUE * 10 + DIGIT
  1051.     JRC    NUMERR        ;CHECK FOR RANGE ERROR
  1052.     MOV    C,A        ;SET NEW VALUE
  1053.     DJNZ    NUM1        ;COUNT DOWN
  1054. ;
  1055. ; RETURN FROM NUMBER
  1056. ;
  1057. NUM2:
  1058.     MOV    A,C        ;GET ACCUMULATED VALUE
  1059.     RET
  1060. ;
  1061. ; NUMBER ERROR ROUTINE FOR SPACE CONSERVATION
  1062. ;
  1063. NUMERR:
  1064.     JMP    ERROR        ;USE ERROR ROUTINE - THIS IS RELATIVE PT
  1065. ;
  1066. ; EXTRACT HEXADECIMAL NUMBER FROM COMMAND LINE
  1067. ;   RETURN WITH VALUE IN REG A; ALL REGISTERS MAY BE AFFECTED
  1068. ;
  1069. HEXNUM:
  1070.     CALL    SCANER        ;PARSE NUMBER AND PLACE IN FCBFN
  1071. HNUM0:
  1072.     LXI    H,FCBFN        ;PT TO TOKEN FOR CONVERSION
  1073.     LXI    D,0        ;DE=ACCUMULATED VALUE
  1074.     MVI    B,11        ;B=CHAR COUNT
  1075. HNUM1:
  1076.     MOV    A,M        ;GET CHAR
  1077.     CPI    ' '        ;DONE?
  1078.     JRZ    HNUM3        ;RETURN IF SO
  1079.     CPI    NUMBASE        ;DONE IF NUMBASE SUFFIX
  1080.     JRZ    HNUM3
  1081.     SUI    '0'        ;CONVERT TO BINARY
  1082.     JRC    NUMERR        ;RETURN AND DONE IF ERROR
  1083.     CPI    10        ;0-9?
  1084.     JRC    HNUM2
  1085.     SUI    7        ;A-F?
  1086.     CPI    10H        ;ERROR?
  1087.     JRNC    NUMERR
  1088. HNUM2:
  1089.     INX    H        ;PT TO NEXT CHAR
  1090.     MOV    C,A        ;DIGIT IN C
  1091.     MOV    A,D        ;GET ACCUMULATED VALUE
  1092.     RLC            ;EXCHANGE NYBBLES
  1093.     RLC
  1094.     RLC
  1095.     RLC
  1096.     ANI    0F0H        ;MASK OUT LOW NYBBLE
  1097.     MOV    D,A
  1098.     MOV    A,E        ;SWITCH LOW-ORDER NYBBLES
  1099.     RLC
  1100.     RLC
  1101.     RLC
  1102.     RLC
  1103.     MOV    E,A        ;HIGH NYBBLE OF E=NEW HIGH OF E,
  1104.                 ;  LOW NYBBLE OF E=NEW LOW OF D
  1105.     ANI    0FH        ;GET NEW LOW OF D
  1106.     ORA    D        ;MASK IN HIGH OF D
  1107.     MOV    D,A        ;NEW HIGH BYTE IN D
  1108.     MOV    A,E
  1109.     ANI    0F0H        ;MASK OUT LOW OF E
  1110.     ORA    C        ;MASK IN NEW LOW
  1111.     MOV    E,A        ;NEW LOW BYTE IN E
  1112.     DJNZ    HNUM1        ;COUNT DOWN
  1113. ;
  1114. ; RETURN FROM HEXNUM
  1115. ;
  1116. HNUM3:
  1117.     XCHG            ;RETURNED VALUE IN HL
  1118.     MOV    A,L        ;LOW-ORDER BYTE IN A
  1119.     RET
  1120. ;
  1121. ; PT TO DIRECTORY ENTRY IN TBUFF WHOSE OFFSET IS SPECIFIED BY A AND C
  1122. ;
  1123. DIRPTR:
  1124.     LXI    H,TBUFF     ;PT TO TEMP BUFFER
  1125.     ADD    C        ;PT TO 1ST BYTE OF DIR ENTRY
  1126.     CALL    ADDAH        ;PT TO DESIRED BYTE IN DIR ENTRY
  1127.     MOV    A,M        ;GET DESIRED BYTE
  1128.     RET
  1129. ;
  1130. ; CHECK FOR SPECIFIED DRIVE AND LOG IT IN
  1131. ;
  1132. SLOGIN:
  1133.     XRA    A        ;A=0 FOR DEFAULT DISK
  1134.     STA    FCBDN        ;SELECT DEFAULT DISK SINCE USER/DISK
  1135.                 ;  SPECIFICALLY SELECTED BY THIS ROUTINE
  1136. TEMPDR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1137.     MVI    A,0        ;2ND BYTE (IMMEDIATE ARG) IS TEMPDR
  1138.     ORA    A        ;0=CURRENT DRIVE
  1139.     JRNZ    SLOG1
  1140.     LDA    CURDR        ;LOG IN CURRENT DRIVE
  1141.     INR    A        ;ADD 1 FOR NEXT DCR
  1142. SLOG1:
  1143.     DCR    A        ;ADJUST FOR PROPER DISK NUMBER (A=0)
  1144.     CALL    LOGIN        ;LOG IN NEW DRIVE
  1145. TEMPUSR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1146.     MVI    A,0        ;2ND BYTE IS USER TO BE SELECTED
  1147.     JMP    SETUSR        ;LOG IN NEW USER
  1148.  
  1149. ;
  1150. ; CHECK FOR SPECIFIED DRIVE AND LOG IN DEFAULT DRIVE IF SPECIFIED<>DEFAULT
  1151. ;
  1152. DLOGIN:
  1153. CURDR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1154.     MVI    A,0        ;PREP TO LOG IN CURRENT DRIVE
  1155.     CALL    LOGIN        ;LOGIN CURRENT DRIVE
  1156. CURUSR    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1157.     MVI    A,0        ;PREP TO LOG IN CURRENT USER NUMBER
  1158.     JMP    SETUSR        ;LOG IN NEW USER
  1159.  
  1160. ;
  1161. ;  ROUTINE TO CHECK FOR A WHEEL BYTE AS NON-ZERO
  1162. ;    IF WHEEL BYTE IS ZERO, THEN ABORT (POP STACK AND RETURN)
  1163. ;
  1164. ;
  1165.     IF    WHEEL        ;WHEEL FACILITY?
  1166. ;
  1167. WHLCHK:
  1168.     LDA    WHLADR        ;GET WHEEL BYTE
  1169.     ORA    A        ;ZERO?
  1170.     RNZ            ;OK IF NOT
  1171.     JMP    ERROR        ;PROCESS AS ERROR
  1172. ;
  1173.     ENDIF        ;WHEEL
  1174. ;
  1175.  
  1176. ;
  1177. ; EXTRACT TOKEN FROM COMMAND LINE AND PLACE IT INTO FCBDN;
  1178. ;   FORMAT FCBDN FCB IF TOKEN RESEMBLES FILE NAME AND TYPE (FILENAME.TYP);
  1179. ;   ON INPUT, NXTCHR PTS TO CHAR AT WHICH TO START SCAN;
  1180. ;   ON OUTPUT, NXTCHR PTS TO CHAR AT WHICH TO CONTINUE AND ZERO FLAG IS RESET
  1181. ;     IF '?' IS IN TOKEN
  1182. ;
  1183. ; ENTRY POINTS:
  1184. ;    SCANLOG - LOAD TOKEN INTO FIRST FCB AND LOG IN TEMP USER/DISK
  1185. ;    SCANER - LOAD TOKEN INTO FIRST FCB
  1186. ;    SCANX - LOAD TOKEN INTO FCB PTED TO BY HL
  1187. ;
  1188. SCANLOG:
  1189.     CALL    SCANER        ;DO SCAN
  1190.     PUSH    PSW        ;SAVE FLAG
  1191.     CALL    SLOGIN        ;LOG IN TEMPORARY USER/DISK
  1192.     POP    PSW        ;GET FLAG
  1193.     RET
  1194. SCANER:
  1195.     LXI    H,FCBDN     ;POINT TO FCBDN
  1196. SCANX:
  1197.     XRA    A        ;A=0
  1198.     STA    TEMPDR        ;SET TEMPORARY DRIVE NUMBER TO DEFAULT
  1199.     MOV    M,A        ;SET FIRST BYTE OF FCBDN AS DEFAULT DRIVE
  1200.     STA    COLON        ;SET NO COLON FLAG
  1201.     LDA    CURUSR        ;GET CURRENT USER
  1202.     STA    TEMPUSR        ;SET TEMPUSR
  1203.     CALL    ADVAN        ;SKIP TO NON-BLANK OR END OF LINE
  1204.     SDED    CURTOK        ;SET PTR TO NON-BLANK OR END OF LINE
  1205.     MVI    B,11        ;PREP FOR POSSIBLE SPACE FILL
  1206.     JRZ    SCAN4        ;DONE IF EOL
  1207. ;
  1208. ;  SCAN TOKEN FOR DU: FORM, WHICH MEANS WE HAVE A USER/DISK SPECIFICATION
  1209. ;    DE PTS TO NEXT CHAR IN LINE, HL PTS TO FCBDN
  1210. ;
  1211.     PUSH    D        ;SAVE PTR TO FIRST CHAR
  1212.     CALL    SDELM        ;CHECK FOR DELIMITER AND GET FIRST CHAR
  1213.     CPI    'A'        ;IN LETTER RANGE?
  1214.     JRC    SCAN1
  1215.     CPI    'P'+1        ;IN LETTER RANGE?
  1216.     JRC    SCAN1A
  1217. SCAN1:
  1218.     CPI    '0'        ;CHECK FOR DIGIT RANGE
  1219.     JRC    SCAN2
  1220.     CPI    '9'+1        ;IN DIGIT RANGE?
  1221.     JRNC    SCAN2
  1222. SCAN1A:
  1223.     INX    D        ;PT TO NEXT CHAR
  1224.     CALL    SDELM        ;CHECK FOR DELIMITER; IF NOT, CHECK FOR DIGIT
  1225.     JR    SCAN1
  1226. SCAN2:
  1227.     POP    D        ;RESTORE PTR TO FIRST CHAR
  1228.     CPI    ':'        ;WAS DELIMITER A COLON?
  1229.     JRNZ    SCAN3        ;DONE IF NO COLON
  1230.     STA    COLON        ;SET COLON FOUND
  1231. ;
  1232. ;  SCAN FOR AND EXTRACT USER/DISK INFO
  1233. ;    ON ENTRY, HL PTS TO FCBDN, DE PTS TO FIRST CHAR, AND A CONTAINS FIRST CHAR
  1234. ;
  1235.     LDAX    D        ;GET FIRST CHAR
  1236.     CPI    'A'        ;CONVERT POSSIBLE DRIVE SPEC TO NUMBER
  1237.     JRC    SUD1        ;IF LESS THAN 'A', MUST BE DIGIT
  1238. ;
  1239. ;  SET DISK NUMBER (A=1)
  1240. ;
  1241.     SUI    'A'-1        ;CONVERT DRIVE NUMBER TO 1-16
  1242.     CPI    MAXDISK+1    ;WITHIN RANGE?
  1243.     JNC    ERROR        ;INVALID DISK NUMBER
  1244.     STA    TEMPDR        ;SET TEMPORARY DRIVE NUMBER
  1245.     MOV    M,A        ;SET FCBDN
  1246.     INX    D        ;PT TO NEXT CHAR
  1247.     LDAX    D        ;SEE IF IT IS A COLON (:)
  1248.     CPI    ':'
  1249.     JRZ    SUD2        ;DONE IF NO USER NUMBER (IT IS A COLON)
  1250. ;
  1251. ;  SET USER NUMBER
  1252. ;
  1253. SUD1:
  1254.     PUSH    H        ;SAVE PTR TO FCBDN
  1255.     XCHG            ;HL PTS TO FIRST DIGIT
  1256.     CALL    NUM0A        ;GET NUMBER
  1257.     XCHG            ;DE PTS TO TERMINATING COLON
  1258.     POP    H        ;GET PTR TO FCBDN
  1259.     CPI    MAXUSR+1    ;WITHIN LIMIT?
  1260.     JNC    ERROR
  1261. ;
  1262.     IF    USERON        ;ALLOW USER CHANGE ONLY IF USER IS ALLOWED
  1263. ;
  1264.     STA    TEMPUSR        ;SAVE USER NUMBER
  1265. ;
  1266.     ENDIF
  1267. ;
  1268. SUD2:
  1269.     INX    D        ;PT TO CHAR AFTER COLON
  1270. ;
  1271. ; EXTRACT FILENAME FROM POSSIBLE FILENAME.TYP
  1272. ;   DE PTS TO NEXT CHAR TO PROCESS, HL PTS TO FCBDN
  1273. ;
  1274. SCAN3:
  1275.     XRA    A        ;A=0
  1276.     STA    QMCNT        ;INIT COUNT OF NUMBER OF QUESTION MARKS IN FCB
  1277.     MVI    B,8        ;MAX OF 8 CHARS IN FILE NAME
  1278.     CALL    SCANF        ;FILL FCB FILE NAME
  1279. ;
  1280. ; EXTRACT FILE TYPE FROM POSSIBLE FILENAME.TYP
  1281. ;
  1282.     MVI    B,3        ;PREPARE TO EXTRACT TYPE
  1283.     LDAX    D        ;GET LAST CHAR WHICH STOPPED SCAN
  1284.     CPI    '.'        ;IF (DE) DELIMITER IS A '.', WE HAVE A TYPE
  1285.     JRNZ    SCAN4        ;FILL FILE TYPE BYTES WITH <SP>
  1286.     INX    D        ;PT TO CHAR IN COMMAND LINE AFTER '.'
  1287.     CALL    SCANF        ;FILL FCB FILE TYPE
  1288.     JR    SCAN5        ;SKIP TO NEXT PROCESSING
  1289. SCAN4:
  1290.     CALL    SCANF4        ;SPACE FILL
  1291. ;
  1292. ; FILL IN EX, S1, S2, AND RC WITH ZEROES
  1293. ;
  1294. SCAN5:
  1295.     MVI    B,4        ;4 BYTES
  1296.     XRA    A        ;A=0
  1297.     CALL    SCANF5        ;FILL WITH ZEROES
  1298. ;
  1299. ; SCAN COMPLETE -- DE PTS TO DELIMITER BYTE AFTER TOKEN
  1300. ;
  1301.     SDED    NXTCHR
  1302. ;
  1303. ; SET ZERO FLAG TO INDICATE PRESENCE OF '?' IN FILENAME.TYP
  1304. ;
  1305. QMCNT    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  1306.     MVI    A,0        ;NUMBER OF QUESTION MARKS
  1307.     ORA    A        ;SET ZERO FLAG TO INDICATE ANY '?'
  1308.     RET
  1309.  
  1310. ;
  1311. ;  SCANF -- SCAN TOKEN PTED TO BY DE FOR A MAX OF B BYTES; PLACE IT INTO
  1312. ;    FILE NAME FIELD PTED TO BY HL; EXPAND AND INTERPRET WILD CARDS OF
  1313. ;    '*' AND '?'; ON EXIT, DE PTS TO TERMINATING DELIMITER
  1314. ;
  1315. SCANF:
  1316.     CALL    SDELM        ;DONE IF DELIMITER ENCOUNTERED - <SP> FILL
  1317.     JRZ    SCANF4
  1318.     INX    H        ;PT TO NEXT BYTE IN FCBDN
  1319.     CPI    '*'        ;IS (DE) A WILD CARD?
  1320.     JRNZ    SCANF1        ;CONTINUE IF NOT
  1321.     MVI    M,'?'        ;PLACE '?' IN FCB AND DON'T ADVANCE DE IF SO
  1322.     CALL    SCQ        ;SCANNER COUNT QUESTION MARKS
  1323.     JR    SCANF2
  1324. SCANF1:
  1325.     MOV    M,A        ;STORE FILENAME CHAR IN FCB
  1326.     INX    D        ;PT TO NEXT CHAR IN COMMAND LINE
  1327.     CPI    '?'        ;CHECK FOR QUESTION MARK (WILD)
  1328.     CZ    SCQ        ;SCANNER COUNT QUESTION MARKS
  1329. SCANF2:
  1330.     DJNZ    SCANF        ;DECREMENT CHAR COUNT UNTIL 8 ELAPSED
  1331. SCANF3:
  1332.     CALL    SDELM        ;8 CHARS OR MORE - SKIP UNTIL DELIMITER
  1333.     RZ            ;ZERO FLAG SET IF DELIMITER FOUND
  1334.     INX    D        ;PT TO NEXT CHAR IN COMMAND LINE
  1335.     JR    SCANF3
  1336. ;
  1337. ;  FILL MEMORY POINTED TO BY HL WITH SPACES FOR B BYTES
  1338. ;
  1339. SCANF4:
  1340.     MVI    A,' '        ;<SP> FILL
  1341. SCANF5:
  1342.     INX    H        ;PT TO NEXT BYTE IN FCB
  1343.     MOV    M,A        ;FILL WITH BYTE IN A
  1344.     DJNZ    SCANF5
  1345.     RET
  1346. ;
  1347. ;  INCREMENT QUESTION MARK COUNT FOR SCANNER
  1348. ;    THIS ROUTINE INCREMENTS THE COUNT OF THE NUMBER OF QUESTION MARKS IN
  1349. ;    THE CURRENT FCB ENTRY
  1350. ;
  1351. SCQ:
  1352.     PUSH    H        ;SAVE HL
  1353.     LXI    H,QMCNT        ;GET COUNT
  1354.     INR    M        ;INCREMENT
  1355.     POP    H        ;GET HL
  1356.     RET
  1357. ;
  1358. ; CMDTBL (COMMAND TABLE) SCANNER
  1359. ;   ON RETURN, HL PTS TO ADDRESS OF COMMAND IF CPR-RESIDENT
  1360. ;   ON RETURN, ZERO FLAG SET MEANS CPR-RESIDENT COMMAND
  1361. ;
  1362. CMDSER:
  1363.     LXI    H,CMDTBL    ;PT TO COMMAND TABLE
  1364.     MVI    C,NCMNDS    ;SET COMMAND COUNTER
  1365.     MOV    A,C        ;CHECK NUMBER OF COMMANDS
  1366.     ORA    A        ;IF NONE, THEN ABORT
  1367.     JRZ    CMS5
  1368. CMS1:
  1369.     LXI    D,FCBFN     ;PT TO STORED COMMAND NAME
  1370.     MVI    B,NCHARS    ;NUMBER OF CHARS/COMMAND (8 MAX)
  1371. CMS2:
  1372.     LDAX    D        ;COMPARE AGAINST TABLE ENTRY
  1373.     CMP    M
  1374.     JRNZ    CMS3        ;NO MATCH
  1375.     INX    D        ;PT TO NEXT CHAR
  1376.     INX    H
  1377.     DJNZ    CMS2        ;COUNT DOWN
  1378.     LDAX    D        ;NEXT CHAR IN INPUT COMMAND MUST BE <SP>
  1379.     CPI    ' '
  1380.     JRNZ    CMS4
  1381.     RET            ;COMMAND IS CPR-RESIDENT (ZERO FLAG SET)
  1382. CMS3:
  1383.     INX    H        ;SKIP TO NEXT COMMAND TABLE ENTRY
  1384.     DJNZ    CMS3
  1385. CMS4:
  1386.     INX    H        ;SKIP ADDRESS
  1387.     INX    H
  1388.     DCR    C        ;DECREMENT TABLE ENTRY NUMBER
  1389.     JRNZ    CMS1
  1390. CMS5:
  1391.     INR    C        ;CLEAR ZERO FLAG
  1392.     RET            ;COMMAND IS DISK-RESIDENT (ZERO FLAG CLEAR)
  1393. ;
  1394. ;**** Section 5 ****
  1395. ; CPR-Resident Commands
  1396. ;
  1397. ;
  1398. ;Section 5A
  1399. ;Command: DIR
  1400. ;Function:  To display a directory of the files on disk
  1401. ;Forms:
  1402. ;    DIR <afn>    Displays the DIR files
  1403. ;    DIR <afn> S    Displays the SYS files
  1404. ;    DIR <afn> A    Display both DIR and SYS files
  1405. ;Notes:
  1406. ;    The flag SYSFLG defines the letter used to display both DIR and
  1407. ;        SYS files (A in the above Forms section)
  1408. ;    The flag SOFLG defines the letter used to display only the SYS
  1409. ;        files (S in the above Forms section)
  1410. ;    The flag WIDE determines if the file names are spaced further
  1411. ;        apart (WIDE=TRUE) for 80-col screens
  1412. ;    The flag FENCE defines the character used to separate the file
  1413. ;        names
  1414. ;
  1415.     IF    DIRON        ;DIR ENABLED
  1416. ;
  1417. DIR:
  1418.     CALL    SCANLOG        ;EXTRACT POSSIBLE D:FILENAME.TYP TOKEN AND LOG
  1419.     LXI    H,FCBFN     ;MAKE FCB WILD (ALL '?') IF NO FILENAME.TYP
  1420.     MOV    A,M        ;GET FIRST CHAR OF FILENAME.TYP
  1421.     CPI    ' '        ;IF <SP>, ALL WILD
  1422.     CZ    FILLQ
  1423.     CALL    ADVAN        ;LOOK AT NEXT INPUT CHAR
  1424.     MVI    B,80H        ;PREPARE FOR DIR-ONLY SELECTION
  1425.     JRZ    DIRDN        ;THERE IS NO FLAG, SO DIR ONLY
  1426.     MVI    B,1        ;SET FOR BOTH DIR AND SYS FILES
  1427.     CPI    SYSFLG        ;SYSTEM AND DIR FLAG SPECIFIER?
  1428.     JRZ    GOTFLG        ;GOT SYSTEM SPECIFIER
  1429.     CPI    SOFLG        ;SYS ONLY?
  1430.     JRNZ    DIRDN
  1431.     DCR    B        ;B=0 FOR SYS FILES ONLY
  1432. GOTFLG:
  1433.     INX    D        ;PT TO CHAR AFTER FLAG
  1434. DIRDN:
  1435.     SDED    NXTCHR        ;SET PTR FOR NEXT PASS
  1436.                 ;DROP INTO DIRPR TO PRINT DIRECTORY
  1437.                 ; THEN RESTART CPR
  1438. ;
  1439.     ENDIF            ;DIRON
  1440. ;
  1441. ; DIRECTORY PRINT ROUTINE; ON ENTRY, B REG IS SET AS FOLLOWS:
  1442. ;    0 FOR ONLY SYSTEM FILES, 80H FOR ONLY DIR FILES, 1 FOR BOTH
  1443. ;
  1444.     IF    DIRON OR ERAON
  1445. ;
  1446. DIRPR:
  1447.     MOV    A,B        ;GET FLAG
  1448.     STA    SYSTST        ;SET SYSTEM TEST FLAG
  1449.     MVI    E,0        ;SET COLUMN COUNTER TO ZERO
  1450.     PUSH    D        ;SAVE COLUMN COUNTER (E)
  1451.     CALL    SEARF        ;SEARCH FOR SPECIFIED FILE (FIRST OCCURRANCE)
  1452.     JRNZ    DIR3
  1453.     CALL    PRNNF        ;PRINT NO FILE MSG; REG A NOT CHANGED
  1454.     XRA    A        ;SET ZERO FLAG
  1455.     POP    D        ;RESTORE DE
  1456.     RET
  1457. ;
  1458. ; ENTRY SELECTION LOOP; ON ENTRY, A=OFFSET FROM SEARF OR SEARN
  1459. ;
  1460. DIR3:
  1461.     CALL    GETSBIT        ;GET AND TEST FOR TYPE OF FILES
  1462.     JRZ    DIR6
  1463.     POP    D        ;GET ENTRY COUNT (=<CR> COUNTER)
  1464.     MOV    A,E        ;ADD 1 TO IT
  1465.     INR    E
  1466.     PUSH    D        ;SAVE IT
  1467.     ANI    03H        ;OUTPUT <CRLF> IF 4 ENTRIES PRINTED IN LINE
  1468.     JRNZ    DIR4
  1469.     CALL    CRLF        ;NEW LINE
  1470.     JR    DIR5
  1471. DIR4:
  1472.     CALL    PRINT
  1473. ;
  1474.     IF    WIDE
  1475. ;
  1476.     DB    '  '        ;2 SPACES
  1477.     DB    FENCE        ;THEN FENCE CHAR
  1478.     DB    ' ',' '+80H    ;THEN 2 MORE SPACES
  1479. ;
  1480.     ELSE
  1481. ;
  1482.     DB    ' '        ;SPACE
  1483.     DB    FENCE        ;THEN FENCE CHAR
  1484.     DB    ' '+80H        ;THEN SPACE
  1485. ;
  1486.     ENDIF            ;WIDE
  1487. ;
  1488. DIR5:
  1489.     MVI    B,01H        ;PT TO 1ST BYTE OF FILE NAME
  1490.     MOV    A,B        ;A=OFFSET
  1491.     CALL    DIRPTR        ;HL NOW PTS TO 1ST BYTE OF FILE NAME
  1492.     CALL    PRFN        ;PRINT FILE NAME
  1493. DIR6:
  1494.     CALL    BREAK        ;CHECK FOR ABORT
  1495.     JRNZ    DIR7
  1496.     CALL    SEARN        ;SEARCH FOR NEXT FILE
  1497.     JRNZ    DIR3        ;CONTINUE IF FILE FOUND
  1498. DIR7:
  1499.     POP    D        ;RESTORE STACK
  1500.     MVI    A,0FFH        ;SET NZ FLAG
  1501.     ORA    A
  1502.     RET
  1503. ;
  1504.     ENDIF            ;DIRON OR ERAON
  1505. ;
  1506. ;  PRINT FILE NAME PTED TO BY HL
  1507. ;
  1508. PRFN:
  1509.     MVI    B,8    ;8 CHARS
  1510.     CALL    PRFN1
  1511.     MVI    A,'.'    ;DOT
  1512.     CALL    CONOUT
  1513.     MVI    B,3    ;3 CHARS
  1514. PRFN1:
  1515.     MOV    A,M    ; GET CHAR
  1516.     INX    H    ; PT TO NEXT
  1517.     CALL    CONOUT    ; PRINT CHAR
  1518.     DCR    B    ; COUNT DOWN
  1519.     JRNZ    PRFN1
  1520.     RET
  1521. ;
  1522. ; AFTER A SEARCH, RETURN NZ SET IF DESIRED TYPE OF FILE FOUND, Z IF NOT
  1523. ;   THIS ALGORITHM LOOKS AT THE SYSTEM BIT OF THE LOCATED FILE; THIS
  1524. ;   BIT IS SET TO 1 IF THE FILE IS A SYSTEM FILE AND 0 IF NOT A SYSTEM
  1525. ;   FILE.  THE FOLLOWING EXCLUSIVE OR MASKS ARE APPLIED TO RETURN Z OR NZ
  1526. ;   AS REQUIRED BY THE CALLING PROGRAM:
  1527. ;
  1528. ;    SYSTEM BYTE: X 0 0 0  0 0 0 0   (AFTER 80H MASK, X=1 IF SYS, 0 IF DIR)
  1529. ;
  1530. ;    SYS-ONLY   : 0 0 0 0  0 0 0 0   (XOR 0 = 0 if X=0, = 80H if X=1)
  1531. ;    DIR-ONLY   : 1 0 0 0  0 0 0 0   (XOR 80H = 80h if X=0, = 0 if X=1)
  1532. ;    BOTH       : 0 0 0 0  0 0 0 1   (XOR 1 = 81H or 1H, NZ in both cases)
  1533. ;
  1534. GETSBIT:
  1535.     DCR    A        ;ADJUST TO RETURNED VALUE
  1536.     RRC            ;CONVERT NUMBER TO OFFSET INTO TBUFF
  1537.     RRC
  1538.     RRC
  1539.     ANI    60H
  1540.     MOV    C,A        ;OFFSET INTO TBUFF IN C (C=OFFSET TO ENTRY)
  1541.     MVI    A,10        ;ADD 10 TO PT TO SYSTEM FILE ATTRIBUTE BIT
  1542.     CALL    DIRPTR        ;A=SYSTEM BYTE
  1543.     ANI    80H        ;LOOK AT ONLY SYSTEM BIT
  1544. SYSTST    EQU    $+1        ;IN-THE-CODE VARIABLE
  1545.     XRI    0        ; IF SYSTST=0, SYS ONLY; IF SYSTST=80H, DIR
  1546.                 ; ONLY; IF SYSTST=1, BOTH SYS AND DIR
  1547.     RET            ;NZ IF OK, Z IF NOT OK
  1548. ;
  1549. ; FILL FCB @HL WITH '?'
  1550. ;
  1551. FILLQ:
  1552.     MVI    B,11        ;NUMBER OF CHARS IN FN & FT
  1553. FQLP:
  1554.     MVI    M,'?'        ;STORE '?'
  1555.     INX    H
  1556.     DJNZ    FQLP
  1557.     RET
  1558. ;
  1559. ;Section 5B
  1560. ;Command: ERA
  1561. ;Function:  Erase files
  1562. ;Forms:
  1563. ;    ERA <afn>    Erase Specified files and print their names
  1564. ;    ERA <afn> V    Erase Specified files and print their names, but ask
  1565. ;                for verification before Erase is done
  1566. ;Notes:
  1567. ;    Several Key Flags affect this command:
  1568. ;        ERAV - If TRUE, the V option is enabled, and the character
  1569. ;            which turns it on (the V) is defined by ERDFLG
  1570. ;        ERAOK - If TRUE, the OK? prompt is enabled
  1571. ;    If ERAOK is FALSE, the verification feature is disabled regardless
  1572. ;        of what value ERAV has
  1573. ;    If ERAOK is TRUE, then:
  1574. ;        If ERAV is TRUE, verification is requested only if the V
  1575. ;            flag (actual letter defined by ERDFLG) is in the
  1576. ;            command line
  1577. ;        If ERAV is FALSE, verification is always requested, and a
  1578. ;            V flag in the command line will cause an error
  1579. ;            message to be printed (V?) after the ERA is completed
  1580. ;
  1581.     IF    ERAON        ;ERA ENABLED?
  1582. ;
  1583. ERA:
  1584. ;
  1585.     IF    WERA        ;WHEEL FACILITY ENABLED?
  1586. ;
  1587.     CALL    WHLCHK        ;CHECK FOR IT
  1588. ;
  1589.     ENDIF        ;WERA
  1590. ;
  1591.     CALL    SCANLOG        ;PARSE FILE SPECIFICATION AND LOG IN USER/DISK
  1592. ;
  1593.     IF    ERAV AND ERAOK    ;V FLAG AND OK? ENABLED?
  1594. ;
  1595.     CALL    ADVAN        ;GET ERAFLG IF IT'S THERE
  1596.     STA    ERAFLG        ;SAVE IT AS A FLAG
  1597.     JRZ    ERA1        ;JUMP IF INPUT ENDED
  1598.     INX    D        ;PUT NEW BUF POINTER
  1599. ERA1:
  1600.     XCHG            ;PUT PTR IN HL
  1601.     SHLD    NXTCHR        ;SET PTR TO BYTE FOR NEXT COMMAND PROCESSING
  1602. ;
  1603.     ENDIF            ;ERAV
  1604. ;
  1605.     MVI    B,1        ;DISPLAY ALL MATCHING FILES
  1606.     CALL    DIRPR        ;PRINT DIRECTORY OF ERASED FILES
  1607.     RZ            ;ABORT IF NO FILES
  1608. ;
  1609.     IF    ERAOK        ;PRINT PROMPT
  1610. ;
  1611.     IF    ERAV        ;TEST VERIFY FLAG
  1612. ;
  1613. ERAFLG    EQU    $+1        ;ADDRESS OF FLAG
  1614.     MVI    A,0        ;2ND BYTE IS FLAG
  1615.     CPI    ERDFLG        ;IS IT A VERIFY OPTION?
  1616.     JRNZ    ERA2        ;SKIP PROMPT IF IT IS NOT
  1617. ;
  1618.     ENDIF            ;ERAV
  1619. ;
  1620.     CALL    PRINTC
  1621.     DB    'OK to Erase','?'+80H
  1622.     CALL    CONIN        ;GET REPLY
  1623.     CPI    'Y'        ;YES?
  1624.     RNZ            ;ABORT IF NOT
  1625. ;
  1626.     ENDIF            ;ERAOK
  1627. ;
  1628. ERA2:
  1629.     LXI    D,FCBDN     ;DELETE FILE SPECIFIED
  1630.     CALL    DELETE
  1631.     RET            ;REENTER CPR
  1632. ;
  1633.     ENDIF            ;ERAON
  1634. ;
  1635. ;Section 5C
  1636. ;Command: LIST
  1637. ;Function:  Print out specified file on the LST: Device
  1638. ;Forms:
  1639. ;    LIST <ufn>    Print file (NO Paging)
  1640. ;Notes:
  1641. ;    The flags which apply to TYPE do not take effect with LIST
  1642. ;
  1643.     IF    LTON        ;LIST AND TYPE ENABLED?
  1644. ;
  1645. LIST:
  1646.     MVI    A,0FFH        ;TURN ON PRINTER FLAG
  1647.     JR    TYPE0
  1648. ;
  1649. ;Section 5D
  1650. ;Command: TYPE
  1651. ;Function:  Print out specified file on the CON: Device
  1652. ;Forms:
  1653. ;    TYPE <ufn>    Print file
  1654. ;    TYPE <ufn> P    Print file with paging flag    
  1655. ;Notes:
  1656. ;    The flag PGDFLG defines the letter which toggles the paging
  1657. ;        facility (P in the forms section above)
  1658. ;    The flag PGDFLT determines if TYPE is to page by default
  1659. ;        (PGDFLT=TRUE if TYPE pages by default); combined with
  1660. ;        PGDFLG, the following events occur --
  1661. ;            If PGDFLT = TRUE, PGDFLG turns OFF paging
  1662. ;            If PGDFLT = FALSE, PGDFLG turns ON paging
  1663. ;
  1664. TYPE:
  1665.     XRA    A        ;TURN OFF PRINTER FLAG
  1666. ;
  1667. ; ENTRY POINT FOR CPR LIST FUNCTION (LIST)
  1668. ;
  1669. TYPE0:
  1670.     STA    PRFLG        ;SET FLAG
  1671. ;
  1672.     IF    WLT    ;WHEEL ON?
  1673. ;
  1674.     CALL    WHLCHK        ;CHECK WHEEL BYTE
  1675. ;
  1676.     ENDIF        ;WLT
  1677. ;
  1678.     CALL    SCANLOG        ;EXTRACT FILENAME.TYP TOKEN AND LOG USER/DISK
  1679.     JNZ    ERROR        ;ERROR IF ANY QUESTION MARKS
  1680.     CALL    ADVAN        ;GET PGDFLG IF IT'S THERE
  1681.     STA    PGFLG        ;SAVE IT AS A FLAG
  1682.     JRZ    TYPE1        ;JUMP IF INPUT ENDED
  1683.     INX    D        ;PUT NEW BUF POINTER
  1684. TYPE1:
  1685.     SDED    NXTCHR        ;SET PTR TO BYTE FOR NEXT COMMAND PROCESSING
  1686.     CALL    OPENF        ;OPEN SELECTED FILE
  1687.     JZ    ERROR        ;ABORT IF ERROR
  1688.     CALL    CRLF        ;NEW LINE
  1689.     MVI    A,NLINES-1    ;SET LINE COUNT
  1690.     STA    PAGCNT
  1691.     LXI    B,080H        ;SET CHAR POSITION AND TAB COUNT
  1692.                 ;  (B=0=TAB, C=080H=CHAR POSITION)
  1693. ;
  1694. ;  MAIN LOOP FOR LOADING NEXT BLOCK
  1695. ;
  1696. TYPE2:
  1697.     MOV    A,C        ;GET CHAR COUNT
  1698.     CPI    80H
  1699.     JRC    TYPE3
  1700.     PUSH    H        ;READ NEXT BLOCK
  1701.     PUSH    B
  1702.     CALL    READF
  1703.     POP    B
  1704.     POP    H
  1705.     JRNZ    TYPE7        ;ERROR?
  1706.     MVI    C,0        ;SET CHAR COUNT
  1707.     LXI    H,TBUFF        ;PT TO FIRST CHAR
  1708. ;
  1709. ;  MAIN LOOP FOR PRINTING CHARS IN TBUFF
  1710. ;
  1711. TYPE3:
  1712.     MOV    A,M        ;GET NEXT CHAR
  1713.     ANI    7FH        ;MASK OUT MSB
  1714.     CPI    1AH        ;END OF FILE (^Z)?
  1715.     RZ            ;RESTART CPR IF SO
  1716. ;
  1717. ; OUTPUT CHAR TO CON: OR LST: DEVICE WITH TABULATION
  1718. ;
  1719.     CPI    CR        ;RESET TAB COUNT?
  1720.     JRZ    TYPE4
  1721.     CPI    LF        ;RESET TAB COUNT?
  1722.     JRZ    TYPE4
  1723.     CPI    TAB        ;TAB?
  1724.     JRZ    TYPE5
  1725. ;
  1726. ;  OUTPUT CHAR AND INCREMENT CHAR COUNT
  1727. ;
  1728.     CALL    LCOUT        ;OUTPUT CHAR
  1729.     INR    B        ;INCREMENT TAB COUNT
  1730.     JR    TYPE6
  1731. ;
  1732. ;  OUTPUT <CR> OR <LF> AND RESET TAB COUNT
  1733. ;
  1734. TYPE4:
  1735.     CALL    LCOUT        ;OUTPUT <CR> OR <LF>
  1736.     MVI    B,0        ;RESET TAB COUNTER
  1737.     JR    TYPE6
  1738. ;
  1739. ;  TABULATE
  1740. ;
  1741. TYPE5:
  1742.     MVI    A,' '        ;<SP>
  1743.     CALL    LCOUT
  1744.     INR    B        ;INCR POS COUNT
  1745.     MOV    A,B
  1746.     ANI    7
  1747.     JRNZ    TYPE5
  1748. ;
  1749. ; CONTINUE PROCESSING
  1750. ;
  1751. TYPE6:
  1752.     INR    C        ;INCREMENT CHAR COUNT
  1753.     INX    H        ;PT TO NEXT CHAR
  1754.     PUSH    H        ;SAVE REGS
  1755.     PUSH    B
  1756.     CALL    BREAK        ;CHECK FOR ABORT
  1757.     POP    B        ;GET REGS
  1758.     POP    H
  1759.     JRZ    TYPE2        ;CONTINUE IF NO CHAR
  1760.     CPI    'C'-'@'     ;^C?
  1761.     RZ            ;RESTART IF SO
  1762.     JR    TYPE2
  1763. TYPE7:
  1764.     DCR    A        ;NO ERROR?
  1765.     RZ            ;RESTART CPR
  1766.     JMP    ERROR
  1767. ;
  1768.     ENDIF            ;LTON
  1769. ;
  1770. ;Section 5E
  1771. ;Command: SAVE
  1772. ;Function:  To save the contents of the TPA onto disk as a file
  1773. ;Forms:
  1774. ;    SAVE <Number of Pages> <ufn>
  1775. ;                Save specified number of pages (start at 100H)
  1776. ;                from TPA into specified file; <Number of
  1777. ;                Pages> is in DEC
  1778. ;    SAVE <Number of Sectors> <ufn> S
  1779. ;                Like SAVE above, but numeric argument specifies
  1780. ;                number of sectors rather than pages
  1781. ;Notes:
  1782. ;    The MULTCMD flag (Multiple Commands Allowed) expands the code slightly,
  1783. ;        but is required to support multiple commands with SAVE
  1784. ;    The SECTFLG defines the letter which indicates a sector count
  1785. ;        (S in the Forms section above)
  1786. ;
  1787.     IF    SAVEON        ;SAVE ENABLED?
  1788. ;
  1789. SAVE:
  1790. ;
  1791.     IF    WSAVE    ;WHEEL FACILITY?
  1792. ;
  1793.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  1794. ;
  1795.     ENDIF        ;WSAVE
  1796. ;
  1797.     CALL    NUMBER        ;EXTRACT NUMBER FROM COMMAND LINE
  1798.     MOV    L,A        ;HL=PAGE COUNT
  1799.     MVI    H,0
  1800.     PUSH    H        ;SAVE PAGE COUNT
  1801.     CALL    EXTEST        ;TEST FOR EXISTENCE OF FILE AND ABORT IF SO
  1802.     MVI    C,16H        ;BDOS MAKE FILE
  1803.     CALL    GRBDOS
  1804.     POP    H        ;GET PAGE COUNT
  1805.     JRZ    SAVE3        ;ERROR?
  1806.     XRA    A        ;SET RECORD COUNT FIELD OF NEW FILE'S FCB
  1807.     STA    FCBCR
  1808.     CALL    ADVAN        ;LOOK FOR 'S' FOR SECTOR OPTION
  1809.     INX    D        ;PT TO AFTER 'S' TOKEN
  1810.     CPI    SECTFLG
  1811.     JRZ    SAVE0
  1812.     DCX    D        ;NO 'S' TOKEN, SO BACK UP
  1813.     DAD    H        ;DOUBLE IT FOR HL=SECTOR (128 BYTES) COUNT
  1814. SAVE0:
  1815.     SDED    NXTCHR        ;SET PTR TO BAD TOKEN OR AFTER GOOD TOKEN
  1816.     LXI    D,TPA        ;PT TO START OF SAVE AREA (TPA)
  1817. SAVE1:
  1818.     MOV    A,H        ;DONE WITH SAVE?
  1819.     ORA    L        ;HL=0 IF SO
  1820.     JRZ    SAVE2
  1821.     DCX    H        ;COUNT DOWN ON SECTORS
  1822.     PUSH    H        ;SAVE PTR TO BLOCK TO SAVE
  1823.     LXI    H,128        ;128 BYTES PER SECTOR
  1824.     DAD    D        ;PT TO NEXT SECTOR
  1825.     PUSH    H        ;SAVE ON STACK
  1826.     CALL    DMASET        ;SET DMA ADDRESS FOR WRITE (ADDRESS IN DE)
  1827.     LXI    D,FCBDN     ;WRITE SECTOR
  1828.     MVI    C,15H        ;BDOS WRITE SECTOR
  1829.     CALL    BDOSB        ;SAVE BC
  1830.     POP    D        ;GET PTR TO NEXT SECTOR IN DE
  1831.     POP    H        ;GET SECTOR COUNT
  1832.     JRNZ    SAVE3        ;WRITE ERROR?
  1833.     JR    SAVE1        ;CONTINUE
  1834. SAVE2:
  1835.     LXI    D,FCBDN     ;CLOSE SAVED FILE
  1836.     CALL    CLOSE
  1837.     INR    A        ;ERROR?
  1838.     JRNZ    SAVE4
  1839. SAVE3:
  1840.     CALL    PRNLE        ;PRINT 'NO SPACE' ERROR
  1841. SAVE4:
  1842.     JMP    DEFDMA        ;SET DMA TO 0080 AND RESTART CPR
  1843. ;
  1844.     ENDIF            ;SAVEON
  1845. ;
  1846. ; Test File in FCB for existence, ask user to delete if so, and abort if he
  1847. ;  choses not to
  1848. ;
  1849.     IF    SAVEON OR RENON    ;FOR SAVE AND REN FUNCTIONS
  1850. ;
  1851. EXTEST:
  1852.     CALL    SCANLOG        ;EXTRACT FILE NAME AND LOG IN USER/DISK
  1853.     JNZ    ERROR        ;'?' IS NOT PERMITTED
  1854.     CALL    SEARF        ;LOOK FOR SPECIFIED FILE
  1855.     LXI    D,FCBDN        ;PT TO FILE FCB
  1856.     RZ            ;OK IF NOT FOUND
  1857.     PUSH    D        ;SAVE PTR TO FCB
  1858.     CALL    PRINTC
  1859.     DB    'Erase',' '+80H
  1860.     LXI    H,FCBFN        ;PT TO FILE NAME FIELD
  1861.     CALL    PRFN        ;PRINT IT
  1862.     MVI    A,'?'        ;PRINT QUESTION
  1863.     CALL    CONOUT
  1864.     CALL    CONIN        ;GET RESPONSE
  1865.     POP    D        ;GET PTR TO FCB
  1866.     CPI    'Y'        ;KEY ON YES
  1867.     JNZ    ERR3        ;RESTART AS ERROR IF NO
  1868.     PUSH    D        ;SAVE PTR TO FCB
  1869.     CALL    DELETE        ;DELETE FILE
  1870.     POP    D        ;GET PTR TO FCB
  1871.     RET
  1872. ;
  1873.     ENDIF            ;SAVEON OR RENON
  1874. ;
  1875. ;Section 5F
  1876. ;Command: REN
  1877. ;Function:  To change the name of an existing file
  1878. ;Forms:
  1879. ;    REN <New ufn>=<Old ufn>    Perform function
  1880. ;
  1881.     IF    RENON        ;REN ENABLED?
  1882. ;
  1883. REN:
  1884. ;
  1885.     IF    WREN        ;WHEEL FACILITY?
  1886. ;
  1887.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  1888. ;
  1889.     ENDIF        ;WREN
  1890. ;
  1891.     CALL    EXTEST        ;TEST FOR FILE EXISTENCE AND RETURN
  1892.                 ; IF FILE DOESN'T EXIST; ABORT IF IT DOES
  1893.     LDA    TEMPDR        ;SAVE SELECTED DISK
  1894.     PUSH    PSW        ;SAVE ON STACK
  1895. REN0:
  1896.     LXI    H,FCBDN     ;SAVE NEW FILE NAME
  1897.     LXI    D,FCBDM
  1898.     LXI    B,16        ;16 BYTES
  1899.     LDIR
  1900.     CALL    ADVAN        ;ADVANCE TO NEXT CHARACTER (NON-DELIM)
  1901.     JRZ    REN4        ;ERROR IF NONE
  1902. ;
  1903. ;  PERFORM RENAME FUNCTION
  1904. ;
  1905. REN1:
  1906.     SDED    NXTCHR        ;SAVE PTR TO OLD FILE NAME
  1907.     CALL    SCANER        ;EXTRACT FILENAME.TYP TOKEN
  1908.     JRNZ    REN4        ;ERROR IF ANY '?'
  1909.     POP    PSW        ;GET OLD DEFAULT DRIVE
  1910.     MOV    B,A        ;SAVE IT
  1911.     LXI    H,TEMPDR    ;COMPARE IT AGAINST SELECTED DRIVE
  1912.     MOV    A,M        ;DEFAULT?
  1913.     ORA    A
  1914.     JRZ    REN2
  1915.     CMP    B        ;CHECK FOR DRIVE ERROR (LIKE REN A:T=B:S)
  1916.     JRNZ    REN4
  1917. REN2:
  1918.     MOV    M,B
  1919.     XRA    A
  1920.     STA    FCBDN        ;SET DEFAULT DRIVE
  1921.     LXI    D,FCBDN     ;RENAME FILE
  1922.     MVI    C,17H        ;BDOS RENAME FCT
  1923.     CALL    GRBDOS
  1924.     RNZ
  1925. REN3:
  1926.     CALL    PRNNF        ;PRINT NO FILE MSG
  1927. REN4:
  1928.     JMP    ERROR
  1929. ;
  1930.     ENDIF            ;RENON
  1931. ;
  1932. RSTJMP:
  1933.     JMP    RCPRNL        ;RESTART CPR
  1934. ;
  1935. ;Section 5G
  1936. ;Command: JUMP
  1937. ;Function:  To Call the program (subroutine) at the specified address
  1938. ;         without loading from disk
  1939. ;Forms:
  1940. ;    JUMP <adr>        Call at <adr>;<adr> is in HEX
  1941. ;
  1942.     IF    JUMPON        ;JUMP ENABLED?
  1943. ;
  1944. JUMP:
  1945. ;
  1946.     IF    WJUMP    ;WHEEL FACILITY?
  1947. ;
  1948.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  1949. ;
  1950.     ENDIF        ;WJUMP
  1951. ;
  1952.     CALL    HEXNUM        ;GET LOAD ADDRESS IN HL
  1953.     JR    CALLPROG    ;PERFORM CALL
  1954. ;
  1955.     ENDIF            ;JUMPON
  1956. ;
  1957. ;Section 5H
  1958. ;Command: GO
  1959. ;Function:  To Call the program in the TPA without loading
  1960. ;         loading from disk. Same as JUMP 100H, but much
  1961. ;         more convenient, especially when used with
  1962. ;         parameters for programs like STAT. Also can be
  1963. ;         allowed on remote-access systems with no problems.
  1964. ;
  1965. ;Form:
  1966. ;    GO <parameters like for COMMAND>
  1967. ;
  1968.     IF    GOON        ;GO ENABLED?
  1969. ;
  1970. GO:
  1971. ;
  1972.     IF    WGO    ;WHEEL FACILITY?
  1973. ;
  1974.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  1975. ;
  1976.     ENDIF        ;WGO
  1977. ;
  1978.     LXI    H,TPA        ;Always to TPA
  1979.     JR    CALLPROG    ;Perform call
  1980. ;
  1981.     ENDIF            ;GOON
  1982. ;
  1983. ;Section 5I
  1984. ;Command: COM file processing
  1985. ;Function:  To load the specified COM file from disk and execute it
  1986. ;Forms:  <command line>
  1987. ;Notes:
  1988. ;    COM files are processed as follows --
  1989. ;        1. File name buffers are initialized and a preliminary
  1990. ;            error check is done
  1991. ;        2. MLOAD is used to search for the file along the Path
  1992. ;            and load it into the TPA
  1993. ;        3. CALLPROG is used to set up the buffers to be used by
  1994. ;            the transient (FCB at 5CH, FCB at 6CH, BUFF at 80H)
  1995. ;            and run the program
  1996. ;    The flag MULTCMD comes into play frequently here; it mainly serves
  1997. ;        to save space if MULTCMD is FALSE and enables Multiple
  1998. ;        Commands on the same line if MULTCMD is TRUE
  1999. ;
  2000. COM:
  2001.     LDA    FCBFN        ;ANY COMMAND?
  2002.     CPI    ' '        ;' ' MEANS COMMAND WAS 'D:' TO SWITCH
  2003.     JRNZ    COM1        ;NOT <SP>, SO MUST BE TRANSIENT OR ERROR
  2004. ;
  2005. ;  ENTRY POINT TO SELECT USER/DISK
  2006. ;
  2007. ;
  2008.     IF    WDU    ;WHEEL FACILITY?
  2009. ;
  2010.     CALL    WHLCHK        ;CHECK FOR WHEEL BYTE
  2011. ;
  2012.     ENDIF        ;WDU
  2013. ;
  2014.     LDA    COLON        ;LOOK FOR COLON FLAG
  2015.     ORA    A        ;IF ZERO, JUST BLANK
  2016.     RZ            ;RETURN TO MAIN ROUTINE IF NOTHING SPECIFIED
  2017. ;
  2018. ;  COMMAND IS DU:, SO LOG IN USER/DISK
  2019. ;
  2020.     LDA    TEMPUSR        ;GET SELECTED USER
  2021.     CPI    10H        ;MAKE SURE 4 BITS
  2022.     JNC    ERROR        ;RANGE ERROR?
  2023.     STA    CURUSR        ;SET CURRENT USER
  2024.     CALL    SLOGIN        ;LOG IN USER/DISK AS IF TEMPORARILY
  2025. ;
  2026. ;  NOW, MAKE LOGIN PERMANENT
  2027. ;
  2028.     LDA    TEMPDR        ;GET SELECTED DRIVE
  2029.     ORA    A        ;IF 0 (DEFAULT), NO CHANGE
  2030.     JRZ    COM0
  2031.     DCR    A        ;ADJUST FOR LOG IN
  2032.     STA    CURDR        ;SET CURRENT DRIVE
  2033. COM0:
  2034.     JMP    SETUD        ;SET CURRENT USER/DISK AND RET THRU DLOGIN
  2035. ;
  2036. ;  PROCESS COMMAND
  2037. ;
  2038. COM1:
  2039.     LXI    D,FCBFT        ;PT TO FILE TYPE
  2040.     LDAX    D        ;GET FIRST CHAR OF FILE TYPE
  2041.     CPI    ' '        ;MUST BE BLANK, OR ERROR
  2042.     JNZ    ERROR
  2043.     LXI    H,COMMSG    ;PLACE DEFAULT FILE TYPE (COM) INTO FCB
  2044.     LXI    B,3        ;3 BYTES
  2045.     LDIR
  2046.     LXI    H,TPA        ;SET EXECUTION/LOAD ADDRESS
  2047.     PUSH    H        ;SAVE FOR EXECUTION
  2048. ;
  2049.     IF    CMDRUN        ;COMMAND RUN FACILITY AVAILABLE?
  2050. ;
  2051.     MVI    A,0FFH        ;USE IT IF AVAILABLE
  2052. ;
  2053.     ENDIF        ;CMDRUN
  2054. ;
  2055.     CALL    MLOAD        ;LOAD MEMORY WITH FILE SPECIFIED IN CMD LINE
  2056.     POP    H        ;GET EXECUTION ADDRESS
  2057. ;
  2058. ; CALLPROG IS THE ENTRY POINT FOR THE EXECUTION OF THE LOADED
  2059. ;   PROGRAM; ON ENTRY TO THIS ROUTINE, HL MUST CONTAIN THE EXECUTION
  2060. ;   ADDRESS OF THE PROGRAM (SUBROUTINE) TO EXECUTE
  2061. ;
  2062. CALLPROG:
  2063.     SHLD    EXECADR        ;PERFORM IN-LINE CODE MODIFICATION
  2064.     CALL    SCANER        ;SEARCH COMMAND LINE FOR NEXT TOKEN
  2065.     LXI    H,TEMPDR    ;SAVE PTR TO DRIVE SPEC
  2066.     PUSH    H
  2067.     MOV    A,M        ;SET DRIVE SPEC
  2068.     STA    FCBDN
  2069.     LXI    H,FCBDN+10H    ;PT TO 2ND FILE NAME
  2070.     CALL    SCANX        ;SCAN FOR IT AND LOAD IT INTO FCB+16
  2071.     POP    H        ;SET UP DRIVE SPECS
  2072.     MOV    A,M
  2073.     STA    FCBDM
  2074.     XRA    A
  2075.     STA    FCBCR
  2076.     LXI    D,TFCB        ;COPY TO DEFAULT FCB
  2077.     LXI    H,FCBDN     ;FROM FCBDN
  2078.     LXI    B,33        ;SET UP DEFAULT FCB
  2079.     LDIR
  2080. CMDCH1    EQU    $+1        ;IN-THE-CODE BUFFER FOR ADDRESS OF 1ST CHAR
  2081.     LXI    H,CMDLIN
  2082. CALLP1:
  2083.     MOV    A,M        ;SKIP TO END OF 2ND FILE NAME
  2084.     ORA    A        ;END OF LINE?
  2085.     JRZ    CALLP2
  2086. ;
  2087.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  2088. ;
  2089.     CPI    CMDSEP        ;COMMAND SEPARATOR?
  2090.     JRZ    CALLP2
  2091. ;
  2092.     ENDIF        ;MULTCMD
  2093. ;
  2094.     CPI    ' '        ;END OF TOKEN?
  2095.     JRZ    CALLP2
  2096.     INX    H
  2097.     JR    CALLP1
  2098. ;
  2099. ; LOAD COMMAND LINE INTO TBUFF
  2100. ;
  2101. CALLP2:
  2102.     MVI    B,0        ;SET CHAR COUNT
  2103.     LXI    D,TBUFF+1    ;PT TO CHAR POS
  2104. CALLP3:
  2105.     MOV    A,M        ;COPY COMMAND LINE TO TBUFF
  2106.     STAX    D
  2107.     ORA    A        ;DONE IF ZERO
  2108.     JRZ    CALLP5
  2109. ;
  2110.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  2111. ;
  2112.     CPI    CMDSEP        ;DONE IF COMMAND SEPARATOR
  2113.     JRZ    CALLP4
  2114. ;
  2115.     ENDIF        ;MULTCMD
  2116. ;
  2117.     INR    B        ;INCR CHAR COUNT
  2118.     INX    H        ;PT TO NEXT
  2119.     INX    D
  2120.     JR    CALLP3
  2121. ;
  2122.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  2123. ;
  2124. CALLP4:
  2125.     XRA    A        ;STORE ENDING ZERO
  2126.     STAX    D        ;INSTEAD OF CMDSEP
  2127. ;
  2128.     ENDIF        ;MULTCMD
  2129. ;
  2130. ; RUN LOADED TRANSIENT PROGRAM
  2131. ;
  2132. CALLP5:
  2133. ;
  2134.     IF    MULTCMD        ;MULTIPLE COMMANDS ALLOWED?
  2135. ;
  2136.     SHLD    NXTCHR        ;SAVE PTR TO CONTINUE PROCESSING
  2137. ;
  2138.     ENDIF        ;MULTCMD
  2139. ;
  2140.     MOV    A,B        ;SAVE CHAR COUNT
  2141.     STA    TBUFF
  2142.     CALL    CRLF        ;NEW LINE
  2143.     CALL    DEFDMA        ;SET DMA TO 0080
  2144. ;
  2145. ; EXECUTION (CALL) OF PROGRAM (SUBROUTINE) OCCURS HERE
  2146. ;
  2147. EXECADR    EQU    $+1        ;CHANGE ADDRESS FOR IN-LINE CODE MODIFICATION
  2148.     CALL    TPA        ;CALL TRANSIENT
  2149.     CALL    DEFDMA        ;SET DMA TO 0080, IN CASE PROG CHANGED IT
  2150.     CALL    DLOGIN        ;LOGIN CURRENT USER/DISK
  2151.     JMP    CONT        ;RESTART CPR AND CONTINUE COMMAND PROCESSING
  2152. ;
  2153. ;Section 5J
  2154. ;Command: GET
  2155. ;Function:  To load the specified file from disk to the specified address
  2156. ;Forms:
  2157. ;    GET <adr> <ufn>    Load the specified file at the specified page;
  2158. ;            <adr> is in HEX
  2159. ;
  2160.     IF    GETON        ;GET ENABLED?
  2161. ;
  2162. GET:
  2163. ;
  2164.     IF    WGET    ;WHEEL ON?
  2165. ;
  2166.     CALL    WHLCHK        ;CHECK WHEEL BYTE
  2167. ;
  2168.     ENDIF        ;WGET
  2169. ;
  2170.     CALL    HEXNUM        ;GET LOAD ADDRESS IN HL
  2171.     PUSH    H        ;SAVE ADDRESS
  2172.     CALL    SCANER        ;GET FILE NAME
  2173.     POP    H        ;RESTORE ADDRESS
  2174.     JNZ    ERROR        ;MUST BE UNAMBIGUOUS
  2175. ;
  2176. ; FALL THRU TO MLOAD
  2177. ;
  2178.     IF    CMDRUN        ;COMMAND RUN FACILITY AVAILABLE?
  2179. ;
  2180.     XRA    A        ;NO CMDRUN IF FACILITY IS THERE
  2181. ;
  2182.     ENDIF            ;CMDRUN
  2183. ;
  2184.     ENDIF            ;GETON
  2185.  
  2186. ;
  2187. ;  MEMORY LOAD SUBROUTINE
  2188. ;
  2189. ; LOAD MEMORY WITH THE FILE WHOSE NAME IS SPECIFIED IN THE COMMAND LINE
  2190. ;   ON INPUT, HL CONTAINS STARTING ADDRESS TO LOAD
  2191. ;
  2192. ;    EXIT POINTS ARE A RETURN AND LOG IN CURRENT USER/DISK IF NO ERROR,
  2193. ; A JMP TO ERROR IF COM FILE NOT FOUND OR A MESSAGE AND ABORT IF MEMORY FULL
  2194. ;
  2195. MLOAD:
  2196. ;
  2197.     IF    CMDRUN    ;CMDRUN FACILITY?
  2198. ;
  2199.     STA    CRFLAG    ;SAVE FLAG
  2200. ;
  2201.     ENDIF        ;CMDRUN
  2202. ;
  2203.     SHLD    LOADADR        ;SET LOAD ADDRESS
  2204. ;
  2205. ;   MLA is a reentry point for a non-standard CP/M Modification
  2206. ; The PATH command-search is implemented by this routine
  2207. ;
  2208. MLA:
  2209. ;
  2210.     IF    DRVPREFIX    ;IF DRIVE PREFIX ALLOWED ...
  2211. ;
  2212.     MVI    A,DRVPFATT    ;SET FLAG PER USER SPEC FOR SYS/NON-SYS
  2213.     STA    SYSTST        ;TEST FLAG IN GETSBIT
  2214.     CALL    SLOGIN        ;LOOK UNDER TEMPORARY USER/DISK
  2215.     CALL    SEARF        ;LOOK FOR FILE
  2216. MLARUN:
  2217.     LXI    H,PATH        ;PT TO PATH FOR FAILURE POSSIBILITY
  2218.     JRNZ    MLA4        ;FOUND IT -- LOAD IT AND RUN
  2219. ;
  2220.     ELSE            ;NO DRIVE PREFIX
  2221. ;
  2222. MLARUN:
  2223.     LXI    H,PATH        ;POINT TO PATH
  2224. ;
  2225.     ENDIF        ;DRVPREFIX
  2226. ;
  2227. MLA0:
  2228.     MOV    A,M        ;GET DRIVE
  2229.     ORA    A        ;0=DONE=COMMAND NOT FOUND
  2230. ;
  2231.     IF    CMDRUN        ;COMMAND RUN FACILITY
  2232. ;
  2233.     JRNZ    NOCRUN        ;NOT READY FOR CMD RUN YET
  2234. CRFLAG    EQU    $+1        ;POINTER FOR IN-THE-CODE MODIFICATION
  2235.     MVI    A,0        ;CHECK CRFLAG
  2236.     ORA    A        ;0=NO
  2237.     JZ    ERROR        ;PROCESS AS ERROR IF CMD RUN EXHAUSTED
  2238. ;
  2239.     IF    ROOTONLY    ;ONLY LOOK FOR EXT COMMAND PROCESSOR AT ROOT
  2240. ;
  2241.     PUSH    H
  2242. ;
  2243.     ENDIF        ;ROOTONLY
  2244. ;
  2245.     XRA    A        ;DO NOT REENTER THIS CODE
  2246.     STA    CRFLAG        ;SET ZERO FOR NO ENTRY
  2247.     LHLD    CMDCH1        ;GET PTR TO FIRST CHAR OF COMMAND
  2248.     DCX    H        ;PT TO CHAR COUNT
  2249.     MVI    M,' '        ;STORE LEADING SPACE
  2250.     SHLD    CMDCH1        ;POINT TO LEADING SPACE AS FIRST CHAR
  2251.     SHLD    NXTCHR        ;NEXT CHAR IS FIRST CHAR OF COMMAND
  2252.     LXI    H,CFCB        ;SET CFCB AS COMMAND
  2253.     LXI    D,FCBDN        ;... BY COPYING IT INTO FCBDN
  2254.     LXI    B,12        ;ONLY 12 BYTES REQUIRED
  2255.     LDIR
  2256. ;
  2257.     IF    ROOTONLY    ;LOOK FOR EXT COMMAND PROCESSOR AT ROOT ONLY?
  2258. ;
  2259.     JR    MLA3RT
  2260. ;
  2261.     ELSE            ;FOLLOW PATH LOOKING FOR EXT COMMAND PROCESSOR
  2262. ;
  2263.     XRA    A        ;A=0
  2264.     JR    MLARUN        ;NOW TRY THE RUN
  2265. ;
  2266.     ENDIF        ;ROOTONLY
  2267. ;
  2268. CFCB:
  2269.     CMDFCB            ;FCB DEFINING INITIAL COMMAND
  2270. NOCRUN:
  2271. ;
  2272.     ELSE
  2273. ;
  2274.     JZ    ERROR        ;TRANSIENT LOAD ERROR -- FILE NOT FOUND
  2275. ;
  2276.     ENDIF        ;CMDRUN
  2277. ;
  2278. ; LOOK FOR COMMAND IN DIRECTORY PTED TO BY HL; DRIVE IN A
  2279. ;
  2280.     CPI    CURIND        ;CURRENT DRIVE SPECIFIED?
  2281.     JRNZ    MLA1        ;SKIP DEFAULT DRIVE SELECTION IF SO
  2282.     LDA    CURDR        ;GET CURRENT DRIVE
  2283.     INR    A        ;SET A=1
  2284. MLA1:
  2285.     STA    TEMPDR        ;SELECT DIFFERENT DRIVE IF NOT CURRENT
  2286.     MVI    A,1        ;PREPARE TO ACCEPT BOTH SYSTEM AND DIR FILES
  2287.     STA    SYSTST        ;TEST FLAG IS 1 FOR BOTH
  2288.     INX    H        ;PT TO USER NUMBER
  2289.     MOV    A,M        ;GET USER NUMBER
  2290.     INX    H        ;PT TO NEXT ENTRY IN PATH
  2291.     PUSH    H        ;SAVE PTR
  2292.     ANI    7FH        ;MASK OUT SYSTEM BIT
  2293.     CPI    CURIND        ;CURRENT USER SPECIFIED?
  2294.     JRNZ    MLA2        ;DO NOT SELECT CURRENT USER IF SO
  2295.     LDA    CURUSR        ;GET CURRENT USER NUMBER
  2296. MLA2:
  2297.     STA    TEMPUSR        ;SET TEMPORARY USER NUMBER
  2298.     CMA            ;FLIP BITS SO SYSTEM BIT IS 0 IF SYS-ONLY
  2299.     ANI    80H        ;MASK FOR ONLY NOT OF SYSTEM BIT TO SHOW
  2300.     JRNZ    MLA3        ;DON'T SET FLAG IS ORIGINALLY SYSTEM BIT=0
  2301.     STA    SYSTST        ;TEST FLAG IS 0 FOR SYS-ONLY, 1 FOR BOTH
  2302. MLA3:
  2303.     CALL    SLOGIN        ;LOG IN PATH-SPECIFIED USER/DISK
  2304. MLA3RT:
  2305.     CALL    SEARF        ;LOOK FOR FILE
  2306.     POP    H        ;GET PTR TO NEXT PATH ENTRY
  2307.     JRZ    MLA0        ;CONTINUE PATH SEARCH IF SEARCH FAILED
  2308.                 ;LOAD IF SEARCH SUCCEEDED
  2309. ;
  2310. ; FILE FOUND -- PERFORM SYSTEM TEST AND PROCEED IF APPROVED
  2311. ;
  2312. MLA4:
  2313.     PUSH    H        ;SAVE PTR
  2314.     CALL    GETSBIT        ;CHECK SYSTEM BIT
  2315.     POP    H        ;GET PTR
  2316.     JRZ    MLA0        ;CONTINUE IF NO MATCH
  2317.     CALL    OPENF        ;OPEN FILE FOR INPUT
  2318. LOADADR    EQU    $+1        ;MEMORY LOAD ADDRESS (IN-LINE CODE MOD)
  2319.     LXI    H,TPA        ;SET START ADDRESS OF MEMORY LOAD
  2320. MLA5:
  2321.     MVI    A,ENTRY/256-1    ;GET HIGH-ORDER ADR OF JUST BELOW CPR
  2322.     CMP    H        ;ARE WE GOING TO OVERWRITE THE CPR?
  2323.     JRC    PRNLE        ;ERROR IF SO
  2324.     PUSH    H        ;SAVE ADDRESS OF NEXT SECTOR
  2325.     XCHG            ;... IN DE
  2326.     CALL    DMASET        ;SET DMA ADDRESS FOR LOAD
  2327.     LXI    D,FCBDN     ;READ NEXT SECTOR
  2328.     CALL    READ
  2329.     POP    H        ;GET ADDRESS OF NEXT SECTOR
  2330.     JRNZ    MLA6        ;READ ERROR OR EOF?
  2331.     LXI    D,128        ;MOVE 128 BYTES PER SECTOR
  2332.     DAD    D        ;PT TO NEXT SECTOR IN HL
  2333.     JR    MLA5
  2334. ;
  2335. MLA6:
  2336.     DCR    A        ;LOAD COMPLETE
  2337.     JZ    DLOGIN        ;OK IF ZERO, ELSE FALL THRU TO PRNLE
  2338.  
  2339. ;
  2340. ; LOAD ERROR
  2341. ;
  2342. PRNLE:
  2343.     CALL    PRINTC
  2344.     DB    'Ful','l'+80H
  2345.     CALL    DLOGIN        ;RESTORE CURRENT USER/DISK
  2346.     JMP    RESTRT        ;RESTART ZCPR
  2347.  
  2348. ;*****
  2349.  
  2350. ;
  2351. ;  DEFAULT PATH USED FOR PATH COMMAND-SEARCH
  2352. ;
  2353.     IF    INTPATH        ;USE THIS PATH?
  2354. ;
  2355. PATH:
  2356.     IPATH            ;PATH DEFINED IN ZCPRHDR.LIB
  2357. ;
  2358.     ENDIF        ;INTPATH
  2359.  
  2360. ;*****
  2361.     IF    INTSTACK    ;INTERNAL STACK
  2362. ;
  2363. ;  STACK AREA
  2364. ;
  2365.     DS    48        ;STACK AREA
  2366. STACK    EQU    $        ;TOP OF STACK
  2367. ;
  2368.     ENDIF        ;INTSTACK
  2369. ;
  2370.  
  2371. ;
  2372. ;    The following will cause an error message to appear if
  2373. ; the size of ZCPR2 is over 2K bytes.
  2374. ;
  2375.     IF    ($ GT CPRLOC+800H)
  2376. ZCPR2ER    EQU    NOVALUE        ;ZCPR2 IS LARGER THAN 2K BYTES
  2377.     ENDIF
  2378.  
  2379.     END
  2380.