/* cookie.c - does checks for FPU and CPU */
/* Relies on the COOKIE jar being correct for the hardware */
/* If it is not, then warnings (or crashes) may appear */
/* Warnings can be turned of with the '-nowarn' option */ 
/* Roland Givan (c), Autumn 1994 */
/* This code is LC specific and won't work under GCC */

#include <cookie.h>
#include "c_includes.h"

#define HAS_NOFPU 0
#define HAS_IOFPU 1
#define HAS_COPRO 2
#define HAS_BOTH  3

#define HAS_68000 0
#define HAS_68030 1

#define IS_COPRO (short)(0xE)
#define IS_IOFPU (short)(0x01)
#define IS_68020 0x14

extern int warn(char *mess);

int verify_cpu(void);
int verify_fpu(void);

#ifndef MC68000
#ifndef MC68030
#error Must define either MC68000 or MC68030!
#endif
#endif

#ifdef MC68000
#ifdef MC68030
#error Must only define *one* processor type!
#endif
#endif

#ifndef NOFPU
#ifndef COPRO
#ifndef IOFPU
#error Must define either NOFPU, COPRO or IOFPU!
#endif
#endif
#endif

#ifdef NOFPU
#ifdef COPRO
#error Must not define *2* FPU options!
#endif
#endif

#ifdef NOFPU
#ifdef IOFPU
#error Must not define *2* FPU options!
#endif
#endif

#ifdef IOFPU
#ifdef COPRO
#error Must not define *2* FPU options!
#endif
#endif

int verify_cpu(void)
{
#ifdef MC68000
	if (check_cpu()!=HAS_68000){
		return(warn("This is the 68000 version | but this machine can run | the 68030 version."));
	}
#endif
#ifdef MC68030
	if (check_cpu()!=HAS_68030){
/* We'll be very 'lucky' to get this far. The 68030 version is likely to crash on the 68000 long before here! */
		return(warn("This is the 68030 version | but this machine doesn't appear | to have a one."));
	}
#endif
	return(TRUE);	/* default */
}

int verify_fpu(void)
{
#ifdef NOFPU
	if (check_fpu()!=HAS_NOFPU){
		switch(check_fpu()){
		case HAS_COPRO:
			return(warn("Co-Pro Maths FPU Detected. | Dedicated version will | be faster."));
			break;
		case HAS_IOFPU:
			return(warn("I/O Maths FPU Detected. | Dedicated version will | be faster."));
			break;
		}
	}
#else
	if (check_fpu()!=HAS_BOTH){		/* No need for further checks if machine has both FPU units */
#ifdef COPRO
		if (check_fpu()!=HAS_COPRO){
/* Unlikely to get this far without a COPRO. RMG */
			return(warn("Co-Pro Maths FPU version | but this machine doesn't | appear to have one."));
		}
#endif
#ifdef IOFPU
		if (check_fpu()!=HAS_IOFPU){
/* Unlikely to get this far without an IOFPU. RMG */
			return(warn("I/O Maths FPU version | but this machine doesn't | appear to have one."));
		}
#endif
	}
#endif
	return(TRUE);	/* default */
}

int check_fpu(void)
{
	short fpu;
	long ret=0;

	getcookie(_FPU,&ret);
	fpu=ret>>16;
	if ((fpu & IS_COPRO) && (fpu & IS_IOFPU)){
		return(HAS_BOTH);
	}

	if (fpu & IS_COPRO){
		return(HAS_COPRO);
	}

	if (fpu & IS_IOFPU){
		return(HAS_IOFPU);
	}

	return(HAS_NOFPU);
}

int check_cpu(void)
{
	long cpu=0;

	getcookie(_CPU,&cpu);
	if ((cpu & 0xFF) >= IS_68020){
		return(HAS_68030);	/* 68030 version *should* work on 68020 and upwards */
	}
	return(HAS_68000);	/* Assume 68000 */
}