**************** SYMBOLS ****************
MFMsync=$4489
MFMbuf=$80000-12980
LoadAddr=$00c00
Lvl7=LoadAddr-2
********************************
SECTION BOOTLOADER,CODE_C
START:
	lea BOOT(PC),a0
	moveq #-1,d0
	move.w #$ff,d7
	moveq #0,d2
wBoot1:	sub.l (a0)+,d0
	subx.l d2,d0
	dbf d7,wBoot1
	lea boot(PC),a6
	move.l d0,4(a6)		;checksum Calced
WR:	move.l 4.w,a6
	lea 0.w,a1
	jsr -294(a6)
	lea wPort(PC),a1
	move.l d0,16(a1)
	jsr -354(a6)
	lea wIO(PC),a1
	moveq #0,d0
	moveq #0,d1
	lea wTrdDevice(PC),a0
	jsr -444(a6)
	tst.l d0
	bne.s wError
	lea wIO(PC),a1
	lea Wport(PC),a3
	move.l a3,14(a1)
	move.w #3,28(a1)
	lea boot(PC),a3
	move.l a3,40(a1)
	move.l #2*512,36(a1)
	move.l #0*512,44(a1)
	jsr -456(a6)
	move.w #4,28(a1)
	jsr -456(a6)
	move.w #9,28(a1)
	move.l #0,36(a1)
	jsr -456(a6)
	lea wPort(PC),a1
	jsr -360(a6)
	lea wIO(PC),a1
	jsr -450(a6)
wError:	RTS
wTrdDevice:	dc.b 'trackdisk.device',0
EVEN
wIO:		blk.l 20,0
wPort:		blk.l 8,0
;;
B:
BOOT:		dc.b 'DOS',0
		dc.l 0,1758

BOOTCODE:				;a6=xcbase
	LEA $DFF000,A6
	move.w #$87f0,$96(a6)
	move.w #$7fff,$9c(a6)
	move.w #$7fff,$9a(a6)
	lea Trap(PC),a0
	move.l a0,$80.w
	TRAP #0
Trap:	lea Cop0(PC),a0
	move.l a0,$80(a6)
	move.w #0,$88(a6)
	moveq #14,d0			;FADE FROM WHITE TO BLACK
.lup:	tst.b 6(a6)
	bpl.s .lup
.lup2:	tst.b 6(a6)
	bmi.s .lup2
	sub.w #$111,2(a0)
	dbf d0,.lup
	lea (LoadAddr).w,a0
	move.l a0,a7			;set SP to start of prog-2
	move.w #$4e73,-(a7)		;=RTE
	move.l a7,$7c.w			;now if [$7c.w]<>lvl7,a CARTRIDGE is in
	clr.l $26(a6)			;causes a clr-reset
	moveq #2,d0
	moveq #42,d1
	bsr.s LoadMFM			;LOAD PROGRAM
	JMP (A0)
**************** ROUTINES ****************
LoadMFM:		;load sectors.a0=dst,d0=startsec.W,d1=nrsecs.W(-=Step0)
	MOVEM.L D0-D7/A0-A6,-(SP)
	lea $bfd100,a4
	bsr MotorOn
	tst.w d1			;if neg length,then Step0 first
	bpl.s .NoSt0
	neg.w d1
.St0:	btst #4,$f01(a4)		;head on cyl 0?
	beq.s .Rdy0
	bsr.s StepOut
	bra.s .St0
.Rdy0:	clr.w MFMcyl-B(a5)
.NoSt0:	and.l #$ffff,d0
	divu #22,d0			;startcyl
	sub.w MFMcyl(PC),d0		;delta-step
	beq.s .StRdy
	bmi.s .StOut
	subq.w #1,d0
.StIn:	bsr.s StepIn
	dbf d0,.StIn
	bra.s .StRdy
	not.w d0			;=neg+sub#1
.StOut:	bsr.s StepOut
	dbf d0,.StIn
.StRdy:	swap d0				;startsec within cyl
	cmp.w #11,d0
	blt.s .Head0
	sub.w #11,d0
	bra.s .Head1
.Head0:	bset #2,(a4)
	clr.w MFMhead-B(a5)
	bsr LoadTrak			;read track+decode
	beq.s .End
.Head1:	bclr #2,(a4)			;Head 1
	move.w #1,MFMhead-B(a5)
	bsr LoadTrak			;read track+decode
	beq.s .End
	bsr.s StepIn			;1 cyl forward
	bra.s .Head0
.End:	bsr.s MotorOff
	MOVEM.L (SP)+,D0-D7/A0-A6
	RTS

StepOut:
	bset #1,(a4)
	subq.w #1,MFMcyl-B(a5)
	nop
	bclr #0,(a4)
	nop
	nop
	bset #0,(a4)
	bsr.s StepWt
	RTS

StepIn:
	bclr #1,(a4)
	addq.w #1,MFMcyl-B(a5)
	nop
	bclr #0,(a4)
	nop
	nop
	bset #0,(a4)
	bsr.s StepWt
	RTS

StepWt:					;wait 3 ms
	moveq #47,d6			;3 ms=48 scan lines!
.loop1:	move.b 6(a6),d7
.loop2:	cmp.b 6(a6),d7
	beq.s .loop2
	dbf d6,.loop1
	RTS

MotorOn:
	move.w MFMdrv(PC),d7
	addq.w #3,d7
	or.b #$78,(a4)
	bset d7,(a4)
	nop
	nop
	bclr #7,(a4)			;turns motor on
	nop
	nop
	bclr d7,(a4)
	nop
	nop
.DiskR:	btst #5,$f01(a4)		;wait until motor running
	bne.s .DiskR
	RTS

MotorOff:
	move.w MFMdrv(PC),d7
	addq.w #3,d7
	bset d7,(a4)
	nop
	nop
	bset #7,(a4)
	nop
	nop
	bclr d7,(a4)
	RTS

LoadTrak:		;load track+decode.a0=dst,d0=secoffs,d1=secsleft
	MOVE.W D0,-(SP)
	MOVE.W D1,-(SP)
	lea MFMbuf,a1
	move.w #2,$9c(a6)		;Clr Req
	move.l a1,$20(a6)
	move.w #$8210,$96(a6)		;DskEna
	move.w #MFMsync,$7e(a6)
	move.w #$9500,$9e(a6)
	move.w #$4000,$24(a6)
	move.w #$995a,$24(a6)		;DskLen(12980)+DmaEn
	move.w #$995a,$24(a6)		;start reading MFMdata
.Wrdy:	btst #1,$1f(a6)			;wait until data read
	beq.s .Wrdy
	move.w d0,d2
	add.w d1,d2			;highest sec# (d0=lowest)
	cmp.w #11,d2
	ble.s .NoOvr
	moveq #11,d2
.NoOvr:	sub.w d0,d2			;nrsecs
	move.l #$55555555,d3		;and-const
	move.w d2,d1
	subq.w #1,d1			;loopctr
.FindS:	cmp.w #MFMsync,(a1)+		;search for a sync word
	bne.s .FindS
	cmp.b (a1),d3			;search for 0-nibble
	bne.s .FindS
	move.l (a1)+,d4			;decode fmtbyte/trk#,sec#,eow#
	move.l (a1)+,d5
	and.w d3,d4
	and.w d3,d5
	add.w d4,d4
	or.w d5,d4
	lsr.w #8,d4			;sec#
	sub.w d0,d4			;do we want this sec?
	bmi.s .Skip
	cmp.w d2,d4
	blt.s .DeCode
.Skip:	lea 48+1024(a1),a1		;nope
	bra.s .FindS
.DeCode:lea 40(a1),a1			;found a sec,skip unnecessary data
	clr.l MFMchk-B(a5)
	move.l (a1)+,d6			;decode data chksum.L
	move.l (a1)+,d5
	and.l d3,d6
	and.l d3,d5
	add.l d6,d6
	or.l d5,d6			;chksum
	lea 512(a1),a2
	add.w d4,d4			;x512
	lsl.w #8,d4
	lea (a0,d4.w),a3		;dest addr for this sec
	moveq #127,d7
.DClup:	move.l (a1)+,d4
	move.l (a2)+,d5
	and.l d3,d4
	and.l d3,d5
	eor.l d4,d6			;EOR with checksum
	eor.l d5,d6			;EOR with checksum
	add.l d4,d4
	or.l d5,d4
	move.l d4,(a3)+
	dbf d7,.DClup			;chksum should now be 0 if correct
	or.l d6,MFMchk-B(a5)		;or with track total chksum
	move.l a2,a1
	dbf d1,.FindS			;decode next sec
	MOVE.W (SP)+,D1
	MOVE.W (SP)+,D0
	tst.l MFMchk-B(a5)		;track total chksum OK?
	bne LoadTrak			;no,retry
	moveq #0,d0			;set to start of track
	move.w d2,d3
	add.w d3,d3
	lsl.w #8,d3
	add.w d3,a0
	sub.w d2,d1			;sub #secs loaded
	RTS
**************** VARS ****************
MFMcyl:		dc.w 0
MFMhead:	dc.w 0
MFMdrv:		dc.w 0
MFMchk:		dc.l 0
**************** COPPER ****************
Cop0:
dc.w $180,$fff
dc.w $100,$0200
dc.w $ffff,$fffe
E:
