Le problème
Si on ne change pas la séquence de démarrage, le gcc réclame la version 37 du dos avec le message laconique "Need version 37 of dos.library".
Se limiter à la version 37 est un non sens, le 1.2 (version 33) était livré avec le A500 et A2000, le 1.3 (version 34) était livré avec le A2000B.

Un petit fichier assembleur mystart.s
Ce n'est pas de l'assembleur 68000, mais de l'assembleur compris par gcc.
Le main référencé est préfixé par trois traits bas ___.

  .text
  .even
  .globl  start

start:
  jmp ___startup

Le code source nostartup.c
Le point d'entrée en C a deux traits bas __startup.
.

#define __NOLIBBASE__

#include <stdarg.h>
#include <string.h>

#include <dos/dosextens.h>
#include <workbench/startup.h>

#include <proto/exec.h>
#include <proto/dos.h>

#ifdef __SASC
#   define SAVEDS       __saveds
#   define ASM          __asm
#   define REG(x,y)     register __##x y
#elif defined(__GNUC__)
#   define SAVEDS       __saveds
#   define ASM
#   define REG(x,y)     y __asm(#x)
#else
#   error   add #defines for your compiler...
#endif

size_t strlen(const char *) ;
int sprintf(char *, const char*, ...) ;

int _main(int argc, char*argv[]) ;

#define MAXARG 64
#define isspace(c)      ((c == ' ')||(c == '\t') || (c == '\n'))

#ifdef __NOLIBBASE__
struct Library *DOSBase = NULL ;
struct Library *SysBase = NULL ;
#else
struct DosLibrary *DOSBase = NULL ;
struct ExecBase *SysBase = NULL ;
#endif


BPTR stdout = 0L ;

int ASM SAVEDS __startup(REG(a0, char *cmdline))
{
  int ret ;
  struct Process *me ;
  struct WBStartup *wb = NULL ;
  static int argc;                            /* arg count */
  static char **targv, *argv[MAXARG+1];       /* arg pointers */

  SysBase = (*((struct Library **) 4));

  me=(struct Process *)FindTask( NULL) ;
  if (me->pr_CLI)
  {
  }
  else
  {
    WaitPort(&me->pr_MsgPort) ;
    wb = (struct WBStartup *)GetMsg(&me->pr_MsgPort) ;
  }

  DOSBase = OldOpenLibrary("dos.library") ;
  if (DOSBase)
  {
    char *text ;

    if (wb)
    {
      stdout = Open("CON:10/10/300/100/My prog without startup", MODE_NEWFILE) ;

      if (wb->sm_ToolWindow)
      {
        if (stdout)
        {
          char str[100] ;

          sprintf(str, "toolwindow \"%s\"\n", wb->sm_ToolWindow) ;
          Write(stdout, str, strlen(str)) ;
        }
      }
    }
    else
    {
      char **pargv;
      char *argbuf;
      char *line = cmdline ;

      /***
       *     Build argument pointer list
       ***/
      while (argc < MAXARG)
      {
        while (isspace(*line))  line++;
        if (*line == '\0')      break;
        pargv = &argv[argc++];
        if (*line == '"')
        {
            argbuf = *pargv = ++line;  /* ptr inside quoted string */
            while (*line != '"' && *line != 0)
            {
               if (*line == '*')
               {
                  line++;
                  switch (*line)
                  {
                     case '\0':
                        *argbuf = 0;
                        goto linedone;
                     case 'E':
                        *argbuf++ = '\027' ;
                        break;
                     case 'N':
                        *argbuf++ = '\n' ;
                        break;
                     default:
                        *argbuf++ = *line;
                  }
                  line++;
               }
               else
               {
                 *argbuf++ = *line++;
               }
            }
            line++;
            *argbuf++ = '\0'; /* terminate arg */
        }
        else            /* non-quoted arg */
        {       
            *pargv = line;
            while ((*line != '\0') && (!isspace(*line))) line++;
            if (*line == '\0')  break;
            else                *line++ = '\0';  /* terminate arg */
        }
      }  /* while */

linedone:

      targv = (argc == 0) ? (char **) wb : (char **) &argv[0];

      stdout = Output() ;
    }

    /***
     *     Call user's main program
     ***/

    ret = _main(argc, targv) ;

    if (wb)
    {
      Delay(100) ;
      if (stdout)
      {
        Close(stdout) ;
        stdout = 0L ;
      }
    }

    CloseLibrary((struct Library *)DOSBase) ;
  }
 
  if (wb)
  {
    Forbid() ;
    ReplyMsg(&wb->sm_Message) ;
  }

  me->pr_Result2 = ret ;
  return ret ;
}

size_t strlen(const char *str)
{
  char *s = str ;

  while (*s)
  {
    s++ ;
  }

  return (size_t)(s - str) ;
}

int sprintf(char *buffer, const char *format_string, ...)
{
  va_list args ;
  int len ;
  struct Library *SysBase = (*((struct Library **) 4));

  va_start(args, format_string) ;
  RawDoFmt((UBYTE*)format_string,
           (APTR)args,
           (VOID(*)())"\x16\xc0\x4e\x75", /* move.b d0,(A3)+; rts */
           (APTR)buffer) ;
  va_end(args) ;

  return (int)strlen(buffer) ;
}


// il y a un bug: argv[0] devrait être le nom du programme
//
//
int _main(int argc, char *argv[])
{
  int i ;
  char buf[100] ;

  if (stdout)
  {
    char *text="Hello world\n" ;
    Write(stdout, text, strlen(text)) ;


    if (argc == 0)
    {
      text = "from Workbench\n" ;
      Write(stdout, text, strlen(text)) ;
    }
    else
    {
      for (i = 0 ; i < argc ; i ++ )
      {
        sprintf(buf, "%ld : \"%s\"\n", i, argv[i]) ;
        Write(stdout, buf, strlen(buf)) ;
      }
    }
  }

  return 0 ;
}

Le makefile pour GCC

SRC=..
OBJ=obj
BIN=bin

target: $(BIN)/hello $(BIN)/hello.info

$(BIN)/hello: mystartup.s $(SRC)/nostartup.c
	gcc -s -Os -O3 -nostdlib -noixemul -fbaserel -fomit-frame-pointer -o $(BIN)/hello mystartup.s $(SRC)/nostartup.c

$(BIN)/hello.info: res/hello.info
	copy res/hello.info $(BIN)/hello.info

clean:
	del $(BIN)/#? $(OBJ)/#?
make
construira hello

make clean
détruira le fichier hello


Le makefile pour SAS/C
Pour le SAS/C, pas besoin de fichier assembleur, la première fonction définie sera considérée comme point d'entrée.

SRC=
OBJ=obj
BIN=bin
COPTS= nostackcheck opt optpeep optgo optinline optloop opttime 

target: $(BIN)/hello

$(OBJ)/nostartup.o: $(SRC)/nostartup.c
  sc $(COPTS) OBJNAME $(OBJ)/nostartup.o $(SRC)/nostartup.c

$(BIN)/hello: $(OBJ)/nostartup.o 
  slink $(OBJ)/nostartup.o\
  to $(BIN)/hello\
  verbose smallcode smalldata nodebug

make
construira hello