; Loader.Exe.S: Source for loading data from Disk Images.
;   Before calling 'LoadBytes', setup the registers as follows:
;	D0=Offset into file
;	D1=Length to read
;	D2=Disk number (1-to-NumDisks)
;	A0=Address to load to
;
;                                Mars Bar

	Section	"LoaderCode",Code_F
	Opt	C-

Execbase	=	4
OpenLibrary	=	-408
CloseLibrary	=	-414

Open		=	-30
Close		=	-36
Seek		=	-66
Read		=	-42

Start:	Bsr	OpenDos
	Bsr	SaveProperVBase
	
	Lea	FileNames,A4
	Bsr	OpenFiles
	
; ---------------------------------------------- Start Of Patching ---------

	Move.L	#0,D4
	Move.L	#$CE400/$200,D1
	Move.L	#$B000/$200,D2
	Move.L	#$4C000,A0
	Bsr	Loader1
	Jsr	$4C020
	
	Move.L	#$400/$200,D1
	Move.L	#$1200/$200,D2
	Move.L	#$C0000,A0
	Move.L	#0,D4
	Bsr	Loader1

	Lea	$C0000,A0
	Move.L	#$100000,-4(A0)
	Move.W	#$4EF9,$c01c0
	Move.L	#Loader,$C01c2
	Jmp	$C0000

Loader:	Movem.L	D0-D7/A0-A6,-(Sp)
	Mulu	#$200,D1
	Mulu	#$200,D2
	Move.L	D1,D0
	Move.L	D2,D1
	Move.L	D4,D2
	Add.L	#1,D2
	Bsr	LoadBytes
	Movem.L	(Sp)+,D0-D7/A0-A6
	Movem.L	(Sp)+,D2-D7/A0-A6
	Clr.L	D0
	Tst.L	D0
	Rts

Loader1:Movem.L	D0-D7/A0-A6,-(Sp)
	Mulu	#$200,D1
	Mulu	#$200,D2
	Move.L	D1,D0
	Move.L	D2,D1
	Move.L	D4,D2
	Add.L	#1,D2
	Bsr	LoadBytes
	Movem.L	(Sp)+,D0-D7/A0-A6
	Clr.L	D0
	Tst.L	D0
	Rts

; ------ End Of Patching ---------------------------------------------------
	
OpenFiles:				; A4=List of filename pointers (0=End)
	Lea	FilePointers,A5
.AnotherFile:
	Move.L	(A4)+,FileNamePointer
	Tst.L	FileNamePointer
	Beq.S	.NoMoreFiles
	Bsr	OpenFile
	Move.L	FileBCPL,(A5)+
	Bra.S	.AnotherFile
.NoMoreFiles:
	Rts

OpenDos:Move.L	ExecBase,A6
	Lea	Dosname,A1
	Moveq.L	#0,D0
	Jsr	OpenLibrary(A6)
	Move.L	D0,DosBase
	Rts

OpenFile:Move.L	DosBase,A6
	Move.L	FileNamePointer,D1
	Move.L	#1005,D2
	Jsr	Open(A6)
	Move.L	D0,FileBcpl
	Rts

LoadBytes:
	Move.l	D0,d4		; Offset
	Move.l	d1,d5		; Length
	Move.l	a0,a4		; Address To Load To

	Subq.l	#1,d2		; Disk Number
	Mulu	#4,d2
	Lea	FilePointers,a2
	Move.l	(a2,d2.l),d6	; File BCPL

	Bsr	removeinterrupts
	Bsr	loaddata	
	Bsr	restoreinterrupts
	Rts

RemoveInterrupts:
	Movem.l	d0-d7/a0-a6,-(sp)
	Move.W	#$8000,D0
	Move.w	$dff01c,OldInts
	Move.w	$dff01e,OldIntr
	Move.w	$dff010,OldDsk
	Or.W	D0,OldDsk
	Or.W	D0,OldInts
	Or.W	D0,OldIntr
	Move.w	#$7fff,$dff09a
	Move.w	#$7fff,$dff09c
	Move.w	#$7fff,$dff09e
	Bsr	savecurrentvbase
	Bsr	restorepropervbase
	Move.w	#$C008,$dff09a
	Movem.l	(sp)+,d0-d7/a0-a6
	Rts

RestoreInterrupts:
	Movem.l	d0-d7/a0-a6,-(sp)
	Move.w	#$7fff,$dff09a
	Move.w	#$7fff,$dff09c
	Move.w	#$7fff,$dff09e
	Bsr	restorecurrentvbase
	Move.w	oldints,$dff09a
	Move.w	oldintr,$dff09c
	Move.w	olddsk,$dff09e
	Movem.l	(sp)+,d0-d7/a0-a6
	Rts

LoadData:
	Movem.l	d0-d7/a0-a6,-(sp)	
	Move.l	DosBase,a6
	Move.l	d6,d1
	Move.l	d4,d2
	Move.l	#-1,d3
	Jsr	-66(a6)
	Move.l	d6,d1
	Move.l	a4,d2
	Move.l	d5,d3
	Jsr	-42(a6)
	Movem.l	(sp)+,d0-d7/a0-a6
	Rts

SaveProperVbase:
	Movem.L	D0/A0-A1,-(Sp)
	Lea	$0.L,A0
	Lea	VBasePropDat,A1
	Move.L	#$BF,D0
.Loop:	Move.B	(A0)+,(A1)+
	Dbra.W	D0,.Loop
	Movem.L	(Sp)+,D0/A0-A1
	Rts

RestoreProperVBase:
	Movem.L	D0/A0-A1,-(Sp)
	Lea	$0.L,A0
	Lea	VbasePropDat,A1
	Move.L	#$BF,D0
.Loop:	Move.B	(A1)+,(A0)+
	Dbra.W	D0,.Loop
	Movem.L	(Sp)+,D0/A0-A1
	Rts

SaveCurrentVbase:
	Movem.L	D0/A0-A1,-(Sp)
	Lea	$0.L,A0
	Lea	VbasePresDat,A1
	Move.L	#$BF,D0
.Loop:	Move.B	(A0)+,(A1)+
	Dbra.W	D0,.Loop
	Movem.L	(Sp)+,D0/A0-A1
	Rts

RestoreCurrentVbase:
	Movem.L	D0/A0-A1,-(Sp)
	Lea	$0.L,A0
	Lea	VbasePresDat,A1
	Move.L	#$BF,D0
.Loop:	Move.B	(A1)+,(A0)+
	Dbra.W	D0,.Loop
	Movem.L	(Sp)+,D0/A0-A1
	Rts

DosName:Dc.B	'dos.library',0
	Even
DosBase:Dc.L	0

FileNamePointer:Dc.L	0
FileBCPL:	Dc.L	0

FilePointers:
Disk1BCPL:Dc.L	0
Disk2BCPL:Dc.L	0
Disk3BCPL:Dc.L	0
Disk4BCPL:Dc.L	0
Disk5BCPL:Dc.L	0
Disk6BCPL:Dc.L	0
Disk7BCPL:Dc.L	0
Disk8BCPL:Dc.L	0
Disk9BCPL:Dc.L	0
Disk10BCPL:Dc.L	0

OldInts:Dc.W	0
OldIntr:Dc.W	0
OldDsk:Dc.W	0

FileNames:
	Dc.L	Disk1Name,Disk2Name,Disk3Name
	Dc.L	0
Disk1Name:Dc.b	'Disk1',0
	Even
Disk2Name:Dc.b	'Disk2',0
	Even
Disk3Name:Dc.b	'Disk3',0
	Even

	Section	"BssData",BSS_F
VBasePropDat:Ds.b	$C0
VBasePresDat:Ds.b	$C0
