#include <exec/execbase.h>
#include <libraries/expansion.h>
#include <libraries/configvars.h>
#include <graphics/gfxbase.h>
#define __USE_SYSBASE
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/expansion.h>
#include <string.h>

#include "opts.h"
#include "config.h"

long cpu_id;
long eclock_freq;
long aga;

/*
 * Try to determine the machine ID by searching the resident module list
 * for modules only present on specific machines.  (Thanks, Bill!)
 */
VOID get_cpu_id()
{
	cpu_id |= SysBase->AttnFlags;	/* get FPU and CPU flags */
	if (cpu_id & 0xffff0000) {
		switch (cpu_id >> 16) {
		case 500:
		case 600:
		case 1000:
		case 1200:
		case 2000:
		case 3000:
		case 4000:
			return;
		default:
			print("machine Amiga ");
			printlong(cpu_id >> 16);
			print(" is not recognized\n");
			exit(1);
		}
	}
	if (FindResident("A4000 Bonus") || FindResident("A1000 Bonus") ||
	    FindResident("A4000 bonus") || FindResident("A1000 bonus"))
		cpu_id |= 4000 << 16;
	else if (FindResident("A3000 Bonus") || FindResident("A3000 bonus"))
		cpu_id |= 3000 << 16;
	else if (OpenResource("card.resource")) {
		/* Test for AGA? */
		cpu_id |= 1200 << 16;
	}
	/*
	 * Nothing found, it's probably an A2000 or A500
	 */
	if ((cpu_id >> 16) == 0)
		cpu_id |= 2000 << 16;

	if ((cpu_id & AFF_68020) == 0)
		fatal("Cpu not supported");
}

VOID get_eclock()
{
	/* Fix for 1.3 startups? */
	if (SysBase->LibNode.lib_Version >= 36)
		eclock_freq = SysBase->ex_EClockFrequency;
	else
		eclock_freq = (GfxBase->DisplayFlags & PAL) ?
		    709379 : 715909;

	aga = (GfxBase->ChipRevBits0 & GFXF_AA_LISA) != 0;
}

ULONG get_config()
{
	struct ConfigDev *cd;
	int n;

	n  = 0;
	cd = NULL;
	while (cd = FindConfigDev(cd, -1, -1))
		if (!(cd->cd_Flags & CDF_SHUTUP))
			++n;

	return sizeof(ULONG) + n * sizeof(struct ConfigDev);
}

VOID copy_config(UBYTE *buf)
{
	struct ConfigDev *cd;
	UBYTE *p;
	int n;

	p  = buf + sizeof(ULONG);
	n  = 0;
	cd = NULL;
	while (cd = FindConfigDev(cd, -1, -1)) {
		if (cd->cd_Flags & CDF_SHUTUP)
			continue;

		memcpy(p, cd, sizeof(struct ConfigDev));
		p += sizeof(struct ConfigDev);
		++n;
	}

	*(ULONG *)buf = n;
}

Loader copy_loader(UBYTE *src, UBYTE *dst, ULONG length)
{
	CopyMem(src, dst, length);
	if (SysBase->LibNode.lib_Version >= 36)
		CacheClearU();

	return (Loader)dst;
}
