	.title	'harddisk help program'
	.ident	hardhelp
	.PABS
	.PHEX
XVISION		==	0  ;CHANGE EVERY ASSBY!!!
VERSION		==	4
REVISION	==	0  ;last change 1-Feb-84
;		TABLE OF CONTENTS		PAGE
; 1. Version change descriptions		3
; 2. Instructions for creating hardhelp.com	5
; 3. Equates					6
; 4. ZDTI entry points				16
; 5. Body of code
;	print version and logon			18
;	find size of disk			19
;	conout and prtmsg			20
;	gethex					21
;	init user area from 4100h		22
;	put user and clear errbuf		24
;	setup test parameters			25
;	disktest				27
;	compare					30
;	logerr					32
;	crlf and various hex printings		33
;	seektest				34
;	random					36
;	setup next sector			37
;	verify and reset track,head,sec		39
;	format entire disk			40
;	print track				44
;	setup command buffer			45
;	send comd 40 to cont and read til err	47
;	abs write and read			48
;	bad sector stuff			49
;	read and display continuous		51
;	read 1k block and load user		52
;	pread and pwrite			53
;	set interupts				55
;	interface test				56
;	memory test				59
;	get memory from controller		60
;	select disk				61
;	boot disk				63
;	error number and buffer descriptions	64
;	get unit info				65
;	multiple drive seek test		68
;	cpm 128 byte read and write		70
;	multiple unit write test		71
;	flush controller buffers		72
;	multi volume full test			73
;	size set and default			76
;	setup number of sectors			77
;	assign partition			78
;	test crc circuitry			79
;	display error history			80
; 5. Message buffers				83
; 6. Variable area				87
	.page
	.sbttl	'Version change descriptions'
;version 4.0	20-Jan-84	Les Wilson
;	for release only, no change

;version 4.4	18-Jan-84	Les Wilson
;	1. saving 17k message corrected
;	2. error messages from verify etc, space
;	down a line so track doesnt overwrite

;version 4.3	16-Jan-84	Les Wilson
;	1. format indicates read taking place after
;	Y option selected
;	2. reset HDC after memtest and interface
;	tests.
;	3. unrecognised spelled unrecognized	
;	4. bad sector table warning modified
;	5. unused entry points (labels) removed

;version 4.2	12-Jan-84	Les Wilson
;	changes made to correct way disk was being
;	selected and booted in format,verify, and
;	read/write tests

;version 4.1	10-Jan-84	Les Wilson
;	updated to implement software tests requests
;	as follows:
;	1. Rom is reset to allow loading test
;	programs. new firmware does not recognise
;	all rom commands.  This affected g11c(
;	load user program),g120,g18c(disk read/write
;	test)
;	2. g128(get disk size) removed. duplicates
;	g170(get volume info)
;	3. g14c(net 1k read) option rephrased
;	4. g15c(zero bad sector table) removed,
;	duplicates g158(get,modify bad sector table)
;	5. g164(select volume/partition) returns
;	english failure message
;	6. g16c(error message descriptions) ordered
;	into numeric order
;	7. crc circuitry test first saves sector to
;	be trashed and then restores it
;	8. Y OR N prompt used rather than Y,N
;	where applicable
;	9. g148(warmboot) removed

;version 4.0	14-Dec-83	Les Wilson
;	updated for release

;version 3.9	28-Oct-83	les wilson
;	hardfirm has grown larger so intructions to
;	create hardhelp changed and the init firmware
;	code writes an additional sector to the disk
;	added the following options:
;	1. perform assign function
;	2. test crc circuitry
;	3. display error history
;	4. make zeroing of bad sector table
;		not talk to wrong disk afterwords
;	5. multi volume seek test can accept E5 data only

;version 3.8	20-Apr-83	les wilson
;	hardfirm has grown larger so instructions
;	to create hardhelp changed

;version 3.7	18-Apr-83	les wilson
;	adds flush error(31h) to error messages

;version 3.6	15-Mar-83	les wilson
;	corrects problems in timeout and using
;	badsector tables in multi disk read/write
;	test

;version 3.5	4-Oct-82	les wilson
;	handles 46meg harddisk, buffers moved around
;	better timeout and entry of test routines

;version 3.4	10-sep-82	les wilson
;	reset disk controller done every where 
;	useful.  number of tracks to process option
;	to use error correction an option
;	exit from memtest and interface test thru
;	'r' possible
;	fixed multi volume complete test

;version 3.3	24-aug-82	les wilson
;	everywhere select disk is used expects status
;	format of only one track an option
;	select disk used in disk tests to ensure
;		bad sector tables used

;version 3.2	select disk expects status return

;version 3 for multiple harddisks
;
	.page
	.sbttl	'instructions for creating hardhelp.com'

;
;>zdti hardhelp.hex
;-ihdcit.com
;-r2f00
;-ihmemtst.com
;-r3200
;-f4100 4300 0
;-ihardform.hex
;-r
;-m4100 42ff 3100
;-f4100 4e00 0
;-ihardfirm.hex
;-r
;-control-c
;save 78 hardhelp.com

	.page
	.sbttl	'Equates'

seconds	==	41h	;seconds in hinet time area

;
;	memory buffer locations
;
comdbuf		==	2400h	;command buffer
WBUFFER		==	2700H	;write buffer
RBUFFER		==	2C00H	;read buffer
STATBUFFER	==	2bF8H
ERSTAT		==	2BF0H
hdcitbuf	==	3000h	;hdcit.hex
hdformbuf	==	3100h	;hardform.hex
hdmemtst	==	3300h	;hmemtst.hex
hdfirm		==	4100h	;hardfirm.hex
firmver		==	hdfirm+16h ; version 
firmrev		==	hdfirm+17h ;revision
membuf		==	5000h	;memory buffer
			;from controller
ERRBUF		==	6000H
LOOPCNT		==	6801H	;FOLLOWS ERR BUF
formsave	==	7000h	;buffer to save
			;first 17k of disk when
			;formating

;
DLR	==	"$"
CR	==	0DH
LF	==	0AH
questionmark == 3fh

;
;THIS PROGRAM CAN WORK FOR THE DSC2 OR DSC3
;AND CAN RUN EITHER AN SA4004/8 OR A
;MEMOREX 8 INCH HARD DISK.
;	FOR A DSC2 LET D=0
;	FOR A DSC3 LET D=1
;
DSC	=\ "FOR DSC2 ENTER 0, DSC3/4 ENTER 1 "
;
	.IFE	DSC,[
hhpstatus	==	0F0H
hhinport	==	0F1H
CLRPORT		==	0F2H
hhoutport	==	0F0H
STAT1A		==	6
STAT1B		==	7][
hhpstatus	==	08H
hhinport	==	01H
CLRPORT		==	00H
hhoutport	==	01H
STAT1A		==	3
STAT1B		==	4]
;
;
;
;
combufloc	==	20H	;COMMAND BUFFER LOCATION
;
	.insert	hardequ
	.page
	.sbttl	'zdti entry points'

	.LOC	100H
;
START:
	JMP	LOGON
	NOP			;FALL THROUGH
	CALL	SETINT
	rst	6
	OUT	CLRPORT
	NOP
	RST	6
	CALL	ABSRST
	RST	6
	CALL	ABSWST
	RST	6
	CALL	VERIFY
	RST	6
	CALL	FORMAT
	RST	6
	CALL	rstLOADUSER
	RST	6
	CALL	DISKTEST
	RST	6
	CALL	SEEKTEST
	RST	6
	CALL	doassign
	RST	6
	CALL	INTUSER
	RST	6
	CALL	INTTEST
	RST	6
	CALL	MEMTEST
	RST	6
	CALL	GETMEM
	RST	6
	CALL	RDTHS
	RST	6
	CALL	TSTTHS
	RST	6
	CALL	SEND40
	RST	6
	CALL	docrctest
	RST	6
	CALL	READ1K
	RST	6
	CALL	RDISPC
	RST	6
	CALL	READISP
	RST	6
	CALL	GETBST
	RST	6
	CALL	disperrorhistory
	RST	6
	CALL	COMPARE
	RST	6
	call	seldisk
	rst	6
	call	bootdisk
	rst	6
	call	errdiscription
	rst	6
	call	getvolinfo
	rst	6
	call	multseek
	rst	6
	call	cpmr128
	rst	6
	call	multwrite
	rst	6
	call	cpmw128
	rst	6
	call	bufferdescription
	rst	6
	call	doflush
	rst	6
	call	voltest
	rst	6
	call	sizeset
	rst	6
	call	sizedefault
	rst	6
	.page
	.sbttl	'print version and logon'

;
;
PRTVER:			;PRINT VERSION NUMBER
	LXI	D,VERMSG
	CALL	PRTMSG
	RET
;
LOGON:
	LXI	SP,100H		;INIT STACK
	CALL	PRTVER
	XRA	A
	LXI	H,FIRST		;FIRST TIME THRU HERE
	CMP	M
	JRZ	LG2
	MOV	M,A
	out	clrport		;reset hard disk 
	call	getvolinfo
	.ifn	dsc,[
	LXI	D,MENU
	CALL	PRTMSG
	CALL	CONIN
	CPI	"0"
	JZ	LG2
	CPI	"1"
	JRNZ	..2
	CALL	FORMAT
	JMP	0
..2:	CPI	"2"
	JRNZ	..3
	CALL	INTUSER
	JMP	0
..3:	CPI	"3"
	JRNZ	..4
	CALL	GETBST
	JMP	0
..4:	JMP	0	]

LG2:	LXI	D,LOGMSG
	CALL	PRTMSG
	JMP	104H		;FALL THRU

	.page
	.sbttl	'find size of disk'

FNDSZ:	LXI	D,SIZEMSG
	CALL	PRTMSG
	CALL	CONIN
	MVI	E,memtracks	;NO TRACKS MEMOREX
	LXI	B,mem11headmask*100h+memsectors
	CPI	"1"		;FOR MEMOREX
	JRZ	VALIDSZ
	MVI	B,mem23headmask
	CPI	"2"
	JRZ	VALIDSZ
	mvi	c,mem46sectors
	cpi	"4"
	jrz	validsz
	MVI	E,shutracks		;NO TRACKS SHUGART
	LXI	B,shu14headmask*100h+shusectors
	CPI	"3"
	JRZ	VALIDSZ
	MVI	B,shu28headmask
	CPI	"7"
	JRZ	VALIDSZ
	MVI	B,shuf14headmask	;fixed head
	CPI	"B"
	JRZ	VALIDSZ
	MVI	B,shuf28headmask	;fixed head
	CPI	"F"
	JRZ	VALIDSZ
	JMPR	FNDSZ	;DID NOT FIND VALID RESPONSE
VALIDSZ:
	MOV	A,B
	STA	HEADMASK
	MOV	A,C
	STA	SECPTRK
	INR	A
	STA	NSECTOR
	MOV	A,E
	STA	NTRACK		;NO OF TRACKS
	ret

	.page
	.sbttl	'conout and prtmsg'
;
;
;
CONOUT:	MOV	E,C	;CPM CONVENTION
	MVI	C,2		;WRITE CONSOLE
	JMP	5		;GOTO CPM
;
PRTMSG:
	LDAX	D
	INX	D
	CPI	"$"
	RZ
	PUSH	D
	MOV	C,A
	CPI	"\"
	JRZ	..3
	CALL	CONOUT
..2:	POP	D
	JMPR	PRTMSG
..3:	CALL	CRLF
	JMPR	..2
;
CONINS:	PUSH	H		;SAVE REG, CONIN
	PUSH	D
	PUSH	B
	CALL	CONIN
	POP	B
	POP	D
	POP	H
	RET
;
CONIN:
	MVI	C,1		;READ CONSOLE
	JMP	5		;GOTO CPM
;
CONSTAT:
	MVI	C,11		;CPM CONSTAT
	JMP	5
	.page
	.sbttl	'gethex'
;
;	get hex number into hl register, must be
;	less than 100h
;	on return:
;	a - hex value
;	b - number of hex digits input
;
GETHEX:	CALL	GETADR
	MOV	A,H
	ORA	A
	JRNZ	GHERR1
	MOV	A,L
	RET
GHERR1:	LXI	D,GHERMSG
	CALL	PRTMSG
	JMPR	GETHEX
GETADR:	LXI	H,0		;GET ADR INTO HL IN HEX
	MOV	B,H
	MOV	D,H
GET0:	CALL	CONINS
	CPI	CR
	RZ
	inr	b
	CPI	"G"
	JRNC	GAERR1
	CPI	"A"
	JRC	NUM
	SUI	"A"-("9"+1)
	CPI	"9"+1
	JRC	GAERR1
NUM:	SUI	"0"
	JRC	GAERR1
	DAD	H
	DAD	H
	DAD	H
	DAD	H
	MOV	E,A
	DAD	D
	JMPR	GET0
GAERR1:	PUSH	H
	PUSH	D
	PUSH	B
	LXI	D,BSPSBSP
	CALL	PRTMSG
	POP	B
	dcr	b	;count of chars input
	POP	D
	POP	H
	JMPR	GET0
	.page
	.sbttl	'init user area from 4100h'

INTUSER:		;INIT USER AREA FROM writebuffer
	call	bootdisk	;ask and boot unit
				;to write on
..findsize:
	call	fndsz		;find size of disk
	LXI	D,IUMSG
	CALL	PRTMSG
	LDA	firmver		;VER
	CALL	SPRTHEX
	MVI	C,"."
	CALL	CONOUT
	LDA	firmrev		;REVISION
	CALL	PRTHEX
	CALL	CRLF
	CALL	RSTTHS		;SET THS TO 0,0,1
;
;	stuff headmask,sectors/track and number of tracks
;	into firmware after copying from firmware buffer
;
	lxi	h,hdfirm
	lxi	d,wbuffer
	lxi	b,400h
	ldir

	LDA	HEADMASK
	STA	WBUFFER+offsize
	LDA	SECPTRK
	STA	WBUFFER+offtype
	lda	ntrack
	sta	wbuffer+offtracks
;
;	stuff the volume label
;
	lxi	d,mbf3
	call	prtmsg

	lxi	d,vlabbuf
	mvi	c,0ah		;buffer input
	call	5		;bdos
	lxi	h,vlabbuf+1
	mov	c,m		;count of chars input
	mvi	b,0
	inx	h		;point to input
	lxi	d,wbuffer+offvollabel
	ldir

	CALL	ABSWRITE
	JNZ	INITERR
	CALL	ABSREAD
	JNZ	INITERR
	LXI	H,hdfirm+400h	;GET SECOND BLOCK
	LXI	D,wbuffer
	LXI	B,400H
	LDIR
	MVI	A,2
	STA	SECTOR
	CALL	ABSWRITE
	JNZ	INITERR
	CALL	ABSREAD
	JNZ	INITERR
	LXI	H,hdfirm+800h	;GET third BLOCK
	LXI	D,wbuffer
	LXI	B,400H
	LDIR
	MVI	A,3
	STA	SECTOR
	CALL	ABSWRITE
	JNZ	INITERR
	CALL	ABSREAD
	JNZ	INITERR
	LXI	H,hdfirm+0c00h	;GET fourth BLOCK
	LXI	D,wbuffer
	LXI	B,400H
	LDIR
	MVI	A,4
	STA	SECTOR
	CALL	ABSWRITE
	JNZ	INITERR
	CALL	ABSREAD
	JNZ	INITERR
	OUT	CLRPORT		;RESET HDC TO LOAD USER
	LXI	D,INITMSG
	call	PRTMSG
	call	getvolinfo
	ret
;
INITERR:call	pst		;print status 
	LXI	D,IERRMSG
	call	PRTMSG
	ret

	.page
	.sbttl	'put user area and clear errbuf'
;
PUTUSER:
	LXI	D,wbuffer
	LXI	B,400H		;MOVE 400H ANYWAY
	LDIR
	JMP	LOADUSER
;
CLREB:
	LXI	H,ERRBUF    ;FILL ERROR BUFF WITH 0'S
	LXI	D,ERRBUF+1
	LXI	B,0810H		;LOOPCNT FOLLOWS BUFFER
	MVI	M,0H
	LDIR
	XRA	A
	STA	ERRCNT
	RET
	.page
	.sbttl	'setup test parameters'
;
;	test setup calls several routines used from
;	several tests, return none zero if setup fails
;
testsetup:
	CALL	CLREB
	lda	sizeflag
	cpi	false
	jrz	..dontchangesize
	out	clrport	;reset hard disk controller
	call	seldisk		;select disk to test
	rnz			;return if error
..dontchangesize:
	call	endingtrack
	call	usecrc
	sub	a	;return zero set if ok
	ret		

;
;	boot the selected volume to allow access
;	to rom routines
;
bootselected:
	out	clrport	;reset hard disk
	lda	volsel
	sta	track
	mvi	a,bootunit
	call	setup
	jmp	setupsectors	;return from there

;
;	find ending track for test
;
endingtrack:
	lxi	d,mbf20
	call	prtmsg		;enter ending track, 
				;cr for default
	call	gethex
	mov	c,a
	mov	a,b
	ora	a
	rz			;default chosen
	mov	a,c
	ora	a
	jrz	..zerotracks
	sta	ntracks
	ret
..zerotracks:
	lxi	d,mbf26		;zero is not valid number of tracks
	call	prtmsg
	jmpr	endingtrack
;
;	ask if user wishes crc error correction
;
usecrc:
	lxi	d,mbf21
	call	prtmsg	;use error correction(y or n)
	call	conin
	ani	05fh	;upper case
	cpi	'Y'
	jrz	..use
	cpi	'N'
	jrnz	usecrc
	mvi	a,1	;retry count
	jmpr	..store
..use:	mvi	a,81h	;retry count with crc use
			;bit set
..store:sta	testcrcusage
	ret

	.page
	.sbttl	'disktest'
;
DISKTEST:
	call	okdestroy
	RNZ
	call	testsetup
	rnz
	call	bootselected	;get back rom
	LXI	H,hdcitbuf	;USER PROGRAM HERE
	CALL	PUTUSER
;
	CALL	NSDONE		;INIT T,H,S
;
REDO:	
	call	testcycle
	JMPR	REDO		;DO FOREVER
;
;	basic test cycle used several places
;
testcycle:
	CALL	SETWCP
	CALL	DOTEST
	CALL	RANTST
	CALL	DOTEST
	ret

SETWCP:	LHLD	WCPAT		;GET WORST CASE PAT
	SLAR	L
	RALR	H
	JRNC	..2
	INX	H
..2:	SHLD	WCPAT
	XCHG			;FILLW FROM DE
	CALL	FILLW
	RET
WCPAT:	.WORD	0B6D9H		;WORST CASE PAT
;
FILLW:			;FILL WBUFFER WITH (DE)
	LXI	H,WBUFFER
	MOV	M,D
	INX	H
	MOV	M,E
	DCX	H
	LXI	D,WBUFFER+2	;MOVE WORDS
	JMPR	FB2
;
FILLB:				;FILL WBUFFER WITH (A)
	LXI	H,WBUFFER
	MOV	M,A
	LXI	D,WBUFFER+1
FB2:	LXI	B,1024
	LDIR
	RET
;
RANTST:			;FILL WBUFFER WITH RANDOM
	LXI	D,WBUFFER
	LXI	B,1024
RANT2:	CALL	RANDOM
	STAX	D
	INX	D
	DCX	B
	MOV	A,C
	ORA	B
	JRNZ	RANT2
	RET
;
;
;
CHKSTAT:		;PRINT STATUS IF "S"
	LXI	H,LOOPCNT
..5:	INR	M
	JRNZ	..4
	INX	H
	JMPR	..5
..4:	CALL	CONSTAT		;CHECK FOR SUM REQ
	ORA	A
	RZ
	CALL	CONIN		;GET CHAR
	ani	05fh		;make upper case
	CPI	"R"		;ABORT IF R
	JRNZ	..2
	CALL	CSLINE
	CALL	30H		;DO RESTART 6
..2:	CPI	"S"		;IS IT "S"
	RNZ
CSLINE:	CALL	CRLF
	LXI	D,SUMMSG
	CALL	PRTMSG
	LDA	WBUFFER
	CALL	SPRTHEX
	LDA	TRACK
	CALL	SPRTHEX
	LDA	HEAD
	CALL	SPRTHEX
	LDA	SECTOR
	CALL	SPRTHEX
	LDA	LOOPCNT+2
	CALL	SPRTHEX
	LDA	LOOPCNT+1
	CALL	PRTHEX
	LDA	LOOPCNT
	CALL	PRTHEX
	LDA	ERRCNT
	CALL	SPRTHEX
	CALL	CRLF
	RET
;
DOTEST:
	LDA	WBUFFER
	CALL	CPRTHEX
TSTLOOP:
	CALL	CHKSTAT
	CALL	NEXTS		;GET NEXT SECTOR
	RZ			;RET IF END OF DISK
	MVI	A,1
	STA	RETRYS
	CALL	ABSWRITE
	JNZ	DTERR1
	lda	testcrcusage	;determined in testsetup
	STA	RETRYS
	CALL	ABSREAD
	JNZ	DTERR2
	MVI	A,00H
	STA	FLAG
	CALL	COMPARE
	LDA	FLAG
	CPI	0FFH
	CZ	REREAD
	JMPR	TSTLOOP
	.page
	.sbttl	'compare'
;
COMPARE:
	XRA	A
	STA	CERRCNT		;ZERO ERR CNT
	LXI	H,WBUFFER
	LXI	D,RBUFFER
	LXI	B,04H
CPR2:	LDAX	D
	CMP	M
	JRZ	CNXT
	LDA	CERRCNT
	INR	A
	STA	CERRCNT
	CPI	10
	RZ
	MVI	A,0FFH	;CHANGE TO 0FFH FOR RETRY
			;REQUIRES PROG HDCIT RUNNING
			;IN HDC AT 4100H.
	STA	FLAG
	SHLD	TEMPH
	MOV	A,M	;FILL STATBUFF WITH ERROR INFO.
	LXI	H,ERSTAT+3
	MOV	M,A	;FOR COMP ERR ERSTAT IS LOADED
	DCX	H	;WITH 02,ADDR IN BUF,BYTE SENT,
	LDA	TEMPH	;BYTE REC,AND XOR OF BOTH BYTES
	MOV	M,A
	DCX	H
	LDA	TEMPH+1
	MOV	M,A
	MVI	A,02
	DCX	H
	MOV	M,A
	XCHG
	SHLD	TEMPD
	MOV	A,M
	STA	ERSTAT+4
	MOV	L,C
	MOV	H,B
	SHLD	TEMPB
	CALL	CRLF
	LXI	D,CEMSG		;PRINT COMP ERR MSG
	CALL	PRTMSG
	LHLD	TEMPH
	PUSH	H
	CALL	SPRTHLM		;PRINT (HL) (M)
	LHLD	TEMPD
	PUSH	H
	CALL	SPRTHLM
	POP	H
	MOV	A,M
	POP	H
	XRA	M
	STA	ERSTAT+5
	CALL	SPRTHEX
	CALL	LOGERR
	LHLD	TEMPB
	MOV	B,H
	MOV	C,L
	LHLD	TEMPD
	XCHG
	LHLD	TEMPH
CNXT:	INX	H
	INX	D
	DJNZ	CPR2
	DCR	C
	JRNZ	CPR2
	RET
DTERR1:
	MVI	B,0
	JMPR	DPTER
DTERR2:	MVI	B,1
DPTER:	CALL	PRTERR
	JMP	TSTLOOP		;TRY NEXTS
PRTERR:	MOV	C,A	;SAVE ERR STATUS FROM WAYBACK
	PUSH	B
	MOV	A,B
	STA	ERSTAT
	CALL	CPRTHEX	;0=WRITE, 1=READ, 2=COMPARE
	POP	B
	MOV	A,C
	STA	ERSTAT+1	;LOAD ERROR RETURNED.
	CALL	SPRTHEX	;HDC4 ERROR RETURN
	LDA	TRACK
	STA	ERSTAT+2	;LOAD TRACK.	
	CALL	SPRTHEX
	LDA	HEAD
	STA	ERSTAT+3	;LOAD HEAD.
	CALL	SPRTHEX
	LDA	SECTOR
	STA	ERSTAT+4	;LOAD SECTOR.
	CALL	SPRTHEX
	LDA	WBUFFER
	STA	ERSTAT+5	;LOAD START OF REC	
	CALL	SPRTHEX		;WBUFFER CONTENTS
	lda	volsel
	sta	erstat+6
	call	sprthex		;PRINT SELECTED VOLUME
	LXI	D,ERRFMT
	CALL	PRTMSG
	.page
	.sbttl	'logerr'
;
LOGERR:
;THIS ROUTINE LOADS THE ERROR BUFFER WITH THE
;STATUS INFO CONTAINED IN ERSTAT. EACH ENTRY IN
;THE BUFFER IS 7 BYTES LONG. THE SPACING BETWEEN
;THE BEGINNING OF EACH ENTRY IS 8 BYTES.
	LXI	D,ERRBUF
	LDA	ERRCNT		;MULTIPLY ERRCOUNT
	MOV	L,A		;BY 8 AND ADD TO
	MVI	H,00H		;ERRBUF. GIVES STARTING
	DAD	H		;ADDR OF NEW ENTRY.
	DAD	H
	DAD	H
	DAD	D
	XCHG
	LXI	H,ERSTAT
	LXI	B,07H
	LDIR
	LXI	H,ERRCNT	;INCREMENT ERROR COUNT.
	INR	M
	RNZ
	LXI	D,BUFFUL
	CALL	PRTMSG
	RST	6
	.page
	.sbttl	'crlf and various hex printings'
;
;
CRLF:	MVI	C,0DH
	CALL	CONOUT
	MVI	C,0AH
	JMP	CONOUT	;RET FROM CONOUT
;
SPRTHLM:			;SP PRT (HL)(M)
	MOV	A,M
	PUSH	PSW		;SAVE (M)
	CALL	PRTHL
	POP	PSW
	JMPR	SPRTHEX
PRTHL:	PUSH	H
	MOV	A,H
	CALL	SPRTHEX
	POP	H
	MOV	A,L
	JMPR	PRTHEX
TPRTHEX:		;TAB AND PRINT (A) IN HEX
	PUSH	PSW
	MVI	C,9
	CALL	CONOUT
	JMPR	SPH2
;
CPRTHEX:		;CRLF AND PRINT (A) IN HEX
	PUSH	PSW
	CALL	CRLF
	JMPR	SPH2
SPRTHEX:		;SPACE AND PRINT (A) IN HEX
	PUSH	PSW
	MVI	C," "
	CALL	CONOUT
SPH2:	POP	PSW
PRTHEX:	PUSH	PSW
	RAR
	RAR
	RAR
	RAR
	CALL	PRTNBL
	POP	PSW
PRTNBL:	ANI	0FH	;PRINT NIBBLE
	ADI	030H
	CPI	03AH
	JRC	SML
	ADI	7
SML:	MOV	C,A
	CALL	CONOUT
	RET
	.page
	.sbttl	'seektest'
;
SEEKTEST:
	lda	sizeflag
	cpi	false
	jrz	..dontchangesize
	out	clrport	;reset hard disk controller
	call	seldisk
	rnz		;return if error 
..dontchangesize:
	CALL	CLREB		;CLEAR ERR BUF
	LXI	D,SKMSG
	CALL	PRTMSG
	CALL	CONIN
	CPI	"1"
	JRZ	LONGSK
	CPI	"2"
	JRZ	LSK2
ST2:	CALL	CHKSTAT
	CALL	RANDOM
	LXI	H,NTRACK
	CMP	M
	JRNC	ST2
	STA	TRACK
	CALL	RANDOM
	LXI	H,HEADMASK
	ANA	M
	ANI	7		;TAKE OFF FIXED BIT
	STA	HEAD
ST3:	CALL	RANDOM
	ANI	01FH
	JRZ	ST3		;0 NOT LEGAL SECT
	LXI	H,NSECTOR
	CMP	M
	JP	ST3
	STA	SECTOR
	MVI	A,3
	STA	RETRYS
	CALL	ABSREAD
	JRZ	ST2
	MVI	B,4		;TEST CODE
	CALL	PRTERR
	JMPR	ST2
;
LONGSK:			;LONG SEEK TEST
..2:	CALL	RSTTHS
	CALL	RDCHK
	CALL	CHKSTAT
	LDA	NTRACK
	DCR	A		;TO MAX TRACK NO
	STA	track
	CALL	RDCHK
	JMPR	..2
LSK2:	XRA	A
	STA	CURTRK
..3:	CALL	RSTTHS
	CALL	RDCHK
	CALL	CHKSTAT
	LXI	H,CURTRK
	INR	M
	LDA	NTRACK
	CMP	M
	JRZ	LSK2
	MOV	A,M
	STA	track		;NEXT TRACK
	CALL	RDCHK
	JMPR	..3
;
RDCHK:	CALL	ABSREAD
	RZ
	CALL	PST
	RET
	.page
	.sbttl	'random'
;
RANDOM:			;RET RANDOM NUM IN A
	LDA	LASTRAN
	ADI	31
	XRI	011010001B
	RRC
	STA	LASTRAN
	RET
;
LASTRAN: .BYTE	123
XRANTST:
	CALL	CLREB		;USE ERR BUF
	LXI	B,100H
	LXI	H,ERRBUF
RTL:	CALL	RANDOM
	MOV	L,A
	INR	M
	DCX	B
	MOV	A,C
	ORA	B
	JRNZ	RTL
	RST	6
	.page
	.sbttl	'setup next sector'
;
;
;
NEXTS:			;ROUTINE TO SETUP NEXT SECTOR
	LDA	NFLAG
	CPI	0FH		;IF NFLAG IS SET THEN
	MOV	C,A		;DISK IS DONE AND FIXED
	JRZ	NSS		;HEADS MUST BE DONE
	LDA	HEADMASK	;NEXT.
	ANI	4
	MVI	C,4
	JRZ	NSS		;JUMP IF 14 MB
	MVI	C,8
NSS:
	LDA	SECTOR
	INR	A
	LXI	H,NSECTOR
	CMP	M
	JRZ	NEXTS2		;JUMP IF TRACK IS DONE
	STA	SECTOR
	RET			;RET TO DO NEXT SECTOR
NEXTS2:	MVI	A,1
	STA	SECTOR		;SET SECTOR NO. TO 1
	LDA	HEAD
	INR	A		;INC. HEAD NO.
	CMP	C		;4 OR 8 OR FIXED HEADS.
	JRZ	NEXTS3		;JUMP IF CYLINDER DONE.
	STA	HEAD
	RET			;RET TO DO NEXT HEAD.
NEXTS3:	LDA	NFLAG
	CPI	0FH
	JRZ	NSDONE
	XRA	A		;SET HEAD NO. TO 0
	STA	HEAD
	LDA	TRACK
	INR	A		;INC. CYLINDER NO.
	LXI	H,NTRACK
	CMP	M
	JRNC	NEXTS4		;JMP IF ALL CYL. DONE.
	STA	TRACK
	ANI	3	;PRINT "." EYERY 4 TRACKS
	RNZ			;REMEMBER ZERO FLAG
	MVI	C,"."
	CALL	CONOUT
	XRA	A
	INR	A		;CLEAR ZERO FLAG
	RET
NEXTS4:
	LDA	HEADMASK
	ANI	8
	JRNZ	FIXHD		;JUMP IF FIXED HEADS.
NSDONE:	LXI	H,TRACK
	MVI	M,1		;START AT TRK 1
	INX	H
	MVI	M,0		;HEAD 0
	INX	H
	MVI	M,0		;SECT WILL INC FIRST
	XRA	A
	STA	NFLAG		;RESET FLAG.
	RET			;ZERO FLAG MEANS DONE
FIXHD:	MVI	A,0FH
	STA	NFLAG
	MVI	A,0FFH
	STA	TRACK
	MVI	A,8
	STA	HEAD
	RET
	.page
	.sbttl	'verify and reset track,head,sec'
;
RSTTHS:	MVI	A,0		;SET THS TO 0,0,1
	STA	TRACK
	MVI	A,0
	STA	HEAD
	MVI	A,1
	STA	SECTOR
	RET
;
VERIFY:
	call	testsetup
	rnz
	call	crlf
	CALL	RSTTHS		;SET THS TO 0,0,1
VL2:	CALL	PRTTRK
	CALL	CHKSTAT
	MVI	A,3		;three RETRYS
	STA	RETRYS
	CALL	ABSREAD		;READ DISK
	JRZ	VL
	MVI	B,1		;READ ERROR
	CALL	PRTERR
	lda	testcrcusage	;error correction
				;as user setup
	ori	021H		;MANY RETRYS
	STA	RETRYS
	CALL	ABSREAD
	JRZ	VL
	MVI	B,1
	CALL	PRTERR
VL:	CALL	NEXTS
	RZ
	JMPR	VL2
	.page
	.sbttl	'format entire disk'
;
;
FORMAT:
	out	clrport	;reset hard disk controller
	call	fndsz		;find disk size
	call	bootdisk	;select disk drive
;FORMATS THE ENTIRE DISK WITH E5'S.
;REQUIRES HDFORMAT TO BE LOADED INTO 4100 OF HDC MEM.
;
	LXI	D,FORMSG
	CALL	PRTMSG
	CALL	CONIN
	ani	5fh		;make upper case
	CPI	"Y"
	JRZ	..1
	CPI	18H		;CTL X FOR CLR
	RNZ			;BLOCKS 0 - 17
	lxi	d,mbf33		;zeroing bad sector
	call	prtmsg		;etc
	lxi	d,mbf35
	call	prtmsg
	LXI	H,formsave
	LXI	D,formsave+1
	LXI	B,17*1024
	MVI	M,0
	LDIR			;FILL buffer WITH 0
	JMPR	..DF
..1:	
	lxi	d,mbf34	;zeroing badsector table
	call	prtmsg
	lxi	d,mbf35
	call	prtmsg
	XRA	A
	STA	ERRCNT		;ERRCNT DURING SAVE
	CALL	RSTTHS		;SAVE LOW DISK
	MVI	A,5H	;five retrys,
			;no error correction
	STA	RETRYS
	LXI	D,formsave	;USE BUF 7000 TO b3FF
	MVI	B,17		;SAVE 17K
..2:	PUSH	B
	PUSH	D
	CALL	ABSREAD
	ora	a
	jrz	..readok
	push	psw
	call	prnterr
	pop	psw
..readok:
	LXI	H,ERRCNT
	ORA	M
	MOV	M,A		;SAVE ANY ERR
	CALL	NEXTS		;SETUP NEXT SECT
	LXI	H,RBUFFER
	POP	D
	LXI	B,1024
	LDIR			;MOVE 1K TO BUFF
	POP	B
	DJNZ	..2		;LOOP
	LDA	ERRCNT
	ORA	A
	jrz	..df
	MVI	A,91H
	call	PRNTERR		;PRINT IF ANY ERR
	out	clrport		;reset controller
	ret
..DF:	
	call	endingtrack
..formatall:
	LXI	H,hdformbuf ;FORMAT USER PROG HERE
	CALL	PUTUSER
	LDA	HEADMASK
	MOV	C,A		;SAVE
	ANI	7		;GET NO HEADS-1
	STA	HEAD
	MOV	A,C
	ANI	8		;GET FIXED HD BIT
	JRZ	..3
	MVI	A,0FFH		;IF FIXED HDS
..3:	STA	hhtag0
	XRA	A	
	STA	hhtag1
	XRA	A
	STA	TRACK
	INR	A
	STA	SECTOR
	LDA	SECPTRK
	STA	RETRYS
	LDA	NTRACK
	DCR	A
	STA	RSTAT
	LXI	D,BSYMSG
	CALL	PRTMSG
	MVI	A,FRMATCOM
	EI
	CALL	SETUP		;START FORMATTING.
	LXI	H,RBUFFER
	LXI	D,1
;	CALL	PREAD		;GET ERROR STATUS.
;	have inline code to do the pread
;	the  pread code has a 4 second timeout
;	whereas the format can take many minutes  to
;	occur
;
;
;
; RTN TO READ IN A BLOCK OF DATA FROM THE COMM PORT
; ENTERS WITH REGS AS FOLLOWS
; DE  - BYTE COUNT
; HL - INPUT BUFFER ADRS
;
;PREAD:
	MVI	C,hhinport
	MOV	B,E
	MOV	A,D
	ORA	B
	jRZ	..preaddone
	XRA	A
	CMP	B
	JRZ	..PRDLOOP
	INR	D
..PRDLOOP:
	IN	hhpstatus
	BIT	STAT1B,A
	JRZ	..prdloop
	INI
	JRNZ	..PRDLOOP
	DCR	D
	JRNZ	..PRDLOOP
..preaddone:

	LDA	RBUFFER
	CPI	00H
	cNZ	PRNTERR
	CALL	RSTTHS		;RESTORE 1ST 17K
	XRA	A
	STA	ERRCNT
	INR	A
	STA	RETRYS
	LXI	H,formsave
	MVI	B,17
..WL:	PUSH	B
	LXI	D,WBUFFER
	LXI	B,1024
	LDIR			;BUFF TO WBUFFER
	PUSH	H		;NEXT BUFF ADR
	CALL	ABSWRITE
	LXI	H,ERRCNT
	ORA	M
	MOV	M,A
	CALL	NEXTS
	POP	H
	POP	B
	DJNZ	..WL
	LDA	ERRCNT
	ORA	A
	jrz	..done
	MVI	A,92H
	call	PRNTERR
	out	clrport		;reset controller
	ret
..done:
	LXI	D,DONMSG
	CALL	PRTMSG		;PRINT DONE.
	CALL	RSTTHS
	CALL	ABSREAD		;GET TO TRK 0
	OUT	CLRPORT
	RET
PRNTERR:
	PUSH	PSW
	LXI	D,ERRMSG
	CALL	PRTMSG
	POP	PSW
	CALL	SPRTHEX
	ret
	.page
	.sbttl	'print track'
;
PRTTRK:
	LDA	HEAD
	MOV	B,A
	LDA	SECTOR		;PRT IF BOTH=0
	DCR	A		;SEC STARTS AT 1
	ORA	B
	RNZ
	MVI	C,0DH		;CR
	CALL	CONOUT
	LDA	TRACK
	JMP	PRTHEX	;RET FROM THERE
	.page
	.sbttl	'setup command buffer'
;
;
; SETUP COMMAND BUFFER
;
SETUP:
	STA	combufloc
	LXI	H,TRACK
	LXI	D,combufloc+1
	LXI	B,7
	LDIR

	lxi	x,oldsec
	lxi	y,seccount
	lda	seconds
	mov	0(x),a
	mvi	0(y),0
;
;SEND REQUEST TO SEND
LOOP1:
	IN	hhinport		;CLEAR IF OUT OF SYNC
	IN	hhpstatus
	BIT	STAT1A,A
	JRZ	..ready
	lda	seconds
	cmp	0(x)
	jrz	loop1
	mov	0(x),a
	inr	0(y)
	mov	a,0(y)
	cpi	20
	jrnz	loop1
	lxi	d,mbf25	;time out in handshaking
	call	prtmsg
	rst	6	;return to zdti
..ready:
	MVI	A,REQTOSEND
	OUT	hhoutport
LOOP2:
	IN	hhpstatus
	BIT	STAT1B,A
	JRnZ	..ready
	lda	seconds
	cmp	0(x)
	jrz	loop2
	mov	0(x),a
	inr	0(y)
	mov	a,0(y)
	cpi	20
	jrnz	loop2
	lxi	d,mbf25	;time out in handshaking
	call	prtmsg
	rst	6	;return to zdti
..ready:
	IN	hhinport
	CPI	CLEAR
	JRNZ	LOOP1
	LXI	D,8
	LXI	H,combufloc
	CALL	PWRITE
	RET
	.page
	.sbttl	'send comd 40 to cont and read til err'
;
SEND40:	MVI	A,40H		;SEND COMD 40 TO CONT
	CALL	SETUP
	RET
;
RDTHS:		;READ CONTINUOUSLY THS TILL ERR
	CALL	CLREB
..2:	CALL	CHKSTAT
	CALL	ABSREAD
	JRZ	..2
TFIN:	CALL	PST
	CALL	CSLINE
	RET
;
TSTTHS:		;TEST CONTINUOUSLY THS TILL ERR
	CALL	CLREB
..2:	CALL	CHKSTAT
	CALL	SETWCP		;GET WORST PAT
	CALL	ABSWRITE
	CALL	ABSREAD
	JRZ	..2
	JMPR	TFIN
	.page
	.sbttl	'abs write and read'
;
ABSRST:	CALL	ABSREAD
PST:				;DUMP STATUS
	LXI	H,statbuffer
PST2:	PUSH	H
	MOV	A,M
	CALL	SPRTHEX		;PRINT BYTE
	POP	H
	INR	L		;PRINT THRU 17FFH
	MOV	A,L
	ANI	0FH
	JRNZ	PST2
	JMP	CRLF		;RET FROM THERE
;
ABSWST:	CALL	ABSWRITE
	JMPR	PST
;
;
ABSWRITE:
	IN	hhinport		;CLEAR INTERFACE
	EI
	MVI	A,ABSWRTCOMM
	CALL	SETUP
	LXI	H,WBUFFER
	LXI	D,1024
	CALL	PWRITE
	LXI	H,STATBUFFER
	LXI	D,8
	JMPR	ABSTAT
;
ABSREAD:
	IN	hhinport		;CLEAR INTERFACE
	EI
	MVI	A,ABSRDCOMM
GET1K:	CALL	SETUP
	LXI	H,STATBUFFER
	LXI	D,1024+8	;GET STAT + DATA
ABSTAT:	CALL	PREAD
	LDA	STATBUFFER+7
	ORA	A
	RET
	.page
	.sbttl	'bad sector stuff'
;
GETBST:
	lxi	d,mbf32
	call	prtmsg	;tell them only gods should
			;proceed 
	lda	sizeflag
	cpi	false
	jrz	..dontchangesize
	out	clrport	;reset hard disk controller
	call	seldisk	;boot disk desired
	rnz			;return if error
..dontchangesize:
	call	selbst		;select track,head sec
				;for bad sector table
;
..2A:	CALL	ABSREAD
;**********************************ERR CHECK
..2b:	LXI	D,BSTHDG
	CALL	PRTMSG
	LXI	H,RBUFFER
..3:	MOV	A,M
	CPI	0E5H
	JRZ	..4
	CPI	0
	JRZ	..5
	MOV	C,A
	INX	H
	MOV	B,M
	INX	H
	MOV	A,M		;THS NOW IN C,B,A
	INX	H
	PUSH	H
	PUSH	B
	CALL	CPRTHEX
	POP	B
	PUSH	B
	MOV	A,B
	CALL	TPRTHEX
	POP	B
	MOV	A,C
	CALL	TPRTHEX
	POP	H
	JMPR	..3
;	zero the bad sector table in memory
..4:	lxi	h,rbuffer
	mvi	m,0
	lxi	d,rbuffer + 1
	lxi	b,1023
	ldir
	JMP	..2b
..5:	PUSH	H
	LXI	D,WBUFFER
	LXI	H,RBUFFER
	LXI	B,1024
	LDIR
	POP	H
	LXI	D,WBUFFER-RBUFFER
	DAD	D
..8:	PUSH	H		;POINTER INTO WRT BUF
	LXI	D,NBSTMSG
	CALL	PRTMSG
	CALL	GETHEX
	CPI	0FFH
	JRZ	..6
	CPI	0FEH
	JRNZ	..9
	POP	H		;CLEAN
	JMPR	..4
..9:	PUSH	PSW
	LXI	D,NHMSG
	CALL	PRTMSG
	CALL	GETHEX
	PUSH	PSW
	LXI	D,NSMSG
	CALL	PRTMSG
	CALL	GETHEX
	MOV	C,A
	POP	PSW
	MOV	B,A
	POP	PSW
	POP	H
	MOV	M,C
	INX	H
	MOV	M,B
	INX	H
	MOV	M,A
	INX	H
	JMPR	..8
..6:	POP	H		;CLEAN STACK
;	CALL	SORTBST		;NICE TO SORT
	CALL	ABSWRITE
;	JRNZ	BWERR		;****************************
	OUT	CLRPORT
	CALL	CRLF
	RET

selbst:
	CALL	RSTTHS		;select BAD SEC TBL
	MVI	B,16		;
..2:	PUSH	B
	CALL	NEXTS		;GET TO BLOCK 16
	POP	B
	DJNZ	..2
	ret

	.page
	.sbttl	'read and disp continuous'
;
RDISPC:	CALL	READISP		;RD N DISP CONTINUOUS
	CALL	NEXTS
	CALL	CHKSTAT
	JMP	RDISPC
;
READISP: CALL	ABSRST
DISPRB:	LXI	H,rbuffer
..3:	PUSH	H
	CALL	PRTHL
	POP	H
	PUSH	H
	CALL	PST2
	POP	H
	MVI	A,16
	ADD	L
	MOV	L,A
	CPI	0
	JRNZ	..3
	RET
	.page
	.sbttl	'read 1k block'
;
READ1K:
	MVI	A,15H		;READ 1K BLK
	CALL	GET1K
	JMP	DISPRB

rstloaduser:
	out	clrport	;reset controller 
			;to get access to rom routines
LOADUSER:
	EI
	MVI	A,LDUSER
	CALL	SETUP
	LXI	H,WBUFFER
	LXI	D,300H
	CALL	PWRITE
	RET
	.page
	.sbttl	'pread and pwrite'
;
;
; RTN TO READ IN A BLOCK OF DATA FROM THE COMM PORT
; ENTERS WITH REGS AS FOLLOWS
; DE  - BYTE COUNT
; HL - INPUT BUFFER ADRS
;
PREAD:
	lxi	x,oldsec
	lxi	y,seccount
	lda	seconds		;seconds from time
	mov	0(x),a
	mvi	0(y),0		;zero seconds passed count
	MVI	C,hhinport
	MOV	B,E
	MOV	A,D
	ORA	B
	RZ
	XRA	A
	CMP	B
	JRZ	PRDLOOP
	INR	D
PRDLOOP:
	IN	hhpstatus
	BIT	STAT1B,A
	JRnZ	..pready
	lda	seconds
	cmp	0(x)	;old second
	jrz	prdloop
	mov	0(x),a	;update old second
	inr	0(y)	;increment seconds passed count
	mov	a,0(y)
	cpi	4
	jrnz	prdloop
	lxi	d,mbf23	;pread timed out
	call	prtmsg
	rst	6	;return to zdti
..pready:
	INI
	JRNZ	PRDLOOP
	DCR	D
	JRNZ	PRDLOOP
	RET
;
;
; RTN TO WRITE A BLOCK OF DATA OUT TO THE COMM PORT
; ENTERS WITH REGS AS FOLLOWS
; DE  - BYTE COUNT
; HL - ADRS OF DATA BUFFER
;
PWRITE:
	lxi	x,oldsec
	lxi	y,seccount
	lda	seconds		;seconds from time
	mov	0(x),a
	mvi	0(y),0		;zero seconds passed count
	MVI	C,hhoutport
	MOV	B,E
	MOV	A,D
	ORA	B
	RZ
	XRA	A
	CMP	B
	JRZ	PWRTLOOP
	INR	D
PWRTLOOP:
	IN	hhpstatus
	BIT	STAT1A,A
	JRZ	..pready
	lda	seconds
	cmp	0(x)	;old second
	jrz	pwrtloop
	mov	0(x),a	;update old second
	inr	0(y)	;increment seconds passed count
	mov	a,0(y)
	cpi	4
	jrnz	pwrtloop
	lxi	d,mbf24	;time out in pwrite
	call	prtmsg
	rst	6	;return to zdti
..pready:
	OUTI
	JRNZ	PWRTLOOP
	DCR	D
	JRNZ	PWRTLOOP
	RET
	.page
	.sbttl	'set interupts'
;
;
SETINT:
	.IFE	DSC,[
	LXI	H,INT1
	LXI	D,38H
	LXI	B,8
	LDIR
;
	LXI	H,INT2
	LXI	D,28H
	LXI	B,8
	LDIR
;
	IM1
	XRA	A
	OUT	60H
	MVI	A,20H
	OUT	60H
	EI
	RET
;
INT1:
	XRA	A
	OUT	60H
	MVI	A,20H
	JMPR	INT1-16
;
INT2:
	OUT	60H
	EI
	JMPR	INT2+8][
	RET]
	.page
	.sbttl	'interface test'
;
;
; INTERFACE TEST SUBROUTINE
;
;
INTTEST:
	out	clrport		;reset controller
	LXI	H,hdcitbuf		;LOAD HDCIT
	CALL	PUTUSER
;
	MVI	A,00H		;SET PATTERN
	CALL	FILLB
	CALL	TESTIT		;PERFORM TEST
	jrnz	..return
	MVI	A,0FFH		;SET PATTERN
	CALL	FILLB
	CALL	TESTIT		;PERFORM TEST
	jrnz	..return
	CALL	RANTST		;SET PATTERN
	CALL	TESTIT		;PERFORM TEST
	jrz	inttest
..return:
	out	clrport		;reset controller
	ret

LNGTH:	.BYTE	0
NMBR:	.BYTE	0
FLAG:	.BYTE	0
;	
;	returns with none zero set if user as requested
;	return to menu
;
TESTIT:
	LDA	WBUFFER		;PRINT PATTERN
	CALL	SPRTHEX
	CALL	CRLF
	MVI	A,48H		;SET LINE LENGTH
	STA	LNGTH
	MVI	A,00H		;SET TIME BETWEEN PRINTS
	STA	NMBR
COMLOOP:
	call	menureturn	;see if user wants 
	rnz			;return to menu
	MVI	A,TSTINT	;SET COMMAND
	CALL	SETUP
	LXI	H,WBUFFER
	LXI	D,400H
	EI
	CALL	PWRITE		;WRITE BLOCK TO HDC
	LXI	H,RBUFFER
	LXI	D,400H
	CALL	PREAD		;READ BLOCK FROM HDC
	MVI	A,00H
	STA	FLAG
	CALL	COMPARE		;COMPARE
	LDA	FLAG
	CPI	0FFH
	CZ	REREAD
	LXI	H,NMBR
	DCR	M
	JNZ	COMLOOP		;IF NOT TIME TO PRT $
	MVI	C,"$"
	CALL	CONOUT		;PRINT $
	LXI	H,LNGTH
	DCR	M
	JNZ	COMLOOP		;IF SAME LINE N PATTERN
	RET			;RETURN FOR NEW PATTERN

;
;	see if user wants to return to menu, non zero set
;	if so
menureturn:
	call	constat
	ora	a
	rz
	call	conin
	ani	05fh		;make upper case
	cpi	'R'
	jrnz	..nouserinput
	mvi	a,1
	ora	a		;make return non zero
	ret
..nouserinput:
	sub	a		;make return zero
	ret


;
REREAD:
	MVI	A,RREAD
	CALL	SETUP
	LXI	H,RBUFFER
	LXI	D,400H
	CALL	PREAD
	CALL	CRLF
	LXI	D,BMSG
	CALL	PRTMSG
	CALL	CMBUFF
	LXI	H,RBUFFER
	LXI	D,400H
	CALL	PREAD
	LXI	D,CMSG
	CALL	PRTMSG
	CALL	CMBUFF
	RET
CMBUFF:
	LXI	H,WBUFFER
	LXI	D,RBUFFER
	LXI	B,00H
NXLOC:	LDAX	D
	CMP	M
	JRZ	INHDB
	LXI	D,BAD
	CALL	PRTMSG
	JMP	RETRN
INHDB:	INX	H
	INX	D
	INX	B
	MOV	A,B
	CPI	04H
	JNZ	NXLOC
	LXI	D,OOD
	CALL	PRTMSG
RETRN:	CALL	CRLF
	RET
CHRTRS:	.BYTE	00H
	.page
	.sbttl	'memory test'
;
MEMTEST:
	out	clrport		;reset controller
	LXI	H,hdmemtst	;LOAD HMEMTST
	CALL	PUTUSER
	MVI	A,MTEST
	CALL	SETUP
	EI
RCHR:	LXI	H,CHRTRS
	LXI	D,01H
	CALL	PREAD
	LXI	H,CHRTRS
	MOV	C,M
	CALL	CONOUT
	call	menureturn
	jrz	rchr	;user does not want menu back
	out	clrport	;reset controller
	ret
	.page
	.sbttl	'get memory from controller'
;
;
GETMEM:
;GETMEM GETS A BLOCK OF THE HDC'S MEMORY AND PUTS
;IT IN MEMORY STARTING AT 5000H. THE STARTING 
;ADDRESS IS F000H AND THE BLOCK LENGTH IS 900H.
	LHLD	HEAD		;SAVE COMMBUFF.
	PUSH	H
	LHLD	hhtag0
	PUSH	H
	LXI	H,0F000H	;SET STARTING ADDR.	
	SHLD	HEAD
	LXI	H,0900H		;SET BLOCK LENGTH.
	SHLD	hhtag0
	PUSH	H
	MVI	A,GMEMCOM
	CALL	SETUP
	LXI	H,membuf
	POP	D
	CALL	PREAD		;GET BLOCK
	POP	H		;RESTORE COMMBUFF.
	SHLD	hhtag0
	POP	H
	SHLD	HEAD
	RET

	.page
	.sbttl	'disk select'
;
;	seldisk returns zero flag set if successful
;	nonzero if some error
;
seldisk:	
	lxi	d,mbf1
	call	whichvol
	sta	volsel
	sta	head
	xra	a
	sta	track
	mvi	a,'M'	;let frimware no we're aware
			;of multi drive capability
	sta	retrys
	mvi	a,cpmselect
	call	setup
	lxi	h,sectotimeout	;set up timeout time
	mvi	m,10	;ten seconds to time out
selstat:			;entry point for use elsewhere
				;of status getting
	call	crlf
	lda	seconds
	sta	oldsec
	mvi	a,0		;zero count of seconds waited
	sta	seccount
..waitloop:
	in	hhpstatus
	bit	stat1b,a
	jrnz	..donewait
	lda	seconds
	lxi	h,oldsec
	cmp	m
	jrz	..waitloop
	sta	oldsec
	lda	seccount
	inr	a
	sta	seccount
	lxi	h,sectotimeout
	cmp	m
	jrz	..timedout
	jmpr	..waitloop
..timedout:
	lxi	d,mbf16		;timed out
	call	prtmsg
	out	clrport		;reset controller
	mvi	a,1
	ora	a		;set non zero flag
	ret
..donewait:
	lxi	h,statbuffer	;go get status
	lxi	d,commsize
	call	pread
	call	pst
	lda	statbuffer+7	;error byte
	ora	a
	jrz	..switchinfo
	lxi	d,mbf31
	call	prtmsg
	lda	statbuffer+7
	ora	a
	ret
;
;	switch disk size info
;
..switchinfo:
	lda	volsel
	slar	a
	slar	a
	slar	a
	slar	a
	slar	a	;*32
	mov	e,a
	mvi	d,0
	lxi	x,volinfo
	dadx	d	;x reg points to vol info
	mov	a,vlipresent(x)
	cpi	true
	jrz	..present	;volume present
	lxi	d,mbf17		;volume not present
	call	prtmsg
	mvi	a,1
	ora	a		;set nonezero for error
	ret
..present:
	mov	a,vlitracks(x)
	sta	ntracks
	mov	a,vlitype(x)
	sta	secptrk
	inr	a
	sta	nsector
	mov	a,vlisize(x)
	sta	headmask

	xra	a	;set zero flag for success
	ret



	.page
	.sbttl	'disk boot'
bootdisk:	
	out	clrport		;reboot controller for 
	lxi	d,mbf2
	call	whichvol
	sta	volsel
	jrz	..setup  ;reset booted vol zero
				;already
	sta	track
	mvi	a,bootunit
	call	setup
..setup:jmp	setupsectors	;tell rom number of
			;sectors per track

	.page
	.sbttl	'error number and buffer descriptions'
errdiscription:
	lxi	d,mbf4
	call	prtmsg
	ret

bufferdiscription:
	lxi	d,mbf6
	call	prtmsg
	ret
	
	.page
	.sbttl	'get unit info'
;
;	return with zero flag set if successful,
;	nonzero if failure
;
getvolinfo:
	mvi	a,unitinfo
	call	setup
	lxi	d,mbf15		;waiting for volume info
	call	prtmsg
	lda	seconds
	sta	oldsec
	mvi	a,0		;zero count of seconds waited
	sta	seccount
..waitloop:
	in	hhpstatus
	bit	stat1b,a
	jrnz	..donewait
	lda	seconds
	lxi	h,oldsec
	cmp	m
	jrz	..waitloop
	sta	oldsec
	lda	seccount
	inr	a
	sta	seccount
	cpi	10
	jrz	..timedout
	call	sprthex		;print second count
	jmpr	..waitloop
..timedout:
	lxi	d,mbf16		;timed out
	call	prtmsg
	out	clrport		;reset controller
	mvi	a,01
	ora	a		;set non zero flag
				;for failure
	ret
..donewait:
	call	crlf
	lxi	h,statbuffer	;go get status
	lxi	d,commsize
	call	pread
	call	pst
;
;	check that command successful
;
	lxi	h,statbuffer+7	;error byte
	mov	a,m
	ora	a
	rnz			;non zero is error

	lxi	h,membuf
	lxi	d,vlibufsiz*4
	call	pread		;get info
	lxi	h,membuf
	lxi	d,volinfo
	lxi	b,vlibufsiz*4
	ldir			;put into buffer

;
;	print rom and firmware version
;
	lxi	d,mbf9	;rom version
	call	prtmsg
	lda	statbuffer+1	;rom version
	adi	'0'
	mov	c,a
	call	conout
	mvi	c,'.'
	call	conout
	lda	statbuffer+2	;rom revision
	adi	'0'
	mov	c,a
	call	conout

	lxi	d,mbf10		;firmware version
	call	prtmsg
	lda	statbuffer+3	;firmware version
	adi	'0'
	mov	c,a
	call	conout
	mvi	c,'.'
	call	conout
	lda	statbuffer+4	;firmware revision
	adi	'0'
	mov	c,a
	call	conout
	call	crlf

;
;	print volume info
;
	mvi	a,0
	sta	curvol
	lxi	x,membuf	;point to vol info
printvolloop:
	lxi	d,mbf11
	call	prtmsg
	lda	curvol
	call	prthex
	mvi	c,':'
	call	conout
	mov	a,vlipresent(x)
	cpi	true
	jrz	..ispresent
	lxi	d,mbf12		;volume not present
	call	prtmsg
	mov	a,vliopenerr(x)
	call	prthex
	jmpr	..nextvol
..ispresent:
	lxi	d,mbf13		;tracks,sectors,headmask
	call	prtmsg
	mov	a,vlitracks(x)
	call	sprthex
	mov	a,vlitype(x)
	call	sprthex
	mov	a,vlisize(x)
	call	sprthex
	lxi	d,mbf14		;label
	call	prtmsg
	mov	c,vlivollabel(x)
	call	conout
	mov	c,vlivollabel+1(x)
	call	conout
	mov	c,vlivollabel+2(x)
	call	conout
	mov	c,vlivollabel+3(x)
	call	conout
	mov	c,vlivollabel+4(x)
	call	conout
	mov	c,vlivollabel+5(x)
	call	conout
	mov	c,vlivollabel+6(x)
	call	conout
	mov	c,vlivollabel+7(x)
	call	conout
	mov	c,vlivollabel+8(x)
	call	conout
	mov	c,vlivollabel+9(x)
	call	conout
..nextvol:
	lxi	d,vlibufsiz
	dadx	d
	lda	curvol
	inr	a
	sta	curvol
	cpi	maxvol+1
	jc	printvolloop

	call	crlf		
	xra	a		;set zero flag for success
	ret

	.page
	.sbttl	'multiple drive seek test'
multseek:
	lxi	d,mbf29		;e5 only y or n
	call	prtmsg
	call	conin
	ani	5fh	;upper case
	cpi	'Y'
	jrz	..e5only
	cpi	'N'
	jrnz	multseek
	mvi	a,false
	sta	e5only
	jmpr	..setup
..e5only:
	mvi	a,true
	sta	e5only
..setup:
	out	clrport	;reset hard disk controller
	call	getvolinfo
	rnz			;volinfo failure
	CALL	CLREB		;CLEAR ERR BUF
ms2:	CALL	CHKSTAT
	call	random
	ani	3		;select a disk
	sta	volsel		;selected volume
	call	infoswitch	;switch info to current
				;vol
	jrnz	ms2		;vol not present
ms25:	CALL	RANDOM
	mov	b,a		;use only bottom
	ldar			;bit of psuedo random
	bit	0,b		;random track from 
	jrz	..zero		;refresh register
	set	7,a
	jmpr	..set
..zero:	res	7,a
..set:
	LXI	H,NTRACK
	CMP	M
	JRNC	ms25
	ora	a
	jrz	ms25		;no reads from track
				;zero
	STA	TRACK
	CALL	RANDOM
	LXI	H,HEADMASK
	ANA	M
	ANI	7		;TAKE OFF FIXED BIT
	STA	HEAD
ms3:	CALL	RANDOM
	ANI	0FH
	JRZ	ms3		;0 NOT LEGAL SECT
	LXI	H,NSECTOR
	CMP	M
	JP	ms3
	STA	SECTOR
	MVI	A,3
	STA	RETRYS
	CALL	ABSREAD
	JRnZ	..prterr
	lda	e5only		;see if data needs
				;testing for e5's
	cpi	true
	jrnz	ms2
	lxi	h,rbuffer
	lxi	b,1024
..e5loop:
	mov	a,m
	cpi	0e5h
	jrnz	..baddata
	inx	h
	dcx	b
	mov	a,b
	ora	c
	jrnz	..e5loop
	jmpr	ms2		;go on
..baddata:
	lxi	d,mbf30		;bad data detected
	jmp	prtmsg		;return to user
..prterr:
	MVI	B,4		;TEST CODE
	CALL	PRTERR
	JMPR	ms2

;
;	info switch changes ntracks,nsector,
;	and headmask to correct for vol passed
;	in reg a.  it also selects the unit
;	if the unit is not present it returns
;	with non zero flag set
;
infoswitch:
	call	switch
	rnz

	lda	volsel
	sta	head
	xra	a
	sta	track
	mvi	a,'M' ;let it know we think its a multi
			;drive controller firmware
	sta	retrys
	mvi	a,cpmselect
	call	setup
			;get status back from select
	lxi	h,statbuffer	;go get status
	lxi	d,commsize
	call	pread
	ret
	.page
	.sbttl	'cpm 128 byte read and write'
cpmr128:
	mvi	a,cpmread
	call	setup
	call	crlf
	lxi	h,statbuffer	;go get status
	lxi	d,commsize
	call	pread
	call	pst		;print status
	lda	statbuffer+7	;error return
	ora	a
	rnz			;dont read buffer if bad
	lxi	h,rbuffer
	lxi	d,128
	call	pread		;read the cpm sector
	ret

cpmw128:
	mvi	a,cpmwrite
	call	setup

	lxi	h,wbuffer
	lxi	d,128
	call	pwrite		;write the cpm sector
	call	crlf
	lxi	h,statbuffer	;go get status
	lxi	d,commsize
	call	pread
	call	pst		;print status
	ret
	.page
	.sbttl	'multiple drive write test'
multwrite:
	out	clrport	;reset hard disk controller
	call	okdestroy
	RNZ
	call	getvolinfo
	rnz			;volinfo failure
	CALL	CLREB		;CLEAR ERR BUF
mw2:	CALL	CHKSTAT
	call	setwcp	;fill buffer with worst case
	call	random  ;pattern
	ani	3		;select a disk
	sta	volsel		;selected volume
	call	infoswitch	;switch info to current
				;vol
	jrnz	mw2		;vol not present
mw25:	CALL	RANDOM
	LXI	H,NTRACK
	CMP	M
	JRNC	mw25
	STA	TRACK
	CALL	RANDOM
	LXI	H,HEADMASK
	ANA	M
	ANI	7		;TAKE OFF FIXED BIT
	STA	HEAD
mw3:	CALL	RANDOM
	ANI	0FH
	JRZ	mw3		;0 NOT LEGAL SECT
	LXI	H,NSECTOR
	CMP	M
	JP	mw3
	STA	SECTOR
	MVI	A,81h		;read after write
	STA	RETRYS
	CALL	ABSwrite
	JRZ	mw2
	MVI	B,4		;TEST CODE
	CALL	PRTERR
	JMPR	mw2

	.page
	.sbttl	'flush controller buffers'
doflush:
	mvi	a,flush
	call	setup
	call	crlf
	lxi	h,statbuffer
	lxi	d,commsize
	call	pread
	call	pst
	ret

	.page
	.sbttl	'multi volume full test'
voltest:
	out	clrport		;reset controller
	call	getvolinfo
	rnz			;vol info failure
	CALL	CLREB
	call	okdestroy
	rnz
;
;	ask user which volume to start test on
;
..vtselect:
	lxi	d,mbf18
	call	whichvol
;
;	now loop testing all volumes
;
vtloop:
	call	vtswitch
	jrnz	..notpresent
	lxi	d,mbf7
	call	prtmsg		;tell em which vol
	lda	volsel
	call	sprthex		;vol number
	call	testcycle
..nextvol:
	lda	volsel
	inr	a
	cpi	maxvol+1
	jrc	vtloop
	xra	a		;back to zero
	jmpr	vtloop
..notpresent:			;tell them volume not 
				;present, skipping test
	call	crlf
	lda	volsel
	call	sprthex
	lxi	d,mbf19
	call	prtmsg		;volume not present,skipping test
	jmpr	..nextvol
;
;	ask if ok to destroy data on disk, return 
;	zero if ok, none zero if not ok
;
okdestroy:
	LXI	D,mbf5
	CALL	PRTMSG
	CALL	CONIN
	ani	5fh		;make upper case
	CPI	"Y"
	ret

;
;	which vol is passed a prompt pointer
;	in d register and repeately prompts
;	user until a 0-3 is entered, then
;	returns the binary form in a reg
;
whichvol:
	push	d		;save promt pointer
	call	prtmsg		;enter volume to start test with
	call	conin
	pop	d		;restore promt pointer
	cpi	'0'
	jrc	whichvol	;out of range
	cpi	'4'
	jrnc	whichvol
	sui	'0'		;convert to binary from ascii
	ret

;
;	switch volume info, return none zero if volume
;	not present, zero if present
;
switch:
	sta	volsel
	slar	a
	slar	a
	slar	a
	slar	a
	slar	a	;*32
	mov	e,a
	mvi	d,0
	lxi	x,volinfo
	dadx	d	;x reg points to vol info
	mov	a,vlipresent(x)
	cpi	true
	rnz		;volume not present
	mov	a,vlitracks(x)
	sta	ntracks
	mov	a,vlitype(x)
	sta	secptrk
	inr	a
	sta	nsector
	mov	a,vlisize(x)
	sta	headmask
	sub	a	;set zero flag for success
	ret
;
;	switch volume info and boot selected unit
;
vtswitch:
	call	switch
	rnz
;
;	now select volume to work on
;
	out	clrport		;reset controller
	lda	volsel
	sta	head	;select 
	mvi	a,0
	sta	track	;partition
	mvi	a,'M'
	sta	retrys	;let firmware know we know
			;about multi volumes
	mvi	a,cpmselect
	call	setup
	lxi	h,sectotimeout	;setup timeout time
	mvi	m,100	;one hundred seconds
	call	selstat
	rnz
	call	bootselected
;
;	restore special controller program
;
	LXI	H,hdcitbuf		;USER PROGRAM HERE
	CALL	PUTUSER
	CALL	NSDONE		;INIT T,H,S
	sub	a		;set zero flag to show success
	ret
	.page
	.sbttl	'size set and default'
;
;	to default size, set sizeflag to true, causing
;	sizes to be read from disk firmware
;
sizedefault:
	mvi	a,true
	sta	sizeflag
	ret

;
;	to set size call find size and set size flag
;	to false so size info not reset from firmware
;	for most functions
;
sizeset:
	mvi	a,false
	sta	sizeflag
	lxi	d,mbf22
	call	prtmsg		;NOTE: will not 
				;automatically reset
	call	fndsz		;prompt user for size
	ret

	.page
	.sbttl	'setup number of sectors'
;
;	this routine will setup the rom to know the
;	correct number of sectors for the disk type
;	when doing things such as format
;
setupsectors:
	lda	secptrk	;sectors per track
	sta	savsecptrk
	mvi	a,lduser	;load user program
	call	setup
	lxi	h,setupaction
;put action to controller
	lxi	d,300h	;length of user program
	call	pwrite
	jmp	send40	;trigger action
;
;	this portion of the program gets downloaded
;	to the hard disk controller
;
setupaction:
	.byte	3eh	;mvi a,
savsecptrk:
	.blkb	1
	sta	disktype
	jmp	gogetcommand

	.page
	.sbttl	'assign partition'
;
;	do a partition assign.  name and password must
;	be entered in namepass before doing so
;
doassign:
	lxi	d,mbf27	;tell them they should have 
			;already entered name and password
	call	prtmsg
	mvi	a,assign
	call	setup
	lxi	d,14	;length of name and password
	lxi	h,namepass
	call	pwrite
	lxi	h,statbuffer
	lxi	d,commsize
	call	pread
	call	pst
	ret

	.page
	.sbttl	'test crc circuitry'
;
;	test crc circuitry by forcing a crc error
;	with firmware command and then reading.
;	before trashing put data into write buffer
;	and write out at completion of test
;
docrctest:
	call	seldisk
	rnz
	call	..makelast
	call	absrst		;read in sector
	lxi	h,rbuffer
	lxi	d,wbuffer
	lxi	b,400h		;length of sector
	ldir		;copy to write buffer
	mvi	a,makecrcerror	;forces crc error
	call	setup	;on last sector of disk
	call	..makelast
	call	absrst
	jmp	abswrite	;correct error
			;return from there
;
;	set up command buffer to reference last
;	block on disk
;
..makelast:
	lda	ntrack	;number of tracks
	dcr	a
	sta	track	;last track
	lda	headmask
	sta	head	;last head
	lda	secptrk
	sta	sector
	mvi	a,3
	sta	retrys
	ret
	.page
	.sbttl	'display error history'
;
;	display error history which consists of sixty
;	entries at the end of the bad sector table.
;	the very last byte of the bst is a flag used
;	by firmware to indicate the bst needs writing
;	out. it is ignored in this routine.
;		entries are placed from the end of the
;	table down with each entry consisting of err
;	count,track,head and sector (each a byte)
;
disperrorhistory:
	lda	sizeflag
	cpi	false
	jrz	..dontchangesize
	out	clrport	;reset hard disk controller
	call	seldisk	;boot disk desired
	rnz			;return if error
..dontchangesize:
	call	selbst		;select track,head sec
				;for bad sector table
;
	CALL	ABSREAD
	lxi	d,mbf28		;error history,t,h,s,error
	call	prtmsg
	mvi	b,60	;most history which can occur
	lxi	h,rbuffer + 1024 - 2  ;ignore dirty flag
;
;	within loop get errcnt,t,h,s in regs
;	c,a,d,e for printing
;
..prtloop:
	mov	a,m
	ora	a
	jrz	..prtdone
	mov	e,a	;sector
	dcx	h
	mov	d,m	;head
	dcx	h
	mov	a,m	;track
	dcx	h
	mov	c,m	;errcount
	dcx	h	;set up for next entry
	push	h
	push	b
	push	d
	call	cprthex	;print track
	pop	d
	push	d
	mov	a,d
	call	tprthex	;print head
	pop	d
	mov	a,e
	call	tprthex	;print sector
	pop	b
	push	b
	mov	a,c
	call	tprthex	;print errcount
	pop	b
	pop	h
	djnz	..prtloop
..prtdone:
	lxi	d,donmsg	;done
	call	prtmsg
	ret		
	.page
	.sbttl	'message buffers'
mbf1:	.ascii	"\ENTER VOLUME TO SELECT (0-3):$"

mbf2:	.ascii	"\ENTER VOLUME TO BOOT (0-3):$"

mbf3:	.ascii	"\ENTER VOLUME LABEL (10 CHARS MAX):$"

mbf4:	.ascii	"\ERROR NUMBER DESCRIPTIONS \"
	.ASCII	"\11H  WRITE FAULT                 25H  HEAD INVALID"
	.ASCII	"\12H  VOLUME NOT READY            26H  SECTOR INVALID"
	.ASCII	"\13H  INTERNAL TIMEOUT            27H  VOLUME INVALID"
	.ASCII  "\14H  READ AFTER WRITE FAULT      28H  BAD FIRMWARE VERSION"
	.ASCII  "\15H  UNPROCESSED READ ERROR      29H  DUPLICATE VOLUME LABEL"
	.ASCII	"\16H  UNIT NOT PRESENT            30H  CPM MAPPING ERROR"
	.ASCII	"\17H  NO INDEX FLAG               31H  ERROR FLUSHING BUFFERS"
	.ASCII	"\18H  TIMEOUT SEEKING TRACK       32H  INVALID PARTITION SELECTED"
	.ASCII	"\19H  TIMEOUT SEEKING TRACK 0     40H  CRC,NO CORRECTION ATTEMPTED"
	.ASCII	"\20H  FIRMWARE INIT ERROR         41H  CRC,CORRECTION SUCCESSFUL"
	.ASCII	"\21H  SECTOR-1 MISSING            42H  CRC,CORRECTION FAILED"
	.ASCII	"\22H  BAD T/H/S IN HEADER         80H  UNRECOGNIZED COMMAND"
	.ASCII  "\23H  HEADER CHECKSUM ERROR       91H  ERROR SAVING 17K(HARDHELP)"
	.ASCII	"\24H  TRACK INVALID               92H  ERROR RESTORING 17K(HARDHELP)"
	.ASCII	"$"

mbf5:	.ASCII	"THIS ROUTINE DESTROYS DATA ON THE DISK.\"
	.ASCII	"DO YOU WISH TO CONTINUE"
	.byte	questionmark
	.ascii	" (Y OR N) $"

mbf6:
	.ASCII	"\BUFFER LOCATIONS AND DESCRIPTIONS\"
	.ASCII	"\2400H  COMMAND BUFFER"
	.ASCII	"\2408H  PARTITION NAME AND PASSWORD"
	.ASCII	"\2700H  WRITE BUFFER"
	.ASCIÉ  "\2BF8È  STATUÓ BUFFER"
	.ASCII	"\2C00H  READ BUFFER"
	.ASCII	"\3000H  HDCIT CODE"
	.ASCII  "\3100H  FORMAT CODE"
	.ASCII  "\3300H  MEMTST CODE"
	.ASCII  "\4100H  FIRMWARE CODE"
	.ASCII  "\5000H  MEMORY FROM CONTROLLER BUFFER"
	.ASCII  "\6000H  ERROR BUFFER"
	.ASCII	"\7000H  BUFFER TO SAVE 17K WHEN FORMATTING"
	.ASCII	"\$"

mbf7:	.ascii	"\VOLUME TESTING IS:$"

mbf9:	.ascii	"\ROM VERSION: $"

mbf10:	.ascii	"\FIRMWARE VERSION: $"

mbf11:	.ascii	"\INFO FOR $"

mbf12:	.ascii	" VOLUME NOT PRESENT, ERROR IN OPEN = $"

mbf13:	.ascii	" TRACKS,SECTORS,HEAD MASK :$"

mbf14:	.ascii	" LABEL: $"

mbf15:	.ascii	"\WAITING FOR VOLUME INFO$"

mbf16:	.ascii	"\TIMED OUT \$"

mbf17:	.ascii	"\VOLUME NOT PRESENT \$"

mbf18:	.ascii	"\ENTER VOLUME TO START TEST WITH : $"

mbf19:	.ascii	" VOLUME NOT PRESENT, SKIPPING TEST \$"

mbf20:	.ascii	"\ENTER NUMBER OF TRACKS(IN HEX),CR FOR DEFAULT:$\"

mbf21:	.ascii	"\USE ERROR CORRECTION (Y OR N):$"

mbf22:	.ascii	"\NOTE: AUTOMATIC DISK RESETS WILL NOT OCCUR$"

mbf23:	.ascii	"\TIMED OUT IN PREAD$"

mbf24:	.ascii	"\TIMED OUT IN PWRITE$"

mbf25:	.ascii	"\TIMED OUT IN HANDSHAKING$"

mbf26:	.ascii	"\ZERO IS INVALID NUMBER OF TRACKS$"

mbf27:	.ascii	"\ENTER NAME AND PASSWORD IN NAMEPASS BUFFER BEFORE DOING ASSIGN$"

mbf28:	.ascii	"\\ERROR HISTORY"
	.ASCII	"\TRACK,HEAD,SECTOR,ERROR COUNT, ALL IN HEX$"

mbf29:	.ascii	"\E5 ONLY (Y OR N):$"

mbf30:	.ascii	"\NON E5 DATA DETECTED$"

mbf31:	.ascii	"\BAD VOLUME SELECT$"

mbf32:	.ascii	"\\DO NOT MODIFY BAD SECTOR TABLE"
	.ASCII	" WITHOUT KNOWLEDGE OF YOUR TASK\"
	.ascii	"AND OF ITS CONSEQUENCES(consult DMS Technical Guide)$"

mbf33:	.ascii	"\ZEROING 17K$"

mbf34:	.ascii	"\SAVING 17K$"

mbf35:	.ascii	" INCLUDING FIRMWARE,BAD SECTOR"
	.ASCII	" AND ALLOC TABLES$"

;
	.ifn	dsc,[
MENU:	.BYTE	"\",LF
	.ASCII	"SELECT ONE OF THE FOLLOWING FUNCTIONS"
	.BYTE	"\",LF
	.ASCII	"0 - ACCESS DIAGNOSTIC ROUTINES (MUST BE\"
	.ASCII	"    EXECUTED BY A>DDT HARDHELP.COM)\"
	.ASCII	"1 - FORMAT\"
	.ASCII	"2 - INITIALIZE CONTROLLER FIRMWARE\"
	.ASCII	"3 - DISPLAY/ADD TO BAD SECTOR TABLE\"
	.ASCII	"\ENTER 0,1,2 OR 3 - "
	.BYTE	DLR	]

VERMSG:	.ASCII	"DMS HARD DISK UTILITY PROGRAM VER DSC"
	.BYTE	32H+DSC
	.BYTE	20H,30H+VERSION,".",30H+REVISION,30H+XVISION
	.BYTE	20H,"\",DLR
LOGMSG:	.ASCII	"\THE FOLLOWING ENTRY POINTS ARE IMPLEMENTED:\"
	.ASCII	"100H  PRINT THIS MESSAGE                154H  READ AND DISPLAY\"
	.ASCII	"104H  SETUP INTERRUPTS FOR DSC2         158H  GET BAD SECTOR\"
	.ASCII	"108H  RESET HDC                         15CH  DISPLAY ERROR HISTORY\"
	.ASCII	"10CH  ABSOLUTE SECTOR READ              160H  COMPARE\"
	.ASCII	"110H  ABSOLUTE SECTOR WRITE             164H  CPM VOLUME/PARTITION SELECT\"
	.ASCII	"114H  VERIFY READ ENTIRE VOLUME         168H  BOOT VOLUME\"
	.ASCII	"118H  FORMAT ENTIRE VOLUME              16CH  ERROR NUMBER DESCRIPTION\"
	.ASCII	"11CH  LOAD HDC RAM PROGRAM              170H  GET VOLUME INFO\"
	.ASCII	"120H  RUN WRITE, READ, COMPARE TEST     174H  MULTI VOLUME SEEK TEST\"
	.ASCII	"124H  RUN SEEK TEST                     178H  CPM 128 BYTE READ\"
	.ASCII	"128H  ASSIGN PARTITION                  17CH  MULTI VOLUME RANDOM WRITE TEST\"
	.ASCII	"12CH  INITIALIZE FIRMWARE FROM 4100H    180H  CPM 128 BYTE WRITE\"
	.ASCII	"130H  RUN INTERFACE TEST                184H  BUFFER LOCATIONS/DESCRIPTIONS\"
	.ASCII	"134H  RUN HDC MEMORY TEST               188H  FLUSH CONTROLLER BUFFERS\"
	.ASCII	"138H  GET HDC MEMORY BLOCK              18CH  MULTI VOLUME READ/WRITE TEST\"
	.ASCII	"13CH  REPEAT READ THS                   190H  SET DISK SIZE\"
	.ASCII	"140H  REPEAT TEST THS                   194H  DEFAULT DISK SIZE(FROM FIRMWARE)\"
	.ASCII	"144H  SEND COMMAND 40H TO CONTROLLER\"
	.ASCII	"148H  TEST CRC CIRCUITRY\"
	.ASCII	"14CH  NET 1K READ (DO NOT USE)\"
	.ASCII	"150H  READ DISPLAY CONTINUOUS\$"
ERRFMT:	.ASCII	"-TYPE(0=WRT,1=RD,2=COMP),ERROR,"
	.ASCII	"TRK,HD,SEC,TEST BYTE,VOL\$"
BSTHDG:	.ASCII	"\\DEFECTIVE SECTORS"
	.ASCII	"\TRACK, HEAD, SECTOR, ALL IN HEX$"
NBSTMSG: .ASCII	"\\ADD NEW DEFECTIVE SECTOR"
	.ASCII	"\TRACK (FF TO STOP, FE TO CLEAR BAD SECTOR TABLE AND ERROR HISTORY) - $"
NHMSG:	.ASCII	"\HEAD - $"
NSMSG:	.ASCII	"\SECTOR - $"

GHERMSG: .BYTE	7,questionmark,"\",DLR

BSPSBSP: .BYTE	7,8,20H,8,DLR	;BELL,BSP,SP,BSP

;
INITMSG: .ASCII	"\FIRMWARE LOAD SUCCESSFUL\$"
IERRMSG: .ASCII	"ERROR ENCOUNTERED\$"
;
IUMSG:	.BYTE	"\",LF
	.ASCII	"LOADING FIRMWARE VERSION"
	.BYTE	DLR
SIZEMSG: 
	.ASCII	"\\1 = 11 MB\"
	.ASCII	"2 = 23 MB\"
	.ascii	"4 = 46 MB\"
	.ASCII	"3 = 14 MB\"
	.ASCII	"B = 14 MB WITH FIXED HEADS\"	
	.ASCII	"7 = 28 MB\"
	.ASCII	"F = 28 MB WITH FIXED HEADS\"
	.ASCII	"ENTER VOLUME SIZE(1,2,4,3,7,B OR F)- $"

SUMMSG:	.ASCII	"DATA PATTERN,TRACK,HEAD,SECTOR,LOOPCNT,"
	.ASCII	"ERRCNT $"

;
CEMSG:	.ASCII	"COMPARE ERROR AT $"

;
BUFFUL:	.ASCII	"ERROR BUFFER FULL $"

;
SKMSG:	.BYTE	"\"
	.ASCII	"1-SEEK 0, MAX\"
	.ASCII	"2-SEEK 0, INCREMENTING TRACK\"
	.ASCII	"3-RANDOM SEEK\"
	.ASCII	"ENTER 1,2,OR 3-$"

FORMSG:
	.BYTE	"\",LF,LF
	.ASCII	"HARD DISK FORMAT "
	.BYTE	"\",LF
	.ASCII	"THIS ROUTINE DESTROYS DATA ON THE DISK.\"
	.ASCII	"DO YOU WISH TO CONTINUE"
	.byte	questionmark
	.ascii	" (Y,N OR CNTR X TO ZERO 17 SECTORS) $"
BSYMSG:
	.BYTE	"\",LF
	.ASCII	"BUSY FORMATTING $"
DONMSG:	.BYTE	"\"
	.ASCII	"DONE $"
ERRMSG:	.BYTE	"\"
	.ASCII	"ERROR TYPE $"
BMSG:	.ASCII	"MEMORY AT E000 $"
CMSG:	.ASCII	"MEMORY AT F000 $"
OOD:	.ASCII	"GOOD $"
BAD:	.ASCII	"BAD $"
	.page
	.sbttl	'variable area'

	.ifg	.-comdbuf,[.prntx 'code overflows variables'][
	.prntx	'code length ok']

	.LOC	comdbuf
TRACK:	.BYTE	40H
HEAD:	.BYTE	0
SECTOR:	.BYTE	1
hhtag0:	.BYTE	0
hhtag1:	.BYTE	0
RETRYS:	.BYTE	1H
RSTAT:	.BYTE	0
ERRCNT:	.BYTE	0
namepass:.ascii /NAME    PASSWD/
SECPTRK: .BYTE	17
HEADMASK: .BYTE	3
NSECTOR: .BYTE	18
NTRACK:	.BYTE	202
FIRST:	.BYTE	0FFH
CERRCNT: .BYTE	0

TEMPH:	.WORD	0	;temph,d,b used in
TEMPD:	.WORD	0	;compare
TEMPB:	.WORD	0

CURTRK:	.BYTE	0	;used in seek test

;
NFLAG:	.BYTE	00H		;DISK DONE FLAG BYTE.

vlabbuf: 		;get VOLUME label from user
	.byte	vlabsize ;maximum chars
	.byte	0	;count of chars input
	.blkb	vlabsize ;chars input

volinfo:
	.blkb	128	;buffer for info on all 
			;volumes
volsel:
	.blkb	1	;volume currently
			;selected or booted

curvol:
	.blkb	1	;current volume when printing
			;volume info

oldsec:	.blkb	1	;old second when waiting for 
			;seconds to tick by

seccount:.blkb	1	;count of seconds when waiting
			;for timeout condition
testcrcusage:
	.blkb	1	;retry byte during disk tests,
			;81 for crc error correction,
			;1 for no crc error correction
sizeflag:.byte	true	;true if size to come from 
			;firmware false if user has 
			;set and wants to remain
sectotimeout:.blkb	1 ;seconds to time out in 
			;select disk routine
e5only:	.blkb	1	;true if only e5 data is valid
			;in multivolume random read
			;test


	.ifg	.-wbuffer,[
	.prntx	'variables overflow write buffer'][
	.prntx	'variables ok']

	.END	START
