From 796d8d672081bcc3bcc9036bdcfbb990b24bba80 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Mon, 19 Sep 2022 03:22:19 +1000 Subject: bus/gameboy: Fixes for multi-game cartridges. * Reset the system from a timer callback for the Vast Fame/SL/J.Y. Company multi-game cartridges. This fixes games on gbcolor. * Reset system when leaving configuration mode for GBCK003. Fixes most issues with games. * Moved GBCK003 to its own source file, and added notes for both multi-game cartridge types. --- hash/gbcolor.xml | 6 +- scripts/src/bus.lua | 2 + src/devices/bus/gameboy/carts.cpp | 5 +- src/devices/bus/gameboy/carts.h | 2 +- src/devices/bus/gameboy/gbck003.cpp | 259 ++++++++++++++++++++++++++++++++++++ src/devices/bus/gameboy/gbck003.h | 18 +++ src/devices/bus/gameboy/gbslot.cpp | 4 +- src/devices/bus/gameboy/rom.cpp | 164 ----------------------- src/devices/bus/gameboy/rom.h | 1 - src/devices/bus/gameboy/slmulti.cpp | 80 ++++++++++- 10 files changed, 366 insertions(+), 175 deletions(-) create mode 100644 src/devices/bus/gameboy/gbck003.cpp create mode 100644 src/devices/bus/gameboy/gbck003.h diff --git a/hash/gbcolor.xml b/hash/gbcolor.xml index ee2ca840e17..4d5402d0448 100644 --- a/hash/gbcolor.xml +++ b/hash/gbcolor.xml @@ -25931,11 +25931,12 @@ license:CC0 - + Color GameBoy 188 in 1 (Hong Kong) 199? <unknown> + @@ -26411,8 +26412,7 @@ license:CC0 - - + New Super Color 145 in 1 (China) 200? J.Y. Company diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 555a6c3597b..e5724861157 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -3697,6 +3697,8 @@ if (BUSES["GAMEBOY"]~=null) then MAME_DIR .. "src/devices/bus/gameboy/cartheader.h", MAME_DIR .. "src/devices/bus/gameboy/carts.cpp", MAME_DIR .. "src/devices/bus/gameboy/carts.h", + MAME_DIR .. "src/devices/bus/gameboy/gbck003.cpp", + MAME_DIR .. "src/devices/bus/gameboy/gbck003.h", MAME_DIR .. "src/devices/bus/gameboy/gbslot.cpp", MAME_DIR .. "src/devices/bus/gameboy/gbslot.h", MAME_DIR .. "src/devices/bus/gameboy/gbxfile.cpp", diff --git a/src/devices/bus/gameboy/carts.cpp b/src/devices/bus/gameboy/carts.cpp index 94ffa62cec9..8bb63cf3cbd 100644 --- a/src/devices/bus/gameboy/carts.cpp +++ b/src/devices/bus/gameboy/carts.cpp @@ -10,6 +10,7 @@ #include "carts.h" #include "camera.h" +#include "gbck003.h" #include "huc1.h" #include "huc3.h" #include "mbc.h" @@ -34,7 +35,6 @@ char const *const GB_SACHEN1 = "rom_sachen1"; char const *const GB_SACHEN2 = "rom_sachen2"; char const *const GB_ROCKET = "rom_rocket"; char const *const GB_LASAMA = "rom_lasama"; -char const *const GB_GBCK003 = "rom_gbck003"; char const *const GB_MBC1 = "rom_mbc1"; char const *const GB_MBC2 = "rom_mbc2"; char const *const GB_MBC3 = "rom_mbc3"; @@ -55,6 +55,7 @@ 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_SLMULTI = "rom_slmulti"; +char const *const GB_GBCK003 = "rom_gbck003"; char const *const MEGADUCK_STD = "rom"; char const *const MEGADUCK_BANKED = "rom_banked"; @@ -76,7 +77,6 @@ void gameboy_cartridges(device_slot_interface &device) device.option_add_internal(slotoptions::GB_SACHEN2, GB_ROM_SACHEN2); device.option_add_internal(slotoptions::GB_ROCKET, GB_ROM_ROCKET); device.option_add_internal(slotoptions::GB_LASAMA, GB_ROM_LASAMA); - device.option_add_internal(slotoptions::GB_GBCK003, GB_ROM_GBCK003); device.option_add_internal(slotoptions::GB_MBC1, GB_ROM_MBC1); device.option_add_internal(slotoptions::GB_MBC2, GB_ROM_MBC2); device.option_add_internal(slotoptions::GB_MBC3, GB_ROM_MBC3); @@ -98,6 +98,7 @@ void gameboy_cartridges(device_slot_interface &device) 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_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 47c8e8b7568..e0227401a76 100644 --- a/src/devices/bus/gameboy/carts.h +++ b/src/devices/bus/gameboy/carts.h @@ -26,7 +26,6 @@ extern char const *const GB_SACHEN1; extern char const *const GB_SACHEN2; extern char const *const GB_ROCKET; extern char const *const GB_LASAMA; -extern char const *const GB_GBCK003; extern char const *const GB_MBC1; extern char const *const GB_MBC2; extern char const *const GB_MBC3; @@ -48,6 +47,7 @@ extern char const *const GB_NEWGBCHK; extern char const *const GB_VF001; extern char const *const GB_DIGIMON; extern char const *const GB_SLMULTI; +extern char const *const GB_GBCK003; extern char const *const MEGADUCK_STD; extern char const *const MEGADUCK_BANKED; diff --git a/src/devices/bus/gameboy/gbck003.cpp b/src/devices/bus/gameboy/gbck003.cpp new file mode 100644 index 00000000000..f7db29f8484 --- /dev/null +++ b/src/devices/bus/gameboy/gbck003.cpp @@ -0,0 +1,259 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + GBCK003 multi-game board soldered inside some units + + Used with a menu program for selecting between multiple games designed for + MBC1 cartridges. Supports up to 8 MiB ROM (512 16 KiB pages). Included + games can use up to 4 MiB ROM (256 16 KiB pages). + + The menu program sets up code in WRAM to switch to the selected game's ROM + and exit configuration mode. The configuration values are read directly + from ROM, so the configuration is presumably applied when exiting + configuration mode. + + The write to 0x7B02 that presumably exits configuration mode is followed by + code to do the following (SP contains 0xFFFE at this point): + * Set HL to 0x000D + * Set DE to 0xFF56 + * Set AF to 0x1180 (Znhc) + * Set BC to 0x0000 + * Jump to 0x0100 + + This doesn't match the state set up by any official Nintendo bootstrap + programs. Leaving configuration mode presumably asserts the rest line on + the cartridge edge connector to get out of CGB mode for games that expect + DMG mode. + + 0x0000-3FFF R - Low ROM bank. + 0x4000-7FFF R - High ROM bank. + + 0x2000-2FFF W - Set ROM A21-A14 for 0x4000-7FFF as allowed by mask. + 0x7B00 * W - Set ROM A22-A15 as allowed by mask. + 0x7B01 * W - Set mask for A22-A15 - high for bits controlled by + 0x7B00, low for bits controlled by 0x2000-2FFF. + 0x7B02 * W - Software writes 0xF0 to exit configuration mode. + + * Registers only writable in configuration mode. + + TODO: + * Are large games that require coarse ROM banking supported? + * Is static RAM supported? If so, is it banked? + * What actual ranges are the configuration registers accessible in? + * This isn't really a cartridge - does it belong elsewhere? + + ***************************************************************************/ + +#include "emu.h" +#include "gbck003.h" + +#include "cartbase.ipp" + +#include + +//#define VERBOSE 1 +//#define LOG_OUTPUT_FUNC osd_printf_info +#include "logmacro.h" + + +namespace bus::gameboy { + +namespace { + +class gbck003_device : public flat_ram_device_base +{ +public: + gbck003_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 bank_switch_inner(u8 data); + void bank_switch_outer(u8 data); + void bank_set_mux(u8 data); + void exit_config_mode(u8 data); + + TIMER_CALLBACK_MEMBER(do_reset); + + u16 bank_rom_entry_low() const noexcept + { + // TODO: is this affected by the multiplexer? + return u16(m_bank_setting[0]) << 1; + } + + u16 bank_rom_entry_high() const noexcept + { + return (u16(m_bank_setting[0] & m_bank_mux_rom) << 1) | (m_bank_setting[1] & ~(u16(m_bank_mux_rom) << 1)); + } + + u8 m_bank_setting[2]; + u8 m_bank_mux_rom; + u8 m_config_mode; +}; + + +gbck003_device::gbck003_device( + machine_config const &mconfig, + char const *tag, + device_t *owner, + u32 clock) : + flat_ram_device_base(mconfig, GB_ROM_GBCK003, tag, owner, clock), + m_bank_setting{ 0U, 0U }, + m_bank_mux_rom(0U), + m_config_mode(0U) +{ +} + + +image_init_result gbck003_device::load(std::string &message) +{ + // set up ROM/RAM + set_bank_bits_rom(9); + if (!check_rom(message)) + return image_init_result::FAIL; + install_rom(); + install_ram(); + + // install bank switch handlers + cart_space()->install_write_handler( + 0x2000, 0x3fff, + write8smo_delegate(*this, FUNC(gbck003_device::bank_switch_inner))); + cart_space()->install_write_handler( + 0x7b00, 0x7b00, + write8smo_delegate(*this, FUNC(gbck003_device::bank_switch_outer))); + cart_space()->install_write_handler( + 0x7b01, 0x7b01, + write8smo_delegate(*this, FUNC(gbck003_device::bank_set_mux))); + cart_space()->install_write_handler( + 0x7b02, 0x7b02, + write8smo_delegate(*this, FUNC(gbck003_device::exit_config_mode))); + + // set initial power-on state + set_bank_rom_low(0); + set_bank_rom_high(1); + + // all good + return image_init_result::PASS; +} + + +void gbck003_device::device_start() +{ + flat_ram_device_base::device_start(); + + // this stuff must survive reset for getting out of CGB mode + m_bank_setting[0] = 0U; + m_bank_mux_rom = 0xff; + m_config_mode = 1U; + + save_item(NAME(m_bank_setting)); + save_item(NAME(m_bank_mux_rom)); + save_item(NAME(m_config_mode)); +} + + +void gbck003_device::device_reset() +{ + flat_ram_device_base::device_reset(); + + // TODO: proper reset state + m_bank_setting[1] = 1U; +} + + +void gbck003_device::bank_switch_inner(u8 data) +{ + data &= 0x1f; + m_bank_setting[1] = data ? data : 1; + set_bank_rom_high(bank_rom_entry_high()); +} + + +void gbck003_device::bank_switch_outer(u8 data) +{ + if (m_config_mode) + { + LOG( + "%s: Set base page = 0x%03X (0x%06X)\n", + machine().describe_context(), + u16(data) << 1, + u32(data) << 15); + m_bank_setting[0] = data; + set_bank_rom_low(bank_rom_entry_low()); + set_bank_rom_high(bank_rom_entry_high()); + } + else + { + logerror( + "%s: Write 0x7B00 = 0x%02X after disabling configuration mode\n", + machine().describe_context(), + data); + } +} + + +void gbck003_device::bank_set_mux(u8 data) +{ + if (m_config_mode) + { + LOG( + "%s: Set bank multiplexer = 0x%03X\n", + machine().describe_context(), + u16(data) << 1); + m_bank_mux_rom = data; + set_bank_rom_high(bank_rom_entry_high()); + } + else + { + logerror( + "%s: Write 0x7B01 = 0x%02X after disabling configuration mode\n", + machine().describe_context(), + data); + } +} + + +void gbck003_device::exit_config_mode(u8 data) +{ + if (m_config_mode) + { + if (0xf0 == data) + { + LOG("%s: Configuration mode disabled, resetting system\n", machine().describe_context()); + m_config_mode = 0U; + machine().scheduler().synchronize(timer_expired_delegate(FUNC(gbck003_device::do_reset), this)); + } + else + { + logerror( + "%s: Unknown write 0x7B02 = 0x%02X in configuration mode\n", + machine().describe_context(), + data); + } + } + else + { + logerror( + "%s: Write 0x7B02 = 0x%02X after disabling configuration mode\n", + machine().describe_context(), + data); + } +} + + +TIMER_CALLBACK_MEMBER(gbck003_device::do_reset) +{ + machine().root_device().reset(); // TODO: expose reset line on cartridge interface +} + +} // anonymous namespace + +} // namespace bus::gameboy + + +DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_GBCK003, device_gb_cart_interface, bus::gameboy::gbck003_device, "gb_rom_gbck003", "Game Boy GBCK003 Multi-Game Board") diff --git a/src/devices/bus/gameboy/gbck003.h b/src/devices/bus/gameboy/gbck003.h new file mode 100644 index 00000000000..04aa19f2c44 --- /dev/null +++ b/src/devices/bus/gameboy/gbck003.h @@ -0,0 +1,18 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/*************************************************************************** + + GBCK003 multi-game board soldered inside some units + + ***************************************************************************/ +#ifndef MAME_BUS_GAMEBOY_GBCK003_H +#define MAME_BUS_GAMEBOY_GBCK003_H + +#pragma once + +#include "slot.h" + + +DECLARE_DEVICE_TYPE(GB_ROM_GBCK003, device_gb_cart_interface) + +#endif // MAME_BUS_GAMEBOY_GBCK003_H diff --git a/src/devices/bus/gameboy/gbslot.cpp b/src/devices/bus/gameboy/gbslot.cpp index 0e69f0cb972..e7e22ec4bd5 100644 --- a/src/devices/bus/gameboy/gbslot.cpp +++ b/src/devices/bus/gameboy/gbslot.cpp @@ -292,7 +292,7 @@ std::string cart_licensee_description(u8 const *header) { // TODO: fill in and correct lists, distinguish duplicates static constexpr std::pair BASE[] = { - { 0x01, "Nintendo" }, + { 0x01, "Nintendo" }, { 0x08, "Capcom" }, { 0x09, "Hot-B" }, { 0x0a, "Jaleco" }, { 0x0b, "Coconuts Japan" }, { 0x0c, "Elite Systems" }, { 0x13, "Electronic Arts" }, @@ -407,7 +407,7 @@ std::string cart_licensee_description(u8 const *header) { 0x3932, "Video System" }, { 0x3933, "Ocean/Acclaim" }, { 0x3935, "Varie Corporation" }, - { 0x3936, "Yonezawa/s’pal" }, + { 0x3936, "Yonezawa/s'pal" }, { 0x3937, "Kaneko" }, { 0x3939, "Pack-In-Video Co." }, { 0x4134, "Konami (Yu-Gi-Oh!)" } }; diff --git a/src/devices/bus/gameboy/rom.cpp b/src/devices/bus/gameboy/rom.cpp index b2d53ff0291..cf593b95c8a 100644 --- a/src/devices/bus/gameboy/rom.cpp +++ b/src/devices/bus/gameboy/rom.cpp @@ -18,10 +18,6 @@ - ATV Racing/Rocket Games: - Does it monitor the address to detect RAM writes for logo spoofing, or just /CS? - How does RAM banking work? Are over-size RAM chips just inaccessible? - - GBCK003: - - Are large games that require coarse ROM banking supported? - - Is static RAM supported? If so, is it banked? - - This isn't really a cartridge - does it belong elsewhere? ***********************************************************************************************************/ @@ -1128,165 +1124,6 @@ private: } }; - - -//************************************************************************** -// GBCK003 board soldered inside some units -//************************************************************************** -/* - Seems to be a kind of MBC1 emulator, like MMM01 but less sophisticated. - - Base page for game right shifted by one bit position is written to 0x7B00. - Fine bank mask right shifted by one bit position is written to 0x7B01. - It always seems to write 0xF0 to 0x7B02 before jumping to the game. - */ - -class gbck003_device : public flat_ram_device_base -{ -public: - gbck003_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) : - flat_ram_device_base(mconfig, GB_ROM_GBCK003, tag, owner, clock), - m_bank_setting{ 0U, 0U }, - m_bank_mux_rom(0U), - m_config_mode(0U) - { - } - - virtual image_init_result load(std::string &message) override ATTR_COLD - { - // set up ROM/RAM - set_bank_bits_rom(9); - if (!check_rom(message)) - return image_init_result::FAIL; - install_rom(); - install_ram(); - - // install bank switch handlers - cart_space()->install_write_handler(0x2000, 0x3fff, write8smo_delegate(*this, FUNC(gbck003_device::bank_switch_inner))); - cart_space()->install_write_handler(0x7b00, 0x7b00, write8smo_delegate(*this, FUNC(gbck003_device::bank_switch_outer))); - cart_space()->install_write_handler(0x7b01, 0x7b01, write8smo_delegate(*this, FUNC(gbck003_device::bank_set_mux))); - cart_space()->install_write_handler(0x7b02, 0x7b02, write8smo_delegate(*this, FUNC(gbck003_device::exit_config_mode))); - - // all good - return image_init_result::PASS; - } - -protected: - virtual void device_start() override ATTR_COLD - { - flat_ram_device_base::device_start(); - - save_item(NAME(m_bank_setting)); - save_item(NAME(m_bank_mux_rom)); - save_item(NAME(m_config_mode)); - } - - virtual void device_reset() override ATTR_COLD - { - flat_ram_device_base::device_reset(); - - // TODO: proper reset state - m_bank_setting[0] = 0U; - m_bank_setting[1] = 1U; - m_bank_mux_rom = 0xff; - m_config_mode = 1U; - - set_bank_rom_low(0); - set_bank_rom_high(1); - } - -private: - void bank_switch_inner(u8 data) - { - data &= 0x1f; - m_bank_setting[1] = data ? data : 1; - set_bank_rom_high(bank_rom_entry_high()); - } - - void bank_switch_outer(u8 data) - { - if (m_config_mode) - { - LOG( - "%s: Set base page = 0x%03X (0x%06X)\n", - machine().describe_context(), - u16(data) << 1, - u32(data) << 15); - m_bank_setting[0] = data; - set_bank_rom_low(bank_rom_entry_low()); - set_bank_rom_high(bank_rom_entry_high()); - } - else - { - logerror( - "%s: Write 0x7B00 = 0x%02X after disabling configuration mode\n", - machine().describe_context(), - data); - } - } - - void bank_set_mux(u8 data) - { - if (m_config_mode) - { - LOG( - "%s: Set bank multiplexer = 0x%03X\n", - machine().describe_context(), - u16(data) << 1); - m_bank_mux_rom = data; - set_bank_rom_high(bank_rom_entry_high()); - } - else - { - logerror( - "%s: Write 0x7B01 = 0x%02X after disabling configuration mode\n", - machine().describe_context(), - data); - } - } - - void exit_config_mode(u8 data) - { - if (m_config_mode) - { - if (0xf0 == data) - { - LOG("%s: Configuration mode disabled\n", machine().describe_context()); - m_config_mode = 0U; - } - else - { - logerror( - "%s: Unknown write 0x7B02 = 0x%02X in configuration mode\n", - machine().describe_context(), - data); - } - } - else - { - logerror( - "%s: Write 0x7B02 = 0x%02X after disabling configuration mode\n", - machine().describe_context(), - data); - } - } - - u16 bank_rom_entry_low() const - { - // TODO: is this affected by the multiplexer? - return u16(m_bank_setting[0]) << 1; - } - - u16 bank_rom_entry_high() const - { - return (u16(m_bank_setting[0] & m_bank_mux_rom) << 1) | (m_bank_setting[1] & ~(u16(m_bank_mux_rom) << 1)); - } - - u8 m_bank_setting[2]; - u8 m_bank_mux_rom; - u8 m_config_mode; -}; - } // anonymous namespace } // namespace bus::gameboy @@ -1306,4 +1143,3 @@ DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_SACHEN1, device_gb_cart_interface, bus::g DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_SACHEN2, device_gb_cart_interface, bus::gameboy::sachen_mmc2_device, "gb_rom_sachen2", "Game Boy Sachen MMC2 Cartridge") DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_ROCKET, device_gb_cart_interface, bus::gameboy::rocket_device, "gb_rom_rocket", "Game Boy Rocket Games Cartridge") DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_LASAMA, device_gb_cart_interface, bus::gameboy::lasama_device, "gb_rom_lasama", "Game Boy Story of Lasama Cartridge") -DEFINE_DEVICE_TYPE_PRIVATE(GB_ROM_GBCK003, device_gb_cart_interface, bus::gameboy::gbck003_device, "gb_rom_gbck003", "Game Boy GBCK003 188 in 1 Game Board") diff --git a/src/devices/bus/gameboy/rom.h b/src/devices/bus/gameboy/rom.h index f523446f72f..e1cc56444cd 100644 --- a/src/devices/bus/gameboy/rom.h +++ b/src/devices/bus/gameboy/rom.h @@ -18,6 +18,5 @@ DECLARE_DEVICE_TYPE(GB_ROM_SACHEN1, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_SACHEN2, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_ROCKET, device_gb_cart_interface) DECLARE_DEVICE_TYPE(GB_ROM_LASAMA, device_gb_cart_interface) -DECLARE_DEVICE_TYPE(GB_ROM_GBCK003, device_gb_cart_interface) #endif // MAME_BUS_GAMEBOY_ROM_H diff --git a/src/devices/bus/gameboy/slmulti.cpp b/src/devices/bus/gameboy/slmulti.cpp index b2b76578df7..d6c0711c37a 100644 --- a/src/devices/bus/gameboy/slmulti.cpp +++ b/src/devices/bus/gameboy/slmulti.cpp @@ -5,7 +5,75 @@ Chinese multi-game cartridges by SL and possibly others Supports collections containing very large numbers of games designed for - MBC1 and MBC5 cartridges. + MBC1 and MBC5 cartridges. Supports ROM sizes up to 16 MiB ROM (1024 16 KiB + pages) and 128 KiB static RAM (16 8 KiB pages). Included MBC1 games can + use 32 KiB to at least 512 KiB ROM (2 to 32 pages) and 8 KiB or 32 KiB + static RAM (1 or 4 pages). Included MBC5 games can use 32 KiB to 4 MiB ROM + (2 to 256 pages) and 8 KiB or 32 KiB static RAM (1 or 4 pages). Static RAM + can be disabled for games that don't use it to avoid corrupting save data + for other games. + + The controller starts in configuration mode. After setting up ROM and + static RAM for the selected game, the controller asserts the reset line on + the cartridge edge connector to reset the Game Boy CPU and PPU. This is + necessary to get out of CGB mode on a Game Boy Color for games that don't + have CGB support. The ROM and static RAM configuration settings aren't + affected by the soft reset. + + Changes to the base ROM page seem to take effect immediately. The Vast + Fame games switch the base page when starting the menu program. Changes to + static RAM configuration presumably take effect immediately, although the + menu program doesn't use static RAM. + + The menu program sets up the code to switch to the selected game's ROM and + static RAM configuration in WRAM. The register write to complete setup, + exit configuration mode and reset the system is followed by a nop and a + jp $100. This will jump to the game's entry point if the system fails to + reset, although many games don't work properly if this happens, as they + expect the system state set up by the bootstrap ROM. + + 0x0000-3FFF R - Low ROM bank. + 0x4000-7FFF R - High ROM bank. + 0xA000-BFFF RW - Static RAM if enabled. + + 0x0000-1FFF W - Enable (0x0A) or disable (not 0x0A) static RAM. + 0x2000-2FFF W - Set ROM A21-A14 for 0x4000-7FFF as allowed by mask. + 0x3000-3FFF W - Same as 0x2000 in MBC1 mode, ignored in MBC5 mode. + 0x4000-5FFF W - Set static RAM A14-A13 0xA000-BFFF as allowed by mask. + + 0x5000-5FFF * W - Set command for next write to 0x7000-7FFF. + 0x7000-7FFF * W - Argument for last command written to 0x5000-5FFF. + + * Registers only writable in configuration mode. + + 0x55 - X------- Exit configuration mode and reset system if set? + -XX----- Dumped software writes 11 for MBC1 mode, or 00 for MBC5 + mode. + ---X---- Unknown. + ----X--- Set ROM base A23. + -----XXX Set number of A21-A15 lines controlled by ROM base setting. + 0xAA - XXXXXXXX Set ROM base A22-A15 as allowed by mask. + 0xBB - XX------ Unknown - dumped software always write 00. + --X----- Allow static RAM to be enabled if set. + ---X---- Set static RAM base page mask to A16-A13 if set, or A16-A15 + if clear. + ----XXXX Set static RAM A16-A13 as allowed by mask. + + The Vast Fame cartridges write 0x07 to the 0x7000 area after writing the + base ROM page for the previous 0xAA command without an intervening write to + the 0x5000 area. It isn't clear what this is supposed to do. It seems to + be save to ignore. + + TODO: + * What is the exact effect of bit 7 of the 0x55 command argument? + * Does bit 4 of the 0x55 command argument have a purpose? Does it control + an output for ROM A24 to support 32 MiB ROMs? + * The two bits used for setting MBC1 mode probably have separate effects + that can be controlled independently. + * Can MBC1 games larger than 512 KiB be supported? Does 0x6000-7FFF + switch between coarse ROM banking and static RAM banking in MBC1 mode? + * Do the two most significant bits of the 0xBB command argument have a + purpose? ***************************************************************************/ @@ -44,6 +112,8 @@ private: void set_config_cmd(u8 data); void do_config_cmd(u8 data); + TIMER_CALLBACK_MEMBER(do_reset); + void update_bank_rom_high() { u16 const page(bank_rom_entry_high()); @@ -288,7 +358,7 @@ void slmulti_device::do_config_cmd(u8 data) set_bank_rom_low(m_base_page_rom & ~m_page_mask_rom); update_bank_rom_high(); if (BIT(data, 7)) - machine().root_device().reset(); // TODO: expose reset line on cartridge interface + machine().scheduler().synchronize(timer_expired_delegate(FUNC(slmulti_device::do_reset), this)); break; case 0xaa: @@ -327,6 +397,12 @@ void slmulti_device::do_config_cmd(u8 data) m_config_cmd = 0x0100; } + +TIMER_CALLBACK_MEMBER(slmulti_device::do_reset) +{ + machine().root_device().reset(); // TODO: expose reset line on cartridge interface +} + } // anonymous namespace } // namespace bus::gameboy -- cgit v1.2.3