extern struct ExecBase * SysBase;

static __inline void*
AllocMem (unsigned long byteSize,unsigned long requirements)
{
  register void*  _res  __asm("d0");
  register struct ExecBase *a6 __asm("a6") = SysBase;
  register unsigned long d0 __asm("d0") = byteSize;
  register unsigned long d1 __asm("d1") = requirements;
  __asm __volatile ("jsr a6@(-0xc6)"
  : "=r" (_res)
  : "r" (a6), "r" (d0), "r" (d1)
  : "a0","a1","d0","d1", "memory");
  return _res;
}

static __inline void
FreeMem (void *memoryBlock,unsigned long byteSize)
{
  register struct ExecBase *a6 __asm("a6") = SysBase;
  register void* a1 __asm("a1") = memoryBlock;
  register unsigned long d0 __asm("d0") = byteSize;
  __asm __volatile ("jsr a6@(-0xd2)"
  : /* no output */
  : "r" (a6), "r" (a1), "r" (d0)
  : "a0","a1","d0","d1", "memory");
}

struct atexit_node
{
	struct atexit_node *next;
/*	struct atexit_node *prev; */
	unsigned long function;
};

static struct atexit_node*__atexit_regs=0;
extern volatile void _exit(int status);
extern void __do_global_dtors ();

volatile void exit(int status)
{
	/* alles freigeben, da wären eigentlich nur atexit()-Sachen,
	   für den Rest ist der Programmierer schließlich selbst
           verantwortlich */

	struct atexit_node *t=__atexit_regs,*t2;

	void (*f)(void);


	if(t)
	{
		while(t)
		{
			(unsigned long)f=t->function;
			f();
			t2=t;
			t=t->next;
			FreeMem(t2,sizeof(struct atexit_node));
		}
	}

	__do_global_dtors ();

	_exit(status);
}

int atexit(unsigned long func)
{
	struct atexit_node *an;
	if((an=(struct atexit_node *)AllocMem(sizeof(struct atexit_node),(1L<<16)))) /* MEMF_CLEAR */
	{
		struct atexit_node *t=__atexit_regs;

		/* insert new routine at begin of atexit-list */

		__atexit_regs=an;

		an->next=t;
		an->function=func;

		return(0); /* succsess */
	}
	else
	{
		/* errno=12; */ /* ENOMEM */
		return(-1); /* fail */
	}
}
