home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / p / p2dos11.lbr / ZCPR2.MZC / ZCPR2.MAC
Encoding:
Text File  |  1993-10-25  |  55.0 KB  |  2,305 lines

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