#include <exec/types.h>
#include <exec/libraries.h>
#include <emul/emulinterface.h>
#include <emul/emulregs.h>
#include "a2ixlibrary.h"

#ifdef DEBUG
void dprintf(const char *, ...);
#define DB(x) x
#else
#define DB(x)
#endif

typedef void (*func_ptr) (void);

void *ixemulbase = 0;
int (**_ixbasearray)();
int *ixemul_errno;
char *_ctype_;
void **__sF;
void **__pstk_limit;

#ifdef __PPC__
extern void (*__ctrslist[])() __attribute__((section(".ctors")));
#else
extern func_ptr __CTOR_LIST__[];
#endif

#ifdef MISC_SETVARS
  MISC_SETVARS
#endif

void __LibSetVarsInstance(void)
{  
  int argc = REG_D0;
  void *ixbase = (void *)REG_D1;
  int *errnoptr = (int *)REG_D2;
  char *ctype = (char *)REG_D3;
  void **sf = (void **)REG_D4;
  void **stk_limit = (void **)REG_D5;
  unsigned long nptrs, i, size;

  DB(register int r13 asm("r13"));
  DB(dprintf("setvars(%lx), r13 = %lx, &ixemulbase = %lx, ixemulbase = %lx\n", ixbase, r13, &ixemulbase, ixemulbase);)

  if (ixemulbase)
    return;

  switch (argc)
  {
    default:
    case 5:
      if (stk_limit) __pstk_limit = stk_limit;
    case 4:
      if (sf) __sF = sf;
    case 3:
      if (ctype) _ctype_ = ctype;
    case 2:
      if (errnoptr) ixemul_errno = errnoptr;
    case 1:
      if (ixbase)
      {
	struct ixbase { struct Library lib; int (**basearray)(); };
	ixemulbase = ixbase;
	_ixbasearray = ((struct ixbase *)ixbase)->basearray;
      }
    case 0:
  }

#ifdef CALL_SETVARS
  CALL_SETVARS
#endif

  /* Call constructors */
  size = (int)__ctrslist[-2] / sizeof(__ctrslist[0]) - 2;
  for (i = 0; i < size; ++i) {
    if (__ctrslist[i])
      __ctrslist[i]();
  }
}

asm("
	.section \".ctors\",\"a\",@progbits
__ctrslist:
	.long 0
");

