;DISK UTILITY -	By Ward Christensen
;DU.ASM	V6.1	EDIT 00
;
FALSE	EQU	0
TRUE	EQU	NOT FALSE
;
STDCPM	EQU	TRUE 	;<----
HEATH	EQU	NOT STDCPM
;
	IF	STDCPM
MAXTRK	EQU	77	;MAX TRK #
BASE	EQU	0	;BASE ADDR OF CP/M
TRKSIZE	EQU	26	;SECTORS PER TRACK
SYSTRK	EQU	2	;# OF SYSTEM TRACKS
	ENDIF
;
	IF	HEATH
MAXTRK	EQU	40
BASE	EQU	4200H	;0 FOR REGULAR CP/M
TRKSIZE	EQU	20	;SECTORS/TRACK
SYSTRK	EQU	3	;# OF SYSTEM TRACKS
	ENDIF
;
;N-O-T-E IF YOU HAVE A SYSTEM WITH
;OTHER THAN 76 OR 40 TRACKS, (WHICH ARE
;AUTOMATICALLY HANDLED) YOU MIGHT WANT
;TO CHANGE THE ERROR MESSAGE "NOT IN
;TRKS 0-76" AT LABEL "SETTRK".
;
;	8/6/78
;ORIGINALLY WRITTEN TO RECONSTRUCT BLOWN
;DISKS ON CBBS VIA REMOTE ACCESS
;
;		----------------
;Sorry for the lack of comments in the code 
;portion of this program - it was just hacked
;together to satisfy my needs, but lots of
;other people found it useful.  Its external
;documentation is good, but its sadly lacking
;comments on the instructions.
;		----------------
;
;	11/12/78 WLC
;ADD LOGIN COMMAND
;
;	11/26/78 WLC
;ADD DISK # TO LOGIN COMMAND
;
;	02/25/79 WLC
;PUT SECTOR READ INTO "S" COMMAND
;
;	10/10/79 WLC
;SAVE REGS IN BIOS CALLS
;TRANSLATE INPUT TO UPPER CASE
;ADD COMMANDS: 	< SAVE SECTOR
;		> RESTORE SECT
;		/ REPEAT
;ALLOW CHANGE FROM-THRU
;	01/06/80 WLC
;REWRITE "F" COMMAND
;	01/07/79
;ADD VIEW COMMAND
;	01/08/80
;REPOSITION AFTER "M" COMMAND
;	02/12/80
;MOD FOR HEATH CP/M
;	02/24/80
;MOD LOGIN COMMAND TO NOT REALLY DO LOG, JUST
;DRIVE SELECT
;	05/21/80
;MAKE SECTOR, TRACK, BE DECIMAL, NOT HEX.
;ALSO DIS-ALLOW A READ UNTIL POSITIONED.
;(DU OTHERWISE NOT IN SYNC WITH CP/M)
;	06/22/80
;Put in "Q" command.  Fix so "P" (printer)
;mode outputs L/F's.
;
CR	EQU	0DH
LF	EQU	0AH
TAB	EQU	09H
;
;Any valid command string may be placed as an
;operand of the original DU command, i.e.:
;
;	DU G0;D;G2;=OK<D><A><1A>;D
;
;Functions supported:
;
;	Tnn	Seek to track nn (Decimal) (no read)
;	Snn	Position to sector nn (decimal), and read
;	Gnn	Position to group nn and read.
;	G	Shows current position
;	V	Views the current sector.
;		(assumes ASCII data)
;	Vnn	Views nn sectors
;	Fname	print directory for file "name",
;		then positions to it's directory 
;		sector.  (does N-O-T position correctly
;		with CP/M 2.0: use G0;=FOO     ASM
;		for example, to find the file.
;
;	=string	Ascii search, starting at current
;		sector.  <xx> hex may be imbedded,
;		or used alone:  To find "IN 0FEH":
;		=<db><fe>
;
;	L	Re-logs in the current disk. You may pull
;		out a disk, put in a new, and "L" just
;		to log it in (prevents 	CP/M 1.4
;		from getting R/O errors). (hmmm, on second
;		thought, I'm not doing any BDOS calls
;		anyway, so no R/O errors COULD occur..
;		owell, better safe than sorry)
;
;	Lx	Logs in disk 'x', such as: LB
;
;	D	Dump sector, hex + ASCII
;	A	Dump sector, ASCII only
;	H	Dump sector, hex only
;
;note all dump commands (D, A, H) may be optionally
;	followed by a starting and ending address:
;	D0,7F  is the same as just D
;	D3,5
;	A20,3F
;
;	CHaddr,val,val,val... change hex in sector
;	CAaddr,char string... change ASCII in sector
;		NOTE that <xx> may be hex imbedded
;		in the Ascii:  ca0,OK<d><a><1a>
;
;		----> Use W to write changes to disk.
;		Note that the C command echoes
;		the overlaid data for verification.
;
;	CHaddr-addr,byte
; or	CAaddr-addr,byte	repeats a change
;
;	#	(Used by Ward to set the sector
;		order table to 1,2,3,4,5...
;		for my strange disks)
;
;	+	advance 1 sector (if below track 2,
;		this advances to next numerical, if
;		2 or >, advances based on CP/M's normal
;		sector scrambling algorithm, i.e. so +
;		will get the next logical sector of the file
;
;	-	backs up 1 logical sector
;
;		note + and - may take an amount:
;		for example, +F steps in 15 sectors
;
;	?	Gives command summary
;
;	M	Dumps a map of the group allocations
;		for files.
;	Mn	Shows which file is allocated to
;		group "n".
;
;	Q	Preceeding any command makes DU run
;		in "Quiet" mode - no msgs to console
;		except in case of a disk error.
;
;	R	Reads the sector currently positioned to
;		into memory.  Note R (Read) is implicit in
;		the G, +, and - commands, but N-O-T in the
;		S and T commands (I did it because I was
;		tired of disk reading after T command before
;		I had a chance to issue the S command)
;
;	W	Write back the current sector (N-O-T-E may
;		not be used after an F command, as CP/M was
;		used to find the file in the directory
;
;	X	Exit back to CP/M (Must press return).  Ctl-c
;		was too easy to hit over modem lines, so I
;		decided on 2-byte (X, CR) to exit.
;
;	P	Toggle printer switch on/off
;
;	Z	Sleep - causes the program to pause, such
;		as to look at a dump.  Z is 1 sec.  Znn
;		is nn tenths of a second on a 2 MHz 8080.
;
;	<	Saves current sector in a save buffer
;
;	>	Gets saved buffer.  < and > may be used
;		to move a sector to another place.
;
;	/	Repeats entire command.  Defaults
; or	/nn	to "forever".  NN may be 2 to 254
;
;multiple commands may be separated by ";"
;
;Example: the following commands will erase the
;	b disk directory to all E5's:
;
;	lb			log in b drive
;	g0			position to directory.
;	ch0-7f,e5		fill with e5
;	<			save the sector
;	>;w;+;/16		restore, write, next,
;				repeat 16
;
;----This could be shortened to:
;
;	lb;g0;ch0-7f,e5;<
;	>;w;+;/16
;
	ORG	BASE+100H
	LXI	SP,STACK ;EXITS VIA JMP 0
;SET UP LOCAL JMPS TO BIOS
	LHLD	BASE+1	;WARM BOOT POINTER
	LXI	D,3
	DAD	D	
	SHLD	VCONST+1
	DAD	D
	SHLD	VCONIN+1
	DAD	D
	SHLD	VCONOUT+1
	DAD	D	;LIST
	SHLD	VLIST+1
	DAD	D	;PUNCH
	DAD	D	;RDR
	DAD	D
	SHLD	VHOME+1
	DAD	D
	SHLD	VSELDK+1
	DAD	D
	SHLD	VSETTRK+1
	DAD	D
	SHLD	VSETSEC+1
	DAD	D
	SHLD	VSETDMA+1
	DAD	D
	SHLD	VREAD+1
	DAD	D
	SHLD	VWRITE+1
	CALL	ILPRT
	DB	'DISK UTILITY (DU) V6.1 06/22/80',CR,LF
	DB	CR,LF,'Type ? for help'
	DB	CR,LF,'Type X to exit'
	DB	CR,LF,0
	LXI	H,BASE+80H	;TO INPUT BUFF
	MOV	A,M
	ORA	A
	JZ	PROMPTR	;NO COMMAND
;
;GOT INITIAL COMMAND, SET IT UP
;
	MOV	B,A	;SAVE LENGTH
	DCR	B
	JZ	PROMPTR
	LXI	D,INBUF
	INX	H	;SKIP LEN
	INX	H	;SKIP ' '
	CALL	MOVE
	MVI	A,CR
	STAX	D
	LXI	H,INBUF
	JMP	PROMPTI
;
PROMPTR	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	RDBUF
PROMPTI	MVI	A,255
	STA	TOGO	;LOOP COUNT FOR "/"
PROMPT	LXI	SP,STACK
	XRA	A	;ZERO 2-UP PRINT
	STA	TWOUP	;..SWITCH
	MVI	A,1
	STA	FTSW	;TELL SEARCH NOT TO INCR
	PUSH	H
	LXI	H,BASE+100H
	SHLD	BUFAD	;FOR RDBYTE
	POP	H
	CALL	CTLCS	;ABORT?
	JZ	PROMPTR	;..YES, READ BUFFER
;DO WE HAVE TO POSITION IN DIRECTORY AFTER FIND?
	LDA	FINDFLG
	ORA	A
	JNZ	POSDIR	;POSITION IN DIRECTORY
	MOV	A,M
	CPI	CR
	JZ	PROMPTR
	CPI	';'	;LOGICAL CR?
	INX	H
	JZ	PROMPT
	CALL	UPCASE
	STA	DUMTYPE	;TYPE OF DUMP (A,D,H)
	CPI	'!'	! JZ WARDSK ;<----DON'T USE
	CPI	'+'	! JZ PLUS
	CPI	'-'	! JZ MINUS
	CPI	'='	! JZ SEARCH
	CPI	'<'	! JZ SAVE
	CPI	'>'	! JZ RESTORE
	CPI	'?'	! JZ HELP
	CPI	'A'	! JZ DUMP
	CPI	'C'	! JZ CHG
	CPI	'D'	! JZ DUMP
	CPI	'F'	! JZ POSFIL
	CPI	'G'	! JZ POS
	CPI	'H'	! JZ DUMP
	CPI	'L'	! JZ LOGIN
	CPI	'M'	! JZ MAP
	CPI	'P'	! JZ PRINTFF
	CPI	'Q'	! JZ QUIET
	CPI	'R'	! JZ DOREAD
	CPI	'S'	! JZ POS
	CPI	'T'	! JZ POS
	CPI	'V'	! JZ VIEW
	CPI	'W'	! JZ DOWRITE
	CPI	'X'	! JZ BASE
	CPI	'Z'	! JZ SLEEP
	CPI	'/'	! JZ REPEAT
;
WHAT	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'?',0
	JMP	PROMPTR
;
;QUIET MODE
;
QUIET	STA	QFLAG	;NOW QUIET
	JMP	PROMPT
;
;REPEAT BUFFER CONTENTS
;
REPEAT	CALL	DECIN	;NN SPECIFIED?
	MOV	A,E
	ORA	A
	JZ	NNN	;NO.
	LDA	TOGO	;FIRST TIME?
	CPI	0FFH	;WAS IT 0FFH?
	JNZ	NNN	;NO:  COUNTING
	MOV	A,E	;GET COUNT
	STA	TOGO	;SET COUNT
NNN	LXI	H,INBUF	;READY TO REPEAT
	LDA	TOGO
	CPI	0FFH
	JZ	PROMPT	;CONTINUOUS
	DCR	A	;COUNT DOWN
	STA	TOGO
	JNZ	PROMPT
	JMP	PROMPTR	;RESET
;
;TOGGLE PRINT FLAG
;
PRINTFF	LDA	PFLAG
	XRI	1
	STA	PFLAG
	JMP	PROMPT
;
;SLEEP ROUTINE, IN TENTHS OF A SEC
;
SLEEP	CALL	HEXIN	;GET COUNT IF ANY
	MOV	A,E	;ANY?
	ORA	A
	JNZ	SLEEPLP
	MVI	E,10
SLEEPLP	LXI	B,8000	;APPROX .1 SEC @ 2MHz
SLEEP2	DCX	B
	MOV	A,B
	ORA	C
	JNZ	SLEEP2
	PUSH	D
	CALL	CTLCS
	POP	D
	JZ	PROMPTR
	DCR	E
	JNZ	SLEEPLP
	JMP	PROMPT
;
;CHECK FOR CONTROL-C OR S
;
CTLCS	CALL	CONST
	INR	A
	RNZ		;NO CHAR
	CALL	CONIN
	ANI	1FH	;ALLOW ASCII
	CPI	'S'-40H
	CZ	CONIN
	CPI	'C'-40H
	RET		;0 SET IF CTL-C
;
LOGIN	EQU	$
;	MVI	C,RESETDK ;COMMENTED OUT-
;	PUSH	H	;DON'T BOTHER..
;	CALL	BDOS	;TELLING CP/M
;	POP	H
	MOV	A,M	;DISK REQ?
	LXI	D,0
	CPI	CR
	JZ	LGNODK
	CPI	';'
	JZ	LGNODK
	CALL	UPCASE
	INX	H
	SUI	'A'
	MOV	C,A
	PUSH	H
VSELDK	CALL	$-$	;ADDR FILLED IN BY INIT
	JMP	LOGGED
;
LGNODK	EQU	$
;			MVI	C,SELDK
	PUSH	H
;			CALL	BDOS
LOGGED	POP	H
	CALL	NOWRITE
	JMP	PROMPT
;
;READ IN THE DISK DIRECTORY
;
READDIR	PUSH	H
	CALL	NOWRITE	;POSITIONING LOST
	MVI	A,SYSTRK
	STA	CURTRK
	MVI	A,1
	STA	CURSEC
	MVI	B,16	;# OF SECTORS
	LXI	D,DIRECT ;DMA ADDR
RDIRLP	PUSH	B
	PUSH	D
	MOV	B,D
	MOV	C,E
	CALL	VSETDMA
	LDA	CURTRK
	CALL	SETTRK
	LDA	CURSEC
	CALL	SETSEC
	CALL	READ
	CALL	NEXTSEC
	POP	D
	POP	B
	LXI	H,80H
	DAD	D
	XCHG
	DCR	B
	JNZ	RDIRLP
	LXI	B,BASE+80H
	CALL	VSETDMA
	POP	H
	RET
;
;MAP THE DIRECTORY
;
MAP	CALL	READDIR	;READ IN DIRECTORY
	MVI	C,2	;DFLT START
	CALL	HEXIN
	PUSH	H	;SAVE INBUF PTR
	MOV	A,E	;GET START
	ORA	A	;NOTHING?
	JZ	MAPDF	;..YES, DFLT
	MOV	C,E
MAPDF	MOV	A,C
	CALL	HEX
	MVI	A,'-'
	CALL	TYPE
	CALL	GETGRP	;GET GRP(C) TO HL
MAPCONT	INR	C	;NEXT GRP
	JZ	MAPEND	;DONE
	PUSH	H
	CALL	GETGRP	;GET ANOTHER
	POP	D	;SEE IF SAME
	CALL	CTLCS
	JZ	MAPEND2
	MOV	A,D
	CMP	H
	JNZ	MAPDIFF
	MOV	A,E
	CMP	L
	JNZ	MAPDIFF
;SAME, CONTINUE
	JMP	MAPCONT
;
;DIFFERENT FILE ENCOUNTERED
;
MAPDIFF	MOV	A,C
	DCR	A
	CALL	HEX
	XCHG
	CALL	MAPNAME
	JMP	MAPDF
;
;END
;
MAPEND	MOV	A,C	;GET LAST
	DCR	A
	CALL	HEX
	CALL	MAPNAME
	POP	H
	CALL	CRLF
;
;END OF MAP - REPOSITION TO PREVIOUS GROUP
;
MAPEND2	LDA	GROUP
	PUSH	H
	MOV	L,A
	JMP	POSGRP2
;
;PRINT FILE NAME POINTED TO BY HL
;
MAPNAME	CALL	SPACE
	MOV	A,H
	ORA	L	;NONE?
	JZ	NONAME
	MOV	A,M	;SEE IF ALLOC
	ORA	A	;ZERO?
	MVI	A,' '
	JZ	MAPNSP1
	MVI	A,'('
MAPNSP1	CALL	TYPE
	PUSH	H	;SAVE POINTER
	INX	H	;SKIP ALLOC BYTE
	MVI	B,8
	CALL	MAPN2
	MVI	A,'.'
	CALL	TYPE
	MVI	B,3
	CALL	MAPN2
	CALL	SPACE
	MOV	A,M	;GET EXT
	ORI	'0'
	CALL	TYPE
	POP	H
	MOV	A,M
	ORA	A
	MVI	A,' '
	JZ	MAPNSP2
	MVI	A,')'
MAPNSP2	CALL	TYPE	;")" IF ERASED FILE
	LDA	TWOUP
	XRI	1
	STA	TWOUP
	JZ	CRLF
	JMP	DELIM
;
NONAME	CALL	ILPRT
	DB	'++FREE++        ',0
	LDA	TWOUP
	XRI	1
	STA	TWOUP
	JZ	CRLF
DELIM	MVI	A,':'
	JMP	TYPE
;
;PRINT NAME, LENGTH IN B
;
MAPN2	MOV	A,M
	INX	H
	CPI	' '	;PRINTABLE?
	JC	MAPN2H	;..NO, IN HEX
	CPI	7FH	
	JC	MAPN2A
MAPN2H	CALL	BHEX
	JMP	MAPN2Z
MAPN2A	CALL	TYPE
MAPN2Z	DCR	B
	JNZ	MAPN2
	RET
;
;FIND WHICH FILE GROUP(C) BELONGS TO
;
GETGRP	LXI	H,DIRECT
	MVI	A,64	;# OF FILES
	STA	FILECT
GETGLP	PUSH	H	;SAVE POINTER
	LXI	D,15	;DISP TO LENGTH
	DAD	D
	MOV	A,M	;GET LENGTH
	ORA	A	;ZERO?
	JZ	GETGNF	;NO FILE
	CPI	0E5H	;UNUSED, FORMATTED DISK?
	JZ	GETGNF
	MOV	B,A	;SAVE COUNT
	DCR	B	;ALLOW JP BELOW
GETGL2	INX	H	;TO NEXT
	MOV	A,M	;GET GRP
	CMP	C	;CORRECT ONE?
	JZ	GETGOT	;YES, GOT IT.
	MOV	A,B	;GET REC COUNT
	SUI	8
	MOV	B,A
	JP	GETGL2
;NO FILE
GETGNF	POP	H
	LXI	D,32
	DAD	D	;TO NEXT ENTRY
	LDA	FILECT
	DCR	A
	STA	FILECT
	JNZ	GETGLP	;MORE?
	LXI	H,0	;NO, NOT FOUND
	RET
;
;GOT THE FILE
;
GETGOT	POP	H	;POINT TO NAME
	RET
;
;SAVE THE CURRENT SECTOR
;
SAVE	LDA	WRFLG
	ORA	A
	JZ	BADW	;NONE TO SAVE
	PUSH	H
	LXI	H,BASE+80H
	LXI	D,SAVEBUF
	MVI	B,128
	CALL	MOVE
	MVI	A,1	;..SHOW
	STA	SAVEFLG	;..SAVED EXISTS
	POP	H
	JMP	PROMPT
;
;RESTORE THE CURRENT SECTOR
;
RESTORE	LDA	SAVEFLG
	ORA	A
	JZ	NOSAVE ;NONE TO SAVE
	PUSH	H
	LXI	H,SAVEBUF
	LXI	D,BASE+80H
	MVI	B,128
	CALL	MOVE
	POP	H
	JMP	PROMPT
;
NOSAVE	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'++NO "<" SAVE COMMAND ISSUED'
	DB	CR,LF,0
	JMP	PROMPTR
;
;MOVE (HL) TO (DE) LENGTH IN B
;
MOVE	MOV	A,M
	STAX	D
	INX	H
	INX	D
	DCR	B
	JNZ	MOVE
	RET
;
NOWRITE	XRA	A	;GET 0
	STA	WRFLG	;CAN'T WRITE NOW
	RET
;
;NO MATCH IN SEARCH, TRY NEXT CHAR
;
SRNOMAT	POP	H
	CALL	CTLCS	;ABORT?
	JNZ	SEARCH	;..YES
	LXI	H,INBUF
	MVI	M,CR
	JMP	CALCGRP	;SHOW WHERE STOPPED
;
;SEARCH FOR CHARACTER STRING
;
SEARCH	PUSH	H	;SAVE STRING POINTER
SRCHL	CALL	RDBYTE	;GET A BYTE
	PUSH	PSW
	CALL	GETVAL	;GET SEARCH VALUE
	MOV	B,A
	POP	PSW
	CMP	B	;MATCH?
	JNZ	SRNOMAT	;NO MATCH
	INX	H
	MOV	A,M	;DONE?
	CPI	CR
	JZ	SREQU
	CPI	';'
	JNZ	SRCHL
;GOT MATCH
SREQU	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'= AT ',0
	LDA	BUFAD
	ANI	7FH
	CALL	HEX
	CALL	CRLF
	JMP	CALCGRP
;
;GET VALUE FROM INPUT BUFFER
;
GETVAL	MOV	A,M
	CPI	'<'	;HEX ESCAPE?
	RNZ		;NO, RETURN
;"<<" MEANS ONE "<"
	INX	H
	MOV	A,M
	CPI	'<'
	RZ
;GOT HEX
	PUSH	D
	CALL	HEXIN	;GET VALUE
	CPI	'>'	;PROPER DELIM?
	MOV	A,E	;GET VALUE
	POP	D
	JNZ	WHAT	;ERROR
	RET
;
;READ A BYTE AT A TIME
;
RDBYTE	PUSH	H
	LDA	FTSW	;FIRST READ?
	ORA	A
	JNZ	READ1
	LHLD	BUFAD
	MOV	A,L
	ORA	A	;IN BUFFER?
	JM	NORD	;YES, SKIP READ
;
;HAVE TO READ
;
	CALL	NEXTSEC
READ1	XRA	A
	STA	FTSW	;NOT FIRST READ
	LDA	CURSEC
	CALL	SETSEC
	LDA	CURTRK
	CALL	SETTRK
	CALL	READ
	CALL	CALCSUB
	LXI	H,BASE+80H
NORD	MOV	A,M
	INX	H
	SHLD	BUFAD
	POP	H
	RET
;
;VIEW THE FILE IN ASCII STARTING AT
;CURRENT SECTOR, STEPPING THRU THE DISK
;
VIEW	LDA	WRFLG
	ORA	A
	JZ	BADDMP
	CALL	DECIN	;GET # IF ANY
	PUSH	H
	MOV	A,E
	ORA	A
	JNZ	VIEWLP
	INR	E	;DFLT=1
VIEWLP	LXI	H,BASE+80H ;TO DATA
VIEWCHR	CALL	CTLCS
	JZ	VIEWEND
	MOV	A,M
	CPI	1AH
	JZ	VIEWEOF
	CALL	TYPE
	INR	L
	JNZ	VIEWCHR
	DCR	E
	JZ	VIEWEND
	PUSH	D	;SAVE COUNT
	CALL	NEXTSEC
	LDA	CURSEC
	CALL	SETSEC	
	LDA	CURTRK
	CALL	SETTRK
	CALL	READ
	POP	D	;RESTORE COUNT
	JMP	VIEWLP
;
VIEWEOF	CALL	ILPRT
	DB	CR,LF,TAB,'++EOF++',CR,LF,0
;
VIEWEND	POP	H
	CALL	CRLF
	JMP	CALCGRP
;
;DUMP IN HEX OR ASCII
;
DUMP	LDA	WRFLG
	ORA	A
	JNZ	DUMPOK
BADDMP	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'++Can''t dump, no sector read.',CR,LF,0
EXPL	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'Use G command following F,',CR,LF
	DB	'or R or S following T',CR,LF,0
	JMP	PROMPTR
;
DUMPOK	MOV	A,M
	CPI	';'
	JZ	DUMPDF	;DFLT
	CPI	CR
	JNZ	DUMPNDF
;USE DEFAULT
DUMPDF	LXI	B,BASE+80H
	LXI	D,0FFH
	JMP	DUMP1
DUMPNDF	CALL	DISP
	MOV	B,D
	MOV	C,E
	CPI	CR
	JZ	DUMP1
	CPI	';'
	JZ	DUMP1
	INX	H	;SKIP ','
	CALL	DISP
;
;BC = START, DE = END
;
DUMP1	PUSH	H	;SAVE COMMAND POINTER
	MOV	H,B
	MOV	L,C
DUMPLP	MOV	A,L
	ANI	7FH
	CALL	HEX
	CALL	SPACE
	CALL	SPACE
	LDA	DUMTYPE
	CPI	'A'
	JZ	DUMPAS
	PUSH	H	;SAVE START
DHEX	MOV	A,M
	CALL	HEX
	MOV	A,L
	ANI	3
	CPI	3
	CZ	SPACE
	MOV	A,L
	ANI	7
	CPI	7
	CZ	SPACE
	MOV	A,E
	CMP	L
	JZ	DPOP
	INX	H
	MOV	A,L
	ANI	0FH
	JNZ	DHEX
DPOP	CALL	CTLCS
	JZ	PROMPTR
	LDA	DUMTYPE
	CPI	'H'
	JZ	DNOAS	;HEX ONLY
	POP	H	;GET START ADDR
DUMPAS	CALL	ASTER
DCHR	MOV	A,M
	CPI	' '
	JC	DPER
	CPI	7FH
	JC	DOK
DPER	MVI	A,'.'
DOK	CALL	TYPE
	MOV	A,E
	CMP	L
	JZ	DEND
	INX	H
	MOV	A,L
	ANI	0FH
	JNZ	DCHR
DEND	CALL	ASTER
	CALL	CRLF
	PUSH	D
	CALL	CTLCS
	POP	D
	JZ	PROMPTR
	MOV	A,E
	CMP	L
	JNZ	DUMPLP
	POP	H
	JMP	PROMPT
;
DNOAS	POP	B
	CALL	CRLF
	MOV	A,E
	CMP	L
	JNZ	DUMPLP
	POP	H
	JMP	PROMPT
;
;POSITION
;
POS	PUSH	PSW
	MOV	A,M
	CPI	';'
	JZ	POSINQ
	CPI	CR
	JNZ	POSOK
POSINQ	POP	PSW
	JMP	INQ
;
POSOK	POP	PSW
	CPI	'T'
	JZ	POSTRKD
	CPI	'S'
	JZ	POSSECD
	CPI	'G'
	JZ	POSGRPH
	JMP	WHAT
;
POSTRKD	CALL	DECIN
POSTRK	MOV	A,E
	CALL	SETTRK
	CALL	NOWRITE	;TRACK DOESN'T READ
	MVI	A,1
	STA	NOTPOS	;SHOW NOT POSITIONED
	JMP	CALCGRP
;
POSSECD	CALL	DECIN
POSSEC	MOV	A,E
	ORA	A
	JZ	WHAT
	CPI	27
	JNC	WHAT
	CALL	SETSEC
	CALL	READ
	XRA	A
	STA	NOTPOS
;
CALCGRP	CALL	CALCSUB
	JMP	INQ
;
CALCSUB	PUSH	H
	LDA	CURTRK
	SUI	SYSTRK	;GRP 0 IS TRK 2
	MOV	E,A
	MVI	D,0
	LXI	H,0
	MVI	A,TRKSIZE
C1LP	DAD	D
	DCR	A
	JNZ	C1LP
	LDA	CURSEC
	DCR	A
	ADD	L
	MOV	L,A
	MOV	A,H
	ACI	0
	MOV	H,A
	MOV	A,L
	ANI	7
	STA	GRPDISP
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	MOV	A,H
	STA	GROUP
	POP	H
	RET
;
;POSITION IN THE DIRECTORY AFTER A FIND
;
POSDIR	PUSH	H	;SAVE INBUF
	XRA	A
	STA	FINDFLG	;CANCEL POS REQ
	LDA	DIRPOS	;GET POSITION
	RAR
	RAR
	PUSH	PSW
	ANI	7	;GET GRP DISPLACEMENT
	STA	GRPDISP
	POP	PSW
	RAR
	RAR
	RAR
	ANI	1	;GET GROUP
	STA	GROUP
	MOV	L,A	;SETUP FOR POSGRP2
	JMP	POSGRP2	;POSITION TO IT
;
POSGRPH	CALL	HEXIN
POSGRP	MOV	A,E
	STA	GROUP
	XRA	A
	STA	GRPDISP
	PUSH	H
	MOV	L,E	;MULTIPLY
POSGRP2	MVI	H,0	;BY 8
	DAD	H
	DAD	H
	DAD	H
	LDA	GRPDISP	;MAY BE >0 IF "F" CMD.
	ADD	L	;CAN'T CARRY
	MOV	L,A
;DIVIDE BY 26, QUOTIENT = TRK, REMAINDER = SECTOR
	LXI	D,-TRKSIZE
	MVI	B,0	;TRK
DIVLP	INR	B
	DAD	D
	JC	DIVLP
	DCR	B
	LXI	D,TRKSIZE
	DAD	D
	MOV	A,B
	ADI	SYSTRK	;SYSTEM TRACKS TO GRP 0
	CALL	SETTRK
	MOV	A,L
	INR	A
	CALL	SETSEC
	CALL	READ
	POP	H
	XRA	A
	STA	NOTPOS	;NOW POSITIONED
	JMP	INQ
;
POSFIL	CALL	NOWRITE
	MVI	A,1
	STA	FINDFLG	;SO WE POSITION LATER
	LXI	D,FCB
	XRA	A	;LOGGED IN DISK
	STAX	D
	INX	D
	MVI	B,8
	CALL	MVNAME
	MVI	B,3
	CALL	MVNAME
	LXI	D,FCB
	MVI	C,SRCHF
	PUSH	H
	CALL	BDOS
	INR	A
	JNZ	FLOK
	STA	DIRPOS	;GRP 0 IF NOT FOUND
	CALL	ILPRT
	DB	'++FILE NOT FOUND',CR,LF,0
	POP	H
	JMP	PROMPT
;
FLOK	DCR	A
	STA	DIRPOS	;SAVE POS. IN DIR
	ANI	3
	MOV	L,A
	MVI	H,0
	DAD	H	;X32 BYTES/ENTRY
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	LXI	D,BASE+80H
	DAD	D	;HL POINTS TO ENTRY
	LXI	D,32
	XCHG
	DAD	D
	XCHG
	MVI	A,'D'
	STA	DUMTYPE
	JMP	DUMPLP	;WHICH POPS H
;
MVNAME	MOV	A,M
	CPI	'.'
	JZ	MVIPAD
	CPI	CR
	JZ	PAD
	CPI	';'
	JZ	PAD
	CALL	UPCASE
	STAX	D
	INX	H
	INX	D
	DCR	B
	JNZ	MVNAME
	MOV	A,M
	CPI	CR
	RZ
	CPI	';'
	RZ
	INX	H
	CPI	'.'
	RZ
	JMP	WHAT
;
MVIPAD	INX	H
;
PAD	MVI	A,' '
	STAX	D
	INX	D
	DCR	B
	JNZ	PAD
	RET
;
PLUS	LXI	D,1	;DFLT TO 1 SECT
	MOV	A,M	;GET NEXT CHAR
	CPI	CR	;CR?
	JZ	PLUSGO	;..YES, DFLT TO 1
	CPI	';'
	JZ	PLUSGO
	CALL	DECIN	;GET #
	MOV	A,E
	ORA	A
	JZ	WHAT
PLUSGO	CALL	NEXTSEC
	DCR	E	;MORE TO GO?
	JNZ	PLUSGO	;..YES
;
;OK, INCREMENTED TO SECTOR.  SETUP AND READ
;
PLUSMI	LDA	CURSEC
	CALL	SETSEC	
	LDA	CURTRK
	CALL	SETTRK
	CALL	READ
	JMP	CALCGRP
;
MINUS	LXI	D,1	;SET DFLT
	MOV	A,M	;GET CHAR
	CPI	CR	;CR?
	JZ	MINGO	;..YES, DFLT=1
	CPI	';'
	JZ	MINGO
	CALL	DECIN	;..NO, GET ##
	MOV	A,E
	ORA	A
	JZ	WHAT
MINGO	LDA	CURSEC	;GET CURR
	DCR	A	;BACK UP
	JNZ	MINOK	;TO 0?
	LDA	CURTRK	;..YES, BACK..
	DCR	A	;..UP 1..
	STA	CURTRK	;..TRACK
	MVI	A,TRKSIZE
MINOK	STA	CURSEC
	DCR	E
	JNZ	MINGO
	JMP	PLUSMI
;
;GO TO NEXT SECTOR
;
NEXTSEC	LDA	CURSEC	;GET CURRENT
	INR	A	;BUMP IT
	CPI	TRKSIZE+1	;NEXT TRACK?
	JNZ	NEXTOK	;NO, CONI
	LDA	CURTRK	;BUMP..
	INR	A	;..CURR..
	STA	CURTRK	;..TRK
	MVI	A,1	;SECT=1
NEXTOK	STA	CURSEC
	RET
;
;TELL WHAT GRP, DISPLACEMENT, TRK, SECT, PHY SECT
;
INQ	CALL	INQSUB
	JMP	PROMPT
;
;POSITION INQUIRY SUBROUTINE
;	EXECUTED VIA: G S OR T (WITH NO OPERANDS)
;
INQSUB	LDA	CURTRK
	CPI	SYSTRK
	JC	NOGRP
	CALL	ILPRT
	DB	'G=',0
	LDA	GROUP
	CALL	HEX
	MVI	A,':'
	CALL	TYPE
	LDA	GRPDISP
	ORI	'0'
	CALL	TYPE
	MVI	A,','
	CALL	TYPE
NOGRP	CALL	ILPRT
	DB	' T=',0
	LDA	CURTRK
	CALL	DEC
	CALL	ILPRT
	DB	', S=',0
	LDA	CURSEC
	CALL	DEC
	CALL	ILPRT
	DB	', PS=',0
	LDA	PHYSEC
	CALL	DEC
	CALL	CRLF
	RET
;
CHG	MOV	A,M	;GET TYPE (HEX, ASCII)
	CALL	UPCASE
	PUSH	PSW	;SAVE "H" OR "A"
	INX	H
	CALL	DISP	;GET, VALIDATE DISP TO DE
	INX	H
	LXI	B,0	;SHOW NO 'THRU' ADDR
	CPI	'-'	;TEST DELIM FR. DISP
	JNZ	CHGNTH	;NO THRU
	PUSH	D	;SAVE FROM
	CALL	DISP	;GET THRU
	INX	H	;SKIP END DELIM
	MOV	B,D
	MOV	C,E	;BC = THRU
	POP	D	;GET FROM
	JMP	CHGAH
CHGNTH	CPI	','
	JNZ	WHAT
CHGAH	POP	PSW
	CPI	'H'
	JZ	CHGHEX
	CPI	'A'
	JNZ	WHAT
;CHANGE ASCII
CHGALP	MOV	A,M
	CPI	CR
	JZ	PROMPT
	CPI	';'
	JZ	PROMPT
	LDAX	D
	CPI	' '
	JC	CHGAHX
	CPI	7FH
	JNC	CHGAHX
	JMP	CHGA2
CHGAHX	CALL	BHEX
	JMP	CHGA3
CHGA2	CALL	TYPE
CHGA3	SHLD	BACK	;IN CASE "THRU"
	CALL	GETVAL	;ASCII OR <HEX>
	STAX	D	;UPDATE CHAR
	INX	H	;TO NEXT INPUT CHAR
;SEE IF 'THRU' REQUESTED
	MOV	A,C
	ORA	A
	JZ	CHGANTH
	CMP	E	;DONE?..
	JZ	PROMPT	;..YES
	LHLD	BACK
CHGANTH	INR	E
	JNZ	CHGALP
	MOV	A,M
	CPI	CR
	JZ	PROMPT
	CPI	';'
	JZ	PROMPT
	JMP	WHAT
;
;CHANGE HEX
;
CHGHCOM	INX	H
CHGHEX	MOV	A,M
	CPI	CR
	JZ	PROMPT
	CPI	';'
	JZ	PROMPT
	CPI	','	;DELIM?
	JZ	CHGHCOM
	PUSH	D
	SHLD	HEXAD	;IN CASE 'THRU'
	CALL	HEXIN	;POSITIONS TO DELIM
	MOV	A,E	;GET VALUE
	POP	D	;..ADDR
	PUSH	PSW	;SAVE VALUE
	LDAX	D	;GET OLD
	CALL	HEX	;ECHO IN HEX
	POP	PSW	;GET NEW
	STAX	D	;SAVE NEW
;
	MOV	A,C	;SEE IF 'THRU'
	ORA	A
	JZ	CHGHNTH	;..NO.
	CMP	E	;..YES, DONE?
	JZ	PROMPT
	LHLD	HEXAD	;..NO: MORE
CHGHNTH	INR	E
	JNZ	CHGHEX
	MOV	A,M
	CPI	CR
	JZ	PROMPT
	CPI	';'
	JZ	PROMPT
	JMP	WHAT
;
DOREAD	LDA	NOTPOS
	ORA	A
	JNZ	CANTRD
	CALL	READ
	JMP	PROMPT
;
CANTRD	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'++Can''t read - not positioned',CR,LF
	DB	'Position by:',CR,LF
	DB	9,'Track then Sector, or',CR,LF
	DB	9,'Group',CR,LF,0
	JMP	PROMPT
;
DOWRITE	CALL	WRITE
	JMP	PROMPT
;
BHEX	PUSH	PSW
	MVI	A,'<'
	CALL	TYPE
	POP	PSW
	CALL	HEX
	MVI	A,'>'
	CALL	TYPE
	RET
;
HEX	PUSH	PSW
	RAR
	RAR
	RAR
	RAR
	CALL	NIBBL
	POP	PSW
NIBBL	ANI	0FH
	CPI	10
	JC	HEXNU
	ADI	7
HEXNU	ADI	'0'
	JMP	TYPE
;
DEC	MVI	B,'0'-1
DEC10	INR	B
	SUI	10
	JNC	DEC10
	PUSH	PSW
	MOV	A,B
	CALL	TYPE
	POP	PSW
	ADI	'0'+10	;MAKE ASCII, ADD BACK LAST SUBTR.
	JMP	TYPE
;
SPACE	MVI	A,' '
	JMP	TYPE
ASTER	MVI	A,'*'
	JMP	TYPE
;
ILPRT	XTHL
ILPLP	CALL	CTLCS	;ABORT?
	JZ	PROMPTR
	MOV	A,M
	CALL	TYPE
	INX	H
	MOV	A,M
	ORA	A
	JNZ	ILPLP
	INX	H
	XTHL
	RET
;
;DISP CALLS HEXIN, AND VALIDATES A SECTOR
;DISPLACEMENT, THEN CONVERTS IT TO AN ADDRESS
;
DISP	CALL	HEXIN
	PUSH	PSW	;SAVE DELIMITER
	MOV	A,D
	ORA	A
	JNZ	BADISP
	MOV	A,E
	ORA	A
	JM	BADISP
	ADI	80H	;TO POINT TO BUFFER AT 80
	MOV	E,A
	MVI	D,BASE/256
	POP	PSW	;GET DELIM
	RET
;
BADISP	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'++BAD DISPLACEMENT (NOT 0-7F)'
	DB	CR,LF,0
	JMP	PROMPTR
;
HEXIN	LXI	D,0
	MOV	A,M
	CPI	'#'	;DECIMAL?
	JZ	HDIN	;MAKE DECIMAL
HINLP	MOV	A,M
	CALL	UPCASE
	CPI	CR
	RZ
	CPI	';'
	RZ
	CPI	','
	RZ
	CPI	'-'	;'THRU'?
	RZ
	CPI	'>'
	RZ
	INX	H
	CPI	'0'
	JC	WHAT
	CPI	'9'+1
	JC	HINNUM
	CPI	'A'
	JC	WHAT
	CPI	'F'+1
	JNC	WHAT
	SUI	7
HINNUM	SUI	'0'
	XCHG
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	ADD	L
	MOV	L,A
	XCHG
	JMP	HINLP
;
HDIN	INX	H	;SKIP '.'
DECIN	LXI	D,0
DINLP	MOV	A,M
	CALL	UPCASE
	CPI	CR
	RZ
	CPI	';'
	RZ
	CPI	','
	RZ
	CPI	'-'	;'THRU'?
	RZ
	INX	H
	CPI	'0'
	JC	WHAT
	CPI	'9'+1
	JNC	WHAT
	SUI	'0'
	PUSH	H
	MOV	H,D
	MOV	L,E
	DAD	H	;X2
	DAD	H	;X4
	DAD	D	;X5
	DAD	H	;X10
	ADD	L
	MOV	L,A
	MOV	A,H
	ACI	0
	MOV	H,A
	XCHG
	POP	H
	JMP	DINLP
;
;READ IN A CONSOLE BUFFER FULL
;
RDBUF	CALL	ILPRT
	DB	CR,LF,':',0
	LXI	H,INBUF
	MVI	B,0
RDBLP	CALL	CONIN
	MOV	C,A	;SAVE FOR BS TEST
	CPI	'U'-40H	! JZ	RDCTLU
	CPI	CR	! JZ	RDCR
	CPI	'H'-40H	! JZ	RDBS
	CPI	7FH	! JZ	RDBS
	CPI	'R'-40H	! JZ	RDCTLR
	CPI	' '	! JC	RDBLP
	MOV	M,A
	INX	H
	INR	B
	JM	FULL
	CALL	TYPE
	JMP	RDBLP
;
FULL	DCR	B
	DCX	H
	MVI	A,7	;'DING'
	CALL	TYPE
	JMP	RDBLP
;
;GOT CR
;
RDCR	MOV	M,A	;SAVE IT
	CALL	TYPE	;ECHO IT
	MVI	A,LF	;ECHO..
	CALL	TYPE	;..LF
	LXI	H,INBUF
	RET
;
;GOT DELETE OR BS, ECHO IF BS
;
RDBS	XRA	A	;AT FRONT..
	ORA	B	;..OF LINE?
	JZ	RDCTLU	;..YES, ECHO ^U
	DCX	H
	DCR	B
	MOV	A,C
	CPI	'H'-40H	;BS?
	JZ	BACKUP	;ECHO THE BS
	MOV	A,M	;ECHO..
	CALL	TYPE	;..DELETED CHAR
	JMP	RDBLP
;
BACKUP	MVI	A,'H'-40H
	CALL	TYPE
	JMP	RDBLP
;
;GOT CTL-R, RETYPE
;
RDCTLR	MVI	M,CR
	CALL	CRLF
	LXI	H,INBUF
	MVI	B,0
RDCRL	MOV	A,M
	CPI	CR
	JZ	RDBLP
	CALL	TYPE
	INR	B
	INX	H
	JMP	RDCRL
;
;GOT CTL-U OR BACKUP TO BEG. OF LINE.
;
RDCTLU	MVI	A,'^'
	CALL	TYPE
	MVI	A,'U'
	CALL	TYPE
	JMP	RDBUF
;
CRLF	MVI	A,CR
	CALL	TYPE
	MVI	A,LF
	JMP	TYPE
;
UPCASE	CPI	60H
	RC
	ANI	5FH	;MAKE UPPER CASE
	RET
;
CONST	PUSH	B
	PUSH	D
	PUSH	H
VCONST	CALL	$-$
	POP	H
	POP	D
	POP	B
	RET
;
CONIN	PUSH	B
	PUSH	D
	PUSH	H
VCONIN	CALL	$-$
	POP	H
	POP	D
	POP	B
	RET
;
;CONSOLE OUT WITH TAB EXPANSION
;
TYPE	PUSH	B
	PUSH	D
	PUSH	H
	MOV	C,A	;FOR OUTPUT ROUTINE
	CPI	TAB
	JNZ	TYPEQ
TYPETAB	MVI	A,' '
	CALL	TYPE
	LDA	TABCOL
	ANI	7
	JNZ	TYPETAB
	JMP	TYPERET
;
TYPEQ	LDA	QFLAG
	ORA	A
VCONOUT	CZ	$-$	;ADDR FILLED IN BY 'INIT'
;
;UPDATE COLUMN USED IN TAB EXPANSION
;
	MOV	A,C	;GET CHAR
	CPI	CR
	JNZ	TYPENCR
	MVI	A,0
	STA	TABCOL
	JMP	TYPELST
;
TYPENCR	CPI	LF
	JZ	TYPELST
	CPI	' '	;CTL CHAR?
	JC	TYPERET	;..NO CHANGE IN COL
	LDA	TABCOL
	INR	A
	STA	TABCOL
TYPELST	LDA	PFLAG
	ANI	1
	CNZ	LIST	;FROM C REG.
TYPERET	POP	H
	POP	D
	POP	B
	RET
;
LIST:			;NO PUSH, TYPE SAVED THE REGS.
VLIST	JMP	$-$
;
HOME	PUSH	H
VHOME	CALL	$-$
	POP	H
	RET
;
SETTRK	CPI	MAXTRK
	JC	TRKOK
	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'++not in tracks 0-'
;
	IF	STDCPM
	DB	'76'
	ENDIF
;
	IF	HEATH
	DB	'40'
	ENDIF
;
	DB	'++'
	DB	CR,LF,0
	CALL	NOWRITE
	JMP	PROMPTR
;
TRKOK	STA	CURTRK
	MOV	C,A
	PUSH	H
VSETTRK	CALL	$-$
	POP	H
	RET
;
SETSEC	STA	CURSEC	;LOGICAL
	MOV	C,A
	LDA	CURTRK
	CPI	2
	JC	GSETSEC	;DON'T SCRAMBLE TRK'S 0-1
	PUSH	H
	LXI	H,SECTBL-1
	MOV	A,C
	ADD	L
	MOV	L,A
	MOV	A,H
	ACI	0
	MOV	H,A
	MOV	A,M
	POP	H
	MOV	C,A
GSETSEC	PUSH	H
	MOV	A,C	;GET PHYSICAL SECTOR
	STA	PHYSEC
VSETSEC	CALL	$-$
	POP	H
	RET
;
SETDMA:
VSETDMA	JMP	$-$
;
READ	MVI	A,1
	STA	WRFLG
	PUSH	H
VREAD	CALL	$-$
	ORA	A
	JZ	READOK
	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'++READ failed, sector may be invalid++'
	DB	CR,LF,0
READOK	POP	H
	RET
;
WRITE	LDA	WRFLG
	ORA	A
	JNZ	PWRITE
BADW	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'++CANNOT WRITE UNLESS READ ISSUED'
	DB	CR,LF,0
	JMP	EXPL
PWRITE	PUSH	H
VWRITE	CALL	$-$
	ORA	A
	JZ	WRITEOK
	XRA	A
	STA	QFLAG	;NOT QUIET
	CALL	ILPRT
	DB	'++WRITE failed++',CR,LF,0
WRITEOK	POP	H
	RET
;
;'SCUSE THIS KLUDGE - IT'S TO SET THE SCRAMBLE
;TABLE TO 1,2,3,4,5.. FOR MY 3600 RPM "FLOPPY"..
;
WARDSK	PUSH	H
	LXI	H,SECTBL
	MVI	B,1
	MVI	C,26
WARDLP	MOV	M,B
	INR	B
	DCR	C
	INX	H
	JNZ	WARDLP
	POP	H
	JMP	PROMPT
;
;HELP
;
HELP	CALL	ILPRT
	DB	'Operands in brackets [...] are optional'
 DB CR,LF
	DB	'Numeric values: ''n'' are decimal, ''x'' hex'
 DB CR,LF,CR,LF
	DB	'+[n]	step in [n] sectors;'
 DB CR,LF
	DB	'-[n]	step out [n] sectors'
 DB CR,LF
	DB	'=aaa	search for ASCII aaa from curr sector.'
 DB CR,LF
	DB	'	Caution: upper/lower case matters.'
 DB CR,LF
	DB	'	Use <xx> for hex:'
 DB CR,LF
	DB	'	To find "IN 0" use: =<db><0>	 or'
 DB CR,LF
	DB	'	"(tab)H,0(CR)(LF)" use: =<9>H,0<D><A>'
 DB CR,LF
	DB	'<	save current sector into mem. buff.'
 DB CR,LF
	DB	'>	restore saved sector'
 DB CR,LF
	DB	'?	give help'
 DB CR,LF
	DB	'A[ff,tt] ASCII dump'
 DB CR,LF
	DB	'C	Change:'
 DB CR,LF
	DB	'	CHaddr,byte,byte... (hex)'
 DB CR,LF
	DB	'  or	CAaddr,data...  (Ascii)'
 DB CR,LF
	DB	'	<xx> Allowed for imbedded hex.'
 DB CR,LF
	DB	'  or	CHfrom-thru,byte  e.g. ch0-7f,e5'
 DB CR,LF
	DB	'  or	CAfrom-thru,byte'
 DB CR,LF
	DB	'D[ff,tt] Dump (hex+ASCII)'
 DB CR,LF
	DB	'Fn.t	Find file'
 DB CR,LF
	DB	'Gxx	CP/M Allocation Group xx'
 DB CR,LF
	DB	'H[ff,tt]	hex dump'
 DB CR,LF
	DB	'L	Log in drive'
 DB CR,LF
	DB	'Lx	Log in drive x'
 DB CR,LF
	DB	'M[xx]	Map [from group xx]'
 DB CR,LF
	DB	'P	Toggle printer switch'
 DB CR,LF
	DB	'Q	Quiet mode (no msgs)'
 DB CR,LF
	DB	'R	Read current sector'
 DB CR,LF
	DB	'Snn	Sector nn'
 DB CR,LF
	DB	'Tnn	Track nn'
 DB CR,LF
	DB	'V[nn]	View [nn] ASCII sectors'
 DB CR,LF
	DB	'W	Write current sector'
 DB CR,LF
	DB	'X	Exit program'
 DB CR,LF
	DB	'Z[nn]	Sleep [nn tenths]'
 DB CR,LF
	DB	'/[nn]	Repeat [nn (decimal) times]'
 DB CR,LF,CR,LF
	DB	'Cancel a function with C or Ctl-C.'
 DB CR,LF
	DB	'Suspend output with S or Ctl-S.'
 DB CR,LF
	DB	'Separate commands with ";".'
 DB CR,LF
	DB	'	Example: g0'
 DB CR,LF
	DB	'	+;d;z#20;/'
 DB CR,LF
	DB	'	would step in, dump, sleep 2 sec, '
 DB CR,LF
	DB	'	and repeat until control-c typed.'
 DB CR,LF
	DB	'To use "Q", preceed a command with it.'
 DB CR,LF
	DB	'Quiet mode is set off upon console input.'
 DB CR,LF,CR,LF
	DB	'See DU.DOC for complete examples.'
 DB CR,LF,0
	JMP	PROMPT
;
;DISK SECTOR ORDER - standard CP/M
;
	IF	STDCPM
SECTBL	DB	1,7,13,19,25,5,11,17,23,3,09,15,21
	DB	2,8,14,20,26,6,12,18,24,4,10,16,22
	ENDIF
	IF	HEATH
SECTBL	DB	 1, 2, 9,10,17,18, 5, 6,13,14
	DB	 3, 4,11,12,19,20, 7, 8,15,16
	ENDIF
;
BUFAD	DW	BASE+100H ;FORCES INITIAL READ
HEXAD	DW	0	;TO RE-FETCH A VALUE
TOGO	DB	0FFH	;REPEAT COUNT (FF=CONT)
TWOUP	DB	0
PFLAG	DB	0	;1=PRINT
GROUP	DB	0
GRPDISP	DB	0
SAVEFLG	DB	0
CURTRK	DB	0
CURSEC	DB	1
PHYSEC	DB	1
TABCOL	DB	0
FILECT	DB	0
DIRPOS	DB	0
FINDFLG	DB	0	;1=MUST POSITION AFTER FIND
FTSW	DB	1	;SEARCH W/O INCREMENT
NOTPOS	DB	1	;NOT POSITIONED YET (CAN'T READ)
WRFLG	DB	0	;MAY NOT WRITE UNTIL '+', '-',
;			 OR 'G' COMMAND
QFLAG	DB	0	;QUIET? (0=NO)
	DS	100	;STACK SPACE
STACK:
BACK	DS	2	;TO BACK UP IN "CA0-7F,X"
DUMTYPE	DS	1
SAVEBUF	DS	128
INBUF	DS	128
;
;DIRECTORY READ IN HERE; ALSO SEARCH WORKAREA
;
WORK:
DIRECT	DS	32*64
;
FCB	EQU	BASE+5CH
BDOS	EQU	BASE+5
RESETDK	EQU	13
SELDK	EQU	14
SRCHF	EQU	17	;SEARCH FIRST
