	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	= 6144

	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	no_file

	ENDC

	move.l	ExecBase,a6
	jsr	Disable(a6)

	lea	custom,a5

	bsr	save_file

	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

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

	move.l	handle,d1
	move.l	#nofile_txt,d2
	move.l	#nofile_len,d3
	jsr	Write(a6)
	bra	clean_exit

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

save_file:
	bsr	setup		;Setup Disk-IO-Registers
	moveq	#0,d0
	move.w	Disk_Unit,d0
	bsr	seldrive
	bsr	resetdrive
	bsr	motoron

	moveq	#0,d0
	move.b	Disk_Track,d0

	bsr	stepto
	move.b	Disk_Side,side
	bsr	selside
	move.l	file_adr,startpointer
	move.l	file_len,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-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
	addq.b	#1,side
	and.b	#1,side
	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

	moveq	#0,d4
	move.w	#$5ff,d3
	move.l	trkbuffer,a0
	add.l	#$ff0,a0
	move.w	Disk_Sync,(a0)+
	move.w	diskcode,(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

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,ciab+cra
.loop:
	btst	#0,ciab+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,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

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

nofile_txt:	dc.b	"File not found!",$a
nofile_len =	*-nofile_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
