home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / a2ixlibrary-1.0-bin.lha / share / a2ixlibrary / instance.c < prev    next >
C/C++ Source or Header  |  1996-10-12  |  2KB  |  81 lines

  1. #include <proto/exec.h>
  2. #include <exec/execbase.h>
  3.  
  4. #include "a2ixlibrary.h"
  5.  
  6. extern int __datadata_relocs();
  7. extern int __a4_offset();
  8.  
  9. /* The a4 pointers are stored *before* the start of this struct! */
  10. struct user {
  11.     /* both a magic cookie and a way to get at the library base thru u */
  12.     void     *u_ixbase;
  13.     void     *u_reserved;        /* for future use */
  14.  
  15.     long    u_a4_pointers_size;    /* number of a4 pointers */
  16.     long    u_a4_pointers[0];
  17. };
  18.  
  19. #ifdef INSTANCE_LIBS
  20. INSTANCE_LIBS
  21. #endif
  22.  
  23. #define u  (*(struct user *)(SysBase->ThisTask->tc_TrapData))
  24.  
  25. long lib_open(long base)
  26. {
  27.   char *origdata, *newdata;
  28.   int datasize, numrel, i;
  29.   long *relocs = (long *)__datadata_relocs;
  30.   int offset = (-(long)__a4_offset) / 4 - 1;
  31.   /* cannot use the global SysBase variable because A4 isn't (yet) initialized */
  32.   struct ExecBase *SysBase = (struct ExecBase *)(*((long *)4));
  33.  
  34.   if (offset < 0 || offset >= u.u_a4_pointers_size)
  35.     return 0;
  36.   if (u.u_a4_pointers[-offset - 4])
  37.     return base;
  38.   asm ("movel #___data_size,%0; addl #___bss_size,%0" : "=r" (datasize));
  39.   asm ("movel #__sdata,%0" : "=r" (origdata));
  40.   newdata = AllocMem(datasize, 0);
  41.   if (!newdata) {
  42.     return 0;
  43.   }
  44.   for (i = 0; i < datasize; i++)
  45.     newdata[i] = origdata[i];
  46.   numrel = relocs[0];
  47.   while (numrel--)
  48.     *(long *)(newdata + *++relocs) -= origdata - newdata;
  49.   u.u_a4_pointers[-offset - 4] = (long)(newdata + 0x7ffe);
  50. #ifdef INSTANCE_LIBS
  51.   if (!open_libs()) {
  52.     close_libs();
  53.     u.u_a4_pointers[-offset - 4] = 0;
  54.     FreeMem(newdata, datasize);
  55.     return 0;
  56.   }
  57. #endif
  58. #ifdef CALL_INITS
  59.   CALL_INITS
  60. #endif
  61.   return base;
  62. }
  63.  
  64. void __LibCloseInstance(void)
  65. {
  66.   int datasize;
  67.   int offset = (-(long)__a4_offset) / 4 - 1;
  68.   /* A4 may be invalid here, so we don't use the global SysBase */
  69.   struct ExecBase *SysBase = (struct ExecBase *)(*((long *)4));
  70.  
  71.   if (u.u_a4_pointers[-offset - 4])
  72.   {
  73. #ifdef INSTANCE_LIBS
  74.     close_libs();
  75. #endif
  76.     asm ("movel #___data_size,%0; addl #___bss_size,%0" : "=r" (datasize));
  77.     FreeMem((void *)(u.u_a4_pointers[-offset - 4] - 0x7ffe), datasize);
  78.     u.u_a4_pointers[-offset - 4] = 0;
  79.   }
  80. }
  81.