diff --git a/src/emu/cpu/sh4/sh4.c b/src/emu/cpu/sh4/sh4.c index 0b27614c209..a79b1139eb1 100644 --- a/src/emu/cpu/sh4/sh4.c +++ b/src/emu/cpu/sh4/sh4.c @@ -30,6 +30,24 @@ #include "sh3comn.h" #include "sh4tmu.h" +#if SH4_USE_FASTRAM_OPTIMIZATION +void sh34_base_device::add_fastram(offs_t start, offs_t end, UINT8 readonly, void *base) +{ + if (m_fastram_select < ARRAY_LENGTH(m_fastram)) + { + m_fastram[m_fastram_select].start = start; + m_fastram[m_fastram_select].end = end; + m_fastram[m_fastram_select].readonly = readonly; + m_fastram[m_fastram_select].base = base; + m_fastram_select++; + } +} +#else +void sh34_base_device::add_fastram(offs_t start, offs_t end, UINT8 readonly, void *base) +{ +} +#endif + CPU_DISASSEMBLE( sh4 ); CPU_DISASSEMBLE( sh4be ); @@ -79,7 +97,17 @@ sh34_base_device::sh34_base_device(const machine_config &mconfig, device_type ty , c_md7(0) , c_md8(0) , c_clock(0) +#if SH4_USE_FASTRAM_OPTIMIZATION + , m_bigendian(endianness == ENDIANNESS_BIG) + , m_byte_xor(m_bigendian ? BYTE8_XOR_BE(0) : BYTE8_XOR_LE(0)) + , m_word_xor(m_bigendian ? WORD2_XOR_BE(0) : WORD2_XOR_LE(0)) + , m_dword_xor(m_bigendian ? DWORD_XOR_BE(0) : DWORD_XOR_LE(0)) + , m_fastram_select(0) +#endif { +#if SH4_USE_FASTRAM_OPTIMIZATION + memset(m_fastram, 0, sizeof(m_fastram)); +#endif } @@ -233,7 +261,22 @@ inline UINT8 sh34_base_device::RB(offs_t A) if (A >= 0xe0000000) return m_program->read_byte(A); +#if SH4_USE_FASTRAM_OPTIMIZATION + const offs_t _A = A & AM; + for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) + { + if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) + { + continue; + } + UINT8 *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; + return fastbase[_A ^ m_byte_xor]; + } + return m_program->read_byte(_A); +#else return m_program->read_byte(A & AM); +#endif + } inline UINT16 sh34_base_device::RW(offs_t A) @@ -241,7 +284,22 @@ inline UINT16 sh34_base_device::RW(offs_t A) if (A >= 0xe0000000) return m_program->read_word(A); +#if SH4_USE_FASTRAM_OPTIMIZATION + const offs_t _A = A & AM; + for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) + { + if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) + { + continue; + } + UINT8 *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; + return ((UINT16*)fastbase)[(_A ^ m_word_xor) >> 1]; + } + return m_program->read_word(_A); +#else return m_program->read_word(A & AM); +#endif + } inline UINT32 sh34_base_device::RL(offs_t A) @@ -249,7 +307,22 @@ inline UINT32 sh34_base_device::RL(offs_t A) if (A >= 0xe0000000) return m_program->read_dword(A); +#if SH4_USE_FASTRAM_OPTIMIZATION + const offs_t _A = A & AM; + for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) + { + if (_A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) + { + continue; + } + UINT8 *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; + return ((UINT32*)fastbase)[(_A^m_dword_xor) >> 2]; + } + return m_program->read_dword(_A); +#else return m_program->read_dword(A & AM); +#endif + } inline void sh34_base_device::WB(offs_t A, UINT8 V) @@ -259,8 +332,23 @@ inline void sh34_base_device::WB(offs_t A, UINT8 V) m_program->write_byte(A,V); return; } - +#if SH4_USE_FASTRAM_OPTIMIZATION + const offs_t _A = A & AM; + for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) + { + if (m_fastram[ramnum].readonly == TRUE || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) + { + continue; + } + UINT8 *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; + fastbase[_A ^ m_byte_xor] = V; + return; + } + m_program->write_byte(_A,V); +#else m_program->write_byte(A & AM,V); +#endif + } inline void sh34_base_device::WW(offs_t A, UINT16 V) @@ -270,8 +358,23 @@ inline void sh34_base_device::WW(offs_t A, UINT16 V) m_program->write_word(A,V); return; } - +#if SH4_USE_FASTRAM_OPTIMIZATION + const offs_t _A = A & AM; + for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) + { + if (m_fastram[ramnum].readonly == TRUE || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) + { + continue; + } + void *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; + ((UINT16*)fastbase)[(_A ^ m_word_xor) >> 1] = V; + return; + } + m_program->write_word(_A,V); +#else m_program->write_word(A & AM,V); +#endif + } inline void sh34_base_device::WL(offs_t A, UINT32 V) @@ -281,8 +384,22 @@ inline void sh34_base_device::WL(offs_t A, UINT32 V) m_program->write_dword(A,V); return; } - +#if SH4_USE_FASTRAM_OPTIMIZATION + const offs_t _A = A & AM; + for (int ramnum = 0; ramnum < m_fastram_select; ramnum++) + { + if (m_fastram[ramnum].readonly == TRUE || _A < m_fastram[ramnum].start || _A > m_fastram[ramnum].end) + { + continue; + } + void *fastbase = (UINT8*)m_fastram[ramnum].base - m_fastram[ramnum].start; + ((UINT32*)fastbase)[(_A ^ m_dword_xor) >> 2] = V; + return; + } + m_program->write_dword(_A,V); +#else m_program->write_dword(A & AM,V); +#endif } /* code cycles t-bit diff --git a/src/emu/cpu/sh4/sh4.h b/src/emu/cpu/sh4/sh4.h index d50dc1c7f02..5edb6474988 100644 --- a/src/emu/cpu/sh4/sh4.h +++ b/src/emu/cpu/sh4/sh4.h @@ -11,6 +11,9 @@ #ifndef __SH4_H__ #define __SH4_H__ +// doesn't actually seem to improve performance at all +#define SH4_USE_FASTRAM_OPTIMIZATION 0 +#define SH4_MAX_FASTRAM 3 #define SH4_INT_NONE -1 enum @@ -171,6 +174,10 @@ public: // construction/destruction sh34_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, endianness_t endianness, address_map_constructor internal); +//#if SH4_USE_FASTRAM_OPTIMIZATION + void add_fastram(offs_t start, offs_t end, UINT8 readonly, void *base); +//#endif + static void set_md0(device_t &device, int md0) { downcast(device).c_md0 = md0; } static void set_md1(device_t &device, int md0) { downcast(device).c_md1 = md0; } static void set_md2(device_t &device, int md0) { downcast(device).c_md2 = md0; } @@ -683,6 +690,21 @@ protected: UINT32 sh4_handle_chcr3_addr_r(UINT32 mem_mask) { return m_SH4_CHCR3; } UINT32 sh4_handle_dmaor_addr_r(UINT32 mem_mask) { return m_SH4_DMAOR; } +#if SH4_USE_FASTRAM_OPTIMIZATION + /* fast RAM */ + bool m_bigendian; + UINT32 m_byte_xor; + UINT32 m_word_xor; + UINT32 m_dword_xor; + UINT32 m_fastram_select; + struct + { + offs_t start; /* start of the RAM block */ + offs_t end; /* end of the RAM block */ + UINT8 readonly; /* TRUE if read-only */ + void * base; /* base in memory where the RAM lives */ + } m_fastram[SH4_MAX_FASTRAM]; +#endif }; diff --git a/src/mame/drivers/cv1k.c b/src/mame/drivers/cv1k.c index d133d7fa5ad..fa09d9fd124 100644 --- a/src/mame/drivers/cv1k.c +++ b/src/mame/drivers/cv1k.c @@ -188,15 +188,20 @@ public: m_serflash(*this, "game"), m_eeprom(*this, "eeprom"), m_ram(*this, "mainram"), + m_rombase(*this, "rombase"), m_blitrate(*this, "BLITRATE"), - m_eepromout(*this, "EEPROMOUT") { } + m_eepromout(*this, "EEPROMOUT"), + m_idleramoffs(0), + m_idlepc(0) + { } - required_device m_maincpu; + required_device m_maincpu; required_device m_blitter; required_device m_serflash; required_device m_eeprom; required_shared_ptr m_ram; + required_shared_ptr m_rombase; DECLARE_READ8_MEMBER(cv1k_flash_io_r); DECLARE_WRITE8_MEMBER(cv1k_flash_io_w); @@ -209,13 +214,7 @@ public: virtual void machine_reset(); /* game specific */ - DECLARE_READ64_MEMBER(mushisam_speedup_r); - DECLARE_READ64_MEMBER(ibara_speedup_r); - DECLARE_READ64_MEMBER(espgal2_speedup_r); - DECLARE_READ64_MEMBER(mushitam_speedup_r); - DECLARE_READ64_MEMBER(pinkswts_speedup_r); - DECLARE_READ64_MEMBER(deathsml_speedup_r); - DECLARE_READ64_MEMBER(dpddfk_speedup_r); + DECLARE_READ64_MEMBER(cv1k_speedup_r); DECLARE_DRIVER_INIT(mushisam); DECLARE_DRIVER_INIT(ibara); DECLARE_DRIVER_INIT(espgal2); @@ -226,6 +225,10 @@ public: required_ioport m_blitrate; required_ioport m_eepromout; + + UINT32 m_idleramoffs; + UINT32 m_idlepc; + void install_cv1k_speedups(UINT32 idleramoff, UINT32 idlepc, bool is_typed); }; @@ -327,7 +330,7 @@ WRITE8_MEMBER( cv1k_state::serial_rtc_eeprom_w ) static ADDRESS_MAP_START( cv1k_map, AS_PROGRAM, 64, cv1k_state ) - AM_RANGE(0x00000000, 0x003fffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITENOP // mmmbanc writes here on startup for some reason.. + AM_RANGE(0x00000000, 0x003fffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITENOP AM_SHARE("rombase") // mmmbanc writes here on startup for some reason.. AM_RANGE(0x0c000000, 0x0c7fffff) AM_RAM AM_SHARE("mainram") AM_MIRROR(0x800000) // work RAM AM_RANGE(0x10000000, 0x10000007) AM_READWRITE8(cv1k_flash_io_r, cv1k_flash_io_w, U64(0xffffffffffffffff)) AM_RANGE(0x10400000, 0x10400007) AM_DEVWRITE8("ymz770", ymz770_device, write, U64(0xffffffffffffffff)) @@ -337,7 +340,7 @@ static ADDRESS_MAP_START( cv1k_map, AS_PROGRAM, 64, cv1k_state ) ADDRESS_MAP_END static ADDRESS_MAP_START( cv1k_d_map, AS_PROGRAM, 64, cv1k_state ) - AM_RANGE(0x00000000, 0x003fffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITENOP // mmmbanc writes here on startup for some reason.. + AM_RANGE(0x00000000, 0x003fffff) AM_ROM AM_REGION("maincpu", 0) AM_WRITENOP AM_SHARE("rombase") // mmmbanc writes here on startup for some reason.. AM_RANGE(0x0c000000, 0x0cffffff) AM_RAM AM_SHARE("mainram") // work RAM AM_RANGE(0x10000000, 0x10000007) AM_READWRITE8(cv1k_flash_io_r, cv1k_flash_io_w, U64(0xffffffffffffffff)) AM_RANGE(0x10400000, 0x10400007) AM_DEVWRITE8("ymz770", ymz770_device, write, U64(0xffffffffffffffff)) @@ -821,85 +824,60 @@ ROM_START( dfkbl ) ROM_LOAD16_WORD_SWAP( "u24", 0x400000, 0x400000, CRC(31f9eb0a) SHA1(322158779e969bb321241065dd49c1167b91ff6c) ) ROM_END - - -READ64_MEMBER( cv1k_state::mushisam_speedup_r ) +READ64_MEMBER( cv1k_state::cv1k_speedup_r ) { - if (m_maincpu->pc()== 0xc04a2aa ) m_maincpu->spin_until_time( attotime::from_usec(10)); // mushisam / mushisamb -// else printf("read %08x\n", m_maincpu->pc()); - return m_ram[0x00024d8/8]; + if (m_maincpu->pc()== m_idlepc ) m_maincpu->spin_until_time( attotime::from_usec(10)); + return m_ram[m_idleramoffs/8]; } +void cv1k_state::install_cv1k_speedups(UINT32 idleramoff, UINT32 idlepc, bool is_typed) +{ + m_idleramoffs = idleramoff; + m_idlepc = idlepc; + + m_maincpu->space(AS_PROGRAM).install_read_handler(0xc000000+m_idleramoffs, 0xc000000+m_idleramoffs+7, read64_delegate(FUNC(cv1k_state::cv1k_speedup_r),this)); + + m_maincpu->add_fastram(0x00000000, 0x003fffff, TRUE, m_rombase); + + m_maincpu->add_fastram(0x0c000000, 0x0c000000+m_idleramoffs-1, FALSE, m_ram); + m_maincpu->add_fastram(0x0c000000+m_idleramoffs+8, is_typed ? 0x0cffffff : 0x0c7fffff, FALSE, m_ram + ((m_idleramoffs+8)/8)); +} + + DRIVER_INIT_MEMBER(cv1k_state,mushisam) { - m_maincpu->space(AS_PROGRAM).install_read_handler(0xc0024d8, 0xc0024df, read64_delegate(FUNC(cv1k_state::mushisam_speedup_r),this)); -} - -READ64_MEMBER( cv1k_state::ibara_speedup_r ) -{ - if (m_maincpu->pc()== 0xc04a0aa ) m_maincpu->spin_until_time( attotime::from_usec(10)); // ibara / mushisama - return m_ram[0x0022f0/8]; + install_cv1k_speedups(0x024d8, 0xc04a2aa, false); } DRIVER_INIT_MEMBER(cv1k_state,ibara) { - m_maincpu->space(AS_PROGRAM).install_read_handler(0xc0022f0, 0xc0022f7, read64_delegate(FUNC(cv1k_state::ibara_speedup_r),this)); -} - -READ64_MEMBER( cv1k_state::espgal2_speedup_r ) -{ - if (m_maincpu->pc()== 0xc05177a ) m_maincpu->spin_until_time( attotime::from_usec(10)); // espgal2 - return m_ram[0x002310/8]; + install_cv1k_speedups(0x022f0, 0xc04a0aa, false); } DRIVER_INIT_MEMBER(cv1k_state,espgal2) { - m_maincpu->space(AS_PROGRAM).install_read_handler(0xc002310, 0xc002317, read64_delegate(FUNC(cv1k_state::espgal2_speedup_r),this)); -} - -READ64_MEMBER( cv1k_state::mushitam_speedup_r ) -{ - if (m_maincpu->pc()== 0xc04a0da) m_maincpu->spin_until_time( attotime::from_usec(10)); // mushitam / mushitama - return m_ram[0x0022f0/8]; + install_cv1k_speedups(0x02310, 0xc05177a, false); } DRIVER_INIT_MEMBER(cv1k_state,mushitam) { - m_maincpu->space(AS_PROGRAM).install_read_handler(0xc0022f0, 0xc0022f7, read64_delegate(FUNC(cv1k_state::mushitam_speedup_r),this)); -} - -READ64_MEMBER( cv1k_state::pinkswts_speedup_r ) -{ - // pinkswts / pinkswtsa / pinkswtsb / pinkswtsx / futari15 / futari15a / futari10 / futaribl / futariblj / ibarablk / ibarablka / mmpork / mmmbanc - if (m_maincpu->pc()== 0xc05176a ) m_maincpu->spin_until_time( attotime::from_usec(10)); - return m_ram[0x002310/8]; + install_cv1k_speedups(0x0022f0, 0xc04a0da, false); } DRIVER_INIT_MEMBER(cv1k_state,pinkswts) { - m_maincpu->space(AS_PROGRAM).install_read_handler(0xc002310, 0xc002317, read64_delegate(FUNC(cv1k_state::pinkswts_speedup_r),this)); -} - -READ64_MEMBER( cv1k_state::deathsml_speedup_r ) -{ - if (m_maincpu->pc()== 0xc0519a2 ) m_maincpu->spin_until_time( attotime::from_usec(10)); // deathsml - return m_ram[0x002310/8]; + install_cv1k_speedups(0x02310, 0xc05176a, false); } DRIVER_INIT_MEMBER(cv1k_state,deathsml) { - m_maincpu->space(AS_PROGRAM).install_read_handler(0xc002310, 0xc002317, read64_delegate(FUNC(cv1k_state::deathsml_speedup_r),this)); -} - -READ64_MEMBER( cv1k_state::dpddfk_speedup_r ) -{ - if (m_maincpu->pc()== 0xc1d1346 ) m_maincpu->spin_until_time( attotime::from_usec(10)); // dpddfk / dpddfk10 / dsmbl - return m_ram[0x002310/8]; + install_cv1k_speedups(0x02310, 0xc0519a2, false); } DRIVER_INIT_MEMBER(cv1k_state,dpddfk) { - m_maincpu->space(AS_PROGRAM).install_read_handler(0xc002310, 0xc002317, read64_delegate(FUNC(cv1k_state::dpddfk_speedup_r),this)); + install_cv1k_speedups(0x02310, 0xc1d1346, true); + }