home *** CD-ROM | disk | FTP | other *** search
- **
- ** crt0.asm / ixemul startup code for vbcc/PhxLnk
- **
- ** This startup code will need at least PhxLnk v4.30 to find all
- ** the required linker symbols.
- **
- ** Based on crt0.c by Loren J. Rittle
- ** Written by Frank Wille 1997
- **
- ** Assemble with BASECRT0 set, to generate the small data version.
- **
- ** started: 07-Jan-97
- **
- ** v0.1 (08-Jan-97) hard-coded __stk_limit, __stk_argbytes and __machtype,
- ** no small data support, no moncontrol support for
- ** profiling, etc... ;)
- ** v0.2 (09-Jan-97) omitting the __init_stk_limit()-call seems to be a better
- ** solution for the __stk_limit/__stk_argbytes problem (?)
- ** v0.9 (10-Jan-97) removed some obsolete xdefs, minor code optimizations,
- ** small data support by setting BASECRT0 (!)
- ** v1.0 (02-Feb-97) supports some (all?) nice ixemul.library v45 features
- ** (e.g. automatic stack extension, some network ini-
- ** tialization, etc.) so that v45 is *required* from now
- ** on,
- ** ___ixemulVer may be defined by the user to set the
- ** mininum ixemul-version, which the program requires,
- ** besides ___ixemulVer, some other symbols have moved
- ** into the ixemul.lib to give the user the possibility
- ** to overwrite them by an own definition: _expand_cmd_line,
- ** ___stk_limit, ___stk_argbytes and ___stack,
- ** the __init_stk_limit()-call is in the startup code again,
- ** BASECRT0 mode needs the exec-entries a_bss set to zero
- ** and a_data = _DATA_LEN_ + _BSS_LEN_, this is done by
- ** importing the new linker symbol _SMALL_DATA_LEN_, which
- ** PhxLnk defines since v4.30
- **
-
- IX_VERSION equ 45 ; minimum version for startup code
-
- ; exec.library LVOs
- OpenLibrary equ -552
- CloseLibrary equ -414
- Forbid equ -132
- GetMsg equ -372
- ReplyMsg equ -378
- WaitPort equ -384
- CopyMem equ -624
-
- ; dos.library LVOs
- FilePart equ -870
-
- ; intuition.library LVOs
- EasyRequestArgs equ -588
-
- ; ixemul.library LVOs
- ix_startup equ -552
- ix_exec_entry equ -1896
- ix_get_vars2 equ -1902
- ix_resident equ -2568
- __init_stk_limit equ -2904
- __stkext_startup equ -3450
-
-
- include "exec/execbase.i"
- include "exec/libraries.i"
- include "dos/dosextens.i"
- include "intuition/intuition.i"
-
-
-
- code
-
- xref _main
-
- xref _CODE_LEN_ ; linker symbols, generated by PhxLnk
- xref _DATA_LEN_
- xref _BSS_LEN_
- ; xref ___machtype
- ___machtype equ 0 ; currently hard-coded
-
-
- IFD BASECRT0
- near a4,-2 ; activate small data mode
- xref _SMALL_DATA_LEN_ ; total small data size
- nref _expand_cmd_line
- nref ___stk_limit
- nref ___stk_argbytes
- nref ___ixemulVer
- nref ___stack
- ELSE
- xref _expand_cmd_line ; expand wildcards?
- xref ___stk_limit
- xref ___stk_argbytes
- xref ___ixemulVer ; ixemul.library version to open
- xref ___stack ; desired stack size
- ENDIF
-
- ; This is the first code executed. Note that a_magic has to be at
- ; a known offset from the start of the code section in order for
- ; execve() to know that the program that it is starting uses the
- ; ixemul library.
-
- bra.w _ENTRY
-
- ; this is a struct exec, for now only OMAGIC is supported
- dc.w ___machtype ; a_mid
- dc.w @407 ; a_magic = OMAGIC
- dc.l _CODE_LEN_ ; a_text
- IFND BASECRT0
- dc.l _DATA_LEN_ ; a_data
- dc.l _BSS_LEN_ ; a_bss
- ELSE
- dc.l _SMALL_DATA_LEN_
- dc.l 0
- ENDIF
- dc.l 0 ; a_syms
- dc.l _exec_entry ; a_entry
- dc.l 0 ; a_trsize
- dc.l 0 ; a_drsize
-
-
- abort_txt:
- dc.b "Abort",0
- liberr_txt:
- dc.b "Need at least version %ld of ixemul.library.",0
- crt_txt:
- IFD BASECRT0
- dc.b "b"
- ENDIF
- dc.b "crt0",0
- even
-
-
- xdef _ix_get_variables ; should this be extern?
- _ix_get_variables:
- ; int from_vfork_setup_child (0 or 1)
- move.l _ixemulbase,a0
- pea __res_socket
- lea __res,a1 ; set resolver state default settings
- move.l a1,-(sp)
- move.l #5,(a1)+ ; retrans = RES_TIMEOUT
- move.l #4,(a1)+ ; retry = 4
- move.l #$2c0,(a1)+ ; options = RES_DEFAULT
- move.l #1,(a1)+ ; nscount = 1
- pea _h_errno
- tst.l 4*4(sp) ; from_vfork_setup_child ?
- beq .1
- pea _errno
- pea _environ
- bra .2
- .1: clr.l -(sp)
- clr.l -(sp)
- .2: pea _environ
- pea ___sF
- pea _DOSBase
- pea _SysBase
- pea _sys_nerr
- pea __ctype_
- pea 11.w
- jsr ix_get_vars2(a0)
- add.w #48,sp
- rts
-
-
- _start_stdio:
- ; int argc, char **argv, char **env
- move.l a6,-(sp)
- clr.l -(sp)
- bsr _ix_get_variables ; init SysBase, DOSBase, etc.
-
- ; we call a v36 dos.library function here, because crt0 should have
- ; already failed on a pre-v36 system.
- move.l _DOSBase,a6
- move.l 4*4(sp),a0
- move.l (a0),d1 ; argv[0]
- beq .1
- jsr FilePart(a6) ; get program name
- move.l d0,___progname
-
- ; call main
- .1: movem.l 3*4(sp),d0-d1/a0 ; argc, argv, env
- move.l a0,_environ
- movem.l d0-d1/a0,-(sp)
- jsr _main ; call main(argc,argv,env) entry point
- add.w #16,sp
- move.l (sp)+,a6
- rts
-
-
- _exec_entry:
- ; struct Library *ibase, int argc, char *argv[], char *env[]
- IFD BASECRT0
- bsr _geta4
- move.l 4(sp),a0 ; ibase
- move.l a4,-(sp)
- pea 2.w
- jsr ix_resident(a0)
- addq.w #8,sp
- ENDIF
- move.l 4(sp),a0 ; ibase
- move.l a0,_ixemulbase ; set ixemulbase
- move.l ___ixemulVer,d0
- cmp.w LIB_VERSION(a0),d0
- bls .1 ; version ok?
-
- move.l 4.w,a6
- move.l d0,-(sp)
- pea abort_txt(pc)
- pea liberr_txt(pc)
- pea crt_txt(pc)
- subq.w #8,sp
- bsr ix_panic
- add.w #24,sp
- move.l #(20<<8)|0,d0 ; W_EXITCODE(20,0)
- rts
-
- .1 move.l a0,-(sp)
- move.l ___stk_argbytes,-(sp)
- pea ___stk_limit
- jsr __init_stk_limit(a0)
- addq.w #8,sp
- move.l (sp)+,a0
- pea _start_stdio(pc)
- pea _errno
- move.l 24(sp),-(sp) ; env
- move.l 24(sp),-(sp) ; argv
- move.l 24(sp),-(sp) ; argc
- move.l ___stack,d0 ; desired stack size set?
- beq .2
- jsr __stkext_startup(a0) ; stack extension, if required
- .2 jsr ix_exec_entry(a0)
- add.w #20,sp
- rts
-
-
- IFD BASECRT0
- xref _DATA_BAS_
- xdef _geta4
- _geta4:
- lea _DATA_BAS_+32766,a4 ; init small data base register
- rts
- ENDIF
-
-
- ; Note: This routine must be far enough away from the start of code
- ; so that the PC relative offset won't fit in a byte and the assembler
- ; will generate the right instruction pattern that execve() is looking
- ; for to know that this is a program that uses the ixemul.library.
-
- _ENTRY:
- IFD BASECRT0
- movem.l d2/a2/a4/a6,-(sp)
- bsr _geta4
- ELSE
- movem.l d2/a2/a6,-(sp)
- ENDIF
- move.l a0,d2 ; a2/d2 save command line
- move.l d0,a2
- move.l 4.w,a6 ; ExecBase (v37)
- cmp.w #37,LIB_VERSION(a6) ; required for StackSwap()
- blo .6
- move.l ___ixemulVer,d0 ; user-defined version
- moveq #IX_VERSION,d1 ; minimum version required
- cmp.l d1,d0
- bhs .4
- move.l d1,d0
- move.l d0,___ixemulVer
- .4: lea ixemul_name(pc),a1
- jsr OpenLibrary(a6) ; open ixemul.library
- move.l d0,_ixemulbase
- beq .1
-
- move.l d0,a6 ; a6 ixemulbase
- IFD BASECRT0
- move.l a4,-(sp)
- pea 2.w
- jsr ix_resident(a6)
- addq.w #8,sp
- ENDIF
- move.l ___stk_argbytes,-(sp)
- pea ___stk_limit
- jsr __init_stk_limit(a6)
- pea _errno
- pea _start_stdio(pc)
- move.l _default_wb_window,-(sp)
- move.l _expand_cmd_line,-(sp)
- move.l a2,-(sp)
- move.l d2,-(sp)
- move.l ___stack,d0 ; desired stack size set?
- beq .5
- jsr __stkext_startup(a6) ; stack extension, if required
- .5: jsr ix_startup(a6) ; ixemul startup
-
- move.l d0,d2
- add.w #32,sp
- move.l a6,a1
- move.l 4.w,a6
- jsr CloseLibrary(a6) ; close ixemul.library
- move.l d2,d0
- bra .3
-
- .1: move.l ___ixemulVer,-(sp) ; error on opening ixemul.library
- pea abort_txt(pc)
- pea liberr_txt(pc)
- pea crt_txt(pc)
- subq.w #8,sp
- bsr ix_panic
- add.w #24,sp
- .6: move.l ThisTask(a6),a2
- tst.l pr_CLI(a2) ; started from CLI?
- bne .2
- ; Quickly deal with the WB startup message, as the library couldn't do
- ; this for us. Nothing at all is done that isn't necessary to just shutup
- ; workbench.
- jsr Forbid(a6)
- add.w #pr_MsgPort,a2
- move.l a2,a0
- jsr WaitPort(a6)
- move.l a2,a0
- jsr GetMsg(a6)
- move.l d0,a1
- jsr ReplyMsg(a6) ; reply WBStartup message
- .2: moveq #20,d0
- .3:
- IFD BASECRT0
- movem.l (sp)+,d2/a2/a4/a6
- ELSE
- movem.l (sp)+,d2/a2/a6
- ENDIF
- rts
-
- ixemul_name:
- dc.b "ixemul.library",0
- intuition_name:
- dc.b "intuition.library",0
- even
-
-
- ix_panic:
- ; Displays a v36 easy-requester.
- ; A comlete EasyStruct is already on stack, when called. Only es_StructSize
- ; and es_Flags will be initialized here.
- ; a6 = ExecBase
- lea intuition_name(pc),a1
- moveq #36,d0
- jsr OpenLibrary(a6) ; open intuition.library v36
- tst.l d0
- beq .1
- movem.l a2-a3/a6,-(sp)
- move.l d0,a6 ; IntuitionBase
- sub.l a0,a0
- lea 4*4(sp),a1 ; EasyStruct
- move.l #EasyStruct_SIZEOF,es_StructSize(a1)
- clr.l es_Flags(a1)
- sub.l a2,a2
- lea EasyStruct_SIZEOF(a1),a3 ; ArgList
- jsr EasyRequestArgs(a6) ; render panic requester
- move.l a6,a1
- movem.l (sp)+,a2-a3/a6
- jsr CloseLibrary(a6) ; close intuition.library
- .1: rts
-
-
- ; null mcount and moncontrol, just in case some routine is
- ; compiled for profiling
- xdef mcount
- xdef _moncontrol
- _moncontrol:
- mcount:
- rts
-
-
-
- IFD BASECRT0
- section __MERGED,data
- ELSE
- data
- ENDIF
-
- _environ:
- dc.l dummy_environ ; default for progs not started via exec_entry
- ___progname:
- dc.l dummy_environ ; use dummy_environ as empty string
- __res_socket: ; resolv socket used for communications
- dc.l -1
-
- xdef _environ
- xdef ___progname
- xdef __res_socket
-
-
-
- IFD BASECRT0
- section __MERGED,bss
- ELSE
- bss
- ENDIF
-
- _ixemulbase:
- ds.l 1
- _errno: ; error results from the library
- ds.l 1
- __ctype_:
- ds.l 1
- _sys_nerr: ; number of system error codes
- ds.l 1
- _SysBase:
- ds.l 1
- _DOSBase:
- ds.l 1
- ___sF:
- ds.l 1
- ___SaveSP:
- ds.l 1
- dummy_environ:
- ds.l 1
- _default_wb_window: ; Default Workbench output window name
- ds.l 1
- _h_errno:
- ds.l 1 ; networking error code
- __res: ; resolver state
- ds.b 448 ; sizeof(struct __rest_state) + some extra bytes
-
- xdef _ixemulbase
- xdef _errno
- xdef __ctype_
- xdef _sys_nerr
- xdef _SysBase
- xdef _DOSBase
- xdef ___sF
- xdef ___SaveSP
- xdef _h_errno
- xdef __res
-
- end
-