/* Custom INIT.C for START.PRG, based on original supplied with Megamax C and modified by FTL. Changes from original:
- Removed call to GEMDOS Mshrink() to return unused memory to the system
- Removed _argc, _argv and call to _initargcv()
- Removed call to exit() */

/*
	This is the very first stuff that executes when a program is run.
	It sets up the global variables, strings, stack etc.
*/

#define STACKSIZE 8192

/* Base page definitions */
#define ltpa 0			/* Low TPA address */
#define htpa 4			/* High TPA address */
#define lcode 8			/* Code segment start */
#define codelen 12		/* Code segment length */
#define ldata 16		/* Data segment start */
#define datalen 20		/* Data segment length */
#define lbss 24			/* Bss  segment start */
#define bsslen 28		/* Bss  segment length */
#define freelen 32		/* free segment length */
#define resvd 36		/* Reserved */
#define fcb2 56			/* 2nd parsed fcb */
#define fcb1 92			/* 1st parsed fcb */
#define command 128		/* Command tail */

extern _init(), _main(), main();
char *_base;	/* points to base page of program */

#ifndef LINT
overlay "init!"
asm {
	_init:		/* initialization entry point; RTS plugged in by linker */
}
#endif

#ifndef LINT
overlay "main"
asm {
	_main:
		move.l	A7,A5			; save A7 so we can get the base page address
		move.l	4(A5),A5		; A5=basepage address
		move.l	codelen(A5),D0
		add.l	datalen(A5),D0
		add.l	bsslen(A5),D0
		add.l	#256+STACKSIZE,D0 ;D0=basepage+textlen+datalen+bsslen+8K stack
		move.l	D0,D1
		add.l	A5,D1			; compute stack top
		and.l	#-2,D1			; ensure even byte boundary
		move.l	D1,A7			; setup user stack

		move.l	lbss(A5), A0	;swap data and bss segments
		move.l	lbss(A5), A1
		adda.l	bsslen(A5), A1
		move.l	datalen(A5), D0
		subq.l	#1, D0			; dbf loop is stupid
		ble		swapcont		;might not have any data
	swap:
		move.b	-(A0), -(A1)
		dbf		D0,swap
	swapcont:

		move.l	ldata(A5), A0	;clear bss segment
		move.l	bsslen(A5), D0
		subq.l	#1, D0
	clear:	
		clr.b	(A0)+
		dbf		D0, clear

		move.l	ldata(A5), A4	;A4 points between bss and data
		adda.l	bsslen(A5), A4

		move.l	A5, _base(A4);

		move.l	lcode(A5), A5	;A5 points to jump table

		jsr		_init			;initialize globals and statics now
		jsr		main			;call application's entry point
}
#endif
