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

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