 /*
  * UAE - The Un*x Amiga Emulator
  *
  * ROM file management
  *
  */ 

#include "sysconfig.h"
#include "sysdeps.h"

#include "options.h"
#include "uae.h"
#include "gui.h"
#include "memory.h"
#include "rommgr.h"
#include "zfile.h"
#include "crc32.h"
#include "fsdb.h"
#include "autoconf.h"
#include "filesys.h"
#include "arcadia.h"

#define SAVE_ROM 0

static struct romlist *rl;
static int romlist_cnt;
// Bumped on every change to the rom list contents (add/clear). Lets callers that
// cache derived data detect a rebuild even when the entry count is unchanged
// (e.g. a rescan that swaps ROMs for a different set of the same size).
static int romlist_gen;

struct romlist *romlist_getit (void)
{
	return rl;
}

int romlist_count (void)
{
	return romlist_cnt;
}

int romlist_get_generation (void)
{
	return romlist_gen;
}

TCHAR *romlist_get (const struct romdata *rd)
{
	int i;

	if (!rd)
		return 0;
	for (i = 0; i < romlist_cnt; i++) {
		if (rl[i].rd->id == rd->id)
			return rl[i].path;
	}
	return 0;
}

static struct romlist *romlist_getrl (const struct romdata *rd)
{
	int i;

	if (!rd)
		return 0;
	for (i = 0; i < romlist_cnt; i++) {
		if (rl[i].rd == rd)
			return &rl[i];
	}
	return 0;
}

static void romlist_cleanup (void);
void romlist_add (const TCHAR *path, struct romdata *rd)
{
	struct romlist *rl2;

	if (path == NULL || rd == NULL) {
		romlist_cleanup ();
		return;
	}
	romlist_cnt++;
	romlist_gen++;
	rl = xrealloc (struct romlist, rl, romlist_cnt);
	rl2 = rl + romlist_cnt - 1;
	rl2->path = my_strdup (path);
	rl2->rd = rd;
	struct romdata *rd2 = getromdatabyid (rd->id);
	if (rd2 != rd && rd2) { // replace "X" with parent name
		rd->name = rd2->name;
		rd->sortpriority = rd2->sortpriority;
	}
}

struct romdata *getromdatabypath (const TCHAR *path)
{
	int i;
	for (i = 0; i < romlist_cnt; i++) {
		struct romdata *rd = rl[i].rd;
		if (rd->configname && path[0] == ':') {
			if (!_tcscmp(path + 1, rd->configname))
				return rd;
		}
		if (my_issamepath(rl[i].path, path))
			return rl[i].rd;
	}
	return NULL;
}

#define NEXT_ROM_ID 342

#if NEXT_ROM_ID >= MAX_ROMMGR_ROMS
#error Increase MAX_ROMMGR_ROMS!
#endif

#define ALTROM(id,grp,num,size,flags,crc32,a,b,c,d,e) \
{ _T("X"), 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, NULL, crc32, a, b, c, d, e },
#define ALTROMPN(id,grp,num,size,flags,pn,crc32,a,b,c,d,e) \
{ _T("X"), 0, 0, 0, 0, 0, size, id, 0, 0, flags, (grp << 16) | num, 0, pn, crc32, a, b, c, d, e },

static struct romdata roms[] = {
	{ _T("AROS KS ROM (built-in)"), 0, 0, 0, 0, _T("AROS\0"), 524288 * 2, 66, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xffffffff, 0, 0, 0, 0, 0, _T("AROS"), NULL, 6 },
	{ _T("ROM Disabled"), 0, 0, 0, 0, _T("NOROM\0"), 0, 87, 0, 0, ROMTYPE_NONE, 0, 0, NULL,
	0xffffffff, 0, 0, 0, 0, 0, _T("NOROM"), NULL, -1 },
	{ _T("Enabled"), 0, 0, 0, 0, _T("ENABLED\0"), 0, 142, 0, 0, ROMTYPE_NOT, 0, 0, NULL,
	0xffffffff, 0, 0, 0, 0, 0, _T("ENABLED"), NULL, -1 },

	{ _T("Cloanto Amiga Forever ROM key"), 0, 0, 0, 0, 0, 2069, 0, 0, 1, ROMTYPE_KEY, 0, 0, NULL,
	0x869ae1b1, 0x801bbab3,0x2e3d3738,0x6dd1636d,0x4f1d6fa7,0xe21d5874 },
	{ _T("Cloanto Amiga Forever 2006 ROM key"), 0, 0, 0, 0, 0, 750, 48, 0, 1, ROMTYPE_KEY, 0, 0, NULL,
	0xb01c4b56, 0xbba8e5cd,0x118b8d92,0xafed5693,0x5eeb9770,0x2a662d8f },
	{ _T("Cloanto Amiga Forever 2010 ROM key"), 0, 0, 0, 0, 0, 1544, 73, 0, 1, ROMTYPE_KEY, 0, 0, NULL,
	0x8c4dd05c, 0x05034f62,0x0b5bb7b2,0x86954ea9,0x164fdb90,0xfb2897a4 },

	{ _T("6570-036 Keyboard MCU ROM"), 0, 0, 0, 0, _T("KBDMCU\0"), 2048, 321, 0, 0, ROMTYPE_KBMCU, 0, 0, NULL,
	0x4a3fc332, 0x83b21d0c, 0x8b93fc9b, 0x9b3b287f, 0xde4ec8f3, 0xbadac5a2 },
	{ _T("68HC05 Keyboard MCU ROM"), 0, 0, 0, 0, _T("KBDMCU\0"), 8192, 322, 0, 0, ROMTYPE_KBMCU, 0, 0, NULL,
	0x2a77eec4, 0x301ec6a6, 0x9404457d, 0x912c89e3, 0xfc54095e, 0xda9f0e93 },
	{ _T("D8039HLC Keyboard MCU ROM"), 0, 0, 0, 0, _T("KBDMCU\0"), 2048, 323, 0, 0, ROMTYPE_KBMCU, 0, 0, NULL,
	0xc23d280e, 0xb5c4b8c3, 0x8b9e4a86, 0x4abc871d, 0x048bd1c3, 0xa02c8432 },

	{ _T("KS ROM v23.93 (Velvet)"), 23, 93, 23, 93, _T("VELVET\0"), 131072, 125, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xadcb44c9, 0x7c36b2ba,0x298da3da,0xce60d0ba,0x8511d470,0x76a40d5c, NULL, NULL, 4 },
	ALTROMPN(125, 1, 1, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x1d988ab8, 0xee3988a2, 0xb2693334, 0x0239d1d9, 0xf50d4fb3, 0xe0daf3bc)
	ALTROMPN(125, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xe466b28f, 0x3e197d69, 0xcffa3e1a, 0x0c291d57, 0xb53f7d1f, 0xcb858cf7)
	ALTROMPN(125, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x715988a9, 0x08c36600, 0x3948c4c5, 0x4216ef8c, 0x17ebe16c, 0xc91d3b7a)
	ALTROMPN(125, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xc4dc7e6a, 0x66b231d0, 0x8425c858, 0xdfcd36d2, 0xd38a0df8, 0x518e06a4)

	{ _T("KS ROM v1.0 (A1000)(NTSC)"), 1, 0, 1, 0, _T("A1000\0"), 262144, 1, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x299790ff, 0x00C15406,0xBEB4B8AB,0x1A16AA66,0xC05860E1,0xA7C1AD79 },
	{ _T("KS ROM v1.1 (A1000)(NTSC)"), 1, 1, 31, 34, _T("A1000\0"), 262144, 2, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xd060572a, 0x4192C505,0xD130F446,0xB2ADA6BD,0xC91DAE73,0x0ACAFB4C},
	{ _T("KS ROM v1.1 (A1000)(PAL)"), 1, 1, 31, 34, _T("A1000\0"), 262144, 3, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xec86dae2, 0x16DF8B5F,0xD524C5A1,0xC7584B24,0x57AC15AF,0xF9E3AD6D },
	{ _T("KS ROM v1.2 (A1000)"), 1, 2, 33, 166, _T("A1000\0"), 262144, 4, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x9ed783d0, 0x6A7BFB5D,0xBD6B8F17,0x9F03DA84,0xD8D95282,0x67B6273B },
	{ _T("KS ROM v1.2 (A500,A1000,A2000)"), 1, 2, 33, 180, _T("A500\0A1000\0A2000\0"), 262144, 5, 0, 0, ROMTYPE_KICK, 0, 0, _T("315093-01"),
	0xa6ce1636, 0x11F9E62C,0xF299F721,0x84835B7B,0x2A70A163,0x33FC0D88 },
	{ _T("KS ROM v1.3 (A500,A1000,A2000)"), 1, 3, 34, 5, _T("A500\0A1000\0A2000\0"), 262144, 6, 0, 0, ROMTYPE_KICK, 0, 0, _T("315093-02"),
	0xc4f0f55f, 0x891E9A54,0x7772FE0C,0x6C19B610,0xBAF8BC4E,0xA7FCB785 },
	{ _T("KS ROM v1.3 (A3000)(SK)"), 1, 3, 34, 5, _T("A3000\0"), 262144, 32, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xe0f37258, 0xC39BD909,0x4D4E5F4E,0x28C1411F,0x30869504,0x06062E87 },
	{ _T("KS ROM v1.4 (A3000)"), 1, 4, 36, 16, _T("A3000\0"), 524288, 59, 3, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xbc0ec13f, 0xF76316BF,0x36DFF14B,0x20FA349E,0xD02E4B11,0xDD932B07 },
	ALTROMPN(59, 1, 1, 262144, ROMTYPE_EVEN, _T("390629-02"), 0x58327536,0xd1713d7f,0x31474a59,0x48e6d488,0xe3368606,0x1cf3d1e2)
	ALTROMPN(59, 1, 2, 262144, ROMTYPE_ODD , _T("390630-02"), 0xfe2f7fb9,0xc05c9c52,0xd014c66f,0x9019152b,0x3f2a2adc,0x2c678794)
	{ _T("KS ROM v2.04 (A500+)"), 2, 4, 37, 175, _T("A500+\0"), 524288, 7, 0, 0, ROMTYPE_KICK, 0, 0, _T("390979-01"),
	0xc3bdb240, 0xC5839F5C,0xB98A7A89,0x47065C3E,0xD2F14F5F,0x42E334A1 },
	{ _T("KS ROM v2.05 (A600)"), 2, 5, 37, 299, _T("A600\0"), 524288, 8, 0, 0, ROMTYPE_KICK, 0, 0, _T("391388-01"),
	0x83028fb5, 0x87508DE8,0x34DC7EB4,0x7359CEDE,0x72D2E3C8,0xA2E5D8DB },
	{ _T("KS ROM v2.05 (A600HD)"), 2, 5, 37, 300, _T("A600HD\0A600\0"), 524288, 9, 0, 0, ROMTYPE_KICK, 0, 0, _T("391304-01"),
	0x64466c2a, 0xF72D8914,0x8DAC39C6,0x96E30B10,0x859EBC85,0x9226637B },
	{ _T("KS ROM v2.05 (A600HD)"), 2, 5, 37, 350, _T("A600HD\0A600\0"), 524288, 10, 0, 0, ROMTYPE_KICK, 0, 0, _T("391304-02"),
	0x43b0df7b, 0x02843C42,0x53BBD29A,0xBA535B0A,0xA3BD9A85,0x034ECDE4 },
	{ _T("KS ROM v2.04 (A3000)"), 2, 4, 37, 175, _T("A3000\0"), 524288, 71, 8, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x234a7233, 0xd82ebb59,0xafc53540,0xddf2d718,0x7ecf239b,0x7ea91590 },
	ALTROMPN(71, 1, 1, 262144, ROMTYPE_EVEN, _T("390629-03"), 0xa245dbdf,0x83bab8e9,0x5d378b55,0xb0c6ae65,0x61385a96,0xf638598f)
	ALTROMPN(71, 1, 2, 262144, ROMTYPE_ODD , _T("390630-03"), 0x7db1332b,0x48f14b31,0x279da675,0x7848df6f,0xeb531881,0x8f8f576c)

	{ _T("KS ROM v3.0 (A1200)"), 3, 0, 39, 106, _T("A1200\0"), 524288, 11, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x6c9b07d2, 0x70033828,0x182FFFC7,0xED106E53,0x73A8B89D,0xDA76FAA5 },
	ALTROMPN(11, 1, 1, 262144, ROMTYPE_EVEN, _T("391523-01"), 0xc742a412,0x999eb81c,0x65dfd07a,0x71ee1931,0x5d99c7eb,0x858ab186)
	ALTROMPN(11, 1, 2, 262144, ROMTYPE_ODD , _T("391524-01"), 0xd55c6ec6,0x3341108d,0x3a402882,0xb5ef9d3b,0x242cbf3c,0x8ab1a3e9)
	{ _T("KS ROM v3.0 (A4000)"), 3, 0, 39, 106, _T("A4000\0"), 524288, 12, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x9e6ac152, 0xF0B4E9E2,0x9E12218C,0x2D5BD702,0x0E4E7852,0x97D91FD7 },
	ALTROMPN(12, 1, 1, 262144, ROMTYPE_EVEN, _T("391513-02"), 0x36f64dd0,0x196e9f3f,0x9cad934e,0x181c07da,0x33083b1f,0x0a3c702f)
	ALTROMPN(12, 1, 2, 262144, ROMTYPE_ODD , _T("391514-02"), 0x17266a55,0x42fbed34,0x53d1f11c,0xcbde89a9,0x826f2d11,0x75cca5cc)
	{ _T("KS ROM v3.1 (A4000)"), 3, 1, 40, 70, _T("A4000\0"), 524288, 13, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x2b4566f1, 0x81c631dd,0x096bbb31,0xd2af9029,0x9c76b774,0xdb74076c },
	ALTROM(13, 1, 1, 262144, ROMTYPE_EVEN, 0xf9cbecc9,0x138d8cb4,0x3b8312fe,0x16d69070,0xde607469,0xb3d4078e)
	ALTROM(13, 1, 2, 262144, ROMTYPE_ODD , 0xf8248355,0xc2379547,0x9fae3910,0xc185512c,0xa268b82f,0x1ae4fe05)
	{ _T("KS ROM v3.1 (A500,A600,A2000)"), 3, 1, 40, 63, _T("A500\0A600\0A2000\0"), 524288, 14, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xfc24ae0d, 0x3B7F1493,0xB27E2128,0x30F989F2,0x6CA76C02,0x049F09CA },
	{ _T("KS ROM v3.1 (A1200)"), 3, 1, 40, 68, _T("A1200\0"), 524288, 15, 1, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x1483a091, 0xE2154572,0x3FE8374E,0x91342617,0x604F1B3D,0x703094F1 },
	ALTROMPN(15, 1, 1, 262144, ROMTYPE_EVEN, _T("391773-01"), 0x08dbf275,0xb8800f5f,0x90929810,0x9ea69690,0xb1b8523f,0xa22ddb37)
	ALTROMPN(15, 1, 2, 262144, ROMTYPE_ODD , _T("391774-01"), 0x16c07bf8,0x90e331be,0x1970b0e5,0x3f53a9b0,0x390b51b5,0x9b3869c2)
	{ _T("KS ROM v3.1 (A3000)"), 3, 1, 40, 68, _T("A3000\0"), 524288, 61, 2, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xefb239cc, 0xF8E210D7,0x2B4C4853,0xE0C9B85D,0x223BA20E,0x3D1B36EE },
	ALTROM(61, 1, 1, 262144, ROMTYPE_EVEN, 0x286b9a0d,0x6763a225,0x8ec493f7,0x408cf663,0x110dae9a,0x17803ad1)
	ALTROM(61, 1, 2, 262144, ROMTYPE_ODD , 0x0b8cde6a,0x5f02e97b,0x48ebbba8,0x7d516a56,0xb0400c6f,0xc3434d8d)
	{ _T("KS ROM v3.1 (A4000)(Cloanto)"), 3, 1, 40, 68, _T("A4000\0"), 524288, 31, 2 | 4, 1, ROMTYPE_KICK, 0, 0, NULL,
	0x43b6dd22, 0xC3C48116,0x0866E60D,0x085E436A,0x24DB3617,0xFF60B5F9 },
	{ _T("KS ROM v3.1 (A4000)"), 3, 1, 40, 68, _T("A4000\0"), 524288, 16, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xd6bae334, 0x5FE04842,0xD04A4897,0x20F0F4BB,0x0E469481,0x99406F49 },
	ALTROM(16, 1, 1, 262144, ROMTYPE_EVEN, 0xb2af34f8,0x24e52b5e,0xfc020495,0x17387ab7,0xb1a1475f,0xc540350e)
	ALTROM(16, 1, 2, 262144, ROMTYPE_ODD , 0xe65636a3,0x313c7cbd,0xa5779e56,0xf19a41d3,0x4e760f51,0x7626d882)
	{ _T("KS ROM v3.1 (A4000T)"), 3, 1, 40, 70, _T("A4000T\0"), 524288, 17, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x75932c3a, 0xB0EC8B84,0xD6768321,0xE01209F1,0x1E6248F2,0xF5281A21 },
	ALTROMPN(17, 1, 1, 262144, ROMTYPE_EVEN, _T("391657-01"), 0x0ca94f70,0xb3806eda,0xcb3362fc,0x16a154ce,0x1eeec5bf,0x5bc24789)
	ALTROMPN(17, 1, 2, 262144, ROMTYPE_ODD , _T("391658-01"), 0xdfe03120,0xcd7a706c,0x431b04d8,0x7814d3a2,0xd8b39710,0x0cf44c0c)
	{ _T("KS ROM v3.X (A4000)(Cloanto)"), 3, 10, 45, 57, _T("A4000\0"), 524288, 46, 2 | 4, 1, ROMTYPE_KICK, 0, 0, NULL,
	0x3ac99edc, 0x3cbfc9e1,0xfe396360,0x157bd161,0xde74fc90,0x1abee7ec },

	{ _T("KS ROM v3.1.4-1 (A1200)"), 3, 1, 46, 143, _T("A1200\0"), 524288, 276, 1, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xF17FA97F, 0x6355A9ED, 0x5DC84042, 0x2F9B7330, 0x8A91BE0D, 0x0BB506BD },
	ALTROM(276, 1, 1, 262144, ROMTYPE_EVEN, 0x8786c81c, 0x5f015f47,0xa77c58eb,0xadcd0ff2,0xb7b2e590,0x092a9de1)
	ALTROM(276, 1, 2, 262144, ROMTYPE_ODD, 0x595f5c17, 0x54cb54fa,0x95870c05,0xaef8dc54,0xf4722404,0x56d2c6dd)
	{ _T("KS ROM v3.1.4-1 (A3000)"), 3, 1, 46, 143, _T("A3000\0"), 524288, 277, 2, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x50c3529c, 0x1a34b25a,0x25e260e3,0x8e879172,0x850143c8,0x0b461a64 },
	ALTROM(277, 1, 1, 262144, ROMTYPE_EVEN, 0xc0b1c172, 0xe5361ef0,0x19b6cde6,0x40ce1695,0x53addbce,0xc25baafa)
	ALTROM(277, 1, 2, 262144, ROMTYPE_ODD, 0x34a26902, 0xec36b5c7,0x9572189a,0x82e102f3,0xab5993b0,0xc79ee172)
	{ _T("KS ROM v3.1.4-1 (A4000)"), 3, 1, 46, 143, _T("A4000\0"), 524288, 278, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xd47e18fd, 0xbad0ae38,0x8442db02,0xeaeb6a53,0x63ef43eb,0x4e308ae6 },
	ALTROM(278, 1, 1, 262144, ROMTYPE_EVEN, 0x83e4232b, 0x6ba0637c,0x16b725d7,0x227e2405,0x148f2da0,0x22bd4308)
	ALTROM(278, 1, 2, 262144, ROMTYPE_ODD, 0x99b50a0f, 0xb784217e,0x69bb11fe,0xf218263f,0x3df6230e,0x7af2d3cd)
	{ _T("KS ROM v3.1.4-1 (A4000T)"), 3, 1, 46, 143, _T("A4000T\0"), 524288, 279, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x75a2b2a5, 0x938a60a1,0xd2c0d411,0xf64bb27e,0x5af40258,0xb8decbf3 },
	ALTROM(279, 1, 1, 262144, ROMTYPE_EVEN, 0x363eb810, 0x2bc46983,0xcd65b6c6,0xbd96d9c7,0x44bbc044,0x52bc7bed)
	ALTROM(279, 1, 2, 262144, ROMTYPE_ODD, 0xa84ee292, 0x8f815768,0xc7fd0091,0xdc6a2360,0x17aba072,0x7716e7f4)
	{ _T("KS ROM v3.1.4-1 (A500)"), 3, 1, 46, 143, _T("A500\0"), 524288, 280, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xD52B52FD, 0x8A240508, 0x7CE18222, 0x5656DD0B, 0x93069C45, 0x743F9E34 },

	{ _T("KS ROM v3.1.4-2 (A1200)"), 3, 1, 46, 143, _T("A1200\0"), 524288, 281, 1, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xB87506A7, 0xEF36C463, 0x8EE45DE6, 0xBB937017, 0x61216C95, 0x8CD0D57B },
	ALTROM(281, 1, 1, 262144, ROMTYPE_EVEN, 0xf30a5e19, 0xa485aa98,0x87bd154b,0x3739b1ad,0x89567c63,0xc579a03f)
	ALTROM(281, 1, 2, 262144, ROMTYPE_ODD, 0xa4efa49f, 0x00c38075,0x223ded76,0x32880253,0x898a7987,0xc018af73)
	{ _T("KS ROM v3.1.4-2 (A3000)"), 3, 1, 46, 143, _T("A3000\0"), 524288, 282, 2, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xBA35F8EB, 0xD73AE3A3, 0x6F12BB49, 0xBBF6BA04, 0xA890FF7A, 0xAC419015 },
	ALTROM(282, 1, 1, 262144, ROMTYPE_EVEN, 0x7ada7e63, 0x69f90617,0xe4f0642f,0x49a797f0,0xa0f4ae3c,0xfe35a33f)
	ALTROM(282, 1, 2, 262144, ROMTYPE_ODD, 0xc9b738c1, 0x02781591,0x44cfe65d,0xc9182cc6,0x8fee513b,0x0390b89f)
	{ _T("KS ROM v3.1.4-2 (A4000)"), 3, 1, 46, 143, _T("A4000\0"), 524288, 283, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x1B84CB33, 0xAAB44CD6, 0x51E6B6F8, 0x1A3EFFD8, 0xE0BA6B37, 0xAB322F32 },
	ALTROM(283, 1, 1, 262144, ROMTYPE_EVEN, 0x5cc345ca, 0x61b72a19,0x9da0299f,0x67ff551a,0x0c6e7efa,0xd3161206)
	ALTROM(283, 1, 2, 262144, ROMTYPE_ODD, 0xd461846b, 0x7d34a763,0xcf41ec41,0x2013e371,0x245071ab,0x84942998)
	{ _T("KS ROM v3.1.4-2 (A4000T)"), 3, 1, 46, 143, _T("A4000T\0"), 524288, 284, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xd6d0ef3e, 0xcd73aefe,0x9cbfc258,0xe7966cd1,0x4a7b2f46,0x47c9ba45 },
	ALTROM(284, 1, 1, 262144, ROMTYPE_EVEN, 0x5e59e0ae, 0x6f6375f4,0xf455bfd8,0x534c9861,0x269c3599,0x0391d3a9)
	ALTROM(284, 1, 2, 262144, ROMTYPE_ODD, 0x7819e09e, 0xf77b1f37,0x39c4f0ae,0x9019c3cc,0x6f3abc1c,0x8732d5cf)
	{ _T("KS ROM v3.1.4-2 (A500)"), 3, 1, 46, 143, _T("A500\0"), 524288, 285, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x568F8786, 0xD81CD6F1, 0x31040895, 0x843D9DFA, 0x95A45BC9, 0x5EDD9704 },
	
	{ _T("KS ROM v3.2 (A1200)"), 3, 2, 47, 96, _T("A1200\0"), 524288, 286, 1, 0, ROMTYPE_KICK, 0, 0, NULL,
	 0xBD1FF75E, 0x5B298287, 0x6FEC2166, 0x673BE447, 0x64388126, 0x2C84090E },
	ALTROM(286, 1, 1, 262144, ROMTYPE_EVEN, 0x86e17951, 0x7dad5302,0x6ca140cc,0xee2ea462,0x1f45e449,0x032260c5)
	ALTROM(286, 1, 2, 262144, ROMTYPE_ODD, 0xb49c1f15, 0xce3fa1ee,0x4253ddcf,0x37e13b2c,0x4e1ae6d4,0x0161e823)
	{ _T("KS ROM v3.2 (A3000)"), 3, 2, 47, 96, _T("A3000\0"), 524288, 287, 2, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xf3af46cc, 0x7bc0e756, 0x22d7254e, 0x11ea708e, 0x5d149007, 0x866c93ab },
	ALTROM(287, 1, 1, 262144, ROMTYPE_EVEN, 0x707cbe15, 0x31f2bef9,0xf63ca78c,0x71305201,0xd18a8eb6,0xd8428d06)
	ALTROM(287, 1, 2, 262144, ROMTYPE_ODD, 0x552a2633, 0x3e7bb0eb,0x875c4604,0x9afef204,0xcd47ead1,0x3a613fbc)
	{ _T("KS ROM v3.2 (A4000)"), 3, 2, 47, 96, _T("A4000\0"), 524288, 288, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x9BB8FC93, 0x37A8AA0B, 0x83782D75, 0xCE0B4A80, 0x631FF345, 0x9E91DC63 },
	ALTROM(288, 1, 1, 262144, ROMTYPE_EVEN, 0x9d23df57, 0x3890560b,0x4d838293,0xb853c347,0x39d6efe2,0xe94eef40)
	ALTROM(288, 1, 2, 262144, ROMTYPE_ODD, 0x3dbce6ae, 0xe44a3659,0xca633bfa,0x19a225d1,0x260001db,0x394776aa)
	{ _T("KS ROM v3.2 (A4000T)"), 3, 2, 47, 96, _T("A4000T\0"), 524288, 289, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x9188A509, 0xEDE1748E, 0xB2CBB1E8, 0x6AC5BF7D, 0xC9B97246, 0xA4A54358 },
	ALTROM(289, 1, 1, 262144, ROMTYPE_EVEN, 0x5a37a67a, 0x84edf115,0x65c950d4,0x90ec31e8,0x9bf13510,0xbd25de24)
	ALTROM(289, 1, 2, 262144, ROMTYPE_ODD, 0x8f2ea96e, 0x04978080,0x225428f5,0x101dd510,0xab265715,0x181da194)
	{ _T("KS ROM v3.2 (A500/A600/A2000/A1000/CDTV)"), 3, 2, 47, 96, _T("A500\0"), 524288, 290, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x8173D7B6, 0xB88E364D, 0xAF23C9C9, 0x920E548B, 0x0D3D944E, 0x65B1031D },

	{ _T("KS ROM v3.2.1 (A1200)"), 3, 2, 47, 102, _T("A1200\0"), 524288, 291, 1, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x2B653371, 0x0984fc0d, 0xf07dc058, 0x5db0923d, 0x580629f7, 0x0fca420d },
	ALTROM(291, 1, 1, 262144, ROMTYPE_EVEN, 0x74159ab0, 0x7864da88,0x5fba3a51,0xf3f91479,0x13e241c2,0x0315eaf4)
	ALTROM(291, 1, 2, 262144, ROMTYPE_ODD, 0x273058a8, 0xdcff4b7e,0xd3ee440a,0x315de36a,0x7b9cadce,0xbca4fc60)
	{ _T("KS ROM v3.2.1 (A3000)"), 3, 2, 47, 102, _T("A3000\0"), 524288, 292, 2, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x0078F607, 0xeb93508f, 0x0bb0cde8, 0x1d88bf22, 0xd0504556, 0x5d66ef74 },
	ALTROM(292, 1, 1, 262144, ROMTYPE_EVEN, 0xf77dcf59, 0x39a1faef,0x1b6c8ae2,0xc15596f0,0x438dd3ad,0x6eca839d)
	ALTROM(292, 1, 2, 262144, ROMTYPE_ODD, 0x8c58d0e2, 0xb8b18bca,0x1b43eb73,0x6c26006a,0xff708a3b,0x25c6d6db)
	{ _T("KS ROM v3.2.1 (A4000)"), 3, 2, 47, 102, _T("A4000\0"), 524288, 293, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xF3CED3B8, 0x7db3c322, 0x6acc0bfe, 0x548c788c, 0xf1bc7c4c, 0x8774d66f },
	ALTROM(293, 1, 1, 262144, ROMTYPE_EVEN, 0x573f93d0, 0x8aca3a41,0x41a3fd90,0x1a354cb2,0x038439e7,0xe4317d76)
	ALTROM(293, 1, 2, 262144, ROMTYPE_ODD, 0xbcbcfacd, 0x0bb57c68,0xc7478833,0x3ef8740f,0xb1ce3b22,0x8076b1f1)
	{ _T("KS ROM v3.2.1 (A4000T)"), 3, 2, 47, 102, _T("A4000T\0"), 524288, 294, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xAF3452EC, 0xa75fcd34, 0x9680cede, 0xab06e496, 0xc6338394, 0xe81788d7 },
	ALTROM(294, 1, 1, 262144, ROMTYPE_EVEN, 0x686eed65, 0x07fe9982,0xc666f683,0x9d946634,0x77db0706,0x03512ad9)
	ALTROM(294, 1, 2, 262144, ROMTYPE_ODD, 0x6ad0c89d, 0xc1012f5e,0xf4505f19,0x02b8b41f,0xc2a22252,0xe4e5edc6)
	{ _T("KS ROM v3.2.1 (A500/A600/A2000/A1000/CDTV)"), 3, 2, 47, 102, _T("A500\0"), 524288, 295, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x4F078456, 0x8f64ada6, 0x8a7f128b, 0xa782e8dc, 0x9fa58334, 0x4171590a },

	{ _T("KS ROM v3.2.2 (A1200)"), 3, 2, 47, 111, _T("A1200\0"), 524288, 304, 1, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x5c40328a, 0xd9622547, 0xd84741b5, 0x2c547260, 0x7f9aca75, 0x565cbba3 },
	ALTROM(304, 1, 1, 262144, ROMTYPE_EVEN, 0x35269969, 0x05ed4e33,0x580cef50,0x1ef07a13,0x7e4f7aa1,0xaad654cf)
	ALTROM(304, 1, 2, 262144, ROMTYPE_ODD, 0xe1cdbeee, 0x475d2af5,0x7bbf40c1,0x8db9eb00,0x813cf29b,0x1989fef3)
	{ _T("KS ROM v3.2.2 (A3000)"), 3, 2, 47, 111, _T("A3000\0"), 524288, 305, 2, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x46335b57, 0x443d9836, 0x9aca3ba5, 0x1ab2d478, 0x9d14fa9a, 0x26379c0b },
	ALTROM(305, 1, 1, 262144, ROMTYPE_EVEN, 0xb4bb227d, 0xb0a06998,0xb611ed8a,0xc73b5ecd,0x9a44bd93,0x529e4d30)
	ALTROM(305, 1, 2, 262144, ROMTYPE_ODD, 0x8b3cd4d6, 0xbb9f5b20,0x095de7c0,0xb3f93234,0x61e869fc,0x4b052fa8)
	{ _T("KS ROM v3.2.2 (A4000)"), 3, 2, 47, 111, _T("A4000\0"), 524288, 306, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x4bea9798, 0xa3207bd5, 0xb5a3ca62, 0x9010f315, 0x9ac79304, 0x0fa813ef },
	ALTROM(306, 1, 1, 262144, ROMTYPE_EVEN, 0x4eea180a, 0xd5306cba,0x4a5458cc,0x7714828b,0x65fed7bf,0x397ab6d7)
	ALTROM(306, 1, 2, 262144, ROMTYPE_ODD, 0x2cedff92, 0xafe9bde2,0xbede61db,0x981d89f1,0x837efb86,0xb1539bce)
	{ _T("KS ROM v3.2.2 (A4000T)"), 3, 2, 47, 111, _T("A4000T\0"), 524288, 307, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x36bbcd8a, 0x8e3fff26, 0x75cc1b97, 0xb4f072b6, 0x3fd4de70, 0x93f7c627 },
	ALTROM(307, 1, 1, 262144, ROMTYPE_EVEN, 0x16703ae7, 0x18c09abf,0x0f5bc5f8,0x16ead687,0xe3e2037d,0x63655d82)
	ALTROM(307, 1, 2, 262144, ROMTYPE_ODD, 0xd7b72128, 0xdda6b034,0x0fe290df,0x9b6ae377,0x5ebad2b2,0x8baa158d)
	{ _T("KS ROM v3.2.2 (A500/A600/A2000/A1000/CDTV)"), 3, 2, 47, 111, _T("A500\0"), 524288, 308, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xe4458462, 0x7d5ebe68, 0x6b69d59a ,0x863cc77a, 0x36b2cd60, 0x359a9ed2 },

	{ _T("KS ROM v3.2.3 (A1200)"), 3, 2, 47, 115, _T("A1200\0"), 524288, 333, 1, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xB18D3B67, 0x3f48ef0e, 0xca607855, 0xd7872796, 0xba886d78, 0x89451fad },
	{ _T("KS ROM v3.2.3 (A3000)"), 3, 2, 47, 115, _T("A3000\0"), 524288, 334, 2, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x74C0B23F, 0x76222baa, 0x6d5654db, 0xba4a769b, 0xb86c1f39, 0x322d1c1c },
	{ _T("KS ROM v3.2.3 (A4000)"), 3, 2, 47, 115, _T("A4000\0"), 524288, 335, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xB6A4698E, 0x81902f41, 0xcbf6fc6b, 0x7d18c691, 0xa4ada624, 0x5d174bde },
	{ _T("KS ROM v3.2.3 (A4000T)"), 3, 2, 47, 115, _T("A4000T\0"), 524288, 336, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x588A5E6D, 0x8eeb6c2b, 0x282e589b, 0xd1589ebb, 0xa3a78a41, 0x722499ec },
	{ _T("KS ROM v3.2.3 (A500/A600/A2000/A1000/CDTV)"), 3, 2, 47, 115, _T("A500\0"), 524288, 337, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0xE1F50B0B, 0xa9d51491, 0xd4b13566, 0x73621b61, 0xf789aed9, 0x79bd01be },

	{ _T("KS ROM v3.2 (Walker)"), 3, 2, 43, 1, _T("WALKER\0"), 524288, 296, 2, 1, ROMTYPE_KICK, 0, 0, NULL,
	0x261339f8, 0x7A9095F1, 0x107966F9, 0x0267DC4C, 0xB3C1972E, 0xFB4B78A8, NULL, NULL, 4 },
	{ _T("Casablanca 74095 - 00 717 - 02"), 3, 1, 0, 0, _T("CASABLANCA\0"), 524288 * 2, 231, 2 | 4, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x2ec384e3,0x47f9ee6d, 0x0f8ac5a6,0x5c6eddc3,0x0bcd47c8,0x574d8725, NULL, NULL, 4 },
	ALTROMPN(231, 1, 1, 524288, ROMTYPE_EVEN, _T("74095 00 717 02 01 U4"), 0x1bdcd18c, 0xabc7b734,0x1f8df24d,0xd4f1d062,0xfc0f7680,0x4d1053b9)
	ALTROMPN(231, 1, 2, 524288, ROMTYPE_ODD , _T("74095 00 717 02 02 U5"), 0x6ccb0431, 0xa2a43444,0xbeda38be,0x1fa5cabe,0x75fc4def,0x063bcd7a)
	{ _T("DraCo Boot ROM v1.3"), 1, 3, 1, 3, _T("DRACO\0"), 131072, 234, 2 | 4, 0, ROMTYPE_CB_DRACO, 0, 0, NULL,
	0x0e9c5899,0x82151324,0x01207554,0x60c8a068,0x4793ec18,0x3f744d74, NULL, NULL, 4 },
	{ _T("DraCo Boot ROM v1.5"), 1, 5, 1, 5, _T("DRACO\0"), 131072, 311, 2 | 4, 0, ROMTYPE_CB_DRACO, 0, 0, NULL,
	0x7b4cdd4a,0x4d383adb,0x85c681a3,0xb625dcda,0x7a229a17,0x6af4d161, NULL, NULL, 4 },

	{ _T("CD32 KS ROM v3.1"), 3, 1, 40, 60, _T("CD32\0"), 524288, 18, 1, 0, ROMTYPE_KICKCD32, 0, 0, NULL,
	0x1e62d4a5, 0x3525BE88,0x87F79B59,0x29E017B4,0x2380A79E,0xDFEE542D, NULL, NULL, 1 },
	{ _T("CD32 extended ROM"), 3, 1, 40, 60, _T("CD32\0"), 524288, 19, 1, 0, ROMTYPE_EXTCD32, 0, 0, NULL,
	0x87746be2, 0x5BEF3D62,0x8CE59CC0,0x2A66E6E4,0xAE0DA48F,0x60E78F7F, NULL, NULL, 1 },

	/* plain CD32 rom */
	{ _T("CD32 ROM (KS + extended)"), 3, 1, 40, 60, _T("CD32\0"), 2 * 524288, 64, 1, 0, ROMTYPE_CD32 | ROMTYPE_KICKCD32 | ROMTYPE_EXTCD32, 0, 0, NULL,
	0xf5d4f3c8, 0x9fa14825,0xc40a2475,0xa2eba5cf,0x325bd483,0xc447e7c1, NULL, NULL, 1 },
	/* real CD32 rom dump 391640-03 */
	ALTROMPN(64, 1, 1, 2 * 524288, ROMTYPE_CD32 | ROMTYPE_KICKCD32 | ROMTYPE_EXTCD32, _T("391640-03"), 0xa4fbc94a, 0x816ce6c5,0x07787585,0x0c7d4345,0x2230a9ba,0x3a2902db )

	{ _T("CD32 Full Motion Video Cartridge ROM"), 3, 1, 40, 30, _T("CD32FMV\0"), 262144, 23, 1, 0, ROMTYPE_CD32CART, 0, 0, NULL,
	0xc35c37bf, 0x03ca81c7,0xa7b259cf,0x64bc9582,0x863eca0f,0x6529f435, NULL, NULL, 3 },
	{ _T("CD32 Full Motion Video Cartridge ROM"), 3, 1, 40, 22, _T("CD32FMV\0"), 262144, 74, 1, 0, ROMTYPE_CD32CART, 0, 0, _T("391777-01"),
	0xf11158eb, 0x94e469a7,0x6030dcb2,0x99ebc752,0x0aaeef9d,0xb54284cf, NULL, NULL, 3 },

	{ _T("CDTV extended ROM v1.0"), 1, 0, 1, 0, _T("CDTV\0"), 262144, 20, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
	0x42baa124, 0x7BA40FFA,0x17E500ED,0x9FED041F,0x3424BD81,0xD9C907BE },
	ALTROMPN(20, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("252606-01"), 0x791cb14b,0x277a1778,0x92449635,0x3ffe56be,0x68063d2a,0x334360e4)
	ALTROMPN(20, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("252607-01"), 0xaccbbc2e,0x41b06d16,0x79c6e693,0x3c3378b7,0x626025f7,0x641ebc5c)
	{ _T("CDTV extended ROM v2.7"), 2, 7, 2, 7, _T("CDTV\0"), 262144, 22, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
	0xceae68d2, 0x5BC114BB,0xA29F60A6,0x14A31174,0x5B3E2464,0xBFA06846 },
	ALTROM(22, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x36d73cb8,0x9574e546,0x4b390697,0xf28f9a43,0x4e604e5e,0xf5e5490a)
	ALTROM(22, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x6e84dce7,0x01a0679e,0x895a1a0f,0x559c7253,0xf539606b,0xd447b54f)
	{ _T("CDTV/A570 extended ROM v2.30"), 2, 30, 2, 30, _T("CDTV\0"), 262144, 21, 0, 0, ROMTYPE_EXTCDTV, 0, 0, _T("391298-01"),
	0x30b54232, 0xED7E461D,0x1FFF3CDA,0x321631AE,0x42B80E3C,0xD4FA5EBB },
	ALTROM(21, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x48e4d74f,0x54946054,0x2269e410,0x36018402,0xe1f6b855,0xfd89092b)
	ALTROM(21, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x8a54f362,0x03df800f,0x032046fd,0x892f6e7e,0xec08b76d,0x33981e8c)
	{ _T("CDTV extended ROM v47.1"), 3, 2, 47, 96, _T("CDTV\0"), 262144, 297, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
	 0xAB6274E7, 0xCFC16F8E, 0x930BADCB, 0x9C3E7F88, 0x9A57D645, 0x571FA86A },
	ALTROM(297, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x3db9efdc, 0x7b3fe991,0x974e7d3c,0x85d92566,0xdd3c8d75,0x4b4b4b33)
	ALTROM(297, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, 0x50d15c4d, 0x4604dffa,0xcbe415d8,0xb41e60d6,0x951d78a8,0x9a5b2e7c)

	{ _T("CDTV-CR extended ROM v3.32"), 3, 32, 3, 32, _T("CDTVCR\0"), 262144, 107, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
	0x581a85cf, 0xd6b8d3f2,0x854eba9b,0x2d514579,0x9529e8b3,0x3b85e0b4 },
	{ _T("CDTV-CR extended ROM v3.44"), 3, 44, 3, 44, _T("CDTVCR\0"), 262144, 108, 0, 0, ROMTYPE_EXTCDTV, 0, 0, NULL,
	0x0b7bd64f, 0x3b160c5a,0xbe79f10a,0xe6924332,0x8004bb9e,0x3162b648 },

	{ _T("A1000 bootstrap ROM"), 0, 0, 0, 0, _T("A1000\0"), 65536, 24, 0, 0, ROMTYPE_KICK, 0, 0, NULL,
	0x0b1ad2d0, 0xBA93B8B8,0x5CA0D83A,0x68225CC3,0x3B95050D,0x72D2FDD7 },
	ALTROM(24, 1, 1, 8192,           0, 0x62f11c04, 0xC87F9FAD,0xA4EE4E69,0xF3CCA0C3,0x6193BE82,0x2B9F5FE6)
	ALTROMPN(24, 2, 1, 4096, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("252179-01"), 0x42553bc4,0x8855a97f,0x7a44e3f6,0x2d1c88d9,0x38fee1f4,0xc606af5b)
	ALTROMPN(24, 2, 2, 4096, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("252180-01"), 0x8e5b9a37,0xd10f1564,0xb99f5ffe,0x108fa042,0x362e877f,0x569de2c3)

	{ _T("The Diagnostic 2.0 (Logica)"), 2, 0, 2, 0, _T("LOGICA\0"), 524288, 72, 0, 0, ROMTYPE_KICK | ROMTYPE_SPECIALKICK, 0, 0, NULL,
	0x8484f426, 0xba10d161,0x66b2e2d6,0x177c979c,0x99edf846,0x2b21651e, NULL, NULL, 5 },

	{ _T("Freezer: Action Replay Mk I v1.00"), 1, 0, 1, 0, _T("AR\0"), 65536, 52, 0, 0, ROMTYPE_AR, 0, 1, NULL,
	0x2d921771, 0x1EAD9DDA,0x2DAD2914,0x6441F5EF,0x72183750,0x22E01248, NULL, NULL, 1 },
	ALTROM(52, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x82d6eb87, 0x7c9bac11,0x28666017,0xeee6f019,0x63fb3890,0x7fbea355)
	ALTROM(52, 1, 2, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x40ae490c, 0x81d8e432,0x01b73fd9,0x2e204ebd,0x68af8602,0xb62ce397)
	{ _T("Freezer: Action Replay Mk I v1.50"), 1, 50, 1, 50, _T("AR\0"), 65536, 25, 0, 0, ROMTYPE_AR, 0, 1, NULL,
	0xf82c4258, 0x843B433B,0x2C56640E,0x045D5FDC,0x854DC6B1,0xA4964E7C, NULL, NULL, 1 },
	ALTROM(25, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x7fbd6de2, 0xb5f71a5c,0x09d65ecc,0xa8a3bc93,0x93558461,0xca190228)
	ALTROM(25, 1, 2, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x43018069, 0xad8ff242,0xb2cbf125,0x1fc53a73,0x581cf57a,0xb69cee00)
	{ _T("Freezer: Action Replay Mk II v2.05"), 2, 5, 2, 5, _T("AR\0"), 131072, 26, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
	0x1287301f, 0xF6601DE8,0x888F0050,0x72BF562B,0x9F533BBC,0xAF1B0074, NULL, NULL, 1 },
	{ _T("Freezer: Action Replay Mk II v2.12"), 2, 12, 2, 12, _T("AR\0"), 131072, 27, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
	0x804d0361, 0x3194A07A,0x0A82D8B5,0xF2B6AEFA,0x3CA581D6,0x8BA8762B, NULL, NULL, 1 },
	{ _T("Freezer: Action Replay Mk II v2.14"), 2, 14, 2, 14, _T("AR\0"), 131072, 28, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
	0x49650e4f, 0x255D6DF6,0x3A4EAB0A,0x838EB1A1,0x6A267B09,0x59DFF634, NULL, NULL, 1 },
	{ _T("Freezer: Action Replay Mk III v3.09"), 3, 9, 3, 9, _T("AR\0"), 262144, 29, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
	0x0ed9b5aa, 0x0FF3170A,0xBBF0CA64,0xC9DD93D6,0xEC0C7A01,0xB5436824, NULL, NULL, 1 },
	ALTROM(29, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x2b84519f, 0x7841873b,0xf009d834,0x1dfa2794,0xb3751bac,0xf86adcc8)
	ALTROM(29, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, 0x1d35bd56, 0x6464be16,0x26b51949,0x9e76e4e3,0x409e8016,0x515d48b6)
	{ _T("Freezer: Action Replay Mk III v3.17"), 3, 17, 3, 17, _T("AR\0"), 262144, 30, 0, 0, ROMTYPE_AR2, 0, 1, NULL,
	0xc8a16406, 0x5D4987C2,0xE3FFEA8B,0x1B02E314,0x30EF190F,0x2DB76542, NULL, NULL, 1 },
	ALTROM(30, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x5fb69a10, 0x2ce641d1,0xe2e25476,0x9be7d1ba,0x41aace07,0x9cb04e27)
	ALTROM(30, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, 0xf767d072, 0xa7431d22,0xbfdb746a,0x8bb6073c,0x9edf7a2b,0x65c6d307)
	{ _T("Freezer: Action Replay 1200"), 0, 0, 0, 0, _T("AR\0"), 262144, 47, 0, 0, ROMTYPE_AR, 0, 1, NULL,
	0x8d760101, 0x0F6AB834,0x2810094A,0xC0642F62,0xBA42F78B,0xC0B07E6A, NULL, NULL, 1 },

	{ _T("Freezer: Action Cartridge Super IV Professional"), 0, 0, 0, 0, _T("SUPERIV\0"), 0, 62, 0, 0, ROMTYPE_SUPERIV, 0, 1, NULL,
	0xffffffff, 0, 0, 0, 0, 0, _T("SuperIV"), NULL, 2 },
	{ _T("Freezer: Action Cart. Super IV Pro (+ROM v4.3)"), 4, 3, 4, 3, _T("SUPERIV\0"), 170368, 60, 0, 0, ROMTYPE_SUPERIV, 0, 1, NULL,
	0xe668a0be, 0x633A6E65,0xA93580B8,0xDDB0BE9C,0x9A64D4A1,0x7D4B4801, NULL, NULL, 2 },
	{ _T("Freezer: X-Power Professional 500 v1.2"), 1, 2, 1, 2, _T("XPOWER\0"), 131072, 65, 0, 0, ROMTYPE_XPOWER, 0, 1, NULL,
	0x9e70c231, 0xa2977a1c,0x41a8ca7d,0x4af4a168,0x726da542,0x179d5963, NULL, NULL, 2 },
	ALTROM(65, 1, 1, 65536, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xf98742e4,0xe8e683ba,0xd8b38d1f,0x79f3ad83,0xa9e67c6f,0xa91dc96c)
	ALTROM(65, 1, 2, 65536, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xdfb9984b,0x8d6bdd49,0x469ec8e2,0x0143fbb3,0x72e92500,0x99f07910)
	{ _T("Freezer: X-Power Professional 500 v1.3"), 1, 3, 1, 3, _T("XPOWER\0"), 131072, 68, 0, 0, ROMTYPE_XPOWER, 0, 1, NULL,
	0x31e057f0, 0x84650266,0x465d1859,0x7fd71dee,0x00775930,0xb7e450ee, NULL, NULL, 2 },
	ALTROM(68, 1, 1, 65536, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x0b2ce0c7,0x45ad5456,0x89192404,0x956f47ce,0xf66a5274,0x57ace33b)
	ALTROM(68, 1, 2, 65536, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x34580c35,0x8ad42566,0x7364f238,0x978f4381,0x08f8d5ec,0x470e72ea)
	{ _T("Freezer: Nordic Power v1.5"), 1, 5, 1, 5, _T("NPOWER\0"), 65536, 69, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL,
	0x83b4b21c, 0xc56ced25,0x506a5aab,0x3fa13813,0x4fc9e5ae,0x0f9d3709, NULL, NULL, 2 },
	ALTROM(69, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xdd207174,0xae67652d,0x64f5db20,0x0f4b2110,0xee59567f,0xfbd90a1b)
	ALTROM(69, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x8f93d85d,0x73c62d21,0x40c0c092,0x6315b702,0xdd5d0f05,0x3dad7fab)
	{ _T("Freezer: Nordic Power v2.0"), 2, 0, 2, 0, _T("NPOWER\0"), 65536, 67, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL,
	0xa4db2906, 0x0aec68f7,0x25470c89,0x6b699ff4,0x6623dec5,0xc777466e, NULL, NULL, 2 },
	ALTROM(67, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xb21be46c,0x50dc607c,0xce976bbd,0x3841eaf0,0x591ddc7e,0xa1939ad2)
	ALTROM(67, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x96057aed,0xdd9209e2,0x1d5edfc1,0xcdb52abe,0x93de0f35,0xc43da696)
	{ _T("Freezer: Nordic Power v3.0"), 3, 0, 3, 0, _T("NPOWER\0"), 65536, 70, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL,
	0x72850aef, 0x59c91d1f,0xa8f118f9,0x0bdba05a,0x9ae788d7,0x7a6cc7c9, NULL, NULL, 2 },
	ALTROM(70, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xf3330e1f,0x3a597db2,0xb7d11b6c,0xb8e13496,0xc215f223,0x88c4ca3c)
	ALTROM(70, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0xee58e0f9,0x4148f4cb,0xb42cec33,0x8ca144de,0xd4f54118,0xe0f185dd)
	{ _T("Freezer: Nordic Power v3.2"), 3, 2, 3, 2, _T("NPOWER\0"), 65536, 115, 0, 0, ROMTYPE_NORDIC, 0, 1, NULL,
	0x46158b6e, 0xd8c3f5af,0x5f109c61,0x5f6acb38,0x68fe6c06,0x580041b5, NULL, NULL, 2 },
	ALTROM(115, 1, 1, 32768, ROMTYPE_EVEN|ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x4bfc71de,0x51914de0,0xdc0f055a,0x29ca188d,0xa7f61914,0xfdecbd07)
	ALTROM(115, 1, 2, 32768, ROMTYPE_ODD |ROMTYPE_SCRAMBLED|ROMTYPE_8BIT, 0x923ec443,0x9f1e5334,0xaa620745,0xf4d0c50e,0x8736543b,0x6d4366c5)
	{ _T("Freezer: Pro Access v2.17"), 2, 17, 2, 17, _T("PROACCESS\0"), 65536, 116, 0, 0, ROMTYPE_AR, 0, 1, NULL,
	0xc4c265cd, 0x6a5c0d99,0x69a624dc,0x1b437aec,0x5dbcd4c7,0x2ce9064a, NULL, NULL, 2 },
	ALTROM(116, 1, 1, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, 0x1909f7e9, 0x5abe9b9d,0xaae328c8,0x134e2b62,0x7b33b698,0xe342afc2)
	ALTROM(116, 1, 2, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, 0xa3927c72, 0x7adc9352,0x2d112ae9,0x23b9a70d,0x951b1e7a,0xba800ea6)

	{ _T("Freezer: HRTMon v2.37 (built-in)"), 0, 0, 0, 0, _T("HRTMON\0"), 0, 63, 0, 0, ROMTYPE_HRTMON, 0, 1, NULL,
	0xffffffff, 0, 0, 0, 0, 0, _T("HRTMon"), NULL, 2 },

	{ _T("A2090A"), 0, 0, 0, 0, _T("A2090A\0"), 16384, 122, 0, 0, ROMTYPE_A2090, 0, 0, NULL,
	0x73fe45a7, 0x77ce9091,0x4be5a3bf,0x6f26b343,0x062b5bd8,0xc63c3754 },
	ALTROMPN(122, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("315097-01"), 0x150b116c,0x8011d873,0x3be53db0,0x79dfe319,0x7ffb8634,0x1baa6dbd)
	ALTROMPN(122, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("315098-01"), 0xbe422e3b,0x64ad1646,0x030db10f,0x54f13f64,0x7d449e4d,0x17f9ab5c)
	{ _T("A2090A Combitec Turbo"), 0, 0, 0, 0, _T("A2090A\0"), 32768, 212, 0, 0, ROMTYPE_A2090, 0, 0, NULL,
	0x6a0190cd, 0xb2aac2cf,0xbb0a5e13,0x969cc64b,0x747a7f3c,0x71c33932 },
	ALTROMPN(212, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xaa75cb54,0x65181fca,0x5d9b9129,0x6eaf47c6,0x9e389375,0x26b48e50)
	ALTROMPN(212, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x4b87249c,0xa4908b21,0x524b5bf2,0x5a5249aa,0x6a5b7dfb,0x19aad133)
	{ _T("A2090B Combitec"), 0, 0, 0, 0, _T("A2090B\0"), 32768, 213, 0, 0, ROMTYPE_A2090B, 0, 0, NULL,
	0xdc1d45a9, 0x3e99c413,0x665826a6,0x647e9c7a,0x9354a0c2,0x908f4593 },
	ALTROMPN(213, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x48f4ab56,0x0165bac6,0x8caa0fce,0xd9d037bd,0x7f910124,0x79101632)
	ALTROMPN(213, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x77a66021,0x48fbe33f,0xb4b98838,0x64b4c0f3,0x81e56c11,0xf8673694)
	{ _T("A2090B Combitec Turbo"), 0, 0, 0, 0, _T("A2090B\0"), 32768, 214, 0, 0, ROMTYPE_A2090B, 0, 0, NULL,
	0x5aa840fb, 0x497da06b,0xeacbda16,0xbbb60054,0x3ade47b9,0x1453e6d4 },
	ALTROMPN(214, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xe5c3590b,0xc3fbd7d1,0x89ab29ef,0xd01f1fd8,0x61330f39,0xf778eea3)
	ALTROMPN(214, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x97e44570,0x6cfcc04c,0xc1ceb0dd,0xdc3caf18,0x56ba8677,0xa2a53756)
	{ _T("A2090B MacroSystem"), 0, 0, 0, 0, _T("A2090B\0"), 32768, 217, 0, 0, ROMTYPE_A2090B, 0, 0, NULL,
	0xdf1744ed, 0x0f16f5b0,0x482ab3aa,0xba867945,0x6a9d050d,0x57c42682 },
	ALTROMPN(217, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xe4df7cb8,0xd6795d9c,0x5892f41b,0x256aff7f,0x56faacb3,0x1f024a3b)
	ALTROMPN(217, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0924e479,0x6f2642c8,0xa977cf12,0x418fffff,0x3bafe846,0xfde1f1e5)

	{ _T("A590/A2091 v4.4"), 4, 4, 4, 4, _T("A590\0A2091\0"), 16384, 268, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
	0x9fd5c76b, 0x0e4190ed,0x156b65cf,0x57aba1e7,0x8513355c,0xf5e0b366 },
	ALTROMPN(268, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390389-01"), 0x0dbc6d28,0x79378b86,0x93b334fe,0x12ee8d39,0x3235e3b5,0x71bfb55b)
	ALTROMPN(268, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390388-01"), 0x4d1b9757,0x43ff80f7,0xc5770566,0x012d8711,0x8552842b,0xb01010f5)
	{ _T("A590/A2091 v4.6"), 4, 6, 4, 6, _T("A590\0A2091\0"), 16384, 202, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
	0x00a38212, 0xa029a4de,0x56e5539d,0x0ee00588,0xc2634f13,0x29f06269 },
	ALTROMPN(202, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390389-02"), 0x26013266,0x60dedda8,0xd406b276,0x2ad1504a,0x88a4d6e2,0x9c0fb10d)
	ALTROMPN(202, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390388-02"), 0x6c9cb089,0xbd8c6bb7,0x9ae91a4d,0x1b9ee76f,0xdd11aaf9,0x7ca4358b)
	{ _T("A590/A2091 v5.92"), 5, 92, 5, 92, _T("A590\0A2091\0"), 16384, 215, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
	0x0d39b8d9, 0xf8bd7c20,0xf2d0e7a5,0xf344228c,0x94bc8841,0xcbf8e042 },
	ALTROMPN(215, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xf99e3934,0x1aa7f789,0xdb48ad0b,0x75f8bb6b,0x3e5532fb,0xf30f5766)
	ALTROMPN(215, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x8f9dd6f8,0x3a8a4639,0xa498bf9a,0x95cb11c4,0x5c13687e,0xfa714942)
	{ _T("A590/A2091 v6.0"), 6, 0, 6, 0, _T("A590\0A2091\0"), 16384, 53, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
	0x8396cf4e, 0x5E03BC61,0x8C862ABE,0x7BF79723,0xB4EEF4D2,0x1859A0F2 },
	ALTROMPN(53, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390389-03"), 0xb0b8cf24,0xfcf40175,0x05f4d441,0x814b45d5,0x59c19eab,0x43816b30)
	ALTROMPN(53, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390388-03"), 0x2e77bbff,0x8a098845,0x068f32cf,0xa4d34a27,0x8cd290f6,0x1d35a52c)
	{ _T("A590/A2091 v6.1"), 6, 1, 6, 1, _T("A590\0A2091\0"), 16384, 206, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
	0xaccf6452, 0xf56061ab,0x37768281,0x94d89729,0x802ee7ae,0x1de9df90 },
	ALTROMPN(206, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390722-01"), 0xc460cfdb,0x0de457da,0xec3b84f7,0x5e8fb344,0xdefe24ce,0x56cda3e0)
	ALTROMPN(206, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-01"), 0x00dbf615,0x503940d0,0x4fb3b49e,0xaa61100f,0xd3a48701,0x8b35e25a)
	{ _T("A590/A2091 v6.6"), 6, 6, 6, 6, _T("A590\0A2091\0"), 16384, 54, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
	0x33e00a7a, 0x739BB828,0xE874F064,0x9360F59D,0x26B5ED3F,0xBC99BB66 },
	ALTROMPN(54, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390722-02"), 0xe536bbb2,0xfd7f8a6d,0xa18c1b02,0xd07eb990,0xc2467a24,0x183ede12)
	ALTROMPN(54, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-02"), 0xc0871d25,0xe155f18a,0xbb90cf82,0x0589c15e,0x70559d3b,0x6b391af8)
	{ _T("A590/A2091 v7.0"), 7, 0, 7, 0, _T("A590\0A2091\0"), 16384, 55, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
	0x714a97a2, 0xE50F01BA,0xF2899892,0x85547863,0x72A82C33,0x3C91276E },
	ALTROMPN(55, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390722-03"), 0xa9ccffed,0x149f5bd5,0x2e2d2990,0x4e3de483,0xb9ad7724,0x48e9278e)
	ALTROMPN(55, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390721-03"), 0x2942747a,0xdbd7648e,0x79c75333,0x7ff3e4f4,0x91de224b,0xf05e6bb6)

	{ _T("A590/A2091 Guru ROM v6.14"), 6, 14, 6, 14, _T("A590\0A2091\0"), 32768, 56, 0, 0, ROMTYPE_A2091, 0, 0, NULL,
	0x04e52f93, 0x6DA21B6F,0x5E8F8837,0xD64507CD,0x8A4D5CDC,0xAC4F426B },

	{ _T("A4091 v40.4"), 40, 4, 40, 4, _T("A4091\0"), 32768, 240, 0, 0, ROMTYPE_A4091, 0, 0, NULL,
	0x9ba7e7dc, 0x18985b7e,0xc95239da,0x21a242a4,0xfc42f134,0x96434534 },
	{ _T("A4091 v40.9"), 40, 9, 40, 9, _T("A4091\0"), 32768, 57, 0, 0, ROMTYPE_A4091, 0, 0, NULL,
	0x7e12a120, 0xa411d572,0x6801dc44,0x3d41428f,0x382ae3d5,0x6f44ef27 },
	{ _T("A4091 v40.13"), 40, 13, 40, 13, _T("A4091\0"), 32768, 58, 0, 0, ROMTYPE_A4091, 0, 0, _T("391592-02"),
	0x54cb9e85, 0x3CE66919,0xF6FD6797,0x4923A12D,0x91B730F1,0xFFB4A7BA },

	{ _T("SupraDrive AMAB6"), 3, 8, 3, 8, _T("SUPRA\0"), 8192, 121, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB6"),
	0x7ce693c2, 0x2f220f99,0xf4c61a81,0x915f04cc,0x8464d8d2,0xa15c65bc },
	{ _T("SupraDrive AMAB5"), 3, 0, 3, 0, _T("SUPRA\0"), 8192, 134, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB5"),
	0xfac9a231, 0xa52290fb,0x56873c55,0x667c608e,0x8fe330ed,0xdefa1669 },
	{ _T("SupraDrive AMAB4"), 0, 0, 0, 0, _T("SUPRA\0"), 8192, 135, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB4"),
	0xde7f3f1c, 0xc0acbfc8,0x6641a6c1,0x024870cc,0x519f8c4c,0xbdfe8c64 },
	{ _T("SupraDrive AMAB3"), 0, 0, 0, 0, _T("SUPRA\0"), 8192, 136, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB3"),
	0x3ead39aa, 0x02fe79ee,0xef423098,0xec6add8c,0xb92f849f,0xc64bcd41 },
	{ _T("SupraDrive AMAB2"), 0, 0, 0, 0, _T("SUPRA\0"), 8192, 299, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("AMAB2"),
	0x297c99f3, 0x8e5e8ea9,0xa203c3ad,0x6dd35e57,0xb1b01f38,0x9b31edda },
	{ _T("SupraDrive 2000DMA (44-25B)"), 0, 0, 0, 0, _T("SUPRADMA\0"), 8192, 298, 0, 0, ROMTYPE_SUPRA, 0, 0, _T("44-25B"),
	0x0f040976, 0x9faa3201,0xd09e57bf,0xb0e95b45,0x4fff3b90,0xdf219105 },

	{ _T("Blizzard 1230-I/II"), 0, 0, 0, 0, _T("B1230MKII\0"), 32768, 163, 0, 0, ROMTYPE_CB_B1230MK2, 0, 0, NULL,
	0xf307cd34, 0xd2f0bfe5, 0x6e84e9f2, 0x2dc11583, 0x30702fd7, 0xd59584ee },
	{ _T("Blizzard 1230-III"), 0, 0, 0, 0, _T("B1230MKIII\0"), 32768, 162, 0, 0, ROMTYPE_CB_B1230MK3, 0, 0, NULL,
	0x8412a22c, 0x3a4c55f3, 0xdaf62084, 0xd947e418, 0x137db019, 0xf13efc7d },
	{ _T("Blizzard 1230-IV"), 0, 0, 0, 0, _T("B1230MKIV\0"), 32768, 89, 0, 0, ROMTYPE_CB_BLIZ1230, 0, 0, NULL,
	0x3078dbdc, 0x4d3e7fd0, 0xa1a4c3ae, 0xe17c5de3, 0xcbe1af03, 0x447aff92 },
	{ _T("Blizzard 1240/1260"), 0, 0, 0, 0, _T("B1240\0B1260\0"), 32768, 90, 0, 0, ROMTYPE_CB_BLIZ1260, 0, 0, NULL,
	0xf88ae0f1, 0xf69aca4b,0xb13e3389,0x04676f0c,0x8616f8db,0x074c313d },

	{ _T("Blizzard 2060 v7.25"), 7, 25, 7, 25, _T("B2060\0"), 65536, 237, 0, 0, ROMTYPE_CB_BLIZ2060, 0, 0, NULL,
	0x17c8dcbe, 0xa39a6d23, 0x2cb9a81b, 0x5f3694d3, 0x68873782, 0x5ad581bc },
	ALTROMPN(237, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xb97efdeb, 0xb615eaec, 0x4687c2de, 0x40b74b5f, 0xd6215e30, 0xe9f32187)
	ALTROMPN(237, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x2822156f, 0x46f520b0, 0x5a014b63, 0x207c5337, 0x3cd76fef, 0x994d7e37)
	{ _T("Blizzard 2060 v8.2"), 8, 2, 8, 2, _T("B2060\0"), 65536, 168, 0, 0, ROMTYPE_CB_BLIZ2060, 0, 0, NULL,
	0x2f42af81, 0x003577b8, 0x4e1f2e59, 0x3add6c9f, 0xfd65a7b4, 0x2abaa933 },
	ALTROMPN(168, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xb5892212, 0x7282a8ca, 0xf7ab194d, 0x16e1d05a, 0x582f0ebf, 0x1046b3d0)
	ALTROMPN(168, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x821a01c0, 0x6fd29f69, 0x28c5980e, 0x313b3b15, 0xb5d683ac, 0x209dd1bf)
	{ _T("Blizzard 2060 v8.5"), 8, 5, 8, 5, _T("B2060\0"), 65536, 92, 0, 0, ROMTYPE_CB_BLIZ2060, 0, 0, NULL,
	0xce270bc0, 0xe043c1aa, 0x3bb06e06, 0xd4dabff3, 0x0a8c6317, 0xabfef2bb },
	ALTROMPN(92, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xa6023f20, 0xdfb048d6, 0xbdc03587, 0x241e8121, 0x26aba603, 0xd69b0238)
	ALTROMPN(92, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x9635a9cd, 0x47578b27, 0xc4ba6e54, 0x891930dd, 0xcb4b6a45, 0x5d6b31b2)

	{ _T("Blizzard SCSI Kit III"), 1, 139, 1, 139, _T("BSCSIII\0"), 65536, 167, 0, 0, ROMTYPE_BLIZKIT3, 0, 0, NULL,
	0xfd2c772f, 0x1411c248, 0x72f7cb8d, 0xecbe4744, 0xf0b8d12a, 0x1aaaad44, NULL, NULL },
	{ _T("Blizzard SCSI Kit IV"), 8, 5, 8, 5, _T("BSCSIV\0"), 32768, 94, 0, 0, ROMTYPE_BLIZKIT4, 0, 0, NULL,
	0xf53a0fca, 0xefe17ca5,0x88c44a7f,0x0f8c62be,0x20f23278,0xcfe06727, NULL, _T("blizzard_scsi_kit_iv.rom") },
	{ _T("Fastlane"), 8, 5, 8, 5, _T("FASTLANE\0"), 32768, 102, 0, 0, ROMTYPE_FASTLANE, 0, 0, NULL,
	0x00447765, 0x2644e7cb,0xba5cc54e,0x880b4b42,0x49fd1dd1,0x2eb4a3bc, NULL, _T("fastlanez3.rom") },
	{ _T("Oktagon 2008"), 6, 12, 6, 12, _T("OKTAGON\0"), 32768, 103, 0, 0, ROMTYPE_OKTAGON, 0, 0, NULL,
	0xbb0d2f6a, 0x56c441fa,0x37d19339,0x3081b2e8,0xceae823b,0xc7e97e49, NULL, _T("oktagon2008.rom") },
	{ _T("Warp Engine"), 0, 0, 0, 0, _T("WARPENGINE\0"), 32768, 93, 0, 0, ROMTYPE_CB_WENGINE, 0, 0, NULL,
	0x4deb574a, 0x6e6c95ff,0xe8448391,0xd36c5b68,0xc9065cb0,0x702a7d27 },

	{ _T("TekMagic 2060 v1.0"), 1, 0, 1, 0, _T("TEKMAGIC\0TEKMAGIC2060\0"), 65536, 104, 0, 0, ROMTYPE_CB_TEKMAGIC, 0, 0, NULL,
	0x9e9781d5, 0xf65b60d1,0x4300c50f,0x2ed17cf4,0x4dcfdef9,0x16697bc9, NULL,  _T("tekmagic2060.rom") },
	ALTROMPN(104, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x888da4cf, 0x6ae85f3a, 0x65331ba4, 0xaaba67ae, 0x34763d70, 0x2bde0495)
	ALTROMPN(104, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaf1f47db, 0x28d5bed0, 0xbc517d46, 0x500e8159, 0x723e0b64, 0x4733c26a)
	{ _T("TekMagic 2040 v1.1"), 1, 1, 1, 1, _T("TEKMAGIC\0TEKMAGIC2040\0"), 65536, 303, 0, 0, ROMTYPE_CB_TEKMAGIC, 0, 0, NULL,
	0xff60cfe3, 0xea208934,0x5e2602cf,0xc715b2fc,0x50a392dd,0xd751823a, NULL,  _T("tekmagic2040.rom") },
	ALTROMPN(303, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xc19580de, 0x691b1119, 0x5163fd52, 0xb8a9025e, 0x3ac4311f, 0x7bc84013)
	ALTROMPN(303, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xbf3551fd, 0x4dc520fa, 0x7868e01b, 0xd6bfa3d6, 0x396f1e55 ,0x18d55372)
	{ _T("GVP T-Rex II v1.0"), 1, 0, 1, 0, _T("GVPTREXII\0"), 32768, 317, 0, 0, ROMTYPE_CB_TREXII, 0, 0, NULL,
	0xd908947a, 0x888b53f0,0xb7f064e5,0xf068279f,0x855dba0e,0x5a42249f, NULL, NULL },

	{ _T("Zeus 040"), 2, 98, 2, 98, _T("ZEUS040\0"), 16384, 225, 0, 0, ROMTYPE_CB_ZEUS040, 0, 0, NULL,
	0x2c609194, 0x9a91cf45,0x6816067a,0x943c18f1,0xbd30effe,0x482d4aaf, NULL, NULL },
	ALTROMPN(225, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xc0bea5dd, 0x1540a755, 0x36066da4, 0x8bcb3dd4, 0xf13f179b, 0x9439f379)
	ALTROMPN(225, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x7989684f, 0x9dc4d885, 0x242bf7eb, 0xe75a01b2, 0x483c9e3c, 0x8013896b)
	{ _T("CSA Magnum 040"), 0, 0, 0, 0, _T("MAGNUM040\0"), 65536, 226, 0, 0, ROMTYPE_CB_MAGNUM40, 0, 0, NULL,
	0xb94e805b, 0x4c1859ba,0x7ea2cedb,0xf5251bed,0xfbb76e6c,0x0617300e },
	{ _T("CSA Twelve Gauge"), 0, 0, 0, 0, _T("12GAUGE\0"), 32768, 241, 0, 0, ROMTYPE_CB_12GAUGE, 0, 0, NULL,
	0x2a74074d, 0xc1f29093,0x491339cd,0xdc81f994,0x0f0965df,0xa3a193f2 },
	{ _T("Hardital TQM"), 0, 0, 0, 0, _T("TQM\0"), 32768, 228, 0, 0, ROMTYPE_CB_TQM, 0, 0, NULL,
	0x3bc9b90c, 0x24fa6ab8, 0x5ca64ae6, 0x43851a85, 0xa473ff0c, 0x5a48f272, NULL, NULL },
	{ _T("MacroSystem Falcon 040 (No SCSI)"), 0, 0, 0, 0, _T("FALCON040\0"), 131072, 229, 0, 0, ROMTYPE_CB_FALCON40, 0, 0, NULL,
	0xa2ba67d1, 0x2015685f, 0xaadfbaf6, 0x8b19b07e, 0x5f4e888f, 0x738b99d7, NULL, NULL },
	{ _T("GVP A1230 Turbo+ Series II v5.0"), 5, 0, 5, 0, _T("A1230SII\0"), 16384, 230, 0, 0, ROMTYPE_CB_A1230S2, 0, 0, NULL,
	0x96bd351f, 0xb7648daf, 0x52d0732d, 0x897548f3, 0x29ebf624, 0x101474d5, NULL, NULL },
	{ _T("GVP A1230 Turbo+ Series II v5.3"), 5, 3, 5, 3, _T("A1230SII\0"), 16384, 312, 0, 0, ROMTYPE_CB_A1230S2, 0, 0, NULL,
	0x0a3bb4b1, 0xf870116f, 0x699ec800, 0x2a1b31bb, 0x0f412e27, 0xc5d01266, NULL, NULL },
	{ _T("GVP A1230 Turbo+"), 0, 0, 0, 0, _T("A1230SI\0"), 16384, 260, 0, 0, ROMTYPE_CB_A1230S1, 0, 0, NULL,
	0x3f0b8d7a, 0x258c6ee7, 0x5d8dfee5, 0x7871c5be, 0x79a83fa3, 0xca53a1a9, NULL, NULL },
	{ _T("Harms 3000 Professional"), 0, 0, 0, 00, _T("HARMS3000PRO\0"), 65536, 248, 0, 0, ROMTYPE_CB_HARMS3KP, 0, 0, NULL,
	0x80da32b5,0x0a3ded88,0x20a24238,0xd3e43baf,0x7163226c,0x861e2d88, NULL, NULL },
	ALTROMPN(248, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xc22c5ee5, 0xc211f305, 0xacb2ce10, 0x32b1b296, 0xc5780dde, 0x78dba814)
	ALTROMPN(248, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xe1062444, 0x7c0dd74f, 0x2bc0a94d, 0xd85aa85f, 0x771b8658, 0x697533cd)

	{ _T("A2620/A2630 -07"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 105, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-07/390283-07"),
	0x169d80e9, 0x41f518cb,0x41c1dc1f,0xcc636383,0x20676af5,0x4969010c, NULL, NULL },
	ALTROMPN(105, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-07"), 0xf2904058, 0x33695119, 0x5fdf5d56, 0x095a696b, 0x0ba2641d, 0x334845df)
	ALTROMPN(105, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-07"), 0xf697d458, 0x09fe260b, 0x03784e87, 0x3351dbec, 0x5146a455, 0x814383d1)
	{ _T("A2620/A2630 -06"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 106, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-06/390283-06"),
	0xeb31fd9e, 0x2d6a5c68,0x1040f98d,0x7e63ad08,0x90da9e83,0x2b5c704d, NULL, NULL },
	ALTROMPN(106, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-06"), 0xd6ae582c, 0x47b3dea3, 0x31db76e6, 0x1380a3d6, 0x9f191657, 0xdd1cd4b3)
	ALTROMPN(106, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-06"), 0xcd379634, 0x65e251e2, 0xf6961c8e, 0x33a86c3d, 0x01248f70, 0xa159823b)
	{ _T("A2620/A2630 -04"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 165, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-04/390283-04"),
	0xd4666ae9, 0x93cbd775, 0x42843f6d, 0x8234c271, 0xab860304, 0x06a1ae0a, NULL, NULL },
	ALTROMPN(165, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-04"), 0x28d5af1e, 0xc6a51a63, 0xca2a0833, 0xf32c4a59, 0x7d9d5b95, 0xcfa79a9e)
	ALTROMPN(165, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-04"), 0x325aaf5f, 0xe76b384b, 0x5740cc0e, 0x782ae887, 0xe921352b, 0x115b2489)
	{ _T("A2620/A2630 -03"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 216, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-03/390283-03"),
	0x4f771c97, 0xa6e2eec1, 0xc31a88d8, 0xda482834, 0x5f8f50fe, 0xa9151374, NULL, NULL },
	ALTROMPN(216, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-03"), 0x17030f12, 0x84219860, 0x2fb44696, 0x051e9f9e, 0xf9ec069f, 0xc59e763f)
	ALTROMPN(216, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-03"), 0x2e18f86a, 0x985ccc7f, 0x7dd38404, 0xf96cc712, 0x90c732cc, 0x9638c101)
	{ _T("A2620/A2630 -02"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 210, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-02/390283-03"),
	0xa846b93b, 0xc9a8d824,0x9a301da8,0xfadf2b45,0xfc62ecff,0xb7242267, NULL, NULL },
	ALTROMPN(210, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-02"), 0xe5c9fb3d, 0x69e68a1d, 0x8112771a, 0x358723e0, 0xa82cd57a, 0xd8c8865e)
	ALTROMPN(210, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-02"), 0x42c21bb4, 0x53874595, 0x79b20aa3, 0x57fa73ec, 0x66db863e, 0x456108a8)
	{ _T("A2620/A2630 -01"), 0, 0, 0, 0, _T("A2620\0A2630\0"), 65536, 164, 0, 0, ROMTYPE_CB_A26x0, 0, 0, _T("390282-01/390283-01"),
	0x6ee2ecdd, 0x4c82e3ba, 0x2d2dd1d3, 0x82f01098, 0xc26681b8, 0xff62f36d, NULL, NULL },
	ALTROMPN(164, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("390282-01"), 0xdf76493b, 0x331ede0a, 0x8ca995cc, 0x1917f592, 0x18718e5b, 0x3c7fac39)
	ALTROMPN(164, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("390283-01"), 0xd74187de, 0x681e4985, 0x4da64bf1, 0x6f2f99f7, 0x4b195f54, 0x0b8bd614)
	{ _T("DKB 1230/1240/Cobra"), 1, 23, 1, 23, _T("DKB\0"), 1460, 112, 0, 0, ROMTYPE_CB_DKB, 0, 0, NULL,
	0x15ac5257, 0xf0431d02,0xac0f83d3,0x45db18c0,0x23f0cefb,0x33d17217, NULL, NULL },
	{ _T("DKB 1230/1240/Cobra + Ferret v1.23"), 1, 23, 1, 23, _T("DKB\0"), 12060, 208, 0, 0, ROMTYPE_CB_DKB, 0, 0, NULL,
	0xda878913, 0xb62a68ef,0xb9378d74,0x0be17452,0x1ad07d2e,0xa461a313, NULL, NULL },
	{ _T("DKB Rapidfire/Spitfire v1.31"), 1, 31, 1, 31, _T("RAPIDFIRE\0"), 11284, 207, 0, 0, ROMTYPE_RAPIDFIRE, 0, 0, NULL,
	0x68725e50, 0xa66f8ef6,0x901e0e41,0xf8b72bba,0x12165788,0xa452cf01, NULL, NULL },
	{ _T("Fusion Forty"), 0, 0, 0, 0, _T("FUSIONFORTY\0"), 131072, 113, 0, 0, ROMTYPE_CB_FUSION, 0, 0, NULL,
	0x48fcb5fd, 0x15674dac,0x90b6d8db,0xdda3a175,0x997184c2,0xa423d733, NULL, NULL },
	ALTROMPN(113, 1, 1, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U28"), 0x434a21a8, 0x472c1623, 0x02babd00, 0x7c1a77ff, 0x40dd12ab, 0x39c97f82)
	ALTROMPN(113, 1, 2, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, _T("U27"), 0x38373cf6, 0xfe8aa931, 0xada6b6f3, 0x6b48ca3c, 0x9b86677d, 0xbee4da59)
	ALTROMPN(113, 1, 3, 32768, ROMTYPE_QUAD | ROMTYPE_EVEN | ROMTYPE_8BIT, _T("U25"), 0xc9e990d3, 0xb251ef73, 0x1374e796, 0xa87cbc7e, 0x9263320a, 0x28a71d2b)
	ALTROMPN(113, 1, 4, 32768, ROMTYPE_QUAD | ROMTYPE_ODD  | ROMTYPE_8BIT, _T("U26"), 0x2e117fe0, 0xbb2de2da, 0x6db4e92c, 0x636fefe6, 0x13a32699, 0xcea31011)
	{ _T("Apollo 1240/1260"), 5, 60, 5, 60, _T("APOLLO12XX\0"), 131072, 119, 0, 0, ROMTYPE_CB_APOLLO_12xx, 0, 0, NULL,
	0xcd009ad9, 0x1c3b4851,0xc5a221e3,0xa7ca24fc,0xc1df4a5b,0x9f2343ad },
	{ _T("Apollo 630"), 5, 61, 5, 61, _T("APOLLO630\0"), 16384, 313, 0, 0, ROMTYPE_CB_APOLLO_630, 0, 0, NULL,
	0x286cf453, 0xe0597cb6,0x5a6471b3,0xfd674e7b,0xc9e2423d,0x43e51ffc },
	{ _T("GVP A3001 Series I"), 3, 3, 3, 3, _T("A3001SI\0"), 8192, 114, 0, 0, ROMTYPE_CB_A3001S1, 0, 0, NULL,
	0xaaff7c65, 0x424cf3da,0xcc9da794,0x0ba74446,0x69dd1691,0x44ae87ee, NULL, NULL },
	{ _T("Kupke Golem 030"), 0, 0, 0, 0, _T("GOLEM030\0"), 8192, 126, 0, 0, ROMTYPE_CB_GOLEM030, 0, 0, NULL,
	0x05d473f4, 0x574ec567, 0xcc67e06f, 0x91dcecb9, 0x8c204399, 0x5fe2a09f, NULL, NULL },
	{ _T("DKB WildFire v1.0"), 1, 0, 1, 0, _T("WILDFIRE\0"), 18016, 318, 0, 0, ROMTYPE_CB_DBK_WF, 0, 0, NULL,
	0x08fc84f6, 0xec27aab5, 0x0cdd0db9, 0x6ddd9db3, 0xeff92183, 0xcbaf3f78, NULL, NULL },
	{ _T("DKB WildFire v1.1"), 1, 1, 1, 1, _T("WILDFIRE\0"), 18352, 143, 0, 0, ROMTYPE_CB_DBK_WF, 0, 0, NULL,
	0xb2dae8c4, 0xcdfe2d96, 0xe44d4f8d, 0x3833a5e8, 0xb6c832fd, 0xc7b341a9, NULL, NULL },
	{ _T("M-Tec E-Matrix 530"), 0, 0, 0, 0, _T("EMATRIX530\0"), 65536, 144, 0, 0, ROMTYPE_CB_EMATRIX, 0, 0, NULL,
	0x3942d827, 0x5aaf118f, 0x61fc3083, 0x1435b87c, 0x8bdab6a4, 0x59b4ee22, NULL, NULL },
	{ _T("Typhoon MK2"), 0, 0, 0, 0, _T("TYPHOON2\0"), 65536, 236, 0, 0, ROMTYPE_CB_TYPHOON2, 0, 0, NULL,
	0xf5edf7e2, 0xf62bab24, 0xeaa91a16, 0x07d838af, 0x7b5fef4d, 0x05c58edc, NULL, NULL },
	{ _T("SX32 Pro"), 0, 0, 0, 0, _T("SX32PRO\0"), 65536, 160, 0, 0, ROMTYPE_CB_SX32PRO, 0, 0, NULL,
	0xbfd68a88, 0x84a50880, 0x76917549, 0xadf33b16, 0x8a869adb, 0x9e5a6fac, NULL, NULL },
	{ _T("IVS Vector 4.14"), 4, 14, 4, 14, _T("VECTOR030\0"), 65536, 166, 0, 0, ROMTYPE_CB_VECTOR, 0, 0, NULL,
	0x3befa0c0, 0x4414673c, 0xa52f78a0, 0xae656824, 0xfd08b54f, 0xa1de237c, NULL, NULL },
	ALTROMPN(166, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xb64e3bbf, 0xd6f4fc81, 0x38325a78, 0x74ff1c15, 0x7c93f1a2, 0x444904ae)
	ALTROMPN(166, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x541b5988, 0x3546517b, 0x57cecd2f, 0x9fbfcd0c, 0xf26fdbbf, 0xfb009e3e)
	{ _T("QuikPak 4060 XP v2.1"), 2, 1, 2, 1, _T("QUIKPAK\0"), 32768, 239, 0, 0, ROMTYPE_CB_QUIKPAKXP, 0, 0, NULL,
	0x3a8eb518, 0x902dd0ba, 0x56c2afd0, 0xbb425bf5, 0x264fbc62, 0x90ad2c4e, NULL, NULL },
	{ _T("QuikPak 4060 XP v2.2"), 2, 2, 2, 2, _T("QUIKPAK\0"), 65536, 319, 0, 0, ROMTYPE_CB_QUIKPAKXP, 0, 0, NULL,
	0x47009144, 0x547fd232, 0xd774e872, 0x37a83d30, 0xeb06e3d6, 0xb88456c2, NULL, NULL },
	{ _T("QuikPak 4060"), 0, 0, 0, 0, _T("QUIKPAK\0"), 32768, 320, 0, 0, ROMTYPE_CB_QUIKPAK, 0, 0, NULL,
	0x2b12aa6d, 0x023cd8a5, 0x7f24a992, 0x12d64c93, 0x69da614a, 0x3f6d0932, NULL, NULL },

	{ _T("Preferred Technologies Nexus"), 1, 0, 1, 0, _T("PTNEXUS\0"), 8192, 139, 0, 0, ROMTYPE_PTNEXUS, 0, 0, NULL,
	0xf495879a, 0xa3bd0202, 0xe14aa5b6, 0x49d3ce88, 0x22975950, 0x6500dbc2, NULL, NULL },
	{ _T("ICD AdSCSI 2000 v1.6 (icddisk v1.0)"), 1, 6, 1, 6, _T("ADSCSI\0"), 32768, 133, 0, 0, ROMTYPE_ADSCSI, 0, 0, NULL,
	0x7dba3e1f, 0x1e05f284, 0xd59a1e5d, 0x4e4de44e, 0x6f075175, 0x625cd6c0, NULL, NULL },
	{ _T("ICD AdSCSI 2000 v2.01 (icddisk v32.1)"), 0, 0, 0, 0, _T("ADSCSI\0"), 32768, 309, 0, 0, ROMTYPE_ADSCSI, 0, 0, NULL,
	0x0860a46d, 0xf6bd0520, 0x06d50449, 0x4efd48da, 0xe6a58d7b, 0x774c9eef, NULL, NULL },
	{ _T("ICD AdSCSI 2000 v2.1 (icddisk v33.0)"), 0, 0, 0, 0, _T("ADSCSI\0"), 32768, 232, 0, 0, ROMTYPE_ADSCSI, 0, 0, NULL,
	0x3184ec04, 0xf8ab84b0, 0x4853404f, 0x840085ce, 0x5fe992e3, 0x5dc443da, NULL, NULL },
	{ _T("ICD AdSCSI 2000 v2.2 (icddisk v34.0)"), 2, 2, 2, 2, _T("ADSCSI\0"), 32768, 233, 0, 0, ROMTYPE_ADSCSI, 0, 0, NULL,
	0x6881cd2f, 0x482fab24, 0xdf39446b, 0xa8662c7e, 0x67f11854, 0x895a46d9, NULL, NULL },
	{ _T("Archos ADD-500"), 1, 21, 1, 21, _T("ADD\0"), 16384, 132, 0, 0, ROMTYPE_ADD500, 0, 0, NULL,
	0x3f4e4a74, 0x9ed96fc0,0xd6381dc3,0x3192b0af,0xdfae4b74,0x576c3a69, NULL, NULL },
	{ _T("Protar A500HD"), 1, 193, 1, 193, _T("PROTAR\0"), 32768, 131, 0, 0, ROMTYPE_PROTAR, 0, 0, NULL,
	0x10c1b22c, 0x2b800cde,0x79fd559e,0xebd5e432,0xd711af3d,0x0b8ea7e9, NULL, NULL },
	{ _T("M-Tec AT500 v1.33w"), 1, 33, 1, 33, _T("MTECAT\0"), 32768, 130, 0, 0, ROMTYPE_MTEC, 0, 0, NULL,
	0x38b6b6b0, 0x8bb1093a,0xd592e7df,0x99c48f83,0xb9f842b2,0xb1a6e618, NULL, NULL },
	{ _T("AdIDE 40/44 v33"), 33, 0, 33, 0, _T("ADIDE\0"), 16384, 141, 0, 0, ROMTYPE_ADIDE, 0, 0, NULL,
	0x330254ce, 0xc91dd3b5,0x3f1986bd,0x94fba150,0xe753c2da,0x4dee78e7, NULL, NULL },
	{ _T("AdIDE 40/44 v34"), 34, 0, 34, 0, _T("ADIDE\0"), 16384, 129, 0, 0, ROMTYPE_ADIDE, 0, 0, NULL,
	0xedf84cbe, 0xabdbc01d,0xaa0b3aae,0xe4401ad7,0xe65525a9,0x6bfa2b27, NULL, NULL },
	{ _T("Vector Falcon 8000 v7.1"), 7, 1, 7, 1, _T("VECTOR\0"), 32768, 128, 0, 0, ROMTYPE_VECTOR, 0, 0, NULL,
	0xa8120c55, 0x248935ab, 0xf4d74036, 0xefdafdbb, 0x7817e232, 0xfc13e0fa, NULL, NULL },
	ALTROMPN(128, 1, 1, 16384, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x798b1152, 0x603ba087,0xecee69ac,0x7ccf6e88,0x3e374fc8,0x808bcbb4)
	ALTROMPN(128, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xd8b2f469, 0xbc600f99,0xa0ff7384,0xdabc7a04,0xb7bb0e71,0xad615db5)
	{ _T("Vector Falcon 8000 v7.6"), 7, 6, 7, 6, _T("VECTOR\0"), 32768, 172, 0, 0, ROMTYPE_VECTOR, 0, 0, NULL,
	0x2177a145, 0x8a7e617f,0xed566bb8,0xb33f6409, 0x05d9b946, 0xcee6d4bf, NULL, NULL },
	ALTROMPN(172, 1, 1, 16384, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x6228a3e4,0x72fa4175,0x21731e91,0x6c6c8519,0x91110287,0x9f4c0cb9)
	ALTROMPN(172, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf0a0ab0d,0xd239405a,0x5c4983ce,0xeaff0fd2,0x36d42d82,0x5a0cafd1)
	{ _T("Kommos A500/A2000 v1.8"), 1, 8, 1, 8, _T("KOMMOS\0"), 32768, 127, 0, 0, ROMTYPE_KOMMOS, 0, 0, NULL,
	0xc1a5c848, 0x291310f1, 0x25455f2d, 0x8e114bcd, 0xe104ca4c, 0x9db51747, NULL, NULL },
	ALTROMPN(127, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x1b86d2ed, 0x969995a1, 0x2ebf8c15, 0xab87e8d0, 0xddc837a1, 0xb90fbfa8)
	ALTROMPN(127, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x65b4c3a0, 0x60e904d4, 0xe45bb6ba, 0x3e253ffa, 0xda4ee2e5, 0xc8548da1)
	{ _T("Kommos A500/A2000 v1.7"), 1, 7, 1, 7, _T("KOMMOS\0"), 32768, 140, 0, 0, ROMTYPE_KOMMOS, 0, 0, NULL,
	0x025d7835, 0x8205ad6e, 0x08dbf5a6, 0x9ba17956, 0xb5237ffe, 0x768de5a4, NULL, NULL },
	ALTROMPN(140, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x3d982391, 0xbe26e141, 0x1e16cab4, 0xeab8af33, 0x1476ef8e, 0x21fcb2af)
	ALTROMPN(140, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x68adc0ad, 0xb5eef088, 0xed8a9439, 0xb0302907, 0xcb3cb207, 0x62f28da7)
	{ _T("Kupke Golem v3.9"), 3, 9, 3, 9, _T("GOLEM\0"), 16384, 124, 0, 0, ROMTYPE_GOLEM, 0, 0, NULL,
	0x49157dd0, 0x03b615c9,0x2befa474,0xa37303ca,0xdc3e830d,0x3c0d9a9f, NULL, NULL },
	ALTROMPN(124, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x88cf2ec5, 0x59680f8d, 0xae520893, 0xff9ada35, 0xac9a1146, 0x4f87453c)
	ALTROMPN(124, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x713298ad, 0x2ad7d6f3, 0xd696fd2c, 0x51a256ee, 0xea185c47, 0x52906e04)
	{ _T("GVP Series I v1.0"), 1, 0, 1, 16, _T("GVPI\0"), 16384, 123, 0, 0, ROMTYPE_GVPS1, 0, 0, NULL,
	0x1a4c20aa, 0xb9a3377e,0x2d9b5163,0x28693c63,0x19ffb65b,0x40ae3618, NULL, NULL },
	ALTROMPN(123, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x27f15785, 0x1a71a78d, 0xdd4e9559, 0x0f133bba, 0x4a71122f, 0x44caef78)
	ALTROMPN(123, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xa723193e, 0x05b4a072, 0x785c7824, 0x54e003c3, 0x6d88bd9b, 0xf5f561b9)
	{ _T("GVP Series I v3.7"), 1, 0, 1, 16, _T("GVPI\0"), 16384, 222, 0, 0, ROMTYPE_GVPS1, 0, 0, NULL,
	0x5dcddce0, 0xd7396422,0x0bd96364,0x3101d00f,0x5fe94c60,0x58fe7578, NULL, NULL },
	ALTROMPN(222, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x532ea912, 0x06b4aa28, 0xd80be728, 0x6c641590, 0x40706d7d, 0x8c323523)
	ALTROMPN(222, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x968f24eb, 0xcfb3e234, 0xd44517c4, 0x3cd3cec2, 0xbb6ec27a, 0xaaedd220)

	{ _T("GVP Series I/II v3.15"), 3, 15, 3, 15, _T("GVPII\0GVPI\0"), 16384, 111, 0, 0, ROMTYPE_GVPS12, 0, 0, NULL,
	0xf99c6f11, 0x77098a9e,0x35acaef2,0x11a546f0,0xc564cdac,0xf52836c4, NULL, NULL },
	{ _T("GVP Series I/II v3.7"), 3, 7, 3, 7, _T("GVPII\0GVPI\0"), 16384, 238, 0, 0, ROMTYPE_GVPS12, 0, 0, NULL,
	0xe136b9c4, 0xabcc0b52,0xa99dba6f,0xc2eb8428,0x63c7c805,0xb7f4d770, NULL, NULL },
	{ _T("GVP Series II v4.13"), 4, 13, 4, 13, _T("GVPII\0"), 16384, 263, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
	0xfc20b5e2, 0x85c050ba, 0x894ced53, 0x359fd7d6, 0x730250e7, 0x4c4b66bf, NULL, NULL },
	{ _T("GVP Series II v4.15"), 4, 15, 4, 15, _T("GVPII\0"), 16384, 109, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
	0xf89f44d6, 0xbf10c12c,0xc72dd040,0x549ea17c,0x24947633,0xe3773297, NULL, NULL },
	{ _T("GVP Series II Guru ROM"), 6, 14, 6, 14, _T("GVPII\0"), 32768, 110, 0, 0, ROMTYPE_GVPS2, 0, 0, NULL,
	0x756103b1, 0x7f1335ea,0xf5b7ce73,0xc5231173,0x261da5aa,0xe7249645, NULL, NULL },
	{ _T("AlfaPower v6.10"), 6, 10, 6, 10, _T("ALFAPOWER\0"), 32768, 117, 0, 0, ROMTYPE_ALFA, 0, 0, NULL,
	0x1cfb0a0b, 0xc7275eda,0x547d6664,0x5c4eb7a0,0x3b5cef37,0xa498365a, NULL, NULL },
	{ _T("AlfaPower v8.2"), 8, 2, 8, 2, _T("ALFAPOWERPLUS\0"), 32768, 310, 0, 0, ROMTYPE_ALFAPLUS, 0, 0, NULL,
	0x42b570db, 0xf7d3f6bf,0x83ef13f9,0x438bf0d3,0x790d2f69,0xc26dcabe, NULL, NULL },
	{ _T("AlfaPower v8.3"), 8, 3, 8, 3, _T("ALFAPOWERPLUS\0"), 32768, 118, 0, 0, ROMTYPE_ALFAPLUS, 0, 0, NULL,
	0xe8201bad, 0xdefea015,0x596fce32,0x11e84397,0x23046a31,0x5a7726dc, NULL, NULL },
	{ _T("Masoboshi MC-702 v2.204"), 2, 204, 2, 204, _T("MASOBOSHI\0"), 32768, 338, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL,
	0x0748c752, 0x6795c299,0x47d2d665,0xa6f698b0,0xc033752c,0x27d0a5b1, NULL, NULL },
	{ _T("Masoboshi MC-702 v2.202"), 2, 202, 2, 202, _T("MASOBOSHI\0"), 32768, 339, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL,
	0x07746315, 0xba388102,0xd070538e,0x7a8c1555,0x6830c653,0x130b902c, NULL, NULL },
	{ _T("Masoboshi MC-702 v2.201"), 2, 201, 2, 201, _T("MASOBOSHI\0"), 32768, 120, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL,
	0xcd99b98a, 0x3897e46a,0x66d5833f,0x849b8e81,0x30acb3cb,0x319a2fa0, NULL, NULL },
	{ _T("Masoboshi MC-702 v2.197"), 2, 197, 2, 197, _T("MASOBOSHI\0"), 32768, 316, 0, 0, ROMTYPE_MASOBOSHI, 0, 0, NULL,
	0x534e170c, 0xcf7c6c51,0x1c767f68,0x934aa897,0xb08b70bc,0xcf2a367f, NULL, NULL },
	{ _T("Roctec RocHard RH800C v1"), 1, 0, 1, 0, _T("ROCHARD\0"), 16384, 138, 0, 0, ROMTYPE_ROCHARD, 0, 0, NULL,
	0x0e980aec, 0xbcafa14d,0xe80576cb,0xe3e0c638,0x1ca90379,0xe078a8bd, NULL, NULL },
	ALTROMPN(138, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xde3a855b, 0xda2fe069, 0xd78c9ccc, 0xc221711f, 0x1e598298, 0x2bdabffd)
	ALTROMPN(138, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xb0ed3006, 0x0a88d84e, 0x2094f9e5, 0x18d37f90, 0x34764f22, 0x9696c3d9)
	{ _T("Roctec RocHard RH800C v2"), 2, 0, 2, 0, _T("ROCHARD\0"), 16384, 146, 0, 0, ROMTYPE_ROCHARD, 0, 0, NULL,
	0x5c27be3f, 0xacdb8bc7,0x64493f65,0x9da4c1e8,0x3005ceeb,0xced73dbc, NULL, NULL },
	ALTROMPN(146, 1, 1, 8192, ROMTYPE_ODD |  ROMTYPE_8BIT, NULL, 0xc5b8f068, 0x6ada1205, 0x44d284d0, 0x326d68cb, 0x7a2d9fb4, 0x77f35852)
	ALTROMPN(146, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xc88843cb, 0x3d7eb1b6, 0x8139b81b, 0x0665684c, 0x536ab3d0, 0x52a5dd9d)
	{ _T("Apollo 500/2000"), 0, 0, 0, 0, _T("APOLLOHD\0"), 16384, 145, 0, 0, ROMTYPE_APOLLOHD, 0, 0, NULL,
	0x931bad25, 0x24b4ee4c,0x129c7a93,0xf83ad570,0x66afd80c,0x4179f39c, NULL, NULL },
	{ _T("Multi Evolution 500/2000 v2.2"), 2, 2, 2, 2, _T("MULTIEVOLUTION\0"), 65536, 245, 0, 0, ROMTYPE_MEVOLUTION, 0, 0, NULL,
	0x8fbe3fc5, 0x367ad3a3,0x7d1c9d61,0xe92915d3,0xb8121402,0x372b6aa1, NULL, NULL },
	ALTROMPN(245, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xa81522e9, 0x162d1fe7, 0x173848fa, 0x45d93872, 0xb1a9ab8f, 0x16f2b166)
	ALTROMPN(245, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x55c7c65a, 0x3dfaca7f, 0x9a6c0b0d, 0x2689bdc1, 0x313bbef7, 0xb164cad8)
	{ _T("Multi Evolution 500/2000 v3.0"), 3, 0, 3, 0, _T("MULTIEVOLUTION\0"), 65536, 156, 0, 0, ROMTYPE_MEVOLUTION, 0, 0, NULL,
	0xd13a2c89, 0xf9e38c4b,0xf5c6499d,0x486946ba,0x7b7636b8,0x0845265b, NULL, NULL },
	ALTROMPN(156, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x339b3549, 0x74de857b, 0x42f9a8e0, 0xc1f3c29e, 0x06982622, 0x853d08fe)
	ALTROMPN(156, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x3aca5d1f, 0x786f2197, 0xc614be91, 0xae7e87da, 0xb42c3290, 0xd7997763)
	{ _T("Multi Evolution 500/2000 v3.4"), 3, 4, 3, 4, _T("MULTIEVOLUTION\0"), 65536, 244, 0, 0, ROMTYPE_MEVOLUTION, 0, 0, NULL,
	0x99516e5d, 0x036bd049,0xb661996b,0x1b4ab621,0x16bfaf73,0xb12a2202, NULL, NULL },
	ALTROMPN(244, 1, 1, 32768, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x9b3018e2, 0x55af3abd, 0x74a8c4f9, 0x5ac8cf22, 0xf306fb3a, 0x78a551e3)
	ALTROMPN(244, 1, 2, 32768, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x5bf01c8c, 0xdd13e047, 0xd3d4b8fa, 0x149b784c, 0x788647ff, 0x11b22979)
	{ _T("Kupke Golem v4.2"), 4, 2, 4, 2, _T("GOLEMFAST\0"), 16384, 157, 0, 0, ROMTYPE_GOLEMFAST, 0, 0, NULL,
	0x5e94ee56, 0xf83dae55, 0x49f9b735, 0x52d5c6e0, 0x41da4c6c, 0x995a7f47, NULL, NULL },
	ALTROMPN(157, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xec13fda0, 0x6af1447c, 0x4363c46d, 0x05697458, 0x01daa30c, 0x03c01c9f)
	ALTROMPN(157, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x39b0075e, 0xf6644ea0, 0x6c3ed349, 0xfb0fb6b4, 0xa9f07655, 0x0b104179)
	{ _T("Phoenix Board SCSI v.J"), 3, 1, 3, 1, _T("PBSCSI\0"), 32768, 159, 0, 0, ROMTYPE_PHOENIXB, 0, 0, NULL,
	0x1f672e4b, 0xb20d50b8, 0x31ec9823, 0xfa732fc6, 0x522ecc6a, 0xae36ec33, NULL, NULL },
	{ _T("IVS GrandSlam/Trumpcard Pro v4.9"), 4, 9, 4, 9, _T("IVSPRO\0"), 16384, 161, 0, 0, ROMTYPE_IVSTPRO, 0, 0, NULL,
	0x4a15f224, 0x29500b47, 0x289e84ac, 0x575e3c7d, 0x82199b45, 0x605d8fc9, NULL, NULL },
	{ _T("IVS Trumpcard v4.9"), 4, 9, 4, 9, _T("IVSTC\0"), 16384, 249, 0, 0, ROMTYPE_IVSTC, 0, 0, NULL,
	0x5282febc, 0x9d69a534, 0x60529d66, 0x13b64723, 0xb0c8dfa5, 0x80274048, NULL, NULL },
	{ _T("IVS Trumpcard v3.1"), 3, 1, 3, 1, _T("IVSTC\0"), 8192, 261, 0, 0, ROMTYPE_IVSTC, 0, 0, NULL,
	0xfe48dd5d, 0x03e6c1b1, 0xf3300c94, 0x4cc176ea, 0xb3082e91, 0xe75d5e62, NULL, NULL },
	{ _T("IVS Trumpcard v1.5"), 1, 5, 1, 5, _T("IVSTC\0"), 8192, 262, 0, 0, ROMTYPE_IVSTC, 0, 0, NULL,
	0x6f37eb74, 0xbf510c23, 0x1c2134d7, 0xed4b4158, 0xba4acf14, 0xa34824d2, NULL, NULL },
	{ _T("Expansion Systems Dataflyer+ v1.5"), 1, 5, 1, 5, _T("DATAFLYERPLUS\0"), 32768, 170, 0, 0, ROMTYPE_DATAFLYER, 0, 0, NULL,
	0x00888f19, 0x54b73354, 0xb3592691, 0x59a80909, 0x0bdb67df, 0x8ac22aa9, NULL, NULL },
	{ _T("Expansion Systems Dataflyer+ v1.7"), 1, 7, 1, 7, _T("DATAFLYERPLUS\0"), 32768, 171, 0, 0, ROMTYPE_DATAFLYER, 0, 0, NULL,
	0xb0814aca, 0xb817672c, 0x1beb86c6, 0x840aa4bd, 0xf4640835, 0x1ed103f4, NULL, NULL },
	{ _T("Expansion Systems Dataflyer+ v2.0"), 2, 0, 2, 0, _T("DATAFLYERPLUS\0"), 32768, 211, 0, 0, ROMTYPE_DATAFLYER, 0, 0, NULL,
	0x8b35c0d0, 0x31237f26, 0x399a9de4, 0x0a48871f, 0xffa1bd91, 0xc881fde7, NULL, NULL },
	{ _T("Expansion Systems Dataflyer+ v2.1"), 2, 1, 2, 1, _T("DATAFLYERPLUS\0"), 32768, 169, 0, 0, ROMTYPE_DATAFLYER, 0, 0, NULL,
	0xc49daa65, 0x20275716, 0xdc7eb00e, 0x5dc53680, 0xb5c8a90a, 0x7c00e390, NULL, NULL },
	{ _T("Microbotics HardFrame v1.5"), 1, 5, 1, 5, _T("HARDFRAME\0"), 32768, 173, 0, 0, ROMTYPE_HARDFRAME, 0, 0, NULL,
	0x8d144212, 0xc5a4f497, 0x5216c1b1, 0xe08760d0, 0x0bd579ef, 0xea226354, NULL, NULL },
	{ _T("Microbotics HardFrame v1.8"), 1, 8, 1, 8, _T("HARDFRAME\0"), 32768, 258, 0, 0, ROMTYPE_HARDFRAME, 0, 0, NULL,
	0x10de5e2d, 0x3e25af59, 0xe6bb0d69, 0xd925f07b, 0x200b1b0e, 0x45e57d33, NULL, NULL },
	{ _T("Microbotics HardFrame v1.9"), 1, 9, 1, 9, _T("HARDFRAME\0"), 32768, 256, 0, 0, ROMTYPE_HARDFRAME, 0, 0, NULL,
	0x948a3de8, 0xc34cb0ef, 0xa0ebdd71, 0x9d604d38, 0x625a160d, 0x9e2ca95d, NULL, NULL },
	{ _T("Mainhattan Data A-Team v1.8"), 1, 8, 1, 8, _T("ATEAM\0"), 65536, 174, 0, 0, ROMTYPE_ATEAM, 0, 0, NULL,
	0x4fe08a5d, 0x007e5c61, 0x4048f598, 0x6d14011d, 0x23a41435, 0x5e0a2259, NULL, NULL },
	{ _T("M-Tec AT500 Megabody v1.33"), 1, 33, 1, 33, _T("MTECAT\0"), 32768, 199, 0, 0, ROMTYPE_MTEC, 0, 0, NULL,
	0x19715a2f, 0x124f9d10, 0x19f1b285, 0x16f33f4e, 0x2bf03ca0, 0x2f9ad772, NULL, NULL },
	{ _T("Comspec SA series v34.805"), 34, 805, 34, 805, _T("COMSPEC\0"), 16384, 200, 0, 0, ROMTYPE_COMSPEC, 0, 0, NULL,
	0x44458e28, 0x048b8232, 0xfe54252b, 0xb81e0d06, 0x83c9e92d, 0x880f3cbf, NULL, NULL },
	ALTROMPN(200, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xd5838a35, 0xb3d83657, 0x661a9fe1, 0xd54e6e69, 0xc8b13878, 0x0960a107)
	ALTROMPN(200, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x098c5529, 0x6f51827d, 0x40a79438, 0x69e2d0fb, 0x6e2e46e9, 0xb65c1244)
	{ _T("California Access Malibu v1.0"), 1, 0, 1, 0, _T("MALIBU\0"), 8192, 201, 0, 0, ROMTYPE_MALIBU, 0, 0, NULL,
	0xe60b1ce6, 0xa7c4b709, 0x494f4034, 0x42b8ec11, 0x090dc1d0, 0x18098ebc, NULL, NULL },
	{ _T("Ashcom Design AddHard v2.0"), 1, 0, 1, 0, _T("ADDHARD\0"), 16384, 209, 0, 0, ROMTYPE_ADDHARD, 0, 0, NULL,
	0xe9ad804a, 0x9ebabbeb,0xc1e5ce9e,0xd8e43870,0xdd810524,0x770ba6b4, NULL, NULL },
	{ _T("Spirit Technology InMate"), 1, 0, 1, 0, _T("INMATE\0"), 32768, 218, 0, 0, ROMTYPE_INMATE, 0, 0, NULL,
	0xa2e0cfb8, 0xfa7199d2,0xea343b01,0x4b0f6eb6,0x992d2e95,0x40fce61b, NULL, NULL },
	{ _T("Vortex System 2000"), 1, 0, 1, 0, _T("SYSTEM2000\0"), 16384, 219, 0, 0, ROMTYPE_SYSTEM2000, 0, 0, NULL,
	0x053097c3, 0xee87f26c,0xf858b63a,0xd6bff74b,0x802cea03,0x97281fad, NULL, NULL },
	{ _T("Kupke Golem HD3000 v1.4"), 1, 4, 1, 4, _T("GOLEMHD3000\0"), 16384, 220, 0, 0, ROMTYPE_GOLEMHD3000, 0, 0, NULL,
	0x93ba65c7, 0x33ba9d1e,0x27e9c210,0xa27ee6d3,0x855d3feb,0x1649ddc2, NULL, NULL },
	ALTROMPN(220, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x2af75b4c, 0xe25be651, 0x56eef3bc, 0xa036d76c, 0xca3903a9, 0x469f0de5)
	ALTROMPN(220, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x8283dc0c, 0xe3820358, 0x1d130b40, 0x9c333f41, 0xdfd6afcd, 0xf3fabb81)
	{ _T("Evesham Micros Reference"), 1, 1, 1, 1, _T("EVESHAMREF\0"), 65536, 221, 0, 0, ROMTYPE_EVESHAMREF, 0, 0, NULL,
	0xb0225f48, 0x2b170b40, 0x2f60d28c, 0x344fc463, 0x7e99915f, 0x92e0e8f1, NULL, NULL },
	{ _T("Profex Electronics HD 3300"), 22, 0, 22, 0, _T("PROFEXHD3300\0"), 8192, 223, 0, 0, ROMTYPE_PROFEX, 0, 0, NULL,
	0xfe4bf404, 0xc6c1e465, 0xc05e4794, 0xee76c9e2, 0x94def44d, 0x1c7560a1, NULL, NULL },
	{ _T("Elsat Mega Ram HD"), 1, 0, 1, 0, _T("ELSATHD\0"), 16384, 224, 0, 0, ROMTYPE_ELSATHD, 0, 0, NULL,
	0x1b854f6b, 0xc39d6202, 0xccb65f17, 0x63d1835e, 0x19d5b63d, 0x28f1b6a3, NULL, NULL },
	ALTROMPN(224, 1, 1, 8192, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x3ba56b91, 0xef55760e, 0x8d5a5408, 0x7062f9ab, 0xc63ef067, 0x0b23f108)
	ALTROMPN(224, 1, 2, 8192, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x20c2cbb6, 0xb83d7406, 0x6c335a77, 0x0acb30d6, 0xff79a00f, 0x629a6953)
	{ _T("Xetec FastTrak"), 1, 42, 1, 42, _T("FASTTRACK\0"), 32768, 227, 0, 0, ROMTYPE_FASTTRAK, 0, 0, NULL,
	0xc5ae45d4, 0x8d682bc1,0x72bd2d35,0x4ba2db5c,0x9f6745a4,0x8937782c, NULL, NULL },
	{ _T("C-Ltd Kronos"), 1, 0, 1, 0, _T("KRONOS\0"), 8192, 235, 0, 0, ROMTYPE_KRONOS, 0, 0, NULL,
	0x9366d357, 0x7113add0,0x4c782ed7,0xa56a74ba,0x3378d55c,0x5605eaf6, NULL, NULL },
	{ _T("AccessX 500 v2.1"), 2, 1, 2, 1, _T("ACCESSX500\0"), 32768, 242, 0, 0, ROMTYPE_ACCESSX, 0, 0, NULL,
	0x039a14a7, 0x1a710b94, 0xcc1bd217, 0xb0c310af, 0x4b0f6d0a, 0x1125b05a, NULL, NULL },
	{ _T("AccessX 2000 v2.1"), 2, 1, 2, 1, _T("ACCESSX2000\0"), 32768, 255, 0, 0, ROMTYPE_ACCESSX, 0, 0, NULL,
	0xd1b7ab32, 0x09da8da3, 0x12310256, 0x42f761da, 0xc2af7f49, 0x84db4c31, NULL, NULL },
	{ _T("AccessX 500/2000 v2.1 (descrambled)"), 2, 1, 2, 1, _T("ACCESSX\0"), 32768, 243, 0, 0, ROMTYPE_ACCESSX, 0, 0, NULL,
	0x415a5cae, 0x15c8c15f, 0x3700e867, 0xd1dbe2ee, 0xcbb7c7cd, 0x245555fa, NULL, NULL },
	{ _T("Pacific Peripherals Overdrive v1.5"), 1, 5, 1, 5, _T("OVERDRIVE\0"), 8192, 246, 0, 0, ROMTYPE_OVERDRIVE, 0, 0, NULL,
	0x086e2716b, 0x075b50cb,0x166e00ac,0x4016ef7f,0x02532e86,0xe73b7711, NULL, NULL },
	{ _T("Pacific Peripherals Overdrive v2.0"), 2, 0, 2, 0, _T("OVERDRIVE\0"), 8192, 247, 0, 0, ROMTYPE_OVERDRIVE, 0, 0, NULL,
	0xebe42aa6, 0xdff761c2,0x429d0d26,0x2151d831,0x12746f83,0x3b8d36f0, NULL, NULL },
	{ _T("Archos Overdrive HD v5.0"), 5, 0, 5, 0, _T("ARCHOSHD\0"), 32768, 250, 0, 0, ROMTYPE_ARCHOSHD, 0, 0, NULL,
	0x30c0e3f9, 0x90014e97,0x700333a7,0x931b382f,0xe672b6e4,0x4b7b8acc, NULL, NULL },
	{ _T("Archos Overdrive HD v3.0"), 3, 0, 3, 0, _T("ARCHOSHD\0"), 32768, 332, 0, 0, ROMTYPE_ARCHOSHD, 0, 0, NULL,
	0x68c6dc4b, 0x67a5df20,0xf6d893a3,0x0ff130b4,0xe4b9aaab,0xf4be5e90, NULL, NULL },
	{ _T("Trumpcard 500AT v1.1"), 1, 1, 1, 1, _T("TRUMPCARDAT\0"), 16384, 251, 0, 0, ROMTYPE_IVST500AT, 0, 0, NULL,
	0xb6467cb8, 0xbc1cd85f,0x16011691,0x32a2a8d6, 0x2ee38666,0x520d5cf1, NULL, NULL },
	{ _T("Trumpcard 500AT v1.2"), 1, 2, 1, 2, _T("TRUMPCARDAT\0"), 16384, 252, 0, 0, ROMTYPE_IVST500AT, 0, 0, NULL,
	0x3eb87eb3, 0xff41889e,0x641114e5,0x5ec1f784,0xd79216ce,0xe9a74a40, NULL, NULL },
	{ _T("Trifecta v4.31"), 0, 0, 0, 0, _T("TRIFECTA\0"), 32768, 253, 0, 0, ROMTYPE_TRIFECTA, 0, 0, NULL,
	0x591c3cd4, 0x681b8a67,0x3775dd0c,0x8f13b641,0x8852a51e,0xf3a29da3, NULL, NULL },
	{ _T("Mastercard v2.3"), 0, 0, 0, 0, _T("MTECMASTERCARD\0"), 65536, 254, 0, 0, ROMTYPE_MASTERCARD, 0, 0, NULL,
	0x4837cc3d, 0xeea5e9ab,0xb3ffb4ed,0xdf09825c,0x7e8de75d,0x0d08c01f, NULL, NULL },
	{ _T("Hardital Dotto"), 0, 0, 0, 0, _T("DOTTO\0"), 32768, 257, 0, 0, ROMTYPE_DOTTO, 0, 0, NULL,
	0xee803484, 0x62822cb9,0x0b095efa,0x455496ea,0xd5b22740,0x77d86375, NULL, NULL },
	{ _T("A.L.F. 2"), 0, 0, 0, 0, _T("ALF2\0"), 65536, 264, 0, 0, ROMTYPE_ALF2, 0, 0, NULL,
	0x9cf8a7b7, 0x3df4667c,0xd3436367,0x7896da65,0x94994769,0x13bc6746, NULL, NULL },
	{ _T("M.A.S.T. Fireball"), 0, 0, 0, 0, _T("MASTFB\0"), 8192, 265, 0, 0, ROMTYPE_MASTFB, 0, 0, NULL,
	0xb475ff5f, 0x63609553,0x98b06812,0x23ade9ac,0x6ee31364,0x5375fce3, NULL, NULL },
	{ _T("Hardital Synthesis v48.5"), 48, 5, 48, 5, _T("SYNTHESIS\0"), 32768, 300, 0, 0, ROMTYPE_SYNTHESIS, 0, 0, NULL,
	0x9bd8065a, 0x1e886634,0x44d191eb,0x268ac86a,0x0f9fc99f,0x3e91b9dc, NULL, NULL },
	{ _T("Hardital Synthesis v53.1"), 53, 1, 53, 1, _T("SYNTHESIS\0"), 32768, 266, 0, 0, ROMTYPE_SYNTHESIS, 0, 0, NULL,
	0x667c7616, 0x0eb1cb38,0x3133f070,0x7cb57944,0xc516f236,0xbad4d4f6, NULL, NULL },
	{ _T("Combitec HD20A/HD40A"), 0, 0, 0, 0, _T("HD20A\0"), 32768, 267, 0, 0, ROMTYPE_HD20A, 0, 0, NULL,
	0x0e7391b4, 0x7c365adb,0x3496c479,0x5e94a166,0xd834254a,0x6112d91c, NULL, NULL },
	{ _T("Buddha v103.17"), 103, 17, 103, 17, _T("BUDDHA\0"), 32768, 340, 0, 0, ROMTYPE_BUDDHA, 0, 0, NULL,
	0x2b7b24e0, 0xec17a589,0x62c373a2,0x892090ec,0x9b1722d2,0xc326d631, NULL, NULL },

	{ _T("CyberStorm MK I 68060 Support"), 0, 0, 0, 0, _T("CSMKI\0"), 32768, 95, 0, 0, ROMTYPE_CB_CSMK1, 0, 0, NULL,
	0x33a8ff3a, 0x8f4bdda0,0x10338a48,0x51e4a2fb,0xb4aa6d6e,0x202fe98e, NULL, NULL },
	{ _T("CyberStorm MK I CyberSCSI Module"), 0, 0, 0, 0, _T("CSMKISCSI\0"), 32768, 101, 0, 0, ROMTYPE_CSMK1SCSI, 0, 0, NULL,
	0x4e71ec63, 0x8e95bc8d,0xa06050fc,0xb596b5b4,0xc8cf9102,0x1ff4aeb3, NULL, NULL },
	{ _T("CyberStorm MK II"), 0, 0, 0, 0, _T("CSMKII\0"), 131072, 96, 0, 0, ROMTYPE_CB_CSMK2, 0, 0, NULL,
	  0, 0, 0, 0, 0, 0, NULL, _T("cyberstormmk2.rom") },

	{ _T("CyberStorm MK III v44.67"), 44, 67, 0, 0, _T("CSMKIII\0"), 131072, 97, 0, 0, ROMTYPE_CB_CSMK3, 0, 0, NULL,
	  0, 0x4673baad,0xee2bfca3,0x151fbe15,0x3bc48308,0x8d932118, NULL, _T("cyberstormmk3.rom") },
	{ _T("CyberStorm MK III v44.69"), 44, 69, 0, 0, _T("CSMKIII\0"), 131072, 324, 0, 0, ROMTYPE_CB_CSMK3, 0, 0, NULL,
	  0, 0xfa033a77,0x1c9174f4,0xf91a595c,0xbcc46416,0xfbba84af, NULL, NULL },
	{ _T("CyberStorm MK III v44.71"), 44, 71, 0, 0, _T("CSMKIII\0"), 131072, 325, 0, 0, ROMTYPE_CB_CSMK3, 0, 0, NULL,
	  0, 0x8f902c86,0x2cb1792f,0x789b2cf8,0xec1016d9,0x62e029c5, NULL, NULL },
	{ _T("CyberStorm PPC v44.67"), 44, 67, 0, 0, _T("CSPPC\0"), 131072, 98, 0, 0, ROMTYPE_CB_CSPPC, 0, 0, NULL,
	  0, 0x7223763d,0x90316bdb,0x4d5001a9,0xa877cce4,0x00d68283, NULL, _T("cyberstormppc.rom") },
	{ _T("CyberStorm PPC v44.69"), 44, 69, 0, 0, _T("CSPPC\0"), 131072, 326, 0, 0, ROMTYPE_CB_CSPPC, 0, 0, NULL,
	  0, 0x34807066,0xe2b7694e,0x856a3031,0x387f40f2,0xbe75aad9, NULL, NULL },
	{ _T("CyberStorm PPC v44.71"), 44, 71, 0, 0, _T("CSPPC\0"), 131072, 327, 0, 0, ROMTYPE_CB_CSPPC, 0, 0, NULL,
	  0, 0xc7cb3c4f,0xa66e260f,0x43bff704,0x4049a264,0xa729e590, NULL, NULL },
	{ _T("Blizzard PPC 68040 v44.67"), 44, 67, 0, 0, _T("BPPC\0"), 524288, 99, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
	  0, 0x96564e51,0x5df30654,0x05d223ab,0xc958fe76,0xc5223fb5, NULL, _T("blizzardppc_040.rom") },
	{ _T("Blizzard PPC 68060 v44.67"), 44, 67, 0, 0, _T("BPPC\0"), 524288, 100, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
	  0, 0xf7533d16,0x9fcfc720,0x192fbc32,0x92b75f99,0x8c36f8ce, NULL, _T("blizzardppc_060.rom") },
	{ _T("Blizzard PPC 68040 v44.69"), 44, 67, 0, 0, _T("BPPC\0"), 524288, 328, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
	  0, 0xc8a63707,0xbe89c549,0x25f99e6b,0x6c1b8ca4,0x605b2e57, NULL, NULL },
	{ _T("Blizzard PPC 68060 v44.69"), 44, 67, 0, 0, _T("BPPC\0"), 524288, 329, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
	  0, 0xacc30e57,0xed900be3,0x87f466d0,0x57600791,0x316b0af5, NULL, NULL },
	{ _T("Blizzard PPC 68040 v44.71"), 44, 67, 0, 0, _T("BPPC\0"), 524288, 330, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
	  0, 0x9d0e3e2c,0xd5ca81b0,0x322f265c,0x83198aee,0xc81ee336, NULL, NULL },
	{ _T("Blizzard PPC 68060 v44.71"), 44, 67, 0, 0, _T("BPPC\0"), 524288, 331, 0, 0, ROMTYPE_CB_BLIZPPC, 0, 0, NULL,
	  0, 0x33fd6090,0xc54114bf,0xdb73618a,0xaf19cc43,0x7ebdee3f, NULL, NULL },

	{ _T("ACA 500"), 0, 0, 0, 0, _T("ACA500\0"), 524288, 137, 0, 0, ROMTYPE_CB_ACA500, 0, 0, NULL,
	  0, 0, 0, 0, 0, 0, NULL, _T("menu500.aca") },

	{ _T("Picasso IV"), 7, 4, 7, 4, _T("PIV\0"), 131072, 91, 0, 0, ROMTYPE_PICASSOIV, 0, 0, NULL,
	0xa8133e7e, 0xcafafb91,0x6f16b9f3,0xec9b49aa,0x4b40eb4e,0xeceb5b5b },

	{ _T("A1060 BIOS 2.05"), 2, 5, 2, 5, _T("A1060\0"), 16384, 259, 0, 0, ROMTYPE_A1060, 0, 0, _T("380619-02"),
	0xf5384f6a, 0xa3bab2ad,0xd9555353,0x64d6e5fc,0x5bedac05,0xe35fad0b, NULL, NULL },
	{ _T("A1060 BIOS 2.06"), 2, 6, 2, 6, _T("A1060\0"), 16384, 147, 0, 0, ROMTYPE_A1060, 0, 0, _T("380619-03"),
	0x185f2bbd, 0xeba74ad1,0x000a5351,0xa5d99179,0xbf75f831,0xac2d2402, NULL, NULL },
	{ _T("A1060 BIOS 2.07"), 2, 7, 2, 7, _T("A1060\0"), 16384, 341, 0, 0, ROMTYPE_A1060, 0, 0, _T("380619-04"),
	0xe44ac214, 0x0990ea8c,0x509ead36,0x7391741d,0xf2d4542c,0xcb9d8fb7, NULL, NULL },
	{ _T("A2088 BIOS 3.4"), 3, 4, 3, 4, _T("A2088\0"), 16384, 148, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-04"),
	0x05552160, 0xd1defdee, 0x1c0eae41, 0x07d81e26, 0x74915cd2, 0x9d352f2e, NULL, NULL },
	{ _T("A2088 BIOS 3.5"), 3, 5, 3, 5, _T("A2088\0"), 16384, 158, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-04"),
	0xf8e1ad83, 0x45a2b7db,0x6e86fe80,0x5cfef63c,0x65c331a7,0x16a6e9e8, NULL, NULL },
	{ _T("A2088 BIOS 3.6.1"), 3, 61, 3, 61, _T("A2088\0"), 16384, 149, 0, 0, ROMTYPE_A2088, 0, 0, _T("380788-06"),
	0x5fd93e56, 0xc1b707a8,0xa62907d7,0x5299f10a,0xa60efd1f,0x44514b26, NULL, NULL },
	{ _T("A2088T BIOS 4.0 (09/11/89)"), 4, 10, 4, 10, _T("A2088T\0"), 32768, 203, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390657-01"),
	0x12545545, 0x54f7a99e,0x2e5dbc30,0x43f52001,0xa4abb3b6,0x8e4832fd, NULL, NULL },
	{ _T("A2088T BIOS 4.0 (14/11/89)"), 4, 10, 4, 10, _T("A2088T\0"), 32768, 204, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390657-01"),
	0xb6b3b6f7, 0x7929a92f,0x25203cea,0xad302ddd,0x31db55cd,0x49b3020a, NULL, NULL },
	{ _T("A2088T BIOS 4.10"), 4, 10, 4, 11, _T("A2088T\0"), 32768, 150, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390657-02"),
	0x20c5d1a9, 0x08e3fbb7,0x28dfc514,0x24083313,0x373ea7a5,0xa2c3e965, NULL, NULL },
	{ _T("A2088T BIOS 4.11"), 4, 11, 4, 11, _T("A2088T\0"), 32768, 151, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390547-02"),
	0x074bc9b0, 0x2a3f56bc,0xe395f203,0x46eb68c4,0xade7153e,0x3e69f892, NULL, NULL },
	{ _T("A2088T BIOS 4.12"), 4, 12, 4, 12, _T("A2088T\0"), 32768, 152, 0, 0, ROMTYPE_A2088T, 0, 0, _T("390547-03"),
	0x92447176, 0x582fa254,0x73aa2679,0xefcd41a5,0xbdadf1a2,0x6a87a75f, NULL, NULL },
	{ _T("A2286 BIOS 3.6"), 3, 6, 3, 6, _T("A2286\0"), 32768, 153, 0, 0, ROMTYPE_A2286, 0, 0, NULL,
	0x63d75f70, 0x9f5d6c78,0x656d2fe7,0x36608644,0x771b6d30,0x31083264, NULL, NULL },
	ALTROMPN(153, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("380682-03"), 0xb3f76402, 0xef9ba5f2, 0x2714ad6d, 0xfa5e0aef, 0x2d09ce83, 0x578ee26d)
	ALTROMPN(153, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("380683-03"), 0xab053693, 0x75229d80, 0x443fad78, 0xa298d04b, 0x37c8e6c3, 0x2c1b6df0)
	{ _T("A2286 BIOS 4.2"), 4, 2, 4, 2, _T("A2286\0"), 32768, 154, 0, 0, ROMTYPE_A2286, 0, 0, NULL,
	0xd572e205, 0x74fdf0f8,0x325fbc41,0x2b98c72d,0xf5095804,0x831c46b5, NULL, NULL },
	ALTROMPN(154, 1, 1, 16384, ROMTYPE_ODD  | ROMTYPE_8BIT, _T("380682-04"), 0xc23dcd55, 0x38dc24b7, 0x14427b15, 0xd5214cc9, 0xb9be0de7, 0x20bd6a34)
	ALTROMPN(154, 1, 2, 16384, ROMTYPE_EVEN | ROMTYPE_8BIT, _T("380683-04"), 0xdad80c0b, 0x12fe2916, 0x64f8c412, 0x3877a24e, 0x05837091, 0x44d8acd0)
	{ _T("A2386SX BIOS 1.00"), 1, 0, 1, 0, _T("A2386SX\0"), 65536, 155, 0, 0, ROMTYPE_A2386, 0, 0, _T("391168-01"),
	0x37003e0c, 0x2e127e9c,0x8581d30c,0x2e46404b,0x21608e3c,0xe935fa27, NULL, NULL },
	{ _T("A2386SX BIOS 1.00.03"), 1, 0, 1, 0, _T("A2386SX\0"), 65536, 205, 0, 0, ROMTYPE_A2386, 0, 0, _T("391168-01"),
	0x41041761, 0x78659be4,0x5755f8bd,0x004a101b,0x658ae75d,0xf142ddc9, NULL, NULL },

	{ _T("Arcadia OnePlay 2.11"), 2, 11, 0, 0, _T("ARCADIA\0"), 0, 49, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 8 },
	{ _T("Arcadia TenPlay 2.11"), 2, 11, 0, 0, _T("ARCADIA\0"), 0, 50, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 8 },
	{ _T("Arcadia OnePlay 2.20"), 2, 20, 0, 0, _T("ARCADIA\0"), 0, 75, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 8 },
	{ _T("Arcadia OnePlay 3.00"), 3, 0, 0, 0, _T("ARCADIA\0"), 0, 51, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 8 },
	{ _T("Arcadia TenPlay 3.10"), 3, 10, 0, 0, _T("ARCADIA\0"), 0, 76, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 8 },
	{ _T("Arcadia TenPlay 4.00"), 4, 0, 0, 0, _T("ARCADIA\0"), 0, 77, 0, 0, ROMTYPE_ARCADIABIOS, 0, 0, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 8 },

	{ _T("Arcadia SportTime Table Hockey v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 33, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia SportTime Bowling v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 34, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia World Darts v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 35, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Magic Johnson's Fast Break v2.8"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 36, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Leader Board Golf v2.4"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 37, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Leader Board Golf"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 38, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Ninja Mission v2.5"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 39, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Road Wars v2.3"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 40, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Sidewinder v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 41, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Spot v2.0"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 42, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Space Ranger v2.0"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 43, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Xenon v2.3"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 44, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia World Trophy Soccer v3.0"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 45, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Blastaball v2.1"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 78, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Delta Command"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 79, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Pharaohs Match"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 80, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia SportTime Table Hockey"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 81, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia World Darts (bad)"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 82, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Magic Johnson's Fast Break v2.7"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 83, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Ninja Mission"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 84, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Sidewinder"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 85, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Leader Board Golf v2.5"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 86, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },
	{ _T("Arcadia Aaargh"), 0, 0, 0, 0, _T("ARCADIA\0"), 0, 88, 0, 0, ROMTYPE_ARCADIAGAME, 0, 2, NULL, 0, 0, 0, 0, 0, 0, NULL, NULL, 9 },

	// maddog_01.dat, maddog_02.dat
	{ _T("American Laser Games Mad Dog McCree v1C"), 0, 0, 0, 0, _T("ALG\0"), 131072, 175, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x48fd863c, 0x9bf6f337,0x585122a5,0x97c19d71,0x224e3b68,0x347a98de, NULL, NULL, 10 },
	ALTROMPN(175, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf64014ec, 0xd343a2cb, 0x5d899215, 0x3b8c916f, 0x39b11d3d, 0xb736543d)
	ALTROMPN(175, 1, 2, 65536, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x04572557, 0x3dfe2ce9, 0x4ced8701, 0xa3e73ed5, 0x869b6fbe, 0x1c8b3286)
	// md_2.02_u1.bin, md_2.02_u2.bin
	{ _T("American Laser Games Mad Dog McCree v2.02"), 0, 0, 0, 0, _T("ALG\0"), 262144, 176, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x65181234, 0x321fe70a,0xb0986712,0xe4c6cc17,0x0fe48f1d,0x491ba069, NULL, NULL, 10 },
	ALTROMPN(176, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf46e1242, 0x2960bc18,0x00b22eea,0x50036ae4,0x3fd3cb2a,0xb7dcf8a4)
	ALTROMPN(176, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xa49890d1, 0x148f78fb,0x426f5b91,0x2e8c3836,0xa149bfcb,0x966da477)
	// md_2.03_1.bin, md_2.03_2.bin
	{ _T("American Laser Games Mad Dog McCree v2.03"), 0, 0, 0, 0, _T("ALG\0"), 262144, 177, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xbf0878ad, 0x7ff88de7,0x3fd5245e,0x346cca21,0xd0765de1,0x8ba28877, NULL, NULL, 10 },
	ALTROMPN(177, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xa50d3c04, 0x4cf100fd,0xb5b2f223,0x6539fd0e,0xc33b3db1,0x9c64a6b8)
	ALTROMPN(177, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x6f5b8f2d, 0xbbf32bb2,0x7a998d53,0x744411d7,0x5efdbdb7,0x30855809)
	// md2_01.bin, md2_02.bin
	{ _T("American Laser Games Mad Dog II: The Lost Gold v2.02"), 0, 0, 0, 0, _T("ALG\0"), 262144, 178, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x992f9a53, 0xf039a74c,0xc63e1465,0xb3036d4c,0x030df1ef,0x5ba03ff4, NULL, NULL, 10 },
	ALTROMPN(178, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaddffa51, 0x665e9d93,0xddfa6b2e,0xa5d006b4,0x1bf7eac3,0x294244cc)
	ALTROMPN(178, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x4092227f, 0x6e5393aa,0x5e64b598,0x87260f48,0x3c509600,0x84de7bd1)
	// md2_1.10_u1.bin, md2_1.10_u2.bin
	{ _T("American Laser Games Mad Dog II: The Lost Gold v1.10"), 0, 0, 0, 0, _T("ALG\0"), 262144, 179, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xc3230ece, 0x4dd60b21,0xf7ab65cd,0x77304753,0x6a4ff2eb,0x75b0778c, NULL, NULL, 10 },
	ALTROMPN(179, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0e113b2c, 0x739d777f,0x3cb92fbc,0x730c6c1b,0x664d8741,0x21d191b1)
	ALTROMPN(179, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x61808612, 0x1a0a301e,0x79585a81,0xe6cf4673,0x7068970f,0xb8a205fa)
	// md2_01_v.2.04.bin, md2_02_v.2.04.bin
	{ _T("American Laser Games Mad Dog II: The Lost Gold v2.04"), 0, 0, 0, 0, _T("ALG\0"), 262144, 180, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x1b9ddae6, 0xd52cc668,0xe4876294,0x5c4d9033,0x71d8a0b1,0x323b4464, NULL, NULL, 10 },
	ALTROMPN(180, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x361bd99c, 0x5de6ef38,0xe334e19f,0x509227de,0x7880306a,0xc984ec23)
	ALTROMPN(180, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x0e1227f4, 0xbfd9081b,0xb7d2bcbb,0x77357839,0xf292ce61,0x36e9b228)
	// md2_1.0_1.bin, md2_1.0_2.bin
	{ _T("American Laser Games Mad Dog II: The Lost Gold v1.00"), 0, 0, 0, 0, _T("ALG\0"), 262144, 181, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x348b1a05, 0xece8f1ec,0x4d97f98d,0xb1279ed5,0x28cb0fca,0x51c167bb, NULL, NULL, 10 },
	ALTROMPN(181, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0ce8db97, 0xdd4c09db,0x59bb8c6c,0xaba935b1, 0xb28babe2, 0x8ba8516b)
	ALTROMPN(181, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x97272a1d, 0x10901464,0x7c491f01,0x9ffb2109, 0x1c7d0b89, 0xe1755b75)
	// sp_14_u1.bin, sp_14_u2.bin
	{ _T("American Laser Games Space Pirates v1.4"), 0, 0, 0, 0, _T("ALG\0"), 262144, 182, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x69e09b90, 0xda3cba84,0x1c37222f,0xc45b4704,0x997072ad,0x1e9a1f8e, NULL, NULL, 10 },
	ALTROMPN(182, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x4102988c, 0x969d4668,0xbe50990c,0x7debf9ed,0x4e8b8c6e,0x422acdf5)
	ALTROMPN(182, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x30390ab0, 0x80fa14d8,0x81902258,0x398225bd,0xfd71ed5e,0x9e2d6c91)
	// sp_01.dat, sp_02.dat
	{ _T("American Laser Games Space Pirates v2.2"), 0, 0, 0, 0, _T("ALG\0"), 262144, 183, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x09c2cfcb, 0x93ad6a25,0x77fa7870,0x971890f2,0x6af11382, 0xa433f80b, NULL, NULL, 10 },
	ALTROMPN(183, 1, 1, 131072, ROMTYPE_EVEN  | ROMTYPE_8BIT, NULL, 0x10d162a2, 0x26833d5b,0xe1057be8,0x639c00a7,0xbe18be33,0x404ea751)
	ALTROMPN(183, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xc0975188, 0xfd7643dc,0x972e7861,0x249ab7e7,0x61999759,0x84888ae4)
	// sp_14b_u1.bin, sp_14b_u2.bin
	{ _T("American Laser Games Space Pirates v1.4 (Rev B PCB hack)"), 0, 0, 0, 0, _T("ALG\0"), 262144, 271, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x024092d3, 0xd5e04a80, 0xabeb1ffe, 0xff089539, 0x01e398d8, 0xadce9bb2, NULL, NULL, 10 },
	ALTROMPN(271, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0b77952b, 0xc1497f16, 0xe042a248, 0x224f8527, 0xdff69d7a, 0xdc00f46c)
	ALTROMPN(271, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x1e6ec8d6, 0x9472613e, 0x209cab7d, 0xc73940f8, 0x1030c857, 0xd3d6a47c)
	// johnny_01.bin, johnny_02.bin
	{ _T("American Laser Games Who Shot Johnny Rock? v1.6"), 0, 0, 0, 0, _T("ALG\0"), 131072, 184, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xaeda7df4, 0xa612c4b9,0x2bd81ab9,0x564e58da,0x9a6a4d81,0x93c59acf, NULL, NULL, 10 },
	ALTROMPN(184, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x046569b3, 0xefe5a8b2,0xbe1c5556,0x95f2a91c,0x88951d35,0x45f1b915)
	ALTROMPN(184, 1, 2, 65536, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xedde1745, 0x573b79f8,0x808fedaa,0xbf3b7623,0x50a91579,0x2d26c1bc)
	// wsjr151.bin,wsjr152.bin
	{ _T("American Laser Games Who Shot Johnny Rock? v1.5"), 0, 0, 0, 0, _T("ALG\0"), 131072, 185, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x50eb4827, 0x72568673,0x4163aa16,0xd0ad3177,0xbd720187,0x125a63ec, NULL, NULL, 10 },
	ALTROMPN(185, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x8ab626dd, 0xe45561f7,0x7fc279b7,0x1dc1dd2e,0x15a0870c,0xb5c1cd89)
	ALTROMPN(185, 1, 2, 65536, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x9beeb1d7, 0x3fe0265e,0x5d36103d,0x3d9557d7,0x5e5e3728,0xe0b30da7)
	// wsjrU1A.bin,wsjrU2A.bin
	{_T("American Laser Games Who Shot Johnny Rock? v1.6 (Maddog Rev A PCB hack)"), 0, 0, 0, 0, _T("ALG\0"), 131072, 272, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xaa413638, 0x387e9613, 0xf7034ac2, 0x509f90dc, 0x796da9ca, 0x39e506f9, NULL, NULL, 10 },
	ALTROMPN(272, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x2a9225a7, 0x644428b2, 0x000ce281, 0xbc0247dd, 0xa9276355, 0x92849717)
	ALTROMPN(272, 1, 2, 65536, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0x1e10eb58, 0x80cd169e, 0xf1959852, 0xf5b1ec3b, 0x2e2f995d, 0x588cf1df)
	// wsjrU1B.bin,wsjrU2B.bin
	{_T("American Laser Games Who Shot Johnny Rock? v1.6 (Rev B PCB hack)"), 0, 0, 0, 0, _T("ALG\0"), 262144, 273, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xa8cb412c, 0x2059d37c, 0xf63fdeaf, 0x9c0fc83e, 0xad018a8f, 0x982dc11f, NULL, NULL, 10 },
	ALTROMPN(273, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0848dc29, 0x9b70ac17, 0x705f06d3, 0x8c8285bb, 0x7edead7d, 0x2b286fd2)
	ALTROMPN(273, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL, 0xc6634148, 0x5c99ca64, 0x7b421383, 0xdf6e3391, 0xac685b35, 0x4a1a5539)
	// gg_1.dat,gg_2.dat
	{ _T("American Laser Games Gallagher's Gallery v2.2"), 0, 0, 0, 0, _T("ALG\0"), 262144, 186, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xcbe791de, 0x17aa6f16,0x7e138409,0xe1ef039e,0x928fee5a,0xf43e91cb, NULL, NULL, 10 },
	ALTROMPN(186, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x855c9d82, 0x96711aaa,0x02f309ca,0xcd3e8d8e,0xfbe95cfc,0x811aba96)
	ALTROMPN(186, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x3793b211, 0xdccb1d9c,0x5e2d6a4d,0x249426ae,0x6348e9fc,0x9b72e665)
	// gg_21_rom1.bin,gg_21_rom2.bin
	{ _T("American Laser Games Gallagher's Gallery v2.1"), 0, 0, 0, 0, _T("ALG\0"), 262144, 187, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x9bfe35bb, 0x76c8cad8,0xd0f4758f,0x1adc0fc9,0x7cb6ad30,0x44b54d47, NULL, NULL, 10 },
	ALTROMPN(187, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x70f887e5, 0xcd6cedc8,0x5bbe6767,0x4dfd140f,0xed901877,0x8f8cd8db)
	ALTROMPN(187, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x4109f39e, 0x42d06de4,0x2c56f21e,0x4899b4c4,0x252baabb,0x51f24fda)
	// gg_20_rom1.bin,gg_20_rom2.bin
	{ _T("American Laser Games Gallagher's Gallery v2.0"), 0, 0, 0, 0, _T("ALG\0"), 262144, 269, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xec0a948f, 0x97942bdf, 0x14e2bbe5, 0x5114c973, 0xd7d5bd98, 0x84795a51, NULL, NULL, 10 },
	ALTROMPN(269, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x229dd4b8, 0x982b3c95, 0x4bbd6aeb, 0x71e7cfa0, 0xe1074264, 0x5d726332)
	ALTROMPN(269, 1, 2, 131072, ROMTYPE_ODD | ROMTYPE_8BIT, NULL,  0xb7e96e7b, 0x7bfc5600, 0x15c94edc, 0x2c57b533, 0x95eebae4, 0x51c644ff)			
	// fd_131_u1.bin,fd_131_u2.bin
	{ _T("American Laser Games Fast Draw Showdown v1.31"), 0, 0, 0, 0, _T("ALG\0"), 262144, 188, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x6977addf, 0xdc845431,0xbb1a39bd,0x615afe5f,0x7cb7c8d0,0x3433ef8c, NULL, NULL, 10 },
	ALTROMPN(188, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xe1ed7982, 0xf7562c6e,0x0ce6bf1a,0x9885cc59,0x3e08c250,0x9f82bbe1)
	ALTROMPN(188, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xb7c79ab3, 0x6eca1bc9,0x590c22a0,0x04fb8590,0x1e5c7d41,0xf5b14ee2)
	// fast_01.bin,fast_02.bin
	{ _T("American Laser Games Fast Draw Showdown v1.30"), 0, 0, 0, 0, _T("ALG\0"), 262144, 189, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x47772e36, 0x5af67b5e,0xa56b2337,0xfdd427fb,0xd82d478f,0xb1994dbc, NULL, NULL, 10 },
	ALTROMPN(189, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x0d76a2da, 0xd396371a,0xe1b9b0b6,0xe6bc6f1f,0x85c4b97b,0xfc5dc34d)
	ALTROMPN(189, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x4c4eb71e, 0x3bd487c5,0x46b6c807,0x70a5fc88,0x0dcb1039,0x5ca431a2)
	// lbh_101_u1.bin,lbh_101_u2.bin
	{ _T("American Laser Games The Last Bounty Hunter v1.01"), 0, 0, 0, 0, _T("ALG\0"), 262144, 190, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xd2a5a539, 0xb97c799b,0x53355b55,0x4dfbf335,0x6f20fd2b,0xa5998806, NULL, NULL, 10 },
	ALTROMPN(190, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xb21c5c42, 0x9ac856cd,0xf2c9538c,0xc4ae55f0,0x79f33737,0x6d3361c0)
	ALTROMPN(190, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xf13b25d2, 0xe2f663c2,0x3b03592f,0x482ef5e1,0xdf87b651,0x937a500d)
	// bounty_01.bin,bounty_02.bin
	{ _T("American Laser Games The Last Bounty Hunter v0.06"), 0, 0, 0, 0, _T("ALG\0"), 262144, 191, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xce600734, 0xe52aea03,0x080dcd08,0x8d4b61ed,0xe46de9c7,0xfc4dd74e, NULL, NULL, 10 },
	ALTROMPN(191, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x2727ef1d, 0xf5342139,0x0b65c21a,0x7666ff9d,0x0f53ebf2,0xa463d836)
	ALTROMPN(191, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x977566b2, 0x937e079e,0x992ecb59,0x30b17c10,0x24c326e1,0x0962642b)
	// cp_151_u1.bin,cp_151_u2.bin
	{ _T("American Laser Games Crime Patrol v1.51"), 0, 0, 0, 0, _T("ALG\0"), 262144, 192, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xcada2bed, 0xc5da9d82,0x7864feff,0x75d87dd1,0x9ec06529,0x7d2b318b, NULL, NULL, 10 },
	ALTROMPN(192, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xaefd6e09, 0x351e665e,0x2e636804,0x7a5cc80d,0x0f9d876b,0xca068b6a)
	ALTROMPN(192, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xf2270cee, 0x1e735373,0x723c3cff,0xb6dd04d5,0xc30c08e7,0x57deae61)
	// cp01.dat,cp02.dat
	{ _T("American Laser Games Crime Patrol v1.4"), 0, 0, 0, 0, _T("ALG\0"), 262144, 193, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x51ba3153, 0x55086ba0,0xef41c6d6,0x41041b73,0x047cad38,0xaf2a21f3, NULL, NULL, 10 },
	ALTROMPN(193, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xa39a8b50, 0x55ca317e,0xf13c3a42,0xf12d68c4,0x80e6cc2d,0x4459f6a4)
	ALTROMPN(193, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xe41fd2e8, 0x1cd9875f,0xb4133ba4,0xe3616271,0x975dc736,0xb343f156)
	// cp_1.20_u1.bin,cp_1.20_u2.bin
	{ _T("American Laser Games Crime Patrol v1.2"), 0, 0, 0, 0, _T("ALG\0"), 262144, 194, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x63e9f444, 0x6f2624a5,0x6a672f97,0xc751ae51,0xb4b834a5,0x097a855a, NULL, NULL, 10 },
	ALTROMPN(194, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x475e847a, 0x82fd1608,0x35758cd5,0x1ea22f90,0xb08921a4,0x0409f94d)
	ALTROMPN(194, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x814f5777, 0x341a1d7b,0x64112af3,0xe8243bdb,0xfec72e7f,0xa85aa903)
	// cp_10_rom1.bin, cp_10_rom2.bin
	{ _T("American Laser Games Crime Patrol v1.0"), 0, 0, 0, 0, _T("ALG\0"), 262144, 270, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
		0xb3846a9f, 0x0157ff74, 0xb10b0bc2, 0x576ddcab, 0x80af6466, 0x6d49afc9, NULL, NULL, 10 },
	ALTROMPN(270, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x6e4614cd, 0x0f73f477, 0xe13b3f18, 0x4e9a55f4, 0xbe954746, 0x61c912d5)
	ALTROMPN(270, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xaac76488, 0xfabf4700, 0x610480a2, 0x8dad6e14, 0x83e58ec2, 0x27e465ff)
	// cp2_1.3_1.bin, cp2_1.3_2.bin
	{ _T("American Laser Games Crime Patrol 2: Drug Wars v1.3"), 0, 0, 0, 0, _T("ALG\0"), 262144, 195, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x57d1f606, 0xffbee51c,0x9c52a9c6,0x6440cbf8,0x34144321,0x75036282, NULL, NULL, 10 },
	ALTROMPN(195, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xdbdaa79a, 0x99804490,0x9d5c93e3,0xbd1baafe,0xfab818fd,0xb7b3f55e)
	ALTROMPN(195, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0xe653395d, 0x8f6c86d9,0x8a52b7d8,0x5ae285fd,0x841167cd,0x07979318)
	// cp2_1.dat, cp2_2.dat
	{ _T("American Laser Games Crime Patrol 2: Drug Wars v1.1"), 0, 0, 0, 0, _T("ALG\0"), 262144, 196, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x49c751db, 0x789679f9,0xa3fe3aa0,0xf9b8bb35,0x1f3ea632,0xe429408d, NULL, NULL, 10 },
	ALTROMPN(196, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf4e5251e, 0xe0c91343,0xa98193d4,0x87c40e7a,0x85f542b2,0xa7a88f03)
	ALTROMPN(196, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x47879042, 0x8bb6c541,0xe4e8e450,0x8da8d4b9,0x3600176a,0x2e7a1f41)
	// platoonv4u1.bin,platoonv4u2.bin
	{ _T("Nova Platoon V.3.1 US"), 0, 0, 0, 0, _T("ALG\0"), 262144, 197, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xad975c96, 0x9565207f,0x6684baa8,0xe5c85c34,0x740a3f60,0x75d3a7b5, NULL, NULL, 10 },
	ALTROMPN(197, 1, 1, 131072, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0x09a133cf, 0x9b3ff630,0x35be8576,0xc88fb284,0xa25c2da5,0xdb0d5160)
	ALTROMPN(197, 1, 2, 131072, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x8b33263e, 0xa1df3823,0x6321af90,0xb522e2a7,0x83984fdf,0x02e4c597)
	// zb_u2.bin,zb_u3.bin
	{ _T("Picmatic Zorton Brothers Ver. 1.00"), 0, 0, 0, 0, _T("ALG\0"), 131072, 198, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x9cda09ae, 0x3353ae63,0x64b3d0b1,0x006db48e,0xa2bdc7b5,0x4946bbb9, NULL, NULL, 10 },
	ALTROMPN(198, 1, 1, 65536, ROMTYPE_EVEN | ROMTYPE_8BIT, NULL, 0xf59cfc4a, 0x9fadf7f1,0xe23d6b4e,0x828bf2b3,0xde919d08,0x7c690a3f)
	ALTROMPN(198, 1, 2, 65536, ROMTYPE_ODD  | ROMTYPE_8BIT, NULL, 0x938b25cb, 0xd0114bbc,0x588dcfce,0x6a469013,0xd0e35afb,0x93e38af5)
	// zort_1-01_23-3-94_odd.u2, zort_1-01_23-3-94_even.u3
	{ _T("Picmatic Zorton Brothers Ver. 1.01"), 0, 0, 0, 0, _T("ALG\0"), 131072, 301, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0x37d274c2, 0xb756f787,0xfca4c190,0x4813b1e4,0xddf36c24,0xc815c708, NULL, NULL, 10 },
	ALTROMPN(301, 1, 2, 65536, ROMTYPE_EVEN  | ROMTYPE_8BIT, NULL, 0x6a051c6a, 0xf8daafab,0x068fef57,0xe47287bd,0x72be860b,0x84e2e75c)
	ALTROMPN(301, 1, 1, 65536, ROMTYPE_ODD   | ROMTYPE_8BIT, NULL, 0x21e63949, 0x0a62ad10,0x8f8cfa00,0xdc8f03de,0xa2ff6f1b,0x277e8d5d)
	// mspsl 200 odd 30394.u2, mspsl 200 even 30394.u3
	{ _T("Picmatic Marbella Vice"), 0, 0, 0, 0, _T("ALG\0"), 131072, 302, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xf78c8fa2, 0x07656cbf,0xdb6135f2,0x6add3b5f,0xa4ce5d46,0xdda706f9, NULL, NULL, 10 },
	ALTROMPN(302, 1, 1, 65536, ROMTYPE_EVEN  | ROMTYPE_8BIT, NULL, 0x01c9a503, 0xf61ec2cd,0x241b2bf8,0xa982e81e,0x5a181786,0x01f0a0a0)
	ALTROMPN(302, 1, 2, 65536, ROMTYPE_ODD   | ROMTYPE_8BIT, NULL, 0x78eb6fd6, 0xe4048180,0x95f03b6e,0x0746620f,0x5ce48c3f,0x7149b8a0)
	{ _T("Picmatic Marbella Vice (100Hz TV)"), 0, 0, 0, 0, _T("ALG\0"), 131072, 315, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xae2d2805, 0x0e392b46,0x15777fe5,0x24ed27ab,0xf8539d4b,0xb1e3ba9d, NULL, NULL, 10 },
	ALTROMPN(315, 1, 1, 65536, ROMTYPE_EVEN  | ROMTYPE_8BIT, NULL, 0xd2b5e5ca, 0xde765039,0x61076aca,0xd405db9e,0x83bd5334,0xb02bf908)
	ALTROMPN(315, 1, 2, 65536, ROMTYPE_ODD   | ROMTYPE_8BIT, NULL, 0x2c9ebccb, 0x4e8dcb85,0x26a8debb,0x70f3f567,0x13903ba8,0xbfbb3ed5)
	// spilz0d4-odd-27-9-95-salvajes-displays-27c512.u4, spilz0d4-even-27-9-95-salvajes-displays-27c512.u5
	{ _T("Picmatic Tierras Salvajes (100Hz TV)"), 0, 0, 0, 0, _T("ALG\0"), 131072, 314, 0, 0, ROMTYPE_ALG, 0, 0, NULL,
	0xe6c539ec, 0xa5f70818,0xd93ab33c,0xa4149a50,0xc38b2a13,0x0ee5d7ab, NULL, NULL, 10 },
	ALTROMPN(314, 1, 1, 65536, ROMTYPE_EVEN  | ROMTYPE_8BIT, NULL, 0x730e4696, 0x4db0cc7d,0x160de5e7,0x0f1d1842,0xfa94adb8,0xee7f954f)
	ALTROMPN(314, 1, 2, 65536, ROMTYPE_ODD   | ROMTYPE_8BIT, NULL, 0xd46dd5e0, 0x7d808c6e,0xd88bf9a9,0x8cdb468c,0xe71c0952,0xb0b5d7b2)

	{ NULL }

};

void dumpromlist(void)
{
	for (int i = 0; roms[i].name; i++) {
		struct romdata *rd = &roms[i];
		if (rd->name && rd->group == 0) {
			write_log(_T("%s"), rd->name);
			if (rd->size)
				write_log (_T(" [%dk]"), rd->size >> 10);
			write_log(_T("\n"));
		}
	}
}

void romlist_clear (void)
{
	int i;
	int mask = 0;
	struct romdata *parent;
	const TCHAR *pn;

	xfree (rl);
	rl = 0;
	romlist_cnt = 0;
	romlist_gen++;
	parent = 0;
	pn = NULL;
	for (i = 0; roms[i].name; i++) {
		struct romdata *rd = &roms[i];
		if (rd->group == 0) {
			parent = rd;
			mask = rd->type;
			pn = parent->partnumber;
		} else {
			rd->type &= ~ROMTYPE_MASK;
			rd->type |= mask & ROMTYPE_MASK;
			if (rd->partnumber && !pn) {
				TCHAR *newpn;
				if (parent->partnumber == NULL)
					parent->partnumber = my_strdup (_T(""));
				newpn = xcalloc (TCHAR, _tcslen (parent->partnumber) + 1 + _tcslen (rd->partnumber) + 1);
				if (parent->partnumber[0] != '\0') {
					_tcscpy (newpn, parent->partnumber);
					_tcscat (newpn, _T("/"));
				}
				_tcscat (newpn, rd->partnumber);
				xfree ((char *) parent->partnumber);
				parent->partnumber = newpn;
			}
		}
	}
}

/* remove rom entries that need 2 or more roms but not everything required is present */
static void romlist_cleanup(void)
{
	int i = 0;
	while (roms[i].name) {
		struct romdata *rd = &roms[i];
		int grp = rd->group >> 16;
		int ok = 1;
		int j = i;
		int k = i;
		while (rd->name && (rd->group >> 16) == grp && grp > 0) {
			struct romlist *rl = romlist_getrl(rd);
			if (!rl)
				ok = 0;
			rd++;
			j++;
		}
		if (ok == 0) {
			while (i < j && roms[i].name) {
				struct romlist *rl2 = romlist_getrl(&roms[i]);
				if (rl2) {
					size_t cnt = romlist_cnt - (rl2 - rl) - 1;
					write_log(_T("%s '%s' removed from romlist\n"), roms[k].name, rl2->path);
					xfree(rl2->path);
					if (cnt > 0)
						memmove(rl2, rl2 + 1, cnt * sizeof (struct romlist));
					romlist_cnt--;
					romlist_gen++;
				}
				i++;
			}
		}
		if (!roms[i].name) {
			break;
		}
		i++;
	}
#if 0
	for (i = 0; i < romlist_cnt; i++) {
		struct romlist *rll = &rl[i];
		write_log (_T("%d: %08x %s (%s)\n"), rll->rd->id, rll->rd->group, rll->rd->name, rll->path);
	}
#endif
}

struct romlist **getromlistbyident (int ver, int rev, int subver, int subrev, const TCHAR *model, int romflags, bool all)
{
	int i, j, ok, out, max;
	struct romdata *rd;
	struct romlist **rdout, *rltmp;
	void *buf;

	for (i = 0; roms[i].name; i++);
	if (all)
		max = i;
	else
		max = romlist_cnt;
	buf = xmalloc (uae_u8, (sizeof (struct romlist*) + sizeof (struct romlist)) * (i + 1));
	rdout = (struct romlist**)buf;
	rltmp = (struct romlist*)((uae_u8*)buf + (i + 1) * sizeof (struct romlist*));
	out = 0;
	for (i = 0; i < max; i++) {
		ok = 0;
		if (!all)
			rd = rl[i].rd;
		else
			rd = &roms[i];
		if (rd->group)
			continue;
		if (model && !_tcsicmp (model, rd->name))
			ok = 2;
		if ((ver < 0 || rd->ver == ver) && (rev < 0 || rd->rev == rev) && (rd->rev != 0 || rd->ver != 0)) {
			if (subver >= 0) {
				if (rd->subver == subver && (subrev < 0 || rd->subrev == subrev) && rd->subver > 0)
					ok = 1;
			} else {
				ok = 1;
			}
		}
		if (!ok)
			continue;
		if (model && ok < 2) {
			const TCHAR *p = rd->model;
			ok = 0;
			while (p && *p) {
				if (!_tcscmp(rd->model, model)) {
					ok = 1;
					break;
				}
				p = p + _tcslen(p) + 1;
			}
		}
		if (romflags && (rd->type & romflags) == 0)
			ok = 0;
		if (ok) {
			if (all) {
				rdout[out++] = rltmp;
				rltmp->path = NULL;
				rltmp->rd = rd;
				rltmp++;
			} else {
				rdout[out++] = &rl[i];
			}
		}
	}
	if (out == 0) {
		xfree (rdout);
		return NULL;
	}
	for (i = 0; i < out; i++) {
		int v1 = rdout[i]->rd->subver * 1000 + rdout[i]->rd->subrev;
		for (j = i + 1; j < out; j++) {
			int v2 = rdout[j]->rd->subver * 1000 + rdout[j]->rd->subrev;
			if (v1 < v2) {
				struct romlist *rltmp = rdout[j];
				rdout[j] = rdout[i];
				rdout[i] = rltmp;
			}
		}
	}
	rdout[out] = NULL;
	return rdout;
}

struct romdata *getarcadiarombyname (const TCHAR *name)
{
	int i;
	for (i = 0; roms[i].name; i++) {
		if (roms[i].group == 0 && (roms[i].type == ROMTYPE_ARCADIABIOS || roms[i].type == ROMTYPE_ARCADIAGAME)) {
			const TCHAR *p = roms[i].name;
			p = p + _tcslen (p) + 1;
			if (_tcslen (name) >= _tcslen (p) + 4) {
				const TCHAR *p2 = name + _tcslen (name) - _tcslen (p) - 4;
				if (!memcmp (p, p2, _tcslen (p)) && !memcmp (p2 + _tcslen (p2) - 4, ".zip", 4))
					return &roms[i];
			}
		}
	}
	return NULL;
}

struct romlist **getarcadiaroms(int type)
{
	int i, out, max;
	void *buf;
	struct romlist **rdout, *rltmp;
	int romtype1, romtype2;

	if (type) {
		romtype1 = ROMTYPE_ALG;
		romtype2 = ROMTYPE_ALG;
	} else {
		romtype1 = ROMTYPE_ARCADIABIOS;
		romtype2 = ROMTYPE_ARCADIAGAME;
	}

	max = 0;
	for (i = 0; roms[i].name; i++) {
		if (roms[i].group == 0 && (roms[i].type == romtype1 || roms[i].type == romtype2))
			max++;
	}
	buf = xmalloc (uae_u8, (sizeof (struct romlist*) + sizeof (struct romlist)) * (max + 1));
	rdout = (struct romlist**)buf;
	rltmp = (struct romlist*)((uae_u8*)buf + (max + 1) * sizeof (struct romlist*));
	out = 0;
	for (i = 0; roms[i].name; i++) {
		if (roms[i].group == 0 && (roms[i].type == romtype1 || roms[i].type == romtype2)) {
			rdout[out++] = rltmp;
			rltmp->path = NULL;
			rltmp->rd = &roms[i];
			rltmp++;
		}
	}
	rdout[out] = NULL;
	return rdout;
}


static int kickstart_checksum_do (uae_u8 *mem, int size)
{
	uae_u32 cksum = 0, prevck = 0;
	int i;
	for (i = 0; i < size; i += 4) {
		uae_u32 data = mem[i] * 65536 * 256 + mem[i + 1] * 65536 + mem[i + 2] * 256 + mem[i + 3];
		cksum += data;
		if (cksum < prevck)
			cksum++;
		prevck = cksum;
	}
	return cksum == 0xffffffff;
}

static int kickstart_checksum_more_do (uae_u8 *mem, int size)
{
	uae_u8 *p = mem + size - 20;
	if (p[0] != ((size >> 24) & 0xff) || p[1] != ((size >> 16) & 0xff)
		|| p[2] != ((size >> 8) & 0xff) || p[3] != ((size >> 0) & 0xff))
		return 0;
	if (size == 524288) {
		if (mem[0] != 0x11 || mem[1] != 0x14)
			return 0;
	} else if (size == 262144) {
		if (mem[0] != 0x11 || mem[1] != 0x11)
			return 0;
	} else {
		return 0;
	}
	return kickstart_checksum_do(mem, size);
}

#define ROM_KEY_NUM 4
struct rom_key {
	uae_u8 *key;
	int size;
};

static struct rom_key keyring[ROM_KEY_NUM];

static void addkey (uae_u8 *key, int size, const TCHAR *name)
{
	int i;

	//write_log (_T("addkey(%08x,%d,'%s')\n"), key, size, name);
	if (key == NULL || size == 0) {
		xfree (key);
		return;
	}
	for (i = 0; i < ROM_KEY_NUM; i++) {
		if (keyring[i].key && keyring[i].size == size && !memcmp (keyring[i].key, key, size)) {
			xfree (key);
			//write_log (_T("key already in keyring\n"));
			return;
		}
	}
	for (i = 0; i < ROM_KEY_NUM; i++) {
		if (keyring[i].key == NULL)
			break;
	}
	if (i == ROM_KEY_NUM) {
		xfree (key);
		//write_log (_T("keyring full\n"));
		return;
	}
	keyring[i].key = key;
	keyring[i].size = size;
}

void addkeyfile (const TCHAR *path)
{
	struct zfile *f;
	int keysize;
	uae_u8 *keybuf;

	f = zfile_fopen (path, _T("rb"), ZFD_NORMAL);
	if (!f)
		return;
	zfile_fseek (f, 0, SEEK_END);
	keysize = zfile_ftell32(f);
	if (keysize > 0) {
		zfile_fseek (f, 0, SEEK_SET);
		keybuf = xmalloc (uae_u8, keysize);
		zfile_fread (keybuf, 1, keysize, f);
		addkey (keybuf, keysize, path);
	}
	zfile_fclose (f);
}

void addkeydir(const TCHAR *path)
{
	TCHAR tmp[MAX_DPATH];

	_tcscpy(tmp, path);
	if (zfile_exists(tmp)) {
		int i;
		for (i = uaetcslen(tmp) - 1; i > 0; i--) {
			if (tmp[i] == '\\' || tmp[i] == '/')
				break;
		}
		tmp[i] = 0;
	}
	_tcscat(tmp, _T("/"));
	_tcscat(tmp, _T("rom.key"));
	addkeyfile(tmp);
}

int get_keyring (void)
{
	int i, num = 0;
	for (i = 0; i < ROM_KEY_NUM; i++) {
		if (keyring[i].key)
			num++;
	}
	return num;
}

int load_keyring (struct uae_prefs *p, const TCHAR *path)
{
	uae_u8 *keybuf;
	int keysize;
	TCHAR tmp[MAX_DPATH], *d;
	int keyids[] = { 0, 48, 73, -1 };
	int cnt, i;

	free_keyring ();
	keybuf = target_load_keyfile (p, path, &keysize, tmp);
	addkey (keybuf, keysize, tmp);
	for (i = 0; keyids[i] >= 0; i++) {
		struct romdata *rd = getromdatabyid (keyids[i]);
		TCHAR *s;
		if (rd) {
			s = romlist_get (rd);
			if (s)
				addkeyfile (s);
		}
	}

	cnt = 0;
	for (;;) {
		keybuf = NULL;
		keysize = 0;
		tmp[0] = 0;
		switch (cnt)
		{
		case 0:
			if (path)
				_tcscpy (tmp, path);
			break;
		case 1:
			_tcscat (tmp, _T("rom.key"));
			break;
		case 2:
			if (p) {
				_tcscpy (tmp, p->path_rom.path[0]);
				_tcscat (tmp, _T("rom.key"));
			}
			break;
		case 3:
			_tcscpy (tmp, _T("roms/rom.key"));
			break;
		case 4:
			_tcscpy (tmp, home_dir.c_str());
#ifdef AMIBERRY
			// Ensure we have a trailing slash
			if (home_dir.back() != '/' && home_dir.back() != '\\') {
				_tcscat(tmp, _T("/"));
			}
#endif
			_tcscat (tmp, _T("rom.key"));
			break;
		case 5:
			_sntprintf (tmp, sizeof tmp, _T("%s../shared/rom/rom.key"), home_dir.c_str());
			break;
		case 6:
			if (p) {
				for (i = 0; uae_archive_extensions[i]; i++) {
					if (_tcsstr (p->romfile, uae_archive_extensions[i]))
						break;
				}
				if (!uae_archive_extensions[i]) {
					_tcscpy (tmp, p->romfile);
					d = _tcsrchr (tmp, '/');
					if (!d)
						d = _tcsrchr (tmp, '\\');
					if (d)
						_tcscpy (d + 1, _T("rom.key"));
				}
			}
			break;
		case 7:
			return get_keyring ();
		}
		cnt++;
		if (!tmp[0])
			continue;
		addkeyfile (tmp);
	}
}
void free_keyring (void)
{
	int i;
	for (i = 0; i < ROM_KEY_NUM; i++)
		xfree (keyring[i].key);
	memset (keyring, 0, sizeof (struct rom_key) * ROM_KEY_NUM);
}

struct romdata *getromdatabyname (const TCHAR *name)
{
	TCHAR tmp[MAX_DPATH];
	int i = 0;
	while (roms[i].name) {
		if (!roms[i].group) {
			getromname (&roms[i], tmp);
			if (!_tcscmp (tmp, name) || !_tcscmp (roms[i].name, name))
				return &roms[i];
		}
		i++;
	}
	return 0;
}

struct romdata *getromdatabytype (int romtype)
{
	int i = 0;
	while (roms[i].name) {
		if (romtype == roms[i].type && roms[i].group == 0)
			return &roms[i];
		i++;
	}
	return 0;
}

struct romdata *getromdatabyid (int id)
{
	int i = 0;
	while (roms[i].name) {
		if (id == roms[i].id && roms[i].group == 0)
			return &roms[i];
		i++;
	}
	return 0;
}

struct romdata *getromdatabyidgroup (int id, int group, int subitem)
{
	int i = 0;
	group = (group << 16) | subitem;
	while (roms[i].name) {
		if (id == roms[i].id && roms[i].group == group)
			return &roms[i];
		i++;
	}
	return 0;
}

STATIC_INLINE int notcrc32 (uae_u32 crc32)
{
	if (crc32 == 0xffffffff || crc32 == 0x00000000)
		return 1;
	return 0;
}

struct romdata *getromdatabycrc (uae_u32 crc32, bool allowgroup)
{
	int i = 0;
	while (roms[i].name) {
		if (roms[i].group == 0 && crc32 == roms[i].crc32 && !notcrc32(crc32))
			return &roms[i];
		i++;
	}
	if (allowgroup) {
		i = 0;
		while (roms[i].name) {
			if (roms[i].group && crc32 == roms[i].crc32 && !notcrc32(crc32))
				return &roms[i];
			i++;
		}
	}
	return 0;
}
struct romdata *getromdatabycrc (uae_u32 crc32)
{
	return getromdatabycrc (crc32, false);
}

static int cmpsha1 (const uae_u8 *s1, const struct romdata *rd)
{
	int i;

	for (i = 0; i < SHA1_SIZE / 4; i++) {
		uae_u32 v1 = (s1[0] << 24) | (s1[1] << 16) | (s1[2] << 8) | (s1[3] << 0);
		uae_u32 v2 = rd->sha1[i];
		if (v1 != v2)
			return -1;
		s1 += 4;
	}
	return 0;
}

struct romdata *getfrombydefaultname(const TCHAR *name, int size)
{
	int i = 0;
	while (roms[i].name) {
		if (notcrc32(roms[i].crc32) && size >= roms[i].size && roms[i].defaultfilename && !_tcsicmp(roms[i].defaultfilename, name)) {
			return &roms[i];
		}
		i++;
	}
	return NULL;
}

static struct romdata *checkromdata (const uae_u8 *sha1, int size, uae_u32 mask)
{
	int i = 0;
	while (roms[i].name) {
		if (roms[i].crc32 != 0xffffffff && roms[i].size >= size) {
			if (roms[i].type & mask) {
				if (!cmpsha1 (sha1, &roms[i]))
					return &roms[i];
			}
		}
		i++;
	}
	return NULL;
}

int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size)
{
	int cnt, t, i;

	for (i = ROM_KEY_NUM - 1; i >= 0; i--) {
		uae_u8 sha1[SHA1_SIZE];
		struct romdata *rd;
		int keysize = keyring[i].size;
		uae_u8 *key = keyring[i].key;
		if (!key)
			continue;
		for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize)  {
			mem[cnt] ^= key[t];
			if (real_size == cnt + 1)
				t = keysize - 1;
		}
		if ((mem[2] == 0x4e && mem[3] == 0xf9) || (mem[0] == 0x11 && (mem[1] == 0x11 || mem[1] == 0x14))) {
			cloanto_rom = 1;
			return 1;
		}
		get_sha1 (mem, size, sha1);
		rd = checkromdata (sha1, size, -1);
		if (rd) {
			if (rd->cloanto)
				cloanto_rom = 1;
			return 1;
		}
		if (i == 0)
			break;
		for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize)  {
			mem[cnt] ^= key[t];
			if (real_size == cnt + 1)
				t = keysize - 1;
		}
	}
	return 0;
}

static int decode_rekick_rom_do (uae_u8 *mem, int size, int real_size)
{
	uae_u32 d1 = 0xdeadfeed, d0;
	int i;

	for (i = 0; i < size / 8; i++) {
		d0 = ((mem[i * 8 + 0] << 24) | (mem[i * 8 + 1] << 16) | (mem[i * 8 + 2] << 8) | mem[i * 8 + 3]);
		d1 = d1 ^ d0;
		mem[i * 8 + 0] = d1 >> 24;
		mem[i * 8 + 1] = d1 >> 16;
		mem[i * 8 + 2] = d1 >> 8;
		mem[i * 8 + 3] = d1;
		d1 = ((mem[i * 8 + 4] << 24) | (mem[i * 8 + 5] << 16) | (mem[i * 8 + 6] << 8) | mem[i * 8 + 7]);
		d0 = d0 ^ d1;
		mem[i * 8 + 4] = d0 >> 24;
		mem[i * 8 + 5] = d0 >> 16;
		mem[i * 8 + 6] = d0 >> 8;
		mem[i * 8 + 7] = d0;
	}
	return 1;
}

int decode_rom (uae_u8 *mem, int size, int mode, int real_size)
{
	if (mode == 1) {
		if (!decode_cloanto_rom_do (mem, size, real_size)) {
#ifndef SINGLEFILE
			notify_user (NUMSG_NOROMKEY);
#endif
			return 0;
		}
		return 1;
	} else if (mode == 2) {
		decode_rekick_rom_do (mem, size, real_size);
		return 1;
	}
	return 0;
}

struct romdata *getromdatabydata (uae_u8 *rom, int size)
{
	uae_u8 sha1[SHA1_SIZE];
	uae_u8 tmp[4];
	uae_u8 *tmpbuf = NULL;
	struct romdata *ret = NULL;

	if (size > 11 && !memcmp (rom, "AMIROMTYPE1", 11)) {
		uae_u8 *tmpbuf = xmalloc (uae_u8, size);
		int tmpsize = size - 11;
		memcpy (tmpbuf, rom + 11, tmpsize);
		decode_rom (tmpbuf, tmpsize, 1, tmpsize);
		rom = tmpbuf;
		size = tmpsize;
	}
#if 0
	if (size > 0x6c + 524288 && !memcmp (rom, "AMIG", 4)) {
		uae_u8 *tmpbuf = (uae_u8*)xmalloc (uae_u8, size);
		int tmpsize = size - 0x6c;
		memcpy (tmpbuf, rom + 0x6c, tmpsize);
		decode_rom (tmpbuf, tmpsize, 2, tmpsize);
		rom = tmpbuf;
		size = tmpsize;
	}
#endif
	get_sha1 (rom, size, sha1);
	ret = checkromdata(sha1, size, -1);
	if (!ret) {
		get_sha1 (rom, size / 2, sha1);
		ret = checkromdata (sha1, size / 2, -1);
		if (!ret) {
			/* ignore AR2/3 IO-port range until we have full dump */
			memcpy (tmp, rom, 4);
			memset (rom, 0, 4);
			get_sha1 (rom, size, sha1);
			ret = checkromdata (sha1, size, ROMTYPE_AR2);
			memcpy (rom, tmp, 4);
			// BlizzardPPC/CyberStormMK3/PPC images have config data
			if (!ret && (size == 131072 || size == 524288)) {
				uae_u8 *rt = xmalloc(uae_u8, 524288);
				if (rt) {
					memcpy(rt, rom, size);
					memset(rt + 0x10, 0, 0x20);
					get_sha1(rt, 0x1c000, sha1);
					ret = checkromdata(sha1, size, -1);
					if (!ret && size == 524288) {
						get_sha1(rt, 0x50000, sha1);
						ret = checkromdata(sha1, size, -1);
					}
					xfree(rt);
				}
			}
		}
	}
	xfree (tmpbuf);
	return ret;
}

struct romdata *getromdatabyzfile (struct zfile *f)
{
	int pos, size;
	uae_u8 *p;
	struct romdata *rd;

	pos = zfile_ftell32(f);
	zfile_fseek (f, 0, SEEK_END);
	size = zfile_ftell32(f);
	if (size > 2048 * 1024)
		return NULL;
	p = xmalloc (uae_u8, size);
	if (!p)
		return NULL;
	memset (p, 0, size);
	zfile_fseek (f, 0, SEEK_SET);
	zfile_fread (p, 1, size, f);
	zfile_fseek (f, pos, SEEK_SET);
	rd = getromdatabydata (p, size);
	xfree (p);
	return rd;
}

void getromname	(const struct romdata *rd, TCHAR *name)
{
	name[0] = 0;
	if (!rd)
		return;
	while (rd->group)
		rd--;
	_tcscat (name, rd->name);
	if ((rd->subrev || rd->subver) && rd->subver != rd->ver)
		_sntprintf (name + _tcslen (name), sizeof name + _tcslen (name), _T(" rev %d.%d"), rd->subver, rd->subrev);
	if (rd->size > 0)
		_sntprintf (name + _tcslen (name), sizeof name + _tcslen (name), _T(" (%dk)"), (rd->size + 1023) / 1024);
	if (rd->partnumber && rd->partnumber[0] != '\0')
		_sntprintf (name + _tcslen (name), sizeof name + _tcslen (name), _T(" [%s]"), rd->partnumber);
}

struct romlist *getromlistbyromdata (const struct romdata *rd)
{
	int ids[2];

	ids[0] = rd->id;
	ids[1] = -1;
	return getromlistbyids(ids, NULL);
}

struct romlist *getromlistbyromtype(uae_u32 romtype, const TCHAR *romname)
{
	int i = 0;
	while (roms[i].name) {
		if (roms[i].type == romtype) {
			struct romdata *rd = &roms[i];
			for (int j = 0; j < romlist_cnt; j++) {
				if (rl[j].rd->id == rd->id) {
					if (romname) {
						if (my_issamepath(rl[j].path, romname))
							return &rl[j];
					} else {
						return &rl[j];
					}
				}
			}
		}
		i++;
	}
	return NULL;
}

struct romlist *getromlistbyids (const int *ids, const TCHAR *romname)
{
	struct romdata *rd;
	int i, j;

	i = 0;
	if (romname) {
		while (ids[i] >= 0) {
			rd = getromdatabyid (ids[i]);
			if (rd) {
				for (j = 0; j < romlist_cnt; j++) {
					if (rl[j].rd->id == rd->id) {
						if (my_issamepath(rl[j].path, romname))
							return &rl[j];
					}
				}
			}
			i++;
		}
	}
	i = 0;
	while (ids[i] >= 0) {
		rd = getromdatabyid (ids[i]);
		if (rd) {
			for (j = 0; j < romlist_cnt; j++) {
				if (rl[j].rd->id == rd->id)
					return &rl[j];
			}
		}
		i++;
	}
	return NULL;
}

struct romdata *getromdatabyids (const int *ids)
{
	struct romdata *rd;
	int i;

	i = 0;
	while (ids[i] >= 0) {
		rd = getromdatabyid (ids[i]);
		if (rd)
			return rd;
		i++;
	}
	return NULL;
}

void romwarning(int romtype)
{
	int i, exp;
	TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
	TCHAR tmp3[MAX_DPATH];

	if (!romtype)
		return;
	exp = 0;
	tmp2[0] = 0;
	i = 0;
	while (roms[i].name) {
		struct romdata *rd = &roms[i];
		if (rd->type == romtype) {
			getromname (rd, tmp1);
			_tcscat (tmp2, _T("- "));
			_tcscat (tmp2, tmp1);
			_tcscat (tmp2, _T("\n"));
			if (rd->type & (ROMTYPE_SCSI | ROMTYPE_CPUBOARD | ROMTYPE_CD32CART))
				exp++;
		}
		i++;
	}
	translate_message (exp ? NUMSG_EXPROMNEED : NUMSG_ROMNEED, tmp3);
	gui_message (tmp3, tmp2);
}

void romwarning (const int *ids)
{
	int i, exp;
	TCHAR tmp1[MAX_DPATH], tmp2[MAX_DPATH];
	TCHAR tmp3[MAX_DPATH];

	if (ids[0] == -1)
		return;
	exp = 0;
	tmp2[0] = 0;
	i = 0;
	while (ids[i] >= 0) {
		struct romdata *rd = getromdatabyid (ids[i]);
		if (!(rd->type & ROMTYPE_NONE)) {
			getromname (rd, tmp1);
			_tcscat (tmp2, _T("- "));
			_tcscat (tmp2, tmp1);
			_tcscat (tmp2, _T("\n"));
			if (rd->type & (ROMTYPE_SCSI | ROMTYPE_CPUBOARD | ROMTYPE_CD32CART))
				exp++;
		}
		i++;
	}
	translate_message (exp ? NUMSG_EXPROMNEED : NUMSG_ROMNEED, tmp3);
	gui_message (tmp3, tmp2);
}


static void byteswap(uae_u8* buf, int size)
{
	int i;
	for (i = 0; i < size; i += 2) {
		uae_u8 t = buf[i];
		buf[i] = buf[i + 1];
		buf[i + 1] = t;
	}
}
static void halfswap(uae_u8* buf, int size)
{
	for (int i = 0; i < size / 2; i++) {
		int j = size / 2 + i;
		uae_u8 t = buf[i];
		buf[i] = buf[j];
		buf[j] = t;
	}
}
static void wordbyteswap (uae_u8 *buf, int size)
{
	int i;
	for (i = 0; i < size; i += 4) {
		uae_u8 t;
		t = buf[i + 0];
		buf[i + 0] = buf[i + 2];
		buf[i + 2] = t;
		t = buf[i + 1];
		buf[i + 1] = buf[i + 3];
		buf[i + 3] = t;
	}
}

static void mergecd32 (uae_u8 *dst, uae_u8 *src, int size)
{
	int i, k;
	k = 0;
	for (i = 0; i < size / 2; i += 2) {
		int j = i + size / 2;
		dst[k + 1] = src[i + 0];
		dst[k + 0] = src[i + 1];
		dst[k + 3] = src[j + 0];
		dst[k + 2] = src[j + 1];
		k += 4;
	}
#if 0
	{
		struct zfile *f;
		f = zfile_fopen ("c:\\d\\1.rom","wb", ZFD_NORMAL);
		zfile_fwrite (dst, 1, size, f);
		zfile_fclose(f);
	}
#endif
}

static void descramble (const struct romdata *rd, uae_u8 *data, int size, int odd)
{
	int flags = rd->type;

	if (flags & (ROMTYPE_NORDIC | ROMTYPE_XPOWER))
		descramble_nordicpro (data, size, odd);
}

static int read_rom_file(uae_u8 *buf, const struct romdata *rd, bool rw)
{
	struct zfile *zf;
	struct romlist *rl = romlist_getrl (rd);
	uae_char tmp[11];

	if (!rl || rl->path[0] == '\0')
		return 0;
	zf = zfile_fopen (rl->path, rw ? _T("rb+") : _T("rb"), ZFD_NORMAL);
	if (!zf)
		return 0;
	addkeydir (rl->path);
	zfile_fread (tmp, sizeof tmp, 1, zf);
	if (!memcmp (tmp, "AMIROMTYPE1", sizeof tmp)) {
		zfile_fread (buf, rd->size, 1, zf);
		decode_cloanto_rom_do (buf, rd->size, rd->size);
	} else {
		memcpy (buf, tmp, sizeof tmp);
		zfile_fread (buf + sizeof tmp, rd->size - sizeof (tmp), 1, zf);
	}
	zfile_fclose (zf);
	return 1;
}

#if SAVE_ROM
static void save_rom(uae_u8 *rom, int size)
{
	struct zfile *f;
	f = zfile_fopen (_T("c:\\temp\\1.rom"), _T("wb"));
	zfile_fwrite (rom, 1, size, f);
	zfile_fclose(f);
}
#endif

static void alg_descramble(struct romdata *rd, uae_u8 *buf, int size)
{
	if (rd->id == 197) {
		// ALG Platoon
		uae_u8 *tmp = xmalloc(uae_u8, size);
		if (tmp) {
			memcpy(tmp, buf, size);
			static const int platoon[] = { 0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15,16,24,20,28,18,26,22,30,17,25,21,29,19,27,23,31 };
			for (int i = 0; i < 32; i++) {
				memcpy(buf + i * 0x2000, tmp + platoon[i] * 0x2000, 0x2000);
			}
			xfree(tmp);
		}
	} else if (rd->id == 182) {
		// ALG Space Pirates (PAL R4?)
		uae_u8 *tmp = xmalloc(uae_u8, size);
		if (tmp) {
			memcpy(tmp, buf, size);
			static const int sp[] = { 33,32,34,35,49,48,50,51,45,44,46,47,61,60,62,63,37,36,38,39,53,52,54,55,41,40,42,43,57,56,58,59,
									  33,32,34,35,49,48,50,51,45,44,46,47,61,60,62,63,37,36,38,39,53,52,54,55,41,40,42,43,57,56,58,59 };
			for (int i = 0; i < 64; i++) {
				memcpy(buf + i * 0x1000, tmp + sp[i] * 0x1000, 0x1000);
			}
			xfree(tmp);
		}
	} else if ((rd->id == 184) || (rd->id == 185)) {
		// ALG Johnny Rock (PAL R3)
		uae_u8 *tmp = xmalloc(uae_u8, size);
		if (tmp) {
			memcpy(tmp, buf, size);
			static const int wsjr[] = { 0,1,3,2,4,5,7,6,8,9,11,10,12,13,15,14,16,17,19,18,20,21,23,22,24,25,27,26,28,29,31,30 };
			for (int i = 0; i < 32; i++) {
				memcpy(buf + i * 0x1000, tmp + wsjr[i] * 0x1000, 0x1000);
			}
			xfree(tmp);
		}
	} else if ((rd->id == 175) || (rd->id == 272)) {
		// ALG Mad Dog (Original Rev A board, PAL R1)
		uae_u8 *tmp = xmalloc(uae_u8, size);
		if (tmp) {
			memcpy(tmp, buf, size);
			static const int mdm[] = { 0,1,3,2,4,5,7,6,12,13,15,14,8,9,11,10,16,17,19,18,20,21,23,22,28,29,31,30,24,25,27,26 };
			for (int i = 0; i < 32; i++) {
				memcpy(buf + i * 0x1000, tmp + mdm[i] * 0x1000, 0x1000);
			}
			xfree(tmp);
		}
	}
}

struct zfile *read_rom(struct romdata *prd, bool rw)
{
	struct romdata *rd2 = prd;
	struct romdata *rd = prd;
	struct romdata *rdpair = NULL;
	const TCHAR *name;
	int id = rd->id;
	uae_u32 crc32;
	int size;
	uae_u8 *buf, *buf2;

	/* find parent node */
	for (;;) {
		if (rd2 == &roms[0])
			break;
		if (rd2[-1].id != id)
			break;
		rd2--;
	}
	
	size = rd2->size;
	crc32 = rd2->crc32;
	name = rd->name;
	buf = xmalloc (uae_u8, size * 2);
	memset (buf, 0xff, size * 2);
	if (!buf)
		return NULL;
	buf2 = buf + size;
	while (rd->id == id) {
		int i, j, add;
		int ok = 0;
		uae_u32 flags = rd->type;
		int odd = (flags & ROMTYPE_ODD) ? 1 : 0;

		add = 0;
		for (i = 0; i < 2; i++) {
			memset (buf, 0, size);
			if (!(flags & (ROMTYPE_EVEN | ROMTYPE_ODD))) {
				read_rom_file(buf, rd, rw);
				if (flags & ROMTYPE_CD32) {
					memcpy (buf2, buf, size);
					mergecd32 (buf, buf2, size);
				}
				add = 1;
				i++;
			} else if (flags & ROMTYPE_QUAD) {
				if (i == 0) {
					for (int k = 0; k < 4; k++) {
						read_rom_file(buf2, rd2 + k + 1, rw);
						for (j = 0; j < size; j += 4)
							buf[j + k] = buf2[j / 4];
					}
				} else {
					for (int kk = 0; kk < 2; kk++) {
						for (int k = 0; k < 2; k++) {
							read_rom_file(buf2, rd2 + k + kk * 2 + 1, rw);
							for (j = 0; j < size / 2; j += 2) {
								buf[j + k + kk * (rd2->size / 2)] = buf2[j / 2];
							}
						}
					}
				}
				add = 4;
			} else {
				int romsize = size / 2;
				if (i)
					odd = !odd;
				if (rd->id == rd[1].id)
					rdpair = &rd[1];
				else if (rd != roms)
					rdpair = &rd[-1];
				else
					rdpair = rd;
				if (flags & ROMTYPE_8BIT) {
					read_rom_file(buf2, rd, rw);
					if (flags & ROMTYPE_BYTESWAP)
						byteswap (buf2, romsize);
					if (flags & ROMTYPE_SCRAMBLED)
						descramble (rd, buf2, romsize, odd);
					for (j = 0; j < size; j += 2)
						buf[j + odd] = buf2[j / 2];
					read_rom_file(buf2, rdpair, rw);
					if (flags & ROMTYPE_BYTESWAP)
						byteswap (buf2, romsize);
					if (flags & ROMTYPE_SCRAMBLED)
						descramble (rd + 1, buf2, romsize, !odd);
					for (j = 0; j < size; j += 2)
						buf[j + (1 - odd)] = buf2[j / 2];
				} else {
					read_rom_file(buf2, rd, rw);
					if (flags & ROMTYPE_BYTESWAP)
						byteswap (buf2, romsize);
					if (flags & ROMTYPE_SCRAMBLED)
						descramble (rd, buf2, romsize, odd);
					for (j = 0; j < size; j += 4) {
						buf[j + 2 * odd + 0] = buf2[j / 2 + 0];
						buf[j + 2 * odd + 1] = buf2[j / 2 + 1];
					}
					read_rom_file(buf2, rdpair, rw);
					if (flags & ROMTYPE_BYTESWAP)
						byteswap (buf2, romsize);
					if (flags & ROMTYPE_SCRAMBLED)
						descramble (rd + 1, buf2, romsize, !odd);
					for (j = 0; j < size; j += 4) {
						buf[j + 2 * (1 - odd) + 0] = buf2[j / 2 + 0];
						buf[j + 2 * (1 - odd) + 1] = buf2[j / 2 + 1];
					}
				}
				add = 2;
			}

#if SAVE_ROM
			save_rom(buf, size);
#endif

			if (notcrc32(crc32) || get_crc32(buf, size) == crc32) {
				ok = 1;
			}
			if (!ok && (rd->type & ROMTYPE_AR)) {
				uae_u8 tmp[2];
				tmp[0] = buf[0];
				tmp[1] = buf[1];
				buf[0] = buf[1] = 0;
				if (get_crc32(buf, size) == crc32)
					ok = 1;
				buf[0] = tmp[0];
				buf[1] = tmp[1];
			}
			if (!ok) {
				/* perhaps it is byteswapped without byteswap entry? */
				byteswap (buf, size);
				if (get_crc32(buf, size) == crc32) {
					ok = 1;
				}
				if (!ok) {
					byteswap(buf, size);
					// CD32 ROM with lower and upper 512k swapped?
					if (size == 2 * 512 * 1024) {
						halfswap(buf, size);
						if (get_crc32(buf, size) == crc32) {
							ok = 1;
						} else {
							halfswap(buf, size);
						}
					}
				}
			}
			if (ok) {
				alg_descramble(rd, buf, size);
			}
			if (ok) {
				struct zfile *zf = zfile_fopen_empty (NULL, name, size);
				if (zf) {
					zfile_fwrite (buf, size, 1, zf);
					zfile_fseek (zf, 0, SEEK_SET);
				}
				xfree (buf);
				return zf;
			}
		}
		rd += add;

	}
	xfree (buf);
	return NULL;
}

struct zfile *rom_fopen(const TCHAR *name, const TCHAR *mode, int mask)
{
	return zfile_fopen (name, mode, mask);
}

static struct zfile *rom_fopen2(const TCHAR *name, const TCHAR *mode, int mask)
{
	struct zfile *f2 = NULL;
	struct zfile *f = rom_fopen(name, mode, mask);
	if (f) {
		int size = zfile_size32(f);
		if (size == 524288 * 2 || size == 524288 || size == 262144) {
			uae_u8 *newrom = NULL;
			uae_u8 *tmp1 = xcalloc(uae_u8, 524288 * 2);
			uae_u8 *tmp2 = xcalloc(uae_u8, 524288 * 2);
			for (;;) {
				if (zfile_fread(tmp1, 1, size, f) != size)
					break;
				if (size == 524288 * 2) {
					// Perhaps it is 1M interleaved ROM image?
					mergecd32(tmp2, tmp1, 524288 * 2);
					if (kickstart_checksum_more_do(tmp2, 524288) && kickstart_checksum_more_do(tmp2 + 524288, 524288)) {
						newrom = tmp2;
						break;
					}
					// byteswapped KS ROM?
					byteswap(tmp1, 524288 * 2);
					if (kickstart_checksum_more_do(tmp1, 524288) && kickstart_checksum_more_do(tmp1 + 524288, 524288)) {
						newrom = tmp1;
						break;
					} else {
						byteswap(tmp1, 524288 * 2);
						wordbyteswap(tmp1, 524288 * 2);
						if (kickstart_checksum_more_do(tmp1, 524288) && kickstart_checksum_more_do(tmp1 + 524288, 524288)) {
							newrom = tmp1;
							break;
						}
					}
				} else {
					// byteswapped KS ROM?
					byteswap(tmp1, size);
					if (kickstart_checksum_more_do(tmp1, size)) {
						newrom = tmp1;
						break;
					} else {
						byteswap(tmp1, size);
						wordbyteswap(tmp1, size);
						if (kickstart_checksum_more_do(tmp1, size)) {
							newrom = tmp1;
							break;
						}
					}
				}
				break;
			}
			if (newrom) {
				f2 = zfile_fopen_data(zfile_getname(f), size, newrom);
			}
			xfree(tmp2);
			xfree(tmp1);
		}
	}
	if (f2) {
		zfile_fclose(f);
		f = f2;
	}
	if (f) {
		zfile_fseek(f, 0, SEEK_SET);
	}
	return f;
}

struct zfile *read_rom_name(const TCHAR *filename, bool rw)
{
	struct zfile *f;

	for (int i = 0; i < romlist_cnt; i++) {
		if (my_issamepath(filename, rl[i].path)) {
			struct romdata *rd = rl[i].rd;
			f = read_rom (rd);
			if (f)
				return f;
		}
	}
	f = rom_fopen2(filename, rw ? _T("rb+") : _T("rb"), ZFD_NORMAL);
	if (f) {
		uae_u8 tmp[11] = { 0 };
		zfile_fread(tmp, sizeof tmp, 1, f);
		if (!memcmp(tmp, "AMIROMTYPE1", sizeof tmp)) {
			struct zfile *df;
			int size;
			uae_u8 *buf;
			addkeydir(filename);
			zfile_fseek(f, 0, SEEK_END);
			size = zfile_ftell32(f) - sizeof tmp;
			zfile_fseek(f, sizeof tmp, SEEK_SET);
			buf = xmalloc(uae_u8, size);
			zfile_fread(buf, size, 1, f);
			df = zfile_fopen_empty(f, _T("tmp.rom"), size);
			decode_cloanto_rom_do(buf, size, size);
			zfile_fwrite(buf, size, 1, df);
			zfile_fclose(f);
			xfree(buf);
			zfile_fseek(df, 0, SEEK_SET);
			f = df;
		} else {
			zfile_fseek (f, -((int)sizeof tmp), SEEK_CUR);
		}
	}
	return f;
}

struct zfile *read_rom_name_guess (const TCHAR *filename, TCHAR *out)
{
	int i, j;
	struct zfile *f;
	const TCHAR *name;

	for (i = uaetcslen(filename) - 1; i >= 0; i--) {
		if (filename[i] == '/' || filename[i] == '\\')
			break;
	}
	if (i < 0)
		return NULL;
	name = &filename[i];

	for (i = 0; i < romlist_cnt; i++) {
		TCHAR *n = rl[i].path;
		for (j = uaetcslen(n) - 1; j >= 0; j--) {
			if (n[j] == '/' || n[j] == '\\')
				break;
		}
		if (j < 0)
			continue;
		if (!_tcsicmp(name, n + j)) {
			struct romdata *rd = rl[i].rd;
			f = read_rom (rd);
			if (f) {
				write_log (_T("ROM %s not found, using %s\n"), filename, rl[i].path);
				_tcscpy(out, rl[i].path);
				return f;
			}
		}
	}
	return NULL;
}

void kickstart_fix_checksum (uae_u8 *mem, int size)
{
	uae_u32 cksum = 0, prevck = 0;
	int i, ch = size == 524288 ? 0x7ffe8 : (size == 262144 ? 0x3ffe8 : 0x3e);

	mem[ch] = 0;
	mem[ch + 1] = 0;
	mem[ch + 2] = 0;
	mem[ch + 3] = 0;
	for (i = 0; i < size; i+=4) {
		uae_u32 data = (mem[i] << 24) | (mem[i + 1] << 16) | (mem[i + 2] << 8) | mem[i + 3];
		cksum += data;
		if (cksum < prevck)
			cksum++;
		prevck = cksum;
	}
	cksum ^= 0xffffffff;
	mem[ch++] = cksum >> 24;
	mem[ch++] = cksum >> 16;
	mem[ch++] = cksum >> 8;
	mem[ch++] = cksum >> 0;
}

int kickstart_checksum (uae_u8 *mem, int size)
{
	if (!kickstart_checksum_do (mem, size)) {
#ifndef	SINGLEFILE
		notify_user (NUMSG_KSROMCRCERROR);
#endif
		return 0;
	}
	return 1;
}

static void clean_path(TCHAR *s)
{
	for (;;) {
		size_t v = _tcscspn(s, _T("?:\t\r\n"));
		if (s[v] == 0) {
			break;
		}
		memmove(s + v, s + v + 1, (uaetcslen(s + v + 1) + 1) * sizeof(TCHAR));
	}
}

int configure_rom (struct uae_prefs *p, const int *rom, int msg)
{
	struct romdata *rd;
	TCHAR *path = 0;
	int i;

	if (rom[0] < 0)
		return 1;
	i = 0;
	while (rom[i] >= 0) {
		rd = getromdatabyid (rom[i]);
		if (!rd) {
			i++;
			continue;
		}
		path = romlist_get (rd);
		if (path)
			break;
		i++;
	}
	if (!path) {
		if (msg)
			romwarning(rom);
		return 0;
	}
	if (rd->type & (ROMTYPE_KICK | ROMTYPE_KICKCD32))
		_tcscpy (p->romfile, path);
	if ((rd->type & (ROMTYPE_EXTCD32 | ROMTYPE_EXTCDTV | ROMTYPE_ARCADIABIOS | ROMTYPE_ALG)) && !(rd->type & ROMTYPE_KICKCD32))
		_tcscpy (p->romextfile, path);
	if (rd->type & ROMTYPE_CD32CART) {
		_tcscpy(p->cartfile, path);
		struct boardromconfig *brc = get_device_rom_new(p, ROMTYPE_CD32CART, 0, NULL);
		if (brc)
			_tcscpy(brc->roms[0].romfile, p->cartfile);
	}
	if ((rd->type & ROMTYPE_ARCADIAGAME) ||
		rd->type == ROMTYPE_HRTMON || rd->type == ROMTYPE_XPOWER || rd->type ==  ROMTYPE_NORDIC || rd->type == ROMTYPE_AR || rd->type == ROMTYPE_SUPERIV)
		_tcscpy (p->cartfile, path);
	if (rd->type & ROMTYPE_CPUBOARD)
		set_device_rom(p, path, ROMTYPE_CPUBOARD, 0);

	if (rd->type & (ROMTYPE_ARCADIAGAME | ROMTYPE_ALG)) {
		get_nvram_path(p->flashfile, sizeof(p->flashfile) / sizeof(TCHAR));
		_sntprintf(p->flashfile + _tcslen(p->flashfile), sizeof p->flashfile / sizeof(TCHAR) - _tcslen(p->flashfile), _T("%s.nvr"), rd->name);
		clean_path(p->flashfile);
	}
#ifdef ARCADIA
	if (rd->type & ROMTYPE_ALG) {
		get_video_path(p->genlock_video_file, sizeof(p->genlock_video_file) / sizeof(TCHAR));
		_sntprintf(p->genlock_video_file + _tcslen(p->genlock_video_file), sizeof p->genlock_video_file / sizeof(TCHAR) - _tcslen(p->genlock_video_file), _T("%s.avi"), rd->name);
		clean_path(p->genlock_video_file);
	}
#endif
	return 1;
}

void set_device_rom(struct uae_prefs *p, const TCHAR *path, int romtype, int devnum)
{
	int idx;
	const struct expansionromtype *ert = get_device_expansion_rom(romtype);
	if (path == NULL) {
		struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
		if (brc) {
			brc->roms[idx].romfile[0] = 0;
			brc->roms[idx].romident[0] = 0;
		}
	} else {
		struct boardromconfig *brc = get_device_rom_new(p, romtype, devnum, &idx);
		_tcscpy(brc->roms[idx].romfile, path);
	}
}

const struct expansionromtype *get_unit_expansion_rom(int hdunit)
{
	if (hdunit >= HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST && hdunit <= HD_CONTROLLER_TYPE_SCSI_LAST)
		return &expansionroms[hdunit - HD_CONTROLLER_TYPE_SCSI_EXPANSION_FIRST];
	if (hdunit >= HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST && hdunit <= HD_CONTROLLER_TYPE_IDE_LAST)
		return &expansionroms[hdunit - HD_CONTROLLER_TYPE_IDE_EXPANSION_FIRST];
	if (hdunit >= HD_CONTROLLER_TYPE_CUSTOM_FIRST && hdunit <= HD_CONTROLLER_TYPE_CUSTOM_LAST)
		return &expansionroms[hdunit - HD_CONTROLLER_TYPE_CUSTOM_FIRST];
	return NULL;
}

const struct expansionromtype *get_device_expansion_rom(int romtype)
{
	for (int i = 0; expansionroms[i].name; i++) {
		const struct expansionromtype *ert = &expansionroms[i];
		if ((ert->romtype & ROMTYPE_MASK) == (romtype & ROMTYPE_MASK))
			return ert;
	}
	return NULL;
}

static void device_rom_defaults(struct uae_prefs *p, struct boardromconfig *brc, int romtype, int devnum)
{
	memset(brc, 0, sizeof(boardromconfig));
	brc->device_type = romtype;
	brc->device_num = devnum;
	for (int i = 0; i < MAX_BOARD_ROMS; i++) {
		brc->roms[i].device_id = 7;	
		brc->roms[i].back = brc;
	}
	int order = 0;
	for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
		if (p->expansionboard[i].device_order > order)
			order = p->expansionboard[i].device_order;
	}
	for (int i = 0; i < MAX_RAM_BOARDS; i++) {
		if (p->fastmem[i].device_order > order)
			order = p->fastmem[i].device_order;
		if (p->z3fastmem[i].device_order > order)
			order = p->z3fastmem[i].device_order;
	}
	for (int i = 0; i < MAX_RTG_BOARDS; i++) {
		if (p->rtgboards[i].device_order > order)
			order = p->rtgboards[i].device_order;
	}
	brc->device_order = order + 1;
}

struct boardromconfig *get_device_rom_new(struct uae_prefs *p, int romtype, int devnum, int *index)
{
	int idx2;
	static struct boardromconfig fake;
	const struct expansionromtype *ert = get_device_expansion_rom(romtype);
	if (!ert) {
		if (index)
			*index = 0;
		return &fake;
	}
	if (index)
		*index = ert->parentromtype ? 1 : 0;
	struct boardromconfig *brc = get_device_rom(p, ert->parentromtype ? ert->parentromtype : romtype, devnum, &idx2);
	if (!brc) {
		for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
			brc = &p->expansionboard[i];
			if (brc->device_type == 0)
				continue;
			int ok = 0;
			for (int j = 0; j < MAX_BOARD_ROMS; j++) {
				if (!brc->roms[j].romfile[0] && !brc->roms[j].romident[0] && !brc->roms[j].board_ram_size)
					ok++;
			}
			if (ok == MAX_BOARD_ROMS)
				memset(brc, 0, sizeof(boardromconfig));
		}
		for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
			brc = &p->expansionboard[i];
			if (brc->device_type == 0) {
				device_rom_defaults(p, brc, romtype, devnum);
				return brc;
			}
		}
		return &fake;
	}
	return brc;
}

void clear_device_rom(struct uae_prefs *p, int romtype, int devnum, bool deleteDevice)
{
	int index;
	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &index);
	if (!brc)
		return;
	if (deleteDevice) {
		memset(brc, 0, sizeof(struct boardromconfig));
	} else {
		memset(&brc->roms[index], 0, sizeof(struct romconfig));
	}
}

struct boardromconfig *get_device_rom(struct uae_prefs *p, int romtype, int devnum, int *index)
{
	const struct expansionromtype *ert = get_device_expansion_rom(romtype);
	if (!ert) {
		if (index)
			*index = 0;
		return NULL;
	}
	int parentrom = ert->parentromtype ? ert->parentromtype : romtype;
	if (index)
		*index = ert->parentromtype ? 1 : 0;
	for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
		struct boardromconfig *brc = &p->expansionboard[i];
		if (!brc->device_type)
			continue;
		if ((brc->device_type & ROMTYPE_MASK) == (parentrom & ROMTYPE_MASK) && brc->device_num == devnum)
			return brc;
	}
	return NULL;
}

struct romconfig *get_device_romconfig(struct uae_prefs *p, int romtype, int devnum)
{
	int idx;
	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
	if (brc)
		return &brc->roms[idx];
	return NULL;
}

void board_prefs_changed(int romtype, int devnum)
{
	if (romtype != -1) {
		int idx1, idx2;
		struct boardromconfig *brc1 = get_device_rom(&currprefs, romtype, devnum, &idx1);
		struct boardromconfig *brc2 = get_device_rom(&changed_prefs, romtype, devnum, &idx2);
		if (brc1 && brc2) {
			memcpy(brc1, brc2, sizeof(struct boardromconfig));
		} else if (brc1 && !brc2) {
			clear_device_rom(&currprefs, romtype, devnum, true);
		} else if (!brc1 && brc2) {
			brc1 = get_device_rom_new(&currprefs, romtype, devnum, &idx1);
			if (brc1)
				memcpy(brc1, brc2, sizeof(struct boardromconfig));
		}
	} else {
		for (int i = 0; expansionroms[i].name; i++) {
			const struct expansionromtype *ert = &expansionroms[i];
			for (int j = 0; j < MAX_BOARD_ROMS; j++) {
				board_prefs_changed(ert->romtype, j);
			}
		}
	}
}

bool is_board_enabled(struct uae_prefs *p, int romtype, int devnum)
{
	int idx;
	if (romtype == ROMTYPE_CPUBOARD && p->cpuboard_type) {
		return devnum == 0;
	}
	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
	if (!brc)
		return false;
	return brc->roms[idx].romfile[0] != 0;
}

static bool isspecialrom(const TCHAR *name)
{
	if (!_tcsicmp(name, _T(":NOROM")))
		return true;
	if (!_tcsicmp(name, _T(":ENABLED")))
		return true;
	return false;
}

struct zfile *read_device_from_romconfig(struct romconfig *rc, uae_u32 romtype, bool rw)
{
	struct zfile *z = NULL;
	if (isspecialrom(rc->romfile))
		return z;
	z = read_rom_name(rc->romfile, rw);
	if (z)
		return z;
	if (romtype) {
		struct romlist *rl = getromlistbyromtype(romtype, NULL);
		if (rl) {
			struct romdata *rd = rl->rd;
			z = read_rom(rd, rw);
		}
	}
	return z;
}

struct zfile *read_device_rom(struct uae_prefs *p, int romtype, int devnum, int *roms)
{
	int idx;
	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
	if (brc) {
		const TCHAR *romname = brc->roms[idx].romfile;
		if (isspecialrom(romname))
			return NULL;
		struct zfile *z = read_rom_name (romname, false);
		if (!z && roms) {
			struct romlist *rl = getromlistbyids(roms, romname);
			if (rl) {
				struct romdata *rd = rl->rd;
				z = read_rom (rd);
			}
		}
		return z;
	}
	return NULL;
}

int is_device_rom(struct uae_prefs *p, int romtype, int devnum)
{
	int idx;
	struct boardromconfig *brc = get_device_rom(p, romtype, devnum, &idx);
	if (brc) {
		const TCHAR *romname = brc->roms[idx].romfile;
		if (romname[0] == '\0')
			return -1;
		if (isspecialrom(romname))
			return 0;
		return 1;
	}
	return -1;
}

struct boardromconfig *get_boardromconfig(struct uae_prefs *p, int romtype, int *index)
{
	for (int i = 0; i < MAX_EXPANSION_BOARDS; i++) {
		struct boardromconfig *brc = &p->expansionboard[i];
		if (!brc->device_type)
			continue;
		if ((brc->device_type & ROMTYPE_MASK) == (romtype & ROMTYPE_MASK)) {
			for (int j = 0; j < MAX_BOARD_ROMS; j++) {
				if (brc->roms[j].romfile[0]) {
					if (index)
						*index = j;
					return brc;
				}
			}
		}
	}
	return NULL;
}

static struct zfile *parse_trumpcard_driver(struct zfile *z)
{
	int size;
	uae_u8 *dp = zfile_getdata(z, 0, -1, &size);
	if (!dp)
		return z;
	if (dp[0] != 0x00 || dp[1] != 0x00 || dp[2] != 0x03 || dp[3] != 0xf3) {
		xfree(dp);
		return z;
	}
	uae_u8 *d = dp + 0x1c + dp[11] * 4;
	if (dp >= dp + size) {
		xfree(dp);
		return z;
	}
	struct zfile *zd = zfile_fopen_empty(NULL, zfile_getname(z), 16384);
	int i, out;
	out = 0;
	for (i = 0; i < size - 4; i++) {
		if (d[i] == 0x4e && d[i + 1] == 0x71 && d[i + 2] == 0x4e && d[i + 3] == 0x71)
			break;
		uae_u8 v;
		v = (d[i] & 0xf0) | 0x0f;
		zfile_fwrite(&v, 1, 1, zd);
		v = (d[i] << 4) | 0x0f;
		zfile_fwrite(&v, 1, 1, zd);
		out += 2;
	}
	int datastart = i;
	for (; i < size - 4; i += 2) {
		if (d[i] == 0x66 && d[i + 1] == 0x66 && d[i + 2] == 0x99 && d[i + 3] == 0x99) {
			zfile_fwrite(&d[datastart], i - datastart + 4, 1, zd);
			out += i - datastart + 4;
			break;
		}
	}
	uae_u8 zero = 0;
	while (out & 15) {
		zfile_fwrite(&zero, 1, 1, zd);
		out++;
	}
	for (i = 0; i < 16; i++)  {
		zfile_fwrite(&zero, 1, 1, zd);
		out++;
	}
	zero = 0xff;
	while (out < 16384) {
		zfile_fwrite(&zero, 1, 1, zd);
		out++;
	}
	xfree(dp);
	return zd;
}

static bool load_rom_rc1(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags, struct zfile **zf)
{
	if (zf) {
		*zf = NULL;
	}
	if (flags & LOADROM_ONEFILL)
		memset(rom, 0xff, maxromsize);
	if (flags & LOADROM_ZEROFILL)
		memset(rom, 0x00, maxromsize);
	struct zfile *f = read_device_from_romconfig(rc, romtype, zf != NULL);
	if (!f)
		return false;
	TCHAR *ext = _tcsrchr(zfile_getname(f), '.');
	if ((romtype == ROMTYPE_IVSTPRO || romtype == ROMTYPE_IVSTC || romtype == ROMTYPE_IVST500AT) && ext && !_tcsicmp(ext, _T(".driver"))) {
		f = parse_trumpcard_driver(f);
	}
	zfile_fseek(f, fileoffset, SEEK_SET);
	int cnt = 0;
	int pos = 0;
	int bytes = 0;
	bool eof = false;
	while (cnt < maxromsize && cnt < maxfilesize && pos < maxromsize) {
		uae_u8 b = 0xff;
		if (!eof) {
			if (!zfile_fread(&b, 1, 1, f))
				eof = true;
			else
				bytes++;
		}
		if (eof) {
			int bitcnt = 0;
			for (int i = 1; i < maxromsize; i <<= 1) {
				if (cnt & i)
					bitcnt++;
			}
			if (bitcnt == 1)
				break;
		}

		rom[pos] = b;
		if (flags & LOADROM_EVENONLY) {
			rom[pos + 1] = (flags >> 16) & 0xff;
			pos += 2;
		} else {
			pos += 1;
		}
		cnt++;
	}
	if (f)
		write_log(_T("ROM '%s' loaded, %d bytes.\n"), zfile_getname(f), bytes);
	if (!zf) {
		zfile_fclose(f);
	} else {
		*zf = f;
	}
	int posend = pos;
	if (!(flags & LOADROM_FILL))
		return true;
	int oldpos = 0;
	while (pos < maxromsize) {
		rom[pos] = rom[oldpos];
		oldpos++;
		pos++;
		if (oldpos >= posend)
			oldpos = 0;
	}
	return true;
}

bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags)
{
	return load_rom_rc1(rc, romtype, maxfilesize, fileoffset, rom, maxromsize, flags, NULL);
}
struct zfile *load_rom_rc_zfile(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags)
{
	struct zfile *zf = NULL;
	if (!load_rom_rc1(rc, romtype, maxfilesize, fileoffset, rom, maxromsize, flags, &zf)) {
		return NULL;
	}
	return zf;
}

struct zfile *flashromfile_open(const TCHAR *name)
{
	struct zfile *f;
	TCHAR path[MAX_DPATH];
	bool rw = true;

	if (name == NULL || !name[0])
		return NULL;
	f = zfile_fopen(name, _T("rb"), ZFD_NORMAL);
	if (f) {
		if (zfile_iscompressed(f)) {
			rw = false;
		} else {
			zfile_fclose(f);
			f = NULL;
		}
	}
	if (!f) {
		rw = true;
		f = zfile_fopen(name, _T("rb+"), ZFD_NONE);
		if (!f) {
			rw = false;
			f = zfile_fopen(name, _T("rb"), ZFD_NORMAL);
			if (!f) {
				get_rom_path(path, sizeof path / sizeof(TCHAR));
				_tcscat(path, name);
				rw = true;
				f = zfile_fopen(path, _T("rb+"), ZFD_NONE);
				if (!f) {
					rw = false;
					f = zfile_fopen(path, _T("rb"), ZFD_NORMAL);
				}
			}
		}
	}
	if (f) {
		write_log(_T("Flash file '%s' loaded, %s.\n"), name, rw ? _T("RW") : _T("RO"));
	}
	return f;
}

static const TCHAR *get_path_basename(const TCHAR *name)
{
	const TCHAR *sep1 = _tcsrchr(name, '\\');
	const TCHAR *sep2 = _tcsrchr(name, '/');
	const TCHAR *sep = sep1;
	if (!sep || (sep2 && sep2 > sep))
		sep = sep2;
	return sep ? sep + 1 : name;
}

static bool accelerator_flash_path(const TCHAR *name, TCHAR *path, int size)
{
	if (name == NULL || !name[0])
		return false;

	get_nvram_path(path, size);
	const TCHAR *base = get_path_basename(name);
	if (!base[0])
		return false;

	if (_tcslen(path) + _tcslen(base) + 4 >= static_cast<size_t>(size))
		return false;

	_tcsncat(path, base, size - _tcslen(path) - 1);
	path[size - 1] = 0;

	TCHAR *ext = _tcsrchr(path, '.');
	const TCHAR *slash1 = _tcsrchr(path, '\\');
	const TCHAR *slash2 = _tcsrchr(path, '/');
	const TCHAR *slash = slash1;
	if (!slash || (slash2 && slash2 > slash))
		slash = slash2;
	if (ext && (!slash || ext > slash)) {
		_tcsncpy(ext, _T(".nvr"), size - (ext - path) - 1);
		path[size - 1] = 0;
	} else {
		_tcsncat(path, _T(".nvr"), size - _tcslen(path) - 1);
		path[size - 1] = 0;
	}
	return true;
}

static struct zfile *flashromfile_open_source(const TCHAR *name)
{
	struct zfile *f = zfile_fopen(name, _T("rb"), ZFD_NORMAL);
	if (f)
		return f;

	TCHAR path[MAX_DPATH];
	get_rom_path(path, sizeof path / sizeof(TCHAR));
	_tcscat(path, name);
	return zfile_fopen(path, _T("rb"), ZFD_NORMAL);
}

static bool copy_flashrom_source_to_nvram(struct zfile *source, const TCHAR *path)
{
	const uae_s64 source_size = zfile_size(source);
	if (source_size <= 0)
		return false;

	struct zfile *out = zfile_fopen(path, _T("wb"), 0);
	if (!out)
		return false;

	zfile_fseek(source, 0, SEEK_SET);
	uae_u8 buffer[8192];
	uae_s64 copied = 0;
	for (;;) {
		const size_t got = zfile_fread(buffer, 1, sizeof buffer, source);
		if (got == 0)
			break;
		if (zfile_fwrite(buffer, 1, got, out) != got) {
			zfile_fclose(out);
			my_unlink(path);
			zfile_fseek(source, 0, SEEK_SET);
			return false;
		}
		copied += got;
	}
	zfile_fclose(out);
	zfile_fseek(source, 0, SEEK_SET);
	if (copied != source_size) {
		my_unlink(path);
		return false;
	}
	return true;
}

static bool accelerator_flash_shadow_valid(struct zfile *shadow, struct zfile *source)
{
	const uae_s64 shadow_size = zfile_size(shadow);
	if (shadow_size <= 0)
		return false;
	return source == NULL || shadow_size == zfile_size(source);
}

struct zfile *flashromfile_open_accelerator(const TCHAR *name)
{
	TCHAR path[MAX_DPATH];
	if (!accelerator_flash_path(name, path, sizeof path / sizeof(TCHAR)))
		return NULL;

	struct zfile *source = flashromfile_open_source(name);
	struct zfile *f = zfile_fopen(path, _T("rb+"), ZFD_NONE);
	if (f) {
		if (accelerator_flash_shadow_valid(f, source)) {
			zfile_fclose(source);
			write_log(_T("Accelerator flash file '%s' loaded from NVRAM, RW.\n"), path);
			return f;
		}
		write_log(_T("Accelerator flash file '%s' invalid size, recreating from source.\n"), path);
		zfile_fclose(f);
		my_unlink(path);
	}

	if (!source)
		return NULL;

	if (!copy_flashrom_source_to_nvram(source, path)) {
		write_log(_T("Accelerator flash file '%s' could not be created, using source read-only.\n"), path);
		return source;
	}
	zfile_fclose(source);

	f = zfile_fopen(path, _T("rb+"), ZFD_NONE);
	if (f)
		write_log(_T("Accelerator flash file '%s' initialized in NVRAM, RW.\n"), path);
	return f;
}

struct romdata *scan_single_rom_file(struct zfile *f)
{
	uae_u8 buffer[20] = { 0 };
	uae_u8 *rombuf;
	int cl = 0, size;
	struct romdata *rd = 0;

	zfile_fseek(f, 0, SEEK_END);
	size = zfile_ftell32(f);
	zfile_fseek(f, 0, SEEK_SET);
	if (size > 524288 * 2) {/* don't skip KICK disks or 1M ROMs */
		write_log(_T("'%s': too big %d, ignored\n"), zfile_getname(f), size);
		return 0;
	}
	zfile_fread(buffer, 1, 11, f);
	if (!memcmp(buffer, "KICK", 4)) {
		zfile_fseek(f, 512, SEEK_SET);
		if (size > 262144)
			size = 262144;
	} else if (!memcmp(buffer, "AMIROMTYPE1", 11)) {
		cl = 1;
		size -= 11;
	} else {
		zfile_fseek(f, 0, SEEK_SET);
	}

	rombuf = xcalloc(uae_u8, size);
	if (!rombuf)
		return 0;
	zfile_fread(rombuf, 1, size, f);
	if (cl > 0) {
		decode_cloanto_rom_do(rombuf, size, size);
		cl = 0;
	}
	if (!cl) {
		rd = getromdatabydata(rombuf, size);
		if (!rd && (size & 65535) == 0) {
			/* check byteswap */
			int i;
			for (i = 0; i < size; i += 2) {
				uae_u8 b = rombuf[i];
				rombuf[i] = rombuf[i + 1];
				rombuf[i + 1] = b;
			}
			rd = getromdatabydata(rombuf, size);
		}
		if (size == 2 * 512 * 1024 && (!rd || rd->size < 2 * 512 * 1024)) {
			halfswap(rombuf, size);
			struct romdata* rd2 = getromdatabydata(rombuf, size);
			halfswap(rombuf, size);
			if (rd2 && rd2->size == 2 * 512 * 1024) {
				rd = rd2;
			}
		}
	}
	if (!rd) {
		const TCHAR *name = my_getfilepart(zfile_getname(f));
		rd = getfrombydefaultname(name, size);
	}
	if (!rd) {
		write_log(_T("!: Name='%s':%d\nCRC32=%08X SHA1=%s\n"),
			zfile_getname(f), size, get_crc32(rombuf, size), get_sha1_txt(rombuf, size));
	} else {
		TCHAR tmp[MAX_DPATH];
		getromname(rd, tmp);
		write_log(_T("*: %s:%d = %s\nCRC32=%08X SHA1=%s\n"),
			zfile_getname(f), size, tmp, get_crc32(rombuf, size), get_sha1_txt(rombuf, size));
	}
	xfree(rombuf);
	return rd;
}

struct romdata *scan_single_rom(const TCHAR *path)
{
	struct zfile *z;
	TCHAR tmp[MAX_DPATH];
	struct romdata *rd;

	_tcscpy(tmp, path);
	rd = scan_arcadia_rom(tmp, 0);
	if (rd)
		return rd;
	rd = getromdatabypath(path);
	if (rd && rd->crc32 == 0xffffffff)
		return rd;
	z = zfile_fopen(path, _T("rb"), ZFD_NORMAL);
	if (!z)
		return 0;
	return scan_single_rom_file(z);
}
