+ u32 d = 0;
+ if ((a & 0xffc0) == 0x5100) { // a15100
+ d = Pico32x.regs[(a & 0x3f) / 2];
+ goto out;
+ }
+
+ if ((a & 0xfffc) == 0x30ec) { // a130ec
+ d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S';
+ goto out;
+ }
+
+ elprintf(EL_UIO, "m68k unmapped r16 [%06x] @%06x", a, SekPc);
+ return d;
+
+out:
+ elprintf(EL_32X, "m68k 32x r16 [%06x] %04x @%06x", a, d, SekPc);
+ return d;
+}
+
+void PicoWrite8_32x(u32 a, u32 d)
+{
+ if ((a & 0xffc0) == 0x5100) { // a15100
+ u16 *r = Pico32x.regs;
+
+ elprintf(EL_32X, "m68k 32x w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
+ a &= 0x3f;
+ if (a == 1) {
+ if ((d ^ r[0]) & d & P32XS_ADEN) {
+ Pico32xStartup();
+ r[0] &= ~P32XS_nRES; // causes reset if specified by this write
+ r[0] |= P32XS_ADEN;
+ p32x_reg_write8(a, d); // forward for reset processing
+ }
+ return;
+ }
+
+ // allow only COMM for now
+ if ((a & 0x30) == 0x20) {
+ u8 *r8 = (u8 *)r;
+ r8[a ^ 1] = d;
+ }
+ return;
+ }
+
+ elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
+}
+
+void PicoWrite16_32x(u32 a, u32 d)
+{
+ if ((a & 0xffc0) == 0x5100) { // a15100
+ u16 *r = Pico32x.regs;
+
+ elprintf(EL_UIO, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
+ a &= 0x3e;
+ if (a == 0) {
+ if ((d ^ r[0]) & d & P32XS_ADEN) {
+ Pico32xStartup();
+ r[0] &= ~P32XS_nRES; // causes reset if specified by this write
+ r[0] |= P32XS_ADEN;
+ p32x_reg_write16(a, d); // forward for reset processing
+ }
+ return;
+ }
+
+ // allow only COMM for now
+ if ((a & 0x30) == 0x20)
+ r[a / 2] = d;
+ return;
+ }
+
+ elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
+}
+
+/* quirk: in both normal and overwrite areas only nonzero values go through */
+#define sh2_write8_dramN(n) \
+ if ((d & 0xff) != 0) { \
+ u8 *dram = (u8 *)Pico32xMem->dram[n]; \
+ dram[(a & 0x1ffff) ^ 1] = d; \
+ }
+
+static void m68k_write8_dram0_ow(u32 a, u32 d)
+{
+ sh2_write8_dramN(0);
+}
+
+static void m68k_write8_dram1_ow(u32 a, u32 d)
+{
+ sh2_write8_dramN(1);
+}
+
+#define sh2_write16_dramN(n) \
+ u16 *pd = &Pico32xMem->dram[n][(a & 0x1ffff) / 2]; \
+ if (!(a & 0x20000)) { \
+ *pd = d; \
+ return; \
+ } \
+ /* overwrite */ \
+ if (!(d & 0xff00)) d |= *pd & 0xff00; \
+ if (!(d & 0x00ff)) d |= *pd & 0x00ff; \
+ *pd = d;
+
+static void m68k_write16_dram0_ow(u32 a, u32 d)
+{
+ sh2_write16_dramN(0);
+}
+
+static void m68k_write16_dram1_ow(u32 a, u32 d)
+{
+ sh2_write16_dramN(1);
+}
+
+// -----------------------------------------------------------------
+
+// hint vector is writeable
+static void PicoWrite8_hint(u32 a, u32 d)
+{
+ if ((a & 0xfffc) == 0x0070) {
+ Pico32xMem->m68k_rom[a ^ 1] = d;
+ return;
+ }
+
+ elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x",
+ a, d & 0xff, SekPc);
+}
+
+static void PicoWrite16_hint(u32 a, u32 d)
+{
+ if ((a & 0xfffc) == 0x0070) {
+ ((u16 *)Pico32xMem->m68k_rom)[a/2] = d;
+ return;
+ }
+
+ elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x",
+ a, d & 0xffff, SekPc);
+}
+
+// normally not writable, but somebody could make a RAM cart
+static void PicoWrite8_cart(u32 a, u32 d)
+{
+ elprintf(EL_UIO, "m68k w8 [%06x] %02x @%06x", a, d & 0xff, SekPc);
+
+ a &= 0xfffff;
+ m68k_write8(a, d);
+}
+
+static void PicoWrite16_cart(u32 a, u32 d)
+{
+ elprintf(EL_UIO, "m68k w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc);
+
+ a &= 0xfffff;
+ m68k_write16(a, d);
+}
+
+// same with bank, but save ram is sometimes here
+static u32 PicoRead8_bank(u32 a)
+{
+ a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
+ return m68k_read8(a);
+}
+
+static u32 PicoRead16_bank(u32 a)
+{
+ a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
+ return m68k_read16(a);
+}
+
+static void PicoWrite8_bank(u32 a, u32 d)
+{
+ if (!(Pico.m.sram_reg & SRR_MAPPED))
+ elprintf(EL_UIO, "m68k w8 [%06x] %02x @%06x",
+ a, d & 0xff, SekPc);
+
+ a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
+ m68k_write8(a, d);
+}
+
+static void PicoWrite16_bank(u32 a, u32 d)
+{
+ if (!(Pico.m.sram_reg & SRR_MAPPED))
+ elprintf(EL_UIO, "m68k w16 [%06x] %04x @%06x",
+ a, d & 0xffff, SekPc);
+
+ a = (Pico32x.regs[4 / 2] << 20) | (a & 0xfffff);
+ m68k_write16(a, d);
+}
+
+static void bank_map_handler(void)
+{
+ cpu68k_map_set(m68k_read8_map, 0x900000, 0x9fffff, PicoRead8_bank, 1);
+ cpu68k_map_set(m68k_read16_map, 0x900000, 0x9fffff, PicoRead16_bank, 1);
+}
+
+static void bank_switch(int b)
+{
+ unsigned int rs, bank;
+
+ bank = b << 20;
+ if ((Pico.m.sram_reg & SRR_MAPPED) && bank == SRam.start) {
+ bank_map_handler();
+ return;
+ }
+
+ if (bank >= Pico.romsize) {