	INCLUDE	inc.i

_PRG	EQU	1	; Default...
_ACC	EQU	0
_AUT	EQU	0

	IFD	ACC
_ACC	EQU	1
_PRG	EQU 0
	ELSE

	IFD	AUT
_AUT	EQU	1
_ACC	EQU 1
	ENDC
	ENDC	; !ACC
	
;
; Initilization code; this is common to both 16 and 32 bit libraries,
; so be careful!
;
	INFO
	xref	__app		; short, declared in crtinit.c
	xref	__base		; BASEPAGE *, declared in crtinit.c
	xref	__heapbase	; void *
	xref	__stksize	; long, declared by user or in stack.c
	
	IF	_BASREL
	FINFO
	xref	__LinkerDB
	ENDC
	
	CODE
	IF	_REGARG
	xdef	@_start
	xref	@_acc_main
	xref	@_crtinit
@_start:
	ELSE
	xdef	__start
	xref	__acc_main
	xref	__crtinit
__start:
	ENDC
	
	
;
; Assumption: basepage is passed in a0 for accessories; for programs
; a0 is always 0.

	IF	_BASREL
	lea	__LinkerDB,a4
	ENDC
	sub.l	a6,a6		; clear a6 for debuggers
	IF	_AUT
	cmp.w	#0,a0		; test if acc or program
	beq.s	__startprg	; if a program, go elsewhere
	tst.l	36(a0)		; also test parent basepage pointer
	bne.s	__startprg	; for acc's, it must be 0
	ENDC
	IF	_ACC
	move.l	a0,__base	; acc basepage is in A0
	move.l	__heapbase,sp	; stack must be set from heap
	add.l	__stksize,sp
	IF	_REGARG
	bra	@_acc_main
	ELSE
	bra	__acc_main	; function is in crtinit.c
	ENDC
	ENDC
;
; program startup code: doesn't actually do much, other than push
; the basepage onto the stack and call _start1 in crtinit.c
;
	IF	_PRG
__startprg:
	move.l	4(sp),a0	; get basepage
	move.l	a0,__base	; save it
	move.l	4(a0),d0	; get _base->p_hitpa
	bclr	#$0,d0		; round off
	move.l	d0,sp		; set stack (temporarily)
	IF	_REGARG
	bra	@_crtinit
	ELSE
	bra	__crtinit	; in crtinit.c
	ENDC
	ENDC

;
; _setstack: changes the stack pointer; called as
;     void setstack( void *newsp )
; called from crtinit.c once the new stack size has been decided upon
;
; WARNING WARNING WARNING: after you do this, local variables may no longer
; be accessible!
; destroys a1 and a7

	IF	_REGARG
	xdef	@_setstack
@_setstack:
	ELSE
	xdef	__setstack
__setstack:
	ENDC
	
	move.l	(sp)+,a1	; save return address
	IF	_REGARG
	move.l	a0,sp		; new stack pointer - from register
	ELSE
	move.l	(sp)+,sp	; new stack pointer - from stack
	ENDC
	subq.l	#4,sp		; fixup for tidy upon return
	jmp	(a1)		; back to caller

;
; interfaces for gprof: for crt0.s, does nothing, but for gcrt0.s branches
; to the appropriate subroutines
;
	IF	_REGARG
	xdef	@_monstartup
	xdef	@_moncontrol
	xdef	@__mcleanup
@_monstartup:
@_moncontrol:
@__mcleanup:
	ELSE
	xdef 	__monstartup
	xdef	__moncontrol
	xdef 	___mcleanup
__monstartup:
__moncontrol:
___mcleanup:
	ENDC
	rts
	end
