	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

	INCLUDE	work:Sources/Includes/ExecOffsets.i
	INCLUDE	work:Sources/Includes/DosOffsets.i

mili3	= 2128	;+1000	;Langsamer steppen wegen 32Mhz
mili50	= 35468	;+2699

inbits	= ciaa+pra
outbits	= ciab+prb

bufferstart	= $7a000

font	= $3f000
	;Parameter fr die Disketten-erkennung

syncwert	= $4489
code1		= $2aa5	;Apidya disk #1
code2		= $4aa9	;Apidya disk #2

Verify	= 1

Dos	= 1

trklen	= $1a00

	IFEQ	Dos
	ORG	$70000-8

	dc.l	$70000
	dc.l	$70000
	ENDC

start:
	IFNE	Dos

	movem.l	d0/a0,-(sp)

	move.l	ExecBase,a6
	lea	dosname,a1
	moveq	#0,d0
	jsr	OpenLibrary(a6)
	move.l	d0,DosBase
	movem.l	(sp)+,d0/a0
	tst.l	DosBase
	beq	clean_exit

	bsr	read_command_line
	bne.s	.ok

	bsr	write_useage

	bra	clean_exit

.ok:
	move.l	ExecBase,a6
	move.l	#$4000+$1a00,d0
	move.l	#$10002,d1
	jsr	AllocMem(a6)
	move.l	d0,chip_pointer
	beq	clean_exit

	move.l	d0,trkbuffer

	;File-laden

	bsr	Load_File
	beq	clean_exit

	ENDC

	move.l	ExecBase,a6
	jsr	Disable(a6)

	lea	custom,a5

	bsr	setup		;Setup Disk-IO-Registers
	bsr	setup_config	;Check Drives

	bsr	save_file

;	bsr	search_disks	;Search for Apidya Disks.

	move.l	ExecBase,a6
	jsr	Enable(a6)

clean_exit:
	IFNE	Dos

	move.l	ExecBase,a6

	move.l	DosBase,d0
	beq.s	.no_dos
	move.l	d0,a1
	jsr	CloseLibrary(a6)

.no_dos:
	move.l	chip_pointer,d0
	beq.s	.no_chip
	move.l	d0,a1
	move.l	#$4000+$1a00,d0
	jsr	FreeMem(a6)
.no_chip:
	move.l	file_adr,d0
	beq.s	.no_file
	move.l	d0,a1
	move.l	file_len,d0
	jsr	FreeMem(a6)
.no_file:
	ENDC
	moveq	#0,d0
	rts

Load_File:
	move.l	DosBase,a6
	move.l	#filename,d1
	move.l	#1005,d2
	jsr	Open(a6)
	move.l	d0,handle
	beq.s	.error

	move.l	handle,d1
	moveq	#0,d2
	moveq	#1,d3
	jsr	Seek(a6)
	move.l	handle,d1
	moveq	#0,d2
	moveq	#-1,d3
	jsr	Seek(a6)
	move.l	d0,file_len
	beq.s	.close_error

	move.l	ExecBase,a6
	move.l	#$10000,d1
	jsr	AllocMem(a6)
	move.l	d0,file_adr
	beq	.close_error

	move.l	DosBase,a6
	move.l	handle,d1
	move.l	file_adr,d2
	move.l	file_len,d3

	jsr	Read(a6)

	move.l	handle,d1
	jsr	Close(a6)

	moveq	#1,d0
	rts
.error:
	moveq	#0,d0
	rts

.close_error:
	move.l	handle,d1
	move.l	DosBase,a6
	jsr	Close(a6)
	moveq	#0,d0
	rts

write_useage:
	move.l	DosBase,a6
	jsr	Output(a6)
	move.l	d0,handle

	move.l	handle,d1
	move.l	#useage_txt,d2
	move.l	#useage_len,d3
	jmp	Write(a6)

read_command_line:
	move.w	d0,d7

	bsr	read_unit

	lea	filename,a1
	bsr	read_string
	bne.s	.no_pars

	bsr	read_number
	cmp.l	#$ffff,d0
	bhi.s	.no_pars
	move.w	d0,Disk_Sync
	bsr	read_number
	cmp.l	#$ffff,d0
	bhi.s	.no_pars
	move.w	d0,diskcode
	bsr	read_number
	cmp.l	#79,d0
	bhi.s	.no_pars
	move.b	d0,Disk_Track
	bsr	read_number
	cmp.l	#1,d0
	bhi.s	.no_pars
	move.b	d0,Disk_Side
	bsr	read_number
	bmi.s	.ok
	cmp.l	#$1a00,d0
	bhi.s	.no_pars
	move.w	d0,Disk_Offset
.ok:
	moveq	#1,d0
	rts

.no_pars:
	moveq	#0,d0
	rts

read_unit:
	bsr	skip_spaces
	cmp.b	#$a,(a0)
	beq.s	.out

	move.l	a0,a1
	move.w	d7,d6

	bsr	.get_char
	bmi.s	.out
	and.b	#$df,d0
	cmp.b	#"D",d0
	bne.s	.out2
	bsr	.get_char
	bmi.s	.out
	and.b	#$df,d0
	cmp.b	#"F",d0
	bne.s	.out2
	moveq	#0,d0
	bsr	.get_char
	bmi.s	.out
	sub.b	#"0",d0
	cmp.b	#3,d0
	bhi.s	.out2
	move.w	d0,Disk_Unit
	bsr	.get_char
	bmi.s	.out
	cmp.b	#":",d0
	bne.s	.out2
	bsr	.get_char
	bmi.s	.out
	cmp.b	#" ",d0
	bne.s	.out2
.out:
	rts
.out2:
	move.l	a1,a0
	move.w	d6,d7
	rts

.get_char:
	move.b	(a0)+,d0
	subq.w	#1,d7
	rts

read_string:
	bsr	skip_spaces
	cmp.b	#$a,(a0)
	beq	.no_par

	moveq	#0,d5
	move.b	(a0)+,d0
	subq.w	#1,d7
	bmi.s	.no_par
	cmp.b	#34,d0
	bne.s	.no_quote
	st	d5
	move.b	(a0)+,d0
	subq.w	#1,d7
	bmi.s	.no_par
.no_quote:
	move.b	d0,(a1)+
	move.b	(a0)+,d0
	subq.w	#1,d7
	bmi.s	.no_par
	cmp.b	#34,d0
	beq.s	.end
	tst.b	d5
	bne.s	.no_quote
	cmp.b	#" ",d0
	bne.s	.no_quote
.end:
	moveq	#0,d0
	clr.b	(a1)
	rts
.no_par:
	moveq	#1,d0
	rts

read_number:
	bsr	skip_spaces
	cmp.b	#$a,(a0)
	beq	.no_par
	cmp.b	#"$",(a0)
	beq.s	.read_hex
	moveq	#0,d0
.loop:
	moveq	#0,d1
	move.b	(a0)+,d1
	subq.w	#1,d7
	bmi.s	.no_par
	sub.b	#"0",d1
	cmp.b	#9,d1
	bhi.s	.end
	mulu	#10,d0
	add.w	d1,d0
	bra.s	.loop

.read_hex:
	addq.l	#1,a0
	subq.w	#1,d7
	bmi.s	.no_par
	moveq	#0,d0
.hloop:
	move.b	(a0)+,d1
	subq.w	#1,d7
	bmi.s	.no_par
	cmp.b	#"A",d1
	blt.s	.ok
	and.b	#$df,d1
.ok:
	sub.b	#"0",d1
	bmi.s	.end
	cmp.b	#9,d1
	bls.s	.use

	subq.b	#7,d1
	cmp.b	#10,d1
	blo.s	.end
	cmp.b	#15,d1
	bhi.s	.end
.use:
	asl.l	#4,d0
	or.b	d1,d0
	bra.s	.hloop

.no_par:
	moveq	#-1,d0
.end:
	rts

skip_spaces:
	move.b	(a0)+,d0
	subq.w	#1,d7
	bmi.s	.panic
	cmp.b	#" ",d0
	beq.s	skip_spaces
.panic:
	addq.w	#1,d7
	subq.l	#1,a0
	rts

myclist:
	dc.w	$0180,$f00
	dc.w	$8007,$fffe
	dc.w	$0180,$000
	dc.w	$ffff,$fffe

loadfile:
	move.l	a0,oldclist
	lea	filetable(pc),a0
	add.w	d0,d0
	add.w	d0,d0
	move.w	d0,d1
	add.w	d0,d0
	add.w	d0,d1

	move.b	(a0,d1.w),disk_num	;Disk
	move.b	1(a0,d1.w),start_track	;Spur
	move.b	2(a0,d1.w),start_head	;Kopf
	move.l	4(a0,d1.w),startpointer	;Adresse
	move.l	8(a0,d1.w),diskIOlen	;Lnge
	bsr	set_diskname
	bsr	loadit
.noload:
	rts

loadit:
	bsr	setup

	move.b	disk_num,d0
	lea	drive_disks(pc),a0
	moveq	#3,d1
.loop:
	cmp.b	(a0,d1.w),d0
	beq	.found
	dbf	d1,.loop

;	lea	text2(pc),a1
	bsr	showtext
	bsr	react_user
	bsr	resttext

	bra	.gotit

.found:
	move.w	d1,unit_num
.gotit:
	bsr	reselect

	move.b	start_track,d0
	bsr	stepto
	move.b	start_head,d0
	move.w	unit_num,d1
	lea	side(pc),a0
	move.b	d0,(a0,d1.w)
	bsr	selside
	bsr	checkdrive
	bsr	reselect
	bsr	motoron

	bsr	load

	bsr	motoroff
	rts

save_file:
	move.b	#1,disk_num
	move.w	Disk_Unit,unit_num
	bsr	reselect
	moveq	#0,d0
	move.b	Disk_Track,d0
	bsr	stepto
	move.b	Disk_Side,d0
	move.w	unit_num,d1
	lea	side(pc),a0
	move.b	d0,(a0,d1.w)

	bsr	selside

	bsr	reselect
	move.w	dmaconr(a5),d0
	or.w	#$8000,d0
	move.w	d0,olddma
.checkin:
	btst	#2,inbits
	beq	.no_disk

	bsr	reselect
	bsr	motoron

	move.l	file_adr,startpointer	;Adresse
	move.l	file_len,diskIOlen	;Lnge
	bsr	set_diskname

	bsr	save
.no_disk:
	bsr	motoroff

	rts

farbe:
	move.w	#$ffff,d0
.loop:
	move.w	d0,$dff180
	dbf	d0,.loop
	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-lnge 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	#$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

	lea	side(pc),a0
	eor.b	#1,(a0,d5.w)
	bne	.nexttrack
	bsr	stepin

	bra	.nexttrack
.end:
	rts

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

	move.l	trkbuffer,a0
	lea	$be8(a0),a0
	move.w	#syncwert,(a0)+
	move.w	diskcode,(a0)+

	;Einfgen der Tracknummer.

	lea	tracknr(pc),a3
	moveq	#0,d0
	move.b	(a3,d5.w),d0
	swap	d0
	move.l	d0,-(sp)
	lsr.l	#1,d0
	bsr	encodeone
	subq.l	#2,a0		;Nur ein Wort einfgen.

	move.l	(sp)+,d0
	bsr	encodeone
	subq.l	#2,a0		;Wieder nur ein Wort.

	moveq	#0,d4
	move.w	#(trklen/4)-1,d3

.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	;Checksum
	move.l	d4,d0
	bsr	encodeone	;codieren.
	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	.correct
	bclr	#31,d0
.correct:
	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-lnge bergeben.

load:

	move.l	trkbuffer,a1
	move.w	#$e00,d7
.clear:
	clr.l	(a1)+
	dbf	d7,.clear

	move.w	#$1002,intena(a5)
	move.w	#$8210,dmacon(a5)
	move.w	#3,trycount
.nexttrack:
	bsr	selside
	clr.w	errorcount
.tryloop:
	move.w	#$7700,adkcon(a5)
	move.w	#0,dsklen(a5)
	move.w	#syncwert,dsksync(a5)
	move.w	#$b500,adkcon(a5)
	move.l	trkbuffer,dskpth(a5)
	move.w	#$9a20,dsklen(a5)	;$1a20 Bytes laden
	move.w	#$9a20,dsklen(a5)

	move.l	#$f0000,d0
.waitdma:
	subq.l	#1,d0
	beq	.timeout
	btst	#1,intreqr+1(a5)
	beq	.waitdma

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

	move.l	startpointer,a3

	move.l	trkbuffer,a1
	lea	-2(a1),a1
.sync:
	addq.l	#2,a1
	cmp.w	#syncwert,(a1)
	beq	.sync
	move.w	diskcode,d0
	cmp.w	(a1),d0		;Wenn kein Synchelp, dann neu laden.
	bne	.wrongdisk

	addq.l	#6,a1		;Synchelp und Tracknr berspringen.

	move.w	#(trklen/4)-1,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)+
	ELSEIF
	cmp.l	(a3)+,d0
	bne	farbe
	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
	lea	side(pc),a0
	eor.b	#1,(a0,d5.w)
	bne	.nexttrack
	bsr	stepin
	bra	.nexttrack
.end:
	rts

.checkerror:
	move.w	#$0f0,$dff180

	addq.w	#1,errorcount
	cmp.w	#3,errorcount
	bne	.tryloop
	subq.w	#1,trycount
	bmi	.end
	lea	tracknr(pc),a0
	move.b	(a0,d5.w),-(sp)
	bsr	resetdrive
	bsr	checkdrive
	bsr	reselect
	bsr	motoron
	bsr	selside
	move.b	(sp)+,d0
	bsr	stepto
	bra	.nexttrack

.timeout:
	move.w	#$4000,dsklen(a5)	;DMA stoppen.
	btst	#2,inbits
	beq	.notimeout

	;Echter Timeout -> Diskettenfehler.

;	lea	text1(pc),a1
	bsr	showtext
	bsr	waitmouse

	bsr	resttext
	bsr	reselect

	bsr	checkdrive
	bsr	reselect
	bsr	motoron
	bne	.notimeout
	moveq	#50,d0
.wloop:
	bsr	wait
	dbf	d0,.wloop
	bra	.tryloop

.wrongdisk:
	move.w	#$4000,dsklen(a5)
	btst	#2,inbits
	beq	.notimeout

.notimeout:
	bsr	motoroff
	moveq	#50,d0
.wloop2:
	bsr	wait
	dbf	d0,.wloop2

	bsr	reselect

;	lea	text2(pc),a1
	bsr	showtext

	bsr	react_user
	bsr	resttext

	bsr	reselect
	bsr	checkdrive
	bsr	reselect
	bsr	motoron
	bne	.notimeout

	bra	.tryloop
set_diskname:
	tst.b	disk_num
	bpl	.disk1
	move.w	#code2,diskcode
	moveq	#"2",d0
	bra	.disk2
.disk1:
	move.w	#code1,diskcode
	moveq	#"1",d0
.disk2:
;	move.b	d0,disk_name
	rts

stepto:
	lea	tracknr(pc),a0
	cmp.b	(a0,d5.w),d0
	beq	.done
	blt	.out
	bsr	stepin
	bra	stepto
.out:
	bsr	stepout
	bra	stepto
.done:
	rts

resetdrive:
	bsr	motoroff
	bsr	reselect
	move.b	selmask,d0
	bset	#1,d0
	move.b	d0,selmask	;Step-richtung festlegen

	bsr	wait
.loop:
	btst	#4,inbits
	beq	.done
	bsr	dostep
	bra	.loop
.done:
	lea	tracknr(pc),a0
	move.b	#0,(a0,d5.w)
	rts

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

stepout:
	move.b	selmask,d7
	bset	#1,d7
	move.b	d7,selmask
	bsr	wait
	lea	tracknr(pc),a0
	subq.b	#1,(a0,d5.w)
	bra	dostep

stepin:
	move.b	selmask,d7
	bclr	#1,d7
	move.b	d7,selmask
	bsr	wait
	lea	tracknr(pc),a0
	addq.b	#1,(a0,d5.w)
	bra	dostep

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

	rts

checkdrive:
	bsr	reselect
	move.w	dmaconr(a5),d0
	or.w	#$8000,d0
	move.w	d0,olddma
.checkin:
	btst	#2,inbits
	bne	.out

;	lea	text2(pc),a1
	bsr	showtext

	bsr	react_user
	bra	resttext

.out:
	bsr	resttext
	rts

motoron:
	move.b	#%01111001,outbits
	bclr	#7,selmask
	move.b	selmask,outbits

	move.b	#mili50&$ff,ciab+talo
	move.b	#mili50/$100,ciab+tahi

	moveq	#20,d0
.wait2:
	bset	#0,ciab+cra
.wait:
	btst	#0,ciab+icr
	beq.s	.waiton
	subq.w	#1,d0
	beq	.fail
	bra	.wait2
.waiton:
	btst	#5,inbits
	bne	.wait

	move.b	#mili3&$ff,ciab+talo
	move.b	#mili3/$100,ciab+tahi
	moveq	#0,d0
	rts		;Zero-flag is set.

.fail:
	move.b	#mili3&$ff,ciab+talo
	move.b	#mili3/$100,ciab+tahi
	moveq	#1,d0	;Clear	Zero-flag
	rts

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

seldrive:
	moveq	#0,d5
	move.w	d0,unit_num
	move.w	d0,d5
	addq.w	#3,d0
	move.b	selmask,d7
	or.b	#%01111001,d7
	and.b	#%11111001,d7	;Motorzustand lassen, wie er ist.
	bclr	d0,d7
	move.b	d7,selmask
	move.b	d7,outbits
	rts

reselect:
	move.w	unit_num,d0
	bra	seldrive

unselect:
	or.b	#%01111000,selmask
	move.b	selmask,outbits
	rts

selside:
	lea	side(pc),a0
	move.b	(a0,d5.w),d0
	tst.b	d0
	beq	.upper
	bset	#2,selmask
	bra	.wait
.upper:
	bclr	#2,selmask
.wait:
	move.b	selmask,outbits
	move.b	#mili50&$ff,ciab+talo
	move.b	#mili50/$100,ciab+tahi
	bset	#0,ciab+cra
.loop:
	btst	#0,ciab+icr
	beq.s	.loop
	bset	#0,ciab+cra
.loop2:
	btst	#0,ciab+icr
	beq.s	.loop2

	move.b	#mili3&$ff,ciab+talo
	move.b	#mili3/$100,ciab+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	ciab+cra,d0
	and.b	#%11000000,d0
	or.b	#%00001000,d0
	move.b	d0,ciab+cra
	move.b	#%01111111,ciab+icr

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

	bsr	wait
	rts

	;Routine checkt stndig alle vier Drives und prft, ob
	;die geforderte Diskette eingelegt wurde.

react_user:
	bsr	search_disks

	lea	drive_bits(pc),a0
	clr.l	(a0)

	move.w	unit_num,d0
	lea	tracknr(pc),a0
	move.b	(a0,d0.w),-(sp)	;Tracknummer, bei der das Laden stehenblieb
	lea	side(pc),a0
	move.b	(a0,d0.w),-(sp)	;Surface, bei der das Laden stehenblieb

	;Alle Drives durchsuchen, bei denen Diskchange an ist.
.again:
	move.w	#3,unit_num
	lea	drive_bits(pc),a0
	lea	drive_flags(pc),a1
.loop1:
	move.w	unit_num,d5
	bset	#7,selmask
	tst.b	(a0,d5.w)
	beq	.noton
	bclr	#7,selmask
	move.b	#%01111001,outbits
.noton:
	bsr	reselect

	tst.b	(a1,d5.w)		;Valid drive ?
	beq	.nochange

	btst	#2,inbits
	bne	.motoroff

	move.b	#%01111001,outbits	;Motor on
	bclr	#7,selmask
	move.b	selmask,outbits		;Probably no Disk inserted.
	st	(a0,d5.w)		;Flag fr Motor on setzen.
	bra	.nochange

.motoroff:				;A Disk is inserted!
	move.b	#%11111001,outbits	;Motor off
	bset	#7,selmask
	move.b	selmask,outbits
	clr.b	(a0,d5.w)		;Flag fr Motor off

.nochange:
	subq.w	#1,unit_num
	bpl	.loop1

	;Nun sind die Motoren der Laufwerke an, in denen keine Diskette ist.
	;Wo der Motor an ist, wird getestet, ob eine Diskette drin ist.

	move.w	#3,unit_num
.loop2:
	move.w	unit_num,d0
	lea	drive_bits(pc),a0
	tst.b	(a0,d0.w)
	beq	.notest

	bclr	#7,selmask
	move.b	#%01111001,outbits

	bsr	reselect
	lea	drive_flags(pc),a0
	tst.b	(a0,d5.w)
	beq	.notest

	btst	#5,inbits
	bne	.notest

	;Anscheinend ist eine Diskette eingelegt. Nachprfen!

	moveq	#50,d0
.waitit:
	bsr	wait
	dbf	d0,.waitit

	bsr	searchone

	lea	drive_disks(pc),a0
	tst.b	(a0,d5.w)
	beq	.notest

	lea	drive_bits(pc),a0
	clr.b	(a0,d5.w)		;Es ist eine Disk drin !

.notest:
	subq.w	#1,unit_num
	bpl	.loop2

	moveq	#3,d0
	lea	drive_disks(pc),a0
	move.b	disk_num,d1
.loop3:
	cmp.b	(a0,d0.w),d1
	beq	.found
	dbf	d0,.loop3

	bra	.again
.found:
	move.w	d0,-(sp)

	;Alle Motoren wieder Ausschalten.
	move.w	#3,unit_num
.loop4:
	bsr	reselect
	bsr	motoroff
	subq.w	#1,unit_num
	bpl	.loop4

	move.w	(sp)+,d0
	move.w	d0,unit_num

	lea	side(pc),a0
	move.b	(sp)+,(a0,d0.w)	;Surface, bei der das Laden stehenblieb

	move.w	unit_num,d0
	lea	tracknr(pc),a0
	move.b	(sp)+,d0	;Tracknummer, bei der das Laden stehenblieb
	bsr	stepto
	bsr	selside

	rts

	;Routine durchsucht alle vier Drives und merkt sich die
	;enthaltenen Disketten.

search_disks:
	move.w	#0,unit_num
	clr.l	drive_disks
.nextdrive:
	bsr	searchone
	addq.w	#1,unit_num
	cmp.w	#4,unit_num
	blt	.nextdrive
	clr.w	unit_num
	rts

searchone:
	move.w	unit_num,d5
	lea	drive_flags(pc),a0
	tst.b	(a0,d5.w)
	beq	.nodrive
	bsr	reselect

	lea	tracknr(pc),a0
	tst.b	(a0,d5.w)
	bne	.notzero

	moveq	#1,d0
	bsr	stepto
	bra.s	.ok
.notzero:
	bsr	stepin

	moveq	#5,d0		;18 ms Delay
.loop:
	bsr	wait
	dbf	d0,.loop

	bsr	stepout
.ok:
	btst	#2,inbits	;Disk inserted ?
	beq	.nodrive

	move.b	#%01111001,outbits
	bclr	#7,selmask
	move.b	selmask,outbits
	move.l	#$f0000,d0
.waitmotor:
	subq.l	#1,d0
	beq	.nodrive
	btst	#5,inbits
	bne	.waitmotor

	move.l	trkbuffer,a0
	clr.l	(a0)+
	clr.l	(a0)+

	move.w	#$1002,intena(a5)
	move.w	#$8210,dmacon(a5)
	bsr	selside
	move.w	#$7700,adkcon(a5)
	move.w	#0,dsklen(a5)
	move.w	#syncwert,dsksync(a5)
	move.w	#$9500,adkcon(a5)
	move.l	trkbuffer,dskpth(a5)
	move.w	#$8010,dsklen(a5)	;$10 Bytes laden
	move.w	#$8010,dsklen(a5)

	move.l	#$f0000,d0
.waitdma:
	subq.l	#1,d0
	beq	.nodrive
	btst	#1,intreqr+1(a5)
	beq	.waitdma

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

	move.l	trkbuffer,a1
	lea	-2(a1),a1
.sync:
	addq.l	#2,a1
	cmp.w	#syncwert,(a1)
	beq	.sync

	lea	drive_disks(pc),a0
	move.w	(a1),d0
	cmp.w	#code1,d0
	beq	.disk1
	cmp.w	#code2,d0
	bne	.nodrive
	st	(a0,d5.w)
	bra	.nodrive
.disk1
	move.b	#1,(a0,d5.w)
.nodrive:
	bsr	motoroff
	rts

setup_config:
	moveq	#0,d0
	bsr	seldrive
	bsr	resetdrive

	move.w	#1,unit_num
	move.l	#$ff000000,drive_flags

.nextdrive:
	bsr	reselect

	move.b	#%01111001,outbits
	bclr	#7,selmask
	move.b	selmask,outbits		;Motor on

	move.b	#%11111001,outbits
	bset	#7,selmask
	move.b	selmask,outbits		;Motor off
	bsr	unselect

	moveq	#0,d2		;Longword to read in Drive Type!
	moveq	#31,d6
.loop:
	bsr	reselect
	bsr	wait
	move.b	inbits,d1
	and.b	#%00100000,d1
	ror.b	#5,d1
	lsl.l	#1,d2
	or.b	d1,d2
	bsr	unselect
	bsr	wait

	dbf	d6,.loop

	tst.l	d2
	bne	.nodisk

	bsr	reselect
	bsr	resetdrive

	move.w	unit_num,d0
	lea	drive_flags(pc),a0
	st	(a0,d0.w)

.nodisk:
	addq.w	#1,unit_num
	cmp.w	#4,unit_num
	blt	.nextdrive

	rts

waitmouse:
	btst	#6,$bfe001
	bne	waitmouse
	rts

showtext:
	bsr	farbe
	rts

resttext:
;	move.l	oldclist,cop1lch(a5)
	rts

messclist1:
	dc.w	$00e0,$0000
	dc.w	$00e2,$0000
	dc.w	$ffff,$fffe

	;Filetable enthlt Eintrge ber die mglichen zu ladenden Files.

	;Format :
	;dc.b	Disk	(1/-1)
	;dc.b	Spur
	;dc.b	Kopf
	;dc.b	PAD
	;dc.l	Adresse
	;dc.l	Lnge

	;-----
	;12 Bytes pro Eintrag

filetable:

	;Testfile

	dc.b	1
	dc.b	1
	dc.b	0
	dc.b	0	;PAD
	dc.l	$a00
	dc.l	trklen*56

useage_txt:	dc.b	"Longtrack-Save-System V1.0",$a
		dc.b	"USEAGE : UNIT NAME SYNC DISKCODE TRACK SIDE [OFFSET]",$a
useage_len =	*-useage_txt

dosname:	dc.b	"dos.library",0

	even

startpointer:	dc.l	0
diskIOlen:	dc.l	0
oldclist:	dc.l	0
trkbuffer:	dc.l	bufferstart
handle:		dc.l	0
file_len:	dc.l	0
file_adr:	dc.l	0

chip_pointer:	dc.l	0

DosBase:	dc.l	0

olddma:		dc.w	0

drive_flags:	dc.b	0,0,0,0	;Vier Drives
drive_disks:	dc.b	0,0,0,0
drive_bits:	dc.b	0,0,0,0
side:		dc.b	0,0,0,0
tracknr:	dc.b	0,0,0,0

diskcode:	dc.w	code1	;Erkennung der Disketten Nummer.
unit_num:	dc.w	0
errorcount:	dc.w	0
trycount:	dc.w	0
selmask:	dc.b	0
disk_num:	dc.b	1
start_head:	dc.b	0
start_track:	dc.b	0

Disk_Sync:	dc.w	0
Disk_Track:	dc.b	0
Disk_Side:	dc.b	0
Disk_Offset:	dc.w	0
Disk_Unit:	dc.w	0

filename:	ds.b	256
