From 4a1fb1832381958386c1dc91a8a5422af386441d Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 11 Aug 2013 01:32:19 +0300 Subject: [PATCH] 32x: handle FEN quirk Metal Head relies on it? --- pico/32x/32x.c | 6 +++--- pico/32x/memory.c | 29 ++++++++++++++++++++++------- pico/pico_int.h | 3 ++- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/pico/32x/32x.c b/pico/32x/32x.c index dd4d0ed..0a72ddb 100644 --- a/pico/32x/32x.c +++ b/pico/32x/32x.c @@ -155,7 +155,7 @@ void PicoPower32x(void) memset(&Pico32x, 0, sizeof(Pico32x)); Pico32x.regs[0] = P32XS_REN|P32XS_nRES; // verified - Pico32x.vdp_regs[0x0a/2] = P32XV_VBLK|P32XV_HBLK|P32XV_PEN; + Pico32x.vdp_regs[0x0a/2] = P32XV_VBLK|P32XV_PEN; Pico32x.sh2_regs[0] = P32XS2_ADEN; } @@ -322,8 +322,8 @@ static inline void run_sh2(SH2 *sh2, int m68k_cycles) pevt_log_sh2_o(sh2, EVT_RUN_START); sh2->state |= SH2_STATE_RUN; cycles = C_M68K_TO_SH2(*sh2, m68k_cycles); - elprintf(EL_32X, "%csh2 +run %u %d", - sh2->is_slave?'s':'m', sh2->m68krcycles_done, cycles); + elprintf(EL_32X, "%csh2 +run %u %d @%08x", + sh2->is_slave?'s':'m', sh2->m68krcycles_done, cycles, sh2->pc); done = sh2_execute(sh2, cycles); diff --git a/pico/32x/memory.c b/pico/32x/memory.c index 11b0462..0e19d69 100644 --- a/pico/32x/memory.c +++ b/pico/32x/memory.c @@ -93,12 +93,12 @@ void p32x_m68k_poll_event(u32 flags) m68k_poll.addr = m68k_poll.cnt = 0; } -static void sh2_poll_detect(SH2 *sh2, u32 a, u32 flags) +static void sh2_poll_detect(SH2 *sh2, u32 a, u32 flags, int maxcnt) { int cycles_left = sh2_cycles_left(sh2); if (a == sh2->poll_addr && sh2->poll_cycles - cycles_left <= 10) { - if (sh2->poll_cnt++ > 3) { + if (sh2->poll_cnt++ > maxcnt) { if (!(sh2->state & flags)) elprintf(EL_32X, "%csh2 state: %02x->%02x", sh2->is_slave?'s':'m', sh2->state, sh2->state | flags); @@ -321,6 +321,8 @@ static void p32x_reg_write16(u32 a, u32 d) if (Pico32x.dmac0_fifo_ptr == DMAC_FIFO_LEN) r[6 / 2] |= P32XS_FULL; } + else + elprintf(EL_32X|EL_ANOMALY, "DREQ FIFO overflow!"); break; } @@ -363,9 +365,22 @@ static void p32x_reg_write16(u32 a, u32 d) // VDP regs static u32 p32x_vdp_read16(u32 a) { + u32 d; a &= 0x0e; - return Pico32x.vdp_regs[a / 2]; + d = Pico32x.vdp_regs[a / 2]; + if (a == 0x0a) { + // tested: FEN seems to be randomly pulsing on hcnt 0x80-0xf0, + // most often at 0xb1-0xb5, even during vblank, + // what's the deal with that? + // we'll just fake it along with hblank for now + Pico32x.vdp_fbcr_fake++; + if (Pico32x.vdp_fbcr_fake & 4) + d |= P32XV_HBLK; + if ((Pico32x.vdp_fbcr_fake & 7) == 0) + d |= P32XV_nFEN; + } + return d; } static void p32x_vdp_write8(u32 a, u32 d) @@ -442,7 +457,7 @@ static u32 p32x_sh2reg_read16(u32 a, SH2 *sh2) return (r[0] & P32XS_FM) | Pico32x.sh2_regs[0] | Pico32x.sh2irq_mask[sh2->is_slave]; case 0x04: // H count (often as comm too) - sh2_poll_detect(sh2, a, SH2_STATE_CPOLL); + sh2_poll_detect(sh2, a, SH2_STATE_CPOLL, 3); sh2s_sync_on_read(sh2); return Pico32x.sh2_regs[4 / 2]; case 0x10: // DREQ len @@ -458,7 +473,7 @@ static u32 p32x_sh2reg_read16(u32 a, SH2 *sh2) if (Pico32x.comm_dirty_68k & comreg) Pico32x.comm_dirty_68k &= ~comreg; else - sh2_poll_detect(sh2, a, SH2_STATE_CPOLL); + sh2_poll_detect(sh2, a, SH2_STATE_CPOLL, 3); sh2s_sync_on_read(sh2); return r[a / 2]; } @@ -917,7 +932,7 @@ static u32 sh2_read8_cs0(u32 a, SH2 *sh2) if ((a & 0x3ff00) == 0x4100) { d = p32x_vdp_read16(a); - sh2_poll_detect(sh2, a, SH2_STATE_VPOLL); + sh2_poll_detect(sh2, a, SH2_STATE_VPOLL, 7); goto out_16to8; } @@ -971,7 +986,7 @@ static u32 sh2_read16_cs0(u32 a, SH2 *sh2) if ((a & 0x3ff00) == 0x4100) { d = p32x_vdp_read16(a); - sh2_poll_detect(sh2, a, SH2_STATE_VPOLL); + sh2_poll_detect(sh2, a, SH2_STATE_VPOLL, 7); goto out; } diff --git a/pico/pico_int.h b/pico/pico_int.h index 34b2881..53c6f4e 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -512,7 +512,8 @@ struct Pico32x unsigned int sh2irqs; // common irqs unsigned short dmac_fifo[DMAC_FIFO_LEN]; unsigned int dmac0_fifo_ptr; - unsigned int pad; + unsigned short vdp_fbcr_fake; + unsigned short pad; unsigned char comm_dirty_68k; unsigned char comm_dirty_sh2; unsigned char pwm_irq_cnt; -- 2.39.2