diff options
-rw-r--r-- | scripts/src/bus.lua | 2 | ||||
-rw-r--r-- | src/devices/bus/msx/slot/panasonic08r.cpp | 165 | ||||
-rw-r--r-- | src/devices/bus/msx/slot/panasonic08r.h | 52 | ||||
-rw-r--r-- | src/devices/bus/msx/slot/ram_mm.h | 3 |
4 files changed, 222 insertions, 0 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index b1043154c3e..6ca699992a0 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2010,6 +2010,8 @@ if (BUSES["MSX_SLOT"]~=null) then MAME_DIR .. "src/devices/bus/msx/slot/music.h", MAME_DIR .. "src/devices/bus/msx/slot/panasonic08.cpp", MAME_DIR .. "src/devices/bus/msx/slot/panasonic08.h", + MAME_DIR .. "src/devices/bus/msx/slot/panasonic08r.cpp", + MAME_DIR .. "src/devices/bus/msx/slot/panasonic08r.h", MAME_DIR .. "src/devices/bus/msx/slot/rom.cpp", MAME_DIR .. "src/devices/bus/msx/slot/rom.h", MAME_DIR .. "src/devices/bus/msx/slot/ram.cpp", diff --git a/src/devices/bus/msx/slot/panasonic08r.cpp b/src/devices/bus/msx/slot/panasonic08r.cpp new file mode 100644 index 00000000000..82c57ede439 --- /dev/null +++ b/src/devices/bus/msx/slot/panasonic08r.cpp @@ -0,0 +1,165 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/* + + Emulation of the firmware mapper as found in Panasonic FS-A1ST and FS-A1GT Turbo-R machines. + + +*/ + +#include "emu.h" +#include "panasonic08r.h" + + +DEFINE_DEVICE_TYPE(MSX_SLOT_PANASONIC08R, msx_slot_panasonic08r_device, "msx_slot_panasonic08r", "MSX Internal Panasonic08r") + + +msx_slot_panasonic08r_device::msx_slot_panasonic08r_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, MSX_SLOT_PANASONIC08R, tag, owner, clock) + , msx_internal_slot_interface(mconfig, *this) + , m_sram_size(0) + , m_nvram(*this, "nvram") + , m_rom_region(*this, finder_base::DUMMY_TAG) + , m_bank(*this, "bank%u", 0U) + , m_view{ + {*this, "view0"}, {*this, "view1"}, {*this, "view2"}, {*this, "view3"}, + {*this, "view4"}, {*this, "view5"}, {*this, "view6"}, {*this, "view7"} + } + , m_mm(*this, finder_base::DUMMY_TAG) + , m_region_offset(0) + , m_control(0) +{ +} + + +void msx_slot_panasonic08r_device::device_add_mconfig(machine_config &config) +{ + NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0); +} + + +void msx_slot_panasonic08r_device::device_start() +{ + // Sanity checks + if (m_rom_region->bytes() < m_region_offset + 0x400000) + fatalerror("Memory region '%s' is too small for the panasonic08r firmware\n", m_rom_region.finder_tag()); + if (m_sram_size != 0x4000 && m_sram_size != 0x8000) + fatalerror("Invalid SRAM size for the panasonic08r firmware\n"); + + m_sram = std::make_unique<u8[]>(m_sram_size); + m_nvram->set_base(&m_sram[0], m_sram_size); + + save_item(NAME(m_selected_bank)); + save_item(NAME(m_control)); + save_item(NAME(m_bank9)); + + for (int i = 0; i < 8; i++) + { + m_bank[i]->configure_entries(0, 0x200, m_rom_region->base() + m_region_offset, 0x2000); + m_bank[i]->configure_entry(0x80, &m_sram[0]); + m_bank[i]->configure_entry(0x81, &m_sram[0x2000]); + if (m_sram_size >= 0x8000) + { + m_bank[i]->configure_entry(0x82, &m_sram[0x4000]); + m_bank[i]->configure_entry(0x83, &m_sram[0x6000]); + } + + // Assuming smaller internal RAM is mirrored. + int internal_ram_banks = m_mm->get_ram().size() / 0x2000; + int start_bank = 0x180; + do { + int nr_banks = internal_ram_banks; + if (start_bank + nr_banks > 0x200) + nr_banks = 0x200 - start_bank; + m_bank[i]->configure_entries(start_bank, nr_banks, m_mm->get_ram().data(), 0x2000); + start_bank += internal_ram_banks; + } + while (start_bank < 0x200); + } + + for (int i = 0; i < 8; i++) + { + const u16 start = 0x2000 * i; + const u16 end = start + 0x1fff; + + page(i/2)->install_view(start, end, m_view[i]); + m_view[i][0].install_read_bank(start, end, m_bank[i]); + m_view[i][1].install_readwrite_bank(start, end, m_bank[i]); + } + + m_view[3][2].install_read_bank(0x6000, 0x7fff, m_bank[3]); + m_view[3][2].install_read_handler(0x7ff0, 0x7ff7, read8sm_delegate(*this, [this] (offs_t offset) { return m_selected_bank[offset] & 0xff; }, "bank_r")); + m_view[3][3].install_readwrite_bank(0x6000, 0x7fff, m_bank[3]); + m_view[3][3].install_read_handler(0x7ff0, 0x7ff7, read8sm_delegate(*this, [this] (offs_t offset) { return m_selected_bank[offset] & 0xff; }, "bank_r")); + page(1)->install_write_handler(0x6000, 0x6000, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<0>))); + page(1)->install_write_handler(0x6400, 0x6400, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<1>))); + page(1)->install_write_handler(0x6800, 0x6800, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<2>))); + page(1)->install_write_handler(0x6c00, 0x6c00, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<3>))); + page(1)->install_write_handler(0x7000, 0x7000, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<4>))); + page(1)->install_write_handler(0x7400, 0x7400, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<6>))); + page(1)->install_write_handler(0x7800, 0x7800, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<5>))); + page(1)->install_write_handler(0x7c00, 0x7c00, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<7>))); + page(1)->install_readwrite_handler(0x7ff8, 0x7ff8, + read8smo_delegate(*this, [this] () { return m_bank9; }, "bank9_r"), + write8smo_delegate(*this, [this] (u8 data) + { + m_bank9 = data; + select_banks(); + }, "bank9_w")); + page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*this, [this] (u8 data) + { + m_control = data; + select_banks(); + }, "control_w" + )); +} + + +void msx_slot_panasonic08r_device::device_reset() +{ + m_control = 0; + m_bank9 = 0; + for (int i = 0 ; i < 8; i++) + { + m_selected_bank[i] = 0; + m_bank[i]->set_entry(0); + m_view[i].select(0); + } +} + + +template <int Bank> +void msx_slot_panasonic08r_device::set_view() +{ + const bool sram_active = (m_selected_bank[Bank] >= 0x80 && m_selected_bank[Bank] < 0x84); + const bool ram_active = (m_selected_bank[Bank] >= 0x180); + const int view = ((sram_active || ram_active) ? 1 : 0) | ((Bank == 3 && BIT(m_control, 2)) ? 2 : 0); + + m_view[Bank].select(view); +} + + +template <int Bank> +void msx_slot_panasonic08r_device::bank_w(u8 data) +{ + u16 bank = data; + + if (BIT(m_control, 4)) + bank |= (BIT(m_bank9, Bank) << 8); + m_selected_bank[Bank] = bank; + m_bank[Bank]->set_entry(bank); + set_view<Bank>(); +} + + +void msx_slot_panasonic08r_device::select_banks() +{ + bank_w<0>(m_selected_bank[0]); + bank_w<1>(m_selected_bank[1]); + bank_w<2>(m_selected_bank[2]); + bank_w<3>(m_selected_bank[3]); + bank_w<4>(m_selected_bank[4]); + bank_w<5>(m_selected_bank[5]); + bank_w<6>(m_selected_bank[6]); + bank_w<7>(m_selected_bank[7]); +} diff --git a/src/devices/bus/msx/slot/panasonic08r.h b/src/devices/bus/msx/slot/panasonic08r.h new file mode 100644 index 00000000000..c7efcf6e27a --- /dev/null +++ b/src/devices/bus/msx/slot/panasonic08r.h @@ -0,0 +1,52 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +#ifndef MAME_BUS_MSX_SLOT_PANASONIC08R_H +#define MAME_BUS_MSX_SLOT_PANASONIC08R_H + +#pragma once + +#include "ram_mm.h" +#include "slot.h" +#include "machine/nvram.h" + + +DECLARE_DEVICE_TYPE(MSX_SLOT_PANASONIC08R, msx_slot_panasonic08r_device) + + +class msx_slot_panasonic08r_device : public device_t, public msx_internal_slot_interface +{ +public: + msx_slot_panasonic08r_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // configuration helpers + template <typename T> msx_slot_panasonic08r_device &set_mm_tag(T &&tag) { m_mm.set_tag(std::forward<T>(tag)); return *this; } + void set_rom_start(const char *region, u32 offset) { m_rom_region.set_tag(region); m_region_offset = offset; } + msx_slot_panasonic08r_device &set_sram_size(u16 size) { m_sram_size = size; return *this; } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual void device_add_mconfig(machine_config &config) override; + +private: + template <int Bank> void set_view(); + template <int Bank> void bank_w(u8 data); + + void select_banks(); + + u16 m_sram_size; + required_device<nvram_device> m_nvram; + required_memory_region m_rom_region; + memory_bank_array_creator<8> m_bank; + memory_view m_view[8]; + required_device<msx_slot_ram_mm_device> m_mm; + u32 m_region_offset; + u16 m_selected_bank[8]; + u8 m_control; + u8 m_bank9; + std::unique_ptr<u8[]> m_sram; +}; + + +#endif // MAME_BUS_MSX_SLOT_PANASONIC08R_H diff --git a/src/devices/bus/msx/slot/ram_mm.h b/src/devices/bus/msx/slot/ram_mm.h index 69ce5f41053..a6015fe095e 100644 --- a/src/devices/bus/msx/slot/ram_mm.h +++ b/src/devices/bus/msx/slot/ram_mm.h @@ -15,6 +15,9 @@ public: msx_slot_ram_mm_device &set_total_size(u32 total_size) { m_total_size = total_size; return *this; } msx_slot_ram_mm_device &set_unused_bits(u8 unused_bits) { m_unused_bits = unused_bits; return *this; } + // Backdoor for the Turbo-R firmware/internal mapper to access internal RAM. + std::vector<u8> &get_ram() { return m_ram; } + protected: virtual void device_start() override; |