/*
 *  This file is part of ixemul.library for the Amiga.
 *  Copyright (C) 1994  Rafael W. Luebbert
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  $Id: hwck.c,v 1.3 1994/10/18 09:12:51 rluebbert Exp $
 *
 *  $Log: hwck.c,v $
 * Revision 1.3  1994/10/18  09:12:51  rluebbert
 * Check for math emulation code (881 || 882) in 040s.  Assume no FPU otherwise.
 * No 040 FPU instruction support yet.
 *
 * Revision 1.2  1994/06/22  14:56:04  rluebbert
 * added struct ExecBase **4
 *
 * Revision 1.1  1994/06/19  15:11:39  rluebbert
 * Initial revision
 *
 */

#define _KERNEL
#include <ixemul.h>
#include <stdarg.h>
#include <proto/intuition.h>

static int show_msg(const char *msg, va_list ap, char *gadgetformat)
{
  struct IntuitionBase *IntuitionBase;
  u_char old_flags;
  struct Task *me = SysBase->ThisTask;
  int ret = 0;

  /*
   * This function may be called with our signals enabled. So we have to make
   * sure that no signals are processed while in here.
   * Since this function may be called at random points in initialization,
   * it is not safe to call sigsetmask() here, so I have to resort to the
   * more drastic solution of temporarily turning off TF_LAUNCH
   */
  old_flags = me->tc_Flags;
  me->tc_Flags &= ~TF_LAUNCH;

  if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0)))
    {
      struct EasyStruct panic = {
        sizeof(struct EasyStruct),
        0,
        "ixemul.library message",
        (char *)msg,
        gadgetformat
      };
        
      ret = EasyRequestArgs(NULL, &panic, NULL, ap);

      CloseLibrary ((struct Library *) IntuitionBase);
   }

  if (ixemulbase && (ix.ix_flags & ix_create_enforcer_hit) && betterthan68010())
    {
      asm ("movel #0,d0
            move.l d0,0xdeaddead
            nop
            add.l #2,sp
            move.l d0,0xdeaddead
            nop
            sub.l #2,sp" : /* no output */ : );
    }
  me->tc_Flags = old_flags;
  return ret;
}

void ix_panic(const char *msg, ...)
{
  va_list ap;
        
  va_start(ap, msg);
  show_msg(msg, ap, "Abort");
  va_end(ap);
}

void ix_warning(const char *msg, ...)
{
  va_list ap;
        
  va_start(ap, msg);
  if (!show_msg(msg, ap, "Continue|Abort"))
    exit(20);
  va_end(ap);
}

struct ixemul_base *ix_init_glue(struct ixemul_base *ixbase)
{
  /* First set SysBase, because it is used by the 'u' macro. The Enforcer
     manual recommends caching ExecBase because low-memory accesses are slower
     when using Enforcer, besides the extra penalty of being in CHIP memory.
     Also, lots of accesses to address 4 can hurt interrupt performance. */

  SysBase = *(struct ExecBase **)4;

#if defined (mc68020) || defined (mc68030) || defined (mc68040) || defined (mc68060)
  if (!betterthan68010())
    {
      ix_panic("This ixemul version requires a 68020/30/40/60.");
      return NULL;
    }
#endif
#ifdef __HAVE_68881__
  if (!gotanfpu())
    {
      if (SysBase->AttnFlags & AFF_68040)
	ix_panic("68040 math emulation code not found.");
      else
	ix_panic("This ixemul version requires an FPU.");
      return NULL;
    }
#endif
  return ix_init(ixbase);
}

