**=====================================================**
*                                                       *
*         "DUTIL" DISK UTILITY				*
*	   Version 2.22  25 October 1983		*
*	   BB-II 5"/8" SD/DD:512 DMA version		*
*	   EPROM/RAM Version				*
*                                                       *
**=====================================================**

TRUE	equ	0FFFFH
FALSE	equ	0
EPROM	equ	false		;EPROM or CPM version

	IF	EPROM
ROM	equ	01000H
RUN	equ	0D600H
BUF	equ	00100H
	org	RUN
	cpi	'/'		;make this position
	rnz			; independent 
	lxi	h,ROM
	lxi	d,RUN
	lxi	b,01000H
	db	0EDH,0B0H
	ENDIF

	IF	NOT EPROM
	org	0100H
BUF	equ	01200H
	ENDIF

	jmp	START

;*------------------------------------------------------*
;*      DISK TYPE CONFIGURATION				*
;*------------------------------------------------------*


FIVE	equ	true		;0=8" 0FFFFH=5"
NSTART	equ	5		;revs til ready

	IF	FIVE
SPEED	equ	12		;Step speed
FSPEED 	equ	1		;FDÃ 0=6ms,1=12ms,2=20ms,3=30ms
NTRKS	equ	80		;Number of tracks both sides
DOUBLE	equ	0		;double sided:0=false,1=true
WHACK	equ	10		;copy tracks
SPTSD	equ	18		;sectors/track single
SPTDD	equ	10		;sectors/track double
DTYPSD	equ	2		;DSKTYP 5" SD
DTYPDD	equ	3		;          DD

SGAP0:	equ	0		;gap0: pre-index
SGAP1:	equ	32		;gap1: post-index
SGAP2:	equ	11		;gap2: id 
SGAP3:	equ	6		;gap3: post-data
DGAP0:	equ	0		;gap0: pre-index
DGAP1:	equ	32		;gap1: post-index
DGAP2:	equ	24		;gap2: id
DGAP3:	equ	22		;gap3: post-data

ILDD:	db	1,6,2,7,3,8,4,9,5,10  
ILSD:	db	1,10,2,11,3,12,4,13,5,14,6,15,7,16,8,17,9,18
	ENDIF

	IF	NOT FIVE
SPEED	equ	8		;ROM step speed 
FSPEED	equ	2		;FDÃ 0=3ms,1=6ms,2=10ms,3=15ms
DOUBLE	equ	0		;double sided 0=false 1=true
NTRKS	equ	40*(DOUBLE+1)	;Number of tracks both sides
WHACK	equ	6		;copy tracks
SPTSD	equ	26		;sectors/track single
SPTDD	equ	16		;sectors/track double
DTYPSD	equ	0		;DSKTYP 8" SD
DTYPDD	equ	1		;	   DD

SGAP0:	equ	40		;gap0: pre-index
SGAP1:	equ	26		;gap1: post-index
SGAP2:	equ	11		;gap2: id 
SGAP3:	equ	27		;gap3: post-data
DGAP0:	equ	0		;gap0: pre-index
DGAP1:	equ	50		;gap1: post-index
DGAP2:	equ	22		;gap2: id
DGAP3:	equ	54		;gap3: post-data

ILDD:	db	1,9,2,10,3,11,4,12,5,13,6,14,7,15,8,16  
ILSD:	db	1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18
	db	19,20,21,22,23,24,25,26
	ENDIF

SBYTES	equ	128		;bytes/sector single
SDSTYP	equ	0		;sector type 128 bytes
DBYTES	equ	512		;bytes/sector  double
DDSTYP	equ	2		;	     512 bytes

;*------------------------------------------------------*
;*	INITIALIZATION AND MAIN PROGRAM LOOP		*
;*------------------------------------------------------*

START:	mvi	a,008H		;enable
	sta	0FF70H		; RAM and
	out	0C8h		;  DSCOPY
	mvi	a,SPEED		;Set
	sta	0FF90H		; step speed
	mvi	a,NSTART	;Set
	sta	0FF95H		; NREVS

	lxi	sp,STACK	;init stack pointer
	xra	a
	sta	UNIT
	sta	TRK
	cma
	sta	SELUNIT		; for new unit and new track
	sta	DDFLG		;init for double
	lxi	h,HLMSG		;print
	call	PTXT		; help menu

; Main program loop

DUTIL:	lxi	sp,STACK	;re init sp
	mvi	a,2		;set track to track
	sta	SKEWF		; skew factor
	xra	a
	sta	PASCNT
	mvi	a,0FFH
	sta	OLDTRK
	call	HOME		;home drive each time
	call	CRLF		;newline
DUTI1:  mvi	c,'A'		;print prompt
	lda	UNIT
	cpi	0
	jz	DUTI2
	mvi	c,'B'
DUTI2:	call	CONOUT
	mvi	c,':'		; and density
	lda	DDFLG		; ':' for DD
	ora	a		; '.' for SD
	jnz	DUTI3
	mvi	c,'.'
DUTI3:	call	CONOUT
	mvi	c,'>'
	call	CONOUT
	call	GCHAR		;get command letter
	cpi	0DH		; do nothing if <cr>
	jz	DUTI1
	call	DUTIL0		;go decode
	jmp	DUTIL		; and loop

; Input or Command error

INERR:	lxi	H,INEMSG
	call	PTXT
	jmp	DUTIL

INEMSG	db	7,' ?? ',0DH,0AH,3

; Decode command and jump to routine

DUTIL0:	cpi	'Q'		;'Q' Sequential commands
	jnz	DECOD3		; no, skip
	lxi	h,SQMSG		; yes, print
	call	PTXT		; 'Sequential'
	call	GCHAR
	cpi	'W'		;'SW'?
	jnz	DECOD1		; no, skip
	lxi	H,WRMSG		; yes, complete
	call	ACCEPT		;  command
	jmp	DQW		;  and jump to routine
DECOD1	cpi	'R'		;random?
	jnz	INERR		; no, skip
	lxi	H,RDMSG		; yes, accept
	call	ACCEPT
	jmp	DQR
DECOD3	cpi	'R'		;'RR' read read ?
	jnz	DECOD5		; no, skip
	lxi	H,RAMSG		; yes, complete command
	call	PTXT
	call	GCHAR		;get next
	cpi	'W'		; write?
	jnz	DECOD4		; no, skip
	lxi	H,WRMSG		; yes, complete command
	call	ACCEPT
	jmp	DRW
DECOD4	cpi	'R'		;read?
	jnz	INERR		; no, error
	lxi	H,RDMSG		; yes, complete
	call	ACCEPT
	jmp	DRR

SQMSG	db	8,'Sequential ',3
RAMSG	db	'andom ',3
RDMSG	db	'ead',3
WRMSG	db	'rite/Readback',3

DECOD5:	cpi	'A'
	jz	SUNITA
	cpi	'B'
	jz	SUNITB
	cpi	'C'
	jz	COPY		;COPY DISK
	cpi	'V'
	jz	VCOPY		;Verify copy
	cpi	'D'
	jz	DUMP		;DUMP SECTOR
	cpi	'Z'
	jz	TSTSK		;SEEK
	cpi	'F'
	jz	FORMAT		;FORMAT TRACK
	cpi	'T'
	jz	RTRK		;FORMAT READ
	cpi	'L'
	jz	LOAD		;LOAD (READ) FROM DISK
	cpi	'S'
	jz	SAVE		;SAVE (WRITE) TO DISK
	cpi	'P'
	jz	PATCH		;PATCH SECTOR
	cpi	'?'
	jz	HELP		;HELP LIST
	cpi	'M'
	jz	MODE		;change density
	cpi	'X'
	jz	EXIT		;exit to system
	jmp	INERR

;*------------------------------------------------------*
;*			COMMANDS			*
;*------------------------------------------------------*

*******************
* COPY A DISKETTE *
*******************

VCOPY:	mvi	a,0FFH		;set verify
	sta	VFLAG		; flag
	lxi	H,VCOPMSG	;command completion
	jmp	COPY0		

COPY:	xra	a		;clear
	sta	VFLAG		; flag
	lxi	H,COPMSG	;command
COPY0:	call	ACCEPT		; completion
	xra	a		;set
	sta	TRK		; TRK = 0
	mvi	a,4
	sta	SKEWF
	call	FDRAW

	lxi	H,SPTSD+SPTDD*(NTRKS-1)	
	lda	DDFLG
	ora	a
	jnz	COPY00
	lxi	H,NTRKS*SPTSD
COPY00:	shld	SECREM		;sectors to be copied

	lxi	H,SPTSD		;just 1 SD track
	shld	SECINC		; first time
	jmp	COPY2		;  through
COPY1:	lda	TRK		; and then
	cpi	1		;  for DD
	jnz	COPY2
	lxi	H,SPTDD*WHACK	; tracks per read/write
	lda	DDFLG
	ora	a
	jnz	COPY10
	lxi	H,SPTSD*WHACK
COPY10:	shld	SECINC

COPY2:	lhld	SECREM		;test for number of sectors
	mov	A,H		; remaining equal to zero
	ora	L		; or h=l=0
	jz	COPYR		; done
	xchg			;put in de
	lhld	SECINC		; load sectors remaining in hl
	xchg			;now calculate
	mov	A,L		;SECREM=SECREM-SECINC
	sub	E		; do 16bit
	mov	L,A		; subtraction
	mov	A,H
	sbb	D
	mov	H,A
	jnc	COPY3		;if result .GE. 0, update SECREM
	lhld	SECREM		; else this will be last time and
	shld	SECINC		;  SECINC = SECREM
	lxi	H,0		;set SECREM = 0 no more left
COPY3:	shld	SECREM

; Read from Drive A:

	xra	A		;set unit
	sta	UNIT
	lda	TRK		;set track
	sta	CTRK
	call	CSETUP		;setup
COPY4:	call	DDOTS		;print dots
	call	READP		;read physical sector
	jnz	ERROR
	call	ISKEWA		;increment skew address
	call	DCREC		;decrement record count
	jnz	COPY4

; Write to Drive B:

	mvi	a,1		;set unit
	sta	UNIT
	lda	CTRK		;set track
	sta	TRK
	call	CSETUP
COPY5:	call	WRITP		;write physical
	jnz	ERROR
	call	ISKEWA		;increment skew address
	call	DCREC		;decrement record count
	jnz	COPY5

; Verify tracks

	lda	VFLAG
	ora	A
	jz	COPY1
	lda	CTRK		;SET
	sta	TRK		; TRACK
	call	CSETUP
COPY6:	call	READP		;READ JUST WRITTEN
	jnz	ERROR		; ERROR?
	call	ISKEWA
	call	DCREC
	jnz	COPY6
	jmp	COPY1		;NO, CONTINUE

COPYR:	xra	A
	sta	UNIT
	ret

; Setup for Copy: set sector, skew, dma addr and # records

CSETUP:	mvi	a,1		;each operation
	sta	SCTR		; starts with sector 1
	sta	SKEW
	lxi	H,BFFR1		;set buffer
	shld	TADDR		; address
	lhld	SECINC		;set number of sectors
	shld	CREC		; (records) in CREC
	ret

; Increment skewed disk address

ISKEWA:	lda	NSCTP1		;get SPT plus 1
	mov	B,A		; into B
	lda	SCTR		;get sector
	inr	A		; incrment
	cmp	B		; and test with B	
	jnz	ISKEW0		;skip if not end of track
	mvi	A,1		; else, new track
ISKEW0	sta	SCTR
	lxi	H,SKEW		;test for end of
	cmp	M		; skewed track
	stc			;set carry if not end
	rnz			; exit
	lda	SKEW		;else calculate new
	lxi	H,SKEWF		; skewed end by adding in
	add	M		;  track skew factor	
	cmp	B		;modulo NSP
	jc	ISKEW2		;skip if not over
	dcr	B		;subtrac off
	sub	B		; NSP
ISKEW2:	sta	SKEW		;update
	sta	SCTR		; for new track
	lxi	H,TRK		;incrment for
	inr	M		; next track
	mvi	A,NTRKS		;test for end
	cmp	M		; of disk
	stc			; and set carry if not
	rnz
	cmc			;clear carry to indicate
	ret			; last track

; Decrement sector (record) count

DCREC:	lhld	TADDR		;increment
	xchg			; dma
	lhld	NBYTES		;  address
	dad	D
	shld	TADDR
	lhld	CREC		;decrement
	dcx	H		; record count
	shld	CREC
	mov	A,H
	ora	L
	ret

COPMSG	db	'opy entire disk from A: to B:',3
VCOPMSG	db	008H,'Copy and verify entire disk from A: to B:',3

*****************
* DUMP A SECTOR *
*****************

DUMP:	lxi	H,DUMSG		;COMPLETE CMD
	call	ACCEPT		; AND ACCEPT
	lxi	H,BFFR1		;SET BUFFER #1
	shld	TADDR		; FOR TaddDR
	lxi	H,TSMSG		;GET TRACK/SECTOR
	call	PTXT		; PROMPT
	call	IHEXN		;GET VALUES
	mov	a,h
	sta	TRK
	mov	a,l
	sta	SCTR
DUMP0:	call	READ		;READ THE SECTOR
	jnz	ERROR		; ERROR?
*
DUMP1	lhld	TADDR		;SET HL
	call	DBFFR		;DUMP BFFR
	lxi	h,DNMSG		;NEXT?
	call	PTXT		; PROMPT
	call	CONIN		; GET RESPONSE
	cpi	' '		; IF SPACE
	jz	DUMP2		; YES, ELSE NO
	call	CRLF
	ret
DUMP2:	lxi	h,DTMSG		;PRINT THIS
	call	PTXT
	lda	NSCTP1
	mov	b,a
	lda	SCTR		;INCR DISK addR
	inr	a		; SECTOR
	sta	SCTR		; AND
	cmp	b		; TEST END OF TRACK
	jnz	DUMP5
	mvi	A,1		;YES, RESET
	sta	SCTR		; UPDATE
	lda	TRK		; AND INCR
	cpi	NTRKS-1		; TRACK, END?
	jz	INERR		; YES, ERROR
	inr	A		; NO, INCR
	sta	TRK		; UPDATE
DUMP5	lda	TRK		;GET TRACK
	call	PACC		; PRINT
	lda	SCTR		;GET SECTOR
	call	PACC		; AND PRINT
	call	CRLF		;SPACE A LINE
	jmp	DUMP0		; AND CONTINUE

; Dump Buffer

DBFFR:	push	h
	xra	a
	sta	DLCNTR
	lxi	h,0
	shld	DCNTR
; Print Address for each line printed
DBFFR0:	lhld	DCNTR		;this is the
	mov	a,h		; relative address
	push	h
	call	PACC
	pop	h
	mov	a,l
	call	PACC
	mvi	c,':'
	call	CONOUT
	call	SPACES
; Print hex values first
DBFFR1:	pop	h		;GET POINTER
	mov	a,m		; INTO BUFFER
	inx	h		;INCR
	push	h		; AND SAVE
	call	PACC		;PRINT ONE VALUE
	mvi	c,' '		; AND ONE
	call	CONOUT		; SPACE
	lhld	DCNTR
	inx	h
	shld	DCNTR
	mov	a,l
	ani	00FH		;TEST FOR EOL?
	jnz	DBFFR1		; NO, CONTINUE
; Print ASCII values next
	call	SPACES		;SPACE OVER A LITTLE
	lxi	D,-16		;BACK UP BUFFER
	pop	H		;POINTER
	DAD	D		; TO BEGIN OF LINE
	push	H		; AND SAVE
	lhld	DCNTR
	lxi	d,-16
	dad	d
	shld	DCNTR
DBFFR2	pop	H		;GET POINTER
	mov	A,M		; AND THE CHAR
	inx	H		;INC POINTER
	push	H		; AND SAVE
	ani	07FH		;MASK TO PRINT
	mov	C,A		; SAVE IN C
	cpi	07FH		;TEST PRINTABLE
	jz	DBFFR3		; NO, USE '.'
	cpi	' '		;TEST PRINTABLE
	jnc	DBFFR4		; YES, SKIP
DBFFR3	mvi	C,'.'		; NO, USE '.'
DBFFR4	call	CONOUT		;PRINT CHAR
	lhld	DCNTR
	inx	h
	shld	DCNTR
	mov	a,l
	ani	00FH		;TEST FOR
	jnz	DBFFR2		; EOL, NO CONTINUE
; Pause after half sector
	call	CRLF
	call	BREAK
	lxi	H,DLCNTR
	inr	M
	mvi	A,21
	cmp	M
	jnz	DBFFR5
	mvi	M,0
	call	CONIN
	cpi	' '
	jnz	DUTIL
; test for end
DBFFR5:	lhld	DCNTR
	xchg
	lhld	NBYTES
	mov	a,h
	cmp	d
	jnz	DBFFR0		;CONTINUE
	mov	a,l
	cmp	e
	jnz	DBFFR0

DBFFR6:	call	CRLF		; ELSE
	pop	H		;STRIP OFF
	ret			; AND EXIT

DTMSG	db	' Track/Sector: ',3
DNMSG	db	'   Next?',3
DUMSG	db	'ump Sector',3

************************************
* SEQUENTIAL AND RANDOM READ/WRITE *
************************************

; Sequential read

DQR	call	FDRAW
DQR0:	call	ZADDR		;SET TTSS=0001
DQR1	call	DDOTS		;dots and console break
	call	DREAD
	call	ISKEWA		;increment disk address
	jc	DQR1		; and loop
	call	DPMSG		;print pass message
	jmp	DQR0

; Sequential write/readback

DQW:	call	FDRAW
	mvi	a,4
	sta	SKEWF
DQW0:	call	ZADDR
	call	RDATA
DQW1:	call	DDOTS
	lhld	DQCNT
	shld	BFFR1
	inx	h
	shld	DQCNT
	shld	BFFR1
	call	DWRITE		;write to disk
	call	ISKEWA
	jc	DQW1

	call	CRLF
	call	ZADDR
DQW2:	call	DDOTS
	call	DREAD		;read into other
	lhld	DQCNT
	inx	h
	shld	DQCNT
	xchg
	lhld	BFFR2
	mov	a,h
	cmp	d
	jnz	DQW3
	mov	a,l
	cmp	e
	jz	DQW4
DQW3:	call	ERROR
DQW4:	call	ISKEWA		;increment address
	jc	DQW2
	call	DPMSG
	jmp	DQW0

; Random Read

DRR:	call	RADDR		;random address
	call	DREAD		;READ
	call	BREAK
	jmp	DRR

; Randon Write/readback

DRW:	call	RADDR		;get random address
	call	RDATA		;RANDOM DATA
	call	DWRITE		;WRITE
	call	DREAD		;READBACK
	jnz	DRW0
	call	COMPR		;COMPARE
DRW0:	call	BREAK
	jmp	DRW

; Zero disk address

ZADDR:	lxi	h,0
	shld	DQCNT
	xra	a		;start at 0,1,1
	sta	TRK
	mvi	A,1
	sta	SCTR
	sta	SKEW
	ret

; Read from disk into buffer2

DREAD:	lxi	H,BFFR2
	shld	TADDR
	call	READP
	push	psw
	cnz	ERROR
	pop	psw
	ret

; Write to disk from buffer1

DWRITE:	lxi	H,BFFR1
	shld	TADDR
	call	WRITP
	push	psw
	cnz	ERROR
	pop	psw
	ret

; Print '+++' for each new track

DDOTS:	call	BREAK
	lda	TRK
	lxi	h,OLDTRK
	cmp	m
	rz
	mov	M,A
	IF	DOUBLE
	lda	TRK
	cpi	NTRKS/2
	cz	CRLF
	ENDIF
	mvi	c,'+'
	call	CONOUT
	ret

; Print ' Pass ' message

DPMSG:	lxi	h,PSMSG
	call	PTXT
	lda	PASCNT
	inr	a
	sta	PASCNT
	call	PACC
	mvi	c,' '
	call	CONOUT
	call	CRLF
	ret

PSMSG:	db	0DH,'++ Pass ',3

; Compare buffers

COMPR:	lhld	NBYTES
	mov	B,H
	mov	C,L
	lxi	H,BFFR1		;HL=PTR1
	lxi	D,BFFR2		;DE=PTR2
CMPR1:	ldax	D		;FETCH
	cmp	M		;COMPARE
	jz	CMPR2		;ERROR IF MISMATCH
	mvi	A,0FFH		;SPECIAL CODE
	call	ERROR
CMPR2:	inx	H		;INCR
	inx	D		; PTRS
	dcx	B		;dcr COUNTER
	mov	A,B
	ora	C
	jnz	CMPR1
	ret

; Fill buffers with random data pattern

RDATA:	lxi	B,DBYTES
	lxi	D,BFFR1
RDATA0:	mov	A,C
	stax	D
	inx	D
	dcx	B
	mov	A,B
	ora	C
	jnz	RDATA0
	ret

; Generate random disk address

RADDR:	mvi	A,NTRKS		;max track number
	mov	B,A
	db	0EDH,05FH	;LDAR
	ani	07FH		;0-127
	sta	TRK
	cmp	B
	jnc	RADDR		;try again if too big

RADDR1:	lda	TRK		;compare random
	mvi	b,SPTSD+1	; sector to approriate
	cpi	0		; NSPT for SD or DD
	jz	RADDR2
	lda	DDFLG
	ora	a
	jz	RADDR2
	mvi	b,SPTDD+1
RADDR2:	db	0EDH,05FH	;LDAR
	ani	01FH		;0-31
	ora	A
	jz	RADDR
	sta	SCTR
	cmp	B
	jnc	RADDR2		;if sector too big
	ret
	db	0EDH,05FH	;LDAR

*************
* TEST SEEK *
*************

TSTSK:	lxi	h,SKMSG		;Command
	call	ACCEPT		; completion

TSTSK0:	call	HOME		;Home first
	jnz	ERROR
	IF	NOT DOUBLE
	mvi	a,NTRKS-1
	ENDIF
	IF	DOUBLE
	mvi	a,NTRKS/2-1
	ENDIF
	sta	TRK		; last track side 0
	call	SEEKN
	jnz	ERROR
	call	BREAK
	jmp	TSTSK0

SKMSG	DB	08H,'Test Seek',3

**************************
* LOAD/SAVE TO/FROM DISK *
**************************

LOAD:	lxi	H,LDMSG
	call	ACCEPT
	lxi	H,L1MSG
	call	SPARMS
LOADER:	call	READ
	jnz	ERROR
	call	INCP
	jnz	LOADER
	ret

SAVE:	lxi	H,SVMSG
	call	ACCEPT
	lxi	H,L1MSG
	call	SPARMS
SAVER:	call	WRITE
	jnz	ERROR
	call	INCP
	jnz	SAVER
	ret

LDMSG	db	'oad (read) from disk',3
L1MSG	db	' memory address (MMMM):',3
SVMSG	DB	'ave (write) to disk',3

; Scan for input parameters

SPARMS:	call	PTXT		;print load or save msg
	call	IHEXN		;get transfer address
	shld	TADDR
	lxi	H,TSMSG		;Request track
	call	PTXT		; and sector
	call	IHEXN
	mov	A,H
	sta	TRK
	mov	A,L
	sta	SCTR
	lxi	H,SZMSG		;Request number
	call	PTXT		; of sectors
	call	IHEXN		; and
	mov	A,L		; store
	sta	NREC		; in 'NREC'
	ret

TSMSG	DB	' Enter track/sector (TTSS): ',03
SZMSG	DB	' Enter number of sectors (NN):',03

; Increment Sector and Track for sequential load/save

INCP:	lhld	TADDR		;increment DMA address
	xchg
	lhld	NBYTES
	dad	d
	shld	TADDR
	lxi	H,NREC		;decrement record count
	dcr	M
	RZ
	lxi	H,SCTR		;increment sectotr
	inr	M		; and wrap around to
	lda	NSCTP1		; next track
	cmp	M
	rnz
	mvi	M,1
	lxi	H,TRK
	inr	M
	ret

****************
* PATCH SECTOR *
****************

PATCH:	lxi	H,PTMSG
	call	ACCEPT
	lxi	H,TSMSG		;Prompt for track/sector
	call	PTXT
	call	IHEXN
	mov	a,h
	sta	TRK
	mov	a,l
	sta	SCTR
	lxi	H,BFFR2
	shld	TADDR
	call	READ		;read into BFFR2

PATCH1:	call	CRLF
	call	CRLF		;print sector
	lxi	H,BFFR2
	call	DBFFR

PATCH2:	lxi	H,PAMSG		;address
	call	PTXT
	call	SCAN
	jz	PATC22
PATC21:	mvi	c,7
	call	conout
	jmp	PATCH2		;error try again
PATC22:	mov	A,B		;test for only cr
	cpi	1
	jz	PATCH4
	push	h
	xchg
	lhld	NBYTES
	xchg
	ora	a
	db	0EDH,052H	;SBC hl,de	
	pop	h
	jnc	PATC21		;must be less than or equal
	shld	TADDR		; to NBYTES
; Print address, datum and prompt for input
PATCH3:	lhld	TADDR		;get displacement
	push	h		;print address
	mov	a,h
	call	PACC
	pop	h
	push	h
	mov	a,l
	call	PACC
	mvi	C,' '
	call	CONOUT
	pop	h	
	lxi	D,BFFR2
	dad	D
	mov	A,M
	call	PACC		;print datum
	mvi	C,' '
	call	CONOUT
PATC31: call	SCAN		;prompt for input
	jnz	PATCH1
	mov	A,B		;Test for
	cpi	1		; single character <CR>
	jz	PATC35
	mov	A,L
	lhld	TADDR
	lxi	D,BFFR2
	dad	D
	mov	M,A
PATC35	lhld	TADDR
	inx	h
	shld	TADDR
	jmp	PATCH3
; Prompt for write out
PATCH4:	lxi	H,PWMSG		;query for write out
	call	PTXT
	call	GCHAR		;get response
	cpi	'Y'
	jz	PATCH5		;yes, skip go write
	cpi	'N'		;no, done
	jz	PATCH6
	jmp	PATCH1		;continue command 
PATCH5:	lxi	H,BFFR2		;set address
	shld	TADDR		; and write out
	call	WRITE
	jnz	ERROR
PATCH6:	call	CRLF
	ret

PTMSG	db	'atch Sector',3
PAMSG	db	0DH,'Address:     ',8,8,8,8,3
PWMSG	db	0AH,0DH,' Write out? (Y/N/Continue)',3

****************
* HELP COMMAND *
****************

HELP:	lxi	H,HLMSG
	call	PTXT
	ret

HLMSG:	db  	01AH,0AH,'DISK UTILITY (SD/DD-512) VER 2.22R',0AH
	db	0AH,0DH,'     QR    Sequential Read'
     	db	0AH,0DH,'     QW    Sequential Write'
	db	0AH,0DH,'     RR    Random Read'
	db	0AH,0DH,'     RW    Random Write'
	db	0AH,0DH,'     F     Format Disk'
	db	0AH,0DH,'     T     Format Track Read'
	db	0AH,0DH,'     A     Select drive A:'
	db	0AH,0DH,'     B     Select drive B:'
	db	0AH,0DH,'     C     Copy Disk'
	db	0AH,0DH,'     V     Verify copy disk'
	db	0AH,0DH,'     D     Dump Sector'
	db	0AH,0DH,'     L     Load from disk'
	db	0AH,0DH,'     S     Save to disk'
	db	0AH,0DH,'     P     Patch Sector'
	db	0AH,0DH,'     M     Change Density mode'
	db	0AH,0DH,'     X     Exit program'
	db	0AH,0DH,'     ?     Help',0AH,0DH,3

************
* SET UNIT *
************

SUNITA:	lxi	H,SUNMSG
	call	ACCEPT
	mvi	a,0
	sta 	UNIT
	ret

SUNITB:	lxi	H,SUNMSG
	call	ACCEPT
	mvi	A,1
	sta	UNIT
	ret

SUNMSG	db	':',3

****************
* MODE DENSITY *
****************

MODE:	lxi	H,MODMSG
	call	ACCEPT
	lda	DDFLG
	xri	0FFH
	sta	DDFLG
	ret

MODMSG	db	8,'Change Mode',3

***************
* EXIT SYSTEM *
***************

EXIT:	lxi	H,EXIMSG
	call	ACCEPT
	call	CRLF

	IF	EPROM
	jmp	0F003H
EXIMSG	db	8,'Exiting to Monitor ...',3
	ENDIF

	IF	NOT EPROM
EXIMSG	db	8,'Exiting to CPM ...',3
	jmp	0
	ENDIF

;*------------------------------------------------------*
;*		UTILITY ROUTINES			*
;*------------------------------------------------------*

; Error print routine

ERROR:	push	PSW		;save status
	lxi	H,ERMSG		;print
	call	PTXT		;"DISK ERROR"
	pop	PSW		;recover status
	call	PACC		;print
	call	SPACES
	lda	UNIT		;get unit
	call	PACC		; and print
	call	SPACES
	lda	TRK		;get track
	call	PACC		; and print
	call	SPACES
	lda	SCTR		;get sector
	call	PACC		; and print
	call	CRLF
	mvi	a,FINCMD
	call	CMDOUT
	mvi	a,0ffh
	sta	SELTRK
	sta	SELUNIT
	mvi	b,6
	mvi	a,0c3h
ERROR1:	out	DMA
	dcr	b
	jnz	ERROR1
	mvi	a,RESCMD
	call	FCMDI
	ret

ERMSG	db	'sta drv trk sct',07H,0AH,0DH,03

; Get character from console and echo

GCHAR:	call	CONIN
	mov	C,A
	push	psw
	call	CONOUT
	pop	psw
	ret

; Output <cr><lf> for newline

CRLF:	mvi	C,0DH
	call	CONOUT
	mvi	C,0AH
	call	CONOUT
	ret

; Output two spaces

SPACES:	mvi	C,' '
	call	CONOUT
	mvi	C,' '
	call	CONOUT
	ret

; Print message and accept

ACCEPT:	call	PTXT		;print message pointed to by hl
	call	CONIN		;get accept
	cpi	0DH		; <cr> is accept
	jnz	INERR		; no, go back to start
	call	CRLF		; yes,
	ret

; Test for console break or DC1/DC2 handshake

BREAK:	call	CONST		;char pending
	rz			; no, return
BREAK1:	call	CONIN		;get char
	cpi	013H		;x-off
	jz	BREAK1		;wait for x-on
	cpi	00DH		;escape character?
	jz	DUTIL
	cpi	01BH
	jz	DUTIL
	ret

; Print text pointed to by hl with 003H terminator

PTXT:	mov	A,M
	cpi	03H
	rz
	mov	C,A
	push	H
	call	CONOUT
	pop	H
	inx	H
	jmp	PTXT

; Print a-register as two hex digits

PACC:	push	PSW
	rrc
	rrc
	rrc
	rrc
	call	PACC0
	pop	PSW
PACC0:	ani	0FH
	adi	090H
	daa
	aci	040H
	daa
	mov	C,A
	call	CONOUT
	ret

; ASCII to binary conversion

ASBIN:	sui	030H
	cpi	10
	rm
	sbi	007H
	ret

; Check for valid hex digit

AORN:	cpi	'0'
	jc	AORN2
	cpi	'9'+1
	jc	AORN1
	cpi	'A'-1
	jc	AORN2
	cpi	'F'+1
	jnc	AORN2
AORN1:	xra	A
	ret
AORN2:	ori	0FFH
	ret

; SCAN FOR NUMERIC OPERAND
;    VALUE IN HL, LENGTH IN B, NZ=ERROR

SCAN:	lxi	H,0		;INIT retURNED VALUE
	mvi	B,0		; AND LENGTH
SCAN1:	push	H		;SAVE HL, B
	push	B
	call	CONIN		;GET A CHARACTER
	pop	B		;RESTORE HL,B
	pop	H
	mov	C,A		;SAVE IN C
; test for backspace
	cpi	08H		;BACKSPACE
	jnz	SCAN2		; NO, SKIP
	mov	A,B		;YES, TEST
	ora	A		; FOR BEGINNING
	jz	SCAN1		;  OF LINE
	push	H		;NO, SAVE
	push	B
	lxi	H,BKMSG		;BACKUP AND BLANK
	call	PTXT
	pop	B		;RESTORE
	pop	H
	dcr	B		;DECREMENT COUNTER
	mov	A,L		;DECREMENT
	ani	0F0H		; ACCUMULATED
	rar
	rar
	rar
	rar
	mov	L,H
	mvi	H,0
	jmp	SCAN4
; Test for carriage return
SCAN2	inr	B		;INCR COUNTER
	cpi	0DH		;TEST FOR END
	jnz	SCAN3		; NO, SKIP
	push	B		;YES
	call	CRLF		; OUTPUT CRLF
	pop	B
	xra	A		;SET Z
	ret
; Test for valid digit
SCAN3	call	AORN		;check
	rnz			; no, return with nz
	push	H		;echo char
	push	B
	call	CONOUT
	pop	B
	pop	H
	mov	A,C		;CONVERT TO
	call	ASBIN		; HEX
SCAN4	dad	H		;ACCUMULATE TOTAL
	dad	H
	dad	H
	dad	H
	add	L
	mov	L,A
	jmp	SCAN1

BKMSG:	db	08H,' ',08H,03H

; Input hex number

IHEXN:	call	SCAN
	jnz	INERR
	mov	A,B
	cpi	1
	jz	INERR
	ret


;*------------------------------------------------------*
;*		FORMATTING ROUTINES			*
;*------------------------------------------------------*

RESCMD	equ	008H+FSPEED	;Restore command
SKNCMD	equ	018H+FSPEED	;Seek no verify
SKVCMD	equ	01CH+FSPEED	;Seek verify
FMTCMD	equ	0F0H		;Format track
RDTCMD	equ	0E0H		;Read format track
RDCMD	equ	080H		;Read data
FINCMD	equ	0D0H		;Force interupt

STATUS	equ	0D4H		;1793 FDC status register	
CMD	equ	0D4H		;         command
TRACK	equ	0D5H		;	  track
SECTOR	equ	0D6H		;	  sector		
DATA	equ	0D7H		;	  data
DMA	equ	08CH		;dma channel

******************
* FORMAT COMMAND *
******************

FORMAT:	lxi	H,FMDMSG	;command
	lda	DDFLG
	ora	a
	jnz	FORM00
	lxi	H,FMSMSG
FORM00:	call	ACCEPT		; completion
	xra	a		;zero
	sta	FERCNT		; error count
	call	FDRAW		;draw track line

FORMA0:	call	SEEKN		;seek no verify
	jnz	ERROR		; exit if error
	call	SETTLE		;this will be write
	mvi	A,1		;set
	sta	SCTR		; sector
	sta	PSCTR		;  for first
	lxi	H,BFFR1		;build track here
	call	DENTST		;test density
	jnz	FORMA2		; double, skip
	call	SBUILD		; single
	jmp	FORMA3		;  go format
FORMA2:	call	DBUILD		; build double
FORMA3:	call	FTRACK		;format track
	jnz	ERROR

	call	FVERFY		;Verify read
	cpi	'+'		; if OK
	jz	FORMA4		;  print '+'
	lxi	H,FERCNT	;bump error count	
	inr	m
FORMA4:	mov	c,a
	call	CONOUT		;print '+,2,3,?'
	call	BREAK		;Console break?
	IF	DOUBLE
	lda	TRK
	cpi	NTRKS/2-1
	cz	CRLF
	ENDIF
	lxi	H,TRK		;Increment track
	inr	M		; and test
	mvi	A,NTRKS		; for end
	cmp	M
	jnz	FORMA0		;no, continue

	call	CRLF		;yes, newline
	lda	FERCNT		; and report
	ora	a		; errors if any
	rz
	call	PACC
	lxi	H,FERMSG
	call	PTXT
	ret
FERMSG	db	' Error(s)',0AH,0DH,7,3
FMDMSG:	db	'ormat Disk (DD:512)',3
FMSMSG	db	'ormat Disk (SD.128)',3

; Build single density track in memory

SBUILD:	mvi	a,SGAP0		;gap0: pre-index
	ora	a
	jz	SBUI00
	call	SGAP
	mvi	a,0FCH		;index mark
	call	FPUT
SBUI00:	mvi	a,SGAP1		;gap1: post-index
	jmp	SBUIL1
SBUIL0:	mvi	a,SGAP3		;gap3: post-data
SBUIL1:	call	SGAP
	call	FID
	mvi	a,SGAP2		;gap2: id 
	call	SGAP
	mvi	A,0FBH		;data mark
	call	FPUT
	lxi	b,SBYTES	
	call	DFILL
	mvi	A,0F7H		;crc bytes
	call	FPUT
	call	ISIL
	jnz	SBUIL0
	mvi	B,0		;gap4: pre-index
	mvi	A,0FFH
	call	FILL
	call	FILL
	ret

; Build double density track

DBUILD:	mvi	a,DGAP0		;gap0: pre-index
	ora	a
	jz	DBUI00		;skip if none
	mvi	c,0F6H
	call	DGAP
	mvi	a,0FCH		;index mark
	call	FPUT
DBUI00:	mvi	a,DGAP1		;gap1: post-index
	jmp	DBUIL1
DBUIL0:	mvi	a,DGAP3		;gap3: post-data
DBUIL1:	mvi	C,0F5H
	call	DGAP
	call	FID
	mvi	a,DGAP2		;gap2: id
	mvi	C,0F5H
	call	DGAP
	mvi	A,0FBH		;data mark
	call	FPUT
	lxi	b,DBYTES
	call	DFILL
	mvi	A,0F7H		;crc bytes
	call	FPUT
	call	ISIL
	jnz	DBUIL0
	mvi	B,0		;gap4: pre-index
	mvi	A,0FEH
	call	FILL
	call	FILL
	ret

; Increment sector interleaved

ISIL:	lda	NSCTP1
	mov	b,a
	lda	SCTR
	inr	a
	sta	SCTR
	cmp	b
	rz
	push	h		;preserve hl for format
	call	PSFMAP
	pop	h
	ora	a		;set nz
	ret

; Formatter logical to physical sector mapper (SD and DD)

PSFMAP:	lda	SCTR
	mov	c,a		;make index
	mvi	b,0
	dcx	b
	lxi	h,ILSD		;assume SD	
	call	DENTST
	jz	PSFMP0		; yes, skip
	lxi	h,ILDD		; no, DD
PSFMP0:	dad	b		;index into table
	mov	a,m		; get result
	sta	PSCTR		; store and 
	ret			; return

; Logical to physical sector mapper (DD only)

PSMAP:	lda	SCTR		;get logical sector
	mov	c,a		; save in c
	call	DENTST		;test SD
	jz	PSMAP0		; yes, skip
	mvi	b,0		;make
	dcx	b		; into
	lxi	h,ILDD		;  index
	dad	b		;   into table
	mov	c,m		;get result into c
PSMAP0:	mov	a,c
	sta	PSCTR		; store and 
	ret			; return

; Draw the track-status line

FDRAW:	mvi	c,'1'
	mvi	b,8
FDRAW0:	push	b
	mvi	c,'.'
	mvi	b,8
FDRAW1:	call	conout
	dcr	b
	jnz	FDRAW1
	pop	b
	call	conout
	push	b
	mvi	c,'0'
	call	conout
	pop	b
	inr	c
	dcr	b
	jnz	FDRAW0
	call	CRLF
	ret

; Format write of a single track from BFFR1

FTRACK:	mvi	a,1		;setup for write
	call	DMAOUT		;start up DMA channel
	mvi	A,FMTCMD	;output format 
	call	CMDOUT		; track command
FTRK0:	in	STATUS		;loop
	ani	001H		; until busy
	jnz	FTRK0		;  not busy
	mvi	a,083		;stop DMA
	out	DMA		; channel
	in	STATUS		;get status mask for
	ani	0C4H		; NR,WP,LOSTDATA
	ret

; Output DMA channel program (direction in a-reg)

DMAOUT:	push	psw
DMAOU0:	
;	lda	MOVECS
;	ora	a
;	jnz	DMAOU0
	pop	psw
	sta	DMADIR		;set direction
	mvi	b,DMALEN	;b=count
	mvi	c,DMA		;c=port
	lxi	h,DMADCB	;hl=channel program
	db	0EDH,0B3H	;OTIR
	ret

DMADCB:	db	0C3H		;WR6: RESET
	db	06DH		;WR0: XFER,A->B,PORT A,BLKSZ FOLLOWS
	db	DATA		;     PORT A (1793 data port)
DMABLK:	dw	0FFFFH		;     BLOCKSIZE
	db	02CH		;WR1: A IS I/O FIXED
	db	010H		;WR2: B IS MEMORY INCREMENTING
	db	08DH		;WR3: BYTE MODE, DMA FOLLOWS
DMADDR:	dw	BFFR1		;     DMA BUFFER ADDRESS
	db	08AH		;WR4: HI RDY, /CE ONLY
	db	0CFH		;WR6: LOAD SOURCE
DMADIR:	db	001H		;WR0: 05:A->B READ; 01:B->A WRITE
	db	0CFH		;WR6: LOAD SOURCE
	db	087H		;WR6: ENABLE DMA
DMALEN	equ	$-DMADCB

; Read verify track

FVERFY:	call	FTREAD
	mvi	a,'+'
	rz			;verify OK
	call	FTREAD
	mvi	a,'2'
	rz			;recoverable read error
	call	FTRACK		;try another write
	call	FTREAD
	mvi	a,'3'		;recoverable write error
	rz
	mvi	a,'?'
	ret			;nfg

FTREAD:	mvi	a,1
	sta	SCTR
	sta	PSCTR
FTREA0:	lda	PSCTR
	out	SECTOR
	mvi	a,005H		;setup for read
	call	DMAOUT		;start up DMA
	mvi	A,RDCMD		;read data command
	call	CMDOUT
FTREA1:	in	STATUS		;loop until
	ani	001H		; busy
	jnz	FTREA1		;  goes away
	mvi	a,083H		;stop
	out	DMA		; DMA
	in	STATUS		;check status
	ani	0BDH		; NR,WP,LOSTDATA
	rnz
	call	ISIL		;increment sector
	jnz	FTREA0		; interleaved
	ret

; Fill buffer with HL = B*A

FILL:	mov	M,A
	inx	H
	dcr	B
	jnz	FILL
	ret

; Fill buffer with prep data HL = B*E5

DFILL:	mvi	m,0E5H		;SECTOR PREP DATA
	inx	h
	dcx	b
	mov	a,c
	ora	b
	jnz	DFILL
	ret

; Build double density gap: HL = A*4E+12*0+3*C

DGAP:	mov	B,A		;count in b
	mvi	A,04EH
	call	FILL
	xra	A
	mvi	B,12
	call	FILL
	mov	A,C
	mvi	B,3
	call	FILL
	ret

; Build single density gap: HL = A*FF+6*0

SGAP:	mov	B,A		;count in b
	mvi	A,0FFH		;datum in a
	call	FILL
	xra	A
	mvi	B,6
	call	FILL
	ret

; Put a single character into buffer

FPUT:	mov	M,A
	inx	H
	ret

; Build ID record: FEh.TRK.SIDE.SCTR.SECTYP.F7h

FID:	mvi	A,0FEH
	call	FPUT
FID4	mvi	b,0		;assume side 0
	lda	TRK		;test track
	IF	DOUBLE
	cpi	NTRKS/2		;side 0
	jc	FID5		; yes, skip
	mvi	b,1		; no, side=1
	sui	NTRKS-1		;calc track going
	cma
	inr	a
	ENDIF
FID5:	call	FPUT		;track
	mov	a,b	
	call	FPUT		;side
	lda	PSCTR
	call	FPUT		;sector
	lda	NSCTYP
	call	FPUT		;sector type 
	mvi	A,0F7H
	call	FPUT		;crc's
	ret

*********************
* FORMAT TRACK READ *
*********************

RTRK:	lxi	H,RTMSG		;Command completion
	call	ACCEPT		
	lxi	H,RTTMSG	;request track
	call	PTXT
	call	IHEXN
	mov	A,L
	sta	TRK
	call	SEEKN
	jnz	ERROR
	mvi	a,0FFH		;set for next
	sta	SELTRK		; operation

	mvi	a,5		;setup for read
	call	DMAOUT		;start up DMA channel
	mvi	A,RDTCMD	;output format 
	call	CMDOUT		; track command
RTRK0:	in	STATUS		;loop
	ani	001H		; until busy
	jnz	RTRK0		;  not busy
	mvi	a,083		;stop DMA
	out	DMA		; channel

	lxi	H,11000		;print buffer
	shld	NBYTES
	lxi	H,BFFR1
	call	DBFFR
	ret

RTMSG:	db	08H,'Format Read',3
RTTMSG:	db	' Enter track: ',03

;*------------------------------------------------------*
;*		BB-II MONITOR INTERFACE			*
;*------------------------------------------------------*

*********************
* Console Interface *
*********************

MCONST	equ	0F006H		;console status
MCONIN	equ	0F009H		;        input
MCONOUT	equ	0F00CH		;        output

CONST:	call	MCONST
	ora	a		;must set flags
	ret

CONIN:	call	MCONIN
	cpi	07BH		;upshift
	rnc			; to upper case
	cpi	061H
	rc
	ani	05FH
	ret

CONOUT:	mov	a,c
	push	b
	call	MCONOUT
	pop	b
	ret

******************
* Disk Interface *
******************

MSELC	equ	0F01BH		;select
MSEEK	equ	0F021H		;seek      
MREAD	equ	0F024H		;read
MWRIT	equ	0F027H		;write
SETDEN	equ	0F030H		;SMC disk type/density
READY	equ	0F033H		;drive ready and set spinup
MTRACK	equ	0FF87H		;track for TRKTAB
CTCB3	equ	08BH

; Test density Z=SD, NZ=DD

DENTST:	lda	TRK		;if track=0 
	ora	a		; then
	rz			;  return Z
	lda	DDFLG		;if not double
	ora	a		; then
	ret			;  return Z

; Select Density and Side 

DENSET:	call	DENTST
	jnz	DENSE1
	mvi	A,SPTSD+1	;SD track
	sta	NSCTP1
	lxi	H,SBYTES
	shld	NBYTES
	mvi	a,SDSTYP
	sta	NSCTYP
	mvi	a,DTYPSD	;set single density
	call	SETDEN
	ret

DENSE1:	mvi	A,SPTDD+1	;DD track
	sta	NSCTP1
	lxi	H,DBYTES
	shld	NBYTES
	mvi	a,DDSTYP
	sta	NSCTYP
	mvi	a,DTYPDD	;set double density
	call	SETDEN
	ret

; Set side

SIDSET:	lda	TRK		;get track
	mvi	B,1		;assume side 1
	IF	DOUBLE
	cpi	NTRKS/2
	jc	SETSD3
	mvi	B,9
	sui	NTRKS-1
	cma
	inr	A
	ENDIF
SETSD3:	sta	MTRACK
	mov	A,B		;set side
	out	0C8H
	ret	

; Select Disk

SELECT:	lda	UNIT		;test same unit
	lxi	H,SELUNIT
	cmp	M
	jz	SELEC1		;yes, skip
	mov	m,a		;no, update
	lxi	h,SELTRK
	mvi	m,0FFH
SELEC1:	mov	C,A
	call	MSELC
	ret

; Seek Track 

HOME:	xra	a		;home special
	sta	TRK		; case of seek
SEEKN:	mvi	a,0FFH		;assure
	sta	SELTRK		; seek to track
	sta	RDFLAG		; but no verify
SEEK:	call	SELECT		;select drive
	rnz			; exit if error
	lda	TRK		;test for change
	lxi	H,SELTRK	;of track
	cmp	M
	rz			;no, exit
	mov	M,A
	call	READY		;spinup
	rnz			; exit if error
	call	DENSET		;set correct density
	call	SIDSET		; and side
	lda	TRK		;set for
	cpi	0		; correct seek command
	mvi	A,RESCMD
	jz	SEEK2
	lda	MTRACK		;get single sided track
	out	DATA		; output to 1793
	lda	RDFLAG
	ora	a
	mvi	a,SKNCMD	;if write then
	jnz	SEEK2		; verify seek
	mvi	a,SKVCMD
SEEK2:	call	FCMDI
	call	SETTLE		; else do head settling
	ret

; Output type I command

FCMDI:	call	CMDOUT		;output command to 1793
FCMDI0:	in	STATUS		;wait until
	ani	001H		; busy goes
	jnz	FCMDI0		;  away 
	in	STATUS		;test for
	ani	098H		; ready.writeprotect,
	ret

; Output command and delay

CMDOUT:	out	CMD		;output command
	mvi	a,10		; and wait
CMDOU1:	dcr	a		; a little
	jnz	CMDOU1		; before status
	ret			; is ready 28us MFM

; Head settling delay (15ms)

SETTLE:	push	PSW		;keep flags intact
	mvi	B,15
SETTL0:	in	CTCB3
	mov	C,A
SETTL1: in	CTCB3
	cmp	C
	jz	SETTL1
	dcr	B
	jnz	SETTL0
	pop	PSW
	ret

; Disk read and write routines

READP:	call	PSMAP		;read physical sector
	jmp	READ0
READ:	lda	SCTR		;read logical sector
	sta	PSCTR
READ0:	mvi	a,0FFH
	jmp	WRIT1

WRITP:	call	PSMAP		;write physical sector
	jmp	WRIT0
WRITE:	lda	SCTR		;write logical sector
	sta	PSCTR
WRIT0:	xra	a
WRIT1:	sta	RDFLAG
	call	SEEK
	rnz
	lhld	TADDR
	lda	PSCTR
	mov	C,A
	lda	RDFLAG
	ora	A
	jz	MWRIT
	jmp	MREAD

;*------------------------------------------------------*
;*			VARIABLES			*
;*------------------------------------------------------*

;	org	RAM

TADDR	ds	2		;disk DMA address
UNIT	ds	1		;     UNIT
SELUNIT	ds	1		;     selected UNIT
TRK	ds	1		;     TRACK
SELTRK	ds	1		;     selected TRACK
SCTR	ds	1		;logical sector
PSCTR	ds	1		;physical sector
RDFLAG	ds	1		;read (write/) flag

NBYTES	ds	2		;bytes/sector
NSCTP1	ds	1		;sectors/track + 1
NSCTYP	ds	1		;sector type
DDFLG	ds	1		;density flag
SKEWF	ds	1		;track to track skew
SKEW	ds	1		;"first" sector of skewed track 
DCNTR	ds	2		;dump byte counter
DLCNTR	ds	1		;     line counter
PASCNT	ds	1		;pass counter
OLDTRK	ds	1		;dots counter
FERCNT	ds	1		;format error count
RQST	ds	1		;command request
VFLAG	ds	1		;verify flag for copy
CTRK	ds	1		;COPY current track
CSCTR	ds	1		;     current sector
SECREM	ds	2		;     sectors remaining
SECINC	ds	2		;     sectors/read increment
CREC	ds	2		;     number of sectors read/written
NREC	ds	1		;number of sectors (records)
DQCNT	ds	2		;sequential sector count
	ds	32
STACK	equ	$

; Disk Buffers 

	org	BUF

BFFR1	ds	DBYTES
BFFR2	ds	DBYTES

	END
