home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / ZCPR2 / ZCPR.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  57KB  |  2,373 lines

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