 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

	lea	__BSSBAS,a0	; get base of BSS
	moveq	#0,d1
	move.l	#__BSSLEN,d0	; get length of BSS in longwords
	bra.s	clr_lp		; and clear for length given

clr_bss	move.l	d1,(a0)+
clr_lp	dbf	d0,clr_bss

; 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	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 V37 or greater.",10,0
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 _WBenchMsg
 XDEF __StackPtr

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

   END
