;	MED module load routines by Teijo Kinnunen 1990
;	V3.00 module support added		22-Jan-1991
;	upgraded for V3.20 (OctaMED V2.00)	02-Aug-1991

;	Function: d0 = _LoadModule(a0)
;	a0 = module name
;	d0 = pointer to loaded module, zero if load failed

	xdef	_LoadModule
	xdef	_UnLoadModule
	code
_LoadModule:
	movem.l a2-a4/a6/d2-d6,-(sp)
	moveq	#0,d6			;d6 = return value (zero = error)
	move.l  a0,a4			;a4 = module name
	movea.l 4,a6
	lea     dosname(pc),a1
	moveq	#0,d0
	jsr     -$228(a6)		;OpenLibrary()
	tst.l   d0
	beq     xlm1
	move.l  d0,a3			;a3 = DOSBase
	move.l  d0,a6
	move.l  a4,d1			;name = d1
	move.l  #1005,d2		;accessmode = MODE_OLDFILE
	jsr     -$1e(a6)		;Open()
	move.l  d0,d4			;d4 = file handle
	beq     xlm2
	move.l  d4,d1
	moveq   #0,d2
	moveq   #1,d3			;OFFSET_END
	jsr     -$42(a6)		;Seek(fh,0,OFFSET_END)
	move.l  d4,d1
	moveq	#0,d3
	not.l   d3			;OFFSET_BEGINNING
	jsr     -$42(a6)		;Seek(fh,0,OFFSET_BEGINNING)
	move.l  d0,d5			;d5 = file size
	movea.l 4,a6
	moveq   #2,d1			;get chip mem
	jsr     -$c6(a6)		;AllocMem()
	tst.l   d0
	beq.s   xlm3
	move.l  d0,a2			;a2 = pointer to module
	move.l  d4,d1	;file
	move.l  d0,d2	;buffer
	move.l  d5,d3	;length
	move.l  a3,a6
	jsr     -$2a(a6)		;Read()
	cmp.l   d5,d0
	bne.s   xlm4			;something wrong...
	cmp.l   #'MMD0',(a2)
	bne.s   xlm4			;this is not a module!!!
	movea.l a2,a0
	bsr.s   _RelocModule
	move.l  a2,d6			;no error...
	bra.s   xlm3
xlm4:	move.l  a2,a1			;error: free the memory
	move.l  d5,d0
	movea.l 4,a6
	jsr     -$d2(a6)		;FreeMem()
xlm3:	move.l  a3,a6			;close the file
	move.l  d4,d1
	jsr     -$24(a6)		;Close(fhandle)
xlm2:	move.l  a3,a1			;close dos.library
	movea.l 4,a6
	jsr     -$19e(a6)
xlm1:	move.l  d6,d0			;push return value
	movem.l (sp)+,a2-a4/a6/d2-d6	;restore registers
	rts				;and exit...
dosname dc.b	'dos.library',0

;	Function: _RelocModule(a0)
;	a0 = pointer to module

; THIS FUNCTION IS A BIT STRANGELY ARRANGED AROUND THE SMALL RELOC-ROUTINE.
reloci	move.l	24(a2),d0
	beq.s	xloci
	movea.l	d0,a0
	moveq   #0,d0
	move.b  787(a1),d0	;number of samples
	subq.b  #1,d0
relocs:	bsr.s   relocentr
	move.l	-4(a0),d3	;sample ptr
	beq.s	nosyn
	move.l	d3,a3
	tst.w	4(a3)
	bpl.s	nosyn		;type >= 0
	move.w	20(a3),d2	;number of waveforms
	lea	278(a3),a3	;ptr to wf ptrs
	subq.w	#1,d2
relsyn:	add.l	d3,(a3)+
	dbf	d2,relsyn
nosyn:	dbf     d0,relocs
xloci	rts
norel	addq.l	#4,a0
	rts
relocentr:
	tst.l   (a0)
	beq.s   norel
	add.l   d1,(a0)+
	rts
_RelocModule:
	movem.l	a2-a3/d2-d3,-(sp)
	movea.l a0,a2
	move.l  a2,d1		;d1 = ptr to start of module
	bsr.s	relocp
	movea.l 8(a2),a1
	bsr.s	reloci
rel_lp	bsr.s	relocb
	move.l	32(a2),d0	;extension struct
	beq.s	rel_ex
	move.l	d0,a0
	bsr.s	relocentr	;ptr to next module
	bsr.s	relocentr	;InstrExt...
	addq.l	#4,a0		;skip sizes of InstrExt
; We reloc the pointers of MMD0exp, so anybody who needs them can easily
; read them.
	bsr.s	relocentr	;annotxt
	addq.l	#4,a0		;annolen
	bsr.s	relocentr	;InstrInfo
	addq.l	#8,a0
	bsr.s	relocentr	;rgbtable (not useful for most people)
	addq.l	#4,a0		;skip channelsplit
	bsr.s	relocentr	;NotationInfo
	move.l	d0,a0
	move.l	(a0),d0
	beq.s	rel_ex
	move.l	d0,a2
	bsr.s	relocp
	movea.l 8(a2),a1
	bra.s	rel_lp
rel_ex	movem.l	(sp)+,d2-d3/a2-a3
	rts

relocb	move.l	16(a2),d0
	beq.s	xlocb
	movea.l	d0,a0
	move.w  504(a1),d0
	subq.b  #1,d0
rebl	bsr.s   relocentr
	dbf     d0,rebl
xlocb	rts

relocp	lea	8(a2),a0
	bsr.s	relocentr
	addq.l	#4,a0
	bsr.s	relocentr
	addq.l	#4,a0
	bsr.s	relocentr
	addq.l	#4,a0
	bra.s	relocentr

;	Function: _UnLoadModule(a0)
;	a0 = pointer to module
_UnLoadModule:
	move.l  a6,-(sp)
	move.l  a0,d0
	beq.w   xunl
	movea.l 4,a6
	move.l  4(a0),d0
	beq.s   xunl
	movea.l a0,a1
	jsr     -$d2(a6)	;FreeMem()
xunl:	move.l	(sp)+,a6
	rts
	end
