From ba6e8bfd4b707aab042e47bc3e2a14f70be01075 Mon Sep 17 00:00:00 2001 From: notaz Date: Wed, 28 Aug 2013 03:07:33 +0300 Subject: [PATCH] cd: clean up dmna handling, stuff --- pico/cd/mcd.c | 17 +++++++++-- pico/cd/memory.c | 73 +++++++++++++++++++++++++----------------------- pico/pico_int.h | 2 +- 3 files changed, 54 insertions(+), 38 deletions(-) diff --git a/pico/cd/mcd.c b/pico/cd/mcd.c index 539d157..82ae1bc 100644 --- a/pico/cd/mcd.c +++ b/pico/cd/mcd.c @@ -252,15 +252,18 @@ int pcd_sync_s68k(unsigned int m68k_target, int m68k_poll_sync) #undef now } +#define pcd_run_cpus_normal pcd_run_cpus +//#define pcd_run_cpus_lockstep pcd_run_cpus + static void SekSyncM68k(void); -static void pcd_run_cpus(int m68k_cycles) +static inline void pcd_run_cpus_normal(int m68k_cycles) { SekCycleAim += m68k_cycles; if (Pico_mcd->m.m68k_poll_cnt >= 16 && !SekShouldInterrupt()) { int s68k_left = pcd_sync_s68k(SekCycleAim, 1); if (s68k_left <= 0) { - elprintf(EL_CDPOLL, "m68k poll [%02x] %d @%06x", + elprintf(EL_CDPOLL, "m68k poll [%02x] x%d @%06x", Pico_mcd->m.m68k_poll_a, Pico_mcd->m.m68k_poll_cnt, SekPc); SekCycleCnt = SekCycleAim; return; @@ -271,6 +274,16 @@ static void pcd_run_cpus(int m68k_cycles) SekSyncM68k(); } +static inline void pcd_run_cpus_lockstep(int m68k_cycles) +{ + unsigned int target = SekCycleAim + m68k_cycles; + do { + SekCycleAim += 8; + SekSyncM68k(); + pcd_sync_s68k(SekCycleAim, 0); + } while (CYCLES_GT(target, SekCycleAim)); +} + #define PICO_CD #define CPUS_RUN(m68k_cycles) \ pcd_run_cpus(m68k_cycles) diff --git a/pico/cd/memory.c b/pico/cd/memory.c index 82e6d6d..f8ffaeb 100644 --- a/pico/cd/memory.c +++ b/pico/cd/memory.c @@ -184,24 +184,24 @@ void m68k_reg_write8(u32 a, u32 d) case 3: dold = Pico_mcd->s68k_regs[3]; elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc); - //if ((Pico_mcd->s68k_regs[3]&4) != (d&4)) dprintf("m68k: ram mode %i mbit", (d&4) ? 1 : 2); - //if ((Pico_mcd->s68k_regs[3]&2) != (d&2)) dprintf("m68k: %s", (d&4) ? ((d&2) ? "word swap req" : "noop?") : - // ((d&2) ? "word ram to s68k" : "word ram to m68k")); - if (dold & 4) { // 1M mode - d ^= 2; // writing 0 to DMNA actually sets it, 1 does nothing - } else { - if ((d ^ dold) & d & 2) { // DMNA is being set - dold &= ~1; // return word RAM to s68k - /* Silpheed hack: bset(w3), r3, btst, bne, r3 */ - SekEndRun(20+16+10+12+16); - } - } - d = (d & 0xc2) | (dold & 0x1f); if ((d ^ dold) & 0xc0) { elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3)); remap_prg_window(d); } + + // 2M mode state is tracked regardless of current mode + if (d & 2) { + Pico_mcd->m.dmna_ret_2m |= 2; + Pico_mcd->m.dmna_ret_2m &= ~1; + } + if (dold & 4) { // 1M mode + d ^= 2; // 0 sets DMNA, 1 does nothing + d = (d & 0xc2) | (dold & 0x1f); + } + else + d = (d & 0xc0) | (dold & 0x1c) | Pico_mcd->m.dmna_ret_2m; + goto write_comm; case 6: Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer @@ -343,35 +343,34 @@ void s68k_reg_write8(u32 a, u32 d) elprintf(EL_CDREG3, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k); d &= 0x1d; d |= dold & 0xc2; + + // 2M mode state + if (d & 1) { + Pico_mcd->m.dmna_ret_2m |= 1; + Pico_mcd->m.dmna_ret_2m &= ~2; // DMNA clears + } + if (d & 4) { - if ((d ^ dold) & 0x1d) { - d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit - remap_word_ram(d); - } if (!(dold & 4)) { elprintf(EL_CDREG3, "wram mode 2M->1M"); wram_2M_to_1M(Pico_mcd->word_ram2M); } + + if ((d ^ dold) & 0x1d) + remap_word_ram(d); + + if ((d ^ dold) & 0x05) + d &= ~2; // clear DMNA - swap complete } else { if (dold & 4) { elprintf(EL_CDREG3, "wram mode 1M->2M"); - if (!(d&1)) { // it didn't set the ret bit, which means it doesn't want to give WRAM to m68k - d &= ~3; - d |= (dold&1) ? 2 : 1; // then give it to the one which had bank0 in 1M mode - } wram_1M_to_2M(Pico_mcd->word_ram2M); remap_word_ram(d); } - // s68k can only set RET, writing 0 has no effect - else if ((dold ^ d) & d & 1) { // RET being set - SekEndRunS68k(20+16+10+12+16); // see DMNA case - } else - d |= dold & 1; - if (d & 1) - d &= ~2; // DMNA clears + d = (d & ~3) | Pico_mcd->m.dmna_ret_2m; } goto write_comm; } @@ -806,20 +805,22 @@ static u32 PicoReadS68k8_pr(u32 a) // regs if ((a & 0xfe00) == 0x8000) { a &= 0x1ff; - elprintf(EL_CDREGS, "s68k_regs r8: [%02x] @ %06x", a, SekPcS68k); if (a >= 0x0e && a < 0x30) { d = Pico_mcd->s68k_regs[a]; s68k_poll_detect(a, d); - elprintf(EL_CDREGS, "ret = %02x", (u8)d); - return d; + goto regs_done; } else if (a >= 0x58 && a < 0x68) d = gfx_cd_read(a & ~1); else d = s68k_reg_read16(a & ~1); if (!(a & 1)) d >>= 8; - elprintf(EL_CDREGS, "ret = %02x", (u8)d); - return d & 0xff; + +regs_done: + d &= 0xff; + elprintf(EL_CDREGS, "s68k_regs r8: [%02x] %02x @ %06x", + a, d, SekPcS68k); + return d; } // PCM @@ -847,11 +848,12 @@ static u32 PicoReadS68k16_pr(u32 a) // regs if ((a & 0xfe00) == 0x8000) { a &= 0x1fe; - elprintf(EL_CDREGS, "s68k_regs r16: [%02x] @ %06x", a, SekPcS68k); if (0x58 <= a && a < 0x68) d = gfx_cd_read(a); else d = s68k_reg_read16(a); - elprintf(EL_CDREGS, "ret = %04x", d); + + elprintf(EL_CDREGS, "s68k_regs r16: [%02x] %04x @ %06x", + a, d, SekPcS68k); return d; } @@ -1024,6 +1026,7 @@ void pcd_state_loaded_mem(void) wram_2M_to_1M(Pico_mcd->word_ram2M); remap_word_ram(r3); remap_prg_window(r3); + Pico_mcd->m.dmna_ret_2m &= 3; // restore hint vector *(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector; diff --git a/pico/pico_int.h b/pico/pico_int.h index be56abd..2053ac6 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -395,7 +395,7 @@ struct mcd_misc unsigned short s68k_poll_cnt; unsigned int s68k_poll_clk; unsigned char bcram_reg; // 18: battery-backed RAM cart register - unsigned char pad2; + unsigned char dmna_ret_2m; unsigned short pad3; int pad4[9]; }; -- 2.39.2