*****************************************************************
*								*
*	 Morrow Designs CP/M vers 2.2 Cold Boot Loader.		*
*		  Cbios revision E.2,  3/4/82.			*
*								*
* The following routines will boot CP/M from the		*
* Disk Jockey 2D Rev. B 8 inch disk controller (DJ2D/B),	*
* Disk Jockey DMA 8 + 5 1/4 inch controller (DJDMA),		*
* Hard Disk Controller revision 3 (HDC3),			*
* or the Hard Disk DMA (HDDMA) disk controllers.		*
*								*
* Provisions have been made for a Micronix boot loader.		*
* This loader always gets loaded to 0100h.			*
*								*
*	     8 inch floppy disk boot loader for the		*
*            Morrow Designs Disk Jockey 2D/B (DJ2DB)		*
*								*
* The 'order' column is the interleave sequence used by the	*
* loader during the load.					*
*								*
*   track   sector    sysgen	load order	Name		*
*								*
*	0	 1	 900	ff00	 0	Boot loader	*
*	0	 2	 980			Unused		*
*	0	 3	 a00					*
*	0	 4	 a80					*
*	0	 5	 b00	9100	 1	CCP		*
*	0	 6	 b80	9180	12			*
*	0	 7	 c00	9200	 2			*
*	0	 8	 c80	9280	13			*
*	0	 9	 d00	9300	 3			*
*	0	10	 d80	9380	14			*
*	0	11	 e00	9400	 4			*
*	0	12	 e80	9480	15			*
*	0	13	 f00	9500	 5			*
*	0	14	 f80	9580	16			*
*	0	15	1000	9600	 6			*
*	0	16	1080	9680	17			*
*	0	17	1100	9700	 7			*
*	0	18	1180	9780	18			*
*	0	19	1200	9800	 8			*
*	0	20	1280	9880	19			*
*	0	21	1300	9900	 9	BDOS		*
*	0	22	1380	9980	20			*
*	0	23	1400	9a00	10			*
*	0	24	1480	9a80	21			*
*	0	25	1500	9b00	11			*
*	0	26	1580	9b80	22			*
*								*
* Track 1 is recorded in double density format.  There are	*
* 1024 bytes per sector.					*
*								*
*	1	 1	1600	9c00	 4			*
*	1	 2	1a00	a000	 1			*
*	1	 3	1e00	a400	 5	CBIOS (@ a700h)	*
*	1	 4	2200	a800	 2			*
*	1	 5	2600	ac00	 6			*
*	1	 6	2a00	b000	 3			*
*	1	 7	2e00	b400	 7			*
*	1	 8	3200	b800		Unused		*
*								*
* Three spare sectors (track 0, sectors 2 to 4) have been	*
* provided for a more advanced boot loader at a later date.	*
*								*
* The warm boot loader starts on track 0, sector 5 and		*
* continues through to track 1 sector 3.  Only the first	*
* 3/4 K bytes of track 1, sector 3 is loaded since CP/M		*
* requires that the warm boot loader load up to the start	*
* of (but not past) the Cbios jump table.			*
*								*
*								*
*	     8 inch floppy disk boot loader for the		*
*	     Morrow Designs Disk Jockey DMA (DJDMA)		*
*								*
* The loading is identical to that of of the DJ2DB except	*
* that the loader itself is loaded at 80h and the 'order'	*
* column does not apply.  The DJDMA is capable of loading a	*
* complete track at a time and thus it merely zaps the		*
* tracks in all at once.					*
*								*
*								*
*	   5 1/4 inch floppy disk boot loader for the		*
*	     Morrow Designs Disk Jockey DMA (DJDMA)		*
*								*
* The cold boot loader (track 0, sector 0) is loaded into	*
* RAM at 80h.  This loader will start loading from track 0,	*
* sector 1 and stops at track 1, sector 9.  The load		*
* sequence is as follows:					*
*								*
*   track   sector    sysgen	load order	Name		*
*	0	 0	 900	  80	 0	Cold boot	*
*	0	 1	 b00	9500	 1	CCP		*
*	0	 2	 d00	9700	 2			*
*	0	 3	 f00	9900	 3			*
*	0	 4	1100	9b00	 4			*
*	0	 5	1300	9d00	 5	BDOS		*
*	0	 6	1500	9f00	 6			*
*	0	 7	1700	a100	 7			*
*	0	 8	1900	a300	 8			*
*	0	 9	1b00	a500	 9			*
*								*
*	1	 0	1d00	a700	10			*
*	1	 1	1f00	a900	11			*
*	1	 2	2100	ab00	12	CBIOS		*
*	1	 3	2300	ad00	13			*
*	1	 4	2500	af00	14			*
*	1	 5	2700	b100	15			*
*	1	 6	2900	b300	16			*
*	1	 7	2b00	b500	17			*
*	1	 8	2d00	b700	18			*
*	1	 9	2f00	b900	19			*
*								*
* The warm boot starts from track 0 sector 1 and continues	*
* through to track 1 sector 1.					*
*								*
*								*
*	Shugart SA4000 disk interface boot loader for the	*
*	Morrow Designs Hard Disk Controller rev. 3 (HDC3)	*
*								*
* The cold boot loader (track 0, sector 1) is loaded into	*
* RAM in the very last part of the Cbios.  This area is		*
* used for uninitialized tables and thus is a safe place	*
* for the loader.  This cold boot loader will start loading	*
* the CCP from track 0, sector 2 and will finish up with	*
* the last part of the Cbios on track 0, sector 20.		*
*								*
*   track   sector    sysgen	load order	Name		*
*	0	 1	 900	fc00	 1	Cold boot	*
*	0	 2	 b00	9500	 2	CCP		*
*	0	 3	 d00	9700	 3			*
*	0	 4	 f00	9900	 4			*
*	0	 5	1100	9b00	 5			*
*	0	 6	1300	9d00	 6	BDOS		*
*	0	 7	1500	9f00	 7			*
*	0	 8	1700	a100	 8			*
*	0	 9	1900	a300	 9			*
*	0	10	1b00	a500	10			*
*	0	11	1d00	a700	11			*
*	0	12	1f00	a900	12			*
*	0	13	2100	ab00	13	CBIOS		*
*	0	14	2300	ad00	14			*
*	0	15	2500	af00	15			*
*	0	16	2700	b100	16			*
*	0	17	2900	b300	17			*
*	0	18	2b00	b500	18			*
*	0	19	2d00	b700	19			*
*	0	20	2f00	b900	20			*
*	0	21	3100			Unused		*
*								*
* The warm boot load sequence starts at track 0, sector 2	*
* and goes straight through to sector 12.  There is still	*
* plenty of room left in this loader for more advanced		*
* things like sector interleaving although this is hardly	*
* necessary on a hard disk.					*
*								*
*								*
*	Shugart SA1000 disk interface boot loader for the	*
*	 Morrow Designs Hard Disk DMA controller (HDDMA)	*
*								*
*   track   sector    sysgen	load order	Name		*
*	0	 1	 900	 100	 0	Cold boot + CCP	*
*	0	 2	 d00	9300	 1			*
*	0	 3	1100	9700	 2			*
*	0	 4	1500	9b00	 3	Bdos (@ 9d00)	*
*	0	 5	1900	9f00	 4			*
*	0	 6	1d00	a300	 5			*
*	0	 7	2100	a700	 6	Cbios		*
*	0	 8	2500	ab00	 7			*
*	0	 9	2900	af00	 8			*
*								*
*	1	10	2d00	b300	 9			*
*								*
* Since 1k byte sectors were implemented on this disk;  	*
* track 0, sector 1 contains both the cold boot loader and	*
* part of the CCP.  The cold boot loader relocates this		*
* peice of the CCP to it proper resting place as part of	*
* the boot process.						*
*								*
*****************************************************************

*****************************************************************
*								*
* The following table gives a general idea as to where the	*
* various parts of of the operating system are in memory.	*
*								*
* The only changes to the map that I see in the future is	*
* the increasing the space for the uninitialized tables		*
* following the Cbios.  The amount of code and table space	*
* that can actually be loaded from the disk is fixed by the	*
* amount of space available on the system tracks.		*
*								*
* Our most restrictive (smallest) drive is the 5 1/4 inch	*
* 'minnie floppy'.  This drive has 20 512 byte sectors for	*
* a total of 10k bytes on the system tracks.  The 8 inch	*
* floppy disk drive is also very close to being filled up.	*
*								*
* Since 512 bytes are reserved for the cold boot loader we	*
* have a total of 9.5k bytes for the operating system.  Out	*
* of this 5.5k bytes are used by the (CCP + BDOS) leaving	*
* us with a total of 4k bytes of loaded code and data space	*
* to play with.  Right now we are using all of this space	*
* so any major additions will have to result in a little	*
* (lot?) of code shuffeling or in the creation of a Cbios	*
* that simply will not fit on a small disk drive.		*
*								*
*	sysgen	48k	56k	60k	62k	64k		*
*	 image	CP/M	CP/M	CP/M	CP/M	CP/M		*
*								*
*	 900	~~~~	~~~~	~~~~	~~~~	~~~~	Loader	*
*	 b00	9500	b500	c500	cd00	d500	CCP	*
*	1300	9d00	bd00	cd00	d500	dd00	BDOS	*
*	2100	ab00	cb00	db00	e300	ed00	Cbios	*
*	3100	bb00	db00	eb00	f300	fb00	Tables	*
*	35ff	bfff	dfff	efff	f7ff	ffff	The End	*
*								*
*	~~~~	8d00	ad00	bd00	c500	cd00	DDT	*
*								*
*****************************************************************
	
micron	equ	0		;Set to 1 for Micronix boot loader

	if	micron eq 0

msize	equ	48		;Memory size of target CP/M
			
biosln	equ	1700h		;BIOS length
codlen	equ	11h		;Code length
	
ccpln	equ	800h
bdosln	equ	0e00h

size	equ	(msize*1024)	
ccp	equ	size-(biosln+ccpln+bdosln)
bdos	equ	ccp+ccpln
bios	equ	ccp+ccpln+bdosln

cboot	equ	bios		;Cold boot address for CP/M
loaddr	equ	ccp		;Load address for floppy

	else			;Micronix boot loader

cboot	equ	0100h		;Cold boot address for the loader
loaddr	equ	0100h
	
				;If the load address is moved forward from
				;0100 then the starting extended address for
				;the djdma boot loader should be adjusted.
	endif

retries	equ	10		;Maximum # of disk retries

*****************************************************************
*								*
* Only one of the following equates should be set.  The		*
* others sould be 0.  These equates define the boot loader	*
* that is to be used.						*
*								*
******************************************************************

maxhd	equ	0		;Set to boot an HDC3 controller
maxmw	equ	1		;Set to boot a HDDMA controller
maxfd	equ	0		;Set to boot a DJ2D/B controller
maxdm	equ	0		;Set to boot a DJDMA controller with 8 inch
maxmf	equ	0		;Set to boot a DJDMA controller with 5 1/4 inch


*****************************************************************
*								*
* The following equates are for the Hard Disk Controller 3.	*
*								*
*****************************************************************

	if	maxhd ne 0
hdorg	equ	50h		;Hard Disk Controller
hdstat	equ	hdorg		;Hard Disk Status
hdcntl	equ	hdorg		;Hard Disk Control
hddata	equ	hdorg+3		;Hard Disk Data
hdfunc	equ	hdorg+2		;Hard Disk Function
hdcmnd	equ	hdorg+1		;Hard Disk Command
hdreslt	equ	hdorg+1		;Hard Disk Result
retry	equ	2		;Retry bit of result
tkz	equ	1		;Track zero bit of status
opdone	equ	2		;Operaction done bit of status
complt	equ	4		;Complete bit of status
tmout	equ	8		;Time out bit of status
wfault	equ	10h		;Write fault bit of status
drvrdy	equ	20h		;Drive ready bit of status
indx	equ	40h		;Index bit of status
pstep	equ	4		;Step bit of function
nstep	equ	0fbh		;Step bit mask of function
hdrlen	equ	4		;Sector header length
secln	equ	512		;Sector data length
wenabl	equ	0fh		;Write enable
wreset	equ	0bh		;Write reset of function
scenbl	equ	5		;Controller control
dskclk	equ	7		;Disk clock for control
mdir	equ	0f7h		;Direction mask for function
null	equ	0fch		;Null command
idbuff	equ	0		;Initialize data command
isbuff	equ	8		;Initialize header command
rsect	equ	1		;Read sector command
wsect	equ	5		;Write sector command
	endif

*****************************************************************
*								*
* The following equates are for the Hard Disk DMA.		*
*								*
*****************************************************************
	
	if	maxmw ne 0
cyl	equ	153		;Specifications for a Seagate Technology 506
heads	equ	4		;Number of heads per cylinder
spt	equ	9		;Sectors per track
precomp	equ	64		;Cylinder to start write precomensation
lowcurr	equ	128		;Cylinder to start low current
stepdly	equ	30		;Step delay (0-12.7 milliseconds)
headdly	equ	20		;Settle delay (0-255 milliseconds)
sectsiz	equ	7		;Sector size code (must be 3 for this Cbios)
				; 0 =  128 byte sectors
				; 1 =  256 byte sectors
				; 3 =  512 byte sectors
				; 7 = 1024 byte sectors (default for CP/M)
				; f = 2048 byte sectors

				;Define controller commands
dmaread	equ	0		;Read sector
dmawrit	equ	1		;Write sector
dmarhed	equ	2		;Find a sector
dmawhed	equ	3		;Write headers (format a track)
dmalcon	equ	4		;Load disk parameters
dmassta	equ	5		;Sense disk drive status
dmanoop	equ	6		;Null controller operation

reset	equ	54h		;Reset controller
attn	equ	55h		;Send a controller attention

chan	equ	50h		;Default channel address
stepout	equ	10h		;Step direction out
stepin	equ	0		;Step direction in
band1	equ	40h		;No precomp, high current
band2	equ	0c0h		;Precomp, high current
band3	equ	80h		;precomp, low current
track0	equ	1		;Track zero status
wfault	equ	2		;Write fault from drive
dready	equ	4		;Drive ready
	endif

*****************************************************************
*								*
* The following equates are for the Disk Jockey 2D/B.		*	
*								*
*****************************************************************

	if	maxfd ne 0
origin	equ	0f800h		;Orgin of DJ 2D Mod B PROM
djram	equ	origin+400h
				;Disk Jockey 2D Mod B routines
tkzero	equ	origin+9h	;Track 0 seek
trkset	equ	origin+0ch	;Set track
setsec	equ	origin+0fH	;Set sector
setdma	equ	origin+12h	;Set DMA address
dread	equ	origin+15h	;Read sector
dmast	equ	origin+24h	;Get DMA address
status	equ	origin+27h	;Disk status
dskerr	equ	origin+2ah	;Flash error light
setden	equ	origin+2dh	;Set density
	endif

*****************************************************************
*								*
* The following equates are for the Disk Jockey DMA if wanted.	*
*								*
*****************************************************************

	if	(maxdm ne 0) or (maxmf ne 0)

djkick	equ	0efh		;Kick port for DJDMA controller
channl	equ	50h
	
	if	maxdm ne 0	;8 inch boot loader
trkoff	equ	22*128		;Number of bytes loaded from track 0
	else			;5 1/4 inch boot loader
trkoff	equ	9*512		;Number of bytes loaded from track 0
	endif

setdma	equ	23h		;Set DMA address
djhalt	equ	25h		;Halt controller
djbran	equ	26h		;Branch controller command
redtrk	equ	29h		;Read track command

	endif

*****************************************************************
*								*
* Define the origin address for the various boot loaders.	*
*								*
*****************************************************************

	if	maxhd ne 0	;HDC3
boot	equ	bios+biosln-512	;Very last part of CP/M system
	endif

	if	maxmw ne 0	;HDDMA
boot	equ	100h
	endif

	if	maxfd ne 0	;DJ2D/B
boot	equ	djram+300h	;Upper 3/4 of on board floppy RAM
	endif

	if	(maxdm ne 0) or (maxmf ne 0)	;DJDMA
boot	equ	80h
	endif

offset	equ	900h-boot	;DDT offset

	org	boot

*****************************************************************
*								*
* Cold Boot loader for a hard disk.				*
*								*
*****************************************************************

	if	(maxhd ne 0) or (maxmw ne 0)

	lxi	sp,cstkhd	;Set up stack at end of this sector

	if	maxhd ne 0
	lxi	b,19*100h+2	;B = sector count, C = sector #
	call	clodhd
	jmp	cboot		;Go to CP/M
	else
	lxi	h,boot+200h	;Copy part of CCP up
	lxi	d,loaddr
	lxi	b,200h
movlop:	mov	a,m		;Get a byte
	stax	d		;Save it
	inx	h		;Bump pointers
	inx	d
	dcx	b		;Bump counter
	mov	a,b		;Test for end
	ora	c
	jnz	movlop
	lxi	b,10*100h+2	;B = sector count, C = sector #
	call	clodhd
	jmp	cboot		;Go to CP/M
	endif

clodhd	push	b		;Save sector and count
	mov	a,c		;Load sector
	sta	hdsec
	lxi	h,loaddr-200h	;Get DMA address (self modifying)
cdmahd	equ	$-2		;Storage for previous DMA address
	if	maxhd ne 0
	lxi	d,200h		;Offset to new DMA address
	else
	lxi	d,400h
	endif
	dad	d		;Add in offset, HL = new DMA address
	shld	cdmahd		;Save new DMA address
	call	crdhd		;Attempt a read
	pop	b		;Recover sector number and count
				;	B = count, C = number
	dcr	b		;Update sector count
	rz			;All done ?
	inr	c		;Bump sector number
	jmp	clodhd		;Continue reading

*****************************************************************
*								*
* crdhd does the actual read from the controller, the DMA	*
* address and sector # have already been set up.		*
*								*
*****************************************************************

	if	maxhd ne 0	;Low level HDC3 drivers
crdhd	lxi	b,retries*100h+1 ;Maximum # of attempts
crhd	push	b		;Save error count
	call	hdread		;Attempt the read
	pop	b		;Restore the error count
	rnc			;Return if no error
	dcr	b		;Update error count
	jnz	crhd		;Try again if not too many errors
	jmp	$		;Dynamic error halt

hdread	call	hdprep		;Prepare the sector header image
	rc			;Error exit
	mvi	a,rsect		;Read sector command
	out	hdcmnd
	call	process		;Process the read
	rc			;Error exit
	xra	a		;Pointer to data buffer
	out	hdcmnd
	mvi	b,secln/4	;Number of bytes to read
	lhld	cdmahd		;Get destination of data
	in	hddata		;Two dummy data bytes
	in	hddata
rtloop	in	hddata		;Move four bytes
	mov	m,a		;Byte one
	inx	h
	in	hddata		;Byte two
	mov	m,a
	inx	h
	in	hddata		;Byte three
	mov	m,a
	inx	h
	in	hddata		;Byte four
	mov	m,a
	inx	h
	dcr	b		;Update byte count
	jnz	rtloop
	ret

process	in	hdstat		;Wait for command to finish
	mov	b,a
	ani	opdone
	jz	process
	mvi	a,dskclk	;Turn on Disk Clock
	out	hdcntl
	in	hdstat
	ani	tmout		;Timed out ?
	stc
	rnz
	in	hdreslt
	ani	retry		;Any retries ?
	stc
	rnz
	xra	a		;No error exit
	ret

hdprep	in	hdstat		;Is Drive ready ?
	ani	drvrdy
	stc
	rnz
	mvi	a,isbuff	;Initialize pointer to header buffer
	out	hdcmnd
	mvi	a,null
	out	hdfunc		;Select drive A
	xra	a
	out	hddata		;Form head byte
	out	hddata		;Form track byte
	mvi	a,0		;Form sector byte
hdsec	equ	$-1
	out	hddata
	mvi	a,80h		;Form Key
	out	hddata
	mvi	a,dskclk	;Turn on Disk clock
	out	hdcntl
	mvi	a,wenabl	;Write enable on
	out	hdcntl
	ret

	org	boot+200h-2	;Last word on sector is load address

cstkhd	equ	$
	dw	boot
	endif

	if	maxmw ne 0	;Low level HDDMA routines
crdhd	call	hdsetup		;Set up parameters
	lxi	b,retries*100h+1 ;Maximum # of attempts
crhd	push	b		;Save error count
	call	hdissue		;Attempt the read
	pop	b		;Restore the error count
	rnc			;Return if no error
	dcr	b		;Update error count
	jnz	crhd		;Try again if not too many errors
error	jmp	$		;Dynamic error halt

hdsetup	shld	dmadma		;Set up DMA address
	call	hdreset		;Reset controller
	lda	hdsec		;Set logical sector number
	dcr	a		;Range is actaully 0-16
	call	divspt		;Figure out head number -> (c)
	adi	spt		;Make real sector number
	sta	dmarg3
	mov	a,c
	sta	dmarg2		;Save head number
	cma			;Negative logic for the controller
	ani	7		;3 bits of head select
	rlc			;Shove over to bits 2 - 4
	rlc
	sta	dmasel1		;Save in command channel head select
	ret

divspt	mvi	c,0		;Clear head counter
divsptx	sui	spt		;Subtract a tracks worth of sectors
	rc			;Return if all done
	inr	c		;Bump to next head
	jmp	divsptx

hdreset	mvi	a,(ret)		;One time code
	sta	hdreset
	out	reset		;Send reset pulse to controller
	lxi	h,dmachan	;Address of command channel
	shld	chan		;Default channel address
	xra	a
	sta	chan+2		;Clear extended address byte
	xthl			;Wait for reset (around 10 uSEC's)
	xthl
	call	hdissue		;Do load constants
	jc	error		;Controller not present
	mvi	a,dmassta	;Sense status command
	sta	dmaop
rdychek	call	hdissue
	ani	dready		;Check for drive ready
	jnz	rdychek		;Loop if not ready
	lxi	h,0ffffh
	shld	dmastep		;Do recalibrate
	call	hdissue
	lxi	h,0
	shld	dmastep		;Clear step counter
	shld	dmarg0		;Clear cylinder #
	shld	dmarg3		;Clear sector # + read disk command
	ret

hdissue	lxi	h,dmastat	;Status byte
	mvi	m,0
	out	attn		;Start controller
	lxi	d,0		;Time out counter
	mov	b,e		;Controller busy status
hdiloop	mov	a,m		;Get status
	ora	a		;Set up CPU flags
	rm			;Return no error (carry reset)
	stc
	rnz			;Return error status
	xthl			;Waste some time
	xthl
	xthl
	xthl
	dcx	d		;Bump timeout counter
	mov	a,d
	ora	e
	jnz	hdiloop		;Loop if still busy
	stc			;Set error flag
	ret

hdsec	db	0		;Currently selected sector

dmachan	equ	$		;Command channel area
dmasel0	db	10h		;Drive select (step out, drive 0)
dmastep	dw	0		;Relative step counter
dmasel1	db	0		;Head select
dmadma	dw	0		;DMA address
	db	0		;Extended address
dmarg0	db	0		;First argument
dmarg1	db	stepdly		;Second argument (stepping time)
dmarg2	db	headdly		;Third argument (Settle time)
dmarg3	db	sectsiz		;Fourth argument (Sector size)
dmaop	db	dmalcon		;Operation code
dmastat	db	0		;Controller status byte
dmalnk	dw	dmachan		;Link address to next command channel
	db	0		;extended address

	org	boot+200h
cstkhd	equ	$		;Stack area at end of sector
	endif	
	endif

*****************************************************************
*								*
* Cold boot loader for the Disk Jockey 2D Revision B controller	*
*								*
*****************************************************************

	if	maxfd ne 0
t0boot	mvi	a,5-2		;First sector - 2
newsec	equ	$-1
	inr	a		;Update sector #
	inr	a
	cpi	27		;Size of track in sectors + 1
trksiz	equ	$-1
	jc	nowrap		;Skip if not at end of track
	jnz	t1boot		;Done with this track
exit	equ	$-2
	sui	27-6		;Back up to sector 6
backup	equ	$-1
	lxi	h,loaddr-80h	;Memory address of sector - 100h
nxtdma	equ	$-2
	shld	newdma
nowrap	sta	newsec		;Save the updated sector #
	mov	c,a
	call	setsec		;Set up the sector
	lxi	h,loaddr-100h	;Memory address of sector - 100h
newdma	equ	$-2
	lxi	d,100h		;Update DMA address
secsiz	equ	$-2
	dad	d
nowrp	shld	newdma		;Save the updated DMA address
	mov	b,h
	mov	c,l
	call	setdma		;Set up the new DMA address
	lxi	b,retries*100h+0;Maximum # of errors, track #
nxtrty	equ	$-2
fread	push	b
	call	trkset		;Set up the proper track
	call	dread		;Read the sector
	pop	b
	jnc	t0boot		;Continue if no error
	dcr	b
	jnz	fread		;Keep trying if error
	jmp	dskerr		;Too many errors, flash the light

t1boot	lxi	h,cboot		;We jump to cboot next time
	shld	exit
	mvi	c,1		;Select double density
	call	setden
	xra	a		;First sector - 2
	sta	newsec
	mvi	a,8		;Size of (logical) track + 1
	sta	trksiz
	dcr	a		;Number of sectors to back up
	sta	backup
	lxi	h,loaddr+0700h	;DMA start address for first revolution - 2048
	shld	newdma
	lxi	h,loaddr+0300h	;DMA start address for second revolution - 2048
	shld	nxtdma
	lxi	h,2048		;Difference between DMA addresses
	shld	secsiz
	lxi	h,retries*100h+1;Maximum # of errors, track #
	shld	nxtrty
	jmp	t0boot		;Go load in track 1
	endif

*****************************************************************
*								*
* Cold boot loader for the Disk Jockey DMA controller		*
*								*
*****************************************************************

	if	(maxdm ne 0) or (maxmf ne 0)	;Set up DJDMA loader

	mvi	a,djbran	;Load branch channel command
	sta	channl
	lxi	h,commnd	;Load new command channel address
	shld	channl+1
	xra	a
	sta	channl+3

djstrt:	out	djkick		;Start controller
djwait:	lda	djdone		;Get final status
	ora	a		;0 = still busy
	jz	djwait		;Loop if busy
	lxi	h,sectb0	;Check for bad load
	lxi	b,40ffh		;b = ok, c = loaded
	lxi	d,endtbl-sectb0	;Error count + # of sectors
djloop:	mov	a,m		;Load sector code
	cmp	c		;Check for 0ffh (already loaded)
	jz	djcont		;Skip if load was 'ok'
	mov	m,c		;Load 'loaded' flag
	cmp	b		;Check for 'ok' status
	jz	djcont		;Skip if load ok
	inr	m		;Make flag = 0
	inr	d		;Bump error counter
djcont:	dcr	e		;Bump sector count
	inx	h		;Bump table pointer
	jnz	djloop
	mov	a,d		;Check out error counter
	ora	a
	jz	cboot		;Start CP/M if no errors
	dcr	m		;Drop retry counter
	jnz	djstrt		;Retry load operation
	jmp	$		;Dynamic error halt

commnd:	db	setdma		;Set DMA address
	dw	loaddr-512	;Start at CCP
	if	micron eq 0
	db	0		;Extended address for CP/M
	else
	db	0ffh		;Wrap around from ffff00 to 000100
	endif

	db	redtrk		;Read track
	db	0		;Track 0
	db	0		;Side 0
	db	0		;Drive 0
	dw	sectb0		;Sector table 0
	db	0		;Extended address
	db	0		;Returned status

	db	setdma		;Set DMA address
	dw	loaddr+trkoff	;Load address for track 1
	db	0		;Extended address

	db	redtrk		;Read track
	db	1		;Track 1
	db	0		;Side 0
	db	0		;Drive 0
	dw	sectb1		;Sector table 1
	db	0		;Extended address
	db	0		;Returned status

	db	djhalt		;Halt controller
djdone:	db	0		;Returned status
	
	org	boot+5dh	;Boot + 5ch contains 'configuration byte'

	if	maxdm ne 0	;Booting from 8 inch drives
sectb0:	dw	0ffffh, 0ffffh	;Do not load boot loader
	dw	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0	;22 sectors to be loaded

sectb1:	dw	0, 0, 0, 0ff00h	;First seven sectors

	db	retries		;Retry counter
	else			;Booting from 5 1/5 inch drives
sectb0:	dw	0ffh, 0, 0, 0, 0;Do not load boot loader
	
sectb1:	dw	0, 0, 0, 0, 0	;Load ten sectors

	db	retries		;Retry counter
	endif

endtbl	equ	$-1		;end of table marker

	endif

	end
