mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
32x: handle FEN quirk
Metal Head relies on it?
This commit is contained in:
parent
cd0ace2832
commit
4a1fb18323
3 changed files with 27 additions and 11 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue