From 2a33336d959243c7877c0f50493162bf9131782b Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 10 Nov 2022 03:45:57 +1100 Subject: bus/gameboy: Added support for newer NT/Makon cartridges. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bus/gameboy: Removed the non-working "Digimon 2" cartridge device. gbcolor.xml: Corrected titles for a few Chinese games. New working software items (gbcolor.xml) ---------------------------------------- Capcom Vs. SNK: Millennium Fight 2001 (China) [Pepper9801, taizou] Digimon 02 4 (China) [taizou] Digimon 2 (China) [Robyn A1200, taizou] Digimon Pocket (China) [taizou] Harry Potter 3 (China) [taizou] Pokémon Diamond: Special Pikachu Edition [taizou] Pokémon Jade: Special Pikachu Edition [taizou] Pokémon: Mewtwo Strikes Back [taizou] Street Fighter Zero 4 (China) [taizou] Software items promoted to working (gbcolor.xml) ------------------------------------------------ Shùmǎ Bào Lóng 02 4 (China) [Vas Crabb] Shùmǎ Bào Lóng 3 Shuǐjīng Bǎn (China) [Vas Crabb] --- hash/gbcolor.xml | 256 ++++++++++++++++++++++++++--------- scripts/src/bus.lua | 2 + src/devices/bus/gameboy/cartbase.cpp | 102 ++++++++++++++ src/devices/bus/gameboy/cartbase.h | 31 +++++ src/devices/bus/gameboy/carts.cpp | 5 +- src/devices/bus/gameboy/carts.h | 2 +- src/devices/bus/gameboy/gbslot.cpp | 3 + src/devices/bus/gameboy/gbxfile.h | 1 + src/devices/bus/gameboy/mbc.cpp | 67 --------- src/devices/bus/gameboy/mbc.h | 1 - src/devices/bus/gameboy/mbc6.cpp | 125 +++-------------- src/devices/bus/gameboy/mmm01.cpp | 2 +- src/devices/bus/gameboy/ntnew.cpp | 166 +++++++++++++++++++++++ src/devices/bus/gameboy/ntnew.h | 18 +++ 14 files changed, 536 insertions(+), 245 deletions(-) create mode 100644 src/devices/bus/gameboy/ntnew.cpp create mode 100644 src/devices/bus/gameboy/ntnew.h diff --git a/hash/gbcolor.xml b/hash/gbcolor.xml index 152fcae4380..c1384a55e2f 100644 --- a/hash/gbcolor.xml +++ b/hash/gbcolor.xml @@ -25842,22 +25842,6 @@ license:CC0 - - Shuma Baobei - Hai Zhi Shen (China) - 200? - Li Cheng - - - - - - - - - - - - Mo Jie 3 - Bu Wanme De Shijie (China) 200? @@ -27772,12 +27756,12 @@ license:CC0 - Ying Xiong Chuan Shuo (China) + Yīngxióng Chuánshuō (China) 20?? Waixing - + @@ -27914,111 +27898,249 @@ license:CC0 - - - Super Mario 3 Special (China) - 2000 - Yong Yong + + + Capcom Vs. SNK: Millennium Fight 2001 (China) + 200? + Makon - - - + + + - - - Digimon 2 (China) - 20?? - Yong Yong + + Digimon 02 4 (China) + 200? + Makon - - - + + + - + + + + + + Shùmǎ Bào Lóng 02 4 (China) + 200? + Makon + + + + + + - + - Digimon 2 (China, Hacked) + Shùmǎ Bào Lóng 02 4 (China, hacked) 20?? Yong Yong + - + - - Digimon 3 Crystal (China) + + + Shùmǎ Bào Lóng 02 Fěicuì Bǎn (China) 20?? Yong Yong + - - + + - - - Digimon 02 4 (China) + + Digimon 2 (China) + 200? + Makon + + + + + + + + + + + + Shùmǎ Bào Lóng 3 Shuǐjīng Bǎn (China) 20?? Yong Yong + - - - - - + + + + - + - Digimon 02 4 (China, Hacked) + Shùmǎ Bào Lóng 2 (China, hacked) 20?? Yong Yong + - - + + - + + + + + + Harry Potter 3 (China) + 200? + Makon + + + + + + + + + + + + Pokémon: Mewtwo Strikes Back (China) + 200? + Makon + + + + - - Digimon 02 Jade (China) + + + Digimon Pocket (China) + 200? + Makon + + + + + + + + + + + Pokémon Diamond: Special Pikachu Edition (China) + 2001 + Makon + + + + + + + + + + Shùmǎ Bǎobèi: Hǎi Zhī Shén (China) + 200? + Li Cheng + + + + + + + + + + + + + + Pokémon Jade: Special Pikachu Edition (China) + 2001 + Makon + + + + + + + + + + + + Street Fighter Zero 4 (China) + 2000 + Makon + + + + + + + + + + + + + Super Mario 3 Special (China) + 2000 + Yong Yong + + + + + + + + + + Digimon 3 Crystal (China) 20?? Yong Yong + - - + + diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index b2057000033..35a2a066228 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3733,6 +3733,8 @@ if (BUSES["GAMEBOY"]~=null) then MAME_DIR .. "src/devices/bus/gameboy/mdslot.h", MAME_DIR .. "src/devices/bus/gameboy/mmm01.cpp", MAME_DIR .. "src/devices/bus/gameboy/mmm01.h", + MAME_DIR .. "src/devices/bus/gameboy/ntnew.cpp", + MAME_DIR .. "src/devices/bus/gameboy/ntnew.h", MAME_DIR .. "src/devices/bus/gameboy/rom.cpp", MAME_DIR .. "src/devices/bus/gameboy/rom.h", MAME_DIR .. "src/devices/bus/gameboy/slmulti.cpp", diff --git a/src/devices/bus/gameboy/cartbase.cpp b/src/devices/bus/gameboy/cartbase.cpp index c36ceb7d837..82bca2c786a 100644 --- a/src/devices/bus/gameboy/cartbase.cpp +++ b/src/devices/bus/gameboy/cartbase.cpp @@ -350,6 +350,108 @@ void mbc_dual_uniform_device_base::set_bank_rom_high(u16 entry) +//************************************************************************** +// 16 KiB fixed at 0x0000, 8 KiB switchable at 0x4000 and 0x6000 +//************************************************************************** + +mbc_8k_device_base::mbc_8k_device_base( + machine_config const &mconfig, + device_type type, + char const *tag, + device_t *owner, + u32 clock) : + device_t(mconfig, type, tag, owner, clock), + device_gb_cart_interface(mconfig, *this), + m_bank_rom(*this, { "romlow", "romhigh" }), + m_bank_bits_rom(0U), + m_bank_mask_rom(0U) +{ +} + + +void mbc_8k_device_base::device_start() +{ +} + + +bool mbc_8k_device_base::check_rom(std::string &message) +{ + memory_region *const romregion(cart_rom_region()); + if (!romregion || !romregion->bytes()) + { + // setting default bank on reset causes a fatal error when no banks are configured + message = "No ROM data found"; + return false; + } + + auto const rombytes(romregion->bytes()); + if ((rombytes & (PAGE_ROM_SIZE - 1)) || ((u32(PAGE_ROM_SIZE) << m_bank_bits_rom) < rombytes)) + { + message = util::string_format( + "Unsupported cartridge ROM size (must be a multiple of 8 KiB and no larger than %u pages)", + 1U << m_bank_bits_rom); + return false; + } + + return true; +} + + +void mbc_8k_device_base::install_rom( + address_space_installer &fixedspace, + address_space_installer &lowspace, + address_space_installer &highspace) +{ + memory_region *const romregion(cart_rom_region()); + auto const rombytes(romregion->bytes()); + + // install the fixed ROM, mirrored if it’s too small + if (0x4000 > rombytes) + fixedspace.install_rom(0x0000, 0x1fff, 0x2000, romregion->base()); + else + fixedspace.install_rom(0x0000, 0x3fff, 0x0000, romregion->base()); + + // configure both banks as views of the ROM + m_bank_mask_rom = device_generic_cart_interface::map_non_power_of_two( + unsigned(rombytes / PAGE_ROM_SIZE), + [this, base = &romregion->as_u8()] (unsigned entry, unsigned page) + { + LOG( + "Install ROM 0x%06X-0x%06X in bank entry %u\n", + page * PAGE_ROM_SIZE, + (page * PAGE_ROM_SIZE) + (PAGE_ROM_SIZE - 1), + entry); + m_bank_rom[0]->configure_entry(entry, &base[page * PAGE_ROM_SIZE]); + m_bank_rom[1]->configure_entry(entry, &base[page * PAGE_ROM_SIZE]); + }); + lowspace.install_read_bank(0x4000, 0x5fff, m_bank_rom[0]); + highspace.install_read_bank(0x6000, 0x7fff, m_bank_rom[1]); +} + + +void mbc_8k_device_base::set_bank_rom_low(u16 entry) +{ + entry &= m_bank_mask_rom; + LOG( + "%s: Set ROM bank low = 0x%06X\n", + machine().describe_context(), + entry * PAGE_ROM_SIZE); + m_bank_rom[0]->set_entry(entry); +} + + +void mbc_8k_device_base::set_bank_rom_high(u16 entry) +{ + entry &= m_bank_mask_rom; + LOG( + "%s: Set ROM bank high = 0x%06X\n", + machine().describe_context(), + entry * PAGE_ROM_SIZE); + m_bank_rom[1]->set_entry(entry); +} + + + //************************************************************************** // 32 KiB switchable at 0x0000 //************************************************************************** diff --git a/src/devices/bus/gameboy/cartbase.h b/src/devices/bus/gameboy/cartbase.h index 760d2911a02..0cc161c858e 100644 --- a/src/devices/bus/gameboy/cartbase.h +++ b/src/devices/bus/gameboy/cartbase.h @@ -141,6 +141,37 @@ private: }; + +//************************************************************************** +// 16 KiB fixed at 0x0000, 8 KiB switchable at 0x4000 and 0x6000 +//************************************************************************** + +class mbc_8k_device_base : public device_t, public device_gb_cart_interface +{ +protected: + mbc_8k_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock); + + virtual void device_start() override ATTR_COLD; + + void set_bank_bits_rom(unsigned bits) { m_bank_bits_rom = bits; } + + bool check_rom(std::string &message) ATTR_COLD; + void install_rom(address_space_installer &fixedspace, address_space_installer &lowspace, address_space_installer &highspace) ATTR_COLD; + + void set_bank_rom_low(u16 entry); + void set_bank_rom_high(u16 entry); + +private: + static inline constexpr unsigned PAGE_ROM_SIZE = 0x2000; + + memory_bank_array_creator<2> m_bank_rom; + + unsigned m_bank_bits_rom; + u16 m_bank_mask_rom; +}; + + + //************************************************************************** // 32 KiB switchable at 0x0000 //************************************************************************** diff --git a/src/devices/bus/gameboy/carts.cpp b/src/devices/bus/gameboy/carts.cpp index dbd4924d71b..42a6e87fc19 100644 --- a/src/devices/bus/gameboy/carts.cpp +++ b/src/devices/bus/gameboy/carts.cpp @@ -19,6 +19,7 @@ #include "mbc6.h" #include "mbc7.h" #include "mmm01.h" +#include "ntnew.h" #include "rom.h" #include "slmulti.h" #include "tama5.h" @@ -54,7 +55,7 @@ char const *const GB_CHONGWU = "rom_chong"; char const *const GB_LICHENG = "rom_licheng"; char const *const GB_NEWGBCHK = "rom_newgbchk"; char const *const GB_VF001 = "rom_vf001"; -char const *const GB_DIGIMON = "rom_digimon"; +char const *const GB_NTNEW = "rom_ntnew"; char const *const GB_SLMULTI = "rom_slmulti"; char const *const GB_GBCK003 = "rom_gbck003"; @@ -97,7 +98,7 @@ void gameboy_cartridges(device_slot_interface &device) device.option_add_internal(slotoptions::GB_LICHENG, GB_ROM_LICHENG); device.option_add_internal(slotoptions::GB_NEWGBCHK, GB_ROM_NEWGBCHK); device.option_add_internal(slotoptions::GB_VF001, GB_ROM_VF001); - device.option_add_internal(slotoptions::GB_DIGIMON, GB_ROM_DIGIMON); + device.option_add_internal(slotoptions::GB_NTNEW, GB_ROM_NTNEW); device.option_add_internal(slotoptions::GB_SLMULTI, GB_ROM_SLMULTI); device.option_add_internal(slotoptions::GB_GBCK003, GB_ROM_GBCK003); } diff --git a/src/devices/bus/gameboy/carts.h b/src/devices/bus/gameboy/carts.h index e0227401a76..1f7107c074c 100644 --- a/src/devices/bus/gameboy/carts.h +++ b/src/devices/bus/gameboy/carts.h @@ -45,7 +45,7 @@ extern char const *const GB_CHONGWU; extern char const *const GB_LICHENG; extern char const *const GB_NEWGBCHK; extern char const *const GB_VF001; -extern char const *const GB_DIGIMON; +extern char const *const GB_NTNEW; extern char const *const GB_SLMULTI; extern char const *const GB_GBCK003; diff --git a/src/devices/bus/gameboy/gbslot.cpp b/src/devices/bus/gameboy/gbslot.cpp index c2526e5d186..e45406ae49d 100644 --- a/src/devices/bus/gameboy/gbslot.cpp +++ b/src/devices/bus/gameboy/gbslot.cpp @@ -746,6 +746,9 @@ std::optional probe_gbx_footer(std::string_view tag, util::random_ case gbxfile::TYPE_VF001: result = slotoptions::GB_VF001; break; + case gbxfile::TYPE_NTNEW: + result = slotoptions::GB_NTNEW; + break; case gbxfile::TYPE_SLMULTI: result = slotoptions::GB_SLMULTI; break; diff --git a/src/devices/bus/gameboy/gbxfile.h b/src/devices/bus/gameboy/gbxfile.h index 51549772c79..1e35e605c42 100644 --- a/src/devices/bus/gameboy/gbxfile.h +++ b/src/devices/bus/gameboy/gbxfile.h @@ -65,6 +65,7 @@ enum : u32 TYPE_MBC7 = 0x4d424337, // 'MBC7' TYPE_MMM01 = 0x4d4d4d31, // 'MMM1' TYPE_NEWGBCHK = 0x4e47484b, // 'NGHK' + TYPE_NTNEW = 0x4e544e00, // 'NTN\0' TYPE_ROCKET = 0x524f434b, // 'ROCK' TYPE_PLAIN = 0x524f4d00, // 'ROM\0' TYPE_SACHEN1 = 0x53414d31, // 'SAM1' diff --git a/src/devices/bus/gameboy/mbc.cpp b/src/devices/bus/gameboy/mbc.cpp index 4bad4a2522d..8063c7964ca 100644 --- a/src/devices/bus/gameboy/mbc.cpp +++ b/src/devices/bus/gameboy/mbc.cpp @@ -49,7 +49,6 @@ the strategies. Strategies implemented by each cartridge should be identified. * HK0701 and HK0819 seem to differ in that HK0819 fully decodes ROM addresses while HK0701 mirrors - we should probably emulated the difference at some point. - * Digimon 2 mapper doesn't work ***********************************************************************************************************/ @@ -1282,71 +1281,6 @@ private: u8 m_split_enable; }; - - -//************************************************************************** -// Yong Yong Digimon 2 (and maybe 4?) -//************************************************************************** -/* - Digimon 2 writes to 0x2000 to set the fine ROM bank, then writes a series - of values to 0x2400 that the patched version does not write. - Digimon 4 seems to share part of the 0x2000 behavior, but does not write - to 0x2400. - */ - -class digimon_device : public rom_mbc_device_base -{ -public: - digimon_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : - rom_mbc_device_base(mconfig, GB_ROM_DIGIMON, tag, owner, clock) - { - } - - virtual image_init_result load(std::string &message) override ATTR_COLD - { - // set up ROM and RAM - if (!install_memory(message, 4, 7)) - return image_init_result::FAIL; - - // install handlers - cart_space()->install_write_handler( - 0x0000, 0x1fff, - write8smo_delegate(*this, FUNC(digimon_device::enable_ram))); - cart_space()->install_write_handler( - 0x2000, 0x2000, - write8smo_delegate(*this, FUNC(digimon_device::bank_switch_fine))); - cart_space()->install_write_handler( - 0x4000, 0x5fff, - write8smo_delegate(*this, FUNC(digimon_device::bank_switch_coarse))); - - // all good - return image_init_result::PASS; - } - -protected: - virtual void device_reset() override ATTR_COLD - { - rom_mbc_device_base::device_reset(); - - set_bank_rom_coarse(0); - set_bank_rom_fine(1); - set_ram_enable(false); - set_bank_ram(0); - } - -private: - void enable_ram(u8 data) - { - set_ram_enable(0x0a == (data & 0x0f)); - } - - void bank_switch_fine(u8 data) - { - data >>= 1; - set_bank_rom_fine(data ? data : 1); - } -}; - } // anonymous namespace } // namespace bus::gameboy @@ -1360,4 +1294,3 @@ DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_CHONGWU, device_gb_cart_interface, bus::gameb DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_LICHENG, device_gb_cart_interface, bus::gameboy::licheng_device, "gb_rom_licheng", "Game Boy Li Cheng MBC5 Cartridge") DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_NEWGBCHK, device_gb_cart_interface, bus::gameboy::ngbchk_device, "gb_rom_ngbchk", "Game Boy HK0701/HK0819 Cartridge") DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_VF001, device_gb_cart_interface, bus::gameboy::vf001_device, "gb_rom_vf001", "Game Boy Vast Fame VF001 Cartridge") -DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_DIGIMON, device_gb_cart_interface, bus::gameboy::digimon_device, "gb_rom_digimon", "Game Boy Digimon 2 Cartridge") diff --git a/src/devices/bus/gameboy/mbc.h b/src/devices/bus/gameboy/mbc.h index 6d492a779a2..9dfedb31232 100644 --- a/src/devices/bus/gameboy/mbc.h +++ b/src/devices/bus/gameboy/mbc.h @@ -16,6 +16,5 @@ DECLARE_DEVICE_TYPE(GB_ROM_CHONGWU, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_LICHENG, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_NEWGBCHK, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_VF001, device_gb_cart_interface) -DECLARE_DEVICE_TYPE(GB_ROM_DIGIMON, device_gb_cart_interface) #endif // MAME_BUS_GAMEBOY_MBC_H diff --git a/src/devices/bus/gameboy/mbc6.cpp b/src/devices/bus/gameboy/mbc6.cpp index eee9867c865..9bfe0900ca8 100644 --- a/src/devices/bus/gameboy/mbc6.cpp +++ b/src/devices/bus/gameboy/mbc6.cpp @@ -55,6 +55,8 @@ #include "emu.h" #include "mbc6.h" +#include "cartbase.h" + #include "bus/generic/slot.h" #include "machine/intelfsh.h" @@ -69,7 +71,7 @@ namespace bus::gameboy { namespace { -class mbc6_device : public device_t, public device_gb_cart_interface +class mbc6_device : public mbc_8k_device_base { public: static constexpr feature_type imperfect_features() { return feature::ROM; } @@ -85,7 +87,6 @@ protected: virtual void device_reset() override ATTR_COLD; private: - static inline constexpr unsigned PAGE_ROM_SIZE = 0x2000; static inline constexpr unsigned PAGE_RAM_SIZE = 0x1000; template u8 read_flash(offs_t offset); @@ -97,18 +98,14 @@ private: void enable_flash_write(u8 data); void enable_ram(u8 data); - bool check_rom(std::string &message) ATTR_COLD; bool check_ram(std::string &message) ATTR_COLD; - void install_rom() ATTR_COLD; void install_ram() ATTR_COLD; required_device m_flash; memory_view m_view_rom_low; memory_view m_view_rom_high; memory_view m_view_ram; - memory_bank_array_creator<2> m_bank_rom; memory_bank_array_creator<2> m_bank_ram; - u8 m_bank_mask_rom; u8 m_bank_mask_ram; u8 m_bank_sel_rom[2]; @@ -124,15 +121,12 @@ mbc6_device::mbc6_device( char const *tag, device_t *owner, u32 clock) : - device_t(mconfig, GB_ROM_MBC6, tag, owner, clock), - device_gb_cart_interface(mconfig, *this), + mbc_8k_device_base(mconfig, GB_ROM_MBC6, tag, owner, clock), m_flash(*this, "flash"), m_view_rom_low(*this, "romlow"), m_view_rom_high(*this, "romhigh" ), m_view_ram(*this, "ram"), - m_bank_rom(*this, { "romlow", "romhigh" }), m_bank_ram(*this, { "ramlow", "ramhigh" }), - m_bank_mask_rom(0U), m_bank_mask_ram(0U), m_bank_sel_rom{ 0U, 0U }, m_bank_sel_ram{ 0U, 0U }, @@ -146,6 +140,7 @@ mbc6_device::mbc6_device( image_init_result mbc6_device::load(std::string &message) { // first check that ROM/RAM regions are supportable + set_bank_bits_rom(7); if (!check_rom(message) || !check_ram(message)) return image_init_result::FAIL; @@ -155,7 +150,7 @@ image_init_result mbc6_device::load(std::string &message) cart_space()->install_view(0xa000, 0xbfff, m_view_ram); // set up ROM and RAM as appropriate - install_rom(); + install_rom(*cart_space(), m_view_rom_low[0], m_view_rom_high[0]); install_ram(); // install memory controller handlers @@ -209,8 +204,11 @@ void mbc6_device::device_add_mconfig(machine_config &config) MACRONIX_29F008TC(config, m_flash); } + void mbc6_device::device_start() { + mbc_8k_device_base::device_start(); + save_item(NAME(m_bank_sel_rom)); save_item(NAME(m_bank_sel_ram)); save_item(NAME(m_flash_select)); @@ -218,8 +216,11 @@ void mbc6_device::device_start() save_item(NAME(m_flash_writable)); } + void mbc6_device::device_reset() { + mbc_8k_device_base::device_reset(); + m_bank_sel_rom[0] = 0U; m_bank_sel_rom[1] = 0U; m_bank_sel_ram[0] = 0U; @@ -233,17 +234,14 @@ void mbc6_device::device_reset() m_view_rom_high.select(0); m_view_ram.disable(); - if (m_bank_mask_rom) - { - m_bank_rom[0]->set_entry(0); - m_bank_rom[1]->set_entry(0); - } - if (m_bank_mask_ram) { m_bank_ram[0]->set_entry(0); m_bank_ram[1]->set_entry(0); } + + set_bank_rom_low(0); + set_bank_rom_high(0); } @@ -291,16 +289,10 @@ void mbc6_device::bank_switch_rom(offs_t offset, u8 data) } } - if (m_bank_mask_rom) - { - u8 const entry(data & m_bank_mask_rom); - LOG( - "%s: Set ROM bank %s = 0x%05X\n", - machine().describe_context(), - bank ? "high" : "low", - entry * PAGE_ROM_SIZE); - m_bank_rom[bank]->set_entry(entry); - } + if (bank) + set_bank_rom_high(data & 0x7f); + else + set_bank_rom_low(data & 0x7f); } @@ -441,23 +433,6 @@ void mbc6_device::enable_ram(u8 data) } -bool mbc6_device::check_rom(std::string &message) -{ - memory_region *const romregion(cart_rom_region()); - if (romregion) - { - auto const rombytes(romregion->bytes()); - if (((PAGE_ROM_SIZE < rombytes) && (rombytes & (PAGE_ROM_SIZE - 1))) || ((u32(PAGE_ROM_SIZE) << 7) < rombytes)) - { - message = "Unsupported cartridge ROM size (must be no larger than 8 KiB, or a multiple of 8 KiB and no larger than 2 MiB)"; - return false; - } - } - - return true; -} - - bool mbc6_device::check_ram(std::string &message) { memory_region *const ramregion(cart_ram_region()); @@ -481,68 +456,6 @@ bool mbc6_device::check_ram(std::string &message) } -void mbc6_device::install_rom() -{ - memory_region *const romregion(cart_rom_region()); - auto const rombytes(romregion ? romregion->bytes() : 0); - if (!rombytes) - { - // just avoid fatal errors - m_view_rom_low[0]; - m_view_rom_high[0]; - m_bank_mask_rom = 0U; - } - else if (PAGE_ROM_SIZE >= rombytes) - { - // not big enough to need banking - install directly - device_generic_cart_interface::install_non_power_of_two<0>( - rombytes, - PAGE_ROM_SIZE - 1, - 0, - 0, - 0x0000, - [this, base = &romregion->as_u8()] (offs_t begin, offs_t end, offs_t mirror, offs_t src) - { - LOG( - "Install ROM 0x%04X-0x%04X at 0x%04X-0x%04X mirror 0x%04X\n", - src, - src + (end - begin), - begin, - end, - mirror); - cart_space()->install_rom(begin, end, 0x2000 | mirror, &base[src]); - m_view_rom_low[0].install_rom(0x4000 | begin, 0x4000 | end, mirror, &base[src]); - m_view_rom_high[0].install_rom(0x6000 | begin, 0x6000 | end, mirror, &base[src]); - }); - m_bank_mask_rom = 0U; - } - else - { - // install the fixed ROM, mirrored if it’s too small - if (0x4000 > rombytes) - cart_space()->install_rom(0x0000, 0x1fff, 0x2000, romregion->base()); - else - cart_space()->install_rom(0x0000, 0x3fff, 0x0000, romregion->base()); - - // configure both banks as views of the ROM - m_bank_mask_rom = device_generic_cart_interface::map_non_power_of_two( - unsigned(rombytes / PAGE_ROM_SIZE), - [this, base = &romregion->as_u8()] (unsigned entry, unsigned page) - { - LOG( - "Install ROM 0x%05X-0x%05X in bank entry %u\n", - page * PAGE_ROM_SIZE, - (page * PAGE_ROM_SIZE) + (PAGE_ROM_SIZE - 1), - entry); - m_bank_rom[0]->configure_entry(entry, &base[page * PAGE_ROM_SIZE]); - m_bank_rom[1]->configure_entry(entry, &base[page * PAGE_ROM_SIZE]); - }); - m_view_rom_low[0].install_read_bank(0x4000, 0x5fff, m_bank_rom[0]); - m_view_rom_high[0].install_read_bank(0x6000, 0x7fff, m_bank_rom[1]); - } -} - - void mbc6_device::install_ram() { memory_region *const ramregion(this->cart_ram_region()); diff --git a/src/devices/bus/gameboy/mmm01.cpp b/src/devices/bus/gameboy/mmm01.cpp index 6cf1315b753..8eece6bd2c4 100644 --- a/src/devices/bus/gameboy/mmm01.cpp +++ b/src/devices/bus/gameboy/mmm01.cpp @@ -227,7 +227,7 @@ void mmm01_device::device_reset() set_bank_rom_low(0x01fe); set_bank_rom_high(0x01ff); - set_bank_ram(0U); + set_bank_ram(0); } diff --git a/src/devices/bus/gameboy/ntnew.cpp b/src/devices/bus/gameboy/ntnew.cpp new file mode 100644 index 00000000000..8dced95ccba --- /dev/null +++ b/src/devices/bus/gameboy/ntnew.cpp @@ -0,0 +1,166 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + Memory controller used for newer NT/Makon games + + ***************************************************************************/ + +#include "emu.h" +#include "ntnew.h" + +#include "cartbase.ipp" + +//#define VERBOSE 1 +//#define LOG_OUTPUT_FUNC osd_printf_info +#include "logmacro.h" + + +namespace bus::gameboy { + +namespace { + +class ntnew_device : public mbc_ram_device_base +{ +public: + ntnew_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + + virtual image_init_result load(std::string &message) override ATTR_COLD; + +protected: + virtual void device_start() override ATTR_COLD; + virtual void device_reset() override ATTR_COLD; + +private: + void enable_ram(offs_t offset, u8 data); + void bank_switch_rom(offs_t offset, u8 data); + void bank_switch_ram(u8 data); + + memory_view m_view_ram; + + u8 m_bank_8k; +}; + + +ntnew_device::ntnew_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + u32 clock) : + mbc_ram_device_base(mconfig, GB_ROM_NTNEW, tag, owner, clock), + m_view_ram(*this, "ram"), + m_bank_8k(0U) +{ +} + + +image_init_result ntnew_device::load(std::string &message) +{ + // set up ROM and RAM + set_bank_bits_rom(8); + set_bank_bits_ram(4); + if (!check_rom(message) || !check_ram(message)) + return image_init_result::FAIL; + cart_space()->install_view(0xa000, 0xbfff, m_view_ram); + install_rom(*cart_space(), *cart_space(), *cart_space()); + install_ram(m_view_ram[0]); + + // install handlers + cart_space()->install_write_handler( + 0x0000, 0x1fff, + write8sm_delegate(*this, FUNC(ntnew_device::enable_ram))); + cart_space()->install_write_handler( + 0x2000, 0x2fff, + write8sm_delegate(*this, FUNC(ntnew_device::bank_switch_rom))); + cart_space()->install_write_handler( + 0x4000, 0x5fff, + write8smo_delegate(*this, FUNC(ntnew_device::bank_switch_ram))); + + // all good + return image_init_result::PASS; +} + + +void ntnew_device::device_start() +{ + mbc_ram_device_base::device_start(); + + save_item(NAME(m_bank_8k)); +} + + +void ntnew_device::device_reset() +{ + mbc_ram_device_base::device_reset(); + + m_view_ram.disable(); + m_bank_8k = 0U; + + set_bank_rom_low(2); + set_bank_rom_high(3); + set_bank_ram(0); +} + + +void ntnew_device::enable_ram(offs_t offset, u8 data) +{ + // TODO: what range actually triggers this, and does it still trigger RAM enable? + if (((offset & 0xff00) == 0x1400) & (0x55 == data)) + { + LOG("%s: 8K ROM banking enabled\n", machine().describe_context()); + m_bank_8k = 1U; + } + + // TODO: how many bits are checked? + bool const enable = 0x0a == (data & 0x0f); + LOG( + "%s: Cartridge RAM %s\n", + machine().describe_context(), + enable ? "enabled" : "disabled"); + if (enable) + m_view_ram.select(0); + else + m_view_ram.disable(); +} + + +void ntnew_device::bank_switch_rom(offs_t offset, u8 data) +{ + if (m_bank_8k) + { + // TODO: what ranges does the controller actually respond to? + switch (offset & 0xff00) + { + case 0x0000: + if (!(data & 0xfe)) + data |= 0x02; + set_bank_rom_low(data); + return; + + case 0x0400: + if (!(data & 0xfe)) + data |= 0x02; + set_bank_rom_high(data); + return; + } + } + + data <<= 1; + if (!(data & 0xfe)) + data |= 0x02; + set_bank_rom_low(data); + set_bank_rom_high(data | 0x01); +} + + +void ntnew_device::bank_switch_ram(u8 data) +{ + set_bank_ram(data & 0x0f); +} + +} // anonymous namespace + +} // namespace bus::gameboy + + +DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_NTNEW, device_gb_cart_interface, bus::gameboy::ntnew_device, "gb_rom_ntnew", "Game Boy newer NT/Makon Cartridge") diff --git a/src/devices/bus/gameboy/ntnew.h b/src/devices/bus/gameboy/ntnew.h new file mode 100644 index 00000000000..74c297d60f5 --- /dev/null +++ b/src/devices/bus/gameboy/ntnew.h @@ -0,0 +1,18 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + Memory controller used for newer NT/Makon games + + ***************************************************************************/ +#ifndef MAME_BUS_GAMEBOY_NTNEW_H +#define MAME_BUS_GAMEBOY_NTNEW_H + +#pragma once + +#include "slot.h" + + +DECLARE_DEVICE_TYPE(GB_ROM_NTNEW, device_gb_cart_interface) + +#endif // MAME_BUS_GAMEBOY_NTNEW_H -- cgit v1.2.3