diff options
Diffstat (limited to 'src/devices/bus/vboy/rom.cpp')
-rw-r--r-- | src/devices/bus/vboy/rom.cpp | 188 |
1 files changed, 162 insertions, 26 deletions
diff --git a/src/devices/bus/vboy/rom.cpp b/src/devices/bus/vboy/rom.cpp index 6c6117c8a9b..20ba18ff62a 100644 --- a/src/devices/bus/vboy/rom.cpp +++ b/src/devices/bus/vboy/rom.cpp @@ -1,59 +1,195 @@ // license:BSD-3-Clause -// copyright-holders:Fabio Priuli -/*********************************************************************************************************** +// copyright-holders:Vas Crabb +/*************************************************************************** + Virtual Boy cartridges + ***************************************************************************/ +#include "emu.h" +#include "rom.h" +#include "bus/generic/slot.h" - Nintendo Virtual Boy cart emulation +//#define VERBOSE 1 +//#define LOG_OUTPUT_FUNC osd_printf_info +#include "logmacro.h" - ***********************************************************************************************************/ +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** +DEFINE_DEVICE_TYPE(VBOY_FLAT_ROM, vboy_flat_rom_device, "vboy_flatrom", "Nintendo Virtual Boy Flat ROM Cartridge") +DEFINE_DEVICE_TYPE(VBOY_FLAT_ROM_SRAM, vboy_flat_rom_sram_device, "vboy_flatrom_sram", "Nintendo Virtual Boy Flat ROM Cartridge with Backup SRAM") -#include "emu.h" -#include "rom.h" -//------------------------------------------------- -// vboy_rom_device - constructor -//------------------------------------------------- +//************************************************************************** +// vboy_flat_rom_device +//************************************************************************** -DEFINE_DEVICE_TYPE(VBOY_ROM_STD, vboy_rom_device, "vboy_rom", "Nintendo Virtual Boy Carts") -DEFINE_DEVICE_TYPE(VBOY_ROM_EEPROM, vboy_eeprom_device, "vboy_eeprom", "Nintendo Virtual Boy Carts + EEPROM") +vboy_flat_rom_device::vboy_flat_rom_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + vboy_flat_rom_device(mconfig, VBOY_FLAT_ROM, tag, owner, clock) +{ +} -vboy_rom_device::vboy_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, type, tag, owner, clock), device_vboy_cart_interface(mconfig, *this) +vboy_flat_rom_device::vboy_flat_rom_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, type, tag, owner, clock), + device_vboy_cart_interface(mconfig, *this) { } -vboy_rom_device::vboy_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : vboy_rom_device(mconfig, VBOY_ROM_STD, tag, owner, clock) + +std::error_condition vboy_flat_rom_device::load() { + // if the host has supplied a ROM space, install with appropriate mirroring + memory_region *const romregion(memregion("^rom")); + if (rom_space() && romregion) + { + // the slot should have verified that the ROM is a supported size + assert(!(romregion->bytes() & 0x0000'0003U)); + assert(romregion->bytes() <= 0x0100'0000U); + + // this should fail a validity check + assert(!(rom_base() & 0x00ff'ffff)); + + // This is a simplification that improves performance. In + // reality, cartridge ROM is 16 bits wide and 32-bit accesses + // are split up automatically. MAME doesn't really support + // dynamic bus sizing, and it's a lot faster to execute from a + // ROM handler than to go through the trampolines necessary to + // emulate 16-bit accesses. + device_generic_cart_interface::install_non_power_of_two<2>( + romregion->bytes() >> 2, + 0x00ff'ffff >> 2, + 0, + rom_base(), + [this, rom = &romregion->as_u32()] (offs_t begin, offs_t end, offs_t mirror, offs_t src) + { + LOG( + "Install ROM 0x%08X-0x%08X at 0x%08X-0x%08X mirror %08X\n", + src << 2, + (src << 2) + (end - begin), + begin, + end, + mirror); + rom_space()->install_rom(begin, end, mirror, &rom[src]); + }); + } + + return std::error_condition(); } -vboy_eeprom_device::vboy_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : vboy_rom_device(mconfig, VBOY_ROM_EEPROM, tag, owner, clock) + +void vboy_flat_rom_device::device_start() { } -/*------------------------------------------------- - mapper specific handlers - -------------------------------------------------*/ -READ32_MEMBER(vboy_rom_device::read_cart) +//************************************************************************** +// vboy_flat_rom_sram_device +//************************************************************************** + +vboy_flat_rom_sram_device::vboy_flat_rom_sram_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + vboy_flat_rom_device(mconfig, VBOY_FLAT_ROM_SRAM, tag, owner, clock) { - return m_rom[offset & m_rom_mask]; } -READ32_MEMBER(vboy_eeprom_device::read_eeprom) +std::error_condition vboy_flat_rom_sram_device::load() { - return m_eeprom[offset]; + std::error_condition const result(vboy_flat_rom_device::load()); + if (result) + return result; + + memory_region *const sramregion(memregion("^sram")); + if (sramregion) + { + // this should fail a validity check + assert(!(chip_base() & 0x00ff'ffff)); + + switch (sramregion->bitwidth()) + { + case 8: + if (chip_space()) + { + device_generic_cart_interface::install_non_power_of_two<2>( + sramregion->bytes() >> 1, + 0x00ff'ffff >> 2, + 0, + chip_base(), + [this, sramregion] (offs_t begin, offs_t end, offs_t mirror, offs_t src) + { + LOG( + "Install SRAM 0x%08X-0x%08X at 0x%08X-0x%08X mirror %08X\n", + src << 1, + (src << 1) + ((end - begin) >> 1), + begin, + end, + mirror); + u8 *const base(&reinterpret_cast<u8 *>(sramregion->base())[src << 1]); + chip_space()->install_readwrite_handler( + begin, + end, + 0, + mirror, + 0, + read8sm_delegate(*this, NAME([base] (offs_t offset) { return base[offset]; })), + write8sm_delegate(*this, NAME([base] (offs_t offset, u8 data) { base[offset] = data; })), + 0x00ff'00ff); + }); + } + save_pointer(NAME(&sramregion->as_u8()), sramregion->bytes()); + break; + + case 16: + if (chip_space()) + { + device_generic_cart_interface::install_non_power_of_two<2>( + sramregion->bytes() >> 2, + 0x00ff'ffff >> 2, + 0, + chip_base(), + [this, sramregion] (offs_t begin, offs_t end, offs_t mirror, offs_t src) + { + LOG( + "Install SRAM 0x%08X-0x%08X at 0x%08X-0x%08X mirror %08X\n", + src << 2, + (src << 2) + (end - begin), + begin, + end, + mirror); + u16 *const base(&reinterpret_cast<u16 *>(sramregion->base())[src << 1]); + chip_space()->install_readwrite_handler( + begin, + end, + 0, + mirror, + 0, + read16s_delegate(*this, NAME([base] (offs_t offset, u16 mem_mask) { return base[offset]; })), + write16s_delegate(*this, NAME([base] (offs_t offset, u16 data, u16 mem_mask) { COMBINE_DATA(base + offset); })), + 0xffff'ffff); + }); + } + save_pointer(NAME(&sramregion->as_u16()), sramregion->bytes() >> 1); + break; + + default: + throw emu_fatalerror("Unsupported Virtual Boy cartridge backup RAM width\n"); + } + + battery_load(sramregion->base(), sramregion->bytes(), nullptr); + } + + return std::error_condition(); } -WRITE32_MEMBER(vboy_eeprom_device::write_eeprom) +void vboy_flat_rom_sram_device::unload() { - COMBINE_DATA(&m_eeprom[offset]); + vboy_flat_rom_device::unload(); + + memory_region *const sramregion(memregion("^sram")); + if (sramregion) + battery_save(sramregion->base(), sramregion->bytes()); } |