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 >
Wrap
C/C++ Source or Header
|
1996-10-12
|
2KB
|
81 lines
#include <proto/exec.h>
#include <exec/execbase.h>
#include "a2ixlibrary.h"
extern int __datadata_relocs();
extern int __a4_offset();
/* The a4 pointers are stored *before* the start of this struct! */
struct user {
/* both a magic cookie and a way to get at the library base thru u */
void *u_ixbase;
void *u_reserved; /* for future use */
long u_a4_pointers_size; /* number of a4 pointers */
long u_a4_pointers[0];
};
#ifdef INSTANCE_LIBS
INSTANCE_LIBS
#endif
#define u (*(struct user *)(SysBase->ThisTask->tc_TrapData))
long lib_open(long base)
{
char *origdata, *newdata;
int datasize, numrel, i;
long *relocs = (long *)__datadata_relocs;
int offset = (-(long)__a4_offset) / 4 - 1;
/* cannot use the global SysBase variable because A4 isn't (yet) initialized */
struct ExecBase *SysBase = (struct ExecBase *)(*((long *)4));
if (offset < 0 || offset >= u.u_a4_pointers_size)
return 0;
if (u.u_a4_pointers[-offset - 4])
return base;
asm ("movel #___data_size,%0; addl #___bss_size,%0" : "=r" (datasize));
asm ("movel #__sdata,%0" : "=r" (origdata));
newdata = AllocMem(datasize, 0);
if (!newdata) {
return 0;
}
for (i = 0; i < datasize; i++)
newdata[i] = origdata[i];
numrel = relocs[0];
while (numrel--)
*(long *)(newdata + *++relocs) -= origdata - newdata;
u.u_a4_pointers[-offset - 4] = (long)(newdata + 0x7ffe);
#ifdef INSTANCE_LIBS
if (!open_libs()) {
close_libs();
u.u_a4_pointers[-offset - 4] = 0;
FreeMem(newdata, datasize);
return 0;
}
#endif
#ifdef CALL_INITS
CALL_INITS
#endif
return base;
}
void __LibCloseInstance(void)
{
int datasize;
int offset = (-(long)__a4_offset) / 4 - 1;
/* A4 may be invalid here, so we don't use the global SysBase */
struct ExecBase *SysBase = (struct ExecBase *)(*((long *)4));
if (u.u_a4_pointers[-offset - 4])
{
#ifdef INSTANCE_LIBS
close_libs();
#endif
asm ("movel #___data_size,%0; addl #___bss_size,%0" : "=r" (datasize));
FreeMem((void *)(u.u_a4_pointers[-offset - 4] - 0x7ffe), datasize);
u.u_a4_pointers[-offset - 4] = 0;
}
}