/*
* 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.
/* The SSFII mapper */
-unsigned char ssf2_banks[8];
+static unsigned char ssf2_banks[8];
static carthw_state_chunk carthw_ssf2_state[] =
{
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)