
		;   C.A
		;
		;   (c)Copyright 1990, Matthew Dillon, All Rights Reserved
		;
		;   Amiga startup code for non-resident and resident DCC
		;   programs.
		;
		;   DLINK:
		;
		;   * __BSS_LEN   : # bytes of bss (occurs after DATA)
		;   * __DATA_LEN  : # bytes of initialized data to copy (if resident)
		;   * __DATA_BAS  : base of data
		;   * __RESIDENT  : is this code residentable?	If this variable
		;		    is set then there are no absolute data/bss
		;		    references except __DATA_BAS and there is
		;		    NO BSS MEMORY ALLOCATED AFTER THE DATA
		;		    SECTION.
		;
		;		    If this variable is not set then absolute
		;		    references refer to the same storage as
		;		    A4 relative accesses and uninitialized
		;		    BSS space exists just after the data section.
		;
		;		    Note that in the large-data model + fragmented
		;		    sections, there are usually real BSS hunks
		;		    floating about that have been zerod by
		;		    LoadSeg() (in this case __BSS_LEN could be 0)
		;
		;   COMPILER:
		;
		;   * If -r option specified when compiling then the compiler
		;     will generate autoinit code to handle data initialization
		;     that would otherwise require a reloc32 hunk.
		;
		;   * If -r or -md specified compiler references all data items
		;     using A4-Relative addressing.
		;
		;   C LIB CODE:
		;
		;   * Resident: Allocate (__DATA_LEN+__BSS_LEN)*4
		;     Not Res : zero out preallocated BSS.
		;
		;   * Generate A4 ref ptr to bss base + 32766 (uses Aztec's
		;     conventions).
		;
		;   * All library code uses the SMALL-DATA with alternate
		;     BSS and DATA section names (based in this source
		;     file) so the linker puts library related data/bss
		;     first.  BUT, BSS always comes after DATA unless
		;     you -frag the link (can't resident a frag'd link),
		;     so if there is more than 64KBytes of *initialized*
		;     data you must -frag the link.

		section text,code

		xref	__RESIDENT	    ; (dlink), executable is residentable
		xref	__BSS_LEN	    ; (dlink), length of BSS
		xref	__DATA_BAS	    ; (dlink), base of initialized data
		xref	__DATA_LEN	    ; (dlink), length of data

		xref	__main		    ; we call _main()

		xref	_LVOSetSignal
		xref	_LVOAllocMem
		xref	_LVOFreeMem

		xdef	__exit		    ; we are _exit()
		xdef	start
		xdef	_SysBase	    ; we export _SysBase

MEMF_CLEAR	equ	$00000001
MEMF_PUBLIC	equ	$00010000

start:
		movem.l D2-D7/A2-A6,-(sp)

		move.l	4,A6		    ; EXEC base

		move.l	sp,A2
		move.l	A0,-(sp)            ; save arg for _main() call
		move.l	D0,-(sp)            ; save arglen for _main() call

		;   If we are flagged resident then there is NO BSS ALLOCATED
		;   If we are not flagged resident then BSS IS ALLOCATED AFTER DATA,
		;	BUT NOT CLEARED.

		move.w	#__RESIDENT,D0
		beq	snotres

		;   Allocate BSS+DATA space and then copy static data.

		move.l	#__BSS_LEN,D0
		add.l	#__DATA_LEN,D0
		asl.l	#2,D0		    ; x4
		addq.l	#8,D0		    ; MemList header extra
		move.l	D0,D5		    ; D5 = #bytes
		move.l	#MEMF_PUBLIC,D1
		jsr	_LVOAllocMem(A6)
		tst.l	D0
		bne	alok
		move.l	A2,sp
		moveq.l #-1,D0
		bra	exfail

alok		move.l	D0,A0
		clr.l	(A0)+               ; MemList entry next ptr
		move.l	D5,(A0)+            ; MemList entry #bytes
		lea	32766(A0),A4        ; SET A4
		lea	-8(A0),A3           ; A3 = MemList entry base
					    ; can't copy to MemList(A4) yet


		;   Copy data to allocated copy

					    ; A0 = dst
		lea	__DATA_BAS,A1	    ; A1 = src
		move.l	#__DATA_LEN,D0	    ; D0 = long words
		bra	bssent
bsslop		move.l	(A1)+,(A0)+
bssent		dbf	D0,bsslop
		sub.l	#$10000,D0
		bcc	bsslop
		bra	clrbss


		;   Not resident, BSS space has been allocated for us
		;   beyond the specified data, just load the base ptr

snotres 	lea	__DATA_BAS,A4
		lea	32766(A4),A4
		sub.l	A3,A3

clrbss
		;   CLEAR BSS	&-32766(A4) + __DATA_LEN*4

		lea	-32766(A4),A0
		move.l	#__DATA_LEN,D0
		asl.l	#2,D0
		add.l	D0,A0

		move.l	#__BSS_LEN,D0	    ; longwords of bss
		moveq.l #0,D1
		bra	clrent
clrlop		move.l	D1,(A0)+
clrent		dbf	D0,clrlop
		sub.l	#$10000,D0
		bcc	clrlop

		move.l	A3,___MemList(A4)   ; memlist entry (if resident)
		move.l	A2,__ExitSP(A4)     ; sp to restore

		moveq.l #0,D0		    ; new signals
		move.l	#$1000,D1	    ; signal mask
		jsr	_LVOSetSignal(A6)   ; clear ^C

		move.l	A6,_SysBase(A4)     ; resident segment.

		jsr	__AutoInit0	    ; A6 has SYSBase
		jsr	__AutoInit1	    ; A6 has SYSBase
		jsr	__main(PC)

		;   fall through to low level exit... this avoids referencing
		;   exit() if the user overides _main().

		pea	0
		pea	0

		;   _EXIT()
		;
		;   since entry uses malloc we must free any incidental memory
		;   at __exit instead of _exit.

__exit:
		move.l	_SysBase(A4),A6
		jsr	__AutoExit1	    ; A6 has SysBase
		jsr	__AutoExit0	    ; A6 has SysBase

		move.l	__ExitSP(A4),A5     ; get sp... because we might free
					    ; the space taken by the variable!

		move.l	___MemList(A4),D0   ; free memory
		beq	ex20
ex10		move.l	D0,A2
		move.l	(A2),A3             ; next...

		move.l	4(A2),D0            ; bytes
		move.l	A2,A1		    ; ptr
		jsr	_LVOFreeMem(A6)

		move.l	A3,D0		    ; next...
		bne	ex10
ex20

		move.l	4(sp),D0            ; get exit code
		move.l	A5,sp		    ; restore sp

		;   FINIS, poof.

exfail
		movem.l (sp)+,D2-D7/A2-A6
		rts


		;   Base of autoinit section

		section autoinit0,code
__AutoInit0:
		section autoinit1,code
__AutoInit1:
		section autoexit0,code
__AutoExit0:
		section autoexit1,code
__AutoExit1:

		;   All library C code is compiled with the -S option
		;   which uses 'libdata' and 'libbss' section names,
		;   forcing library data to come before program data
		;   and library bss to come before program bss (because
		;   library data/bss sections are declared here first
		;   and sections of like name are coagulated).

		section libdata,data
_Reserved	dc.l	0		; force section to exist (dummy)

		section libbss,bss

		xdef	___MemList	; used by malloc/free

_SysBase	ds.l	1
__ExitSP	ds.l	1
___MemList	ds.l	1

		END

