åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå ********
;
;	This CPR is divided into a number of major sections.  The following
; is an outline of these sections and the names of the major routines
; located therein.
;
; Section	Function/Routines
; -------	-----------------
;
;   --		Opening Comments, Equates, and Macro Definitions
;
;    0		JMP Table into CPR
;
;    1		Buffers
;
;    2		CPR Starting Modules
;			CPR1	CPR	RESTRT	RSTCPR	RCPRNL
;			PRNNF	CMDTBL
;
;    3		Utilities
;			CRLF	CONOUT	CONIN	LCOUT	LSTOUT
;			READF	READ	BDOSmost obvious differences between NZCPR and ZCPR are the security
; features, controlled by additional conditional assembly flags. Such
; features restrict access to ZCPR intrinsic commands, add additional
; levels of .COM file searching, and prevent access to higher drives
; or user levels, with either internal or external password control of
; these features. Less obvious differences involve code optimization to
; gain space, and some minor bug fixes in the TYPE command.
;
;******** Structure NotesååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååCURE -  TRUE to conditionally disable potentially-harmful
;	       commands (GO, ERA, SAVE, REN, DFU, GET, JUMP). Under
;	       SECURE, if WHEEL contains RESTRCT, do not accept those
;	       commands, and search for COM files under current user
;	       then user "DEFUSR" only. If WHEEL does not contain
;	       RESTRCT (presumably from passworded change), allow
;	       all commands, and search current user, then last user
;	       set by DFU (originally "RESUSR"), then user "DEFUSR"
;	       forick
;		HEW - Hal Walchli
;
;   In an attempt to maintain a link to the past, changes between the
; current version of NZCPR are provided as both a difference file
; between NZCPR's (NZ14-16.DIF) and as a difference between the current
; version and the "official" ZCPR V1.0 (NZCPR-16.DIF).  These changes
; are made and supported by individuals in contact with each other through
; the Hyde Park RCPM in Chicago. Make comments or complaints there, to
; SBB or PST or anyone else interested.
;
;   The 2%·Â	Í‹É*-"Ã*$$$     SUBqÕ:(=2(þÿÊN
*$å*&Á
w*$#"$*&#"&Ã'
É!"N*´MÍ^Í7	!)6:¬!)¾Ú¾
*Në*²DMÍ†	·ÍÃ2*þÊ­
:*þÊ—
”Í¯	*N"Pë*²6:¬2)Ã·
€*N"N!)€ €$@€BA$!	A ‚"!$"„"ÃÉÃ]xsub*"-!/"*"+!"á"¼éÃÉ1Þ	MÍ*!€"ºÍ!"*¼é
(xsub active)$áå|þÿÒ*yþ
Ê¥þÂ*ë"ºëÃ*7Í*É*ºëÍ*ÉÅÕÍxÑÁÍ*õÍñÉÍ‹<ÉÕÍ›Ñ
ÊÕ:%·Ê*=26Í‹!7^#6#6
#6$	8Í*á7¾Úæ~O#w#Âé!6:6= COM files, giving access with password to an
;	       additional level of COM files.
;
;	       (Note: WHEEL must point to a safe place in memory that
;		won't be overlayed)
;
;	If you have chosen a SECURE system,  all resident commands may be
; activated by entering:  PASS <password> <cr>  Where <password> is a sequence
; of characters placed at PASSID (if INPASS is true, otherwise, see
; documentation in PST's PASS.ASM).  If the password is incorrect. the system
; will come back with PASS? as iow Designs, P&T, Heath
; Org-0 to name a few) have the CCP located at a non-standard address in
; the SYSGEN Image
;
;CPRR	EQU	0E00H-CPRLOC	;DDT LOAD OFFSET FOR APPLE SOFTCARD 56K
CPRR	EQU	0a000H-CPRLOC	;DDT LOAD OFFSET for itt cp/m
;CPRR	EQU	1600H-CPRLOC	;DDT LOAD OFFSET FOR COMPUPRO DISK-1
;CPRR	EQU	1100H-CPRLOC	;DDT LOAD OFFSET FOR MORROW DESIGNS
	ENDIF
;
RAS	EQU	FALSE	;SET TO TRUE IF CPR IS FOR A REMOTE-ACCESS SYSTEM
			;AND YOU DON'T WANT TO RUN SECURE (FOO...)
;
USRMAX	EQU	0000H		;LOCATIOode, CPRTYP must be set TRUE as well, or this
;		symbol will be ignored.
;
;    CPRDIR -	Set to TRUE to generate code for intrinsic DIR command.
;		Note that unlike the various directory programs, a
;		restricted DIR command here allows displaying the names
;		of SYS file ONLY, so many RCPM operators WANT this code.
;
;  Remember, you only get a total of 2048 (0800H) bytes of space for
; ALL of the generated code, or many other areas of your system
; generation will be affected. For example, to besonally, I think CAF and others should fix
;	       their BIOS instead. Mine works right...SBB).
;
;    USRMAX -  Maximum legal user # + 1 stored in this location. 0000H
;	       disables this feature, and uses the value of MAXUSR+1 instead.
;
;    BASE - Base Address of user's CP/M system (normally 0 for DR version)
;           This equate allows easy modification by non-standard CP/M (eg,H89)
;
;    CPRLOC - Base Page Address of CPR; this value can be obtained by running
;	      the BDOSLOC prog    word, all of the normal commands pop into existance.
;
;    MAXDRIV - Maximum legal drive number stored in this location.
;	       (0 means only A:, etc.)  0000H disables this feature.
;	       The value MAXDR is stuffed into MAXDRIV at cold boot,
;	       and presumably will be changed later by a passworded
;	       program if desired.
;
;	       (This code is in addition to BIOS checks. It's needed here
;	       because X: can hang if X: is off line in some BIOS
;	       implementations. Per in the following line:
;
CPRLOC	EQU	0D400H	;FILL IN WITH BDOSLOC SUPPLIED VALUE
;
; Note that you should only use one method or the other.
; Do NOT define CPRLOC twice!
;
; The following gives the required offset to load the CPR into the
; CP/M SYSGEN Image through DDT (the Roffset command); Note that this
; value conforms with the standard value presented in the CP/M reference
; manuals, but it may not necessarily conform with the location of the
; CCP in YOUR CP/M system; several systems (Morr code for intrinsic TYPE command.
;
;    WSTYPE -	Set to TRUE to generate an extra three lines of code
;		to correctly interpret the WordStar (tm) internal
;		end of line hyphen for display, which is the ASCII
;		NEWLINE code (1FH) and normally non-printing or
;		troublemaking -- thanks to PJH for this one. CPRTYP
;		must be TRUE, or this symbol will be ignored.
;
;    CPRLST -	Set to TRUE to generate code for intrinsic LIST command.
;		Since almost all of the LIST code is common to the
;		TYPE cIf you want
; to call a transient program by an intrinsic, then CHANGE THE INTRINSIC
; NAME IN THE TABLE. Even setting the name to blanks is fine to get
; rid of it. The point is, don't remove features others may want, just
; because you disagree, then throw it back in our laps. For those who
; simply MUST be rid of these commands, the following symbols control
; generation of the code in a CLEAN ACCEPTABLE fashion that allows
; others to have these features:
;
;    CPRTYP -	Set to TRUE to generate, set
;	       this equate false if you want to use USERPW or some other pgm.
;
;    RAS    -  Remote-Access System; setting this equate to TRUE disables
;	       certain CPR commands that are considered harmful in a Remote-
;	       Access environment; use under Remote-Access Systems (RBBS) for
;	       security purposes.  Note: SECURE is the direct enemy of RAS,
;	       DON'T define both equates or you will be VERY sorry.
;	       The advantage SECURE has over RAS is that by saying a magic
;	   ANDARD CP/M)
;
	IF	REL
CPRLOC	EQU	0	;MOVCPM IMAGE
	ELSE
;
; If REL is FALSE, the value of CPRLOC may be set in one
; of two ways.  The first way is to set MSIZE and BIOSEX
; as described above using the following three lines:
;
;MSIZE	EQU	56	;SIZE OF MEM IN K-BYTES
;BIOSEX	EQU	2	;EXTRA # K-BYTES IN BIOS
;CPRLOC	EQU	3400H+(MSIZE-20-BIOSEX)*1024	;CPR ORIGIN
;
; The second way is to obtain the origin of your current
; CPR using BDSLOC or its equivalent, then merely set CPRLOC
; to that value asg on ERASE, and so on.
;
***************************************************************************
** Be careful when playing with different combinations of these equates. **
** You might not have enough memory to some combinations.  Check this    **
** if you have problems, if they still persist, gripe to me (PST).       **
***************************************************************************
;
REL	EQU	FALSE	;SET TO TRUE FOR MOVCPM INTEGRATION
;
BASE	EQU	0	;BASE OF CP/M SYSTEM (SET FOR STlected files at once.
;
;  Various individuals keep trying to yank out the TYPE, LIST, and DIR
; commands, either to use the space for other options or just because
; they prefer replacement COM files. To these individuals, I (SBB) say
; keep your paws off these commands. For compatibility with the stock
; CCP, intrinsic DIR and TYPE commands are required. And many users in
; MY neighborhood find it more convenient to use the intrinsic LIST
; command than to have a LIST/PRINT program on every disk. f it was looking for a COM file.
;	NORM is the reverse of PASS, it will disable the WHEEL mode.
;
;    INPASS -  If in the SECURE mode, you wish to use a program similar
;	       to PST's PASS.ASM, set this false, otherwise, ZCPR will
;	       handle the PASSword coding with a built in command.
;
;    DRUSER -  Set this EQU false if you wish to disable RAF's neat hack
;	       that allows you the type B: 7 to move to drive B: user area
;	       seven.  This also removes the USER command.  BasicallyN OF BYTE IN MEMORY CONTAINING
				; NUMBER OF HIGHEST ALLOWABLE USER CODE + 1
				; THIS VALUE IS SET BY CPR ON COLD BOOT,
				; AND PRESUMABLY CONTROLLED AFTER THAT
				; BY A PASSWORD PROGRAM. IF USRMAX=0, THEN
				; MAXUSR BELOW IS USED FOR CHECKING ONLY.
				; 03FH IS RECOMMENDED IF USED  ***
MAXUSR	EQU	15		;MAX ALLOWED USER NUMBER, THIS + 1 IS STUFFED
				; INTO USRMAX ON COLD BOOT, OR USED DIRECTLY
				; IF USRMAX=0
;
MAXDRIV	EQU	0000H	;LOCATION THAT HAS MAX LEGAL DRIVE #
			;SET IT TO ZE fully SECURE, you
; would set SECURE to TRUE, and define MAXDRIV and USRMAX, and maybe
; use the internal password by setting INPASS to TRUE (external is
; MUCH recommended for easier modification). Those options absolutely
; generate too much code unless either CPRTYP or CPRDIR or both are
; set FALSE. A system with SECURE set to FALSE is right on the edge,
; and requires a give and take on options to fit, i.e. you can have
; MAXDRIV and USRMAX with DIR and TYPE if you leave out LIST and
; queryinram on your system, or by setting the
;	      MSIZE and BIOSEX equates to the system memory size in
;	      K-bytes and the "extra" memory required by your BIOS
;	      in K-bytes. BIOSEX is zero if your BIOS is normal size,
;	      and can be negative if your BIOS is in PROM or in
;	      non-contiguous memory.
;
;    EPRMPT - Set TRUE to be prompted "OK?" after seeing what files will
;	      be erased. No, this is NOT for individual file prompting,
;	      it is just to confirm deletion of all seRO TO DISABLE THIS CHECK
			;03DH IS RECOMMENDED IF USED ***
MAXDR	EQU	4	;MAX DRIVE # TO SET INTO MAXDRIV ON COLD BOOT
;
SECURE	EQU	FALSE	;SET TRUE FOR SECURE ENVIRONMENT...
;
DEFUSR	EQU	0		;DEFAULT USER FOR UNRESTRICTED COM FILES
;
	IF	SECURE
WHEEL	EQU	3EH	;SET TO "RESTRCT" FOR LIMITED ACCESS
RESTRCT EQU	0	;WHEN (WHEEL)==RESTRCT, LIMIT COMMANDS
RESUSR	EQU	15	;CHECK HERE FOR RESTRICTED ACCESS COM FILES (LIKE PIP)
			; UNTIL CHANGED BY DFU OR WARM BOOT
	ENDIF	;SECURE
;
INPASS	EQU	FALSE	;SET TRHECKING RANGE OF 8-BIT DISPLACEMENTS
	IF (?DD GT 7FH) AND (?DD LT 0FF80H)
	DB	100H	;Displacement Range Error on Jump Relative
	ELSE
	DB	?DD
	ENDIF
	ENDM
;
;
; Z80 MACRO EXTENSIONS
;
JR	MACRO	?N	;;JUMP RELATIVE
	DB	18H
	@GENDD	?N-$-1
	ENDM
;
JRC	MACRO	?N	;;JUMP RELATIVE ON CARRY
	DB	38H
	@GENDD	?N-$-1
	ENDM
;
JRNC	MACRO	?N	;;JUMP RELATIVE ON NO CARRY
	DB	30H
	@GENDD	?N-$-1
	ENDM
;
JRZ	MACRO	?N	;;JUMP RELATIVE ON ZERO
	DB	28H
	@GENDD	?N-$-1
	ENDM
;
JRNZ	MACRO	?N	;;JUMP RELATIVE ser from his console at the '>' prompt
;	(2) that command issued by a $$$.SUB file at the '$' prompt
;	(3) that command issued by a user program by placing the command into
;	    CIBUFF and setting the character count in CBUFF
;
;   Setting CLEVEL3 to TRUE enables extended processing of the third level of
; ZCPR command.  All the user program need do is to store the command line and
; set the character count; ZCPR will initialize the pointers properly, store
; the ending zero properly, and capitaliz; value of TRUE, and disable the poke.
;
TWOCOL	EQU	FALSE		;TRUE IF TWO COL DIR INSTEAD OF FOUR
;
; The following is presented as an option, but is not generally user-customiz-
; able.  A basic design choice had to be made in the design of ZCPR concerning
; the execution of SUBMIT files.  The original CCP had a problem in this sense
; in that it ALWAYS looked for the SUBMIT file from drive A: and the SUBMIT
; program itself (SUBMIT.COM) would place the $$$.SUB file on the currently
; logged-in drivtime.  The poke is done
; by "STA 0C8B2H", found at 24FEH in the CPM56 image.  To keep this
; feature, change the 0C8B2H address in that instruction by hand to
; the value generated for the symbol TWOPOK in the DIR routine.  If
; you have assembled out the DIR code by setting CPRDIR to FALSE, then
; disable this feature by changing the "STA" to "LDA", i.e. set the
; contents of location 24FEH from 32H to 3AH. If you wish to force
; a two-column display in all cases, set the TWOCOL switch below to a

;   MACROS INCLUDE:
;
$-MACRO 		;FIRST TURN OFF THE EXPANSIONS
;
;	JR	- JUMP RELATIVE
;	JRC	- JUMP RELATIVE IF CARRY
;	JRNC	- JUMP RELATIVE IF NO CARRY
;	JRZ	- JUMP RELATIVE IF ZERO
;	JRNZ	- JUMP RELATIVE IF NO ZERO
;	DJNZ	- DECREMENT B AND JUMP RELATIVE IF NO ZERO
;	LDIR	- MOV @HL TO @DE FOR COUNT IN BC
;	LXXD	- LOAD DOUBLE REG DIRECT
;	SXXD	- STORE DOUBLE REG DIRECT
;
;
;
;	@GENDD MACRO USED FOR CHECKING AND GENERATING
;	8-BIT JUMP RELATIVE DISPLACEMENTS
;
@GENDD	MACRO	?DD	;;USED FOR Cing for $$$.SUB on the logged-in drive, and switching
; logged-in drives without moving the $$$.SUB file as well would cause
; processing to abort.
;
SUBA	EQU	TRUE 	; Set to TRUE to have $$$.SUB always on A:
			; Set to FALSE to have $$$.SUB on the logged-in drive
;
;   The following flag enables extended processing for user-program supplied
; command lines.  This is for Command Level 3 of ZCPR.  Under the current
; ZCPR philosophy, three command levels exist:
;
;	(1) that command issued by the uif they were typed at the Console."
;
;	Hence, to permit this to happen, the $$$.SUB file must always
; be present on a specific drive, and A: is the choice for said drive.
; With this facility engaged as such, Indirect Command Files like:
;
;		DIR
;		A:
;		DIR
;
; can be executed, even though the currently logged-in drive is changed
; during execution.  If the $$$.SUB file was present on the currently
; logged-in drive, the above series of commands would not work since the
; ZCPR would be lookrosoft decided that the way to
; get a two-column directory display instead of four-column (narrow 40-col
; screen, remember) was to have their BIOS poke CCP every time it was
; loaded, if there was no terminal interface card in I/O slot 3.
; Naturally, that will turn into a random poke on any non-standard
; CCP, like this one.  The best way to get this CPR up on the Apple is to
; load it into CPM56.COM, at location 0E00H in the image.  The BIOS code
; that pokes the CPR can also be modified at that  NUMBER BASE
;
SECTFLG	EQU	'S'		;OPTION CHAR FOR SAVE COMMAND TO SAVE SECTORS
;
; END OF CUSTOMIZATION SECTION
;
CR	EQU	0DH
LF	EQU	0AH
TAB	EQU	09H
FFEED	EQU	0CH
BEL	EQU	07H
;
WBOOT	EQU	BASE+0000H		;CP/M WARM BOOT ADDRESS
UDFLAG	EQU	BASE+0004H		;USER NUM IN HIGH NYBBLE, DISK IN LOW
BDOS	EQU	BASE+0005H		;BDOS FUNCTION CALL ENTRY PT
TFCB	EQU	BASE+005CH		;DEFAULT FCB BUFFER
TBUFF	EQU	BASE+0080H		;DEFAULT DISK I/O BUFFER
TPA	EQU	BASE+0100H		;BASE OF TPA
;
;
; MACROS TO PROVIDE Z80 EXTENSIONSTRUE  		;SET TO FALSE TO DISABLE PAGING BY DEFAULT
PGDFLG	EQU	'P'		;FOR TYPE COMMAND: PAGE OR NOT (DEP ON PGDFLT)
				;  THIS FLAG REVERSES THE DEFAULT EFFECT
;
SYSFLG	EQU	'A' 		;FOR DIR COMMAND: LIST $SYS AND $DIR
;
SOFLG	EQU	'S'		;FOR DIR COMMAND: LIST $SYS FILES ONLY
;
SUPRES	EQU	TRUE 		;SUPRESSES USER # REPORT FOR USER 0
;
SPRMPT	EQU	'$'		;CPR PROMPT INDICATING SUBMIT COMMAND
CPRMPT	EQU	'>'		;CPR PROMPT INDICATING USER COMMAND
;
NUMBASE	EQU	'H'		;CHARACTER USED TO SWITCH FROM DEFAULT
				;me of creating the $$$.SUB on the logged-in drive
; or on drive A:.
;
;	A final definition of the Indirect Command File ($$$.SUB or SUBMIT
; File) is presented as follows:
;
;		"An Indirect Command File is one which contains
;		 a series of commands exactly as they would be
;		 entered from a CP/M Console.  The SUBMIT Command
;		 (or SUB Command) reads this files and transforms
;		 it for processing by the ZCPR (the $$$.SUB File).
;		 ZCPR will then execute the commands indicated
;		 EXACTLY as UE IF RUNNING SECURE AND NOT PASS.COM
;
DRUSER	EQU	TRUE	;TRUE TO ALLOW USER COMMAND AND DRIVE/USER HACK
;
EPRMPT	EQU	FALSE	;TRUE TO PROMPT BEFORE ERASING ALL FILES
;
CPRTYP	EQU	TRUE	;TRUE TO GENERATE TYPE CODE
WSTYPE	EQU	TRUE	;TRUE TO GENERATE WORDSTAR HYPHEN CHECK (CPRTYP
			; MUST BE TRUE TOO)
CPRLST	EQU	TRUE	;TRUE TO GENERATE LIST CODE (CPRTYP MUST BE TRUE TOO)
CPRDIR	EQU	TRUE	;TRUE TO GENERATE DIR CODE
;
;  ***  Note to Apple Softcard Users  ***
;
;  In their infinite (?) wisdom (???), MicON NO ZERO
	DB	20H
	@GENDD	?N-$-1
	ENDM
;
DJNZ	MACRO	?N	;;DECREMENT B AND JUMP RELATIVE ON NO ZERO
	DB	10H
	@GENDD	?N-$-1
	ENDM
;
LDIR	MACRO		;;LDIR
	DB	0EDH,0B0H
	ENDM
;
LDED	MACRO	?N	;;LOAD DE DIRECT
	DB	0EDH,05BH
	DW	?N
	ENDM
;
LBCD	MACRO	?N	;;LOAD BC DIRECT
	DB	0EDH,4BH
	DW	?N
	ENDM
;
SDED	MACRO	?N	;;STORE DE DIRECT
	DB	0EDH,53H
	DW	?N
	ENDM
;
SBCD	MACRO	?N	;;STORE BC DIRECT
	DB	0EDH,43H
	DW	?N
	ENDM
;
; END OF Z80 MACRO EXTENSIONS
;
;
;**** Section 0 ****
;
	ORG	Ce the command line for processing.
; Once the command line is properly stored, the user executes the command line
; by reentering the ZCPR through CPRLOC [NOTE:  The C register MUST contain
; a valid User/Disk Flag (see location 4) at this time.]
;
CLEVEL3	EQU	TRUE		;ENABLE COMMAND LEVEL 3 PROCESSING
;
;
;*** TERMINAL AND 'TYPE' CUSTOMIZATION EQUATES
;
NLINES	EQU	24		;NUMBER OF LINES ON CRT SCREEN
WIDE	EQU	TRUE		;TRUE IF WIDE DIR DISPLAY
FENCE	EQU	':'		;SEP CHAR BETWEEN DIR FILES
;
PGDFLT	EQU	e, so when the user was logged into B: and he issued a SUBMIT
; command, the $$$.SUB was placed on B: and did not execute because the CCP
; looked for it on A: and never found it.
;
;	After much debate it was decided to have ZCPR perform the same type of
; function as CCP (look for the $$$.SUB file on A:), but the problem with
; SUBMIT.COM still exists.  Hence, RGF designed SuperSUB and RLC took his
; SuperSUB and designed SUB from it; both programs are set up to allow the
; selection at assembly tiPRLOC
;
;  ENTRY POINTS INTO ZCPR
;
;    If the ZCPR is entered at location CPRLOC (at the JMP to CPR), then
; the default command in CIBUFF will be processed.  If the ZCPR is entered
; at location CPRLOC+3 (at the JMP to CPR1), then the default command in
; CIBUFF will NOT be processed.
;
;    NOTE:  Entry into ZCPR in this way is permitted under this version,
; but in order for this to work, CIBUFF and CBUFF MUST be initialized properly
; AND the C register MUST contain a valid User/Disk Flag (CALL	CONOUT
	CALL	GETUSR		;GET USER NUMBER
;
	IF	SUPRES		;IF SUPPRESSING USR # REPORT FOR USR 0
	ORA	A
	JRZ	RS000
	ENDIF
;
	CPI	10		;USER < 10?
	JRC	RS00
	SUI	10		;SUBTRACT 10 FROM IT
	PUSH	PSW		;SAVE IT
	MVI	A,'1'		;OUTPUT 10'S DIGIT
	CALL	CONOUT
	POP	PSW
RS00:
	ADI	'0'		;OUTPUT 1'S DIGIT (CONVERT TO ASCII)
	CALL	CONOUT
;
; READ INPUT LINE FROM USER OR $$$.SUB
;
RS000:
	CALL	REDBUF		;INPUT COMMAND LINE FROM USER (OR $$$.SUB)
;
; PROCESS INPUT LINE
;
RS1:
;
	IF	CLEVEL3		;IF THIRDERS
;
PAGCNT:
	DB	NLINES-2	;LINES LEFT ON PAGE
CHRCNT:
	DB	0		;CHAR COUNT FOR TYPE
QMCNT:
	DB	0		;QUESTION MARK COUNT FOR FCB TOKEN SCANNER
;
;
;**** Section 2 ****
; CPR STARTING POINTS.  NOTE THAT SOME CP/M IMPLEMENTATIONS
; REQUIRE THE COLD START ADDRESS TO BE IN THE STARTING PAGE
; OF THE CPR, FOR DYNAMIC CCP LOADING.  CMDTBL WAS MOVED FOR
; THIS REASON.
;
; SET USRMAX AND/OR MAXDRIV TO DEFAULT VALUES ON COLD BOOT
; IF REQUIRED. NOTE THAT SOME BIOS IMPLEMENTATIONS WILL END
; UP HERE INr (NOT Carriage
; Return), and a character count of all characters in the command line
; up to and including the last character is placed into location CBUFF
; (immediately before the command line at CIBUFF).  The placed command line
; is then parsed, interpreted, and the indicated command is executed.
; If CLEVEL3 is permitted, a terminating zero is placed after the command
; (otherwise the user program has to place this zero) and the CIBPTR is
; properly initialized (otherwise the user program has executed is stored here.  This command line
; is generated in one of three ways:
;
;	(1) by the user entering it through the BDOS READLN function at
;	    the du> prompt [user input from keyboard]
;	(2) by the SUBMIT File Facility placing it there from a $$$.SUB
;	    file
;	(3) by an external program or user placing the required command
;	    into this buffer
;
;   In all cases, the command line is placed into the buffer starting at
; CIBUFF.  This command line is terminated by the last characte	A,0		;2ND BYTE (IMMEDIATE ARG) IS THE RNGSUB FLAG
	ORA	A		;SET FLAGS ON CLUE
	CMA			;PREPARE FOR COMING 'CMA'
	CNZ	SEAR1
	CMA			;0FFH IS RETURNED IF NO $$$.SUB, SO COMPLEMENT
	STA	RNGSUB		;SET FLAG (0=NO $$$.SUB)
	LDA	CBUFF		;EXECUTE DEFAULT COMMAND?
	ORA	A		;0=NO
	JRNZ	RS1
;
; PROMPT USER AND INPUT COMMAND LINE FROM HIM
;
RESTRT:
	LXI	SP,STACK	;RESET STACK
;
; PRINT PROMPT (DU>)
;
	CALL	CRLF		;PRINT PROMPT
	CALL	GETDRV		;CURRENT DRIVE IS PART OF PROMPT
	ADI	'A'		;CONVERT TO ASCII A-P
	EFAULT TO CURRENT DRIVE
	ENDIF
;
	DB	'$$$'		;FILE NAME
	DB	'     '
	DB	'SUB'		;FILE TYPE
	DB	0		;EXTENT NUMBER
	DB	0		;S1
SUBFS2:
	DS	1		;S2
SUBFRC:
	DS	1		;RECORD COUNT
	DS	16		;DISK GROUP MAP
SUBFCR:
	DS	1		;CURRENT RECORD NUMBER
; COMMAND FILE CONTROL BLOCK
;
FCBDN:
	DS	1		;DISK NAME
FCBFN:
	DS	8		;FILE NAME
FCBFT:
	DS	3		;FILE TYPE
	DS	1		;EXTENT NUMBER
	DS	2		;S1 AND S2
	DS	1		;RECORD COUNT
FCBDM:
	DS	16		;DISK GROUP MAP
FCBCR:
	DS	1		;CURRENT RECORD NUMBER
;
; OTHER BUFF/82 ' ;ZCPR ID FOR DISK DUMP
	DS	BUFLEN-($-CIBUFF)+1	;TOTAL IS 'BUFLEN' BYTES
;
CIBPTR:
	DW	CIBUFF		;POINTER TO COMMAND INPUT BUFFER
CIPTR:
	DW	CIBUF		;POINTER TO CURR COMMAND FOR
				; ERROR REPORTING
;
	DS	26		;STACK AREA
STACK	EQU	$		;TOP OF STACK
;
; FILE TYPE FOR COMMAND
;
COMMSG:
	DB	'COM'
;
; SUBMIT FILE CONTROL BLOCK
;
SUBFCB:
	IF	SUBA		;IF $$$.SUB ON A:
	DB	1		;DISK NAME SET TO DEFAULT TO DRIVE A:
	ENDIF
;
	IF	NOT SUBA	;IF $$$.SUB ON CURRENT DRIVE
	DB	0		;DISK NAME SET TO D
; to be compatible with such programs (provided they determine the buffer
; length from the byte at MBUFF [CPRLOC + 6]), but under ZCPR this is
; no longer necessary, since this buffer pointer is automatically
; initialized in all cases.
;
ENTRY:
	JMP	CPR	; Process potential default command, and set
			; USRMAX to MAXUSR default
	JMP	CPR1	; Do NOT process potential default command
;	
;**** Section 1 ****
; BUFFERS ET AL
;
; INPUT COMMAND LINE AND DEFAULT COMMAND
;
;   The command line to be V	E,A		;SET USER NUMBER
	CALL	SETUSR
	CALL	RESET		;RESET DISK SYSTEM
	STA	RNGSUB		;SAVE SUBMIT CLUE FROM DRIVE A:
	POP	B
	MOV	A,C		;C=USER/DISK NUMBER (SEE LOC 4)
	ANI	0FH		;EXTRACT DEFAULT DISK DRIVE
	STA	TDRIVE		;SET IT
	JRZ	NOLOG		;SKIP IF 0...ALREADY LOGGED
	CALL	LOGIN		;LOG IN DEFAULT DISK
;
	IF	NOT SUBA	;IF $$$.SUB IS ON CURRENT DRIVE
	STA	RNGSUB		;BDOS '$' CLUE
	ENDIF
;
NOLOG:
	LXI	D,SUBFCB	;CHECK FOR $$$.SUB ON CURRENT DISK
RNGSUB	EQU	$+1		;POINTER FOR IN-THE-CODE MODIFICATION
	MVIFAULT COMMAND
;
; NOTE ON MODIFICATION BY RGF: BDOS RETURNS 0FFH IN
; ACCUMULATOR WHENEVER IT LOGS IN A DIRECTORY, IF ANY
; FILE NAME CONTAINS A '$' IN IT.  THIS IS NOW USED AS
; A CLUE TO DETERMINE WHETHER OR NOT TO DO A SEARCH
; FOR SUBMIT FILE, IN ORDER TO ELIMINATE WASTEFUL SEARCHES.
;
	IF	USRMAX OR MAXDRIV
CPR2:
	ELSE
CPR:
	ENDIF	;USRMAX OR MAXDRIV
;
	LXI	SP,STACK	;RESET STACK
	PUSH	B
	MOV	A,C		;C=USER/DISK NUMBER (SEE LOC 4)
	RAR			;EXTRACT USER NUMBER
	RAR
	RAR
	RAR
	ANI	0FH
	MOFLEN	EQU	80		;MAXIMUM BUFFER LENGTH
MBUFF:
	DB	BUFLEN		;MAXIMUM BUFFER LENGTH
CBUFF:
	DB	0		;NUMBER OF VALID CHARS IN COMMAND LINE
CIBUFF:
	DB	'              '	;DEFAULT (COLD BOOT) COMMAND
;
;  The copyright notice from Digital Research is genned into the
; stock CCP at this location. It should be maintained in ZCPR,
; since Digital Research grants permission for ZCPR to exist.
;
	DB	'  COPYRIGHT (C) 1979, DIGITAL RESEARCH  '
CIBUF:
	DB	0			;COMMAND STRING TERMINATOR
	DB	'NZCPR V 1.6 of 08/03see Location 4: the
; most significant nybble contains the User Number and the least significant
; nybble contains the Disk Number).
;
;    Some user programs (such as SYNONYM3) attempt to use the default
; command facility.  Under the original CCP, it was necessary to initialize
; the pointer after the reserved space for the command buffer to point to
; the first byte of the command buffer.  Under current versions, this is
; no longer the case.  The CIBPTR (Command Input Buffer PoinTeR) is located COMMAND LEVEL IS PERMITTED
	CALL	CNVBUF		;CAPITALIZE COMMAND LINE, PLACE ENDING 0,
				; AND SET CIBPTR VALUE
	ENDIF
;
	CALL	DEFDMA		;SET TBUFF TO DMA ADDRESS
	CALL	GETDRV		;GET DEFAULT DRIVE NUMBER
	STA	TDRIVE		;SET IT
	CALL	SCANER		;PARSE COMMAND NAME FROM COMMAND LINE
	CNZ	ERROR		;ERROR IF COMMAND NAME CONTAINS A '?'
	LXI	D,RSTCPR	;PUT RETURN ADDRESS OF COMMAND
	PUSH	D		;ON THE STACK
	LDA	TEMPDR		;IS COMMAND OF FORM 'D:COMMAND'?
	ORA	A		;NZ=YES
	JNZ	COM		; IMMEDIATELY
	CALL	CMDSER		;SCAN STEAD OF AT THE WARM BOOT, DEFEATING PASSWORDING
; OF THESE OPTIONS. RECOMMEND SUCH A BIOS BE FIXED.
;
	IF	USRMAX OR MAXDRIV
CPR:
	IF	USRMAX
	MVI	A,MAXUSR+1	;SET USRMAX ON COLD BOOT
	STA	USRMAX
	ENDIF	;USRMAX
;
	IF	MAXDRIV
	MVI	A,MAXDR		;SET MAXDRIV ON COLD BOOT
	STA	MAXDRIV
	ENDIF	;MAXDRIV
;
	JR	CPR2		; THEN PROCEED
	ENDIF	;USRMAX OR MAXDRIV
;
; START CPR AND DON'T PROCESS DEFAULT COMMAND STORED
;
CPR1:
	XRA	A		;SET NO DEFAULT COMMAND
	STA	CBUFF
;
; START CPR AND POSSIBLY PROCESS DEto init this ptr).
; If the command is placed by a user program, entering at CPRLOC is enough
; to have the command processed.  Again, under the current ZCPR, it is not
; necessary to store the pointer to CIBUFF in CIBPTR; ZCPR will do this for
; the calling program if CLEVEL3 is made TRUE.
;
;   WARNING:  The command line must NOT exceed BUFLEN characters in length.
; For user programs which load this command, the value of BUFLEN can be
; obtained by examining the byte at MBUFF (CPRLOC + 6).
;
BUFOR CPR-RESIDENT COMMAND
	JNZ	COM		;NOT CPR-RESIDENT
	MOV	A,M		;FOUND IT:  GET LOW-ORDER PART
	INX	H		;GET HIGH-ORDER PART
	MOV	H,M		;STORE HIGH
	MOV	L,A		;STORE LOW
	PCHL			;EXECUTE CPR ROUTINE
;
; ENTRY POINT FOR RESTARTING CPR AND LOGGING IN DEFAULT DRIVE
;
RSTCPR:
	CALL	DLOGIN		;LOG IN DEFAULT DRIVE
;
; ENTRY POINT FOR RESTARTING CPR WITHOUT LOGGING IN DEFAULT DRIVE
;
RCPRNL:
	CALL	SCANER		;EXTRACT NEXT TOKEN FROM COMMAND LINE
	LDA	FCBFN		;GET FIRST CHAR OF TOKEN
	SUI	' '		;ANY CHAR?
IN $$$.SUB
	CALL	READ		;DE=SUBFCB
	JRNZ	RB1		;ABORT $$$.SUB IF ERROR IN READING LAST REC
	LXI	D,CBUFF 	;COPY LAST RECORD (NEXT SUBMIT CMND) TO CBUFF
	LXI	H,TBUFF 	;  FROM TBUFF
	LXI	B,BUFLEN	;NUMBER OF BYTES
	LDIR
	LXI	H,SUBFS2	;PT TO S2 OF $$$.SUB FCB
	MVI	M,0		;SET S2 TO ZERO
	INX	H		;PT TO RECORD COUNT
	DCR	M		;DECREMENT RECORD COUNT OF $$$.SUB
	LXI	D,SUBFCB	;CLOSE $$$.SUB
	CALL	CLOSE
	JRZ	RB1		;ABORT $$$.SUB IF ERROR
	MVI	A,SPRMPT	;PRINT SUBMIT PROMPT
	CALL	CONOUT
	LXI	H,CIBUFF	;PRINT CORM			;DONE IF MSB SET
	JR	PRIN1
;
; BDOS FUNCTION ROUTINES
;
;
; RETURN NUMBER OF CURRENT DISK IN A
;
GETDRV:
	MVI	C,19H
	JR	BDOSJP
;
; SET 80H AS DMA ADDRESS
;
DEFDMA:
	LXI	D,TBUFF 	;80H=TBUFF
DMASET:
	MVI	C,1AH
	JR	BDOSJP
;
RESET:
	MVI	C,0DH
BDOSJP:
	JMP	BDOS
;
LOGIN:
	MOV	E,A		;MOVE DESIRED # TO BDOS REG
;
	IF	MAXDRIV
	LDA	MAXDRIV		;CHECK FOR LEGAL DRIVE #
	CMP	E
	JC	ERROR		;DON'T DO IT IF TOO HIGH
	ENDIF	;MAXDRIV
;
	MVI	C,0EH
	JR	BDOSJP	;SAVE SOME CODE SPACE
;
OPENF:NOUT
	MVI	A,LF	;FALL THRU TO CONOUT
;
CONOUT:
	PUSH	B
	MVI	C,02H
OUTPUT:
	ANI	7FH	;PREVENT INADVERTANT GRAPHIC OUTPUT
			; TO EPSON-TYPE PRINTERS
	MOV	E,A
	PUSH	H
	CALL	BDOS
	POP	H
	POP	B
	RET
;
CONIN:
	MVI	C,01H	;GET CHAR FROM CON: WITH ECHO
	CALL	BDOSB
;
; CONVERT CHAR IN A TO UPPER CASE
;
UCASE:
	CPI	61H		;LOWER-CASE A
	RC
	CPI	7BH		;GREATER THAN LOWER-CASE Z?
	RNC
	ANI	5FH		;CAPITALIZE
	RET
;
NOECHO:
	PUSH	D	;SAVE D
	MVI	C,6	;DIRECT CONSOLE I/O
	MVI	E,0FFH	;INPUT
	CALL	FOR NON-RAS
	DB	'GO  '			;JUMP TO 100H
	DW	GO
	DB	'ERA '			;ERASE FILE
	DW	ERA
	DB	'SAVE'			;SAVE MEMORY IMAGE TO DISK
	DW	SAVE
	DB	'REN '			;RENAME FILE
	DW	REN
	DB	'DFU '			;SET DEFAULT USER
	DW	DFU
	DB	'GET '			;LOAD FILE INTO MEMORY
	DW	GET
	DB	'JUMP'			;JUMP TO LOCATION IN MEMORY
	DW	JUMP
	ENDIF	;RAS
;
NCMNDS	EQU	($-CMDTBL)/(NCHARS+2)
;
;**** Section 3 ****
; I/O UTILITIES
;
; OUTPUT CHAR IN REG A TO CONSOLE AND DON'T CHANGE BC
;
;
; OUTPUT <CRLF>
;
CRLF:
	MVI	A,CR
	CALL	COroutine determines if a SUBMIT file is being processed
; and extracts the command line from it if so or from the user's console
;
REDBUF:
	LDA	RNGSUB		;SUBMIT FILE CURRENTLY IN EXECUTION?
	ORA	A		;0=NO
	JRZ	RB1		;GET LINE FROM CONSOLE IF NOT
	LXI	D,SUBFCB	;OPEN $$$.SUB
	PUSH	D		;SAVE DE
	CALL	OPEN
	POP	D		;RESTORE DE
	JRZ	RB1		;ERASE $$$.SUB IF END OF FILE AND GET CMND
	LDA	SUBFRC		;GET VALUE OF LAST RECORD IN FILE
	DCR	A		;PT TO NEXT TO LAST RECORD
	STA	SUBFCR		;SAVE NEW VALUE OF LAST RECORD Y RET ADDR, START WITH <CR><LF>
;
PRINTC:
	PUSH	PSW		;SAVE FLAGS
	CALL	CRLF		;NEW LINE
	POP	PSW
;
PRINT:
	XTHL			;GET PTR TO STRING
	PUSH	PSW		;SAVE FLAGS
	CALL	PRIN1		;PRINT STRING
	POP	PSW		;GET FLAGS
	XTHL			;RESTORE HL AND RET ADR
	RET
;
; PRINT STRING ENDING WITH ZERO BYTE OR CHAR WITH HIGH BIT SET
; PT'ED TO BY HL
;
PRIN1:
	MOV	A,M		;GET NEXT BYTE
	CALL	CONOUT		;PRINT CHAR
	MOV	A,M		;GET NEXT BYTE AGAIN FOR TEST
	INX	H		;PT TO NEXT BYTE
	ORA	A		;SET FLAGS
	RZ			;DONE IF ZERO
	 PGDFLG MEANS NO PAGING, PLEASE
	ELSE			;IF PAGING NOT DEFAULT
	JRNZ	PGBAK		;  PGDFLG MEANS PLEASE PAGINATE
	ENDIF
;
	CALL	NOECHO		;GET CHAR BUT DON'T ECHO TO SCREEN
	CPI	'C'-'@' 	;^C
	JZ	RSTCPR		;RESTART CPR
PGBAK:
	POP	H		;RESTORE HL
	RET
	ENDIF	;CPRTYP
;
READF:
	LXI	D,FCBDN ;FALL THRU TO READ
READ:
	MVI	C,14H	;FALL THRU TO BDOSB
;
; CALL BDOS AND SAVE BC
;
BDOSB:
	PUSH	B
	CALL	BDOS
	POP	B
	ORA	A
	RET
;
; PRINT STRING ENDING WITH ZERO BYTE OR CHAR WITH HIGH BIT SET
; PT'ED TO BER
;
	IF	CPRTYP
	DB	'TYPE'			;TYPE A FILE TO CON:
	DW	TYPE
	ENDIF	;CPRTYP
;
	IF	CPRDIR
	DB	'DIR '			;PULL A DIRECTORY OF DISK FILES
	DW	DIR
	ENDIF	;CPRDIR

NRCMDS	EQU	($-CMDTBL)/(NCHARS+2)	;PUT ANY COMMANDS THAT ARE OK TO
					;RUN WHEN NOT UNDER WHEEL MODE
					;IN FRONT OF THIS LABEL
	IF	CPRLST AND CPRTYP
	DB	'LIST'			;LIST FILE TO PRINTER
	DW	LIST
	ENDIF	;CPRLST AND CPRTYP
;
	IF	INPASS AND SECURE
	DB	'NORM'			;DISABLE WHEEL MODE
	DW	NORM
	ENDIF	;INPASS AND SECURE
;
	IF	NOT RAS		; TO CURRENT USER AND DEFAULT DISK
;
SETUD:
	CALL	GETUSR		;GET NUMBER OF CURRENT USER
	ADD	A		;PLACE IT IN HIGH NYBBLE
	ADD	A
	ADD	A
	ADD	A
	LXI	H,TDRIVE	;MASK IN DEFAULT DRIVE NUMBER (LOW NYBBLE)
	ORA	M		;MASK IN
	STA	UDFLAG		;SET USER/DISK NUMBER
	RET
;
; SET USER/DISK FLAG TO USER 0 AND DEFAULT DISK
;
SETU0D:
TDRIVE	EQU	$+1		;POINTER FOR IN-THE-CODE MODIFICATION
	MVI	A,0		;2ND BYTE (IMMEDIATE ARG) IS TDRIVE
	STA	UDFLAG		;SET USER/DISK NUMBER
	RET
;
; INPUT NEXT COMMAND TO CPR
;	This  $$$.SUB
;
DELETE:
	MVI	C,13H
	JR	BDOSJP	;SAVE MORE SPACE
;
; RESET USER NUMBER IF CHANGED
;
RESETUSR:
TMPUSR	EQU	$+1		;POINTER FOR IN-THE-CODE MODIFICATION
	MVI	A,0		;2ND BYTE (IMMEDIATE ARG) IS TMPUSR
	MOV	E,A		;PLACE IN E
	JR	SETUSR		;THEN GO SET USER
GETUSR:
	MVI	E,0FFH		;GET CURRENT USER NUMBER
SETUSR:
	MVI	C,20H		;SET USER NUMBER TO VALUE IN E (GET IF E=FFH)
	JR	BDOSJP		;MORE SPACE SAVING
;
; END OF BDOS FUNCTIONS
;
;
;**** Section 4 ****
; CPR UTILITIES
;
; SET USER/DISK FLAGIF	CPRTYP
	PUSH	PSW
	CALL	CONOUT	;OUTPUT TO CON:
	POP	PSW
	CPI	LF	;CHECK FOR PAGING
	RNZ			;DONE IF NOT EOL YET
;
;  COUNT DOWN LINES AND PAUSE FOR INPUT (DIRECT) IF COUNT EXPIRES
;
	PUSH	H
	LXI	H,PAGCNT	;COUNT DOWN
	DCR	M
	JRNZ	PGBAK		;JUMP IF NOT END OF PAGE
	MVI	M,NLINES-2	;REFILL COUNTER
;
PGFLG	EQU	$+1		;POINTER TO IN-THE-CODE BUFFER PGFLG
	MVI	A,0		;0 MAY BE CHANGED BY PGFLG EQUATE
	CPI	PGDFLG		;PAGE DEFAULT OVERRIDE OPTION WANTED?
;
	IF	PGDFLT		;IF PAGING IS DEFAULT
	JRZ	PGBAK		; 	LXI	H,TEMPDR
	ORA	M
	JNZ	ERROR
	JR	RESTRT
;
; No File Error Message
;
PRNNF:
	CALL	PRINTC		;NO FILE MESSAGE
	DB	'No Fil','e'+80H
	RET
;
; CPR BUILT-IN COMMAND TABLE
;
NCHARS	EQU	4		;NUMBER OF CHARS/COMMAND
;
; CPR COMMAND NAME TABLE
;   EACH TABLE ENTRY IS COMPOSED OF THE 4-BYTE COMMAND AND 2-BYTE ADDRESS
;
CMDTBL:
;
	IF	INPASS AND SECURE
	DB	'PASS'			;ENABLE WHEEL (SYSOP) MODE
	DW	PASS
	ENDIF	;INPASS AND SECURE
;
	IF	DRUSER
	DB	'USER'			;CHANGE USER AREAS
	DW	USER
	ENDIF	;DRUSMMAND LINE FROM $$$.SUB
	CALL	PRIN1
	CALL	BREAK		;CHECK FOR ABORT (ANY CHAR)
;
	IF	CLEVEL3		;IF THIRD COMMAND LEVEL IS PERMITTED
	RZ			;IF <NULL> (NO ABORT), RETURN TO CALLER AND RUN
	ENDIF
;
	IF	NOT CLEVEL3	;IF THIRD COMMAND LEVEL IS NOT PERMITTED
	JRZ	CNVBUF		;IF <NULL> (NO ABORT), CAPITALIZE COMMAND
	ENDIF
;
	CALL	SUBKIL		;KILL $$$.SUB IF ABORT
	JMP	RESTRT		;RESTART CPR
;
; INPUT COMMAND LINE FROM USER CONSOLE
;
RB1:
	CALL	SUBKIL		;ERASE $$$.SUB IF PRESENT
	CALL	SETUD		;SET USER AND DI
	XRA	A
	STA	FCBCR
	LXI	D,FCBDN ;FALL THRU TO OPEN
;
OPEN:
	MVI	C,0FH	;FALL THRU TO GRBDOS
;
GRBDOS:
	CALL	BDOS
	INR	A	;SET ZERO FLAG FOR ERROR RETURN
	RET
;
CLOSE:
	MVI	C,10H
	JR	GRBDOS
;
SEARF:
	LXI	D,FCBDN ;SPECIFY FCB
SEAR1:
	MVI	C,11H
	JR	GRBDOS
;
SEARN:
	MVI	C,12H
	JR	GRBDOS
;
; CHECK FOR SUBMIT FILE IN EXECUTION AND ABORT IT IF SO
;
SUBKIL:
	LXI	H,RNGSUB	;CHECK FOR SUBMIT FILE IN EXECUTION
	MOV	A,M
	ORA	A		;0=NO
	RZ
	MVI	M,0		;ABORT SUBMIT FILE
	LXI	D,SUBFCB	;DELETEBDOSB
	POP	D
	ORA	A	;DID WE GET A CHAR?
	JRZ	NOECHO	;WAIT FOR IT IF NOT, IT'S EXPECTED
	RET
;
	IF	CPRTYP
LCOUT:
	ENDIF	;CPRTYP
;
	IF	CPRTYP AND CPRLST
	PUSH	PSW	;OUTPUT CHAR TO CON: OR LST: DEP ON PRFLG
PRFLG	EQU	$+1	;POINTER FOR IN-THE-CODE MODIFICATION
	MVI	A,0	;2ND BYTE (IMMEDIATE ARG) IS THE PRINT FLAG
	ORA	A	;0=TYPE
	JRZ	LC1
	POP	PSW	;GET CHAR
;
; OUTPUT CHAR IN REG A TO LIST DEVICE
;
LSTOUT:
	PUSH	B
	MVI	C,05H
	JR	OUTPUT
LC1:
	POP	PSW	;GET CHAR
	ENDIF	;CPRTYP AND CPRLST
;
	SK
	MVI	A,CPRMPT	;PRINT PROMPT
	CALL	CONOUT
	MVI	C,0AH		;READ COMMAND LINE FROM USER
	LXI	D,MBUFF
	CALL	BDOS
;
	IF	CLEVEL3		;IF THIRD COMMAND LEVEL IS PERMITTED
	JMP	SETU0D		;SET CURRENT DISK NUMBER IN LOWER PARAMS
	ENDIF
;
	IF	NOT CLEVEL3	;IF THIRD COMMAND LEVEL IS NOT PERMITTED
	CALL	SETU0D		;SET CURRENT DISK NUMBER IF LOWER PARAMS
				; AND FALL THRU TO CNVBUF
	ENDIF
;
; CAPITALIZE STRING (ENDING IN 0) IN CBUFF AND SET PTR FOR PARSING
;
CNVBUF:
	LXI	H,CBUFF 	;PT TO USER'S COMMAND
	MOV'
;
; EXTRACT FILENAME FROM POSSIBLE FILENAME.TYP
;
SCAN4:
	XRA	A		;A=0
	STA	QMCNT		;INIT COUNT OF NUMBER OF QUESTION MARKS IN FCB
	MVI	B,8		;MAX OF 8 CHARS IN FILE NAME
	CALL	SCANF		;FILL FCB FILE NAME
;
; EXTRACT FILE TYPE FROM POSSIBLE FILENAME.TYP
;
	MVI	B,3		;PREPARE TO EXTRACT TYPE
	CPI	'.'		;IF (DE) DELIMITER IS A '.', WE HAVE A TYPE
	JRNZ	SCAN15		;FILL FILE TYPE BYTES WITH <SP>
	INX	D		;PT TO CHAR IN COMMAND LINE AFTER '.'
	CALL	SCANF		;FILL FCB FILE TYPE
	JR	SCAN16		;SKIP TO NEXT PYBBLE
	MOV	D,A
	MOV	A,E		;SWITCH LOW-ORDER NYBBLES
	RLC
	RLC
	RLC
	RLC
	MOV	E,A		;HIGH NYBBLE OF E=NEW HIGH OF E,
				;  LOW NYBBLE OF E=NEW LOW OF D
	ANI	0FH		;GET NEW LOW OF D
	ORA	D		;MASK IN HIGH OF D
	MOV	D,A		;NEW HIGH BYTE IN D
	MOV	A,E
	ANI	0F0H		;MASK OUT LOW OF E
	ORA	C		;MASK IN NEW LOW
	MOV	E,A		;NEW LOW BYTE IN E
	DJNZ	HNUM1		;COUNT DOWN
;
; RETURN FROM HEXNUM
;
HNUM3:
	XCHG			;RETURNED VALUE IN HL
	MOV	A,L		;LOW-ORDER BYTE IN A
	RET
;
; PT TO DIRECTORY ENTRY IN TBUFF WITER
	RZ
	CPI	';'		;';'=DELIMITER
	RZ
	CPI	'<'		;'<'=DELIMITER
	RZ
	CPI	'>'		;'>'=DELIMITER
	RET
;
; ADVANCE INPUT PTR TO FIRST NON-BLANK AND FALL THROUGH TO SBLANK
;
ADVAN:
	LDED	CIBPTR
;
; SKIP STRING PTED TO BY DE (STRING ENDS IN 0) UNTIL END OF STRING
;   OR NON-BLANK ENCOUNTERED (BEGINNING OF TOKEN)
;
SBLANK:
	LDAX	D
	ORA	A
	RZ
	CPI	' '
	RNZ
	INX	D
	JR	SBLANK
;
; ADD A TO HL (HL=HL+A)
;
ADDAH:
	ADD	L
	MOV	L,A
	RNC
	INR	H
	RET
;
; EXTRACT DECIMAL NUMBER FROM COMMAND LILL	CONOUT		;PRINT COMMAND CHAR
	POP	H		;GET PTR
	INX	H		;PT TO NEXT
	JR	ERR2		;CONTINUE
ERR1:
	CALL	PRINT		;PRINT '?'
	DB	'?'+80H
	CALL	SUBKIL		;TERMINATE ACTIVE $$$.SUB IF ANY
	JMP	RESTRT		;RESTART CPR
;
; CHECK TO SEE IF DE PTS TO DELIMITER; IF SO, RET W/ZERO FLAG SET
;
SDELM:
	LDAX	D
	ORA	A		;0=DELIMITER
	RZ
	CPI	' '		;ERROR IF < <SP>
	JRC	ERROR
	RZ			;<SP>=DELIMITER
	CPI	'='		;'='=DELIMITER
	RZ
	CPI	5FH		;UNDERSCORE=DELIMITER
	RZ
	CPI	'.'		;'.'=DELIMITER
	RZ
	CPI	':'		;':'=DELIMRZ	SCAN2
	SBI	'A'-1		;CONVERT POSSIBLE DRIVE SPEC TO NUMBER
	MOV	B,A		;STORE NUMBER (A:=0, B:=1, ETC) IN B
	INX	D		;PT TO NEXT CHAR
	LDAX	D		;SEE IF IT IS A COLON (:)
	CPI	':'
	JRZ	SCAN3		;YES, WE HAVE A DRIVE SPEC
	DCX	D		;NO, BACK UP PTR TO FIRST NON-BLANK CHAR
SCAN2:
	LDA	TDRIVE		;SET 1ST BYTE OF FCBDN AS DEFAULT DRIVE
	MOV	M,A
	JR	SCAN4
SCAN3:
	MOV	A,B		;WE HAVE A DRIVE SPEC
	STA	TEMPDR		;SET TEMPORARY DRIVE
	MOV	M,B		;SET 1ST BYTE OF FCBDN AS SPECIFIED DRIVE
	INX	D		;PT TO BYTE AFTER ':OKEN FOR CONVERSION
	LXI	D,0		;DE=ACCUMULATED VALUE
	MVI	B,11		;B=CHAR COUNT
HNUM1:
	MOV	A,M		;GET CHAR
	CPI	' '		;DONE?
	JRZ	HNUM3		;RETURN IF SO
	CPI	NUMBASE		;DONE IF NUMBASE SUFFIX
	JRZ	HNUM3
	SUI	'0'		;CONVERT TO BINARY
	JRC	NUMERR		;RETURN AND DONE IF ERROR
	CPI	10		;0-9?
	JRC	HNUM2
	SUI	7		;A-F?
	CPI	10H		;ERROR?
	JRNC	NUMERR
HNUM2:
	INX	H		;PT TO NEXT CHAR
	MOV	C,A		;DIGIT IN C
	MOV	A,D		;GET ACCUMULATED VALUE
	RLC			;EXCHANGE NYBBLES
	RLC
	RLC
	RLC
	ANI	0F0H		;MASK OUT LOW NUE = OLD VALUE * 10 + DIGIT
	JRC	NUMERR		;CHECK FOR RANGE ERROR
	MOV	C,A		;SET NEW VALUE
	DJNZ	NUM1		;COUNT DOWN
;
; RETURN FROM NUMBER
;
NUM2:
	MOV	A,C		;GET ACCUMULATED VALUE
	RET
;
; NUMBER ERROR ROUTINE FOR SPACE CONSERVATION
;
NUMERR:
	JMP	ERROR		;USE ERROR ROUTINE - THIS IS RELATIVE PT
;
; EXTRACT HEXADECIMAL NUMBER FROM COMMAND LINE
;   RETURN WITH VALUE IN REG A; ALL REGISTERS MAY BE AFFECTED
;
HEXNUM:
	CALL	SCANER		;PARSE NUMBER AND PLACE IN FCBFN
HNUM0:
	LXI	H,FCBFN		;PT TO TSER NUMBER FROM THE COMMAND LINE AND VALIDATE IT.
;
USRNUM:		
	CALL	NUMBER
;
	IF	USRMAX
	LXI	H,USRMAX ;PT TO MAXUSR + 1
	CMP	M	;NEW VALUE ALLOWED?
	ELSE
	CPI	MAXUSR+1 ;NEW VALUE ALLOWED?
	ENDIF	;USRMAX
;
	RC		;RETURN TO CALLER IF SO,
			; ELSE FLAG AS ERROR
;
; INVALID COMMAND -- PRINT IT
;
ERROR:
	CALL	CRLF		;NEW LINE
	LHLD	CIPTR		;PT TO BEGINNING OF COMMAND LINE
ERR2:
	MOV	A,M		;GET CHAR
	CPI	' '+1		;SIMPLE '?' IF <SP> OR LESS
	JRC	ERR1
	PUSH	H		;SAVE PTR TO ERROR COMMAND CHAR
	CAINPUT, CIBPTR PTS TO CHAR AT WHICH TO START SCAN;
;   ON OUTPUT, CIBPTR PTS TO CHAR AT WHICH TO CONTINUE AND ZERO FLAG IS RESET
;     IF '?' IS IN TOKEN
;
; ENTRY POINTS:
;	SCANER - LOAD TOKEN INTO FIRST FCB
;	SCANX - LOAD TOKEN INTO FCB PTED TO BY HL
;
SCANER:
	LXI	H,FCBDN 	;POINT TO FCBDN
SCANX:
	XRA	A		;SET TEMPORARY DRIVE NUMBER TO DEFAULT
	STA	TEMPDR
	CALL	ADVAN		;SKIP TO NON-BLANK OR END OF LINE
	SDED	CIPTR		;SET PTR TO NON-BLANK OR END OF LINE
	LDAX	D		;END OF LINE?
	ORA	A		;0=YES
	JZ			;ABORT IF SAME
	LDA	TDRIVE		;LOG IN DEFAULT DRIVE
;
DLOG5:	JMP	LOGIN
;
; ROUTINE COMMON TO BOTH LOGIN ROUTINES; ON EXIT, Z SET MEANS ABORT
;
COMLOG:
TEMPDR	EQU	$+1		;POINTER FOR IN-THE-CODE MODIFICATION
	MVI	A,0		;2ND BYTE (IMMEDIATE ARG) IS TEMPDR
	ORA	A		;0=NO
	RZ
	DCR	A		;COMPARE IT AGAINST DEFAULT
	LXI	H,TDRIVE
	CMP	M
	RET			;ABORT IF SAME
;
; EXTRACT TOKEN FROM COMMAND LINE AND PLACE IT INTO FCBDN;
;   FORMAT FCBDN FCB IF TOKEN RESEMBLES FILE NAME AND TYPE (FILENAME.TYP);
;   ON PROCESS DECIMAL NUMBER
;
NUM0:
	LXI	H,FCBFN		;PT TO BEGINNING OF TOKEN
	LXI	B,1100H		;C=ACCUMULATED VALUE, B=CHAR COUNT
				; (C=0, B=11)
NUM1:
	MOV	A,M		;GET CHAR
	CPI	' '		;DONE IF <SP>
	JRZ	NUM2
	INX	H		;PT TO NEXT CHAR
	SUI	'0'		;CONVERT TO BINARY (ASCII 0-9 TO BINARY)
	CPI	10		;ERROR IF >= 10
	JRNC	NUMERR
	MOV	D,A		;DIGIT IN D
	MOV	A,C		;NEW VALUE = OLD VALUE * 10
	RLC
	RLC
	RLC
	ADD	C		;CHECK FOR RANGE ERROR
	JRC	NUMERR
	ADD	C		;CHECK FOR RANGE ERROR
	JRC	NUMERR
	ADD	D		;NEW VAL	B,M		;CHAR COUNT IN B
	INR	B		;ADD 1 IN CASE OF ZERO
CB1:
	INX	H		;PT TO 1ST VALID CHAR
	MOV	A,M		;CAPITALIZE COMMAND CHAR
	CALL	UCASE
	MOV	M,A
	DJNZ	CB1		;CONTINUE TO END OF COMMAND LINE
CB2:
	MVI	M,0		;STORE ENDING <NULL>
	LXI	H,CIBUFF	;SET COMMAND LINE PTR TO 1ST CHAR
	SHLD	CIBPTR
	RET
;
; CHECK FOR ANY CHAR FROM USER CONSOLE;RET W/ZERO SET IF NONE
;
BREAK:
	PUSH	D		;SAVE DE
	MVI	C,11		;CSTS CHECK
	CALL	BDOSB
	CNZ	CONIN		;GET INPUT CHAR
BRKBK:
	POP	D
	RET
;
; GET THE REQUESTED UROCESSING
SCAN15:
	CALL	SCANF4		;SPACE FILL
;
; FILL IN EX, S1, S2, AND RC WITH ZEROES
;
SCAN16:
	MVI	B,4		;4 BYTES
SCAN17:
	INX	H		;PT TO NEXT BYTE IN FCBDN
	MVI	M,0
	DJNZ	SCAN17
;
; SCAN COMPLETE -- DE PTS TO DELIMITER BYTE AFTER TOKEN
;
	SDED	CIBPTR
;
; SET ZERO FLAG TO INDICATE PRESENCE OF '?' IN FILENAME.TYP
;
	LDA	QMCNT		;GET NUMBER OF QUESTION MARKS
	ORA	A		;SET ZERO FLAG TO INDICATE ANY '?'
	RET
;
;  SCANF -- SCAN TOKEN PTED TO BY DE FOR A MAX OF B BYTES; PLACE IT INTO
;    FHOSE OFFSET IS SPECIFIED BY A AND C
;
DIRPTR:
	LXI	H,TBUFF 	;PT TO TEMP BUFFER
	ADD	C		;PT TO 1ST BYTE OF DIR ENTRY
	CALL	ADDAH		;PT TO DESIRED BYTE IN DIR ENTRY
	MOV	A,M		;GET DESIRED BYTE
	RET
;
; CHECK FOR SPECIFIED DRIVE AND LOG IT IN IF NOT DEFAULT
;
SLOGIN:
	XRA	A		;SET FCBDN FOR DEFAULT DRIVE
	STA	FCBDN
	CALL	COMLOG		;CHECK DRIVE
	RZ
	JR	DLOG5		;DO LOGIN OTHERWISE
;
; CHECK FOR SPECIFIED DRIVE AND LOG IN DEFAULT DRIVE IF SPECIFIED<>DEFAULT
;
DLOGIN:
	CALL	COMLOG		;CHECK DRIVE
	RNE
;   RETURN WITH VALUE IN REG A;ALL REGISTERS MAY BE AFFECTED
;
NUMBER:
	CALL	SCANER		;PARSE NUMBER AND PLACE IN FCBFN
	LXI	H,FCBFN+10 	;PT TO END OF TOKEN FOR CONVERSION
	MVI	B,11		;11 CHARS MAX
;
; CHECK FOR SUFFIX FOR HEXADECIMAL NUMBER
;
NUMS:
	MOV	A,M		;GET CHARS FROM END, SEARCHING FOR SUFFIX
	DCX	H		;BACK UP
	CPI	' '		;SPACE?
	JRNZ	NUMS1		;CHECK FOR SUFFIX
	DJNZ	NUMS		;COUNT DOWN
	JR	NUM0		;BY DEFAULT, PROCESS
NUMS1:
	CPI	NUMBASE		;CHECK AGAINST BASE SWITCH FLAG
	JRZ	HNUM0
;
; ILE NAME FIELD PTED TO BY HL; EXPAND AND INTERPRET WILD CARDS OF
;    '*' AND '?'; ON EXIT, DE PTS TO TERMINATING DELIMITER
;
SCANF:
	CALL	SDELM		;DONE IF DELIMITER ENCOUNTERED - <SP> FILL
	JRZ	SCANF4
	INX	H		;PT TO NEXT BYTE IN FCBDN
	CPI	'*'		;IS (DE) A WILD CARD?
	JRNZ	SCANF1		;CONTINUE IF NOT
	MVI	M,'?'		;PLACE '?' IN FCBDN AND DON'T ADVANCE DE IF SO
	CALL	SCQ		;SCANNER COUNT QUESTION MARKS
	JR	SCANF2
SCANF1:
	MOV	M,A		;STORE FILENAME CHAR IN FCBDN
	INX	D		;PT TO NEXT CHAR IN COMMAND LINEon the CON: Device
;Forms:
;	TYPE <ufn>	Print file
;	TYPE <ufn> P	Print file with paging flag	
;
	IF	CPRTYP
TYPE:
	ENDIF	;CPRTYP
;
	IF	CPRTYP AND CPRLST
	XRA	A		;TURN OFF PRINTER FLAG
;
; ENTRY POINT FOR CPR LIST FUNCTION (LIST)
;
TYPE0:
	STA	PRFLG		;SET FLAG
	ENDIF	;CPRTYP AND CPRLST
;
	IF	CPRTYP
	CALL	SCANER		;EXTRACT FILENAME.TYP TOKEN
	JNZ	ERROR		;ERROR IF ANY QUESTION MARKS
	CALL	ADVAN		;GET PGDFLG IF IT'S THERE
	STA	PGFLG		;SAVE IT AS A FLAG
	JRZ	NOSLAS		;JUMP IF INPUT ENDED
	I '		;2 SPACES
	DB	FENCE		;THEN FENCE CHAR
	DB	' ',' '+80H	;THEN 2 MORE SPACES
	ENDIF
;
	IF	NOT WIDE
	DB	' '		;SPACE
	DB	FENCE		;THEN FENCE CHAR
	DB	' '+80H		;THEN SPACE
	ENDIF
;
DIR5:
	MVI	B,01H		;PT TO 1ST BYTE OF FILE NAME
DIR6:
	MOV	A,B		;A=OFFSET
	CALL	DIRPTR		;HL NOW PTS TO 1ST BYTE OF FILE NAME
	ANI	7FH		;MASK OUT MSB
	CPI	' '		;NO FILE NAME?
	JRNZ	DIR8		;PRINT FILE NAME IF PRESENT
	POP	PSW
	PUSH	PSW
	CPI	03H
	JRNZ	DIR7
	MVI	A,09H		;PT TO 1ST BYTE OF FILE TYPE
	CALL	DIRPTR		;HLC		;DECREMENT TABLE ENTRY NUMBER
	JRNZ	CMS1
	INR	C		;CLEAR ZERO FLAG
	RET			;COMMAND IS DISK-RESIDENT (ZERO FLAG CLEAR)
;
;**** Section 5 ****
; CPR-Resident Commands
;
;
;Section 5A
;Command: DIR
;Function:  To display a directory of the files on disk
;Forms:
;	DIR <afn>	Displays the DIR files
;	DIR <afn> S	Displays the SYS files
;	DIR <afn> A	Display both DIR and SYS files
;
	IF	CPRDIR
;
DIR:
	MVI	A,80H		;SET SYSTEM BIT EXAMINATION
	PUSH	PSW
	CALL	SCANER		;EXTRACT POSSIBLE D:FILENAMEDIF	;SECURE
;
	MVI	C,NCMNDS	;SET COMMAND COUNTER
CMS1:
	LXI	D,FCBFN 	;PT TO STORED COMMAND NAME
	MVI	B,NCHARS	;NUMBER OF CHARS/COMMAND (8 MAX)
CMS2:
	LDAX	D		;COMPARE AGAINST TABLE ENTRY
	CMP	M
	JRNZ	CMS3		;NO MATCH
	INX	D		;PT TO NEXT CHAR
	INX	H
	DJNZ	CMS2		;COUNT DOWN
	LDAX	D		;NEXT CHAR IN INPUT COMMAND MUST BE <SP>
	CPI	' '
	JRNZ	CMS4
	RET			;COMMAND IS CPR-RESIDENT (ZERO FLAG SET)
CMS3:
	INX	H		;SKIP TO NEXT COMMAND TABLE ENTRY
	DJNZ	CMS3
CMS4:
	INX	H		;SKIP ADDRESS
	INX	H
	DCR	PROMPT
	DB	'Ok','?'+80H
	CALL	CONIN		;GET REPLY FOLDED
	CPI	'Y'		;YES?
	JRNZ	ERARJ		;GET OUT IF NOT
	ENDIF	;EPRMPT
;
	LXI	D,FCBDN 	;DELETE FILE(S) SPECIFIED
	JMP	DELETE		;RESTART CPR AFTER DELETE
;
	ENDIF			;RAS
;
;Section 5C
;Command: LIST
;Function:  Print out specified file on the LST: Device
;Forms:
;	LIST <ufn>	Print file (NO Paging)
;
	IF	CPRLST
LIST:
	MVI	A,0FFH		;TURN ON PRINTER FLAG
	JR	TYPE0
	ENDIF	;CPRLST
;
;Section 5D
;Command: TYPE
;Function:  Print out specified file NA	D		;MASK FOR SYSTEM BIT
SYSTST	EQU	$+1		;POINTER TO IN-THE-CODE BUFFER SYSTST
	CPI	0
	JRNZ	DIR10
	POP	D		;GET ENTRY COUNT (=<CR> COUNTER)
	MOV	A,E		;ADD 1 TO IT
	INR	E
	PUSH	D		;SAVE IT
;
	IF	TWOCOL
	ANI	01H		;OUTPUT <CRLF> IF 2 ENTRIES PRINTED IN LINE
	ENDIF	;TWOCOL
;
	IF	NOT TWOCOL
TWOPOK	EQU	$+1		;FOR APPLE PATCHING
	ANI	03H		;OUTPUT <CRLF> IF 4 ENTRIES PRINTED IN LINE
	ENDIF	;NOT TWOCOL
;
	PUSH	PSW
	JRNZ	DIR4
	CALL	CRLF		;NEW LINE
	JR	DIR5
DIR4:
	CALL	PRINT
;
	IF	WIDE
	DB	' R
	STA	SYSTST
	CALL	SEARF		;SEARCH FOR SPECIFIED FILE (FIRST OCCURRANCE)
	CZ	PRNNF		;PRINT NO FILE MSG;REG A NOT CHANGED
;
; ENTRY SELECTION LOOP; ON ENTRY, A=OFFSET FROM SEARF OR SEARN
;
DIR3:
	JRZ	DIR11		;DONE IF ZERO FLAG SET
	DCR	A		;ADJUST TO RETURNED VALUE
	RRC			;CONVERT NUMBER TO OFFSET INTO TBUFF
	RRC
	RRC
	ANI	60H
	MOV	C,A		;OFFSET INTO TBUFF IN C (C=OFFSET TO ENTRY)
	MVI	A,10		;ADD 10 TO PT TO SYSTEM FILE ATTRIBUTE BIT
	CALL	DIRPTR
	POP	D		;GET SYSTEM BIT MASK FROM D
	PUSH	D
	A SCANNER
;    THIS ROUTINE INCREMENTS THE COUNT OF THE NUMBER OF QUESTION MARKS IN
;    THE CURRENT FCB ENTRY
;
SCQ:
	LDA	QMCNT		;GET COUNT
	INR	A		;INCREMENT
	STA	QMCNT		;PUT COUNT
	RET
;
; CMDTBL (COMMAND TABLE) SCANNER
;   ON RETURN, HL PTS TO ADDRESS OF COMMAND IF CPR-RESIDENT
;   ON RETURN, ZERO FLAG SET MEANS CPR-RESIDENT COMMAND
;
CMDSER:
	LXI	H,CMDTBL	;PT TO COMMAND TABLE
;
	IF	SECURE
	MVI	C,NRCMDS
	LDA	WHEEL		;SEE IF NON-RESTRCTED
	CPI	RESTRCT
	JRZ	CMS1		;PASS IF RESTRCTED
	ENNTC
	DB	'All','?'+80H
	CALL	CONIN		;GET REPLY
	CPI	'Y'		;YES?
ERARJ:
	JNZ	RESTRT		;RESTART CPR IF NOT
	CALL	CRLF		;NEW LINE
ERA1:
	CALL	SLOGIN		;LOG IN SELECTED DISK IF ANY
	XRA	A		;PRINT ALL FILES (EXAMINE SYSTEM BIT)
	MOV	B,A		;NO SYS-ONLY OPT TO DIRPR
	CALL	DIRPR		;PRINT DIRECTORY OF ERASED FILES
;
	IF	EPRMPT
;
;  QUERY USER AFTER FILES ARE SEEN, AND GIVE ONE LAST CHANCE TO BACK OUT
;
	MOV	A,E		;HOW MANY FILES DISPLAYED?
	ORA	A
	JZ	RESTRT		;IF NONE, DON'T ASK OR DELETE
	CALL	PRINTC		;EXT FILE
	JR	DIR3		;CONTINUE
DIR11:
	POP	D		;RESTORE STACK
	RET
;
; FILL FCB @HL WITH '?'
;
FILLQ:
	MVI	B,11		;NUMBER OF CHARS IN FN & FT
FQLP:
	MVI	M,'?'		;STORE '?'
	INX	H
	DJNZ	FQLP
	RET
;
;Section 5B
;Command: ERA
;Function:  Erase files
;Forms:
;	ERA <afn>	Erase Specified files and print their names
;
	IF	NOT RAS		;NOT FOR REMOTE-ACCESS SYSTEM
;
ERA:
	CALL	SCANER		;PARSE FILE SPECIFICATION
	CPI	11		;ALL WILD (ALL FILES = 11 '?')?
	JRNZ	ERA1		;IF NOT, THEN DO ERASES
	CALL	PRIHEN LEAVE BIT SPEC UNCHAGNED
	POP	PSW		;GET FLAG
	XRA	A		;SET NO SYSTEM BIT EXAMINATION
	PUSH	PSW 
DIR2:
	POP	PSW		;GET FLAG
DIR2A:
				;DROP INTO DIRPR TO PRINT DIRECTORY
				; THEN RESTART CPR
	ENDIF	;CPRDIR
;
; DIRECTORY PRINT ROUTINE; ON ENTRY, MSB OF A IS 1 (80H) IF SYSTEM FILES
; EXCLUDED. THIS ROUTINE IS ALSO USED BY ERA.
;
DIRPR:
	MOV	D,A		;STORE SYSTEM FLAG IN D
	MVI	E,0		;SET COLUMN COUNTER TO ZERO
	PUSH	D		;SAVE COLUMN COUNTER (E) AND SYSTEM FLAG (D)
	MOV	A,B		;SYS ONLY SPECIFIE
	CPI	'?'		;CHECK FOR QUESTION MARK (WILD)
	CZ	SCQ		;SCANNER COUNT QUESTION MARKS
SCANF2:
	DJNZ	SCANF		;DECREMENT CHAR COUNT UNTIL 8 ELAPSED
SCANF3:
	CALL	SDELM		;8 CHARS OR MORE - SKIP UNTIL DELIMITER
	RZ			;ZERO FLAG SET IF DELIMITER FOUND
	INX	D		;PT TO NEXT CHAR IN COMMAND LINE
	JR	SCANF3
;
;  FILL MEMORY POINTED TO BY HL WITH SPACES FOR B BYTES
;
SCANF4:
	INX	H		;PT TO NEXT BYTE IN FCBDN
	MVI	M,' '		;FILL FILENAME PART WITH <SP>
	DJNZ	SCANF4
	RET
;
;  INCREMENT QUESTION MARK COUNT FORNX	D		;PUT NEW BUF POINTER
	XCHG
	SHLD	CIBPTR
NOSLAS:
	CALL	SLOGIN		;LOG IN SELECTED DISK IF ANY
	CALL	OPENF		;OPEN SELECTED FILE
	JZ	TYPE4		;ABORT IF ERROR
	CALL	CRLF		;NEW LINE
	MVI	A,NLINES-1	;SET LINE COUNT
	STA	PAGCNT
	LXI	H,CHRCNT	;SET CHAR POSITION/COUNT
	MVI	M,0FFH		;EMPTY LINE
	MVI	B,0		;SET TAB CHAR COUNTER
TYPE1:
	LXI	H,CHRCNT	;PT TO CHAR POSITION/COUNT
	MOV	A,M		;END OF BUFFER?
	CPI	80H
	JRC	TYPE2
	PUSH	H		;READ NEXT BLOCK
	CALL	READF
	POP	H
	JRNZ	TYPE3		;ERROR?
	XRA	A		;RE NOW PTS TO 1ST BYTE OF FILE TYPE
	ANI	7FH		;MASK OUT MSB
	CPI	' '		;NO FILE TYPE?
	JRZ	DIR9		;CONTINUE IF SO
DIR7:
	MVI	A,' '		;OUTPUT <SP>
DIR8:
	CALL	CONOUT		;PRINT CHAR
	INR	B		;INCR CHAR COUNT
	MOV	A,B
	CPI	12		;END OF FILENAME.TYP?
	JRNC	DIR9		;CONTINUE IF SO
	CPI	09H		;END IF FILENAME ONLY?
	JRNZ	DIR6		;PRINT TYP IF SO
	MVI	A,'.'		;PRINT DOT BETWEEN FILE NAME AND TYPE
	CALL	CONOUT
	JR	DIR6
DIR9:
	POP	PSW
DIR10:
	CALL	BREAK		;CHECK FOR ABORT
	JRNZ	DIR11
	CALL	SEARN		;SEARCH FOR N.TYP TOKEN
	CALL	SLOGIN		;LOG IN DRIVE IF NECESSARY
	LXI	H,FCBFN 	;MAKE FCB WILD (ALL '?') IF NO FILENAME.TYP
	MOV	A,M		;GET FIRST CHAR OF FILENAME.TYP
	CPI	' '		;IF <SP>, ALL WILD
	CZ	FILLQ
	CALL	ADVAN		;LOOK AT NEXT INPUT CHAR
	MVI	B,0		;SYS TOKEN DEFAULT
	JRZ	DIR2		;JUMP; THERE ISN'T ONE
	CPI	SYSFLG		;SYSTEM FLAG SPECIFIER?
	JRZ	GOTSYS		;GOT SYSTEM SPECIFIER
	CPI	SOFLG		;SYS ONLY?
	JRNZ	DIR2
	MVI	B,80H		;FLAG SYS ONLY
GOTSYS:
	INX	D
	SDED	CIBPTR
	CPI	SOFLG		;SYS ONLY SPEC?
	JRZ	DIR2		;TSET COUNT
	MOV	M,A
TYPE2:
	INR	M		;INCREMENT CHAR COUNT
	LXI	H,TBUFF 	;PT TO BUFFER
	CALL	ADDAH		;COMPUTE ADDRESS OF NEXT CHAR FROM OFFSET
	MOV	A,M		;GET NEXT CHAR
	ANI	7FH		;MASK OUT MSB
	CPI	1AH		;END OF FILE (^Z)?
	RZ			;RESTART CPR IF SO
;
; OUTPUT CHAR TO CON: OR LST: DEVICE WITH TABULATION
;
	IF	WSTYPE		;WORDSTAR HYPHEN CHECK
	CPI	1FH		;IS CHAR WORDSTAR EOL HYPHEN?
	JRNZ	NOHYPH		;PASS IF NOT
	MVI	A,'-'		;YES, MAKE IT A REAL HYPHEN
NOHYPH:
	ENDIF	;WSTYPE
;
	CPI	' '		;IS CHAR CONTROLSRNUM		;GET USER #, IF ANY
	MOV	E,A		;GET IT READY FOR BDOS
	LDA	FCBFN		;SEE IF # SPECIFIED
	CPI	' '
	JRNZ	SUSER		;SELECT IF WANTED
	ENDIF	;DRUSER
;
	JMP	RCPRNL		;RESTART CPR
COM1:
	LDA	FCBFT		;FILE TYPE MUST BE BLANK
	CPI	' '
	JNZ	ERROR
	LXI	H,COMMSG	;PLACE DEFAULT FILE TYPE (COM) INTO FCB
	LXI	D,FCBFT		;COPY INTO FILE TYPE
	LXI	B,3		;3 BYTES
	LDIR
	LXI	H,TPA		;SET EXECUTION/LOAD ADDRESS
	PUSH	H		;SAVE FOR EXECUTION
	CALL	MEMLOAD		;LOAD MEMORY WITH FILE SPECIFIED IN CMD LINE
				; (NO REDR	;COMPARE IT AGAINST CURRENT DEFAULT DRIVE
	MOV	A,M		;MATCH?
	ORA	A
	JRZ	REN2
	CMP	B		;CHECK FOR DRIVE ERROR
	MOV	M,B
	JRNZ	REN4
REN2:
	MOV	M,B
	XRA	A
	STA	FCBDN		;SET DEFAULT DRIVE
	LXI	D,FCBDN 	;RENAME FILE
	MVI	C,17H		;BDOS RENAME FCT
	CALL	GRBDOS
	RNZ
REN3:
	CALL	PRNNF		;PRINT NO FILE MSG
REN4:
	JMP	ERRLOG
;
	ENDIF			;RAS
;
;Section 5G
;Command: USER
;Function:  Change current USER number
;Forms:
;	USER <unum>	Select specified user number;<unum> is in DEC
;
	IF	DRUSER		;IF ;GET PAGE COUNT
	JRZ	SAVE3		;ERROR?
	XRA	A		;SET RECORD COUNT FIELD OF NEW FILE'S FCB
	STA	FCBCR
	CALL	ADVAN		;LOOK FOR 'S' FOR SECTOR OPTION
	INX	D		;PT TO AFTER 'S' TOKEN
	CPI	SECTFLG
	JRZ	SAVE0
	DCX	D		;NO 'S' TOKEN, SO BACK UP
	DAD	H		;DOUBLE IT FOR HL=SECTOR (128 BYTES) COUNT
SAVE0:
	SDED	CIBPTR		;SET PTR TO BAD TOKEN OR AFTER GOOD TOKEN
	LXI	D,TPA		;PT TO START OF SAVE AREA (TPA)
SAVE1:
	MOV	A,H		;DONE WITH SAVE?
	ORA	L		;HL=0 IF SO
	JRZ	SAVE2
	DCX	H		;COUNT DOWN ON SECTORS
	PUSH	H		mber of pages (start at 100H)
;				from TPA into specified file; <Number of
;				Pages> is in DEC
;	SAVE <Number of Sectors> <ufn> S
;				Like SAVE above, but numeric argument specifies
;				number of sectors rather than pages
;
	IF	NOT RAS		;NOT FOR REMOTE-ACCESS SYSTEM
;
SAVE:
	CALL	NUMBER		;EXTRACT NUMBER FROM COMMAND LINE
	MOV	L,A		;HL=PAGE COUNT
	MVI	H,0
	PUSH	H		;SAVE PAGE COUNT
	CALL	EXTEST		;TEST FOR EXISTENCE OF FILE AND ABORT IF SO
	MVI	C,16H		;BDOS MAKE FILE
	CALL	GRBDOS
	POP	H		;Command: COM file processing
;Function:  To load the specified COM file from disk and execute it
;Forms:
;	<command>
;
COM:
	LDA	FCBFN		;ANY COMMAND?
	CPI	' '		;' ' MEANS COMMAND WAS 'D:' TO SWITCH
	JRNZ	COM1		;NOT <SP>, SO MUST BE TRANSIENT OR ERROR
	LDA	TEMPDR		;LOOK FOR DRIVE SPEC
	ORA	A		;IF ZERO, JUST BLANK
	JZ	RCPRNL
	DCR	A		;ADJUST FOR LOG IN
	STA	TDRIVE		;SET DEFAULT DRIVE
	CALL	SETU0D		;SET DRIVE WITH USER 0
	CALL	LOGIN		;LOG IN DRIVE
;
	IF	DRUSER		;DRIVE/USER HACKERY OK?
	CALL	UTENCE AND RETURN
				; IF FILE DOESN'T EXIST; ABORT IF IT DOES
	LDA	TEMPDR		;SAVE CURRENT DEFAULT DISK
	PUSH	PSW		;SAVE ON STACK
REN0:
	LXI	H,FCBDN 	;SAVE NEW FILE NAME
	LXI	D,FCBDM
	LXI	B,16		;16 BYTES
	LDIR
	CALL	ADVAN		;ADVANCE CIBPTR
	CPI	'='		;'=' OK
	JRNZ	REN4
REN1:
	XCHG			;PT TO CHAR AFTER '=' IN HL
	INX	H
	SHLD	CIBPTR		;SAVE PTR TO OLD FILE NAME
	CALL	SCANER		;EXTRACT FILENAME.TYP TOKEN
	JRNZ	REN4		;ERROR IF ANY '?'
	POP	PSW		;GET OLD DEFAULT DRIVE
	MOV	B,A		;SAVE IT
	LXI	H,TEMPAVE PTR TO FCB
	CALL	PRINTC
	DB	'Delete File','?'+80H
	CALL	CONIN		;GET RESPONSE
	POP	D		;GET PTR TO FCB
	CPI	'Y'		;KEY ON YES
	JNZ	RSTCPR		;RESTART IF NO, SP RESET EVENTUALLY
	PUSH	D		;SAVE PTR TO FCB
	CALL	DELETE		;DELETE FILE
	POP	D		;GET PTR TO FCB
	RET
;
	ENDIF			;RAS
;
;Section 5F
;Command: REN
;Function:  To change the name of an existing file
;Forms:
;	REN <New ufn>=<Old ufn>	Perform function
;
	IF	NOT RAS		;NOT FOR REMOTE-ACCESS SYSTEM
;
REN:
	CALL	EXTEST		;TEST FOR FILE EXISH		;COMBINE WITH INC BELOW TO GET ZERO
;
PRT:	INR	B		;INCREMENT CHAR COUNT
NOBOP:	CALL	LCOUT		;PRINT IT
;
; CONTINUE PROCESSING
;
;
TYPE2L:
	CALL	BREAK		;CHECK FOR ABORT
	JRZ	TYPE1		;CONTINUE IF NO CHAR
	CPI	'C'-'@' 	;^C?
	RZ			;RESTART IF SO
	JR	TYPE1
TYPE3:
	DCR	A		;NO ERROR?
	RZ			;RESTART CPR
TYPE4:
	JMP	ERRLOG
	ENDIF	;CPRTYP
;
;Section 5E
;Command: SAVE
;Function:  To save the contents of the TPA onto disk as a file
;Forms:
;	SAVE <Number of Pages> <ufn>
;				Save specified nuNDIF			;RAS
;
;Section 5J
;Command: GO
;Function:  To Call the program in the TPA without loading

;	     loading from disk. Same as JUMP 100H, but much
;	     more convenient, especially when used with
;	     parameters for programs like STAT. Also can be
;	     allowed on remote-access systems with no problems.
;
;Form:
;	GO <parameters like for COMMAND>
;
	IF	NOT RAS		;ONLY IF RAS
;
GO:	LXI	H,TPA		;Always to TPA
	JR	CALLPROG	;Perform call
;
	ENDIF			;END OF GO FOR RAS
;
;Section 5K
;<unum> is in DEC
;
	IF	NOT RAS		;NOT FOR REMOTE-ACCESS SYSTEM
DFU:
	CALL	USRNUM		;GET USER NUMBER
	STA	DFUSR		;PUT IT AWAY
	JR	RSTJMP		;RESTART CPR (NO DEFAULT LOGIN)
	ENDIF	;NOT RAS
;
;Section 5I
;Command: JUMP
;Function:  To Call the program (subroutine) at the specified address
;	     without loading from disk
;Forms:
;	JUMP <adr>		Call at <adr>;<adr> is in HEX
;
	IF	NOT RAS		;NOT FOR REMOTE-ACCESS SYSTEM
;
JUMP:
	CALL	HEXNUM		;GET LOAD ADDRESS IN HL
	JR	CALLPROG	;PERFORM CALL
;
	ENLE IS ALSO USED BY MEMLOAD FOR TPA FULL ERROR
;
PRNLE:	CALL	PRINTC		;DISK OR MEM FULL
	DB	'Ful','l'+80H
;
SAVE3:	JMP	DEFDMA		;SET DMA TO 0080 AND RESTART CPR
				; OR RETURN TO MLERR
;
; Test File in FCB for existence, ask user to delete if so, and abort if he
;  choses not to
;
EXTEST:
	CALL	SCANER		;EXTRACT FILE NAME
	JNZ	ERROR		;'?' IS NOT PERMITTED
	CALL	SLOGIN		;LOG IN SELECTED DISK
	CALL	SEARF		;LOOK FOR SPECIFIED FILE
	LXI	D,FCBDN		;PT TO FILE FCB
	RZ			;OK IF NOT FOUND
	PUSH	D		;S CODE?
	JRNC	PRT		;GO BOP CHAR COUNT AND PRINT IF NOT
	CPI	CR		;IS CHAR A CR?
	JRZ	YESCR		;IF SO, GO ZERO B THEN PRINT
	CPI	FFEED		;FORM FEED?
	JRZ	YESCR		;MANY PRINTERS RETURN CARRIAGE ON THIS
	CPI	LF		;LINE FEED?
	JRZ	NOBOP		;PRINT, BUT DON'T BOP B
	CPI	BEL		;BELL?
	JRZ	NOBOP		;GO RING BUT DON'T BOP B
	CPI	TAB		;TAB?
	JRNZ	TYPE2L		;IF NOT, NO OTHER CHOICES, TOSS CONTROL
LTAB:
	MVI	A,' '		;<SP>
	CALL	LCOUT
	INR	B		;INCR POS COUNT
	MOV	A,B
	ANI	7
	JRNZ	LTAB
	JR	TYPE2L
;
YESCR:	MVI	B,0FFTURN IF ERROR OR TOO BIG)
	POP	H		;GET EXECUTION ADDRESS
;
; CALLPROG IS THE ENTRY POINT FOR THE EXECUTION OF THE LOADED
;   PROGRAM. ON ENTRY TO THIS ROUTINE, HL MUST CONTAIN THE EXECUTION
;   ADDRESS OF THE PROGRAM (SUBROUTINE) TO EXECUTE
;
CALLPROG:
	SHLD	EXECADR		;PERFORM IN-LINE CODE MODIFICATION
	CALL	DLOGIN		;LOG IN DEFAULT DRIVE
	CALL	SCANER		;SEARCH COMMAND LINE FOR NEXT TOKEN
	LXI	H,TEMPDR	;SAVE PTR TO DRIVE SPEC
	PUSH	H
	MOV	A,M		;SET DRIVE SPEC
	STA	FCBDN
	LXI	H,FCBDN+10H	;PT TO 2DRIVE/USER CODE OK...
USER:
	CALL	USRNUM		;EXTRACT USER NUMBER FROM COMMAND LINE
	MOV	E,A		;PLACE USER NUMBER IN E
SUSER:	CALL	SETUSR		;SET SPECIFIED USER
	ENDIF	;DRUSER
RSTJMP:
	JMP	RCPRNL		;RESTART CPR
;
;Section 5H
;Command: DFU
;Function:  Set the Default User Number for the command/file scanner
;	     (MEMLOAD)
;	    Note: When under SECURE mode, this will select the second
;	          user area to check for programs (normally user 15).
;
;Forms:
;	DFU <unum>	Select Default User Number;SAVE PTR TO BLOCK TO SAVE
	LXI	H,128		;128 BYTES PER SECTOR
	DAD	D		;PT TO NEXT SECTOR
	PUSH	H		;SAVE ON STACK
	CALL	DMASET		;SET DMA ADDRESS FOR WRITE (ADDRESS IN DE)
	LXI	D,FCBDN 	;WRITE SECTOR
	MVI	C,15H		;BDOS WRITE SECTOR
	CALL	BDOSB		;SAVE BC
	POP	D		;GET PTR TO NEXT SECTOR IN DE
	POP	H		;GET SECTOR COUNT
	JRZ	SAVE1		;CONTINUE IF NO WRITE ERROR
	JR	PRNLE		;GO PRINT ERROR AND RESET DMA
SAVE2:
	LXI	D,FCBDN 	;CLOSE SAVED FILE
	CALL	CLOSE
	INR	A		;ERROR?
	JRNZ	SAVE3		;PASS IF OK
;
;  PRND FILE NAME
	CALL	SCANX		;SCAN FOR IT AND LOAD IT INTO FCBDN+16
	POP	H		;SET UP DRIVE SPECS
	MOV	A,M
	STA	FCBDM
	XRA	A
	STA	FCBCR
	LXI	D,TFCB		;COPY TO DEFAULT FCB
	LXI	H,FCBDN 	;FROM FCBDN
	LXI	B,33		;SET UP DEFAULT FCB
	LDIR
	LXI	H,CIBUFF-1
COM4:
	INX	H
	MOV	A,M		;SKIP TO END OF 2ND FILE NAME
	ORA	A		;END OF LINE?
	JRZ	COM5
	CPI	' '		;END OF TOKEN?
	JRNZ	COM4
;
; LOAD COMMAND LINE INTO TBUFF
;
COM5:
	MVI	B,-1		;SET CHAR COUNT
	LXI	D,TBUFF		;PT TO CHAR POS
	DCX	H
COM6:
	INR	B		;hen press return.$
Destination drive name (or return to reboot)? $
Destination on @, then press return.$
Function complete.$
No source file on disk.$
Source file incomplete.$
$
SYSGEN will only read/write floppy disks.$
Disk select error.$
Error reading system.$
Error writing system.$
Error verifying system.$ˆ1	#LGDSDD62:äËG(#Ëò:G2€x· €åÕúíRÑá0Û2G:€¸0«:ãËG({î__‚Û12Á>Ã2!ú"2!ì"!	ì^#Vë6É!~æG:O=¸0~æðwNÃä!:M=¹ØË;MOVE 128 BYTES PER SECTOR
	DAD	D		;PT TO NEXT SECTOR IN HL
	JR	ML2
;
ML3:
	DCR	A		;LOAD COMPLETE
	JZ	RESETUSR	;IF ZERO, OK, GO RESET CORRECT USER #
				; ON WAY OUT, ELSE FALL THRU TO PRNLE
;
;  TPA FULL
;
ML4:	CALL	PRNLE		;PRINT MSG AND RESET DEF DMA
;
; TRANSIENT LOAD ERROR
;
MLERR:
		;NOTE THAT THERE IS AN EXTRA RETURN ADDRESS ON
		; THE STACK.  IT WILL BE TOSSED WHEN ERROR EXITS
		; TO RESTRT, WHICH RELOADS SP.
	CALL	RESETUSR	;RESET CURRENT USER NUMBER
				;  RESET MUST BE DONE BEFOrn point for when the .COM (or GET) file is not found the
; first time, Drive A: is selected for a second attempt
;
MLA:
	CALL	SLOGIN		;LOG IN SPECIFIED DRIVE IF ANY
	CALL	OPENF		;OPEN COMMAND.COM FILE
	JRNZ	MLA1		;FILE FOUND - LOAD IT
;
	IF	SECURE
;
;  IF SECURE ENABLED, SEARCH CURRENT DRIVE, CURRENT USER, THEN
; IF IN WHEEL MODE, SEARCH UNDER LAST USER SET BY DFU (ORIG
; "RESUSR" AFTER WARM BOOT) ON CURRENT DRIVE. IF NOT FOUND, OR
; NOT IN WHEEL MODE, THEN SEARCH ON CURRENT DRIVE, UNDER USERLL THRU TO MEMLOAD
;
	ENDIF			;RAS
;
; LOAD MEMORY WITH THE FILE WHOSE NAME IS SPECIFIED IN THE COMMAND LINE
;   ON INPUT, HL CONTAINS STARTING ADDRESS TO LOAD
;
;  EXIT BACK TO CALLER IF NO ERROR.  IF COM FILE TOO BIG OR
; OTHER ERROR, EXIT DIRECTLY TO MLERR.
;
MEMLOAD:
	SHLD	LOADADR		;SET LOAD ADDRESS
	CALL	GETUSR		;GET CURRENT USER NUMBER
	STA	TMPUSR		;SAVE IT FOR LATER
	STA	TSELUSR 	;TEMP USER TO SELECT
;
;   MLA is a reentry point for a non-standard CP/M Modification
; This is the retuTÍ)Í¯õ:TÍ]ñ·À!	6í¡ ê¯É>ÉÍ]·À2CËg 
íCQ2D^#V!xIí°ÉþA8;þQ07æ=OÍ©|µ(*åÕ
^#V!”í±(
¶	Í¯ÑáÉ@4€($Pâ	Í>ÑáÉ*.é!€"S*E"U"G:Q2P*E:CWËg(Ë£>2O{ÓËK(zÓ4:D±Ó0Û40ûÛ0æ˜À:OÓ2zö€Ó43:AÓ0Û48í¢Ã	Û0·ÀÕí[SÑå!O:P¾(44¾8áÃø6áÕ*Uí[SÑÃøáíKSíB"UåíKGíBáò|:|	þD Ëò:R2PíCS:z	þD {î_\ÃÙ¯É
SYSGEN Vers 2.2
Intelligent Terminals Corp.
Release 5b - 03/27/81
$
Source drive name (or return to skip)? $
Source on A, tECURE
	LDA	TMPUSR		;GO TO 'CURRENT' USER CODE
	JR	SETTSE
	ENDIF	;SECURE
;
; FILE FOUND -- PROCEED WITH LOAD
;
MLA1:
LOADADR	EQU	$+1
	LXI	H,TPA
ML2:
	MVI	A,ENTRY/256-1	;GET HIGH-ORDER ADR OF JUST BELOW CPR
	CMP	H		;ARE WE GOING TO OVERWRITE THE CPR?
	JRC	ML4		;ERROR IF SO
	PUSH	H		;SAVE ADDRESS OF NEXT SECTOR
	XCHG			;... IN DE
	CALL	DMASET		;SET DMA ADDRESS FOR LOAD
	LXI	D,FCBDN 	;READ NEXT SECTOR
	CALL	READ
	POP	H		;GET ADDRESS OF NEXT SECTOR
	JRNZ	ML3		;READ ERROR OR EOF?
	LXI	D,128		Z	MLA0		;..EQUAL DEFAULT, AND JUMP IF SO
	ENDIF	;NOT SECURE
;
	STA	TSELUSR		;PUT DOWN NEW ONE
	MOV	E,A
	CALL	SETUSR		;GO SET NEW USER NUMBER
	JR	MLA		;AND TRY AGAIN
;
; ERROR ROUTINE TO SELECT DRIVE A: IF DEFAULT WAS ORIGINALLY SELECTED
;
MLA0:
	LXI	H,TEMPDR	;GET DRIVE FROM CURRENT COMMAND
	XRA	A		;A=0
;
	IF	SECURE
	STA	DFLAG		;ALLOW A: SEARCH
	ENDIF	;SECURE
;
	ORA	M
	JNZ	MLERR		;ERROR IF ALREADY DISK A:
	MVI	M,1		;SELECT DRIVE A:
;
	IF	NOT SECURE
	JR	MLA
	ENDIF	;NOT SECURE
;
	IF	ST ON US
	CALL	SETU0D		;SET USER 0/DISK
	CALL	LOGIN		;LOGIN DISK
	JMP	RESTRT		;RESTART CPR
;
;Section 5L
;Command: GET
;Function:  To load the specified file from disk to the specified address
;Forms:
;	GET <adr> <ufn>	Load the specified file at the specified page;
;			<adr> is in HEX
;
	IF	NOT RAS		;NOT FOR REMOTE-ACCESS SYSTEM
;
GET:
	CALL	HEXNUM		;GET LOAD ADDRESS IN HL
	PUSH	H		;SAVE ADDRESS
	CALL	SCANER		;GET FILE NAME
	POP	H		;RESTORE ADDRESS
	JNZ	ERROR		;MUST BE UNAMBIGUOUS
;
; FAÃfCopyright (C) 1978, Digital Research Portions Copyright (C) 1981, Intelligent Terminals Corporationí{Í|2B~	Í:]þ Êì\Í<Âš	ÍÃ¯2|Å\ÍÁ·ÂÎð!	åT]Í\Íá·Â3€å™	ÍÃÍþÊþaØþ{Ðæ_ÉÆ	ÍÍÙþÊ32üð	ÍÍÙþÂ³	ÍóÍœ:B·(û·Ê3÷	ÍÃì	ÍÍÙþÊ2TC	ÍÍÙþÂ³	ÍóÍÀ:B·(û·(	ÍóÍï:B·(û·('	ÍÃ3j	ÍÃ3>¢2>ˆ2A!	"E:üÍ)¯ÀÍ¯õ:üÍ]ñÉ>£2>¨2A!	"E:TÍ)¯À!Ix	í°Í¯õ:TÍ]ñÉ>¢2>ˆ2A!6"E:;TRIAL PW TO A
	CMP	M		;CHECK FOR MATCH
	JNZ	COM		;NOPE.. LOOK FOR PASS.COM
	INX	H		;INCREMENT COUNTER
	INX	D
	DJNZ	CKPASS		;CONTINUE IF MORE
	MVI	A,NOT RESTRCT	;WHEEL = NOT RESTRCT

PWOUT:	STA	WHEEL
	JMP	RESTRT
;
NORM:
	MVI	A,RESTRCT
	JR	PWOUT
;
PASSWD:
	DB	'YOURPW'		;YOUR PASSWORD
PRGEND:	EQU	$			;END OF PASSWORD
;
	ENDIF	;INPASS
;
	END
NOT PASS.COM
PASS:
	LXI	H,PASSWD		;SET UP POINTERS
	LXI	D,CIBUFF+NCHARS+1
	MVI	B,PRGEND-PASSWD		;B= LENGTH
CKPASS:	LDAX	D		;RESTORE BC
	JRNZ	SETTSE		;GO TRY IF NOT
MLA00:				;SS IF NOT
TSELUSR	EQU	$+1		;MARK IN-THE-CODE VARIABLE
	MVI	A,0		;GET CURR USER
	SUI	DEFUSR		;IS IT UNRESTRICTED COM AREA?
	JRZ	MLA0		;NO MORE CHOICES IF SO
	STA	DFLAG		;MAKE DFLAG NON-ZERO IF NOT
	MVI	A,DEFUSR	; AND TRY UNRESTRICTED COM AREA
SETTSE:
	ENDIF	;SECURE
;
	IF	NOT SECURE
DFUSR	EQU	$+1		;MARK IN-THE-CODE VARI