+ wh = sh2_wmap[offs];
+ wh(a, d >> 16, sh2);
+ wh(a + 2, d, sh2);
+}
+
+// -----------------------------------------------------------------
+
+static void z80_md_bank_write_32x(unsigned int a, unsigned char d)
+{
+ unsigned int addr68k;
+
+ addr68k = Pico.m.z80_bank68k << 15;
+ addr68k += a & 0x7fff;
+ if ((addr68k & 0xfff000) == 0xa15000)
+ Pico32x.emu_flags |= P32XF_Z80_32X_IO;
+
+ elprintf(EL_Z80BNK, "z80->68k w8 [%06x] %02x", addr68k, d);
+ m68k_write8(addr68k, d);
+}
+
+// -----------------------------------------------------------------
+
+static const u16 msh2_code[] = {
+ // trap instructions
+ 0xaffe, // 200 bra <self>
+ 0x0009, // 202 nop
+ // have to wait a bit until m68k initial program finishes clearing stuff
+ // to avoid races with game SH2 code, like in Tempo
+ 0xd406, // 204 mov.l @(_m_ok,pc), r4
+ 0xc400, // 206 mov.b @(h'0,gbr),r0
+ 0xc801, // 208 tst #1, r0
+ 0x8b0f, // 20a bf cd_start
+ 0xd105, // 20c mov.l @(_cnt,pc), r1
+ 0xd206, // 20e mov.l @(_start,pc), r2
+ 0x71ff, // 210 add #-1, r1
+ 0x4115, // 212 cmp/pl r1
+ 0x89fc, // 214 bt -2
+ 0x6043, // 216 mov r4, r0
+ 0xc208, // 218 mov.l r0, @(h'20,gbr)
+ 0x6822, // 21a mov.l @r2, r8
+ 0x482b, // 21c jmp @r8
+ 0x0009, // 21e nop
+ ('M'<<8)|'_', ('O'<<8)|'K', // 220 _m_ok
+ 0x0001, 0x0000, // 224 _cnt
+ 0x2200, 0x03e0, // master start pointer in ROM
+ // cd_start:
+ 0xd20d, // 22c mov.l @(__cd_,pc), r2
+ 0xc608, // 22e mov.l @(h'20,gbr), r0
+ 0x3200, // 230 cmp/eq r0, r2
+ 0x8bfc, // 232 bf #-2
+ 0xe000, // 234 mov #0, r0
+ 0xcf80, // 236 or.b #0x80,@(r0,gbr)
+ 0xd80b, // 238 mov.l @(_start_cd,pc), r8 // 24000018
+ 0xd30c, // 23a mov.l @(_max_len,pc), r3
+ 0x5b84, // 23c mov.l @(h'10,r8), r11 // master vbr
+ 0x5a82, // 23e mov.l @(8,r8), r10 // entry
+ 0x5081, // 240 mov.l @(4,r8), r0 // len
+ 0x5980, // 242 mov.l @(0,r8), r9 // dst
+ 0x3036, // 244 cmp/hi r3,r0
+ 0x8b00, // 246 bf #1
+ 0x6033, // 248 mov r3,r0
+ 0x7820, // 24a add #0x20, r8
+ // ipl_copy:
+ 0x6286, // 24c mov.l @r8+, r2
+ 0x2922, // 24e mov.l r2, @r9
+ 0x7904, // 250 add #4, r9
+ 0x70fc, // 252 add #-4, r0
+ 0x8800, // 254 cmp/eq #0, r0
+ 0x8bf9, // 256 bf #-5
+ //
+ 0x4b2e, // 258 ldc r11, vbr
+ 0x6043, // 25a mov r4, r0 // M_OK
+ 0xc208, // 25c mov.l r0, @(h'20,gbr)
+ 0x4a2b, // 25e jmp @r10
+ 0x0009, // 260 nop
+ 0x0009, // 262 nop // pad
+ ('_'<<8)|'C', ('D'<<8)|'_', // 264 __cd_
+ 0x2400, 0x0018, // 268 _start_cd
+ 0x0001, 0xffe0, // 26c _max_len
+};
+
+static const u16 ssh2_code[] = {
+ 0xaffe, // 200 bra <self>
+ 0x0009, // 202 nop
+ // code to wait for master, in case authentic master BIOS is used
+ 0xd106, // 204 mov.l @(_m_ok,pc), r1
+ 0xd208, // 206 mov.l @(_start,pc), r2
+ 0xc608, // 208 mov.l @(h'20,gbr), r0
+ 0x3100, // 20a cmp/eq r0, r1
+ 0x8bfc, // 20c bf #-2
+ 0xc400, // 20e mov.b @(h'0,gbr),r0
+ 0xc801, // 210 tst #1, r0
+ 0xd004, // 212 mov.l @(_s_ok,pc), r0
+ 0x8b0a, // 214 bf cd_start
+ 0xc209, // 216 mov.l r0, @(h'24,gbr)
+ 0x6822, // 218 mov.l @r2, r8
+ 0x482b, // 21a jmp @r8
+ 0x0009, // 21c nop
+ 0x0009, // 21e nop
+ ('M'<<8)|'_', ('O'<<8)|'K', // 220
+ ('S'<<8)|'_', ('O'<<8)|'K', // 224
+ 0x2200, 0x03e4, // slave start pointer in ROM
+ // cd_start:
+ 0xd803, // 22c mov.l @(_start_cd,pc), r8 // 24000018
+ 0x5b85, // 22e mov.l @(h'14,r8), r11 // slave vbr
+ 0x5a83, // 230 mov.l @(h'0c,r8), r10 // entry
+ 0x4b2e, // 232 ldc r11, vbr
+ 0xc209, // 234 mov.l r0, @(h'24,gbr) // write S_OK
+ 0x4a2b, // 236 jmp @r10
+ 0x0009, // 238 nop
+ 0x0009, // 23a nop
+ 0x2400, 0x0018, // 23c _start_cd
+};
+
+#define HWSWAP(x) (((u16)(x) << 16) | ((x) >> 16))
+static void get_bios(void)
+{
+ u16 *ps;
+ u32 *pl;
+ int i;
+
+ // M68K ROM
+ if (p32x_bios_g != NULL) {
+ elprintf(EL_STATUS|EL_32X, "32x: using supplied 68k BIOS");
+ Byteswap(Pico32xMem->m68k_rom, p32x_bios_g, sizeof(Pico32xMem->m68k_rom));