summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/bus.lua2
-rw-r--r--src/devices/bus/msx/slot/panasonic08r.cpp165
-rw-r--r--src/devices/bus/msx/slot/panasonic08r.h52
-rw-r--r--src/devices/bus/msx/slot/ram_mm.h3
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;