From 9ffd85dd7d6f51234da4c35594cae8b23460fe45 Mon Sep 17 00:00:00 2001 From: wilbertpol Date: Mon, 17 Apr 2023 18:52:50 +0100 Subject: [PATCH] bus/msx/cart: Added Sony HBI-55/Yamaha UDC-01 SRAM data cartridges. (#10966) --- scripts/src/bus.lua | 2 + src/devices/bus/msx/cart/cartridge.cpp | 4 +- src/devices/bus/msx/cart/hbi55.cpp | 181 +++++++++++++++++++++++ src/devices/bus/msx/cart/hbi55.h | 13 ++ src/devices/bus/msx/cart/slotoptions.cpp | 1 + src/devices/bus/msx/cart/slotoptions.h | 1 + 6 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 src/devices/bus/msx/cart/hbi55.cpp create mode 100644 src/devices/bus/msx/cart/hbi55.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index cd04a87cd18..70c61fee451 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1910,6 +1910,8 @@ if (BUSES["MSX_SLOT"]~=null) then MAME_DIR .. "src/devices/bus/msx/cart/fs_sr022.h", MAME_DIR .. "src/devices/bus/msx/cart/halnote.cpp", MAME_DIR .. "src/devices/bus/msx/cart/halnote.h", + MAME_DIR .. "src/devices/bus/msx/cart/hbi55.cpp", + MAME_DIR .. "src/devices/bus/msx/cart/hbi55.h", MAME_DIR .. "src/devices/bus/msx/cart/hfox.cpp", MAME_DIR .. "src/devices/bus/msx/cart/hfox.h", MAME_DIR .. "src/devices/bus/msx/cart/holy_quran.cpp", diff --git a/src/devices/bus/msx/cart/cartridge.cpp b/src/devices/bus/msx/cart/cartridge.cpp index 7731d8ba521..20871d5bee1 100644 --- a/src/devices/bus/msx/cart/cartridge.cpp +++ b/src/devices/bus/msx/cart/cartridge.cpp @@ -15,6 +15,7 @@ #include "fmpac.h" #include "fs_sr022.h" #include "halnote.h" +#include "hbi55.h" #include "hfox.h" #include "holy_quran.h" #include "ink.h" @@ -85,9 +86,10 @@ void msx_cart(device_slot_interface &device, bool is_in_subslot) device.option_add_internal(slotoptions::EC701, MSX_CART_EC701); device.option_add(slotoptions::BEEPACK, MSX_CART_BEEPACK); device.option_add(slotoptions::BM_012, MSX_CART_BM_012); + device.option_add(slotoptions::HBI55, MSX_CART_HBI55); device.option_add(slotoptions::MOONSOUND, MSX_CART_MOONSOUND); - device.option_add(slotoptions::UCN01, MSX_CART_UCN01); device.option_add(slotoptions::SOFTCARD, MSX_CART_SOFTCARD); + device.option_add(slotoptions::UCN01, MSX_CART_UCN01); if (!is_in_subslot) { device.option_add(slotoptions::SLOTEXP, MSX_CART_SLOTEXPANDER); diff --git a/src/devices/bus/msx/cart/hbi55.cpp b/src/devices/bus/msx/cart/hbi55.cpp new file mode 100644 index 00000000000..3121142cc78 --- /dev/null +++ b/src/devices/bus/msx/cart/hbi55.cpp @@ -0,0 +1,181 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +#include "emu.h" +#include "hbi55.h" + +#include "machine/i8255.h" + +namespace { + +/* +Emulation of Sony HBI-55 and Yamaha UDC-01 data cartridges. +Internally these two data cartridges are the same. + +In theory these battery backed ram cartridges could use up to 8 x 2KB sram +chips but only cartridges using 2 2KB sram chips were produced. +*/ + +class msx_cart_hbi55_device : public device_t, public msx_cart_interface, public device_image_interface +{ +public: + msx_cart_hbi55_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, MSX_CART_HBI55, tag, owner, clock) + , msx_cart_interface(mconfig, *this) + , device_image_interface(mconfig, *this) + , m_i8255(*this, "i8255") + , m_address(0) + , m_ce(false) + , m_oe(false) + , m_last_c(0) + { } + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + virtual bool is_readable() const noexcept override { return true; } + virtual bool is_writeable() const noexcept override { return true; } + virtual bool is_creatable() const noexcept override { return true; } + virtual bool is_reset_on_load() const noexcept override { return false; } + virtual bool support_command_line_image_creation() const noexcept override { return true; } + virtual char const *file_extensions() const noexcept override { return "bin"; } + virtual const char *image_type_name() const noexcept override { return "sramcard"; } + virtual const char *image_brief_type_name() const noexcept override { return "sram"; } + virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override; + virtual image_init_result call_load() override; + virtual void call_unload() override; + +private: + static constexpr u32 SRAM_SIZE = 0x1000; + + void ppi_port_a_w(u8 data); + void ppi_port_b_w(u8 data); + void ppi_port_c_w(u8 data); + u8 ppi_port_c_r(); + void sram_update(); + void clear_sram(); + + required_device m_i8255; + std::unique_ptr m_sram; + u16 m_address; + bool m_ce; + bool m_oe; + u8 m_last_c; +}; + +image_init_result msx_cart_hbi55_device::call_load() +{ + if (length() != SRAM_SIZE) + return image_init_result::FAIL; + + if (fread(m_sram.get(), SRAM_SIZE) != SRAM_SIZE) + return image_init_result::FAIL; + + return image_init_result::PASS; +} + +void msx_cart_hbi55_device::call_unload() +{ + if (!is_readonly()) + { + fseek(0, SEEK_SET); + fwrite(m_sram.get(), SRAM_SIZE); + } + clear_sram(); +} + +image_init_result msx_cart_hbi55_device::call_create(int format_type, util::option_resolution *format_options) +{ + clear_sram(); + + if (fwrite(m_sram.get(), SRAM_SIZE) != SRAM_SIZE) + return image_init_result::FAIL; + + return image_init_result::PASS; +} + +void msx_cart_hbi55_device::device_add_mconfig(machine_config &config) +{ + I8255(config, m_i8255); + m_i8255->out_pa_callback().set(FUNC(msx_cart_hbi55_device::ppi_port_a_w)); + m_i8255->out_pb_callback().set(FUNC(msx_cart_hbi55_device::ppi_port_b_w)); + m_i8255->out_pc_callback().set(FUNC(msx_cart_hbi55_device::ppi_port_c_w)); + m_i8255->in_pc_callback().set(FUNC(msx_cart_hbi55_device::ppi_port_c_r)); +} + +void msx_cart_hbi55_device::device_start() +{ + m_sram = std::make_unique(SRAM_SIZE); + clear_sram(); + + save_pointer(NAME(m_sram), SRAM_SIZE); + save_item(NAME(m_address)); + save_item(NAME(m_ce)); + save_item(NAME(m_oe)); + save_item(NAME(m_last_c)); + + io_space().install_write_handler(0xb0, 0xb3, write8sm_delegate(*m_i8255, FUNC(i8255_device::write))); + io_space().install_read_handler(0xb0, 0xb3, read8sm_delegate(*m_i8255, FUNC(i8255_device::read))); +} + +void msx_cart_hbi55_device::device_reset() +{ + m_address = 0; + m_ce = false; + m_oe = false; + m_last_c = 0; +} + +void msx_cart_hbi55_device::clear_sram() +{ + std::fill_n(m_sram.get(), SRAM_SIZE, 0); +} + +void msx_cart_hbi55_device::ppi_port_a_w(u8 data) +{ + // address bits 0-7 + m_address = (m_address & 0xff00) | data; + sram_update(); +} + +void msx_cart_hbi55_device::ppi_port_b_w(u8 data) +{ + // 76543210 + // |||||\\\-- address bits 8-10 + // ||\\\----- to SRAM chip select TC40H138 demux (only Y0 and Y1 are used) + // |\-------- SRAM CE (1 = enable) + // \--------- SRAM OE (1 = output enable, 0 = write enable) + m_address = (m_address & 0x00ff) | ((data & 0x3f) << 8); + m_ce = BIT(data, 6); + m_oe = BIT(data, 7); + sram_update(); +} + +void msx_cart_hbi55_device::ppi_port_c_w(u8 data) +{ + m_last_c = data; + sram_update(); +} + +u8 msx_cart_hbi55_device::ppi_port_c_r() +{ + if (m_ce && m_oe && m_address < SRAM_SIZE) + { + return m_sram[m_address]; + } + // should actually be floating bus + return 0xff; +} + +void msx_cart_hbi55_device::sram_update() +{ + if (m_ce && !m_oe && m_address < SRAM_SIZE) + { + m_sram[m_address] = m_last_c; + } +} + +} // anonymous namespace + +DEFINE_DEVICE_TYPE_PRIVATE(MSX_CART_HBI55, msx_cart_interface, msx_cart_hbi55_device, "msx_cart_hbi55", "Sony HBI-55/Yamaha UDC-01 Data Cartridge (4KB SRAM)") + diff --git a/src/devices/bus/msx/cart/hbi55.h b/src/devices/bus/msx/cart/hbi55.h new file mode 100644 index 00000000000..4b1c772dac7 --- /dev/null +++ b/src/devices/bus/msx/cart/hbi55.h @@ -0,0 +1,13 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +#ifndef MAME_BUS_MSX_CART_HBI55_H +#define MAME_BUS_MSX_CART_HBI55_H + +#pragma once + +#include "bus/msx/slot/cartridge.h" + +DECLARE_DEVICE_TYPE(MSX_CART_HBI55, msx_cart_interface) + + +#endif // MAME_BUS_MSX_CART_HBI55_H diff --git a/src/devices/bus/msx/cart/slotoptions.cpp b/src/devices/bus/msx/cart/slotoptions.cpp index 2971d8307de..0108baa3265 100644 --- a/src/devices/bus/msx/cart/slotoptions.cpp +++ b/src/devices/bus/msx/cart/slotoptions.cpp @@ -36,6 +36,7 @@ char const *const FMPAC = "fmpac"; char const *const FS_SR022 = "fs_sr022"; char const *const GAMEMASTER2 = "gamemaster2"; char const *const HALNOTE = "halnote"; +char const *const HBI55 = "hbi55"; char const *const HFOX = "hfox"; char const *const HOLY_QURAN = "holy_quran"; char const *const INK = "ink"; diff --git a/src/devices/bus/msx/cart/slotoptions.h b/src/devices/bus/msx/cart/slotoptions.h index 68ba3fbce57..ba5d1a24436 100644 --- a/src/devices/bus/msx/cart/slotoptions.h +++ b/src/devices/bus/msx/cart/slotoptions.h @@ -39,6 +39,7 @@ extern char const *const FMPAC; extern char const *const FS_SR022; extern char const *const GAMEMASTER2; extern char const *const HALNOTE; +extern char const *const HBI55; extern char const *const HFOX; extern char const *const HOLY_QURAN; extern char const *const INK;