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 / ZCPR8080.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  58KB  |  2,351 lines

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