From 83ff19ec52ff47992b5d6ceda3900b914eda2123 Mon Sep 17 00:00:00 2001 From: notaz Date: Sat, 3 Oct 2009 16:21:59 +0000 Subject: [PATCH] 32x: built-in BIOS; reset handling; 68k memhandler split git-svn-id: file:///home/notaz/opt/svn/PicoDrive@801 be3aeb3a-fb24-0410-a615-afba39da0efa --- cpu/sh2mame/sh2pico.c | 13 +- pico/32x/32x.c | 68 ++++++-- pico/32x/memory.c | 353 ++++++++++++++++++++++++++++++++---------- pico/cart.c | 30 ++-- pico/pico.h | 4 + pico/pico_int.h | 10 ++ platform/common/emu.c | 13 ++ 7 files changed, 373 insertions(+), 118 deletions(-) diff --git a/cpu/sh2mame/sh2pico.c b/cpu/sh2mame/sh2pico.c index 527b2fa9..e280fec5 100644 --- a/cpu/sh2mame/sh2pico.c +++ b/cpu/sh2mame/sh2pico.c @@ -41,20 +41,11 @@ void p32x_sh2_write32(unsigned int a, unsigned int d, int id); void sh2_reset(SH2 *sh2) { - int save_is_slave; - void *save_irqcallback; - - save_irqcallback = sh2->irq_callback; - save_is_slave = sh2->is_slave; - - memset(sh2, 0, sizeof(SH2)); - - sh2->is_slave = save_is_slave; - sh2->irq_callback = save_irqcallback; - sh2->pc = RL(0); sh2->r[15] = RL(4); sh2->sr = I; + sh2->vbr = 0; + sh2->pending_int_irq = 0; } static void sh2_do_irq(SH2 *sh2, int level, int vector) diff --git a/pico/32x/32x.c b/pico/32x/32x.c index 44cabd77..c75e3fe1 100644 --- a/pico/32x/32x.c +++ b/pico/32x/32x.c @@ -1,8 +1,8 @@ #include "../pico_int.h" #include "../sound/ym2612.h" -SH2 sh2s[2]; struct Pico32x Pico32x; +SH2 sh2s[2]; static void sh2_irq_cb(int id, int level) { @@ -39,15 +39,12 @@ void Pico32xStartup(void) elprintf(EL_STATUS|EL_32X, "32X startup"); PicoAHW |= PAHW_32X; - PicoMemSetup32x(); - sh2_init(&msh2, 0); msh2.irq_callback = sh2_irq_cb; - sh2_reset(&msh2); - sh2_init(&ssh2, 1); ssh2.irq_callback = sh2_irq_cb; - sh2_reset(&ssh2); + + PicoMemSetup32x(); if (!Pico.m.pal) Pico32x.vdp_regs[0] |= P32XV_nPAL; @@ -58,6 +55,54 @@ void Pico32xStartup(void) emu_32x_startup(); } +#define HWSWAP(x) (((x) << 16) | ((x) >> 16)) +void p32x_reset_sh2s(void) +{ + elprintf(EL_32X, "sh2 reset"); + + sh2_reset(&msh2); + sh2_reset(&ssh2); + + // if we don't have BIOS set, perform it's work here. + // MSH2 + if (p32x_bios_m == NULL) { + unsigned int idl_src, idl_dst, idl_size; // initial data load + unsigned int vbr; + + // initial data + idl_src = HWSWAP(*(unsigned int *)(Pico.rom + 0x3d4)) & ~0xf0000000; + idl_dst = HWSWAP(*(unsigned int *)(Pico.rom + 0x3d8)) & ~0xf0000000; + idl_size= HWSWAP(*(unsigned int *)(Pico.rom + 0x3dc)); + if (idl_size > Pico.romsize || idl_src + idl_size > Pico.romsize || + idl_size > 0x40000 || idl_dst + idl_size > 0x40000 || (idl_src & 3) || (idl_dst & 3)) { + elprintf(EL_STATUS|EL_ANOMALY, "32x: invalid initial data ptrs: %06x -> %06x, %06x", + idl_src, idl_dst, idl_size); + } + else + memcpy(Pico32xMem->sdram + idl_dst, Pico.rom + idl_src, idl_size); + + // GBR/VBR + vbr = HWSWAP(*(unsigned int *)(Pico.rom + 0x3e8)); + sh2_set_gbr(0, 0x20004000); + sh2_set_vbr(0, vbr); + + // checksum and M_OK + Pico32x.regs[0x28 / 2] = *(unsigned short *)(Pico.rom + 0x18e); + // program will set M_OK + } + + // SSH2 + if (p32x_bios_s == NULL) { + unsigned int vbr; + + // GBR/VBR + vbr = HWSWAP(*(unsigned int *)(Pico.rom + 0x3ec)); + sh2_set_gbr(1, 0x20004000); + sh2_set_vbr(1, vbr); + // program will set S_OK + } +} + void Pico32xInit(void) { } @@ -66,7 +111,7 @@ void PicoPower32x(void) { memset(&Pico32x, 0, sizeof(Pico32x)); - Pico32x.regs[0] = 0x0082; // SH2 reset? + Pico32x.regs[0] = P32XS_REN|P32XS_nRES; // verified Pico32x.vdp_regs[0x0a/2] = P32XV_VBLK|P32XV_HBLK|P32XV_PEN; Pico32x.sh2_regs[0] = P32XS2_ADEN; } @@ -82,8 +127,11 @@ void PicoUnload32x(void) void PicoReset32x(void) { - extern int p32x_csum_faked; - p32x_csum_faked = 0; // tmp + if (PicoAHW & PAHW_32X) { + Pico32x.sh2irqs |= P32XI_VRES; + p32x_update_irls(); + p32x_poll_event(3, 0); + } } static void p32x_start_blank(void) @@ -129,6 +177,8 @@ static __inline void run_m68k(int cyc) while (SekCycleCnt < SekCycleAim) { \ slice = SekCycleCnt; \ run_m68k(SekCycleAim - SekCycleCnt); \ + if (!(Pico32x.regs[0] & P32XS_nRES)) \ + continue; /* SH2s reseting */ \ slice = SekCycleCnt - slice; /* real count from 68k */ \ if (SekCycleCnt < SekCycleAim) \ elprintf(EL_32X, "slice %d", slice); \ diff --git a/pico/32x/memory.c b/pico/32x/memory.c index 1f08ab4a..1b5bdd43 100644 --- a/pico/32x/memory.c +++ b/pico/32x/memory.c @@ -1,3 +1,22 @@ +/* + * Register map: + * a15100 F....... R.....EA F.....AC N...VHMP 4000 // Fm Ren nrEs Aden Cart heN V H cMd Pwm + * a15102 ........ ......SM ? 4002 // intS intM + * a15104 ........ ......10 ........ hhhhhhhh 4004 // bk1 bk0 Hint + * a15106 F....... .....SDR UE...... .....SDR 4006 // Full 68S Dma Rv fUll[fb] Empt[fb] + * a15108 (32bit DREQ src) 4008 + * a1510c (32bit DREQ dst) 400c + * a15110 llllllll llllll00 4010 // DREQ Len + * a15112 (16bit FIFO reg) 4012 + * a15114 ? (16bit VRES clr) 4014 + * a15116 ? (16bit Vint clr) 4016 + * a15118 ? (16bit Hint clr) 4018 + * a1511a ........ .......C (16bit CMD clr) 401a // Cm + * a1511c ? (16bit PWM clr) 401c + * a1511e ? ? 401e + * a15120 (16 bytes comm) 2020 + * a15130 (PWM) 2030 + */ #include "../pico_int.h" #include "../memory.h" @@ -10,6 +29,7 @@ static const char str_mars[] = "MARS"; +void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s; struct Pico32xMem *Pico32xMem; static void bank_switch(int b); @@ -187,18 +207,14 @@ static void p32x_reg_write8(u32 a, u32 d) // for things like bset on comm port m68k_poll.cnt = 0; - if (a == 1 && !(r[0] & 1)) { - r[0] |= 1; - Pico32xStartup(); - return; - } - - if (!(r[0] & 1)) - return; - switch (a) { case 0: // adapter ctl - r[0] = (r[0] & 0x83) | ((d << 8) & P32XS_FM); + r[0] = (r[0] & ~P32XS_FM) | ((d << 8) & P32XS_FM); + return; + case 1: // adapter ctl, RES bit writeable + if ((d ^ r[0]) & d & P32XS_nRES) + p32x_reset_sh2s(); + r[0] = (r[0] & ~P32XS_nRES) | (d & P32XS_nRES); return; case 3: // irq ctl if ((d & 1) && !(Pico32x.sh2irqi[0] & P32XI_CMD)) { @@ -249,7 +265,9 @@ static void p32x_reg_write16(u32 a, u32 d) switch (a) { case 0x00: // adapter ctl - r[0] = (r[0] & 0x83) | (d & P32XS_FM); + if ((d ^ r[0]) & d & P32XS_nRES) + p32x_reset_sh2s(); + r[0] = (r[0] & ~(P32XS_FM|P32XS_nRES)) | (d & (P32XS_FM|P32XS_nRES)); return; case 0x10: // DREQ len r[a / 2] = d & ~3; @@ -591,8 +609,10 @@ static void sh2_peripheral_write32(u32 a, u32 d, int id) } // ------------------------------------------------------------------ -// default 32x handlers -u32 PicoRead8_32x(u32 a) +// 32x handlers + +// after ADEN +static u32 PicoRead8_32x_on(u32 a) { u32 d = 0; if ((a & 0xffc0) == 0x5100) { // a15100 @@ -600,8 +620,8 @@ u32 PicoRead8_32x(u32 a) goto out_16to8; } - if (!(Pico32x.regs[0] & 1)) - goto no_vdp; + if ((a & 0xfc00) != 0x5000) + return PicoRead8_io(a); if ((a & 0xfff0) == 0x5180) { // a15180 d = p32x_vdp_read16(a); @@ -613,7 +633,6 @@ u32 PicoRead8_32x(u32 a) goto out_16to8; } -no_vdp: if ((a & 0xfffc) == 0x30ec) { // a130ec d = str_mars[a & 3]; goto out; @@ -633,7 +652,7 @@ out: return d; } -u32 PicoRead16_32x(u32 a) +static u32 PicoRead16_32x_on(u32 a) { u32 d = 0; if ((a & 0xffc0) == 0x5100) { // a15100 @@ -641,8 +660,8 @@ u32 PicoRead16_32x(u32 a) goto out; } - if (!(Pico32x.regs[0] & 1)) - goto no_vdp; + if ((a & 0xfc00) != 0x5000) + return PicoRead16_io(a); if ((a & 0xfff0) == 0x5180) { // a15180 d = p32x_vdp_read16(a); @@ -654,7 +673,6 @@ u32 PicoRead16_32x(u32 a) goto out; } -no_vdp: if ((a & 0xfffc) == 0x30ec) { // a130ec d = !(a & 2) ? ('M'<<8)|'A' : ('R'<<8)|'S'; goto out; @@ -668,7 +686,7 @@ out: return d; } -void PicoWrite8_32x(u32 a, u32 d) +static void PicoWrite8_32x_on(u32 a, u32 d) { if ((a & 0xfc00) == 0x5000) elprintf(EL_32X, "m68k 32x w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); @@ -678,8 +696,10 @@ void PicoWrite8_32x(u32 a, u32 d) return; } - if (!(Pico32x.regs[0] & 1)) - goto no_vdp; + if ((a & 0xfc00) != 0x5000) { + PicoWrite8_io(a, d); + return; + } if ((a & 0xfff0) == 0x5180) { // a15180 p32x_vdp_write8(a, d); @@ -694,11 +714,10 @@ void PicoWrite8_32x(u32 a, u32 d) return; } -no_vdp: elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x", a, d & 0xff, SekPc); } -void PicoWrite16_32x(u32 a, u32 d) +static void PicoWrite16_32x_on(u32 a, u32 d) { if ((a & 0xfc00) == 0x5000) elprintf(EL_UIO, "m68k 32x w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); @@ -708,8 +727,10 @@ void PicoWrite16_32x(u32 a, u32 d) return; } - if (!(Pico32x.regs[0] & 1)) - goto no_vdp; + if ((a & 0xfc00) != 0x5000) { + PicoWrite16_io(a, d); + return; + } if ((a & 0xfff0) == 0x5180) { // a15180 p32x_vdp_write16(a, d); @@ -722,10 +743,109 @@ void PicoWrite16_32x(u32 a, u32 d) return; } -no_vdp: elprintf(EL_UIO, "m68k unmapped w16 [%06x] %04x @%06x", a, d & 0xffff, SekPc); } +// before ADEN +u32 PicoRead8_32x(u32 a) +{ + u32 d = 0; + if ((a & 0xffc0) == 0x5100) { // a15100 + // regs are always readable + d = ((u8 *)Pico32x.regs)[(a & 0x3f) ^ 1]; + goto out; + } + + if ((a & 0xfffc) == 0x30ec) { // a130ec + d = str_mars[a & 3]; + goto out; + } + + elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc); + return d; + +out: + elprintf(EL_32X, "m68k 32x r8 [%06x] %02x @%06x", a, d, SekPc); + return d; +} + +u32 PicoRead16_32x(u32 a) +{ + 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); +} + +// ----------------------------------------------------------------- + // hint vector is writeable static void PicoWrite8_hint(u32 a, u32 d) { @@ -1017,73 +1137,136 @@ void p32x_sh2_write32(u32 a, u32 d, int id) p32x_sh2_write16(a + 2, d, id); } +static const u16 msh2_code[] = { + // trap instructions + 0xaffe, // bra + 0x0009, // nop + // have to wait a bit until m68k initial program finishes clearing stuff + // to avoid races with game SH2 code, like in Tempo + 0xd004, // mov.l @(_m_ok,pc), r0 + 0xd105, // mov.l @(_cnt,pc), r1 + 0xd205, // mov.l @(_start,pc), r2 + 0x71ff, // add #-1, r1 + 0x4115, // cmp/pl r1 + 0x89fc, // bt -2 + 0xc208, // mov.l r0, @(h'20,gbr) + 0x6822, // mov.l @r2, r8 + 0x482b, // jmp @r8 + 0x0009, // nop + ('M'<<8)|'_', ('O'<<8)|'K', + 0x0001, 0x0000, + 0x2200, 0x03e0 // master start pointer in ROM +}; + +static const u16 ssh2_code[] = { + 0xaffe, // bra + 0x0009, // nop + // code to wait for master, in case authentic master BIOS is used + 0xd104, // mov.l @(_m_ok,pc), r1 + 0xd206, // mov.l @(_start,pc), r2 + 0xc608, // mov.l @(h'20,gbr), r0 + 0x3100, // cmp/eq r0, r1 + 0x8bfc, // bf #-2 + 0xd003, // mov.l @(_s_ok,pc), r0 + 0xc209, // mov.l r0, @(h'24,gbr) + 0x6822, // mov.l @r2, r8 + 0x482b, // jmp @r8 + 0x0009, // nop + ('M'<<8)|'_', ('O'<<8)|'K', + ('S'<<8)|'_', ('O'<<8)|'K', + 0x2200, 0x03e4 // slave start pointer in ROM +}; + #define HWSWAP(x) (((x) << 16) | ((x) >> 16)) -void PicoMemSetup32x(void) +static void get_bios(void) { - unsigned short *ps; - unsigned int *pl; - unsigned int rs; + u16 *ps; + u32 *pl; int i; - Pico32xMem = calloc(1, sizeof(*Pico32xMem)); - if (Pico32xMem == NULL) { - elprintf(EL_STATUS, "OOM"); - return; + // M68K ROM + if (p32x_bios_g != NULL) { + elprintf(EL_STATUS|EL_32X, "32x: using supplied 68k BIOS"); + Byteswap(Pico32xMem->m68k_rom, p32x_bios_g, 0x100); } + else { + // generate 68k ROM + ps = (u16 *)Pico32xMem->m68k_rom; + pl = (u32 *)ps; + for (i = 1; i < 0xc0/4; i++) + pl[i] = HWSWAP(0x880200 + (i - 1) * 6); - dmac0 = (void *)&Pico32xMem->sh2_peri_regs[0][0x180 / 4]; - - // generate 68k ROM - ps = (unsigned short *)Pico32xMem->m68k_rom; - pl = (unsigned int *)Pico32xMem->m68k_rom; - for (i = 1; i < 0xc0/4; i++) - pl[i] = HWSWAP(0x880200 + (i - 1) * 6); - - // fill with nops - for (i = 0xc0/2; i < 0x100/2; i++) - ps[i] = 0x4e71; + // fill with nops + for (i = 0xc0/2; i < 0x100/2; i++) + ps[i] = 0x4e71; #if 0 - ps[0xc0/2] = 0x46fc; - ps[0xc2/2] = 0x2700; // move #0x2700,sr - ps[0xfe/2] = 0x60fe; // jump to self + ps[0xc0/2] = 0x46fc; + ps[0xc2/2] = 0x2700; // move #0x2700,sr + ps[0xfe/2] = 0x60fe; // jump to self #else - ps[0xfe/2] = 0x4e75; // rts + ps[0xfe/2] = 0x4e75; // rts #endif - - // fill remaining mem with ROM + } + // fill remaining m68k_rom page with game ROM memcpy(Pico32xMem->m68k_rom + 0x100, Pico.rom + 0x100, sizeof(Pico32xMem->m68k_rom) - 0x100); - // 32X ROM - // TODO: move - { - FILE *f = fopen("32X_M_BIOS.BIN", "rb"); - int i; - if (f == NULL) { - printf("missing 32X_M_BIOS.BIN\n"); - exit(1); - } - fread(Pico32xMem->sh2_rom_m, 1, sizeof(Pico32xMem->sh2_rom_m), f); - fclose(f); - f = fopen("32X_S_BIOS.BIN", "rb"); - if (f == NULL) { - printf("missing 32X_S_BIOS.BIN\n"); - exit(1); - } - fread(Pico32xMem->sh2_rom_s, 1, sizeof(Pico32xMem->sh2_rom_s), f); - fclose(f); - // byteswap - for (i = 0; i < sizeof(Pico32xMem->sh2_rom_m); i += 2) { - int t = Pico32xMem->sh2_rom_m[i]; - Pico32xMem->sh2_rom_m[i] = Pico32xMem->sh2_rom_m[i + 1]; - Pico32xMem->sh2_rom_m[i + 1] = t; - } - for (i = 0; i < sizeof(Pico32xMem->sh2_rom_s); i += 2) { - int t = Pico32xMem->sh2_rom_s[i]; - Pico32xMem->sh2_rom_s[i] = Pico32xMem->sh2_rom_s[i + 1]; - Pico32xMem->sh2_rom_s[i + 1] = t; - } + // MSH2 + if (p32x_bios_m != NULL) { + elprintf(EL_STATUS|EL_32X, "32x: using supplied master SH2 BIOS"); + Byteswap(Pico32xMem->sh2_rom_m, p32x_bios_m, sizeof(Pico32xMem->sh2_rom_m)); } + else { + pl = (u32 *)Pico32xMem->sh2_rom_m; + + // fill exception vector table to our trap address + for (i = 0; i < 128; i++) + pl[i] = HWSWAP(0x200); + + // startup code + memcpy(Pico32xMem->sh2_rom_m + 0x200, msh2_code, sizeof(msh2_code)); + + // reset SP + pl[1] = pl[3] = HWSWAP(0x6040000); + // start + pl[0] = pl[2] = HWSWAP(0x204); + } + + // SSH2 + if (p32x_bios_s != NULL) { + elprintf(EL_STATUS|EL_32X, "32x: using supplied slave SH2 BIOS"); + Byteswap(Pico32xMem->sh2_rom_s, p32x_bios_s, sizeof(Pico32xMem->sh2_rom_s)); + } + else { + pl = (u32 *)Pico32xMem->sh2_rom_s; + + // fill exception vector table to our trap address + for (i = 0; i < 128; i++) + pl[i] = HWSWAP(0x200); + + // startup code + memcpy(Pico32xMem->sh2_rom_s + 0x200, ssh2_code, sizeof(ssh2_code)); + + // reset SP + pl[1] = pl[3] = HWSWAP(0x603f800); + // start + pl[0] = pl[2] = HWSWAP(0x204); + } +} + +void PicoMemSetup32x(void) +{ + unsigned int rs; + + Pico32xMem = calloc(1, sizeof(*Pico32xMem)); + if (Pico32xMem == NULL) { + elprintf(EL_STATUS, "OOM"); + return; + } + + dmac0 = (void *)&Pico32xMem->sh2_peri_regs[0][0x180 / 4]; + + get_bios(); // cartridge area becomes unmapped // XXX: we take the easy way and don't unmap ROM, @@ -1110,6 +1293,12 @@ void PicoMemSetup32x(void) // 32X ROM (banked) bank_switch(0); + // SYS regs + cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_32x_on, 1); + cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_32x_on, 1); + cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_32x_on, 1); + cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_32x_on, 1); + // setup poll detector m68k_poll.flag = P32XF_68KPOLL; m68k_poll.cyc_max = 64; diff --git a/pico/cart.c b/pico/cart.c index cbd4bb63..26fb59bb 100644 --- a/pico/cart.c +++ b/pico/cart.c @@ -378,23 +378,21 @@ int pm_close(pm_file *fp) return ret; } - -static void Byteswap(unsigned char *data,int len) +// byteswap, data needs to be int aligned, src can match dst +void Byteswap(void *dst, const void *src, int len) { - int i=0; - - if (len<2) return; // Too short + const unsigned int *ps = src; + unsigned int *pd = dst; + int i, m; - do - { - unsigned short *pd=(unsigned short *)(data+i); - int value=*pd; // Get 2 bytes + if (len < 2) + return; - value=(value<<8)|(value>>8); // Byteswap it - *pd=(unsigned short)value; // Put 2b ytes - i+=2; + m = 0x00ff00ff; + for (i = 0; i < len / 4; i++) { + unsigned int t = ps[i]; + pd[i] = ((t & m) << 8) | ((t & ~m) >> 8); } - while (i+2<=len); } // Interleve a 16k block and byteswap @@ -524,7 +522,7 @@ int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize,int is_sms) elprintf(EL_STATUS, "SMD format detected."); DecodeSmd(rom,size); size-=0x200; // Decode and byteswap SMD } - else Byteswap(rom,size); // Just byteswap + else Byteswap(rom, rom, size); // Just byteswap } else { @@ -621,9 +619,9 @@ static unsigned int rom_crc32(void) elprintf(EL_STATUS, "caclulating CRC32.."); // have to unbyteswap for calculation.. - Byteswap(Pico.rom, Pico.romsize); + Byteswap(Pico.rom, Pico.rom, Pico.romsize); crc = crc32(0, Pico.rom, Pico.romsize); - Byteswap(Pico.rom, Pico.romsize); + Byteswap(Pico.rom, Pico.rom, Pico.romsize); return crc; } diff --git a/pico/pico.h b/pico/pico.h index 7b1a8930..05f9fab6 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -37,6 +37,10 @@ extern void emu_video_mode_change(int start_line, int line_count, int is_32cols) // this must switch to 32bpp mode extern void emu_32x_startup(void); +// optional 32X BIOS, should be left NULL if not used +// must be 256, 2048, 1024 bytes +extern void *p32x_bios_g, *p32x_bios_m, *p32x_bios_s; + // Pico.c #define POPT_EN_FM (1<< 0) // 00 000x #define POPT_EN_PSG (1<< 1) diff --git a/pico/pico_int.h b/pico/pico_int.h index b84b1316..9ed600ed 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -252,6 +252,11 @@ extern SH2 sh2s[2]; #define sh2_vbr(c) (c) ? ssh2.vbr : msh2.vbr #define sh2_sr(c) (c) ? ssh2.sr : msh2.sr +#define sh2_set_gbr(c, v) \ + { if (c) ssh2.gbr = v; else msh2.gbr = v; } +#define sh2_set_vbr(c, v) \ + { if (c) ssh2.vbr = v; else msh2.vbr = v; } + // --------------------------------------------------------- // main oscillator clock which controls timing @@ -416,6 +421,9 @@ typedef struct // 32X #define P32XS_FM (1<<15) +#define P32XS_REN (1<< 7) +#define P32XS_nRES (1<< 1) +#define P32XS_ADEN (1<< 0) #define P32XS2_ADEN (1<< 9) #define P32XS_FULL (1<< 7) // DREQ FIFO full #define P32XS_68S (1<< 2) @@ -514,6 +522,7 @@ extern areaseek *areaSeek; extern areaclose *areaClose; // cart.c +void Byteswap(void *dst, const void *src, int len); extern void (*PicoCartMemSetup)(void); extern void (*PicoCartUnloadHook)(void); @@ -680,6 +689,7 @@ void Pico32xStartup(void); void PicoUnload32x(void); void PicoFrame32x(void); void p32x_update_irls(void); +void p32x_reset_sh2s(void); // 32x/memory.c struct Pico32xMem *Pico32xMem; diff --git a/platform/common/emu.c b/platform/common/emu.c index 507437af..a8de9023 100644 --- a/platform/common/emu.c +++ b/platform/common/emu.c @@ -1299,6 +1299,19 @@ void emu_init(void) char path[512]; int pos; +#if 0 + // FIXME: handle through menu, etc + FILE *f; + f = fopen("32X_M_BIOS.BIN", "rb"); + p32x_bios_m = malloc(2048); + fread(p32x_bios_m, 1, 2048, f); + fclose(f); + f = fopen("32X_S_BIOS.BIN", "rb"); + p32x_bios_s = malloc(1024); + fread(p32x_bios_s, 1, 1024, f); + fclose(f); +#endif + /* make dirs for saves */ pos = plat_get_root_dir(path, sizeof(path) - 4); mkdir_path(path, pos, "mds"); -- 2.39.5