summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/vboy/rom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/vboy/rom.cpp')
-rw-r--r--src/devices/bus/vboy/rom.cpp188
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());
}