
*************************************************************************

Yop Geir, here's the correct version of the loader (I hope). Somewhere in
the source is a bit of annotation for a protection by Maniac, another
coder from our group. I think everything speaks for itself. Track is the
starting track, or actually, cylinder. Range = 0-79. You can also make a
real trackloader by separating the upper and lower head. Range = 0-159.
Asm-One works the same way. It's a real track loader/saver in Asm-One and
not a cylinder one... Aantal is the number of cylinders (or tracks :-)
Aantal is btw a dutch word...oooeeeeehhhh, wow, not just a loader, but a
dutch lesson too :-) Aantal = number of ..., a few ..., some ... etc. !

*************************************************************************


	section	trackload,code_c

run:
j
	move.l	#start,$80.w
	trap	#0
	rts

start
	move.w	#0,track
	move.w	#5,aantal
	bsr.w	loader
	rte

;---------------------------------------------------------------------------

track:		dc.w	0	;starttrack
aantal:		dc.w	0	;number of tracks (min. = 1)

DRIVEON:
	MOVE.B	#$79,$bfd100
	bsr.w	wait_nops
	MOVE.B	#$79-%1000,$bfd100	;activate drive(s)
	bsr.w	wait_nops
WaitForDrive:
	BTST	#5,$bfe001
	BNE.S	WaitForDrive
	rts
DRIVEOFF:
	MOVE.B	#$F9,$bfd100
	bsr.w	wait_nops
	MOVE.B	#$F9-%1000,$bfd100	;deactiveate drive(s)
	bsr.w	wait_nops
	rts
UPPERHEAD:
	BCLR	#2,$bfd100
	bsr.w	wait_nops
	rts
LOWERHEAD:
	BSET	#2,$bfd100
	bsr.w	wait_nops
	rts
STEPIN:
	BSET	#1,$bfd100
	bsr.w	wait_nops
	rts
STEPOUT:
	BCLR	#1,$bfd100
	bsr.b	wait_nops
	rts
SEEKZERO:
	bsr.b	STEPIN
GoFindTrack0:
	BTST	#4,$bfe001
	BEQ.S	FoundTrack0
	bsr.b	STEPTRACk
	BRA.S	GoFindTrack0
FoundTrack0:
	rts
STEPTRACK:
	BCLR	#0,$bfd100
	bsr.b	wait_nops
	BSET	#0,$bfd100
	move.w	#$f0,$dff180
	move.l	d0,temp
	clr.l	d0
	move.b	$dff006,d0
	add.b	#240,d0
w1:	cmp.b	$dff006,d0
	bne.b	w1
	move.l	temp,d0
	move.w	#$0,$dff180
	rts
WAITDISK:
	MOVE.L	#$50000,d0
	MOVE.W	#$0002,$9c(a6)
WaitForDiskDMAToFinish:
	MOVE.W	$1e(a6),d1
	BTST	#1,d1
	BNE.S	DiskDMAReady
	SUBQ.L	#1,d0
	BNE.S	WaitForDiskDMAToFinish
DiskDMAReady:
	rts
temp:
	dc.l	0
wait_nops:
	move.w	#$f,$dff180
	move.l	d0,temp
	clr.l	d0
	move.b	$dff006,d0
	add.b	#10,d0
w2:	cmp.b	$dff006,d0
	bne.b	w2
	move.l	temp,d0
	move.w	#$0,$dff180
	rts
loader:
	bsr.w		DRIVEON			;drive 0 on
	bsr.w		SEEKZERO		;goto track 0
	bsr.w		STEPOUT			;step outside
	move.w		track,d7
	tst.w		d7
	beq.s		nonexttrack
	subq.w		#1,d7
nexttrack:
	bsr.w		STEPTRACK
	dbra		d7,nexttrack
nonexttrack:
	lea		$dff000,a6		;hardware base ->a6
	move.w		#$4489,$7e(a6)		;Syncword
	move.w		#$4000,$24(a6)		;disable writing
	move.w		#$7f00,$9e(a6)		;clear ADKCON
	move.w		#$9500,$9e(a6)		;MFM, No PRECOMP
	move.w		aantal(pc),d7		;number of tracks
	subq.w		#1,d7
	lea		buffer,a0		;decode buffer -> a0
doit:	bsr.w		LOWERHEAD
dolow:	bsr.s		readtrack		;read track
	bsr.b		decodedostrack		;decode track
	bne.s		dolow			;if ERROR -> read again
	bsr.w		UPPERHEAD
doup:	bsr.s		readtrack		;read track
	bsr.s		decodedostrack		;decode track
	bne.s		doup			;if ERROR -> read again
	bsr.w		STEPTRACK		;step a track
	dbf		d7,doit			;decode next track
	bsr.w		DRIVEOFF		;drive 0 off
	rts
readtrack:
	move.l		#trackbuffer,$20(a6)
	move.w		#$9980,$24(a6)		;read $1980 words
	move.w		#$9980,$24(a6)		;(Whole track)
	bsr.w		WAITDISK		;wait till disk DMA
	rts					;is finished
decodedostrack:
	lea		trackbuffer,a1		;pointer to trackbuffer
	move.l		#$55555555,d3
	moveq		#10,d5			;decode 11 blocks
decodenextblock:
	cmp.w		#$4489,(a1)+		;check for next sync word
	beq.s		nogapfound
nosyncfound:
	cmp.w		#$4489,(a1)+		;search for next sync
	bne.s		nosyncfound
nogapfound:
	cmp.w		#$4489,(a1)		;skip all remaining syncs
	bne.s		skippedsyncs
	addq.w		#2,a1
	bra.s		nogapfound
skippedsyncs:
	move.l		(a1)+,d0		;decode Info Blk.
	move.l		(a1)+,d1		;See article.
	and.l		d3,d0
	and.l		d3,d1
	add.l		d0,d0
	or.l		d1,d0
	move.l		d0,d1
	and.l		#$FF000000,d1		;check if header is alright
	cmp.l		#$FF000000,d1
	bne.s		headererror		;if not -> ERROR
	and.l		#$0000FF00,d0		;get sector number
	add.l		d0,d0
	move.l		a0,a2
	add.l		d0,a2			;add to get the right pos.
	add.w		#$28,a1			;skip the rest
	move.l		(a1)+,d4		;decode Data-Checksum
	move.l		(a1)+,d1		;store it in D4
	and.l		d3,d4
	and.l		d3,d1
	add.l		d4,d4
	or.l		d1,d4
	moveq		#127,d6			;decode 2*128 longwords
	clr.l		d2
decodenext:					;decode data block
	move.l		512(a1),d1
	move.l		(a1)+,d0
	eor.l		d0,d2			;calculate Checksum
	eor.l		d1,d2
	and.l		d3,d0			;decode longword
	and.l		d3,d1
	add.l		d0,d0
	or.l		d1,d0
						;put here your decrypt
						;routine (rip-protection)
						;(don't forget to encrypt
						;it first, or you'll get
						;a f****d up code)
						;e.g.
						;	not.l d0
						;or:
						;	eor.l	#$12345677,d0

	move.l		d0,(a2)+		;store longword in buffer
	dbf		d6,decodenext		;decode next longword
	and.l		d3,d2			;skip illegal bits
	cmp.l		d4,d2			;compare checksums
	bne.s		chksumerror		;in not =al -> error
	adda.w		#$0200,a1		;add for next block
	dbf		d5,decodenextblock
	adda.w		#$1600,a0		;update position in buffer
	clr.l		d0			;Return code : OK
	rts
chksumerror:
	move.w		#$00F0,$dff180		;Return code : ERROR
	moveq		#-1,d0	
	rts
headererror:
	move.w		#$0F00,$dff180		;Return code : ERROR
	moveq		#-1,d0
	rts
trackbuffer:
	blk.b		14000,0			;track buffer (+/- 12K)

buffer:
	blk.w		50000,0

;---------------------------------------------------------------------------
