; loader.asm


		INCLUDE "exec/types.i"
		INCLUDE "exec/exec.i"
		INCLUDE "libraries/dosextens.i"


		STRUCTURE	STACKDATA,0
		APTR	Packet
		LONG	ReturnVal
		APTR	DOSBase
		BPTR	Segment
		BYTE	STACKDATA_SIZE


XLIB:		MACRO
		XREF	_LVO\1
		ENDM

LINKEXE:	MACRO
		MOVEA.L _AbsExecBase,A6
		JSR	_LVO\1(A6)
		ENDM

LINKDOS:	MACRO
		MOVEA.L DOSBase(SP),A6
		JSR	_LVO\1(A6)
		ENDM


_AbsExecBase	EQU	4


		XLIB	OpenLibrary
		XLIB	CloseLibrary
		XLIB	LoadSeg
		XLIB	UnLoadSeg


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

StartModule:	DC.L	(EndModule-StartModule)/4	; for BCPL linking


EntryPoint:	SUBA.L	#STACKDATA_SIZE,SP

		LSL.L	#2,D1			; convert to byte pointer
		MOVE.L	D1,Packet(SP)

		CLR.L	ReturnVal(SP)		; no error - for now


OpenDOS:	LEA	DOSName(PC),A1
		CLR.L	D0
		LINKEXE OpenLibrary
		MOVE.L	D0,DOSBase(SP)
		BNE	LoadCode

		MOVE.L	#ERROR_INVALID_RESIDENT_LIBRARY,ReturnVal(SP)
		BRA	Return


LoadCode:	LEA	HandlerName(PC),A1
		MOVE.L	A1,D1
		LINKDOS LoadSeg
		MOVE.L	D0,Segment(SP)
		BNE	CallHandler

		MOVE.L	#ERROR_OBJECT_NOT_FOUND,ReturnVal(SP)
		BRA	CloseDOS


CallHandler:	LEA	SPsave(PC),A1
		MOVE.L	SP,(A1) 		; save current SP

		MOVE.L	Segment(SP),D0		; BPTR to segment
		LSL.L	#2,D0
		MOVEA.L D0,A0			; byte pointer to segment
		MOVE.L	Packet(SP),D0		; packet address
		MOVE.L	 D0,-(SP)		; push (not sure if safe above)

; --- Now, call the loaded handler code.
; --- It is sent the byte address of the startup packet passed to this code.

		JSR	4(A0)			; call first code in segment

		MOVEA.L SPsave(PC),SP		; restore SP


UnloadCode:	MOVE.L	Segment(SP),D1
		LINKDOS UnLoadSeg

CloseDOS:	MOVE.L	DOSBase(SP),A1
		LINKEXE CloseLibrary

Return: 	MOVE.L	ReturnVal(SP),D0	; retrieve return value
		ADDA.L	#STACKDATA_SIZE,SP
		RTS


SPsave: 	DC.L	0

DOSName:	DOSNAME

HandlerName:	DC.B	'L:'
AProcessName:	DC.B	'ID-handler',0


;	trailing definitions for BCPL linking

		CNOP	0,4			; align to lonword boundary

		DC.L	0			; End Marker
		DC.L	1			; Global 1
		DC.L	EntryPoint-StartModule	; Offset
		DC.L	1			; Highest Global Used

EndModule:	END
