;	dc.l	$a00
;	dc.l	$a00
;
;	lea	$b00,a0
;loop:
;	clr.l	(a0)+
;	cmp.l	#$e004,a0
;	bne.s	loop
;	rts
;	END

	opt	d+

	;/* Hardware-include-file      */
	;/* (p) 1990 by Peter Thierolf */

custom	= $dff000

bltddat	= $000
dmaconr	= $002
vposr	= $004
vhposr	= $006
dskdatr	= $008
joy0dat	= $00a
joy1dat	= $00c
clxdat	= $00e
adkconr	= $010
pot0dat	= $012
pot1dat	= $014
potgor	= $016
serdatr	= $018
dskbytr	= $01a
intenar	= $01c
intreqr	= $01e
dskpth	= $020
dskptl	= $022
dsklen	= $024
dskdat	= $026
refptr	= $028
vposw	= $02a
vhposw	= $02c
copcon	= $02e
serdat	= $030
serper	= $032
potgo	= $034
joytest	= $036
strequ	= $038
strvbl	= $03a
strhor	= $03c
strlong	= $03e
bltcon0	= $040
bltcon1	= $042
bltafwm	= $044
bltalwm	= $046
bltcpth	= $048
bltcptl	= $04a
bltbpth	= $04c
bltbptl	= $04e
bltapth	= $050
bltaptl	= $052
bltdpth	= $054
bltdptl	= $056
bltsize	= $058

bltcmod	= $060
bltbmod	= $062
bltamod	= $064
bltdmod	= $066

bltcdat	= $070
bltbdat	= $072
bltadat	= $074

dsksync	= $07e
cop1lch	= $080
cop1lcl	= $082
cop2lch	= $084
cop2lcl	= $086
copjmp1	= $088
copjmp2	= $08a
copins	= $08c
diwstrt	= $08e
diwstop	= $090
ddfstrt	= $092
ddfstop	= $094
dmacon	= $096
clxcon	= $098
intena	= $09a
intreq	= $09c
adkcon	= $09e

audlch	= $000
audlcl	= $002
audlen	= $004
audper	= $006
audvol	= $008
auddat	= $00a

aud0	= $0a0
aud1	= $0b0
aud2	= $0c0
aud3	= $0e0

bpl1pth	= $0e0
bpl1ptl	= $0e2
bpl2pth	= $0e4
bpl2ptl	= $0e6
bpl3pth	= $0e8
bpl3ptl	= $0ea
bpl4pth	= $0ec
bpl4ptl	= $0ee
bpl5pth	= $0f0
bpl5ptl	= $0f2
bpl6pth	= $0f4
bpl6ptl	= $0f6

bplcon0	= $100
bplcon1	= $102
bplcon2	= $104

bpl1mod	= $108
bpl2mod	= $10a

bpl1dat	= $110
bpl2dat	= $112
bpl3dat	= $114
bpl4dat	= $116
bpl5dat	= $118
bpl6dat	= $11a

spr0pth	= $120
spr0ptl	= $122
spr1pth	= $124
spr1ptl	= $126
spr2pth	= $128
spr2ptl	= $12a
spr3pth	= $12c
spr3ptl	= $12e
spr4pth	= $130
spr4ptl	= $132
spr5pth	= $134
spr5ptl	= $136
spr6pth	= $138
spr6ptl	= $13a
spr7pth	= $13c
spr7ptl	= $13e

sprpos	= $000
sprctl	= $002
sprdata	= $004
sprdatb	= $006

spr0	= $140
spr1	= $148
spr2	= $150
spr3	= $158
spr4	= $160
spr5	= $168
spr6	= $170
spr7	= $178

color	= $180

	;/* Cia's */

ciaa	= $bfe001
ciab	= $bfd000

pra	= $000
prb	= $100
ddra	= $200
ddrb	= $300
talo	= $400
tahi	= $500
tblo	= $600
tbhi	= $700
todlo	= $800
todmid	= $900
todhi	= $a00
sdr	= $c00
icr	= $d00
cra	= $e00
crb	= $f00

mili3	= 2128
mili50	= 35468

inbits	= ciaa+pra
outbits	= ciab+prb

trkbuffer	= $7a000

Verify	= 0

trklen	= 6144

	ORG	$7e000-8

	dc.l	$7e000
	dc.l	$7e000

start:
	bsr	setup
	moveq	#0,d0
	bsr	seldrive
	bsr	resetdrive
	bsr	motoron
	moveq	#0,d0
	bsr	stepto
	move.b	#0,side
	bsr	selside
	move.l	#$6e800,startpointer
	move.l	#trklen*1,diskIOlen
	bsr	save

	bsr	motoroff
	rts

	;Erwartet einen eingeschalteten Motor, einen angefahrenen Track
	;sowie eine in 'side' eingetragene Diskettenseite.
	;Im 'startpointer' wird die Save-adresse übergeben,
	;in 'diskIOlen' wird die Save-länge übergeben.

save:
	move.w	#$1002,intena(a5)
	move.w	#$8210,dmacon(a5)

.nexttrack:
	bsr	selside

	move.l	startpointer,a2
	move.w	#$4000,dsklen(a5)
	bsr	encode
	move.w	#$7700,adkcon(a5)
	;move.w	#$8210,dmacon(a5)
	move.w	#$9100,adkcon(a5)
	move.l	#trkbuffer,dskpth(a5)
	move.w	#$dfff,dsklen(a5)	;$1fff Bytes schreiben
	move.w	#$dfff,dsklen(a5)
.waitdma:
	btst	#1,intreqr+1(a5)
	beq	.waitdma
	move.w	#$4000,dsklen(a5)
	move.w	#$1002,intreq(a5)
	sub.l	#trklen,diskIOlen
	beq	.end
	bmi	.end
	add.l	#trklen,startpointer
	addq.b	#1,side
	and.b	#1,side
	bne	.nexttrack
	bsr	stepin
	bra	.nexttrack
.end:
	rts

encode:
	move.w	#$0fff,d0
	lea	trkbuffer,a0
	move.l	#$aaaaaaaa,d1
.fill:
	move.l	d1,(a0)+
	dbf	d0,.fill

	moveq	#0,d4
	move.w	#$5ff,d3
	lea	trkbuffer+$ff0,a0
	move.w	#$4489,(a0)+
	move.w	#$2aaa,(a0)+
.loop:
	move.l	(a2),d0
	add.l	d0,d4
	lsr.l	#1,d0
	bsr	encodeone
	move.l	(a2)+,d0
	bsr	encodeone
	dbf	d3,.loop

	move.l	d4,d0
	lsr.l	#1,d0
	bsr	encodeone
	move.l	d4,d0
	bsr	encodeone
	moveq	#0,d0
encodeone:
	and.l	#$55555555,d0
	move.l	d0,d2
	eor.l	#$55555555,d2
	move.l	d2,d1
	lsl.l	#1,d2
	lsr.l	#1,d1
	bset	#31,d1
	and.l	d2,d1
	or.l	d1,d0
	btst	#0,-1(a0)
	beq	.nocorrect
	bclr	#31,d0
.nocorrect:
	move.l	d0,(a0)+
	rts

	;Erwartet einen eingeschalteten Motor, einen angefahrenen Track
	;sowie eine in 'side' eingetragene Diskettenseite.
	;Im 'startpointer' wird die Load-adresse übergeben,
	;in 'diskIOlen' wird die Load-länge übergeben.

load:
	move.w	#$1002,intena(a5)
	move.w	#$8210,dmacon(a5)
	move.w	#3,trycount
.nexttrack:
	bsr	selside
	clr.w	errorcount
.tryloop:
	move.w	#$0,$dff180
	move.w	#$7700,adkcon(a5)
	move.w	#0,dsklen(a5)
	move.w	#$4489,dsksync(a5)
	move.w	#$9500,adkcon(a5)
	move.l	#trkbuffer,dskpth(a5)
	move.w	#$9810,dsklen(a5)	;$1410 Bytes laden
	move.w	#$9810,dsklen(a5)

.waitdma:
	btst	#1,intreqr+1(a5)
	beq	.waitdma

	move.w	#$1002,intreq(a5)
	move.w	#$4000,dsklen(a5)

	move.l	startpointer,a3

	lea	trkbuffer-2,a1
.sync:
	addq.l	#2,a1
	cmp.w	#$4489,(a1)
	beq	.sync
	cmp.w	#$2aaa,(a1)	;Wenn kein Synchelp, dann neu laden.
	bne	.tryloop
	addq.l	#2,a1

	move.w	#$fff,$dff180
	move.w	#$05ff,d7
	moveq	#0,d3
.loop:
	move.l	(a1)+,d0
	and.l	#$55555555,d0
	asl.l	#1,d0
	move.l	(a1)+,d1
	and.l	#$55555555,d1
	or.l	d1,d0
	add.l	d0,d3
	IFEQ	Verify
	move.l	d0,(a3)+
	ENDC
	dbf	d7,.loop

	move.l	(a1)+,d0
	and.l	#$55555555,d0
	asl.l	#1,d0
	move.l	(a1)+,d1
	and.l	#$55555555,d1
	or.l	d1,d0
	cmp.l	d0,d3
	bne	.checkerror

	sub.l	#trklen,diskIOlen
	beq	.end
	bmi	.end
	add.l	#trklen,startpointer
	addq.b	#1,side
	and.b	#1,side
	bne	.nexttrack
	bsr	stepin
	bra	.nexttrack
.end:
	rts

.checkerror:
	addq.w	#1,errorcount
	cmp.w	#3,errorcount
	bne	.tryloop
	subq.w	#1,trycount
	bmi	.end
	move.w	tracknr,-(sp)
	bsr	resetdrive
	bsr	motoron
	bsr	selside
	move.w	(sp)+,d0
	bsr	stepto
	bra	.nexttrack

stepto:
	cmp.w	tracknr,d0
	beq	.done
	blt	.out
	bsr	stepin
	bra	stepto
.out:
	bsr	stepout
	bra	stepto
.done:
	rts

resetdrive:
	move.b	selmask,d0
	bset	#1,d0
	move.b	d0,selmask	;Step-richtung festlegen
	bsr	motoroff
	bsr	wait
.loop:
	btst	#4,inbits
	beq	.done
	bsr	dostep
	bsr	wait
	bra	.loop
.done:
	move.w	#0,tracknr
	rts

dostep:
	move.b	selmask,d7
	bclr	#0,d7
	move.b	d7,outbits
	nop
	move.b	selmask,outbits
	rts

stepout:
	move.b	selmask,d7
	bset	#1,d7
	move.b	d7,selmask
	bsr	wait
	subq.w	#1,tracknr
	bra	dostep

stepin:
	move.b	selmask,d7
	bclr	#1,d7
	move.b	d7,selmask
	bsr	wait
	addq.w	#1,tracknr
	bra	dostep

wait:
	bset	#0,ciaa+cra
.loop:
	btst	#0,ciaa+icr
	beq.s	.loop
	rts

motoron:
	move.b	#%01111001,outbits
	bclr	#7,selmask
	move.b	selmask,outbits
.wait:
	btst	#5,inbits
	bne	.wait
	rts

motoroff:
	move.b	#%11111001,outbits
	bset	#7,selmask
	move.b	selmask,outbits
	rts

seldrive:
	addq.w	#3,d0
	move.b	#%11111001,d7
	bclr	d0,d7
	move.b	d7,selmask
	rts

selside:
	move.b	side,d0
	tst.b	d0
	beq	.upper
	bset	#2,selmask
	bra	.wait
.upper:
	bclr	#2,selmask
.wait:
	move.b	selmask,outbits
	move.b	#mili50&$ff,ciaa+talo
	move.b	#mili50/$100,ciaa+tahi
	bset	#0,ciaa+cra
.loop:
	btst	#0,ciaa+icr
	beq.s	.loop
	bset	#0,ciaa+cra
.loop2:
	btst	#0,ciaa+icr
	beq.s	.loop2

	move.b	#mili3&$ff,ciaa+talo
	move.b	#mili3/$100,ciaa+tahi
	rts

setup:
	lea	custom,a5
	move.b	ciaa+ddra,d0
	and.b	#%11000011,d0
	move.b	d0,ciaa+ddra
	move.b	#%11111001,outbits
	move.b	#%11111111,ciab+ddrb
	move.b	ciaa+cra,d0
	and.b	#%11000000,d0
	or.b	#%00001000,d0
	move.b	d0,ciaa+cra
	move.b	#%01111111,ciaa+icr

	move.b	#mili3&$ff,ciaa+talo
	move.b	#mili3/$100,ciaa+tahi

	bsr	wait
	rts

trapin:
	move.l	(sp)+,d0
	move.l	(sp)+,d1
	lea	$10100,sp
	move.l	d1,-(sp)
	move.l	d0,-(sp)
	rte

startpointer:	dc.l	0
diskIOlen:	dc.l	0

tracknr:	dc.w	0
selmask:	dc.b	0
side:		dc.b	0
errorcount:	dc.w	0
trycount:	dc.w	0
