From be3556df308941431c1bc069515affdd191d8696 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Sun, 13 Nov 2022 04:29:45 +1100 Subject: bus/gameboy: Added support for Kong Feng and BBD cartridges. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New working software list items (gbcolor.xml) --------------------------------------------- Digimon Adventure 2001 [lana_chan_, taizou] Digimon 6 Adventure 2002 [taizou] Garou: Mark of the Wolves 2001 Harry Potter (China, English) [taizou] Shùmǎ Bào Lóng: Kǒudài Bǎn (China) [RocknRami, taizou] Mó Jiè Chuánshuō (China) [taizou] Mùchǎng Wùyǔ 6 GB (China) [taizou] --- hash/gbcolor.xml | 136 +++++++++++++++-- src/devices/bus/gameboy/carts.cpp | 4 + src/devices/bus/gameboy/carts.h | 2 + src/devices/bus/gameboy/gbslot.cpp | 6 + src/devices/bus/gameboy/gbxfile.h | 2 + src/devices/bus/gameboy/mbc.cpp | 296 +++++++++++++++++++++++++++++++++++-- src/devices/bus/gameboy/mbc.h | 2 + src/devices/bus/gameboy/ntnew.cpp | 2 +- 8 files changed, 419 insertions(+), 31 deletions(-) diff --git a/hash/gbcolor.xml b/hash/gbcolor.xml index 40cf7239fa8..7646122a828 100644 --- a/hash/gbcolor.xml +++ b/hash/gbcolor.xml @@ -26047,18 +26047,33 @@ license:CC0 * ST-0504093C 口袋宝贝-珍珠/Poketmon-pearl --> + - - Harry Potter (China) + Harry Potter (China, English) 20?? Sintax + + - - - + + + - + + + + + + + Harry Potter (China, Chinese) + 20?? + Sintax + + + + + @@ -26141,6 +26156,48 @@ license:CC0 + + Digimon Adventure 2001 + 2001? + BBD + + + + + + + + + + + + Digimon Adventure 6 2002 + 2002? + BBD + + + + + + + + + + + Garou: Mark of the Wolves 2001 + 2001? + BBD + + + + + + + + + + + Digimon Crystal II (China) 200? @@ -26600,6 +26657,53 @@ license:CC0 + + Shùmǎ Bào Lóng: Kǒudài Bǎn (China) + 200? + Kong Feng Industries Limited + + + + + + + + + + + + + + Mó Jiè Chuánshuō (China) + 200? + Kong Feng Industries Limited + + + + + + + + + + + + + + Mùchǎng Wùyǔ 6 GB (China) + 200? + Kong Feng Industries Limited + + + + + + + + + + + @@ -27944,7 +28048,7 @@ license:CC0 Capcom Vs. SNK: Millennium Fight 2001 (China) 200? - Makon + Kǎshèng @@ -27956,7 +28060,7 @@ license:CC0 Digimon 02 4 (China) 200? - Makon + Kǎshèng @@ -27969,7 +28073,7 @@ license:CC0 Shùmǎ Bào Lóng 02 4 (China) 200? - Makon + Kǎshèng @@ -28014,7 +28118,7 @@ license:CC0 Digimon 2 (China) 200? - Makon + Kǎshèng @@ -28058,7 +28162,7 @@ license:CC0 Harry Potter 3 (China) 200? - Makon + Kǎshèng @@ -28072,7 +28176,7 @@ license:CC0 Pokémon: Mewtwo Strikes Back (China) 200? - Makon + Kǎshèng @@ -28085,7 +28189,7 @@ license:CC0 Digimon Pocket (China) 200? - Makon + Kǎshèng @@ -28098,7 +28202,7 @@ license:CC0 Pokémon Diamond: Special Pikachu Edition (China) 2001 - Makon + Kǎshèng @@ -28125,7 +28229,7 @@ license:CC0 Pokémon Jade: Special Pikachu Edition (China) 2001 - Makon + Kǎshèng @@ -28139,7 +28243,7 @@ license:CC0 Street Fighter Zero 4 (China) 2000 - Makon + Kǎshèng diff --git a/src/devices/bus/gameboy/carts.cpp b/src/devices/bus/gameboy/carts.cpp index e43f62c96dc..8dba7084846 100644 --- a/src/devices/bus/gameboy/carts.cpp +++ b/src/devices/bus/gameboy/carts.cpp @@ -52,6 +52,8 @@ char const *const GB_HUC3 = "rom_huc3"; char const *const GB_TAMA5 = "rom_tama5"; char const *const GB_CAMERA = "rom_camera"; char const *const GB_TFANGBOOT = "rom_tfboot"; +char const *const GB_BBD = "rom_bbd"; +char const *const GB_DSHGGB81 = "rom_dshggb81"; char const *const GB_SINTAX = "rom_sintax"; char const *const GB_CHONGWU = "rom_chong"; char const *const GB_LICHENG = "rom_licheng"; @@ -97,6 +99,8 @@ void gameboy_cartridges(device_slot_interface &device) device.option_add_internal(slotoptions::GB_HUC3, GB_ROM_HUC3); device.option_add_internal(slotoptions::GB_TAMA5, GB_ROM_TAMA5); device.option_add_internal(slotoptions::GB_TFANGBOOT, GB_ROM_TFANGBOOT); + device.option_add_internal(slotoptions::GB_BBD, GB_ROM_BBD); + device.option_add_internal(slotoptions::GB_DSHGGB81, GB_ROM_DSHGGB81); device.option_add_internal(slotoptions::GB_SINTAX, GB_ROM_SINTAX); device.option_add_internal(slotoptions::GB_CHONGWU, GB_ROM_CHONGWU); device.option_add_internal(slotoptions::GB_LICHENG, GB_ROM_LICHENG); diff --git a/src/devices/bus/gameboy/carts.h b/src/devices/bus/gameboy/carts.h index 1a33a4d4a22..2ae7df01dd4 100644 --- a/src/devices/bus/gameboy/carts.h +++ b/src/devices/bus/gameboy/carts.h @@ -41,6 +41,8 @@ extern char const *const GB_HUC1; extern char const *const GB_HUC3; extern char const *const GB_TAMA5; extern char const *const GB_TFANGBOOT; +extern char const *const GB_BBD; +extern char const *const GB_DSHGGB81; extern char const *const GB_SINTAX; extern char const *const GB_CHONGWU; extern char const *const GB_LICHENG; diff --git a/src/devices/bus/gameboy/gbslot.cpp b/src/devices/bus/gameboy/gbslot.cpp index 2203e2b94f9..b00e9584cd1 100644 --- a/src/devices/bus/gameboy/gbslot.cpp +++ b/src/devices/bus/gameboy/gbslot.cpp @@ -737,6 +737,12 @@ std::optional probe_gbx_footer(std::string_view tag, util::random_ case gbxfile::TYPE_TFANGBOOT: result = slotoptions::GB_TFANGBOOT; break; + case gbxfile::TYPE_BBD: + result = slotoptions::GB_BBD; + break; + case gbxfile::TYPE_DSHGGB81: + result = slotoptions::GB_DSHGGB81; + break; case gbxfile::TYPE_SINTAX: result = slotoptions::GB_SINTAX; break; diff --git a/src/devices/bus/gameboy/gbxfile.h b/src/devices/bus/gameboy/gbxfile.h index 11f0d09bcda..f454c045a6d 100644 --- a/src/devices/bus/gameboy/gbxfile.h +++ b/src/devices/bus/gameboy/gbxfile.h @@ -50,7 +50,9 @@ enum : u32 enum : u32 { + TYPE_BBD = 0x42424400, // 'BBD\0' TYPE_CAMERA = 0x43414d52, // 'CAMR' + TYPE_DSHGGB81 = 0x47423831, // 'GB81' TYPE_HUC1 = 0x48554331, // 'HUC1' TYPE_HUC3 = 0x48554333, // 'HUC3' TYPE_SLMULTI = 0x4c424d43, // 'LBMC' diff --git a/src/devices/bus/gameboy/mbc.cpp b/src/devices/bus/gameboy/mbc.cpp index 8063c7964ca..c8d67d0ada4 100644 --- a/src/devices/bus/gameboy/mbc.cpp +++ b/src/devices/bus/gameboy/mbc.cpp @@ -49,6 +49,7 @@ 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. + * BC-R1616T3P is a variant of DSHGGB-81 with the same ROM scrambling but without logo spoofing. ***********************************************************************************************************/ @@ -280,12 +281,16 @@ protected: m_spoof_logo = 0U; install_ram_tap(); - m_notif_cart_space = cart_space()->add_change_notifier( - [this] (read_or_write mode) - { - if (u32(mode) & u32(read_or_write::WRITE)) - install_ram_tap(); - }); + add_ram_notifier(); + } + + virtual void device_post_load() override ATTR_COLD + { + mbc5_device_base::device_post_load(); + + install_ram_tap(); + if (!m_spoof_logo) + add_ram_notifier(); } u8 read_rom(offs_t offset) @@ -373,6 +378,16 @@ private: } } + void add_ram_notifier() + { + m_notif_cart_space = cart_space()->add_change_notifier( + [this] (read_or_write mode) + { + if (u32(mode) & u32(read_or_write::WRITE)) + install_ram_tap(); + }); + } + memory_passthrough_handler m_ram_tap; util::notifier_subscription m_notif_cart_space; @@ -383,6 +398,144 @@ private: +//************************************************************************** +// MBC5-like pirate cartridges with scrambled bank numbers and data +//************************************************************************** + +class mbc5_scrambled_device_base : public mbc5_logo_spoof_device_base +{ + + virtual image_init_result load(std::string &message) override ATTR_COLD + { + // install regular MBC5 handlers + image_init_result const result(mbc5_logo_spoof_device_base::load(message)); + if (image_init_result::PASS != result) + return result; + + // bank numbers and ROM contents are scrambled for protection + cart_space()->install_read_handler( + 0x0000, 0x3fff, + read8sm_delegate(*this, FUNC(mbc5_scrambled_device_base::read_rom_low))); + cart_space()->install_read_handler( + 0x4000, 0x7fff, + read8sm_delegate(*this, FUNC(mbc5_scrambled_device_base::read_rom_high))); + cart_space()->install_write_handler( + 0x2000, 0x2000, 0x0000, 0x0f00, 0x0000, + write8smo_delegate(*this, FUNC(mbc5_scrambled_device_base::bank_switch_fine_low_scrambled))); + cart_space()->install_write_handler( + 0x2001, 0x2001, 0x0000, 0x0f00, 0x0000, + write8smo_delegate(*this, FUNC(mbc5_scrambled_device_base::set_data_scramble))); + cart_space()->install_write_handler( + 0x2080, 0x2080, 0x0000, 0x0f00, 0x0000, + write8smo_delegate(*this, FUNC(mbc5_scrambled_device_base::set_bank_scramble))); + + // all good + return image_init_result::PASS; + } + +protected: + using unscramble_function = u8 (*)(u8); + + mbc5_scrambled_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) : + mbc5_logo_spoof_device_base(mconfig, type, tag, owner, clock), + m_unscramble_data(nullptr), + m_unscramble_bank(nullptr), + m_scramble_mode{ 0U, 0U } + { + } + + virtual void device_start() override ATTR_COLD + { + mbc5_logo_spoof_device_base::device_start(); + + save_item(NAME(m_scramble_mode)); + } + + virtual void device_reset() override ATTR_COLD + { + mbc5_logo_spoof_device_base::device_reset(); + + m_unscramble_data = unscramble_data(0U); + m_unscramble_bank = unscramble_bank(0U); + m_scramble_mode[0] = 0U; + m_scramble_mode[1] = 0U; + } + + virtual void device_post_load() override ATTR_COLD + { + mbc5_logo_spoof_device_base::device_post_load(); + + m_unscramble_data = unscramble_data(m_scramble_mode[0]); + m_unscramble_bank = unscramble_bank(m_scramble_mode[1]); + } + + virtual unscramble_function unscramble_data(u8 data) = 0; + virtual unscramble_function unscramble_bank(u8 data) = 0; + + template + static u8 unscramble(u8 data) + { + return bitswap<8>(data, B...); + } + +private: + u8 read_rom_low(offs_t offset) + { + offset = rom_access(offset); + return bank_rom_low_base()[offset]; + } + + u8 read_rom_high(offs_t offset) + { + offset = rom_access(0x4000 | offset) & 0x3fff; + return m_unscramble_data(bank_rom_high_base()[offset]); + } + + void bank_switch_fine_low_scrambled(u8 data) + { + set_bank_rom_fine((bank_rom_fine() & 0x0100) | u16(m_unscramble_bank(data))); + } + + void set_data_scramble(u8 data) + { + LOG( + "%s: Set ROM data scrambling mode 0x%02X\n", + machine().describe_context(), + data); + if (data != m_scramble_mode[0]) + { + m_unscramble_data = unscramble_data(data); + m_scramble_mode[0] = data; + } + + // TODO: does this actually trigger a bank switch? + set_bank_rom_fine((bank_rom_fine() & 0x0100) | u16(data)); + } + + void set_bank_scramble(u8 data) + { + LOG( + "%s: Set ROM bank number scrambling mode 0x%02X\n", + machine().describe_context(), + data); + if (data != m_scramble_mode[1]) + { + m_unscramble_bank = unscramble_bank(data); + m_scramble_mode[1] = data; + } + + // TODO: does this actually trigger a bank switch? + set_bank_rom_fine((bank_rom_fine() & 0x0100) | u16(data)); + } + + unscramble_function m_unscramble_data; + unscramble_function m_unscramble_bank; + + u8 m_scramble_mode[2]; +}; + + + //************************************************************************** // MBC1 (max 2 MiB ROM, max 32 KiB SRAM) //************************************************************************** @@ -658,6 +811,109 @@ private: +//************************************************************************** +// MBC5 variant used by BBD games +//************************************************************************** + +class bbd_device : public mbc5_scrambled_device_base +{ +public: + bbd_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + mbc5_scrambled_device_base(mconfig, GB_ROM_BBD, tag, owner, clock) + { + } + +protected: + virtual unscramble_function unscramble_data(u8 data) override + { + switch (data & 0x07) + { + case 0x0: // no scrambling + return &bbd_device::unscramble<7, 6, 5, 4, 3, 2, 1, 0>; + case 0x4: // Garou + return &bbd_device::unscramble<7, 6, 2, 4, 3, 1, 5, 0>; + case 0x5: // Harry Potter + return &bbd_device::unscramble<7, 6, 5, 1, 3, 2, 4, 0>; + case 0x7: // Digimon Adventure + return &bbd_device::unscramble<7, 6, 2, 4, 3, 5, 1, 0>; + } + + logerror( + "%s: Unsupported ROM data scrambling mode 0x%02X\n", + machine().describe_context(), + data); + return &bbd_device::unscramble<7, 6, 5, 4, 3, 2, 1, 0>; + } + + virtual unscramble_function unscramble_bank(u8 data) override + { + switch (data & 0x07) + { + case 0x0: // no scrambling + return &bbd_device::unscramble<7, 6, 5, 4, 3, 2, 1, 0>; + case 0x3: // Digimon Adventure, Garou - two most significant bits unconfirmed + return &bbd_device::unscramble<7, 6, 5, 1, 0, 2, 4, 3>; + case 0x5: // Harry Potter - two most significant bits unconfirmed + return &bbd_device::unscramble<7, 6, 5, 0, 4, 3, 2, 1>; + } + + logerror( + "%s: Unsupported ROM bank number scrambling mode 0x%02X\n", + machine().describe_context(), + data); + return &bbd_device::unscramble<7, 6, 5, 4, 3, 2, 1, 0>; + } +}; + + + +//************************************************************************** +// MBC5 variant with DSHGGB-81 PCB +//************************************************************************** + +class dshggb81_device : public mbc5_scrambled_device_base +{ +public: + dshggb81_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + mbc5_scrambled_device_base(mconfig, GB_ROM_DSHGGB81, tag, owner, clock) + { + } + +protected: + virtual unscramble_function unscramble_data(u8 data) override + { + switch (data & 0x07) + { + default: // just to shut up dumb compilers + case 0x0: return &dshggb81_device::unscramble<7, 6, 5, 4, 3, 2, 1, 0>; + case 0x1: return &dshggb81_device::unscramble<7, 5, 6, 4, 3, 1, 2, 0>; + case 0x2: return &dshggb81_device::unscramble<7, 1, 2, 4, 3, 5, 6, 0>; + case 0x3: return &dshggb81_device::unscramble<7, 6, 2, 4, 3, 1, 5, 0>; + case 0x4: return &dshggb81_device::unscramble<7, 6, 1, 4, 3, 2, 5, 0>; + case 0x5: return &dshggb81_device::unscramble<7, 1, 5, 4, 3, 6, 2, 0>; + case 0x6: return &dshggb81_device::unscramble<7, 5, 2, 4, 3, 6, 1, 0>; + case 0x7: return &dshggb81_device::unscramble<7, 1, 6, 4, 3, 5, 2, 0>; + } + } + + virtual unscramble_function unscramble_bank(u8 data) override + { + switch (data & 0x07) + { + case 0x0: // no scrambling + return &dshggb81_device::unscramble<7, 6, 5, 4, 3, 2, 1, 0>; + } + + logerror( + "%s: Unsupported ROM bank number scrambling mode 0x%02X\n", + machine().describe_context(), + data); + return &dshggb81_device::unscramble<7, 6, 5, 4, 3, 2, 1, 0>; + } +}; + + + //************************************************************************** // MBC5 variant used by Sintax games //************************************************************************** @@ -681,8 +937,11 @@ public: // bank numbers and ROM contents are scrambled for protection cart_space()->install_read_handler( - 0x0000, 0x7fff, - read8sm_delegate(*this, FUNC(sintax_device::read_rom))); + 0x0000, 0x3fff, + read8sm_delegate(*this, FUNC(sintax_device::read_rom_low))); + cart_space()->install_read_handler( + 0x4000, 0x7fff, + read8sm_delegate(*this, FUNC(sintax_device::read_rom_high))); cart_space()->install_write_handler( 0x2000, 0x2fff, write8smo_delegate(*this, FUNC(sintax_device::bank_switch_fine_low_scrambled))); @@ -717,13 +976,16 @@ protected: } private: - u8 read_rom(offs_t offset) + u8 read_rom_low(offs_t offset) { offset = rom_access(offset); - if (BIT(offset, 14)) - return bank_rom_high_base()[offset & 0x3fff] ^ m_xor_table[m_xor_index]; - else - return bank_rom_low_base()[offset]; + return bank_rom_low_base()[offset]; + } + + u8 read_rom_high(offs_t offset) + { + offset = rom_access(0x4000 | offset) & 0x3fff; + return bank_rom_high_base()[offset] ^ m_xor_table[m_xor_index]; } void bank_switch_fine_low_scrambled(u8 data) @@ -754,8 +1016,12 @@ private: data = bitswap<8>(data, 1, 0, 7, 6, 5, 4, 3, 2); break; case 0x0f: // no scrambling - default: break; + default: + logerror( + "%s: Unsupported ROM bank number scrambling mode 0x%X\n", + machine().describe_context(), + m_scramble_mode & 0x0f); } set_bank_rom_fine((bank_rom_fine() & 0x0100) | u16(data)); @@ -1289,6 +1555,8 @@ private: // device type definition DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_MBC1, device_gb_cart_interface, bus::gameboy::mbc1_device, "gb_rom_mbc1", "Game Boy MBC1 Cartridge") DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_MBC5, device_gb_cart_interface, bus::gameboy::mbc5_device, "gb_rom_mbc5", "Game Boy MBC5 Cartridge") +DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_BBD, device_gb_cart_interface, bus::gameboy::bbd_device, "gb_rom_bbd", "Game Boy BBD Cartridge") +DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_DSHGGB81, device_gb_cart_interface, bus::gameboy::dshggb81_device, "gb_rom_dshggb81", "Game Boy DSHGGB-81 Cartridge") DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_SINTAX, device_gb_cart_interface, bus::gameboy::sintax_device, "gb_rom_sintax", "Game Boy Sintax MBC5 Cartridge") DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_CHONGWU, device_gb_cart_interface, bus::gameboy::chongwu_device, "gb_rom_chongwu", "Game Boy Chongwu Xiao Jingling Pokemon Pikecho Cartridge") DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_LICHENG, device_gb_cart_interface, bus::gameboy::licheng_device, "gb_rom_licheng", "Game Boy Li Cheng MBC5 Cartridge") diff --git a/src/devices/bus/gameboy/mbc.h b/src/devices/bus/gameboy/mbc.h index 4cc03952fea..0da79f570d1 100644 --- a/src/devices/bus/gameboy/mbc.h +++ b/src/devices/bus/gameboy/mbc.h @@ -10,6 +10,8 @@ DECLARE_DEVICE_TYPE(GB_ROM_MBC1, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_MBC5, device_gb_cart_interface) +DECLARE_DEVICE_TYPE(GB_ROM_BBD, device_gb_cart_interface) +DECLARE_DEVICE_TYPE(GB_ROM_DSHGGB81, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_SINTAX, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_CHONGWU, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_LICHENG, device_gb_cart_interface) diff --git a/src/devices/bus/gameboy/ntnew.cpp b/src/devices/bus/gameboy/ntnew.cpp index 7ea72a2d9f4..44fc3394c20 100644 --- a/src/devices/bus/gameboy/ntnew.cpp +++ b/src/devices/bus/gameboy/ntnew.cpp @@ -176,4 +176,4 @@ void ntnew_device::bank_switch_ram(u8 data) } // 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") +DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_NTNEW, device_gb_cart_interface, bus::gameboy::ntnew_device, "gb_rom_ntnew", "Game Boy newer Kasheng/Makon Cartridge") -- cgit v1.2.3