|
@@ -1,6 +1,6 @@
|
|
|
/*
|
|
|
* Support for a few cart mappers and some protection.
|
|
|
- * (C) notaz, 2008,2009,2010
|
|
|
+ * (C) notaz, 2008-2011
|
|
|
*
|
|
|
* This work is licensed under the terms of MAME license.
|
|
|
* See COPYING file in the top-level directory.
|
|
@@ -11,7 +11,7 @@
|
|
|
|
|
|
|
|
|
/* The SSFII mapper */
|
|
|
-unsigned char ssf2_banks[8];
|
|
|
+static unsigned char ssf2_banks[8];
|
|
|
|
|
|
static carthw_state_chunk carthw_ssf2_state[] =
|
|
|
{
|
|
@@ -261,25 +261,205 @@ void carthw_radica_startup(void)
|
|
|
carthw_chunks = carthw_Xin1_state;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+/* Pier Solar. Based on my own research */
|
|
|
+static unsigned char pier_regs[8];
|
|
|
+static unsigned char pier_dump_prot;
|
|
|
+
|
|
|
+static carthw_state_chunk carthw_pier_state[] =
|
|
|
+{
|
|
|
+ { CHUNK_CARTHW, sizeof(pier_regs), pier_regs },
|
|
|
+ { CHUNK_CARTHW + 1, sizeof(pier_dump_prot), &pier_dump_prot },
|
|
|
+ { 0, 0, NULL }
|
|
|
+};
|
|
|
+
|
|
|
+static void carthw_pier_write8(u32 a, u32 d)
|
|
|
+{
|
|
|
+ u32 a8, target, base;
|
|
|
+
|
|
|
+ if ((a & 0xffff00) != 0xa13000) {
|
|
|
+ PicoWrite8_io(a, d);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ a8 = a & 0x0f;
|
|
|
+ pier_regs[a8 / 2] = d;
|
|
|
+
|
|
|
+ elprintf(EL_UIO, "pier w8 [%06x] %02x @%06x", a, d & 0xffff, SekPc);
|
|
|
+ switch (a8) {
|
|
|
+ case 0x01:
|
|
|
+ break;
|
|
|
+ case 0x03:
|
|
|
+ if (!(pier_regs[0] & 2))
|
|
|
+ goto unmapped;
|
|
|
+ target = 0x280000;
|
|
|
+ base = d << 19;
|
|
|
+ goto do_map;
|
|
|
+ case 0x05:
|
|
|
+ if (!(pier_regs[0] & 2))
|
|
|
+ goto unmapped;
|
|
|
+ target = 0x300000;
|
|
|
+ base = d << 19;
|
|
|
+ goto do_map;
|
|
|
+ case 0x07:
|
|
|
+ if (!(pier_regs[0] & 2))
|
|
|
+ goto unmapped;
|
|
|
+ target = 0x380000;
|
|
|
+ base = d << 19;
|
|
|
+ goto do_map;
|
|
|
+ case 0x09:
|
|
|
+ // TODO
|
|
|
+ break;
|
|
|
+ case 0x0b:
|
|
|
+ // eeprom read
|
|
|
+ default:
|
|
|
+ unmapped:
|
|
|
+ //elprintf(EL_UIO, "pier w8 [%06x] %02x @%06x", a, d & 0xffff, SekPc);
|
|
|
+ elprintf(EL_STATUS, "-- unmapped w8 [%06x] %02x @%06x", a, d & 0xffff, SekPc);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return;
|
|
|
+
|
|
|
+do_map:
|
|
|
+ if (base + 0x80000 > Pico.romsize) {
|
|
|
+ elprintf(EL_ANOMALY|EL_STATUS, "pier: missing bank @ %06x", base);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ cpu68k_map_set(m68k_read8_map, target, target + 0x80000 - 1, Pico.rom + base, 0);
|
|
|
+ cpu68k_map_set(m68k_read16_map, target, target + 0x80000 - 1, Pico.rom + base, 0);
|
|
|
+}
|
|
|
+
|
|
|
+static void carthw_pier_write16(u32 a, u32 d)
|
|
|
+{
|
|
|
+ if ((a & 0xffff00) != 0xa13000) {
|
|
|
+ PicoWrite16_io(a, d);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ elprintf(EL_UIO, "pier w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
|
|
|
+ carthw_pier_write8(a + 1, d);
|
|
|
+}
|
|
|
+
|
|
|
+static u32 carthw_pier_read8(u32 a)
|
|
|
+{
|
|
|
+ if ((a & 0xffff00) != 0xa13000)
|
|
|
+ return PicoRead8_io(a);
|
|
|
+
|
|
|
+ if (a == 0xa1300b)
|
|
|
+ return 0; // TODO
|
|
|
+
|
|
|
+ elprintf(EL_UIO, "pier r8 [%06x] @%06x", a, SekPc);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void carthw_pier_statef(void);
|
|
|
+
|
|
|
+static u32 carthw_pier_prot_read8(u32 a)
|
|
|
+{
|
|
|
+ /* it takes more than just these reads here to disable ROM protection,
|
|
|
+ * but for game emulation purposes this is enough. */
|
|
|
+ if (pier_dump_prot > 0)
|
|
|
+ pier_dump_prot--;
|
|
|
+ if (pier_dump_prot == 0) {
|
|
|
+ carthw_pier_statef();
|
|
|
+ elprintf(EL_STATUS, "prot off on r8 @%06x", SekPc);
|
|
|
+ }
|
|
|
+ elprintf(EL_UIO, "pier r8 [%06x] @%06x", a, SekPc);
|
|
|
+
|
|
|
+ return Pico.rom[(a & 0x7fff) ^ 1];
|
|
|
+}
|
|
|
+
|
|
|
+static void carthw_pier_mem_setup(void)
|
|
|
+{
|
|
|
+ cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, carthw_pier_write8, 1);
|
|
|
+ cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, carthw_pier_write16, 1);
|
|
|
+ cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, carthw_pier_read8, 1);
|
|
|
+}
|
|
|
+
|
|
|
+static void carthw_pier_prot_mem_setup(int prot_enable)
|
|
|
+{
|
|
|
+ if (prot_enable) {
|
|
|
+ /* the dump protection.. */
|
|
|
+ int a;
|
|
|
+ for (a = 0x000000; a < 0x400000; a += M68K_BANK_SIZE) {
|
|
|
+ cpu68k_map_set(m68k_read8_map, a, a + 0xffff, Pico.rom + Pico.romsize, 0);
|
|
|
+ cpu68k_map_set(m68k_read16_map, a, a + 0xffff, Pico.rom + Pico.romsize, 0);
|
|
|
+ }
|
|
|
+ cpu68k_map_set(m68k_read8_map, M68K_BANK_SIZE, M68K_BANK_SIZE * 2 - 1,
|
|
|
+ carthw_pier_prot_read8, 1);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ cpu68k_map_set(m68k_read8_map, 0, 0x27ffff, Pico.rom, 0);
|
|
|
+ cpu68k_map_set(m68k_read16_map, 0, 0x27ffff, Pico.rom, 0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void carthw_pier_statef(void)
|
|
|
+{
|
|
|
+ carthw_pier_prot_mem_setup(pier_dump_prot);
|
|
|
+
|
|
|
+ if (!pier_dump_prot) {
|
|
|
+ /* setup all banks */
|
|
|
+ u32 r0 = pier_regs[0];
|
|
|
+ carthw_pier_write8(0xa13001, 3);
|
|
|
+ carthw_pier_write8(0xa13003, pier_regs[1]);
|
|
|
+ carthw_pier_write8(0xa13005, pier_regs[2]);
|
|
|
+ carthw_pier_write8(0xa13007, pier_regs[3]);
|
|
|
+ carthw_pier_write8(0xa13001, r0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static void carthw_pier_reset(void)
|
|
|
+{
|
|
|
+ pier_regs[0] = 1;
|
|
|
+ pier_regs[1] = pier_regs[2] = pier_regs[3] = 0;
|
|
|
+ pier_dump_prot = 3;
|
|
|
+ carthw_pier_statef();
|
|
|
+}
|
|
|
+
|
|
|
+void carthw_pier_startup(void)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ elprintf(EL_STATUS, "Pier Solar mapper startup");
|
|
|
+
|
|
|
+ // mostly same as for realtec..
|
|
|
+ i = PicoCartResize(Pico.romsize + M68K_BANK_SIZE);
|
|
|
+ if (i != 0) {
|
|
|
+ elprintf(EL_STATUS, "OOM");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // create dump protection bank
|
|
|
+ for (i = 0; i < M68K_BANK_SIZE; i += 0x8000)
|
|
|
+ memcpy(Pico.rom + Pico.romsize + i, Pico.rom, 0x8000);
|
|
|
+
|
|
|
+ PicoCartMemSetup = carthw_pier_mem_setup;
|
|
|
+ PicoResetHook = carthw_pier_reset;
|
|
|
+ PicoLoadStateHook = carthw_pier_statef;
|
|
|
+ carthw_chunks = carthw_pier_state;
|
|
|
+}
|
|
|
+
|
|
|
/* Simple unlicensed ROM protection emulation */
|
|
|
static struct {
|
|
|
- u32 addr;
|
|
|
- u32 mask;
|
|
|
- u16 val;
|
|
|
- u16 readonly;
|
|
|
+ u32 addr;
|
|
|
+ u32 mask;
|
|
|
+ u16 val;
|
|
|
+ u16 readonly;
|
|
|
} *sprot_items;
|
|
|
static int sprot_item_alloc;
|
|
|
static int sprot_item_count;
|
|
|
|
|
|
static u16 *carthw_sprot_get_val(u32 a, int rw_only)
|
|
|
{
|
|
|
- int i;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < sprot_item_count; i++)
|
|
|
+ if ((a & sprot_items[i].mask) == sprot_items[i].addr)
|
|
|
+ if (!rw_only || !sprot_items[i].readonly)
|
|
|
+ return &sprot_items[i].val;
|
|
|
|
|
|
- for (i = 0; i < sprot_item_count; i++)
|
|
|
- if ((a & sprot_items[i].mask) == sprot_items[i].addr)
|
|
|
- if (!rw_only || !sprot_items[i].readonly)
|
|
|
- return &sprot_items[i].val;
|
|
|
- return NULL;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
static u32 PicoRead8_sprot(u32 a)
|