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 / ZCPR2-OZ.ARK / ZCPR2.ASM < prev    next >
Assembly Source File  |  1985-02-09  |  57KB  |  2,397 lines

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