home *** CD-ROM | disk | FTP | other *** search
- *************************************************************************
- * *
- * 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
-