home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / developer-tools / aros / source / exec / internal / m68k / m68k-native / init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-16  |  5.3 KB  |  209 lines

  1. /*
  2.  * Exec startup code to emulate Amiga OS behaviour under Amiga OS.
  3.  *
  4.  * Clients of this startup code should be compiled with 'main' predefined
  5.  * to 'submain'. Globals like library bases must be redefined as well if
  6.  * they collide with existing ones.
  7.  */
  8.  
  9. #include <exec/execbase.h>
  10. #include <exec/memory.h>
  11. #include <clib/exec_protos.h>
  12. #include "memory.h"
  13. #include "machine.h"
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16.  
  17. #define NEWLIST(l)                          \
  18. ((l)->lh_Head=(struct Node *)&(l)->lh_Tail, \
  19.  (l)->lh_Tail=NULL,                         \
  20.  (l)->lh_TailPred=(struct Node *)(l))
  21.  
  22. extern void *ExecFunctions[];
  23.  
  24. #define MEMSIZE 1024*1024
  25. static struct MemHeader mh;
  26. static UBYTE memory[MEMSIZE+MEMCHUNK_TOTAL-1];
  27.  
  28. #define NUMVECT 131
  29.  
  30. struct ExecBase *SysBase;
  31.  
  32. #define STACKSIZE 4096
  33.  
  34. static void idle(void)
  35. {
  36.     /* If the idle task ever gets CPU time the emulation has locked up */
  37.     exit(20);
  38. }
  39.  
  40. APTR storedtrap;        /* Stored task trap vector */
  41. extern void trapvec(void);  /* Where the new trap vector points to */
  42.  
  43. /* restore trap vector at exit */
  44. void doexit(void)
  45. {
  46.     struct ExecBase *sb=*(struct ExecBase **)4;
  47.     if(sb->ThisTask->tc_TrapCode==&trapvec)
  48.     sb->ThisTask->tc_TrapCode=storedtrap;
  49. }
  50.  
  51. int submain(int argc,char *argv[]);
  52.  
  53. static int gargc;
  54. static char **gargv;
  55.  
  56. static void boot(void)
  57. {
  58.     /* return the returncode of the boot task */
  59.     exit(submain(gargc,gargv));
  60. }
  61.  
  62. static APTR allocmem(ULONG size)
  63. {
  64.     UBYTE *ret;
  65.  
  66.     size=(size+MEMCHUNK_TOTAL-1)&~(MEMCHUNK_TOTAL-1);
  67.     ret=(UBYTE *)mh.mh_First;
  68.     mh.mh_First=(struct MemChunk *)(ret+size);
  69.     mh.mh_First->mc_Next=NULL;
  70.     mh.mh_Free=mh.mh_First->mc_Bytes=((struct MemChunk *)ret)->mc_Bytes-size;
  71.     return ret;
  72. }
  73.  
  74. int main(int argc,char *argv[])
  75. {
  76.     struct ExecBase *sb=*(struct ExecBase **)4;
  77.  
  78.     if(atexit(&doexit))
  79.     return 20;
  80.  
  81.     storedtrap=sb->ThisTask->tc_TrapCode;
  82.     sb->ThisTask->tc_TrapCode=&trapvec;
  83.  
  84.     /* Put arguments into globals */
  85.     gargc=argc;
  86.     gargv=argv;
  87.  
  88.     /*
  89.     Prepare first MemHeader. I cannot use exec functions
  90.     here because exec is not yet up.
  91.     */
  92.     mh.mh_Node.ln_Name="unknown memory type";
  93.     mh.mh_Node.ln_Pri =0;
  94.     mh.mh_Attributes  =MEMF_PUBLIC; /* Public to my emulation */
  95.     mh.mh_First=(struct MemChunk *)
  96.         (((ULONG)memory+MEMCHUNK_TOTAL-1)&~(MEMCHUNK_TOTAL-1));
  97.     mh.mh_First->mc_Next=NULL;
  98.     mh.mh_First->mc_Bytes=MEMSIZE;
  99.     mh.mh_Lower=mh.mh_First;
  100.     mh.mh_Upper=(UBYTE *)mh.mh_Lower+MEMSIZE;
  101.     mh.mh_Free =MEMSIZE;
  102.  
  103.     /* The following allocations cannot and must not fail. */
  104.     {
  105.     /* Prepare exec.library */
  106.     ULONG neg,i;
  107.     neg=sizeof(struct JumpVec)*NUMVECT;
  108.     neg=(neg+LIBALIGN-1)&~(LIBALIGN-1);
  109.     SysBase=(struct ExecBase *)
  110.         ((UBYTE *)allocmem(neg+sizeof(struct ExecBase))+neg);
  111.     for(i=0;i<NUMVECT;i++)
  112.     {
  113.         SET_JMP(&((struct JumpVec *)SysBase)[-i-1]);
  114.         SET_VEC(&((struct JumpVec *)SysBase)[-i-1],ExecFunctions[i]);
  115.     }
  116.     /* Build GetCC vector (68000 version) */
  117.     ((UWORD *)((UBYTE *)SysBase-88*LIB_VECTSIZE))[0]=0x40c0; /* movew sr,d0 */
  118.     ((UWORD *)((UBYTE *)SysBase-88*LIB_VECTSIZE))[1]=0x4e75; /* rts         */
  119.  
  120.     SysBase->AttnFlags=sb->AttnFlags; /* No CPU check yet */
  121.  
  122. #ifdef mc68000
  123.     /* CPU OK ? */
  124.     if(SysBase->AttnFlags&AFB_68010)
  125.         fprintf(stderr,"Warning: wrong CPU version\n");
  126. #endif
  127.  
  128.     SysBase->LibNode.lib_Node.ln_Name="exec.library";
  129.  
  130.     NEWLIST(&SysBase->MemList);
  131.     AddHead(&SysBase->MemList,&mh.mh_Node);
  132.     NEWLIST(&SysBase->ResourceList);
  133.     NEWLIST(&SysBase->DeviceList);
  134.     NEWLIST(&SysBase->IntrList);
  135.     NEWLIST(&SysBase->LibList);
  136.     NEWLIST(&SysBase->PortList);
  137.     NEWLIST(&SysBase->TaskReady);
  138.     NEWLIST(&SysBase->TaskWait);
  139.  
  140.     for(i=0;i<5;i++)
  141.     {
  142.         NEWLIST(&SysBase->SoftInts[i].sh_List);
  143.     }
  144.  
  145.     NEWLIST(&SysBase->SemaphoreList);
  146.  
  147.     /* There are no memhandlers yet.
  148.      * (not even the library flushing one which is part of ram/dos.library) */
  149.     NEWLIST((struct List *)&SysBase->ex_MemHandlers);
  150.     SysBase->IDNestCnt=0;
  151.     SysBase->TDNestCnt=0;
  152.     SysBase->AttnResched=0;
  153.     }
  154.     {
  155.     /* Add boot task */
  156.     struct Task *t;
  157.     struct MemList *ml;
  158.  
  159.     ml=(struct MemList *)AllocMem(sizeof(struct MemList),MEMF_PUBLIC|MEMF_CLEAR);
  160.     t =(struct Task *)   AllocMem(sizeof(struct Task),   MEMF_PUBLIC|MEMF_CLEAR);
  161.     ml->ml_NumEntries     =1;
  162.     ml->ml_ME[0].me_Addr  =t;
  163.     ml->ml_ME[0].me_Length=sizeof(struct Task);
  164.  
  165.     NEWLIST(&t->tc_MemEntry);
  166.     AddHead(&t->tc_MemEntry,&ml->ml_Node);
  167.     t->tc_Node.ln_Name="Boot task";
  168.     t->tc_Node.ln_Pri=0;
  169.     t->tc_State=TS_RUN;
  170.     t->tc_SigAlloc=0xffff;
  171.     SysBase->ThisTask=t;
  172.     }
  173.     {
  174.     /* Add idle task */
  175.     struct Task *t;
  176.     struct MemList *ml;
  177.     UBYTE *s;
  178.  
  179.     ml=(struct MemList *)AllocMem(sizeof(struct MemList)+sizeof(struct MemEntry),
  180.                       MEMF_PUBLIC|MEMF_CLEAR);
  181.     t =(struct Task *)   AllocMem(sizeof(struct Task),    MEMF_PUBLIC|MEMF_CLEAR);
  182.     s =(UBYTE *)         AllocMem(STACKSIZE,              MEMF_PUBLIC|MEMF_CLEAR);
  183.     ml->ml_NumEntries     =2;
  184.     ml->ml_ME[0].me_Addr  =t;
  185.     ml->ml_ME[0].me_Length=sizeof(struct Task);
  186.     ml->ml_ME[1].me_Addr  =s;
  187.     ml->ml_ME[1].me_Length=STACKSIZE;
  188.  
  189.     NEWLIST(&t->tc_MemEntry);
  190.     AddHead(&t->tc_MemEntry,&ml->ml_Node);
  191.     t->tc_SPLower=s;
  192.     t->tc_SPUpper=s+STACKSIZE;
  193.     t->tc_Node.ln_Name="Idle task";
  194.     t->tc_Node.ln_Pri=-128;
  195. #if STACK_GROWS_DOWNWARDS
  196.     t->tc_SPReg=(UBYTE *)t->tc_SPUpper-SP_OFFSET;
  197. #else
  198.     t->tc_SPReg=(UBYTE *)t->tc_SPLower-SP_OFFSET;
  199. #endif
  200.     AddTask(t,&idle,NULL);
  201.     }
  202.     Enable();
  203.     Permit();
  204.     boot();
  205.  
  206.     /* Get compiler happy */
  207.     return 0;
  208. }
  209.