home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
program
/
dlibsrc
/
dstart.s
< prev
next >
Wrap
Text File
|
1988-10-19
|
7KB
|
265 lines
*************************************************************************
* *
* DSTART.S Startup module for C programs using dLibs *
* *
*************************************************************************
*
* entry points
*
.globl __base * basepage pointer
.globl __start * startup entry point
.globl _etext * end of text segment
.globl _edata * end of data segment
.globl _end * end of BSS segment (end of program)
.globl __break * location of stack/heap break
.globl __exit * terminate immediately with exit code
.globl __argc * number of arguments
.globl __argv * argument list pointer
.globl __envp * environment string pointer
.globl _errno * system error number
.globl _gemdos * trap #1 (gemdos) hook
.globl _bios * trap #13 (bios) hook
.globl _xbios * trap #14 (xbios) hook
.globl _bdos * trap #2 (bdos) hook
*
* external references
*
.globl __STKSIZ * Stack size value from C (unsigned long)
.globl __main * Initial entry point for C program
.globl _main * C program main() function
*
* useful constants
*
MINSTK equ 1024 * Minimum 1K stack size
MARGIN equ 512 * Minimum memory to return to OS
*
* GEMDOS functions
*
Cconws equ $09 * Console write string
Pterm equ $4C * Process terminate (with exit code)
Mshrink equ $4A * Shrink program space
*
* basepage offsets
*
p_hitpa equ $04 * top of TPA
p_tbase equ $08 * base of text
p_tlen equ $0C * length of text
p_dbase equ $10 * base of data
p_dlen equ $14 * length of data
p_bbase equ $18 * base of BSS
p_blen equ $1C * length of BSS
p_env equ $2C * environment string
p_cmdlin equ $80 * command line image
*
* STARTUP ROUTINE (must be first object in link)
*
.text
__start:
*
* save initial stack and basepage pointers
*
move.l sp,a5 * a5 = initial stack pointer
move.l 4(sp),a4 * a4 = basepage address
move.l a4,__base
move.l p_tbase(a4),d3
add.l p_tlen(a4),d3
move.l d3,_etext * end of text segment
move.l p_dbase(a4),d3
add.l p_dlen(a4),d3
move.l d3,_edata * end of data segment
move.l p_bbase(a4),d3
add.l p_blen(a4),d3
move.l d3,_end * end of BSS (end of program)
move.l d3,__break; * set initial _break value
move.l p_env(a4),__envp * save environment pointer
*
* call C function to get command line arguments
*
lea.l p_cmdlin(a4),a0 * get pointer to command line image
move.b (a0)+,d0
ext.w d0 * extract length
move.w d0,-(sp) * cmdlen
move.l a0,-(sp) * cmdline
jsr __initar * call _initargs(cmdline, cmdlen)
addq.l #6,sp
*
* calculate free space available to program
*
move.l __break,d3
move.l d3,a3 * a3 = base of free space
neg.l d3
add.l p_hitpa(a4),d3
sub.l #MARGIN,d3 * d3 = free space
*
* calculate new stack size (store in d2)
*
move.l #__STKSIZ,a2 * a2 = &_STKSIZ
move.l a2,d2 * if __STKSIZ is undefined
beq minimum * use MINSTK
move.l (a2),d2 * if __STKSIZ is positive
bpl setstk * use __STKSIZ
add.l d3,d2 * if __STKSIZ is negative
cmp.l #MINSTK,d2 * try (free space + __STKSIZ)
bge setstk * if < MINSTK
minimum:
move.l #MINSTK,d2 * use MINSTK
*
* check to see if there is enough room for requested stack
*
setstk:
cmp.l d3,d2
blt shrink * if (available < requested)
move.l #stkerr,-(sp)
move.w #Cconws,-(sp)
trap #1 * report a stack error
addq.l #6,sp
move.w #-39,-(sp)
move.w #Pterm,-(sp)
trap #1 * and return error -39 (ENSMEM)
*
* set up new stack pointer and Mshrink
*
shrink:
add.l a3,d2 * new stack = free base + stack size
move.l d2,sp
sub.l a4,d2 * keep space = new stack - __base
move.l d2,-(sp)
move.l a4,-(sp)
clr.w -(sp)
move.w #Mshrink,-(sp)
trap #1 * Mshrink(0, _base, keep);
add.l #12,sp
*
* call C entry point function _main()
*
jsr __main * if _main returns
move.w d0,4(sp) * insert return value and fall thru
*
* void _exit(code)
* int code;
*
* Terminate process with a return value of <code>
*
__exit:
tst.l (sp)+ * pop return PC off the stack
move.w #Pterm,-(sp) * leaving <code>
trap #1 * and terminate.
*
* operating system trap hooks for C
*
*
* long gemdos(function, [parameter, ...])
* int function;
*
_gemdos:
move.l (sp)+,traprtn * save return address
trap #1 * do gemdos trap
bra chkstk
*
* long bios(function, [parameter, ...])
* int function;
*
_bios:
move.l (sp)+,traprtn * save return address
trap #13 * do bios trap
bra chkstk
*
* long xbios(function, [parameter, ...])
* int function;
*
_xbios:
move.l (sp)+,traprtn * save return address
trap #14 * do xbios trap
bra chkstk
*
* int bdos(function, parameter)
* int function;
* long parameter;
*
_bdos:
move.l (sp),traprtn * save return address
move.l a6,(sp) * save old frame pointer
move.l sp,a6 * set up frame pointer
tst.l -(a6) * (fake "link a6,#0")
move.w 8(a6),d0 * function code in D0.W
move.l 10(a6),d1 * parameter value in D1.L
trap #2 * do bdos trap
move.l (sp)+,a6 * restore old frame pointer
*
* check for stack overflow (done after all OS traps)
*
chkstk:
cmp.l __break,sp
bgt nosweat * if (_break > sp)
move.l #stkovf,-(sp)
move.w #Cconws,-(sp)
trap #1 * report a stack overflow
addq.l #6,sp
move.w #-1,-(sp)
move.w #Pterm,-(sp)
trap #1 * and return error -1 (ERROR)
nosweat:
move.l traprtn,-(sp) * else, restore return address
rts * and do a normal return.
*
* this call to _main ensures that it the user's main() function will be
* linked, even if it is in a library.
*
jsr _main * NO PATH TO THIS STATEMENT
* THE FOLLOWING IS SELF MODIFYING CODE, DO NOT DISTURB
move.l #$644c6962,$7320(sp)
moveq.l #$31,d3
move.l $0(a2,d0),d7
*
* initialized data space
*
.data
.even
stkerr: * not enough memory for stack
.dc.b 'Not enough memory',$d,$a,0
stkovf: * impending stack overflow
.dc.b 'Stack overflow',$d,$a,0
_errno: * system error number
.dc.w 0
__argc: * number of command line args
.dc.w 0
__argv: * pointer to command line arg list
.dc.l 0
*
* uninitialized data space
*
.bss
.even
__base: * pointer to basepage
.ds.l 1
_etext: * pointer to end of text segment
.ds.l 1
_edata: * pointer to end of data segment
.ds.l 1
_end: * pointer to end of BSS (end of program)
.ds.l 1
__break: * pointer to stack/heap break
.ds.l 1
__envp: * pointer to environment string
.ds.l 1
traprtn: * storage for return PC in trap hooks
.ds.l 1
.end