
		include	'includes:misc/_hardware.i'
		
;-------------- AmigaDOS FileLoader v5.00

		lea	MFMBuffer,a2
		bsr.b	InitDrives

		lea	Filename(pc),a0
		lea	Buffer,a1
		bsr.b	LoadDOSFile
		rts

;-------------- AmigaDOS-FileLoader (OFS) Definitions -------------------------
;
;		Version 5.00 - (CIAA TIMING VERSION)
;		Written & Developed by 2-Cool of LSD!
;		Copyright İ 1992-1993. All Rights Are Reserved.
;
; _LVOInitDrives
; ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
; Save MFM Bufferptr for loader usage & steps drives to track zero.
;
; INPUTS:	a0=MFMBuffer (Ptr)
;
; OUTPUTS:	None.
;
; _LVOLoadDOSFile
; ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
; Load an AmigaDOS (OFS) File into your buffer (without stepping to track 0)
; You *MUST* call '_LVOInitDrives' BEFORE you access this routine!
;
; INPUTS:	a0=Filename (Ptr)
;		a1=Load Buffer (Ptr)
;
; OUTPUTS:	a0=Load Buffer (Ptr)
;		d0=Result Code (-1=LoadError, 0=LoadedOk)
;		d1=Filelength
;------------------------------------------------------------------------------

InitDrives:	lea	MFMPtr(pc),a1		;mfm buffer ptr
		move.l	a2,(a1)			;save MFM Ptr
		move.w	#$7fff,intena+_custom
		rts

LoadDOSFile:	push	d2-d7/a0-a6		;preserve registers
		lea	(ciabprb).l,a5		;ciab ptr
		bclr	#7,(a5)
		lea	VarBase(pc),a6		;varbase ptr
		bset	#3,(a5)
		exg	a1,a0

		move.l	a0,-(sp)		;save loadptr
		st	(a6)
		move.l	a0,LoadAdr-VarBase(a6)
		st	FileSize-VarBase(a6)
		bclr	#3,(a5)
		move.l	#880,d0			;load rootblock
		bsr.w	LoadSect

		movea.l	a1,a2
		moveq	#-1,d3
GetNameLen:	addq.l	#1,d3
		tst.b	(a2)+			;get filename length (bytes)
		bne.s	GetNameLen

		moveq	#0,d2
		move.l	d3,d4			;make copy of namelen
		move.l	d3,d6
		movea.l	a1,a3

CalcHash:	mulu.w	#13,d3
		move.b	(a1)+,d2		;get char from filename
		add.w	d2,d3
		andi.w	#$7FF,d3
		subq.w	#1,d4
		bne.s	CalcHash

		divu.w	#72,d3
		swap	d3
		lsl.w	#2,d3
		moveq	#0,d5
		move.l	6*4(a0,d3.w),d0
		beq.w	DriveOFF
		
File_Loop:	bsr.w	LoadSect

		moveq	#0,d5
		lea	432(a0),a1		;ptr to filename in block
		cmp.b	(a1)+,d6
		bne.s	NextSect

		movea.l	a3,a2
		move.w	d6,d3
		subq.w	#1,d3			;a2=filename ptr
check_name:	cmpm.b	(a1)+,(a2)+		; are they equal?
		dbne	d3,check_name		; check whole filename
		bne.s	NextSect
		
		move.l	324(a0),d0		;get blocklength (bytes)
		add.l	LoadAdr(pc),d0		;add destadr ptr
		move.l	d0,FileSize-VarBase(a6)	;save filesize
ReadLoop:	move.l	16(a0),d0
		beq.s	DriveOFF
		bsr.w	LoadSect

		lea	24(a0),a1		;a1=ptr to blockdata
		movea.l	LoadAdr(pc),a2		;get current pos
		move.l	FileSize(pc),d0
		move.l	#488-1,d7		;488 bytes per block
copyloop:	move.b	(a1)+,(a2)+		;copy block into buffer
		cmpa.l	d0,a2			;copy done?
		dbeq	d7,copyloop
		move.l	a2,LoadAdr-VarBase(a6)	;save current pos
		bra.s	ReadLoop

NextSect:	move.l	496(a0),d0		;is there another sector?
		bne.b	File_Loop

DriveOFF:	bset	#7,(a5)
		moveq	#0,d0			;clear errorcode
		bset	#3,(a5)
		tst.l	d5
		bne.s	LoadOk
		moveq	#-1,d0			;set errorcode
LoadOk:		bclr	#3,(a5)
		movea.l	(sp)+,a0		;restore loadptr

		move.l	FileSize-VarBase(a6),d1	;save filesize
		suba.l	a0,d1
		pull	d2-d7/a0-a6		;restore registers
		rts

;-------------- Wait 3ms

Wait3ms:	bclr	#0,(a5)
		bset	#0,(a5)

wait_3m:	move.b	#0,$500(a5)
		move.b	#$12,$600(a5)
		move.b	#$19,$E00(a5)
time_out:	btst	#0,$E00(a5)
		bne.s	time_out
wait_diskready:	btst	#5,$F01(a5)		;disk ready
		bne.s	wait_diskready
		rts

MoveIn:		bset	#1,(a5)
		bsr.s	Wait3ms
FindZero:	btst	#4,$F01(a5)		;found track 0?
		bne.s	MoveIn
		sf	(a6)
CheckTrk0:	tst.b	(a6)
		bmi.s	FindZero

FindTrack:	cmp.b	(a6),d2
		beq.s	wait_diskready
		bcc.s	MoveOut
		bset	#1,(a5)
		subq.b	#1,(a6)
		bra.s	FindLoop

MoveOut:	bclr	#1,(a5)
		addq.b	#1,(a6)
FindLoop:	bsr.s	Wait3ms
		bra.s	FindTrack

SectorError:	moveq	#0,d5			;d5=0 (an error occured)
		addq.l	#4,sp			;fix stack
		bra.b	DriveOFF

;-------------- Load any sector 0-1760

LoadSect:	cmp.w	#1760-1,d0		;maximum block
		bgt.s	SectorError

		move.l	MFMPtr(pc),a4		;mfm trackbuffer ptr
		move.l	d0,d2
		ext.l	d2
		divu.w	#11,d2			;11 sectors per track
		move.l	d2,d4
		swap	d4
		cmp.w	TrackNum-VarBase(a6),d2	;got right track?
		beq.s	DecodeMFM

		move.w	d2,TrackNum-VarBase(a6)
		bset	#2,(a5)			;set hi
		btst	#0,d2			;high or low side?
		beq.s	TrackLow
		bclr	#2,(a5)			;set low
TrackLow:	lsr.w	#1,d2
		bsr.b	CheckTrk0
		move.w	#5,RetryCount-VarBase(a6) ;retry load 5 times
		bra.s	ReadTrack

LoadError:	subq.w	#1,RetryCount-VarBase(a6) ;decrease load count
		bne.s	ReadTrack
		moveq	#-1,d2
		move.l	d2,(a6)
		bra.s	LoadSect

;-------------- Read tracks

ReadTrack:	btst	#2,$bfe001		; disk in drive?
		beq.s	LoadError

		move.l	MFMPtr(pc),a4		;track buffer ptr
		lea	_custom+dskpth,a0	;custom+dskpth
		move.l	a4,(a0)+		;dskpth
		move.w	#$8210,dmacon-$24(a0)	;	;dmacon
		move.l	#$00027F00,intreq-$24(a0)	;intreq,
		move.w	#$9500,adkcon-$24(a0)	;	;adkcon
		move.w	#$4489,dsksync-$24(a0)	;	;dsksync
		move.w	#$9A00,(a0)		;dsklen	;tracklength
		move.w	#$9A00,(a0)		;dsklen	;must do *TWICE* to trigger

		move.l	#$A0000,d7		;countdown timer
wait_dma:	subq.l	#1,d7			;decrease dmawait counter
		beq.s	LoadError
		btst	#1,$1f-$24(a0)		;diskblock done (intreq)
		beq.s	wait_dma
		
;-------------- Decode MFM

DecodeMFM:	lea	12800(a4),a2		;a2=decode buffer
		movea.l	a2,a0			;make copy of ptr
		move.l	#$55555555,d5
		moveq	#11-1,d1		;decode 11 blocks
NoGapFound:	cmpi.w	#$4489,(a4)+		;search for next sync
		bne.s	NoGapFound
		cmpi.w	#$4489,(a4)
		beq.s	NoGapFound
		movem.l	(a4),d2/d3
		bsr.s	DecodeLong
		lsr.w	#8,d2
		cmp.w	d4,d2			;compare checksums
		beq.s	Dloop1
		lea	1080(a4),a4		;ptr to next sync
		dbra	d1,NoGapFound		;do all 11 sectors in track
		bra.w	LoadError

Dloop1:		swap	d2
		cmp.b	TrackCMP-VarBase(a6),d2	;is it the right track?
		bne.w	LoadError
		lea	48(a4),a4		;skip the rest
		movem.l	(a4)+,d2-d3
		bsr.s	DecodeLong
		moveq	#0,d3
		move.w	#256-1,d7
dloop:		move.l	(a4)+,d4
		eor.l	d4,d3			;calculate checksum
		dbra	d7,dloop
		and.l	d5,d3
		cmp.l	d3,d2			;is checksum vaild?
		bne.w	LoadError

		lea	-1024(a4),a4
		moveq	#128-1,d7		;decode 2*128 longwords
decodenext:	move.l	512(a4),d3		;decode datablock
		move.l	(a4)+,d2
		and.l	d5,d2
		add.l	d2,d2
		and.l	d5,d3
		or.l	d3,d2
		move.l	d2,(a2)+		;store longword in buffer
		dbra	d7,decodenext
		rts

DecodeLong:	and.l	d5,d2
		add.l	d2,d2
		and.l	d5,d3
		or.l	d3,d2
		rts
EndLoad

LoadSize	=	EndLoad-LoadDOSFile

VarBase:	dc.w	0
TrackNum:	dc.b	0
TrackCMP:	dc.b	0
LoadAdr:	dc.l	0
FileSize:	dc.l	0
RetryCount:	dc.l	0
MFMPtr:		dc.l	0			;ptr to MFM Track Buffer

Filename:	dc.b	'1',0
MFMBuffer	ds.b	126*512			;26 sectors buffer (13k approx)
Buffer		ds.b	200*1024

		printt	'AmigaDOS-File Loader v5.00 (Hardware version)    - Written By 2-Cool of LSD!'
		printt	'ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ'
		printt	'Copyright İ 1992-1993 IDS - InterSect Development Software.'
		printt	'All Rights are Reserved.'
		printt	''
		printt	'DOSLoader size (in bytes) : '
		printv	LoadSize
		printt	''

		end
