From a80a6df774fdd32710dc801d3d68190c5ac12951 Mon Sep 17 00:00:00 2001 From: arbee Date: Mon, 16 Feb 2015 13:42:43 -0500 Subject: [PATCH] m68k: emulate instruction cache for 68020/68EC020. [R. Belmont] nw: Drivers tested gained anywhere from 3-10% unthrottled on Taito F3 and Konami GX games, 10-12% on the Mac II, and 140% on Semicom's dreamwld. --- src/emu/cpu/m68000/m68000.h | 4 +-- src/emu/cpu/m68000/m68kcpu.c | 5 +-- src/emu/cpu/m68000/m68kcpu.h | 60 +++++++++++++++++++++++------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/emu/cpu/m68000/m68000.h b/src/emu/cpu/m68000/m68000.h index 34676200026..d9b9200cee6 100644 --- a/src/emu/cpu/m68000/m68000.h +++ b/src/emu/cpu/m68000/m68000.h @@ -356,8 +356,8 @@ public: UINT16 mmu_tmp_buserror_rw; /* temporary hack: (first) bus error rw */ UINT32 ic_address[M68K_IC_SIZE]; /* instruction cache address data */ - UINT16 ic_data[M68K_IC_SIZE]; /* instruction cache content data */ - + UINT32 ic_data[M68K_IC_SIZE]; /* instruction cache content data */ + bool ic_valid[M68K_IC_SIZE]; /* instruction cache valid flags */ diff --git a/src/emu/cpu/m68000/m68kcpu.c b/src/emu/cpu/m68000/m68kcpu.c index 6c4c30d026e..bbff8fa0354 100644 --- a/src/emu/cpu/m68000/m68kcpu.c +++ b/src/emu/cpu/m68000/m68kcpu.c @@ -2478,10 +2478,11 @@ void m68000_base_device::clear_all() mmu_tmp_buserror_rw = 0; for (int i=0;icpu_type) && (m68k->cacr & M68K_CACR_EI)) - { - UINT32 ic_offset = (address >> 1) % M68K_IC_SIZE; - if (m68k->ic_address[ic_offset] == address) - { - return m68k->ic_data[ic_offset]; - } - else - { - UINT32 data = m68k->memory.readimm16(address); - if (!m68k->mmu_tmp_buserror_occurred) - { - m68k->ic_data[ic_offset] = data; - m68k->ic_address[ic_offset] = address; - } - return data; - } - } - else*/ + if (m68k->cacr & M68K_CACR_EI) { - return m68k->/*memory.*/readimm16(address); + // 68020 series I-cache (MC68020 User's Manual, Section 4 - On-Chip Cache Memory) + if (m68k->cpu_type & (CPU_TYPE_EC020 | CPU_TYPE_020)) + { + UINT32 tag = (address >> 8) | (m68k->s_flag ? 0x1000000 : 0); + int idx = (address >> 2) & 0x3f; // 1-of-64 select + + // do a cache fill if the line is invalid or the tags don't match + if ((!m68k->ic_valid[idx]) || (m68k->ic_address[idx] != tag)) + { + m68k->ic_data[idx] = m68k->read32(address & ~3); + +// printf("m68k: doing cache fill at %08x (tag %08x idx %d)\n", address, tag, idx); + + // if no buserror occured, validate the tag + if (!m68k->mmu_tmp_buserror_occurred) + { + m68k->ic_address[idx] = tag; + m68k->ic_valid[idx] = true; + } + else + { + return m68k->readimm16(address); + } + } + + // at this point, the cache is guaranteed to be valid, either as + // a hit or because we just filled it. + if (address & 2) + { + return m68k->ic_data[idx] & 0xffff; + } + else + { + return m68k->ic_data[idx] >> 16; + } + } } - // this can't happen, but Apple GCC insists -// return 0; + return m68k->readimm16(address); } /* Handles all immediate reads, does address error check, function code setting,