From 691abdfa0fe8668f8c9fa313f2691e89f7541f85 Mon Sep 17 00:00:00 2001 From: kub Date: Fri, 19 Apr 2024 21:08:09 +0200 Subject: [PATCH] mcd, some improvements (dma timing, interrupt handling) --- pico/cd/cdc.c | 15 ++++++++------- pico/cd/mcd.c | 5 ++--- pico/cd/memory.c | 21 ++++++++++++--------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/pico/cd/cdc.c b/pico/cd/cdc.c index de16acbc..1163cb28 100644 --- a/pico/cd/cdc.c +++ b/pico/cd/cdc.c @@ -66,6 +66,7 @@ /* PicoDrive: doing DMA at once, not using callbacks */ //#define DMA_BYTES_PER_LINE 512 +#define DMA_CYCLES_PER_BYTE 4 // or 6? enum dma_type { word_ram_0_dma_w = 1, @@ -354,7 +355,7 @@ void cdc_dma_update(void) do_dma(cdc.dma_w, cdc.dbc + 1); /* reset data byte counter (DBCH bits 4-7 should be set to 1) */ - cdc.dbc = 0xf000; + cdc.dbc = 0xffff; /* clear !DTEN and !DTBSY */ cdc.ifstat |= (BIT_DTBSY | BIT_DTEN); @@ -405,6 +406,9 @@ int cdc_decoder_update(uint8 header[4]) /* set !VALST */ cdc.stat[3] = 0x00; + /* set CRCOK bit */ + cdc.stat[0] = BIT_DECEN; + /* pending decoder interrupt */ cdc.ifstat &= ~BIT_DECI; @@ -602,7 +606,7 @@ void cdc_reg_w(unsigned char data) } if (cdc.dma_w) - pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc / 2); + pcd_event_schedule_s68k(PCD_EVENT_DMA, cdc.dbc * DMA_CYCLES_PER_BYTE); } Pico_mcd->s68k_regs[0x04+1] = 0x07; @@ -643,11 +647,8 @@ void cdc_reg_w(unsigned char data) case 0x0a: /* CTRL0 */ { - /* set CRCOK bit only if decoding is enabled */ - cdc.stat[0] = data & BIT_DECEN; - /* reset DECI if decoder turned off */ - if (!cdc.stat[0]) + if (!(data & BIT_DECEN)) cdc.ifstat |= BIT_DECI; /* update decoding mode */ @@ -827,7 +828,7 @@ unsigned short cdc_host_r(void) if ((int16)cdc.dbc <= 0) { /* reset data byte counter (DBCH bits 4-7 should be set to 1) */ - cdc.dbc = 0xf000; + cdc.dbc = 0xffff; /* clear !DTEN and !DTBSY */ cdc.ifstat |= (BIT_DTBSY | BIT_DTEN); diff --git a/pico/cd/mcd.c b/pico/cd/mcd.c index 44376322..2fdbe725 100644 --- a/pico/cd/mcd.c +++ b/pico/cd/mcd.c @@ -149,7 +149,7 @@ static void pcd_cdc_event(unsigned int now) /* reset CDD command wait flag */ Pico_mcd->s68k_regs[0x4b] = 0xf0; - if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) { + if ((Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) && (Pico_mcd->s68k_regs[0x37] & 4)) { elprintf(EL_INTS|EL_CD, "s68k: cdd irq 4"); pcd_irq_s68k(4, 1); } @@ -209,8 +209,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) { - if (SekCyclesLeftS68k > after) - SekEndRunS68k(after); + SekEndRunS68k(after); pcd_event_schedule(SekCyclesDoneS68k(), event, after); } diff --git a/pico/cd/memory.c b/pico/cd/memory.c index b13644b1..fc4ddb72 100644 --- a/pico/cd/memory.c +++ b/pico/cd/memory.c @@ -142,7 +142,7 @@ static u32 m68k_reg_read16(u32 a) // comm flag/cmd/status (0xE-0x2F) m68k_comm_check(a); d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1]; - goto end; + return d; } elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a); @@ -172,7 +172,8 @@ void m68k_reg_write8(u32 a, u32 d) elprintf(EL_INTS, "m68k: s68k irq 2"); pcd_sync_s68k(SekCyclesDone(), 0); pcd_irq_s68k(2, 1); - } + } else + pcd_irq_s68k(2, 0); return; case 1: d &= 3; @@ -456,9 +457,9 @@ void s68k_reg_write8(u32 a, u32 d) case 0x33: // IRQ mask elprintf(EL_CDREGS|EL_CD, "s68k irq mask: %02x", d); d &= 0x7e; - if ((d ^ Pico_mcd->s68k_regs[0x33]) & d & PCDS_IEN4) { + if ((d ^ Pico_mcd->s68k_regs[0x33]) & PCDS_IEN4) { // XXX: emulate pending irq instead? - if (Pico_mcd->s68k_regs[0x37] & 4) { + if ((d & PCDS_IEN4) && (Pico_mcd->s68k_regs[0x37] & 4)) { elprintf(EL_INTS, "cdd export irq 4 (unmask)"); pcd_irq_s68k(4, 1); } @@ -474,11 +475,12 @@ void s68k_reg_write8(u32 a, u32 d) case 0x37: { u32 d_old = Pico_mcd->s68k_regs[0x37]; Pico_mcd->s68k_regs[0x37] = d & 7; - if ((d&4) && !(d_old&4)) { + if ((d ^ d_old) & 4) { // ?? - pcd_event_schedule_s68k(PCD_EVENT_CDC, 12500000/75); + if (d & 4) + pcd_event_schedule_s68k(PCD_EVENT_CDC, 12500000/75); - if (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4) { + if ((d & 4) && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4)) { elprintf(EL_INTS, "cdd export irq 4"); pcd_irq_s68k(4, 1); } @@ -1223,9 +1225,10 @@ static void m68k_mem_setup_cd(void); PICO_INTERNAL void PicoMemSetupCD(void) { - if (!Pico_mcd) + if (!Pico_mcd) { Pico_mcd = plat_mmap(0x05000000, sizeof(mcd_state), 0, 0); - memset(Pico_mcd, 0, sizeof(mcd_state)); + memset(Pico_mcd, 0, sizeof(mcd_state)); + } pcd_base_address = (Pico.romsize > 0x20000 ? 0x400000 : 0x000000); // setup default main68k map -- 2.39.5