bus/msx/cart: Added Sony HBI-55/Yamaha UDC-01 SRAM data cartridges. (#10966)

This commit is contained in:
wilbertpol 2023-04-17 18:52:50 +01:00 committed by GitHub
parent 94ef073a34
commit 9ffd85dd7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 201 additions and 1 deletions

View File

@ -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",

View File

@ -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);

View File

@ -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<i8255_device> m_i8255;
std::unique_ptr<u8[]> 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<u8[]>(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)")

View File

@ -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

View File

@ -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";

View File

@ -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;