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

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