32x: overflow handling for X-Men
[picodrive.git] / pico / 32x / memory.c
index 1b5bdd4..332b0bc 100644 (file)
@@ -577,6 +577,8 @@ static void sh2_peripheral_write32(u32 a, u32 d, int id)
                        r[0x118 / 4] = r[0x110 / 4] = (signed int)d % divisor;
         r[0x104 / 4] = r[0x11c / 4] = r[0x114 / 4] = (signed int)d / divisor;
       }
+      else
+        r[0x110 / 4] = r[0x114 / 4] = r[0x118 / 4] = r[0x11c / 4] = 0; // ?
       break;
     case 0x114:
       elprintf(EL_32X, "%csh2 divide %08x%08x / %08x @%08x",
@@ -586,8 +588,16 @@ static void sh2_peripheral_write32(u32 a, u32 d, int id)
         signed int divisor = r[0x100 / 4];
         // XXX: undocumented mirroring to 0x118,0x11c?
         r[0x118 / 4] = r[0x110 / 4] = divident % divisor;
-        r[0x11c / 4] = r[0x114 / 4] = divident / divisor;
+        divident /= divisor;
+        r[0x11c / 4] = r[0x114 / 4] = divident;
+        divident >>= 31;
+        if ((unsigned long long)divident + 1 > 1) {
+          //elprintf(EL_32X, "%csh2 divide overflow! @%08x", id ? 's' : 'm', sh2_pc(id));
+          r[0x11c / 4] = r[0x114 / 4] = divident > 0 ? 0x7fffffff : 0x80000000; // overflow
+        }
       }
+      else
+        r[0x110 / 4] = r[0x114 / 4] = r[0x118 / 4] = r[0x11c / 4] = 0; // ?
       break;
   }
 
@@ -894,6 +904,12 @@ static void bank_switch(int b)
   cpu68k_map_set(m68k_read16_map,  0x900000, 0x900000 + rs - 1, Pico.rom + bank, 0);
 
   elprintf(EL_32X, "bank %06x-%06x -> %06x", 0x900000, 0x900000 + rs - 1, bank);
+
+#ifdef EMU_F68K
+  // setup FAME fetchmap
+  for (rs = 0x90; rs < 0xa0; rs++)
+    PicoCpuFM68k.Fetch[rs] = (u32)Pico.rom + bank - 0x900000;
+#endif
 }
 
 // -----------------------------------------------------------------
@@ -1289,6 +1305,12 @@ void PicoMemSetup32x(void)
     rs = 0x80000;
   cpu68k_map_set(m68k_read8_map,   0x880000, 0x880000 + rs - 1, Pico.rom, 0);
   cpu68k_map_set(m68k_read16_map,  0x880000, 0x880000 + rs - 1, Pico.rom, 0);
+#ifdef EMU_F68K
+  // setup FAME fetchmap
+  PicoCpuFM68k.Fetch[0] = (u32)Pico32xMem->m68k_rom;
+  for (rs = 0x88; rs < 0x90; rs++)
+    PicoCpuFM68k.Fetch[rs] = (u32)Pico.rom - 0x880000;
+#endif
 
   // 32X ROM (banked)
   bank_switch(0);