#define MF_POLLING 0x20 // include polling check in read
// address space stuff
-static int dr_is_rom(u32 a)
-{
- // tweak for WWF Raw which writes data to some high ROM addresses
- return (a & 0xc6000000) == 0x02000000 && (a & 0x3f0000) < 0x3e0000;
-}
-
static int dr_ctx_get_mem_ptr(SH2 *sh2, u32 a, u32 *mask)
{
void *memptr;
if (gconst_get(r, &a)) {
a += offs;
// check if rom is memory mapped (not bank switched), and address is in rom
- if (dr_is_rom(a) && p32x_sh2_get_mem_ptr(a, &mask, sh2) == sh2->p_rom) {
+ if (p32x_sh2_mem_is_rom(a, sh2) && p32x_sh2_get_mem_ptr(a, &mask, sh2) == sh2->p_rom) {
switch (size & MF_SIZEMASK) {
case 0: *val = (s8)p32x_sh2_read8(a, sh2s); break; // 8
case 1: *val = (s16)p32x_sh2_read16(a, sh2s); break; // 16
case OP_LOAD_POOL:
#if PROPAGATE_CONSTANTS
if ((opd->imm && opd->imm >= base_pc && opd->imm < end_literals) ||
- dr_is_rom(opd->imm))
+ p32x_sh2_mem_is_rom(opd->imm, sh2))
{
if (opd->size == 2)
u = FETCH32(opd->imm);
else
u = (s16)FETCH_OP(opd->imm);
- // tweak for Blackthorne: avoid stack overwriting
- if (GET_Rn() == SHR_SP && u == 0x0603f800) u = 0x0603f900;
gconst_new(GET_Rn(), u);
}
else
Pico32x.sh2_regs[0] &= ~0x80;
Pico32x.sh2_regs[0] |= d & 0x80;
- if ((d ^ old) & 1)
+ if ((old ^ d) & 1)
p32x_pwm_schedule_sh2(sh2);
if ((old ^ d) & 2)
p32x_update_cmd_irq(sh2, 0);
// Presumably the write goes to the CPU cache and is read back from there,
// but it would be extremely costly to emulate cache behaviour. Just allow
// writes to that region, hoping that the original ROM values are never used.
- if ((a1 & 0x3e0000) == 0x3e0000)
+ if ((a1 & 0x3e0000) == 0x3e0000 && (PicoIn.quirks & PQUIRK_WWFRAW_HACK))
((u16 *)sh2->p_rom)[a1 / 2] = d;
else
sh2_write16_unmapped(a, d, sh2);
return ret;
}
+int p32x_sh2_mem_is_rom(u32 a, SH2 *sh2)
+{
+ if ((a & 0xc6000000) == 0x02000000) {
+ // ROM, but mind tweak for WWF Raw
+ return !(PicoIn.quirks & PQUIRK_WWFRAW_HACK) || (a & 0x3f0000) < 0x3e0000;
+ }
+
+ return 0;
+}
+
int p32x_sh2_memcpy(u32 dst, u32 src, int count, int size, SH2 *sh2)
{
u32 mask;
if (!up || chan->tcr < 4)
return;
-#if MARS_CHECK_HACK
- // XXX Mars Check Program copies 32K longwords (128KB) from a 64KB buffer in
- // ROM or DRAM to SDRAM in 4-longword mode, overwriting an SDRAM comm area in
- // turn, which crashes the test on emulators without CPU cache emulation.
- // This may be a bug in Mars Check. As a kludge limit the transfer to 64KB,
- // which is what the check program test uses for checking the result.
- // A better way would clearly be to have a mechanism to patch the ROM...
- if (size == 3 && chan->tcr == 32768 && chan->dar == 0x06020000) size = 1;
-#endif
+
if (size == 3) size = 2; // 4-word xfer mode still counts in words
// XXX check TCR being a multiple of 4 in 4-word xfer mode?
// XXX check alignment of sar/dar, generating a bus error if unaligned?
Pico.sv.flags &= ~SRF_EEPROM;\r
else if (strcmp(p, "filled_sram") == 0)\r
*fill_sram = 1;\r
+ else if (strcmp(p, "wwfraw_hack") == 0)\r
+ PicoIn.quirks |= PQUIRK_WWFRAW_HACK;\r
+ else if (strcmp(p, "blackthorne_hack") == 0)\r
+ PicoIn.quirks |= PQUIRK_BLACKTHORNE_HACK;\r
+ else if (strcmp(p, "marscheck_hack") == 0)\r
+ PicoIn.quirks |= PQUIRK_MARSCHECK_HACK;\r
else if (strcmp(p, "force_6btn") == 0)\r
PicoIn.quirks |= PQUIRK_FORCE_6BTN;\r
else {\r
// Unusual region 'code'\r
if (rom_strcmp(0x1f0, "EUROPE") == 0 || rom_strcmp(0x1f0, "Europe") == 0)\r
*(u32 *) (Pico.rom + 0x1f0) = CPU_LE4(0x20204520);\r
+\r
+ // tweak for Blackthorne: master SH2 overwrites stack of slave SH2 being in PWM\r
+ // interrupt. On real hardware, nothing happens since slave fetches the values\r
+ // it has written from its cache, but picodrive doesn't emulate caching.\r
+ // move master memory area down by 0x100 bytes.\r
+ // XXX replace this abominable hack. It might cause other problems in the game!\r
+ if (PicoIn.quirks & PQUIRK_BLACKTHORNE_HACK) {\r
+ int i;\r
+ unsigned a = 0;\r
+ for (i = 0; i < Pico.romsize; i += 4) {\r
+ unsigned v = CPU_BE2(*(u32 *) (Pico.rom + i));\r
+ if (a && v == a + 0x400) { // patch if 2 pointers with offset 0x400 are found\r
+ printf("auto-patching @%06x: %08x->%08x\n", i, v, v - 0x100);\r
+ *(u32 *) (Pico.rom + i) = CPU_BE2(v - 0x100);\r
+ }\r
+ // detect a pointer into the incriminating area\r
+ a = 0;\r
+ if (v >> 12 == 0x0603f000 >> 12 && !(v & 3))\r
+ a = v;\r
+ }\r
+ }\r
+\r
+ // tweak for Mars Check Program: copies 32K longwords (128KB) from a 64KB buffer\r
+ // in ROM or DRAM to SDRAM with DMA in 4-longword mode, overwriting an SDRAM comm\r
+ // area in turn. This crashes the test on emulators without CPU cache emulation.\r
+ // This may be a bug in Mars Check, since it's only checking for the 64KB result.\r
+ // Patch the DMA transfers so that they transfer only 64KB.\r
+ if (PicoIn.quirks & PQUIRK_MARSCHECK_HACK) {\r
+ int i;\r
+ unsigned a = 0;\r
+ for (i = 0; i < Pico.romsize; i += 4) {\r
+ unsigned v = CPU_BE2(*(u32 *) (Pico.rom + i));\r
+ if (a == 0xffffff8c && v == 0x5ee1) { // patch if 4-long xfer written to CHCR\r
+ printf("auto-patching @%06x: %08x->%08x\n", i, v, v & ~0x800);\r
+ *(u32 *) (Pico.rom + i) = CPU_BE2(v & ~0x800); // change to half-sized xfer\r
+ }\r
+ a = v;\r
+ }\r
+ }\r
}\r
\r
static void PicoCartDetectMS(void)\r
check_str = 0x100, "IMA IKUNO"
hw = pico
+# X-Men proto
+[X-Men (prototype) - 32X]
+check_str = 0x120, "32X SAMPLE PROGRAM"
+check_str = 0x32b74c, "Bishop Level"
+prop = force_6btn
+
+# WWF Raw
+[WWF Raw - 32X]
+check_str = 0x100, "SEGA 32X"
+check_str = 0x150, "WWF RAW"
+prop = wwfraw_hack # reads back data written to high ROM adresses from cache
+
+# Blackthorne
+[Blackthorne - 32X]
+check_str = 0x100, "SEGA 32X"
+check_str = 0x120, "BLACKTHORNE"
+prop = blackthorne_hack # reads back data overwritten by 2nd CPU from cache
+
+# Mars check program
+[Mars Check - 32X]
+check_str = 0x100, "SEGA"
+check_str = 0x150, "MARS CHECK PROGRAM"
+prop = marscheck_hack # reads back data overwritten by DMA from cache
+
# sram emulation triggers some protection for this one
[Puggsy]
check_str = 0x120, "PUGGSY"
check_str = 0x150, " HardBall III"
sram_range = 0x200000,0x20ffff
-# X-Men proto
-[X-Men (prototype)]
-check_str = 0x150, "32X SAMPLE PROGRAM"
-check_str = 0x32b74c, "Bishop Level"
-prop = force_6btn
-
# The SSF2 mapper
[Mega Everdrive]
check_str = 0x100, "SEGA SSF"
#define PHWS_SMS 2\r
#define PHWS_SG 3\r
\r
-#define PQUIRK_FORCE_6BTN (1<<0)\r
+#define PQUIRK_FORCE_6BTN (1<<0)\r
+#define PQUIRK_BLACKTHORNE_HACK (1<<1)\r
+#define PQUIRK_WWFRAW_HACK (1<<2)\r
+#define PQUIRK_MARSCHECK_HACK (1<<3)\r
\r
// the emulator is configured and some status is reported\r
// through this global state (not saved in savestates)\r
u32 REGPARM(3) p32x_sh2_poll_memory16(u32 a, u32 d, SH2 *sh2);\r
u32 REGPARM(3) p32x_sh2_poll_memory32(u32 a, u32 d, SH2 *sh2);\r
void *p32x_sh2_get_mem_ptr(u32 a, u32 *mask, SH2 *sh2);\r
+int p32x_sh2_mem_is_rom(u32 a, SH2 *sh2);\r
void p32x_sh2_poll_detect(u32 a, SH2 *sh2, u32 flags, int maxcnt);\r
void p32x_sh2_poll_event(SH2 *sh2, u32 flags, u32 m68k_cycles);\r
int p32x_sh2_memcpy(u32 dst, u32 src, int count, int size, SH2 *sh2);\r