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

 XREF @main

 XREF _LVOOpenLibrary
 XREF _LVOOldOpenLibrary
 XREF _LVOCloseLibrary
 XREF _LVOSetSignal
 XREF _LVOForbid
 XREF _LVOWaitPort
 XREF _LVOGetMsg
 XREF _LVOReplyMsg
 XREF _LVOSetIoErr
 XREF _LVOAllocVec
 XREF _LVOFreeVec
 XREF _LVOOutput
 XREF _LVOWrite

 XREF _LinkerDB
 XREF __BSSBAS
 XREF __BSSLEN
 XREF _RESLEN
 XREF _RESBASE
 XREF _NEWDATAL

 XREF _AbsExecBase

LIBCALL	MACRO
	jsr _LVO\1(a6)
	ENDM

  SECTION StartCode,CODE

init:
	movem.l	d0/a0,-(sp)

; first off we will check for our workbench message, if any.  we will store
; the pointer to it in d7 temporarily until we actually copy the data
; segment over.  otherwise we wouldn't be residentiable.

	moveq	#0,d7		; clear out longword

; get address of our task
	move.l	_AbsExecBase.W,a6
	move.l	ThisTask(a6),a3

; clear any pending signals
	moveq	#0,d0
	move.l	#$00003000,d1
	LIBCALL	SetSignal

; check for workbench message
	tst.l	pr_CLI(a3)
	bne.s	FromCLI

	lea	pr_MsgPort(a3),a0
	LIBCALL	WaitPort
	lea	pr_MsgPort(a3),a0
	LIBCALL	GetMsg
	move.l	d0,d7

FromCLI:
	lea	DOSlib(pc),a1
	moveq	#37,d0
	LIBCALL	OpenLibrary
	tst.l	d0
	bne.s	DoMain

	lea	DOSlib(pc),a1
	LIBCALL	OldOpenLibrary
	tst.l	d0
	beq.s	bomb

	move.l	d0,a6
	LIBCALL	Output
	move.l	d0,d1
	beq.s	bomb

	lea	Msg1(pc),a0
	move.l	a0,d2
	moveq	#Msg1Len,d3
	LIBCALL	Write

	move.l	a6,a1
	move.l	_AbsExecBase.W,a6
	LIBCALL	CloseLibrary

bomb:	addq.l	#8,sp		; pop d0/a0 off stack

	move.l	d7,d0		; check if we have a workbench startup
	bsr	ReplyWB		; message and reply it if so

	moveq	#0,d0
	rts

DoMain:
	move.l	d0,-(sp)

	lea	_LinkerDB,a4
	sub.l	#_RESBASE,a4

; get mem to hold data and bss stuff
	move.l	#_RESLEN,d0
	move.l	#MEMF_PUBLIC+MEMF_CLEAR,d1
	LIBCALL	AllocVec
	tst.l	d0
	bne.s	gotmem

; no mem available so bomb out
	move.l	d7,d0		; check for wb startup message and reply
	bsr	ReplyWB		; it if present

	move.l	(sp)+,a6	; get dos base
	addq.l	#8,sp		; pop d0/a0 off of stack

	moveq	#ERROR_NO_FREE_STORE,d1
	LIBCALL	SetIoErr

	move.l	a6,a1
	move.l	_AbsExecBase.W,a6
	LIBCALL	CloseLibrary

	moveq	#20,d0
	rts

; get ready to copy data over into freshly alloced data area
gotmem:	move.l	d0,a0
	move.l	d0,a2

	move.l	d0,a1
	move.l	#_NEWDATAL,d0
cpy:	move.l	(a4)+,(a0)+
	subq.l	#1,d0
	bne.s	cpy

; now do the relocs for resident data
	move.l	(a4)+,d0
reloc:	beq.s	nreloc
	move.l	a1,a0
	add.l	(a4)+,a0
	add.l	(a0),a2
	move.l	a2,(a0)
	move.l	a1,a2
	subq.l	#1,d0
	bra.s	reloc

nreloc:	move.l	a1,a4
	add.l	#_RESBASE,a4

; stash some important junk away
	move.l	(sp)+,_DOSBase(a4)
	move.l	d7,_WBenchMsg(a4)

	move.l	_AbsExecBase.W,a6
	move.l	a6,_SysBase(a4)

; call our main program.  we call the main routine with the following
; arguments:
;
;   d0 = length of command line
;   a0 = pointer to command line
;   a1 = pointer to workbench startup message (or NULL)

	movem.l	(sp)+,d0/a0
	movem.l	sp,__StackPtr(a4)

	movea.l	d7,a1
	jsr	@main
	moveq	#0,d0
	bra.s	Exit

 XDEF _XCEXIT
_XCEXIT:
	move.l	4(sp),d0
 XDEF @XCEXIT
@XCEXIT:

Exit:	move.l	d0,d3			; save return code in safe place

	move.l	_WBenchMsg(a4),d0	; check if we need to reply the
	bsr	ReplyWB			; workbench startup message

	move.l	_DOSBase(a4),a6
	moveq	#0,d1
	LIBCALL	SetIoErr

	move.l	a6,a1
	move.l	_AbsExecBase.W,a6
	LIBCALL	CloseLibrary

	movea.l	__StackPtr(a4),sp

	move.l	a4,a1
	sub.l	#_RESBASE,a1
	LIBCALL	FreeVec

	move.l	d3,d0			; restore return code
	rts

; this subroutine is called when we try to check if we need to reply
; the workbench message.  This is done because we do this in more than
; one place.

ReplyWB:
	move.l	d0,d2
	beq.s	1$

	move.l	_AbsExecBase.W,a6
	LIBCALL	Forbid
	movea.l	d2,a1
	LIBCALL	ReplyMsg

1$	rts

; ---- This is the data we need for the startup module.  we don't put it in
;      a data segment, though, or it would end up being copied over when we
;      clone the data hunk and this stuff isn't needed anywhere else...

DOSlib	dc.b "dos.library",0

Msg1	dc.b "You need KickStart 2.0 or greater.",13
Msg1Len	EQU *-Msg1
	ds.w 0

; ---- This is the BBS segment that holds various startup junk for us.

   SECTION __MERGED,BSS

 XDEF _DOSBase
 XDEF _SysBase
 XDEF _IntuitionBase
 XDEF _WBenchMsg
 XDEF __StackPtr

_DOSBase	ds.b 4
_SysBase	ds.b 4
_IntuitionBase	ds.b 4
_WBenchMsg	ds.b 4
__StackPtr	ds.b 4

   END
