![]() |
![]() |
#1 |
Registered User
Join Date: Jan 2005
Location: Umeå
Age: 44
Posts: 962
|
AROS startup code
Hi,
I would like to learn how to write my own startup code for AROS. On classic AmigaOS, it is very simple - it executes the first function found in an executable file, you just need to setup SysBase before calling any exec.library functions. An hello world example with own startup code would look like this: Code:
#include <exec/exec.h> #include <dos/dos.h> #include <proto/exec.h> #include <proto/dos.h> struct ExecBase *SysBase = NULL; struct DosLibrary *DOSBase = NULL; LONG Something(void) { SysBase = *(struct ExecBase **) 4; DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 36); if(NULL != DOSBase) { Printf("Hello Amiga!\n"); } CloseLibrary((struct Library *) DOSBase); return 0; } Code:
vc +aos68k -c99 -nostdlib -o helloamiga helloamiga.c With gcc things seem a bit trickier, but it is doable - there is for example an excellent guide for writing your own startup code in MorphOS using gcc, with a complete example attached at the end. If I try something similar on AROS and compile the above code with: Code:
gcc -nostdlib -nostartfiles -o helloamiga helloamiga.c Haven't been able to find any information similar to the MorphOS guide for AROS, so I'm hoping someone can point me in the right direction. |
![]() |
![]() |
#2 |
Registered User
Join Date: Jan 2005
Location: Umeå
Age: 44
Posts: 962
|
Responding to myself in case someone else searches for this in the future. This is how you do it for the above example:
Code:
#include <exec/exec.h> #include <dos/dos.h> #include <proto/exec.h> #include <proto/dos.h> struct ExecBase *SysBase = NULL; struct DosLibrary *DOSBase = NULL; __startup AROS_PROCH(Something, arguments, argumentsLength, sysBase) { AROS_PROCFUNC_INIT SysBase = sysBase; DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 0); if(NULL != DOSBase) { Printf("Hello world!\n"); } CloseLibrary((struct Library *) DOSBase); return 0; AROS_PROCFUNC_EXIT } Code:
gcc -nostartfiles -o helloamiga helloamiga.c Last edited by patrik; 24 April 2017 at 23:46. |
![]() |
![]() |
#3 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,583
|
As you mentioned vbcc, here is the vclib startup code for the i386-aros target, which I had to abandon about 10 years ago. Maybe declaring __startup_entry as global is important for the loader, but I don't remember.
Code:
# # vbcc/AROS386 startup # Written by Frank Wille <frank@phoenix.owl.de> 2006 # # Version .set VERSION,1 .set REVISION,01 .macro VBCC_VER .byte "VBCC 0.9" .endm .extern __cstart .text .globl __startup_entry __startup_entry: # Entered with: # 0(%esp) return address to DOS # 4(%esp) argument string pointer # 8(%esp) argument string length # 12(%esp) SysBase pointer movl $__save_regs,%eax mov %esp,(%eax) mov %ebx,4(%eax) mov %ebp,8(%eax) mov %esi,12(%eax) mov %edi,16(%eax) mov 12(%esp),%eax mov %eax,SysBase jmp __cstart VBCC_VER .type __startup_entry,@function .size __startup_entry,.-__startup_entry .globl __asmexit __asmexit: mov 4(%esp),%eax movl $__save_regs,%edx mov (%edx),%esp mov 4(%edx),%ebx mov 8(%edx),%ebp mov 12(%edx),%esi mov 16(%edx),%edi ret .type __asmexit,@function .size __asmexit,.-__asmexit .byte "startup V" .byte '0'+VERSION,'.','0'+(REVISION/10),'0'+(REVISION%10),0 .lcomm __save_regs,20 .comm SysBase,4 Code:
/* ** vbcc/AROS386 startup ** Written by Frank Wille <frank@phoenix.owl.de> 2006 */ #include <dos/dosextens.h> #include <workbench/startup.h> #include <proto/exec.h> #include <proto/dos.h> struct SVar { BPTR WbOutput; char *ArgvBufPtr; char *ArgvArray[1]; }; struct DosLibrary *DOSBase; struct WBStartup *WBenchMsg,*_WBenchMsg; BPTR _stdin,_stdout,_stderr; static struct SVar *svar; extern void __asmexit(int); extern void __main(int,char **); static int strlen(__reg("%edi") const char *) = "\tcld\n" "\txor\t%eax,%eax\n" "\tmov\t%eax,%ecx\n" "\tdec\t%ecx\n" "\trepne\n" "\tscasb\n" "\tnot\t%ecx\n" "\tlea\t-1(%ecx),%eax"; void __exit(int code) { if (DOSBase) { if (svar) { if (svar->WbOutput) Close(svar->WbOutput); FreeVec(svar); } CloseLibrary((struct Library *)DOSBase); } if (WBenchMsg) { Forbid(); ReplyMsg((struct Message *)WBenchMsg); } __asmexit(code); } static void getWbMsg(struct Process *this_proc) { WaitPort(&this_proc->pr_MsgPort); WBenchMsg = _WBenchMsg = (struct WBStartup *)GetMsg(&this_proc->pr_MsgPort); } static void startup_failed(struct Process *this_proc) { if (!this_proc->pr_CLI) getWbMsg(this_proc); __exit(RETURN_FAIL); } static int command_len(void) { char buf[1024]; if (GetProgramName(buf,1024)) return strlen(buf) + 1; return 0; } void __cstart(unsigned char *argstr,int arglen) { struct Process *this_proc = (struct Process *)FindTask(NULL); int argc,argc_est,len; char **argv; unsigned char *p; if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",39))) startup_failed(this_proc); /* estimate number of argv-slots */ if (this_proc->pr_CLI) { for (argc_est=3,len=arglen,p=argstr; len>0 && *p!='\0'; len--,p++) { if (*p <= ' ') argc_est++; } len = command_len(); } else { argc_est = 2; /* two dummy arguments for WB-start */ arglen = 8; len = 0; } if (!(svar = AllocVec(sizeof(struct SVar) + argc_est*sizeof(char *) + len + arglen + 1, MEMF_PUBLIC | MEMF_CLEAR))) { startup_failed(this_proc); } svar->ArgvBufPtr = (char *)&svar->ArgvArray[argc_est+1]; if (this_proc->pr_CLI) { /* started from CLI */ if (len) GetProgramName(svar->ArgvBufPtr,len); argv = svar->ArgvArray; *argv++ = svar->ArgvBufPtr; svar->ArgvBufPtr += len; argc = 1; /* eat trailing control characters on command line */ for (len=arglen,p=argstr+arglen-1; len>0 && *p<=' '; len--,p--); *(p+1) = '\0'; for (p=svar->ArgvBufPtr; *argstr!='\0' && argc<argc_est; ) { while (*argstr!='\0' && *argstr<=' ') argstr++; if (*argstr == '\0') break; argc++; *argv++ = p; if (*argstr == '\"') { unsigned char c; argstr++; while ((c = *argstr++) != '\"') { if (c == '\0') { argstr--; break; } else if (c == '*') { /* BCPL escape character */ switch (c = *argstr++) { case '\0': argstr--; break; case 'N': *p++ = '\n'; break; case 'E': *p++ = 27; break; default: *p++ = c; break; } } else *p++ = c; } } else { while (*argstr > ' ') *p++ = *argstr++; } *p++ = '\0'; } *argv = NULL; argv = svar->ArgvArray; _stdin = Input(); _stdout = Output(); if (!(_stderr = this_proc->pr_CES)) _stderr = _stdout; } else { /* started from Workbench */ struct WBArg *wbarg; getWbMsg(this_proc); argv = (char **)WBenchMsg; argc = 0; if (wbarg = WBenchMsg->sm_ArgList) CurrentDir(wbarg->wa_Lock); /* set I/O to NIL: */ if (svar->WbOutput = Open("NIL:",MODE_OLDFILE)) _stdin = _stdout = _stderr = svar->WbOutput; else startup_failed(this_proc); #if 0 /* @@@ how to do this under AROS ??? */ /* set console task, so Open("*",mode) will work */ this_proc->pr_CIS = _stdin; this_proc->pr_COS = _stdout; this_proc->pr_ConsoleTask = ... #endif } __main(argc,argv); /* vclib init, call main() */ __exit(0); /* although __main() should never return */ } |
![]() |
![]() |
#4 |
Registered User
Join Date: Jan 2005
Location: Umeå
Age: 44
Posts: 962
|
Interesting!
If I would compile the 80x86 versions of vbcc and vasm, could they be used to create an aros executable for something like the helloamiga above? |
![]() |
![]() |
#5 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,583
|
The hello-world in your first posting could work, provided you have got the proto and inline headers of vbcc's i386-aros target.
But you will run into all sorts of problems as soon as you include the original AROS headers files, which depend on gcc-specific extensions. This was the reason I abandoned AROS support. |
![]() |
![]() |
#6 |
Registered User
Join Date: Jan 2005
Location: Umeå
Age: 44
Posts: 962
|
Can the protos and inlines for aros-i386 be generated with the fd2pragma which is included with vbcc?
|
![]() |
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
C/C++ WB friendly fullscreen game startup code | NovaCoder | Coders. Tutorials | 1 | 20 August 2019 13:45 |
non-system startup code time/clock problem | modrobert | Coders. Asm / Hardware | 89 | 14 December 2018 15:37 |
AROS: Stable AROS ABI_V0-20161228 | AMIGASYSTEM | News | 19 | 06 January 2017 00:06 |
New Video of my Aros 68k distribution "Aros Vision" | OlafSch | Amiga scene | 26 | 16 February 2016 11:16 |
Startup Code (from Icon ) - Forbid function | Asman | Coders. System | 2 | 04 January 2014 10:45 |
|
|