From eb36d9c7e631085331439a452b55b1aca54b6664 Mon Sep 17 00:00:00 2001 From: kub Date: Thu, 6 May 2021 21:19:25 +0200 Subject: [PATCH] mcd, fix timing for irq while polling detected --- pico/cd/cdc.c | 14 +++++++------- pico/cd/gfx.c | 2 +- pico/cd/mcd.c | 14 ++++++++++++-- pico/cd/memory.c | 6 +++--- pico/pico_int.h | 1 + 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/pico/cd/cdc.c b/pico/cd/cdc.c index bf688f57..70914636 100644 --- a/pico/cd/cdc.c +++ b/pico/cd/cdc.c @@ -367,7 +367,7 @@ void cdc_dma_update(void) { /* update IRQ level */ elprintf(EL_INTS, "cdc DTE irq 5"); - SekInterruptS68k(5); + pcd_irq_s68k(5, 1); } } @@ -411,7 +411,7 @@ int cdc_decoder_update(uint8 header[4]) { /* update IRQ level */ elprintf(EL_INTS, "cdc DEC irq 5"); - SekInterruptS68k(5); + pcd_irq_s68k(5, 1); } } @@ -469,13 +469,13 @@ void cdc_reg_w(unsigned char data) { /* update IRQ level */ elprintf(EL_INTS, "cdc pending irq 5"); - SekInterruptS68k(5); + pcd_irq_s68k(5, 1); } } else // if (scd.pending & (1 << 5)) { /* clear pending level 5 interrupts */ - SekInterruptClearS68k(5); + pcd_irq_s68k(5, 0); } /* abort any data transfer if data output is disabled */ @@ -614,7 +614,7 @@ void cdc_reg_w(unsigned char data) if ((cdc.ifstat | BIT_DECI) || !(cdc.ifctrl & BIT_DECIEN)) { /* clear pending level 5 interrupt */ - SekInterruptClearS68k(5); + pcd_irq_s68k(5, 0); } #endif Pico_mcd->s68k_regs[0x04+1] = 0x08; @@ -774,7 +774,7 @@ unsigned char cdc_reg_r(void) if ((cdc.ifstat | BIT_DTEI) || !(cdc.ifctrl & BIT_DTEIEN)) { /* clear pending level 5 interrupt */ - SekInterruptClearS68k(5); + pcd_irq_s68k(5, 0); } #endif @@ -826,7 +826,7 @@ unsigned short cdc_host_r(void) { /* update IRQ level */ elprintf(EL_INTS, "cdc DTE irq 5"); - SekInterruptS68k(5); + pcd_irq_s68k(5, 1); } } diff --git a/pico/cd/gfx.c b/pico/cd/gfx.c index b7d9cf1c..0a231b7a 100644 --- a/pico/cd/gfx.c +++ b/pico/cd/gfx.c @@ -421,7 +421,7 @@ void gfx_update(unsigned int cycles) if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN1) { elprintf(EL_INTS|EL_CD, "s68k: gfx_cd irq 1"); - SekInterruptS68k(1); + pcd_irq_s68k(1, 1); } } else { diff --git a/pico/cd/mcd.c b/pico/cd/mcd.c index 559fca7a..255b2e97 100644 --- a/pico/cd/mcd.c +++ b/pico/cd/mcd.c @@ -177,7 +177,7 @@ static void pcd_cdc_event(unsigned int now) if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) { elprintf(EL_INTS|EL_CD, "s68k: cdd irq 4"); - SekInterruptS68k(4); + pcd_irq_s68k(4, 1); } } @@ -188,7 +188,7 @@ static void pcd_int3_timer_event(unsigned int now) { if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN3) { elprintf(EL_INTS|EL_CD, "s68k: timer irq 3"); - SekInterruptS68k(3); + pcd_irq_s68k(3, 1); } if (Pico_mcd->s68k_regs[0x31] != 0) @@ -280,6 +280,16 @@ static void pcd_run_events(unsigned int until) oldest, event_time_next); } +void pcd_irq_s68k(int irq, int state) +{ + if (state) { + SekInterruptS68k(irq); + SekSetStopS68k(0); + Pico_mcd->m.s68k_poll_a = 0; + } else + SekInterruptClearS68k(irq); +} + int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync) { #define now SekCycleCntS68k diff --git a/pico/cd/memory.c b/pico/cd/memory.c index 255461de..f3b7a16f 100644 --- a/pico/cd/memory.c +++ b/pico/cd/memory.c @@ -150,7 +150,7 @@ void m68k_reg_write8(u32 a, u32 d) if (d && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN2)) { elprintf(EL_INTS, "m68k: s68k irq 2"); pcd_sync_s68k(SekCyclesDone(), 0); - SekInterruptS68k(2); + pcd_irq_s68k(2, 1); } return; case 1: @@ -425,7 +425,7 @@ void s68k_reg_write8(u32 a, u32 d) // XXX: emulate pending irq instead? if (Pico_mcd->s68k_regs[0x37] & 4) { elprintf(EL_INTS, "cdd export irq 4 (unmask)"); - SekInterruptS68k(4); + pcd_irq_s68k(4, 1); } } break; @@ -443,7 +443,7 @@ void s68k_reg_write8(u32 a, u32 d) if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) { elprintf(EL_INTS, "cdd export irq 4"); - SekInterruptS68k(4); + pcd_irq_s68k(4, 1); } } return; diff --git a/pico/pico_int.h b/pico/pico_int.h index 84bd2010..c4044167 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -773,6 +773,7 @@ void pcd_event_schedule(unsigned int now, enum pcd_event event, int after); void pcd_event_schedule_s68k(enum pcd_event event, int after); void pcd_prepare_frame(void); unsigned int pcd_cycles_m68k_to_s68k(unsigned int c); +void pcd_irq_s68k(int irq, int state); int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync); void pcd_run_cpus(int m68k_cycles); void pcd_soft_reset(void); -- 2.39.2