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 / DEMON / ZCPR-D-J.COM / ZCPR.MAC < prev    next >
Text File  |  1979-11-30  |  51KB  |  1,980 lines

  1.     TITLE    ZCPR Console Command Processor - Version D&J
  2.     SUBTTL    Last Modified: 5 March 1994
  3. ;
  4. ;  CP/M Z80 Command Processor Replacement (CPR) Version 1.0
  5. ;    CCPZ CREATED AND CUSTOMIZED FOR ARIES-II BY RLC
  6. ;    FURTHER MODIFIED BY RGF AS V2.0
  7. ;    FURTHER MODIFIED BY RLC AS V2.1
  8. ;    FURTHER MODIFIED BY KBP AS V2.2
  9. ;    FURTHER MODIFIED BY RLC AS V2.4 (V2.3 skipped)
  10. ;    FURTHER MODIFIED BY RLC AS V2.5
  11. ;    FURTHER MODIFIED BY RLC AS V2.6
  12. ;    FURTHER MODIFIED BY SBB AS V2.7
  13. ;    FURTHER MODIFIED BY RLC AS V2.8
  14. ;    FURTHER MODIFIED BY RLC AS V2.9
  15. ;    FURTHER MODIFIED BY RLC AS V3.0
  16. ;    FURTHER MODIFIED BY RLC AS V3.1
  17. ;    FURTHER MODIFIED BY RLC AS V4.0
  18. ;    ZCPR VERSION 1.0 CREATED FROM CCPZ VERSION 4.0 BY RLC IN
  19. ;        A COORDINATED EFFORT WITH CCP-GROUP
  20. ;    FURTHER MODIFIED BY SBB (AS CCPZ-V4.1 11/27/81)
  21. ;    & MORE MODS BY ROBERT FISHER (CA. 12/1/81)
  22. ;    [RETROFITTED TO ZCPR BY BEN BRONSON (12/22/81) AS ZCPR-BB]
  23. ;
  24. ;    FURTHER MODIFIED BY DCK AS Version D&J
  25. ;
  26. ;    ZCPR is a group effort by CCP-GROUP, whose active membership involved
  27. ; in this project consists of the following:
  28. ;        RLC - Richard Conn
  29. ;        RGF - Ron Fowler
  30. ;        KBP - Keith Peterson
  31. ;        FJW - Frank Wancho
  32. ;    The following individual also provided a contribution:
  33. ;        SBB - Steve Bogolub
  34. ;
  35. ; (Note by BB: SBB's and R Fisher's changes came too late in the 
  36. ;  history of CCPZ to be included in the first release of ZCPR)
  37. ;
  38. ;    Extensive modifications to add ERAQ, DIR for all usrnum,
  39. ; LIST x.x P, and fix TYPE when FF encountered was done by Don
  40. ; Kirkpatrick, 20 September 1986.
  41. ;
  42. ;        DCK - Don Kirkpatrick
  43. ;
  44. ; Further modified for better polling during LIST/TYPE, 16 July 1987.
  45. ;
  46. ; Further modified to include boot command and to permit multiple
  47. ; commands per line. Fixed bug in jump. Modified type so character
  48. ; is not echoed, 4 July 1988.
  49. ;
  50. ; Modified to add PAGE command 31 December 1989.
  51. ;
  52. ; Added BELL and SAK (Strike Any Key) command.
  53. ;
  54. ; Added ZCPR3 style drive/user number to all FCB parsing. For Example:
  55. ;    A>c4:        Changes to drive C/user 4
  56. ;    A>c4:<program>    Runs <program> found on drive C/user 4
  57. ;    A>dir c4:    Gives directory of drive C/user 4
  58. ;    A>ren <new name>=c4:<old name> 
  59. ;            Renames file found on drive C/user 4
  60. ; Both the drive and user number are optional; 15: is a valid designation.
  61. ; S1 in the FCB is used to store the user number. If S1 contains a valid
  62. ; user number, bit 7 will be set. If no user number is specified, S1 will
  63. ; contain 0.
  64. ;
  65. ; Added POKE and changed SCL to a toggle, 12 August 1992.
  66. ;
  67. ; Added PEEK 30 August 1993.
  68. ;
  69. ;******** Structure Notes ********
  70. ;
  71. ;    This CPR is divided into a number of major sections. The following
  72. ; is an outline of these sections and the names of the major routines
  73. ; located therein.
  74. ;
  75. ; Section    Function/Routines
  76. ; -------    -----------------
  77. ;
  78. ;   --        Opening Comments, Equates, and Macro Definitions
  79. ;
  80. ;    0        JUMP Table into CPR
  81. ;
  82. ;    1        Buffers
  83. ;
  84. ;    2        CPR Starting Modules
  85. ;            CPR1    CPR    RESTRT
  86. ;
  87. ;    3        Utilities
  88. ;            CRLF    PRINTC    PRINT    PRINTS    BELL
  89. ;            CONOUT    BREAK    CHKETX    ABORT    READF
  90. ;            READ    WRITE    DEFDMA    DMASET    SEARF
  91. ;            SEARDE    SEARN    OPENF    OPEN    CLOSE
  92. ;            CREATE    BDOSFN    SUBKIL    DELETE    TLOGIN
  93. ;            DLOGIN    LOGIN    NEWUSR    RSTUSR    SETUSR
  94. ;            BDOSEA    BDOSJP    BDOSBC    BDOSDE
  95. ;
  96. ;     4     CPR Utilities
  97. ;            PROMPT    REDBUF    CNVBUF    UCASE    SDELM
  98. ;            ADVAN    SBLANK    ADDAH    NUMBER    A2NUM
  99. ;            HEXNUM    USRNUM    ERROR    DIRPTR    ULOGIN
  100. ;            SCANER    SCANT    SCANF    CMDSER    SETUDB
  101. ;
  102. ;     5     CPR-Resident Commands and Functions
  103. ;     5A        DIR    DIRPR    PRFN
  104. ;     5B        ERA
  105. ;     5C        ERAQ    PRNNF
  106. ;     5D        SAK    REPLY
  107. ;     5E        BELL
  108. ;     5F        LIST
  109. ;     5G        TYPE    PAGER
  110. ;     5H        EJECT    
  111. ;     5I        SAVE
  112. ;     5J         REN
  113. ;     5K        USER    SUSER
  114. ;     5L        DFU
  115. ;     5M        SCL
  116. ;     5N        PEEK
  117. ;     5O        POKE    
  118. ;     5P        JUMP
  119. ;     5Q        COM
  120. ;     5R        GO     CLLPRG    ERRLOG    ERRJMP
  121. ;     5S        GET    MEMLD    PRNLE
  122. ;     BIOS        BOOT
  123. ;
  124. ;
  125. FALSE    EQU    0
  126. TRUE    EQU    NOT FALSE
  127. ;
  128. ;
  129. ;  CUSTOMIZATION EQUATES
  130. ;
  131. ;  The following equates may be used to customize this CPR for the user's
  132. ;    system and integration technique. The following constants are provided:
  133. ;
  134. ;  TEST   - TRUE to build at intermediate address to debug via debugger.
  135. ;
  136. ;  COMLD  - TRUE to test and execute as a .com file.
  137. ;
  138. ;  REL    - TRUE if integration is to be done via MOVCPM.
  139. ;
  140. ;  BASE   - Base Address of user's CP/M system (normally 0 for DR version).
  141. ;        This equate eases modification by non-standard CP/M (eg. H89).
  142. ;
  143. ;  P2DOS  - Address of BDOS/P2DOS.
  144. ;
  145. TEST    EQU    FALSE         ;SET TO LOAD/RUN AT 8000H FOR DEBUG
  146. COMLD    EQU    FALSE        ;SET TO LOAD AND EXECUTE AS A .COM FILE
  147. REL    EQU    FALSE        ;SET TO TRUE FOR MOVCPM INTEGRATION
  148.                 ;LEAVE ALL FALSE FOR SYSGEN IMAGE
  149. ;
  150. BASE    EQU    0        ;BASE OF CP/M SYSTEM
  151. P2DOS    EQU    0E400H        ;BASE OF BDOS/P2DOS
  152. ZCPRSZ    EQU    00800H        ;SIZE OF ZCPR
  153. P2DOSSZ    EQU    00E00H        ;SIZE OF P2DOS    
  154. BIOS    EQU    P2DOS+P2DOSSZ    ;BASE OF BIOS
  155. CPRLOC    DEFL    P2DOS-ZCPRSZ    ;STANDARD EXECUTION ADDRESS
  156. ;
  157.     IF    REL
  158. CPRLOC    DEFL    0        ;MOVCPM IMAGE
  159.     ENDIF
  160. ;
  161.     IF    TEST
  162. CPRLOC    DEFL    8000H
  163.     ELSE    
  164. BOOT    EQU    BIOS        ;BIOS COLD BOOT ENTRY
  165. LISTST    EQU    BIOS+002DH    ;ENTRY POINT FOR LIST STATUS    
  166.     ENDIF
  167. ;
  168. ;  The following is presented as an option, but is not normally user-customize-
  169. ; able. A basic design choice had to be made in the design of ZCPR concerning
  170. ; the execution of SUBMIT files. The original CCP had a problem in this sense
  171. ; in that it ALWAYS looked for the SUBMIT file from drive A: and the SUBMIT
  172. ; program itself (SUBMIT.COM) would place the $$$.SUB file on the currently
  173. ; default drive. When the user was logged into B: and he issued a SUBMIT
  174. ; command, the $$$.SUB was placed on B: and did not execute. The CPR looked
  175. ; for $$$.SUB on A: and never found it.
  176. ;
  177. ;  After much debate it was decided to have ZCPR perform the same type of
  178. ; function as CCP (look for the $$$.SUB file on A:), but the problem with
  179. ; SUBMIT.COM still exists. Hence, RGF designed SuperSUB and RLC took his
  180. ; SuperSUB and designed SUB from it; both programs are set up to allow the
  181. ; selection at assembly time of creating the $$$.SUB on the default drive
  182. ; or on drive A:.
  183. ;
  184. ;  A final definition of the Indirect Command File ($$$.SUB or SUBMIT
  185. ; File) is presented as follows:
  186. ;
  187. ;        "An Indirect Command File is one which contains
  188. ;         a series of commands exactly as they would be
  189. ;         entered from a CP/M Console. The SUBMIT Command
  190. ;         (or SUB Command) reads this file and transforms
  191. ;         it for processing by the ZCPR (the $$$.SUB File).
  192. ;         ZCPR will then execute the commands indicated
  193. ;         EXACTLY as if they were typed at the Console."
  194. ;
  195. ;  Hence, to permit this to happen, the $$$.SUB file must always
  196. ; be present on a specific drive, and A: is the choice for said drive.
  197. ; With this facility engaged as such, Indirect Command Files like:
  198. ;
  199. ;        DIR
  200. ;        B:
  201. ;        DIR
  202. ;
  203. ; can be executed, even though the currently default drive is changed
  204. ; during execution. If the $$$.SUB file was present on the currently
  205. ; default drive, the above series of commands would not work since the
  206. ; ZCPR would be looking for $$$.SUB on the default drive, and switching
  207. ; default drives without moving the $$$.SUB file as well would cause
  208. ; processing to abort.
  209. ;
  210. ;  Note that the same problem can occur if the user number of the
  211. ; $$$.SUB file is not predefined. It is assumed that the $$$.SUB file
  212. ; is located on user 0 of the specified drive.
  213. ;
  214. ;  The trick of using the $ flag returned by DISK RESET is used to
  215. ; to speed the search for a $*.* file on drive A. This trick will not
  216. ; work if the $$$.SUB file is located on another drive.
  217. ;
  218. ;
  219. ;  Under the ZCPR, three command levels exist:
  220. ;
  221. ;    (1) that command issued by the user from his console at the '>' prompt
  222. ;    (2) that command issued by a $$$.SUB file at the '$' prompt
  223. ;    (3) that command issued by a user program by placing the command into
  224. ;        CIBUFF and setting the character count in CBUFF
  225. ;
  226. ;  To use CIBUFF, the user program stores the command line and character
  227. ; count; ZCPR will initialize the pointers properly, store the ending zero,
  228. ; and capitalize the command line for processing. Once the command line is
  229. ; properly stored, the user executes the command line by reentering ZCPR
  230. ; through CPRLOC [NOTE: The C register MUST contain a valid User/Disk Flag
  231. ; (see location 4) at this time.]
  232. ;
  233. ;
  234. ; Directory customization equates
  235. ;
  236. TWOCOL    EQU    FALSE        ;TRUE FOR TWO-COLUMN DIRECTORY DISPLAY
  237. WIDE    EQU    TRUE        ;TRUE IF WIDE DIRECTORY DISPLAY
  238. FENCE    EQU    '|'        ;CHARACTER BETWEEN FILES
  239. USRDLM    EQU    ':'        ;CHARACTER BETWEEN USER NUMBER AND FILE
  240. USRFLG    EQU    'A'        ;LIST $SYS AND $DIR FOR ALL USER NUMBERS
  241. SYSFLG    EQU    'B'        ;LIST $SYS AND $DIR
  242. SOFLG    EQU    'S'        ;LIST $SYS ONLY
  243. ;
  244. ; List and Type command customization equates
  245. ;
  246. NLINES    EQU    20        ;NUMBER OF LINES ON CRT PAGE
  247. NLINEP    EQU    60        ;NUMBER OF LINES ON LIST DEVICE
  248. FFKILL    EQU    TRUE        ;TRUE SUPPRESSES FF UNTIL FIRST CHARACTER
  249. PGDFLG    EQU    'P'        ;TYPE AND LIST COMMAND DEFAULT TOGGLE
  250. NOSTAT    EQU    FALSE        ;SET TO TRUE IF BIOS LISTST NOT IMPLEMENTED
  251. ;
  252. ; Other customization equates
  253. ;
  254. BUFLEN    EQU    80        ;SIZE OF COMMAND INPUT BUFFER 
  255. MAXUSR    EQU    15        ;MAXIMUM USER NUMBER ACCESSIBLE
  256. DEFUSR    EQU    0        ;DEFAULT USER NUMBER FOR COM FILES
  257. SPRMPT    EQU    '$'        ;CPR PROMPT INDICATING SUBMIT COMMAND
  258. COMCHR    EQU    ';'        ;BEGIN COMMENT CHARACTER
  259. CMDCHR    EQU    ';'        ;BEGIN NEXT COMMAND CHARACTER
  260. NUMBASE    EQU    'H'        ;CHARACTER USED TO SPECIFY HEXIDECIMAL BASE
  261. RECFLG    EQU    'R'        ;CHARACTER FOR SAVE COMMAND TO SAVE RECORDS
  262. SUPRES    EQU    TRUE        ;TRUE TO SUPPRESS USER NUMBER FOR USER 0
  263. MULTPL    EQU    TRUE        ;TRUE TO ALLOW MULTIPLE COMMANDS ON ONE LINE
  264. REBOOT    EQU    TRUE        ;TRUE TO INCLUDE BOOT COMMAND
  265. ;
  266.     IF    TEST
  267. CPRMPT    EQU    '<'        ;CPR PROMPT INDICATING TEST MODE
  268.     ELSE    
  269. CPRMPT    EQU    '>'        ;CPR PROMPT INDICATING USER COMMAND
  270.     ENDIF    
  271. ;
  272. ; END OF CUSTOMIZATION SECTION
  273. ;
  274. ETX    EQU    03H
  275. BELL    EQU    07H
  276. BS    EQU    08H
  277. TAB    EQU    09H
  278. LF    EQU    0AH
  279. FF    EQU    0CH
  280. CR    EQU    0DH
  281. ;
  282. WBOOT    EQU    BASE+0000H    ;CP/M WARM BOOT ADDRESS
  283. UDFLAG    EQU    BASE+0004H    ;USER NUMBER IN HIGH NIBBLE, DISK IN LOW
  284. BDOS    EQU    BASE+0005H    ;BDOS FUNCTION CALL ENTRY POINT
  285. TFCB    EQU    BASE+005CH    ;DEFAULT FCB BUFFER
  286. TBUFF    EQU    BASE+0080H    ;DEFAULT DISK I/O BUFFER
  287. TPA    EQU    BASE+0100H    ;BASE OF TPA
  288. ;
  289. ;
  290. ;**** Section 0 ****
  291. ;
  292.     .Z80
  293.     ASEG
  294.     ORG    100H
  295. ;
  296. ; LOADER FOR TEST PURPOSES
  297. ;   ALLOWS ONE TO EXECUTE ZCPR AS A .COM FILE
  298. ;
  299.     IF    COMLD OR TEST
  300.     LD    HL,BGNXFR
  301.     LD    DE,CPRLOC
  302.     LD    BC,ENDLD-CPRLOC
  303.     LDIR
  304.     LD    BC,(UDFLAG)
  305.     JP    CPRLOC
  306. BGNXFR    EQU    $
  307.     ENDIF
  308. ;
  309.     .PHASE    CPRLOC
  310. ;
  311. ;  ENTRY POINTS INTO ZCPR
  312. ;
  313. ;    If the ZCPR is entered at location CPRLOC (at the JUMP to CPR), then
  314. ; the default command in CIBUFF will be processed. If the ZCPR is entered
  315. ; at location CPRLOC+3 (at the JUMP to CPR1), then the default command in
  316. ; CIBUFF will NOT be processed.
  317. ;
  318. ;    NOTE: Entry into ZCPR in this way is permitted under ZCPR Version 4.0,
  319. ; but in order for this to work, CIBUFF and CBUFF MUST be initialized properly
  320. ; AND the C register MUST contain a valid User/Disk Flag (see Location 4: the
  321. ; most significant nibble contains the User Number and the least significant
  322. ; nibble contains the Disk Number.)
  323. ;
  324. ;    Some user programs (such as SYNONYM3) attempt to use the default
  325. ; command facility. Under the original CPR, it was necessary to initialize
  326. ; a pointer located at the end of the command buffer to point to the first
  327. ; byte in the command buffer. Under Version 4.x of ZCPR, this is no longer
  328. ; the case. This pointer, CIBPTR (Command Input Buffer PoinTeR), has been
  329. ; moved and the former location is now reserved for the stack. ZCPR
  330. ; Version 4.x automatically initializes CIBPTR in all cases.
  331. ;
  332. ENTRY:
  333.     JP    CPR        ; Process potential default command
  334.     JP    CPR1        ; Do NOT process potential default command
  335. ;
  336. ;**** Section 1 ****
  337. ;
  338. ; BUFFERS ET AL
  339. ;
  340. ; INPUT COMMAND LINE AND DEFAULT COMMAND
  341. ;
  342. ;   The command line to be executed is stored here. This command line
  343. ; is generated in one of three ways:
  344. ;
  345. ;    (1) by the user entering it through the BDOS READLN function at
  346. ;        the du> prompt [user input from keyboard].
  347. ;    (2) by the SUBMIT File Facility placing it there from a $$$.SUB
  348. ;        file.
  349. ;    (3) by an external program or user placing the required command
  350. ;        into this buffer.
  351. ;
  352. ;   In all cases, the command line is placed into the buffer starting at
  353. ; CIBUFF. This line contains the last character but NOT the Carriage
  354. ; Return, and the count is of all characters in the command line up to and
  355. ; including the last character. This count is placed into location CBUFF
  356. ; (immediately before the command line at CIBUFF.) If ZCPR is entered via
  357. ; CPRLOC, the command line is then parsed, interpreted, and the indicated
  358. ; command is executed. ZCPR places the terminating zero after the command
  359. ; and CIBPTR is properly initialized.
  360. ;
  361. ;   WARNING: The command line must NOT exceed BUFLEN characters in length.
  362. ; For user programs which load this command, the value of BUFLEN can be
  363. ; obtained by examining the byte at CPRLOC+6.
  364. ;
  365. ; It is now possible to place multiple commands on one line. Each command
  366. ; is separated from its neighbor by a ";". This feature only works for ZCPR
  367. ; commands and programs that return to ZCPR via a RET instruction. Any
  368. ; warm boot reloads ZCPR and destroys the contents of the command buffer.
  369. ; The multiple command feature may be turned off with the SCL command.
  370. ;
  371. MBUFF:    DEFB    BUFLEN        ;MAXIMUM BUFFER LENGTH
  372. CBUFF:    DEFB    0        ;NUMBER OF CHARACTERS IN COMMAND LINE
  373. CIBUFF:    DEFB    '             '    ;DEFAULT (COLD BOOT) COMMAND
  374.     DEFB    0        ;COMMAND STRING TERMINATOR
  375.     DEFB    '  ZCPR-D&J of 5 March 1994  '
  376.     DEFB    0        ;TERMINATOR FOR DUMP IDENTIFICATION
  377.     DEFS    BUFLEN-($-CIBUFF)+1
  378.     DEFW    0        ;SENTINEL FOR STACK END
  379.     DEFS    24        ;STACK AREA
  380. STACK    EQU    $        ;TOP OF STACK
  381. ;
  382. ; SUBMIT FILE CONTROL BLOCK
  383. ;
  384. SUBDN:    DEFB    1        ;DISK DRIVE (A: CONTAINS $$$.SUB)
  385. SUBFN:    DEFB    '$$$     '    ;FILE NAME
  386. SUBFT:    DEFB    'SUB'        ;FILE TYPE
  387. SUBEX:    DEFB    0        ;EXTENT NUMBER
  388. SUBS1    EQU    SUBDN+13    ;S1
  389. SUBS2    EQU    SUBDN+14    ;S2
  390. SUBRC    EQU    SUBDN+15    ;RECORD COUNT
  391. SUBDM    EQU    SUBDN+16    ;DISK GROUP MAP
  392. SUBCR    EQU    SUBDN+32    ;CURRENT RECORD NUMBER
  393. ;
  394. ; COMMAND FILE CONTROL BLOCK
  395. ;
  396. FCBDN:    DEFS    1        ;DISK DRIVE
  397. FCBFN:    DEFS    8        ;FILE NAME
  398. FCBFT:    DEFS    3        ;FILE TYPE
  399. FCBEX:    DEFS    1        ;EXTENT NUMBER
  400. FCBS1:    DEFS    1        ;S1
  401. FCBS2:    DEFS    1        ;S2
  402. FCBRC:    DEFS    1        ;RECORD COUNT
  403. FCBDM:    DEFS    16        ;DISK GROUP MAP
  404. FCBCR:    DEFS    1        ;CURRENT RECORD NUMBER
  405. ;
  406. ; Type and List Variables
  407. ;
  408. CHRCNT:    DEFS    1        ;CHARACTER COUNT FOR TYPE AND LIST
  409. LNCNT:    DEFS    1        ;LINE COUNT FOR TYPE AND LIST
  410. TYPLST:    DEFS    1        ;FLAG FOR TYPE OR LIST
  411. TABCNT:    DEFS    1        ;TAB COUNT FOR TYPE AND LIST
  412. SYSTST:    DEFB    0        ;LIST SYSTEM FILES IN DIRECTORY FLAG
  413. ;
  414. ; General Variables
  415. ;
  416. CIBPTR:    DEFW    CIBUFF        ;POINTER TO COMMAND INPUT BUFFER
  417. CIPTR:    DEFW    CIBUFF        ;POINTER TO CURRENT CMD FOR ERROR REPORTING
  418. TMPUSR:    DEFB    0        ;TEMPORARY USER NUMBER
  419. TDRIVE:    DEFB    0        ;DEFAULT DRIVE
  420. DFUSR:    DEFB    DEFUSR        ;DEFAULT USER
  421. LDADR:    DEFW    TPA        ;MEMORY LOAD ADDRESS
  422. ;
  423. ; CPR BUILT-IN COMMAND TABLE
  424. ;   EACH ENTRY IS COMPOSED OF THE BIT 7 TERMINATED COMMAND AND 2-BYTE ADDRESS
  425. ;
  426. CMDTBL:
  427.     DC    'DIR'
  428.     DEFW    DIR
  429.     DC    'LIST'
  430.     DEFW    LIST
  431.     DC    'TYPE'
  432.     DEFW    TYPE
  433.     DC    'USER'
  434.     DEFW    USER
  435.     DC    'DFU'
  436.     DEFW    DFU
  437.     DC    'PAGE'
  438.     DEFW    EJECT
  439.     DC    'BELL'
  440.     DEFW    RING
  441.     DC    'SAK'
  442.     DEFW    SAK
  443.     DC    'GO'
  444.     DEFW    GO
  445.     DC    'ERA'
  446.     DEFW    ERA
  447.     DC    'ERAQ'
  448.     DEFW    ERAQ
  449.     DC    'SAVE'
  450.     DEFW    SAVE
  451.     DC    'REN'
  452.     DEFW    REN
  453.     DC    'GET'
  454.     DEFW    GET
  455.     DC    'JUMP'
  456.     DEFW    JUMP
  457.     DC    'PEEK'
  458.     DEFW    PEEK
  459.     DC    'POKE'
  460.     DEFW    POKE
  461. NCMNDS    DEFL    17        ;NUMBER OF COMMANDS
  462. ;
  463.     IF    MULTPL
  464.     DC    'SCL'
  465.     DEFW    SINGLE
  466. NCMNDS    DEFL    NCMNDS+1
  467.     ENDIF
  468. ;
  469.     IF    REBOOT
  470.     DC    'BOOT'
  471.     DEFW    BOOT
  472. NCMNDS    DEFL    NCMNDS+1
  473.     ENDIF    
  474. ;
  475. ;
  476. ;**** Section 2 ****
  477. ; CPR STARTING POINTS
  478. ;
  479. ; START CPR AND DON'T PROCESS DEFAULT COMMAND STORED
  480. ;
  481. CPR1:
  482.     XOR    A        ;SET NO DEFAULT COMMAND
  483.     LD    (CBUFF),A
  484. ;
  485. ; START CPR AND POSSIBLY PROCESS DEFAULT COMMAND
  486. ;
  487. CPR:
  488.     LD    SP,STACK    ;MAKE SURE WE HAVE A VALID STACK
  489.     LD    A,C        ;C=USER/DISK NUMBER (SEE LOC 4)
  490.     RRA            ;EXTRACT USER NUMBER
  491.     RRA    
  492.     RRA    
  493.     RRA    
  494.     AND    0FH
  495.     LD    (TMPUSR),A    ;SET USER NUMBER
  496.     LD    A,C        ;GET DISK NUMBER (SEE LOC 4)
  497.     AND    0FH        ;EXTRACT DEFAULT DISK DRIVE
  498.     LD    (TDRIVE),A    ;SAVE DEFAULT DRIVE
  499.     LD    C,0DH        ;RESET DISK SYSTEM
  500.     CALL    BDOS
  501.     LD    (SUBFLG),A    ;SAVE SUBMIT FLAG CLUE
  502.     DEFB    0F6H        ;SET NZ FLAG (OR A,n)
  503. ;
  504. ; PROMPT USER AND PROCESS INPUT COMMAND
  505. ;
  506. RESTRT:
  507.     XOR    A        ;SET ZERO FLAG
  508.     LD    SP,STACK    ;RESET STACK
  509. ;
  510. ; PROCESS INPUT LINE
  511. ;
  512.     CALL    REDBUF        ;CAPITALIZE, NULL TERMINATE, SKIP SPACES
  513. RS3:
  514.     CP    COMCHR        ;COMMENT?
  515.     JR    Z,RESTRT    ;YES, SKIP REST OF LINE
  516.     CALL    SCANER        ;PARSE COMMAND NAME FROM COMMAND LINE
  517.     JR    NZ,RS4        ;ERROR IF NAME CONTAINS A "?"
  518.     CALL    DEFDMA        ;SET TBUFF TO DMA ADDRESS
  519.     CALL    DLOGIN        ;ASSURE PROPER DRIVE
  520.     CALL    RSTUSR        ;ASSURE PROPER USER NUMBER
  521.     CALL    SETUDB        ;SET UD BYTE TO MATCH USER/DRIVE
  522.     CALL    CMDSER        ;SCAN FOR CPR-RESIDENT COMMAND
  523. ;
  524. ; ENTRY POINT FOR CONTINUED SCAN OF COMMAND LINE
  525. ;
  526.     CALL    ADVAN        ;GET ANY CHARACTER
  527.     JR    Z,RESTRT    ;NONE, END OF LINE
  528.     LD    (CIPTR),DE    ;UPDATE START OF LINE IN CASE ERROR
  529.     INC    DE        ;NOT END OF LINE, MUST BE DELIMITER
  530.     LD    (CIBPTR),DE    ;SAVE POINTER
  531. ;
  532.     IF    MULTPL
  533.     LD    HL,NEWCMD    ;COMMAND?
  534.     CP    (HL)
  535. RS4:
  536.     JP    NZ,ERROR    ;NO
  537.     CALL    ADVAN        ;STEP OVER DELIMITER
  538.     JR    RS3
  539.     ELSE
  540. RS4:
  541.     JP    ERROR
  542.     ENDIF
  543. ;
  544. ;
  545. ;**** Section 3 ****
  546. ; I/O UTILITIES
  547. ;
  548. ; OUTPUT <CRLF>
  549. ;
  550. CRLF:
  551.     CALL    PRINT        ;PRINT STRING
  552.     DEFB    CR,LF+80H
  553.     RET
  554. ;
  555. ; PRINT STRING POINTED TO BY RET ADR; START WITH <CRLF>
  556. ;
  557. PRINTC:
  558.     CALL    CRLF        ;NEW LINE
  559. ;
  560. ; PRINT STRING POINTED TO BY RET ADR
  561. ;
  562. PRINT:
  563.     EX    (SP),HL        ;GET POINTER TO STRING
  564.     CALL    PRINTS
  565.     EX    (SP),HL        ;RESTORE HL AND RETURN ADDRESS
  566.     RET
  567. ;
  568. ; PRINT STRING POINTED TO BY HL
  569. ;
  570. PRINT1:
  571.     CALL    CONOUT        ;PRINT CHARACTER
  572. PRINTS:
  573.     LD    A,(HL)        ;GET NEXT BYTE
  574.     INC    HL        ;POINT TO NEXT BYTE
  575.     AND    A        ;TEST FOR 0 OR BIT 7 SET
  576.     RET    Z        ;DONE
  577.     JP    P,PRINT1    ;NOT LAST CHARACTER
  578. ;
  579. ; OUTPUT CHARACTER IN A REG
  580. ;
  581. CONOUT:
  582.     PUSH    BC
  583.     PUSH    DE
  584.     LD    C,02H
  585.     RES    7,A        ;STRIP MSB IN CASE SET FOR EOS
  586.     LD    E,A
  587.     JR    BDOSDE
  588. ;
  589. ; GET CHARACTER FROM CONSOLE AND CHECK FOR ^C
  590. ;
  591. BREAK:
  592.     PUSH    BC
  593.     LD    C,0BH        ;CONSOLE STATUS CHECK
  594.     CALL    BDOSJP
  595.     LD    C,01H        ;GET CHARACTER FROM CON: WITH ECHO
  596.     CALL    NZ,BDOSJP    ;GET CHARACTER
  597.     POP    BC
  598.     RET    Z        ;NO CHARACTER
  599. CHKETX:
  600.     CP    ETX        ;^C?
  601.     RET    NZ         ;NO
  602. ABORT:
  603.     CALL    SUBKIL        ;KILL ANY SUBMIT
  604.     JR    RESTRT        ;AND RESTART
  605. ;
  606. ; BDOS FUNCTIONS
  607. ;
  608. READF:
  609.     LD    DE,FCBDN    ;FALL THRU TO READ
  610. READ:
  611.     LD    C,14H
  612.     DEFB    3AH        ;SKIP NEXT TWO BYTES
  613. WRITE:
  614.     LD    C,15H        ;FALL THRU TO BDOS CALL
  615.     JR    BDOSJP
  616. DEFDMA:
  617.     LD    DE,TBUFF    ;TBUFF = DEFAULT ADDRESS
  618. DMASET:
  619.     LD    C,1AH        ;SET DMA ADDRESS
  620.     JR    BDOSJP
  621. SEARF:
  622.     LD    DE,FCBDN    ;SPECIFY FCB
  623. SEARDE:
  624.     LD    C,11H        ;SEARCH FOR FILE
  625.     DEFB    3AH        ;SKIP NEXT TWO BYTES
  626. SEARN:
  627.     LD    C,12H        ;SEARN IGNORES DE AND USES THE PREVIOUS
  628.     JR    BDOSFN        ;VALUE FROM THE LAST BDOS CALL
  629. OPENF:
  630.     XOR    A
  631.     LD    (FCBCR),A
  632.     LD    DE,FCBDN    ;FALL THRU TO OPEN
  633. OPEN:
  634.     LD    C,0FH        ;OPEN FILE
  635.     DEFB    3AH        ;SKIP NEXT TWO BYTES 
  636. CLOSE:
  637.     LD    C,10H        ;CLOSE FILE
  638.     DEFB    3AH        ;SKIP NEXT TWO BYTES
  639. CREATE:
  640.     LD    C,16H        ;CREATE FILE
  641. BDOSFN:
  642.     CALL    BDOSJP
  643.     INC    A        ;SET ERROR RETURN FLAG
  644.     RET
  645. SUBKIL:
  646.     LD    HL,SUBFLG    ;ABORT SUBMIT FILE
  647.     LD    A,(HL)        ;SUB FILE IN EXECUTION?
  648.     AND    A
  649.     RET    Z        ;NO
  650.     LD    (HL),0        ;KILL SUB FILE EXECUTION FLAG
  651.     LD    DE,SUBDN    ;DELETE $$$.SUB
  652. DELETE:
  653.     LD    C,13H        ;DELETE FILE
  654.     JR    BDOSJP        ;SAVE MORE SPACE
  655. TLOGIN:
  656.     LD    (TDRIVE),A    ;SAVE NEW DEFAULT DRIVE
  657. DLOGIN:
  658.     LD    A,(TDRIVE)    ;LOG IN DEFAULT DRIVE
  659.     LD    C,0EH        ;SELECT DISK
  660.     JR    BDOSEA        ;SAVE SOME CODE SPACE
  661. NEWUSR:
  662.     LD    (TMPUSR),A    ;SET NEW USER NUMBER
  663. RSTUSR:
  664.     LD    A,(TMPUSR)    ;RESET TEMPORARY USER
  665. SETUSR:
  666.     LD    C,20H        ;GET/SET USER NUMBER (GET IF E=FFH)
  667. BDOSEA:
  668.     LD    E,A        ;STUFF PARAMETER INTO REG E
  669. BDOSJP:
  670.     PUSH    BC
  671. BDOSBC:
  672.     PUSH    DE        ; zcpr does not use any BDOS calls that
  673. BDOSDE:
  674.     PUSH    HL        ; return a value in HL. Those HL calls
  675.     CALL    BDOS        ; are:
  676.     POP    HL        ;   get active drive - #24
  677.     POP    DE        ;   get allocation vector - #27
  678.     POP    BC        ;   get read-only map - #29
  679.     AND    A        ;   get disk parameters - #31
  680.     RET
  681. ;
  682. ;
  683. ;**** Section 4 ****
  684. ; CPR UTILITIES
  685. ;
  686. ; PRINT PROMPT (DU>)
  687. ;
  688. PROMPT:
  689.     CALL    CRLF        ;PRINT PROMPT
  690.     LD    A,(TDRIVE)    ;CURRENT DRIVE IS PART OF PROMPT
  691.     ADD    A,'A'        ;CONVERT TO ASCII A-P
  692.     CALL    CONOUT
  693.     LD    A,(TMPUSR)    ;GET USER NUMBER
  694. ;
  695.     IF    SUPRES        ;IF SUPPRESSING USER # REPORT FOR USER 0
  696.     AND    A
  697.     JR    Z,PRPT1        ;ZERO, SUPRESS
  698.     ENDIF    
  699. ;
  700. PRUSRN:
  701.     ADD    A,0        ;CONVERT HEX TO BCD
  702.     DAA
  703.     PUSH    AF        ;SAVE UNITS DIGIT
  704.     AND    0F0H
  705.     LD    A,'1'
  706.     CALL    NZ,CONOUT    ;PRINT IF OVER 10
  707.     POP    AF
  708.     OR    '0'        ;OUTPUT 1'S DIGIT (CONVERT TO ASCII)
  709.     CALL    CONOUT
  710. PRPT1:
  711.     JP    PRINT        ;GO PRINT PROMPT CHARACTER
  712. ;
  713. ; INPUT NEXT COMMAND TO CPR
  714. ;
  715. ;    This routine determines if a SUBMIT file is being processed
  716. ; and extracts the command line from it if so or from the user's console.
  717. ; This routine also invokes the DU> prompt.
  718. ;
  719. REDBUF:
  720.     JR    NZ,CNVBUF    ;PROCESS DEFAULT COMMAND IF ANY
  721. RD0:
  722.     CALL    DEFDMA        ;SELECT TBUFF FOR READ
  723.     XOR    A        ;SELECT USER 0 FOR SUBMIT SEARCH
  724.     CALL    SETUSR
  725.     LD    DE,SUBDN    ;OPEN $$$.SUB
  726. SUBFLG    EQU    $+1        ;IN LINE SUBMIT FLAG
  727.     LD    A,0        ;SUBMIT IN PROGRESS?
  728.     AND    A
  729.     CALL    NZ,OPEN        ;CALL OPEN IF SUBMIT IN PROGRESS
  730.     JR    Z,RB2        ;NONE FOUND SO GET COMMAND LINE
  731.     LD    A,(SUBRC)    ;GET VALUE OF LAST RECORD IN FILE
  732.     DEC    A        ;POINT TO NEXT TO LAST RECORD
  733.     LD    (SUBCR),A    ;SAVE NEW VALUE OF LAST RECORD IN $$$.SUB
  734.     CALL    READ        ;DE=SUBDN
  735.     JR    NZ,RB1        ;ABORT $$$.SUB IF ERROR IN READING LAST REC
  736.     LD    HL,SUBS2    ;POINT TO S2 OF $$$.SUB FCB
  737.     LD    (HL),A        ;SET S2 TO ZERO
  738.     INC    HL        ;POINT TO RECORD COUNT
  739.     DEC    (HL)        ;DECREMENT RECORD COUNT OF $$$.SUB
  740.     PUSH    AF        ;SAVE ZERO FLAG
  741.     CALL    Z,SUBKIL    ;KILL SUBMIT IF ZERO RECORDS LEFT
  742.     POP    AF        ;ELSE
  743.     CALL    NZ,CLOSE    ;JUST CLOSE FILE
  744.     CALL    PROMPT        ;PRINT SUBMIT PROMPT
  745.     DEFB    SPRMPT+80H
  746.     LD    HL,TBUFF+1    ;PRINT COMMAND LINE FROM $$$.SUB
  747.     CALL    PRINTS
  748.     LD    HL,TBUFF    ;MOVE COMMAND LINE TO COMMAND BUFFER    
  749.     LD    DE,CBUFF
  750.     LD    BC,BUFLEN
  751.     LDIR
  752.     CALL    BREAK        ;CHECK FOR ABORT (ANY CHARACTER)
  753.     JR    Z,CNVBUF    ;NONE
  754. ;
  755. ; INPUT COMMAND LINE FROM USER CONSOLE
  756. ;
  757. RB1:
  758.     CALL    SUBKIL        ;ERASE $$$.SUB
  759. RB2:
  760.     CALL    PROMPT        ;PRINT PROMPT
  761.     DEFB    CPRMPT+80H
  762.     LD    C,0AH        ;READ COMMAND LINE FROM USER
  763.     LD    DE,MBUFF
  764.     CALL    BDOS
  765. ;
  766. ; CAPITALIZE STRING (ENDING IN 0) IN CBUFF AND SET POINTER FOR PARSING
  767. ;
  768. CNVBUF:
  769.     LD    HL,CBUFF    ;POINT TO USER'S COMMAND BUFFER
  770.     LD    A,(HL)        ;ANY CHARACTERS IN BUFFER?
  771.     AND    A
  772.     JR    Z,RD0         ;NO, FILL BUFFER
  773.     INC    HL
  774.     LD    (CIBPTR),HL    ;INITIALIZE COMMAND LINE POINTER
  775.     LD    B,A        ;INITIALIZE CHARACTER COUNTER
  776. CB1:
  777.     LD    A,(HL)        ;CAPITALIZE COMMAND CHARACTER
  778.     CALL    UCASE
  779.     LD    (HL),A
  780.     INC    HL        ;POINT TO NEXT CHARACTER
  781.     DJNZ    CB1        ;CONTINUE TO END OF COMMAND LINE
  782.     LD    (HL),B        ;STORE ENDING <NULL>
  783. ;
  784. ; ADVANCE INPUT POINTER TO FIRST NON-BLANK AND FALL THROUGH TO SBLANK
  785. ;
  786. ADVAN:
  787.     LD    DE,(CIBPTR)
  788. ;
  789. ; SKIP STRING POINTED TO BY DE (STRING ENDS IN 0) UNTIL END OF STRING
  790. ;   OR NON-BLANK ENCOUNTERED (BEGINNING OF TOKEN)
  791. ;
  792. SBLANK:
  793.     LD    A,(DE)
  794.     OR    A
  795.     RET    Z
  796.     CP    ' '
  797.     RET    NZ
  798.     INC    DE
  799.     JR    SBLANK
  800. ;
  801. ; CONVERT CHARACTER IN A TO UPPER CASE
  802. ;
  803. UCASE:
  804.     CP    61H        ;LOWER-CASE A
  805.     RET    C
  806.     CP    7BH        ;GREATER THAN LOWER-CASE Z?
  807.     RET    NC
  808.     AND    5FH        ;CAPITALIZE
  809.     RET    
  810. ;
  811. ; CHECK TO SEE IF DE POINTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET
  812. ;
  813. SDELM:
  814.     LD    A,(DE)
  815.     OR    A        ;0=DELIMITER
  816.     RET    Z
  817.     CP    ' '        ;ERROR IF < <SP>
  818.     JP    C,ERROR
  819.     RET    Z        ;<SP> =DELIMITER
  820.     CP    '.'        ;"." =DELIMITER
  821.     RET    Z
  822.     CP    '['        ;"[" =DELIMITER
  823.     RET    Z
  824.     CP    ']'        ;"]" =DELIMITER
  825.     RET    Z
  826.     CP    '>'        ;">" =DELIMITER BUT GREATER NOT
  827.     RET    NC
  828.     CP    ':'        ;":"  ";"  "<"  "=" =DELIMITERS
  829.     RET    C        ;NO DELIMITER FOUND
  830.     CP    A        ;SET ZERO FLAG
  831.     RET    
  832.  
  833. ;
  834. ; ADD A TO HL (HL=HL+A)
  835. ;
  836. ADDAH:
  837.     ADD    A,L
  838.     LD    L,A
  839.     RET    NC
  840.     INC    H
  841.     RET    
  842. ;
  843. ; EXTRACT DECIMAL NUMBER FROM COMMAND LINE
  844. ;   RETURN WITH 8-BIT VALUE IN REG A AND 16-BIT VALUE IN HL
  845. ;   ALL REGISTERS MAY BE AFFECTED
  846. ;
  847. NUMBER:
  848.     CALL    SCANER        ;PARSE NUMBER AND PLACE IN FCBFN
  849.     LD    HL,FCBFN+10    ;POINT TO END OF TOKEN FOR CONVERSION
  850.     LD    B,11        ;11 CHARACTERS MAX
  851. ;
  852. ; CHECK FOR SUFFIX FOR HEXADECIMAL NUMBER
  853. ;
  854. NUMS:
  855.     LD    A,(HL)        ;GET CHARACTERS FROM END, SEARCHING FOR SUFFIX
  856.     DEC    HL        ;BACK UP
  857.     CP    NUMBASE        ;CHECK AGAINST BASE SWITCH FLAG
  858.     JR    Z,HNUM1
  859.     CP    ' '        ;SPACE?
  860.     JR    NZ,NUM1        ;CHECK FOR LAST DIGIT
  861.     DJNZ    NUMS        ;COUNT DOWN
  862. ;
  863. ; PROCESS DECIMAL NUMBER
  864. ;
  865. NUM1:
  866.     LD    HL,0        ;CLEAR GRAND TOTAL
  867.     LD    DE,FCBFN    ;POINT TO BEGINNING OF TOKEN
  868. NUM2:
  869.     LD    A,(DE)        ;GET CHARACTER
  870.     CP    ' '        ;DONE IF <SP>
  871. NUM3:
  872.     LD    A,L        ;TOTAL TO A IN CASE DONE
  873.     RET    Z        ;ALL DONE
  874.     CALL    A2NUM        ;CONVERT DIGIT
  875.     JR    NC,NUM2        ;NO ERROR
  876.     JR    ERROR
  877. ;
  878. ; ASCII TO NUMERICAL CONVERSION
  879. ;   RETURNS WITH CARRY SET IF INVALID OR OVERFLOW
  880. ;   BASE 10 ASSUMED - MAXIMUM VALUE IS 255
  881. ;
  882. A2NUM:
  883.     LD    A,(DE)        ;GET DIGIT
  884.     SUB    '0'        ;CONVERT TO BINARY (ASCII 0-9 TO BINARY)
  885.     CP    10        ;ERROR IF >= 10
  886.     CCF            ;FLIP CARRY
  887.     RET    C
  888.     LD    C,A        ;DIGIT IN C
  889.     LD    A,L        ;NEW VALUE = OLD VALUE * 10
  890.     RLCA            ;*2
  891.     RET    C        ;ERROR
  892.     RLCA            ;*4
  893.     RET    C        ;ERROR
  894.     ADD    A,L        ;*5
  895.     RET    C        ;ERROR
  896.     RLCA            ;*10
  897.     RET    C        ;ERROR
  898.     ADD    A,C        ;NEW VALUE = OLD VALUE * 10 + DIGIT
  899.     RET    C        ;DON'T INC DE IF ERROR
  900.     LD    L,A        ;SET NEW VALUE
  901.     INC    DE        ;GOOD DIGIT
  902.     RET
  903. ;
  904. ; EXTRACT HEXADECIMAL NUMBER FROM COMMAND LINE
  905. ;   RETURN WITH 8-BIT VALUE IN REG A AND 16-BIT VALUE IN HL
  906. ;   ALL REGISTERS MAY BE AFFECTED
  907. ;
  908. HEXNUM:
  909.     CALL    SCANER        ;PARSE NUMBER AND PLACE IN FCBFN
  910. HNUM1:
  911.     LD    HL,0        ;HL=ACCUMULATED VALUE
  912.     LD    DE,FCBFN    ;POINT TO TOKEN FOR CONVERSION
  913. HNUM2:
  914.     LD    A,(DE)        ;GET CHARACTER
  915.     CP    ' '        ;DONE?
  916.     JR    Z,NUM3        ;RETURN IF SO
  917.     CP    'H'        ;DONE IF H SUFFIX
  918.     JR    Z,NUM3
  919.     SUB    '0'        ;CONVERT TO BINARY
  920.     CP    10        ;0-9?
  921.     JR    C,HNUM3
  922.     SUB    17        ;A-F?
  923.     CP    6        ;ERROR?
  924.     JR    NC,ERROR
  925.     ADD    A,10
  926. HNUM3:
  927.     INC    DE        ;POINT TO NEXT CHARACTER
  928.     ADD    HL,HL        ;LEFT SHIFT 4
  929.     ADD    HL,HL
  930.     ADD    HL,HL
  931.     ADD    HL,HL
  932.     OR    L        ;MASK IN NEW LOW
  933.     LD    L,A        ;NEW LOW BYTE IN L
  934.     JR    HNUM2
  935. ;
  936. ; GET THE REQUESTED USER NUMBER FROM THE COMMAND LINE AND VALIDATE IT.
  937. ;
  938. USRNUM:
  939.     CALL    NUMBER
  940.     LD    E,A
  941.     CP    MAXUSR+1
  942.     RET    C
  943. ;
  944. ; INVALID COMMAND -- PRINT IT
  945. ;
  946. ERROR:
  947.     CALL    CRLF        ;NEW LINE
  948.     LD    HL,(CIPTR)    ;POINT TO BEGINNING OF COMMAND LINE
  949. ERR1:
  950.     LD    A,(HL)        ;GET CHARACTER
  951.     CP    ' '+1        ;SIMPLE '?' IF <SP> OR LESS
  952.     CALL    NC,CONOUT    ;PRINT COMMAND CHARACTER OR FALL THRU
  953.     INC    HL        ;POINT TO NEXT
  954.     JR    NC,ERR1        ;CONTINUE
  955.     CALL    PRINT        ;PRINT '?'
  956.     DC    '?'
  957.     JP    ABORT        ;RESTART CPR
  958. ;
  959. ; POINT TO DIRECTORY ENTRY IN TBUFF WHOSE OFFSET IS SPECIFIED BY A AND C
  960. ;
  961. DIRPTR:
  962.     LD    HL,TBUFF    ;POINT TO TEMP BUFFER
  963.     ADD    A,C        ;POINT TO 1ST BYTE OF DIR ENTRY
  964.     CALL    ADDAH        ;POINT TO DESIRED BYTE IN DIR ENTRY
  965.     LD    A,(HL)        ;GET DESIRED BYTE
  966.     RET    
  967. ;
  968. ; CHECK FOR VALID USER AND LOG IN IF VALID
  969. ;
  970. ULOGIN:
  971.     LD    A,(FCBS1)    ;GET USER NUMBER
  972. ALOGIN:
  973.     ADD    A,80H        ;VALID?
  974.     CALL    P,SETUSR    ;SET IF VALID
  975.     RET
  976. ;
  977. ; EXTRACT TOKEN FROM COMMAND LINE AND PLACE IT INTO FCBDN;
  978. ;   FORMAT FCBDN FCB IF TOKEN RESEMBLES FILE NAME AND TYPE (FILENAME.TYP);
  979. ;   ON INPUT, CIBPTR PTS TO CHARACTER AT WHICH TO START SCAN;
  980. ;   ON OUTPUT, CIBPTR PTS TO CHARACTER AT WHICH TO CONTINUE AND ZERO FLAG IS
  981. ;     RESET IF '?' IS IN TOKEN
  982. ;
  983. SCANER:
  984.     LD    HL,FCBDN    ;POINT TO FCBDN
  985. SCAN1:
  986.     PUSH    HL        ;SAVE POINTER TO FCB
  987.     CALL    ADVAN        ;SKIP TO NON-BLANK OR END OF LINE
  988.     LD    (CIPTR),DE    ;SET POINTER TO NON-BLANK OR END OF LINE
  989.     JR    Z,SCAN3        ;END OF COMMAND LINE
  990.     SBC    A,'A'        ;CONVERT POSSIBLE DRIVE SPEC TO NUMBER
  991.     CP    16        ;VALID DRIVE?
  992.     INC    A        ;CONVERT TO DRIVE (A=1, AND SO ON)
  993.     JR    C,SCAN2        ;YES
  994.     XOR    A        ;SELECT DEFAULT DRIVE
  995.     DEC    DE        ;DON'T MOVE TO NEXT CHARACTER
  996. SCAN2:
  997.     LD    H,A        ;STORE NUMBER (A:=0, B:=1, ETC) IN H
  998.     INC    DE        ;POINT TO NEXT CHARACTER
  999.     LD    L,0        ;ZERO TOTAL
  1000.     CALL    A2NUM        ;CONVERT FIRST DIGIT
  1001.     JR    C,SCAN3        ;NOT VALID
  1002.     CALL    A2NUM        ;CONVERT SECOND DIGIT
  1003.     LD    A,L
  1004.     SET    7,L        ;MAKE VALID JUST IN CASE
  1005.     CP    MAXUSR+1    ;TOO BIG?
  1006.     JR    C,SCAN3         ;NO
  1007.     LD    A,(DE)        ;ANY ':'?
  1008.     CP    ':'
  1009.     JP    Z,NAMERR    ;YES, NAME ERROR
  1010. SCAN3:
  1011.     LD    A,(DE)        ;SEE IF LAST CHARACTER IS A COLON (:)
  1012.     INC    DE        ;POINT TO BYTE AFTER ':'
  1013.     CP    ':'
  1014.     JR    Z,SCAN4        ;YES, WE HAVE A DRIVE SPEC
  1015.     LD    HL,0        ;NOT VALID DRIVE SPEC, SWITCH TO DEFAULT
  1016.     LD    DE,(CIPTR)    ;RESTART SCAN
  1017. ;
  1018. ; EXTRACT FILENAME FROM POSSIBLE FILENAME.TYP
  1019. ;
  1020. SCAN4:
  1021.     LD    B,H        ;MOVE DRIVE TO B
  1022.     EX    (SP),HL        ;GET BACK FCB POINTER AND SAVE USER NUMBER
  1023.     LD    (HL),B        ;SAVE DRIVE
  1024.     LD    B,8         ;MAX OF 8 CHARACTERS
  1025.     XOR    A        ;CLEAR '?' COUNT
  1026.     EX    AF,AF        ;AND SAVE
  1027.     CALL    SCANF        ;GET POSSIBLE NAME
  1028.     CALL    SCANT        ;AND POSSIBLE TYPE
  1029. ;
  1030. ; FILL IN EX, S1, S2, AND RC
  1031. ;
  1032.     XOR    A
  1033.     INC    HL        ;POINT TO NEXT BYTE IN FCBDN
  1034.     LD    (HL),A        ;ZERO EX
  1035.     INC    HL
  1036.     POP    BC        ;GET BACK USER NUMBER
  1037.     LD    (HL),C        ;STUFF AWAY USER NUMBER IN S1
  1038.     INC    HL    
  1039.     LD    (HL),A        ;ZERO S2
  1040.     INC    HL
  1041.     LD    (HL),A        ;ZERO RC
  1042. ;
  1043. ; SCAN COMPLETE -- DE POINTS TO DELIMITER BYTE AFTER TOKEN
  1044. ;
  1045.     LD    (CIBPTR),DE
  1046.     EX    AF,AF        ;GET NUMBER OF '?' IN FILENAME.TYP
  1047.     RET    
  1048. ;
  1049. ; EXTRACT FILE TYPE FROM POSSIBLE FILENAME.TYP
  1050. ;
  1051. SCANT:
  1052.     LD    B,3        ;PREPARE TO EXTRACT TYPE
  1053.     CP    '.'        ;IF (DE) DELIMITER IS A '.', WE HAVE A TYPE
  1054.     JR    NZ,SCAN11    ;FILL FILE TYPE WITH <SP>
  1055.     INC    DE        ;POINT TO CHARACTER IN COMMAND LINE AFTER '.'
  1056. SCANF:
  1057.     LD    C,' '        ;FILL CHARACTER
  1058. SCAN11:
  1059.     INC    HL        ;STEP TO NEXT BYTE IN FCBN
  1060.     CALL    SDELM        ;CHECK FOR DELIMITER
  1061.     JR    Z,SCAN12    ;FILL REST WITH FILL BYTE IF A DELIMITER
  1062.     CP    '*'        ;WILD?
  1063.     JR    NZ,SCAN13    ;NO
  1064.     LD    C,'?'        ;CHANGE FILL BYTE TO '?'
  1065. SCAN12:
  1066.     DEC    DE        ;DON'T STEP OFF CURRENT SYMBOL
  1067.     LD    A,C        ;GET FILL BYTE
  1068. SCAN13:
  1069.     CP    '?'        ;QUESTION MARK?
  1070.     JR    NZ,SCAN14    ;NO, JUST STORE CHARACTER
  1071.     EX    AF,AF        ;GET QUESTION MARK COUNT
  1072.     INC    A        ;COUNT IT
  1073.     EX    AF,AF        ;AND SAVE COUNT
  1074. SCAN14:
  1075.     INC    DE        ;POINT TO NEXT CHARACTER IN COMMAND LINE
  1076.     LD    (HL),A        ;STORE CHARACTER IN FCBDN
  1077.     DJNZ    SCAN11        ;COUNT DOWN CHARACTERS IN FILE TYPE (3 MAX)
  1078. SCAN15:
  1079.     CALL    SDELM        ;SKIP REST OF CHARACTERS TO
  1080.     RET    Z        ;DELIMITER
  1081.     INC    DE
  1082.     JR    SCAN15
  1083. ;
  1084. ; CMDTBL (COMMAND TABLE) SCANNER
  1085. ;   JUMPS TO ADDRESS OF COMMAND IF CPR-RESIDENT
  1086. ;   JUMPS TO COM IF NOT CPR-RESIDENT COMMAND
  1087. ;
  1088. CMDSER:
  1089.     LD    A,(FCBFN)    ;ANY COMMAND?
  1090.     CP    ' '        ;' ' MEANS COMMAND WAS 'D:' TO SWITCH
  1091.     LD    A,(FCBS1)    ;GET USER NUMBER IF ANY
  1092.     LD    HL,FCBDN    ;POINT TO DRIVE
  1093.     JR    NZ,CMS0        ;NOT <SP>, SO MUST BE COMMAND
  1094.     ADD    A,80H        ;CONVERT TO USER NUMBER
  1095.     CALL    P,NEWUSR    ;SET IF VALID USER IN FCB
  1096.     LD    A,(HL)         ;LOOK FOR DRIVE SPEC
  1097.     DEC    A        ;ADJUST FOR LOG IN
  1098.     CALL    P,TLOGIN    ;LOG IN DRIVE
  1099. SETUDB:
  1100.     LD    A,(TMPUSR)    ;GET CURRENT USER NUMBER
  1101.     ADD    A,A        ;PLACE IT IN HIGH NIBBLE
  1102.     ADD    A,A
  1103.     ADD    A,A
  1104.     ADD    A,A
  1105.     LD    HL,TDRIVE    ;ADD DEFAULT DRIVE NUMBER (LOW NIBBLE)
  1106.     OR    (HL)
  1107.     LD    (UDFLAG),A    ;UPDATE USER/DRIVE BYTE
  1108.     RET
  1109. CMS0:
  1110.     OR    (HL)        ;DRIVE OR USER NUMBER
  1111.     JR    NZ,CMS5        ;YES, CAN'T BE BUILT IN COMMAND
  1112.     LD    HL,CMDTBL    ;POINT TO COMMAND TABLE
  1113.     LD    B,NCMNDS    ;SET COMMAND COUNTER
  1114. CMS1:
  1115.     LD    DE,FCBFN    ;POINT TO STORED COMMAND NAME
  1116. CMS2:
  1117.     LD    A,(DE)        ;COMPARE AGAINST TABLE ENTRY
  1118.     XOR    (HL)
  1119.     ADD    A,A
  1120.     JR    NZ,CMS3        ;NO MATCH
  1121.     INC    DE        ;POINT TO NEXT CHARACTER
  1122.     INC    HL
  1123.     JR    NC,CMS2        ;NOT END OF TABLE ENTRY
  1124.     LD    A,(DE)        ;NEXT CHARACTER IN INPUT COMMAND MUST BE <SP>
  1125.     CP    ' '
  1126.     JR    NZ,CMS4
  1127.     LD    A,(HL)        ;FOUND COMMAND,
  1128.     INC    HL        ;LOAD ADDRESS,
  1129.     LD    H,(HL)        ;AND
  1130.     LD    L,A        ;JUMP TO IT
  1131.     JP    (HL)        ;COMMAND IS CPR-RESIDENT
  1132. CMS3:
  1133.     BIT    7,(HL)        ;END OF TABLE ENTRY?
  1134.     INC    HL
  1135.     JR    Z,CMS3        ;NO
  1136. CMS4:
  1137.     INC    HL        ;SKIP ADDRESS
  1138.     INC    HL
  1139.     DJNZ    CMS1        ;NOT TO END OF TABLE YET
  1140. CMS5:
  1141.     JP    COM        ;COMMAND MAY BE DISK-RESIDENT
  1142. ;
  1143. ;**** Section 5 ****
  1144. ; CPR-Resident Commands
  1145. ;
  1146. ;
  1147. ;Section 5A
  1148. ;Command: DIR
  1149. ;Function: To display a directory of the files on disk.
  1150. ;Forms:
  1151. ;    DIR <afn>    Display the DIR files
  1152. ;    DIR <afn> S    Display the SYS files
  1153. ;    DIR <afn> B    Display both DIR and SYS files
  1154. ;    DIR <afn> A    Display both DIR and SYS files for all user numbers
  1155. ;
  1156. DIR:
  1157.     CALL    SCANER        ;EXTRACT POSSIBLE D:FILENAME.TYP TOKEN
  1158.     CALL    ULOGIN        ;LOG ANY USER
  1159.     LD    HL,FCBFN    ;MAKE FCB WILD (ALL '?') IF NO FILENAME.TYP
  1160.     LD    A,(HL)        ;GET FIRST CHARACTER OF FILENAME.TYP
  1161.     CP    ' '        ;IF <SP>, ALL WILD
  1162.     JR    NZ,DIR2
  1163.     LD    B,11        ;NUMBER OF CHARACTERS IN FN & FT
  1164. DIR1:
  1165.     LD    (HL),'?'    ;STORE '?'
  1166.     INC    HL
  1167.     DJNZ    DIR1
  1168. DIR2:
  1169.     CALL    ADVAN        ;LOOK AT NEXT INPUT CHARACTER
  1170.     LD    B,0FFH        ;LOAD ALL FILES FLAG
  1171.     CP    USRFLG        ;ALL FILES ON DISK?
  1172.     JR    Z,DIR4        ;YES
  1173.     LD    B,80H        ;IN CASE SYS ONLY
  1174.     CP    SOFLG        ;SYS ONLY?
  1175.     JR    Z,DIR4        ;YES
  1176.     CP    SYSFLG        ;HAVE SYSTEM SPECIFIER?
  1177.     LD    A,B        ;SET SYSTEM BIT EXAMINATION
  1178.     LD    B,0        ;SYSTEM TOKEN DEFAULT
  1179.     JR    NZ,DIRPR
  1180. DIR4:
  1181.     INC    DE
  1182.     LD    (CIBPTR),DE
  1183.     LD    A,B
  1184.     ;DROP INTO DIRPR TO PRINT DIRECTORY
  1185.     ;THEN RESTART CPR
  1186. ;
  1187. ; DIRECTORY PRINT ROUTINE; ON ENTRY, A IS 80H IF SYSTEM FILES EXCLUSIVELY
  1188. ;
  1189. DIRPR:
  1190.     LD    D,A        ;STORE SYSTEM FLAG IN D
  1191.     LD    A,B        ;SAVE SYSTST
  1192.     LD    (SYSTST),A
  1193.     XOR    A        ;SET COLUMN COUNTER TO 0
  1194.     LD    B,A        ;AND USER NUMBER JUST IN CASE
  1195. DIRPR1:
  1196.     ADD    A,03H        ;FORCE CRLF
  1197.     AND    0FCH
  1198.     LD    E,A
  1199.     PUSH    DE    
  1200.     INC    D        ;ALL USER NUMBERS?
  1201.     PUSH    BC        ;SAVE USER NUMBER
  1202.     LD    A,B        ;AND
  1203.     CALL    Z,SETUSR    ;SET IF ALL USER NUMBERS
  1204.     CALL    SEARF        ;SEARCH FOR SPECIFIED FILE (FIRST OCCURRENCE)
  1205. DIRPR2:
  1206.     POP    BC        ;GET BACK USER NUMBER
  1207.     POP    DE        ;AND SYSTEM FLAG
  1208.     JR    NZ,DIRPR4    ;FILE FOUND
  1209.     LD    A,B        ;AT LAST USER NUMBER?
  1210.     INC    B        ;STEP TO NEXT USER NUMBER
  1211.     CP    MAXUSR
  1212.     LD    A,E        ;IN CASE DONE
  1213.     JR    NC,DIRPR3    ;DONE
  1214.     LD    E,D        ;EITHER WAY, E IS GOING TO BE CHANGED
  1215.     INC    E
  1216.     JR    Z,DIRPR1    ;PRINT ALL USER NUMBERS
  1217. DIRPR3:
  1218.     AND    A        ;ANY PRINTED?
  1219.     JP    CHKFND        ;GO CHECK
  1220. ;
  1221. ; ENTRY SELECTION LOOP; ON ENTRY, A=OFFSET FROM SEARF OR SEARN
  1222. ;
  1223. DIRPR4:
  1224.     DEC    A        ;ADJUST TO RETURNED VALUE
  1225.     RRCA            ;CONVERT NUMBER TO OFFSET INTO TBUFF
  1226.     RRCA    
  1227.     RRCA    
  1228.     LD    C,A        ;OFFSET INTO TBUFF IN C (C=OFFSET TO ENTRY)
  1229.     LD    A,10        ;ADD 10 TO POINT TO SYSTEM FILE ATTRIBUTE BIT
  1230.     CALL    DIRPTR
  1231.     PUSH    DE
  1232.     AND    D        ;MASK FOR SYSTEM BIT
  1233.     INC    D        ;ALL FILES?
  1234.     JR    Z,DIRPR5    ;YES
  1235.     LD    HL,SYSTST    ;SYSTEM FILE?
  1236.     CP    (HL)
  1237.     JR    NZ,DIRPR9    ;NO
  1238. DIRPR5:
  1239.     LD    A,E        ;WHAT TO PRINT
  1240. ;
  1241.     IF    TWOCOL
  1242.     AND    01H        ;OUTPUT <CR><LF> IF 2 ENTRIES PRINTED IN LINE
  1243.     ELSE    
  1244. ;
  1245.     AND    03H        ;OUTPUT <CR><LF> IF 4 ENTRIES PRINTED IN LINE
  1246.     ENDIF    
  1247. ;
  1248.     CALL    Z,CRLF        ;NEWLINE ALWAYS RETURNS ZERO TRUE
  1249.     JR    Z,DIRPR6
  1250.     CALL    PRINT
  1251. ;
  1252.     IF    WIDE
  1253.     DEFB    '  '        ;2 SPACES
  1254.     DEFB    FENCE        ;THEN FENCE CHARACTER
  1255.     DC    '  '         ;THEN 2 MORE SPACES
  1256.     ELSE    
  1257. ;
  1258.     DEFB    ' '        ;SPACE
  1259.     DEFB    FENCE        ;THEN FENCE CHARACTER
  1260.     DC    ' '        ;THEN SPACE
  1261.     ENDIF    
  1262. ;
  1263. DIRPR6:
  1264.     POP    DE
  1265.     INC    E        ;BUMP NUMBER OF FILES LISTED
  1266.     PUSH    DE
  1267.     INC    D        ;PRINT WITH USER NUMBER?
  1268.     JR    NZ,DIRPR8    ;NO
  1269.     LD    A,B        ;GET USER NUMBER AND
  1270.     CALL    PRUSRN        ;AND PRINT
  1271.     DEFB    USRDLM+80H    ;USER NUMBER DELIMITER
  1272. DIRPR8:
  1273.     XOR    A        ;DON'T EAT SPACES
  1274.     CALL    PRFN
  1275. DIRPR9:
  1276.     PUSH    BC
  1277.     CALL    SEARN        ;GET NEXT FILENAME
  1278.     JR    DIRPR2
  1279. PRFN:
  1280.     PUSH    BC
  1281.     LD    B,A        ;SAVE EAT SPACES FLAG
  1282.     LD    A,1
  1283.     CALL    DIRPTR        ;HL NOW POINTS TO 1ST BYTE OF FILE NAME
  1284.     LD    C,B        ;SAVE EAT SPACES FLAG
  1285.     LD    B,12        ;12 CHARACTER TOTAL
  1286. PRFN1:
  1287.     LD    A,B        ;CHECK FOR FILE TYPE
  1288.     CP    04H
  1289.     LD    A,(HL)
  1290.     RES    7,A
  1291.     JR    NZ,PRFN2    ;NOT YET AT TYPE
  1292.     DEC    HL        ;ADJUST HL FOR TYPE DELIMITER
  1293.     CP    ' '        ;NO FILE TYPE?
  1294.     JR    Z,PRFN2        ;CONTINUE IF SO
  1295.     LD    A,'.'        ;FILE TYPE EXISTS, PRINT DOT
  1296. PRFN2:
  1297.     INC    HL        ;STEP TO NEXT CHARACTER
  1298.     CP    C        ;EAT SPACES?
  1299.     CALL    NZ,CONOUT
  1300.     DJNZ    PRFN1
  1301.     POP    BC
  1302.     RET    
  1303. ;
  1304. ;Section 5B
  1305. ;Command: ERA
  1306. ;Function: To erase files; names of the erased files are displayed.
  1307. ;Forms:
  1308. ;    ERA <afn>
  1309. ;
  1310. ERA:
  1311.     CALL    SCANER        ;PARSE FILE SPECIFICATION
  1312.     CP    11        ;ALL WILD (ALL FILES = 11 '?')?
  1313.     JR    NZ,ERA1        ;IF NOT, THEN DO ERASES
  1314.     CALL    REPLY
  1315.     JP    NZ,RESTRT    ;RESTART CPR IF NOT
  1316. ERA1:
  1317.     CALL    ULOGIN        ;LOG ANY USER
  1318.     XOR    A        ;PRINT ALL FILES (EXAMINE SYSTEM BIT)
  1319.     LD    B,A        ;NO SYS-ONLY OPT TO DIRPR
  1320.     CALL    DIRPR        ;PRINT DIRECTORY OF ERASED FILES
  1321. ERA2:
  1322.     LD    DE,FCBDN    ;DELETE FILE SPECIFIED
  1323.     JP    DELETE        ;REENTER CPR VIA DELETE
  1324. ;
  1325. ;Section 5C
  1326. ;Command: ERAQ
  1327. ;Function: To erase files with individual query.
  1328. ;Forms:
  1329. ;    ERAQ <afn>
  1330. ;    <afn>? Y
  1331. ;      :
  1332. ;      :
  1333. ;
  1334. ERAQ:
  1335.     CALL    SCANER        ; parse file specification
  1336.     CALL    ULOGIN        ; log any user
  1337.     LD    HL,01FFH    ; load first flag
  1338. ERAQ1:
  1339.     CALL    SEARF        ; find first entry
  1340.     JR    NZ,ERAQ2    ; found one
  1341.     INC    L        ; ever found any?
  1342. ;
  1343. ; Check for File Found
  1344. ;
  1345. CHKFND:
  1346.     RET    NZ        ; yes
  1347. ;
  1348. ; No File Error Message
  1349. ;
  1350. PRNNF:
  1351.     CALL    PRINTC        ;NO FILE MESSAGE
  1352.     DC    'No File'
  1353.     RET    
  1354. ERAQ2:
  1355.     LD    L,H        ; restart found count
  1356. ERAQ3:
  1357.     DEC    H        ; at file to erase?
  1358.     JR    NZ,ERAQ5    ; no
  1359.     INC    H        ; reset H to 1
  1360.     INC    L        ; step count in case don't delete
  1361.     PUSH    HL        ; save flag first
  1362.     DEC    A        ; compute offset
  1363.     RRCA    
  1364.     RRCA    
  1365.     RRCA    
  1366.     LD    C,A
  1367.     CALL    CRLF
  1368.     LD    A,' '        ; eat spaces
  1369.     CALL    PRFN        ; print file name
  1370.     CALL    REPLY1        ; prompt
  1371.     JR    NZ,ERAQ4    ; reply not 'Y'
  1372.     XOR    A
  1373.     CALL    DIRPTR        ; get FCB to delete
  1374.     LD    A,(FCBDN)    ; get drive specification
  1375.     LD    (HL),A        ; select drive
  1376.     EX    DE,HL
  1377.     CALL    DELETE        ; go delete
  1378.     POP    HL        ; get flags
  1379.     DEC    L        ; reduce count since file deleted
  1380.     LD    H,L        ; update next file to process
  1381.     JR    ERAQ1        ; and restart process
  1382. ERAQ4:
  1383.     POP    HL        ; get count
  1384. ERAQ5:
  1385.     CALL    SEARN        ; find next file
  1386.     JR    NZ,ERAQ3    ; more files, go ask
  1387.     RET            ; done
  1388. ;
  1389. ;Section 5D
  1390. ;Command: SAK
  1391. ;Function: To pause until a key is struck; ^C warm boots.
  1392. ;Forms:
  1393. ;    SAK
  1394. ;    ? <any key>
  1395. ;
  1396. SAK:
  1397.     CALL    CRLF        ; strike any key
  1398.     JR    REPLY1
  1399. REPLY:
  1400.     CALL    PRINTC
  1401.     DC    'All'
  1402. REPLY1:
  1403.     CALL    PRINT
  1404.     DC    '? '
  1405. REPL2:
  1406.     CALL    BREAK        ; get response
  1407.     JR    Z,REPL2        ; none
  1408.     CALL    UCASE
  1409.     CP    'Y'
  1410.     RET    
  1411. ;
  1412. ;Section 5E
  1413. ;Command: BELL
  1414. ;Function: To ring terminal bell.
  1415. ;Forms:
  1416. ;    BELL
  1417. ;
  1418. RING:
  1419.     LD    A,BELL        ; load bell into A
  1420.     JP    CONOUT        ; and output it
  1421. ;
  1422. ;Section 5F
  1423. ;Command: LIST
  1424. ;Function: To print specified file on list device.
  1425. ;Forms:
  1426. ;    LIST <ufn>    Print file
  1427. ;    LIST <ufn> P    Print file without default paging
  1428. ;
  1429. LIST:
  1430. ;
  1431.     IF    FFKILL
  1432.     LD    HL,NLINEP+0580H    ; lines/page, first ff and list flags
  1433.     ELSE    
  1434.     LD    HL,NLINEP+0500H    ; lines/page and list flag
  1435.     ENDIF    
  1436. ;
  1437.     JR    TYPE1
  1438. ;
  1439. ;Section 5G
  1440. ;Command: TYPE
  1441. ;Function: To display specified file on console.
  1442. ;Forms:
  1443. ;    TYPE <ufn>    Display file
  1444. ;    TYPE <ufn> P    Display file without default paging
  1445. ;
  1446. TYPE:
  1447. ;
  1448.     IF    FFKILL
  1449.     LD    HL,NLINES+0280H    ; lines/page, first ff and type flags
  1450.     ELSE    
  1451.     LD    HL,NLINES+0200H    ; lines/page and type flag
  1452.     ENDIF    
  1453. ;
  1454. TYPE1:
  1455.     LD    (LNCNT),HL    ; save list/type flag and line cnt
  1456.     XOR    A        ; initialize tab count
  1457.     LD    (TABCNT),A    ; initialize line and tab count
  1458.     CALL    SCANER        ; extract filename.typ token
  1459.     JP    NZ,NAMERR    ; error if any question mark
  1460.     CALL    ADVAN        ; get pgdflg if it's there
  1461.     JR    Z,PGDON         ; jump if no more on cmd line
  1462.     XOR    PGDFLG        ; change page flag?
  1463.     JR    NZ,PGDON    ; no
  1464.     INC    DE        ; step over pgdflg
  1465.     LD    (CIBPTR),DE    ; and save cmd buffer pointer
  1466.     DEC    A        ; no page flag is 0ffh
  1467.     LD    (LNCNT),A    ; save flag
  1468. PGDON:
  1469.     CALL    ULOGIN        ; log any user
  1470.     CALL    OPENF        ; open selected file
  1471.     JR    Z,TYPE3        ; abort if error
  1472.     CALL    CRLF        ; new line
  1473. TYPE2:
  1474.     CALL    READF        ; read next block
  1475.     JR    Z,TYPE4        ; read ok (A register is zero)
  1476.     DEC    A        ; error or eof?
  1477.     RET    Z        ; eof
  1478. TYPE3:
  1479.     JP    PRNNF        ; error
  1480. CHK4LF:
  1481.     LD    A,(LNCNT)    ; get line count (just in case)
  1482.     DJNZ    CHK4VT        ; not lf, try vertical tab
  1483.     RES    7,A        ; reset first ff flag (if any)
  1484.     CP    07FH         ; paging off?
  1485.     JR    Z,CHK4VT    ; yes
  1486.     DEC    A        ; time to page?
  1487.     JR    Z,CHKFF        ; yes!
  1488. CHK4VT:
  1489.     DEC    B        ; step over vt
  1490. CHK4FF:
  1491.     DJNZ    CHK4CR        ; not ff, try vt
  1492.     BIT    7,A        ; first ff?
  1493.     JR    NZ,NXTCHR    ; yes, ignore
  1494. CHKFF:
  1495.     LD    A,(TYPLST)
  1496.     BIT    0,A        ; type or list?
  1497.     LD    E,FF        ; load ff into character reg
  1498.     LD    A,NLINEP    ; reset list count
  1499.     JR    NZ,CHK4CR    ; list
  1500. CHKFF1:
  1501.     LD    C,06H        ; direct console i/o
  1502.     LD    E,0FFH        ; conditional console input
  1503.     CALL    BDOSJP
  1504.     JR    Z,CHKFF1    ; no character yet
  1505.     CALL    CHKETX        ; check for ^C
  1506.     LD    A,NLINES    ; type line count
  1507.     LD    E,LF
  1508. CHK4CR:
  1509.     LD    (LNCNT),A    ; save line count
  1510.     CALL    PAGER        ; output character
  1511.     DJNZ    NXTCHR        ; not cr
  1512.     LD    (HL),B        ; reset tab count
  1513. NXTCHR:
  1514.     LD    A,(CHRCNT)    ; get buffer pointer
  1515.     INC    A        ; step to next character
  1516.     CP    128        ; end-of-buffer?
  1517.     JR    NC,TYPE2    ; yes, read next buffer
  1518. TYPE4:
  1519.     LD    (CHRCNT),A    ; save buffer count
  1520.     LD    HL,TBUFF    ; point to buffer
  1521.     CALL    ADDAH        ; compute address of next character
  1522.     LD    A,(HL)        ; get character to accumulator
  1523.     AND    7FH        ; mask out msb
  1524.     CP    1AH        ; end-of-file (^Z)?
  1525.     RET    Z        ; yes, restart zcpr
  1526.     LD    HL,TABCNT    ; pointer to tab counter
  1527.     LD    E,A        ; save character in e reg
  1528.     SUB    BS        ; backspace?
  1529.     LD    B,A        ; in case not bs
  1530.     JR    NZ,CHK4HT    ; not bs
  1531.     DEC    (HL)        ; step tab count and fall thru
  1532. CHK4HT:
  1533.     DJNZ    CHK4LF        ; no, check for line feed
  1534. CHKHT:
  1535.     LD    E,' '        ; load space into bdos character reg
  1536.     CALL    PAGER        ; print space
  1537.     LD    A,(HL)        ; now in col 0 mod 8?
  1538.     AND    07H
  1539.     JR    NZ,CHKHT    ; go for more
  1540.     JR    NXTCHR
  1541. PAGER:
  1542.     CALL    BREAK        ; check for abort
  1543.     LD    A,(TYPLST)    ; get list/type flag
  1544.     LD    C,A
  1545. ;
  1546.     IF    TEST OR NOT NOSTAT
  1547.     AND    00000010B    ; list?
  1548.     EXX            ; save registers
  1549.     CALL    Z,LISTST    ; check busy
  1550.     EXX            ; restore registers
  1551.     AND    A
  1552.     JR    Z,PAGER        ; printer not ready
  1553.     ENDIF
  1554. ;
  1555.     LD    A,E        ; check for printing character
  1556.     CP    ' '
  1557.     JR    C,PAGE2        ; control character, don't count
  1558.     INC    (HL)        ; step position
  1559. PAGE2:
  1560.     JP    BDOSJP        ; return via bdos
  1561. ;
  1562. ;Section 5H
  1563. ;Command: PAGE
  1564. ;Function: To eject a page on list device via a form feed.
  1565. ;Forms:
  1566. ;    PAGE
  1567. ;
  1568. EJECT:
  1569.     CALL    BREAK        ; check for ^C
  1570. ;
  1571.     IF    TEST OR NOT NOSTAT
  1572.     CALL    LISTST        ; check printer ready
  1573.     AND    A
  1574.     JR    Z,EJECT         ; not ready yet
  1575.     ENDIF
  1576. ;
  1577.     LD    E,FF        ; now for form feed
  1578.     LD    C,05H        ; list output
  1579.     JP    BDOS        ; output character and return via bdos
  1580. ;
  1581. ;Section 5I
  1582. ;Command: SAVE
  1583. ;Function: To save the contents of TPA onto disk as a file. Number of
  1584. ;         pages or records is in decimal. Saved area begins at 100H.
  1585. ;Forms:
  1586. ;    SAVE <Number of Pages> <ufn>
  1587. ;    SAVE <Number of Records> <ufn> R
  1588. ;
  1589. SAVE:
  1590.     CALL    NUMBER        ;EXTRACT NUMBER FROM COMMAND LINE
  1591.     PUSH    HL        ;SAVE IT
  1592.     CALL    SCANER        ;EXTRACT FILENAME.TYP
  1593.     JP    NZ,NAMERR    ;MUST BE NO '?' IN IT
  1594.     CALL    ULOGIN        ;LOG ANY USER
  1595.     CALL    ERA2        ;DELETE FILE IF POSSIBLE
  1596.     CALL    CREATE        ;CREATE NEW FILE
  1597.     JR    Z,SAVE4        ;UNSUCCESSFUL
  1598.     XOR    A        ;SET RECORD COUNT FIELD OF NEW FILE'S FCB
  1599.     LD    (FCBCR),A
  1600.     CALL    ADVAN        ;LOOK FOR RECORD OPTION
  1601.     INC    DE        ;POINT TO TOKEN
  1602.     POP    HL        ;GET BACK PAGE COUNT
  1603.     CP    RECFLG
  1604.     JR    Z,SAVE1
  1605.     DEC    DE        ;NO TOKEN, SO BACK UP
  1606.     ADD    HL,HL        ;DOUBLE IT FOR HL=RECORD (128 BYTES) COUNT
  1607. SAVE1:
  1608.     LD    (CIBPTR),DE    ;SET POINTER TO BAD TOKEN OR AFTER GOOD TOKEN
  1609.     LD    DE,TPA        ;POINT TO START OF SAVE AREA (TPA)
  1610. SAVE2:
  1611.     LD    A,H        ;DONE WITH SAVE?
  1612.     OR    L        ;HL=0 IF SO
  1613.     JR    NZ,SAVE3
  1614.     LD    DE,FCBDN    ;CLOSE SAVED FILE
  1615.     JP    CLOSE        ;AND RESTART CPR
  1616. SAVE3:
  1617.     DEC    HL        ;COUNT DOWN ON RECORDS
  1618.     PUSH    HL        ;SAVE POINTER TO BLOCK TO SAVE
  1619.     CALL    DMASET        ;SET DMA ADDRESS FOR WRITE (ADDRESS IN DE)
  1620.     LD    HL,128        ;128 BYTES PER RECORD
  1621.     ADD    HL,DE        ;POINT TO NEXT RECORD
  1622.     LD    DE,FCBDN    ;WRITE RECORD
  1623.     CALL    WRITE
  1624.     EX    DE,HL        ;GET POINTER TO NEXT RECORD IN DE
  1625.     POP    HL        ;GET RECORD COUNT
  1626.     JR    Z,SAVE2        ;NO WRITE ERROR
  1627. SAVE4:
  1628.     JP    PRNLE        ;PRINT 'NO SPACE' ERROR
  1629. ;
  1630. ;Section 5J
  1631. ;Command: REN
  1632. ;Function: To change the name of an existing file.
  1633. ;Forms:
  1634. ;    REN <newufn>=<oldufn>
  1635. ;
  1636. REN:
  1637.     LD    HL,FCBDN+16    ;PLACE FILENAME IN SECOND HALF OF FCB
  1638.     PUSH    HL        ;SAVE POINTER FOR SEARCH FIRST
  1639.     CALL    SCAN1        ;EXTRACT FILE NAME
  1640.     JR    NZ,NAMERR    ;ERROR IF ANY '?' IN IT
  1641.     CALL    ADVAN        ;ADVANCE CIBPTR
  1642.     CP    '='        ;'=' OK
  1643.     JP    NZ,ERROR
  1644.     EX    DE,HL        ;POINT TO CHARACTER AFTER '=' IN HL
  1645.     INC    HL
  1646.     LD    (CIBPTR),HL    ;SAVE POINTER TO OLD FILE NAME
  1647.     CALL    SCANER        ;EXTRACT FILENAME.TYP TOKEN
  1648.     JR    NZ,NAMERR    ;ERROR IF ANY '?'
  1649.     LD    A,(FCBDN+16+13)    ;GET POSSIBLE USER NUMBER
  1650.     CALL    ALOGIN        ;LOG ANY USER
  1651.     POP    DE         ;GET POINTER FOR SEARCH FIRST
  1652.     CALL    SEARDE        ;CHECK FOR NONE OF THAT NAME
  1653.     JR    Z,REN1         ;NO FILE EXISTS
  1654.     CALL    PRINTC        ;DUPLICATE NAME
  1655.     DC    'Delete'
  1656.     CALL    REPLY1        ;GET REPLY
  1657.     JR    NZ,REN2        ;NOT A 'Y'
  1658.     CALL    DELETE        ;DELETE DUPLICATE
  1659. REN1:
  1660.     LD    A,(DE)        ;GET POSSIBLE DRIVE
  1661.     LD    DE,FCBDN    ;POINT TO FCB
  1662.     LD    (DE),A        ;SAVE POSSIBLE DRIVE
  1663.     LD    C,17H        ;BDOS RENAME FCT
  1664.     CALL    BDOSFN
  1665.     JP    CHKFND        ;CHECK FOR FILE FOUND
  1666. NAMERR:
  1667.     CALL    PRINTC
  1668.     DC    'Name Error'
  1669. REN2:
  1670.     JP    ABORT
  1671. ;
  1672. ;Section 5K
  1673. ;Command: USER
  1674. ;Function: To change current user number; new user number is in decimal.
  1675. ;Forms:
  1676. ;    USER <usrnum>
  1677. ;
  1678. USER:
  1679.     CALL    USRNUM        ;EXTRACT USER NUMBER FROM COMMAND LINE
  1680.     JP    NEWUSR        ;SET NEW USER NUMBER
  1681. ;
  1682. ;Section 5L
  1683. ;Command: DFU
  1684. ;Function: To set the Default User Number for the command/file scanner; new
  1685. ;         default user number is in decimal.
  1686. ;Forms:
  1687. ;    DFU <usrnum>
  1688. ;
  1689. DFU:
  1690.     CALL    USRNUM        ;GET USER NUMBER
  1691.     LD    (DFUSR),A    ;PUT IT AWAY
  1692.     RET
  1693. ;
  1694. ;Section 5M
  1695. ;Command: SCL
  1696. ;Function: To force ZCPR to parse only a single command per line; reset
  1697. ;         to multiple command format at the next ^C.
  1698. ;Forms:
  1699. ;    SCL
  1700. ;
  1701.     IF    MULTPL
  1702. SINGLE:
  1703.     LD    HL,NEWCMD    ; point at current command separator
  1704.     LD    A,CMDCHR    ; get default command separator
  1705.     XOR    (HL)        ; flip current separator
  1706.     LD    (HL),A        ; save new command separator
  1707.     RET
  1708.     ENDIF
  1709. ;
  1710. ;
  1711. ;Section 5N
  1712. ;Command: PEEK
  1713. ;Function: To display hex values beginning at a specified address.
  1714. ;Forms:
  1715. ;    PEEK <hexadr> [<hexcnt>]
  1716. ;
  1717. PEEK:
  1718.     CALL    HEXNUM        ; get display address
  1719.     PUSH    HL        ; save it
  1720.     CALL    HEXNUM        ; get optional count
  1721.     LD    C,L        ; save count
  1722.     POP    HL        ; get back address
  1723. PEEK1:
  1724.     CALL    CRLF        ; start new line
  1725.     CALL    PRHEXW        ; print address
  1726.     LD    B,16        ; 16 values per line
  1727. PEEK2:
  1728.     CALL    PRINT        ; space over
  1729.     DC    ' '
  1730.     LD    A,(HL)        ; get hex value
  1731.     INC    HL        ; step to next value
  1732.     CALL    PRHEXA        ; display value
  1733.     DEC    C        ; done?
  1734.     RET    Z        ; yes
  1735.     DJNZ    PEEK2        ; not end of line
  1736.     JR    PEEK1        ; end of line
  1737. PRHEXW:
  1738.     LD    A,H        ; print hex word in hl
  1739.     CALL    PRHEXA
  1740.     LD    A,L
  1741. PRHEXA:
  1742.     PUSH    AF        ; save right nibble
  1743.     RRCA            ; move left nibble to right
  1744.     RRCA
  1745.     RRCA
  1746.     RRCA
  1747.     CALL    PRHEX        ; display left nibble
  1748.     POP    AF        ; get back right nibble
  1749. PRHEX:
  1750.     AND    0FH        ; convert to ascii
  1751.     ADD    A,90H
  1752.     DAA
  1753.     ADC    A,40H
  1754.     DAA
  1755.     JP    CONOUT        ; go display value
  1756. ;
  1757. ;
  1758. ;Section 5O
  1759. ;Command: POKE
  1760. ;Function: To poke a string of hex values into a set of consecutive addresses.
  1761. ;Forms:
  1762. ;    POKE <hexadr> <hexval> [<hexval>]
  1763. ;
  1764. POKE:
  1765.     CALL    HEXNUM        ; get address
  1766. POKE1:
  1767.     PUSH    HL        ; save address
  1768.     CALL    HEXNUM        ; get next byte
  1769.     LD    A,(FCBFN)    ; done?
  1770.     CP    ' '
  1771.     LD    A,L        ; save byte
  1772.     POP    HL        ; get back address
  1773.     RET    Z        ; done
  1774.     LD    (HL),A        ; save byte
  1775.     INC    HL        ; step to next address
  1776.     JR    POKE1        ; go for more
  1777. ;
  1778. ;
  1779. ;Section 5P
  1780. ;Command: JUMP
  1781. ;Function: To call the program (subroutine) at the specified address
  1782. ;         without loading from disk.
  1783. ;Forms:
  1784. ;    JUMP <hexadr> <command tail>
  1785. ;
  1786. JUMP:
  1787.     CALL    HEXNUM        ;GET LOAD ADDRESS IN HL
  1788.     JR    CLLPRG        ;PERFORM CALL
  1789. ;
  1790. ;Section 5Q
  1791. ;Command: COM file processing
  1792. ;Function: To load the specified COM file from disk and execute it.
  1793. ;Forms:
  1794. ;    <command> <command tail>
  1795. ;
  1796. COM:
  1797.     LD    HL,FCBFT    ;FILE TYPE MUST BE BLANK
  1798.     LD    A,(HL)
  1799.     CP    ' '
  1800.     JP    NZ,ERROR
  1801.     LD    (HL),'C'    ;PLACE DEFAULT FILE TYPE (COM) INTO FCB
  1802.     INC    HL        ;COPY INTO FILE TYPE
  1803.     LD    (HL),'O'    ;3 BYTES
  1804.     INC    HL
  1805.     LD    (HL),'M'
  1806.     LD    HL,TPA        ;SET EXECUTION/LOAD ADDRESS
  1807.     CALL    MEMLD        ;LOAD MEMORY WITH FILE SPECIFIED
  1808.                  ;(NO RETURN IF ERROR OR TOO BIG)
  1809. ;
  1810. ;Section 5R
  1811. ;Command: GO
  1812. ;Function: To call the program in the TPA without loading from disk.
  1813. ;         Same as JUMP 100H, but more convenient, especially when
  1814. ;         used with parameters for programs like STAT.
  1815. ;Form:
  1816. ;    GO <command tail>
  1817. ;
  1818. GO:
  1819.     LD    HL,TPA        ;ALWAYS TO TPA
  1820. ;
  1821. ;
  1822. ; CLLPRG IS THE ENTRY POINT FOR THE EXECUTION OF THE LOADED PROGRAM
  1823. ;   ON ENTRY TO THIS ROUTINE, HL MUST CONTAIN THE EXECUTION
  1824. ;   ADDRESS OF THE PROGRAM (SUBROUTINE) TO EXECUTE
  1825. ;
  1826. CLLPRG:
  1827.     PUSH    HL        ;SAVE EXECUTION ADDRESS
  1828.     LD    HL,(CIBPTR)    ;SAVE THE COMMAND TAIL START ADDRESS
  1829.     PUSH    HL
  1830.     LD    HL,TFCB        ;MAKE FCB FOR PROGRAM
  1831.     CALL    SCAN1        ;SEARCH COMMAND LINE FOR NEXT TOKEN
  1832.     LD    HL,TFCB+16    ;OFFSET FOR 2ND FILE SPEC
  1833.     CALL    SCAN1        ;SCAN FOR IT AND LOAD IT INTO FCBDN+16
  1834.     XOR    A
  1835.     LD    (TFCB+32),A    ;ZERO RECORD COUNT
  1836. ;
  1837. ; LOAD COMMAND LINE INTO TBUFF
  1838. ;
  1839.     POP    HL        ;GET LOCATION OF COMMAND TAIL
  1840. NEWCMD    EQU    $+1        ;IN-LINE COMMAND SEPARATOR
  1841.     LD    BC,CMDCHR+0FF00H;INITIALIZE COUNT AND GET COMMAND FLAG
  1842.     LD    DE,TBUFF    ;DESTINATION FOR COMMAND TAIL
  1843. COM2:
  1844.     INC    DE        ;POINT TO DESTINATION
  1845.     INC    B        ;INCREMENT CHARACTER COUNT
  1846.     LD    A,(HL)        ;COPY CHARACTER TO TBUFF
  1847.     LD    (DE),A
  1848.     INC    HL        ;STEP TO NEXT SOURCE CHARACTER
  1849.     OR    A        ;END OF LINE?
  1850. ;
  1851.     IF    MULTPL
  1852.     JR    Z,COM3        ;YES, END OF LINE
  1853.     XOR    C        ;START OF NEXT COMMAND?
  1854.     JR    NZ,COM2        ;NO
  1855.     LD    (DE),A        ;0 TERMINATE STRING
  1856. COM3:
  1857. ;
  1858.     ELSE
  1859. ;
  1860.     JR    NZ,COM2        ;NOT END OF LINE
  1861.     ENDIF
  1862. ;
  1863.     LD    A,B        ;SAVE CHARACTER COUNT
  1864.     LD    (TBUFF),A
  1865.     DEC    HL        ;BACK UP ONE CHARACTER
  1866.     LD    (CIBPTR),HL    ;SAVE FOR START OF NEXT COMMAND SCAN
  1867. ;
  1868. ; RUN LOADED TRANSIENT PROGRAM
  1869. ;
  1870.     CALL    CRLF        ;NEW LINE
  1871.     CALL    DEFDMA        ;SET DMA TO 0080
  1872.     CALL    RSTUSR        ;RESET TO PROPER USER NUMBER
  1873. ;
  1874. ; EXECUTION (CALL) OF PROGRAM (SUBROUTINE) OCCURS HERE
  1875. ;
  1876.     RET            ;CALL TRANSIENT
  1877. ;
  1878. ;Section 5S
  1879. ;Command: GET
  1880. ;Function: To load the specified file from disk to the specified address
  1881. ;Forms:
  1882. ;    GET <hexadr> <ufn> Load the specified file at the specified page;
  1883. ;
  1884. GET:
  1885.     CALL    HEXNUM        ;GET LOAD ADDRESS IN HL
  1886.     PUSH    HL        ;SAVE ADDRESS
  1887.     CALL    SCANER        ;GET FILE NAME
  1888.     POP    HL        ;RESTORE ADDRESS
  1889.     JP    NZ,NAMERR    ;MUST BE UNAMBIGUOUS
  1890. ;
  1891. ; LOAD MEMORY WITH COMMAND LINE FILE 
  1892. ;   ON INPUT, HL CONTAINS STARTING ADDRESS TO LOAD
  1893. ;   IF COM FILE TOO BIG, EXIT TO ERROR.
  1894. ;
  1895. MEMLD:
  1896.     LD    (LDADR),HL    ;SET LOAD ADDRESS
  1897. ;
  1898. ;   MLA is a reentry point for a non-standard CP/M Modification
  1899. ; This is the return point when the .COM (or GET) file is not found the
  1900. ; first time, the Default User is selected for the second attempt
  1901. ; and Drive A is selected for the final attempt.
  1902. ;
  1903. MLA:
  1904.     CALL    ULOGIN        ;LOG ANY USER
  1905.     LD    HL,(FCBS1)    ;SAVE ANY USER NUMBER
  1906.     CALL    OPENF        ;OPEN COMMAND.COM FILE
  1907.     JR    NZ,MLA1        ;FILE FOUND - LOAD IT
  1908. ;
  1909. ; FILE NOT FOUND - SELECT DEFAULT USER
  1910. ;
  1911.     LD    A,L         ;GET FCB USER
  1912.     AND    A        ;DEFAULT USER?
  1913.     JR    NZ,MLA0        ;NO
  1914.     LD    HL,TMPUSR    ;CURRENT USER SAME AS DEFAULT?
  1915.     LD    A,(DFUSR)    ;GET DEFAULT USER
  1916.     CP    (HL)
  1917.     SET    7,A        ;MAKE INTO VALID USER NUMBER
  1918.     LD    (FCBS1),A    ;PUT USER INTO FCB
  1919.     JR    NZ,MLA        ;AND TRY AGAIN
  1920. ;
  1921. ; FILE NOT FOUND - SELECT DRIVE A IF DEFAULT WAS SOME OTHER DRIVE
  1922. ;
  1923. MLA0:
  1924.     LD    A,(TDRIVE)    ;DRIVE A DEFAULT?
  1925.     AND    A
  1926.     JR    Z,MLA3         ;YES, ERROR
  1927.     XOR    A
  1928.     LD    HL,FCBDN    ;POINT AT DRIVE IN FCB
  1929.     OR    (HL)        ;DRIVE ALREADY SPECIFIED?
  1930.     LD    (HL),1        ;SELECT DRIVE A
  1931.     JR    Z,MLA        ;NO, GO GIVE IT A TRY
  1932. MLA3:
  1933.     CALL    PRNNF        ;CAN'T FIND FILE
  1934.     JR    PRNLE1
  1935. ;
  1936. ; FILE FOUND -- PROCEED WITH LOAD
  1937. ;
  1938. MLA1:
  1939.     LD    HL,(LDADR)    ;GET START ADDRESS OF MEMORY LOAD
  1940. MLA2:
  1941.     LD    A,ENTRY/256-1    ;GET HIGH-ORDER ADR OF JUST BELOW CPR
  1942.     CP    H        ;ARE WE GOING TO OVERWRITE THE CPR?
  1943.     JR    C,PRNLE        ;ERROR IF SO
  1944.     EX    DE,HL        ;MOVE LOAD ADDRES FOR DMASET
  1945.     CALL    DMASET        ;SET DMA ADDRESS
  1946.     LD    HL,128        ;COMPUTE NEXT LOAD ADDRESS
  1947.     ADD    HL,DE        ;AND SAVE ANSWER IN HL
  1948.     CALL    READF        ;READ NEXT RECORD
  1949.     JR    Z,MLA2        ;READ ERROR OR EOF?
  1950.     DEC    A        ;LOAD COMPLETE
  1951.     JP    Z,RSTUSR    ;GO RESET CORRECT USER
  1952. ;
  1953. ; LOAD ERROR
  1954. ;
  1955. PRNLE:
  1956.     CALL    PRINTC
  1957.     DC    'Full'
  1958. PRNLE1:
  1959.     JP    ABORT
  1960. ;
  1961.     IF    (($-ENTRY) GT ZCPRSZ)
  1962.     *ZCPR too large!!*
  1963.     ENDIF
  1964. ;
  1965.     IF    TEST
  1966. LISTST:
  1967.     LD    A,2DH        ;COMPUTE LIST STATUS ENTRY
  1968.     DEFB    0FEH        ;SKIP NEXT BYTE
  1969. BOOT:
  1970.     XOR    A        ;COMPUTE BOOT ENTRY
  1971.     LD    HL,(BASE+1)    ;GET PAGE ADDRESS OF BIOS
  1972.     LD    L,A        ;ADD ENTRY
  1973.     JP    (HL)        ;GO TO BIOS ROUTINE
  1974.     ENDIF
  1975.  
  1976. ENDLD    EQU    $
  1977.  
  1978.     END    
  1979.  
  1980.