home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Computer Club Elmshorn Atari PD
/
CCE_PD.iso
/
pc
/
0600
/
CCE_0638.ZIP
/
CCE_0638
/
GNULIB
/
LIBSRC93.ZOO
/
crt0.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-09
|
8KB
|
237 lines
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
* NB: This file is used for both 16 and 32 bit code.
* USE NO "int"s IN HERE!!!!
*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*
*
* Crt0: C run-time initialization code.
* Written by Eric R. Smith, and placed in the public domain.
* Use at your own risk.
*
* _start(base): sets things up for the process whose basepage is
* base. In particular, it sets up a valid environment, shrinks the
* TPA to a reasonable value, and parses the command line.
*
* 01/03/89 ++jrb
* The (new) meaning of _stksize: (thanks to allan pratt for the feedback)
*
* 11/27/91 ++jrb
* More meanings for _stksize (thanks to eric and allan for the feedback)
*
* _stksize meaning
* -4L keep 3/4, free 1/4, malloc from own heap
* -3L keep 2/4 (1/2), free 1/2 malloc from own heap
* -2L keep 1/4 of memory, free 3/4, malloc from own heap
*
* NOTE: all of the following will do malloc from Malloc() first.
* when that fails, in the -1L case malloc() will then do further
* mallocs from our own heap. This lets us use the maximum amount of
* memory in traditional ST's as well as in newer split address
* STs. In the >=0 cases futher malloc()'s will fail, and they
* will not try to malloc() from own heap. Out own space in the >= 0
* cases are intended mainly for stack+alloca()'s.
*
* -1L keep all of memory (except MINFREE at top) and do
* mallocs from own heap, with heap grown upwards towards
* stack, and the stack growing down towards heap,
* with a minimum slush between them so that they
* dont meet (only checked while malloc'ing). With
* this model, further spawning is not possible, but it is
* well suited for programs such as gcc-cc1 etc.
* Thanks to Piet van Oostrum & Atze Dijkstra for this idea
*
* 0L keep minimum amount of memory. this is also the
* case when _stksize is undefined by the user.
* 1L keep 1/4 of memory, free 3/4 ( as in Alcyon GEMSTART)
* 2L keep 2/4 (1/2), free rest
* 3L keep 3/4, free 1/4
* other keep that many bytes
* -other keep |other| bytes and malloc from own heap
*
* 02/14/90 ++jrb (thanks edgar)
* auto acc detect
* undump friendly
* Note: some of the stuff here may seem extraneous: these are in
* prep for upcoming plug'n play device interface
* (the moment the ol'boss lets me do some "real" work).
*
*
* NOTE: dumping applications should use _initial_stack instead: if
* !=0, then _stksize is initialized from _initial_stack, and
* mallocs are always from internal heap. (TeX works much better now),
* thanks edgar!
*
* Acc convention:
* user sets _heapbase to bottom of stack + heap area
* sets _stksize to the size of this area
* at startup, sp will be set to top of this area
* (_heapbase + _stksize ) and malloc()'s will happen from heap.
* (note malloc() and *not* Malloc())
* OR
* user sets only _stksize. then _heapbase is set to Malloc(_stksize)
* sp to _heapbase + _stksize and mallocs all happen from this heap.
*
* 02/16/90 ++jrb
* - bug fix: dont get screwed by desktop launch when fast bit is set
* convert env string to format usable
* (atari get your act together!!)
*/
#include <basepage.h>
#include <osbind.h>
#ifndef _COMPILER_H
#include <compiler.h>
#endif
#include <stddef.h>
#define isspace(c) ((c) == ' '||(c) == '\t')
#define BUFSIZ ((unsigned long)1024) /* this must track the value */
/* in stdio.h */
#define MINFREE (8L * 1024L) /* free atleast this much mem */
/* on top */
#define MINKEEP (8L * 1024L) /* keep atleast this much mem */
/*
* this little goodie is for emacs
* edgar: note: it has grown two leading '_',
* adjust in emacs/src/sysdep.c:start_of_data()
*
* __data_start removed, as that can be determined from the basepage.
*/
BASEPAGE *_base;
char **environ;
static long argc;
static char **argv;
/*
* initial stack is used primarily by dumping application,
* if it is, malloc is always from heap, and _stksize is init
* from initial_stack (to preserve the value in the undumped run)
*/
long _initial_stack; /* .comm __initial_size, 4 */
extern long _stksize; /* picked up from user or stksiz.c */
/* set to heap base addr when (_stksize <= -1L) || _initial_stack || When DA */
void *_heapbase;
/* default sizeof stdio buffers */
size_t __DEFAULT_BUFSIZ__; /* .comm */
/* are we an app? */
short _app;
/* are we on a split addr mem ST */
short _split_mem = 0;
/* externs to pull in ident strings of all used libraries into the
executable. if a library is not used, then the extern is satisfied
by a dummy in the library
*/
asm("
.globl ___Ident_libg
.globl ___Ident_curses
.globl ___Ident_widget
.globl ___Ident_gem
.globl ___Ident_pml
.globl ___Ident_gnulib
");
static void _acc_main __PROTO((void));
static void _start1 __PROTO((BASEPAGE *bp));
static long parseargs __PROTO((BASEPAGE *bp));
static void setup_handlers __PROTO((void));
static void _start0 __PROTO((BASEPAGE *));
static void setup_handlers __PROTO((void));
__EXTERN void _main __PROTO((long, char **, char **));
__EXTERN void _init_signal __PROTO((void));
__EXTERN void _start __PROTO((BASEPAGE *));
#ifdef __GCRT0__
__EXTERN void monstartup __PROTO((void *lowpc, void *highpc));
__EXTERN void monitor __PROTO((void *lowpc, void *highpc, void *buffer, unsigned long bufsize, unsigned int nfunc));
__EXTERN void moncontrol __PROTO((long flag));
__EXTERN void _mcleanup __PROTO((void));
__EXTERN int profil __PROTO((void *buff, unsigned long bufsiz, unsigned long offset, int shift));
#endif
/*
* From: kbad@atari.UUCP (Ken Badertscher)
* Newsgroups: comp.sys.atari.st
* Subject: Am I a DA? (long)
* .....
* I mentioned before that a DA's registers are garbage on startup, well,
* that's not entirely true. When the DA gets control, register A0 always
* points to its basepage. When a program is started by a GEMDOS Pexec(),
* register A0 is always cleared. Using this fact, it is possible to
* implement startup code which gets the basepage address from register A0
* if the code is launched as a DA, or at 4(sp) if the code is launched by
* Pexec(). Since it knows how it was launched, it can also do the stack
* setup required of a DA, otherwise it can use the stack pointer it gets.
*
*/
/*
* revert back to testing A0 (instead of SP) after controversy on the net.
* packers will just have to fix themselves.
* in addition to testing A0 check long A0@(36) (parents basepage). for an
* acc this should be NULL.
*/
__asm__("
.text
.even
.globl __start
__start:
"
#ifdef __MBASE__
" movl a0,a1 /* Find basepage, data seg */
cmpw #0,a1
jne 1f
movl sp@(4),a1
1:
movl a1@(16)," __MBASESTR__ " /* Set base to data seg + 32K */
subw #32768," __MBASESTR__ "
"
#define Base __MBASESTR__ "@(__base)"
#define Heapbase __MBASESTR__ "@(__heapbase)"
#define Stksize __MBASESTR__ "@(__stksize)"
#else
#define Base "__base"
#define Heapbase "__heapbase"
#define Stksize "__stksize"
#endif
" cmpw #0,a0 /* test acc or prog */
jeq __start0 /* br if prog */
tstl a0@(36) /* tst parent basepage pointer */
jne __start0 /* its a prog if != 0 */
/* its an acc, set up a stck+heap */
movl a0," Base " /* sto basepage */
tstl " Heapbase " /* setup _heapbase and sp */
jne 1f
movl " Stksize ",d3 /* _heapbase not specified */
addql #3, d3
andl #0xfffffffc,d3
movl d3,sp@- /* _heapbase = Malloc(_stksize) */
movw #0x48,sp@-
trap #1
addqw #6,sp
movl d0," Heapbase "
addl d3,d0
movl d0, sp /* sp = _heapbase + _stksize */
jra __acc_main
1: /* heap base specified */
movl " Heapbase ",sp /* setup sp */
addl " Stksize ",sp
jra __acc_main"); /* acc main */
/* dont even think of */
/* dropping through */
static char *acc_argv[] = {"", (char *) 0}; /* no name and no arguments */
static void _acc_main(void)
{
_app = 0; /* this is an accessory */
_main(1L, acc_argv, acc_argv);
/*NOTREACHED*/
}
void _start0(bp)