msx/msx.cpp: Add system control register to allow switching between internal and external kanji support. (#12419)

This commit is contained in:
wilbertpol 2024-05-30 21:11:55 +01:00 committed by GitHub
parent 6270bd3a06
commit 344de2ca8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 61 additions and 36 deletions

View File

@ -124,9 +124,8 @@ std::error_condition msx_cart_fs_sr021_device::initialize_cartridge(std::string
page(1)->install_write_handler(0x7800, 0x7800, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::bank_w<5>))); // a000-bfff
page(1)->install_write_handler(0x7ff9, 0x7ff9, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::control_w)));
// Takes over kanji from base system?
io_space().install_write_handler(0xd8, 0xd9, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::kanji_w)));
io_space().install_read_handler(0xd9, 0xd9, emu::rw_delegate(*this, FUNC(msx_cart_fs_sr021_device::kanji_r)));
io_space().install_write_tap(0xd8, 0xd9, "kanji_w", [this] (offs_t ofs, u8 &data, u8) { this->kanji_w(ofs, data); });
io_space().install_read_tap(0xd9, 0xd9, "kanji_r", [this] (offs_t ofs, u8 &data, u8) { data &= this->kanji_r(ofs); });
return std::error_condition();
}
@ -181,7 +180,7 @@ u8 msx_cart_fs_sr021_device::kanji_r(offs_t offset)
void msx_cart_fs_sr021_device::kanji_w(offs_t offset, u8 data)
{
if (offset)
if (BIT(offset, 0))
m_kanji_latch = (m_kanji_latch & 0x007e0) | ((data & 0x3f) << 11);
else
m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);

View File

@ -85,8 +85,8 @@ void msx_cart_kanji_device::install_kanji_handlers()
m_kanji_mask = cart_kanji_region()->bytes() - 1;
// Install IO read/write handlers
io_space().install_write_handler(0xd8, 0xd9, emu::rw_delegate(*this, FUNC(msx_cart_kanji_device::kanji_w)));
io_space().install_read_handler(0xd9, 0xd9, emu::rw_delegate(*this, FUNC(msx_cart_kanji_device::kanji_r)));
io_space().install_write_tap(0xd8, 0xd9, "kanji_w", [this] (offs_t ofs, u8 &data, u8) { this->kanji_w(ofs, data); });
io_space().install_read_tap(0xd9, 0xd9, "kanji_r", [this] (offs_t ofs, u8 &data, u8) { data &= this->kanji_r(ofs); });
}
std::error_condition msx_cart_kanji_device::initialize_cartridge(std::string &message)
@ -113,7 +113,7 @@ u8 msx_cart_kanji_device::kanji_r(offs_t offset)
void msx_cart_kanji_device::kanji_w(offs_t offset, u8 data)
{
if (offset)
if (BIT(offset, 0))
m_kanji_address = (m_kanji_address & 0x007e0) | ((data & 0x3f) << 11);
else
m_kanji_address = (m_kanji_address & 0x1f800) | ((data & 0x3f) << 5);

View File

@ -226,7 +226,7 @@ void msx_state::msx_base_io_map(address_map &map)
map(0xa8, 0xab).rw(m_ppi, FUNC(i8255_device::read), FUNC(i8255_device::write));
// // Sanyo optical pen interface (not emulated)
// map(0xb8, 0xbb).noprw();
// 0xd8 - 0xdb : Kanji rom interface. I/O handlers will be installed in a kanji rom is present.
// 0xd8 - 0xdb : Kanji rom interface. I/O handlers will be installed if a kanji rom is present.
// 0xfc - 0xff : Memory mapper I/O ports. I/O handlers will be installed if a memory mapper is present in a system
}
@ -250,6 +250,7 @@ void msx_state::machine_reset()
m_caps_led = 0;
m_code_led = 0;
m_system_control = m_has_system_control ? 0x00 : 0xff;
}
void msx_state::machine_start()
@ -260,14 +261,18 @@ void msx_state::machine_start()
if (m_region_kanji.found() && m_region_kanji.length() >= 0x20000)
{
get_io_space().install_write_handler(0xd8, 0xd9, emu::rw_delegate(*this, FUNC(msx_state::kanji_w)));
get_io_space().install_read_handler(0xd9, 0xd9, emu::rw_delegate(*this, FUNC(msx_state::kanji_r)));
get_io_space().install_write_tap(0xd8, 0xd9, "kanji_w", [this] (offs_t ofs, u8 &data, u8) { this->kanji_w(ofs, data); });
get_io_space().install_read_tap(0xd9, 0xd9, "kanji_r", [this] (offs_t ofs, u8 &data, u8) { data &= this->kanji_r(ofs); });
if (m_region_kanji.length() >= 0x40000)
{
get_io_space().install_write_handler(0xda, 0xdb, emu::rw_delegate(*this, FUNC(msx_state::kanji2_w)));
get_io_space().install_read_handler(0xd9, 0xd9, emu::rw_delegate(*this, FUNC(msx_state::kanji2_r)));
get_io_space().install_write_tap(0xda, 0xdb, "kanji2_w", [this] (offs_t ofs, u8 &data, u8) { this->kanji2_w(ofs, data); });
get_io_space().install_read_tap(0xdb, 0xdb, "kanji2_r", [this] (offs_t ofs, u8 &data, u8) { data &= this->kanji2_r(ofs); });
}
}
if (m_has_system_control)
{
get_io_space().install_write_handler(0xf5, 0xf5, write8smo_delegate(*this, [this] (u8 data) { m_system_control = data; }, "system_control"));
}
}
void msx_state::driver_start()
@ -283,6 +288,7 @@ void msx_state::driver_start()
save_item(NAME(m_secondary_slot));
save_item(NAME(m_port_c_old));
save_item(NAME(m_keylatch));
save_item(NAME(m_system_control));
}
u8 msx_state::psg_port_a_r()
@ -382,43 +388,57 @@ u8 msx_state::expanded_slot_r()
u8 msx_state::kanji_r(offs_t offset)
{
const u32 latch = m_kanji_fsa1fx ? bitswap<17>(m_kanji_latch, 4, 3, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 2, 1, 0) : m_kanji_latch;
const u8 result = m_region_kanji[latch];
if (!machine().side_effects_disabled())
if (BIT(m_system_control, 0))
{
m_kanji_latch = (m_kanji_latch & ~0x1f) | ((m_kanji_latch + 1) & 0x1f);
const u32 latch = m_kanji_fsa1fx ? bitswap<17>(m_kanji_latch, 4, 3, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 2, 1, 0) : m_kanji_latch;
const u8 result = m_region_kanji[latch];
if (!machine().side_effects_disabled())
{
m_kanji_latch = (m_kanji_latch & ~0x1f) | ((m_kanji_latch + 1) & 0x1f);
}
return result;
}
return result;
return 0xff;
}
void msx_state::kanji_w(offs_t offset, u8 data)
{
if (offset)
m_kanji_latch = (m_kanji_latch & 0x007e0) | ((data & 0x3f) << 11);
else
m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
if (BIT(m_system_control, 0))
{
if (BIT(offset, 0))
m_kanji_latch = (m_kanji_latch & 0x007e0) | ((data & 0x3f) << 11);
else
m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
}
}
u8 msx_state::kanji2_r(offs_t offset)
{
// TODO: Are there one or two latches in a system?
const u32 latch = m_kanji_fsa1fx ? bitswap<17>(m_kanji_latch, 4, 3, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 2, 1, 0) : m_kanji_latch;
const u8 result = m_region_kanji[0x20000 | latch];
if (!machine().side_effects_disabled())
if (BIT(m_system_control, 1))
{
m_kanji_latch = (m_kanji_latch & ~0x1f) | ((m_kanji_latch + 1) & 0x1f);
// TODO: Are there one or two latches in a system?
const u32 latch = m_kanji_fsa1fx ? bitswap<17>(m_kanji_latch, 4, 3, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 2, 1, 0) : m_kanji_latch;
const u8 result = m_region_kanji[0x20000 | latch];
if (!machine().side_effects_disabled())
{
m_kanji_latch = (m_kanji_latch & ~0x1f) | ((m_kanji_latch + 1) & 0x1f);
}
return result;
}
return result;
return 0xff;
}
void msx_state::kanji2_w(offs_t offset, u8 data)
{
if (offset)
m_kanji_latch = (m_kanji_latch & 0x007e0) | ((data & 0x3f) << 11);
else
m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
if (BIT(m_system_control, 1))
{
if (BIT(offset, 0))
m_kanji_latch = (m_kanji_latch & 0x007e0) | ((data & 0x3f) << 11);
else
m_kanji_latch = (m_kanji_latch & 0x1f800) | ((data & 0x3f) << 5);
}
}
void msx_state::msx_base(ay8910_type ay8910_type, machine_config &config, const internal_layout &layout)
@ -522,6 +542,8 @@ void msx_state::msx1(vdp_type vdp_type, ay8910_type ay8910_type, machine_config
// Software lists
msx1_add_softlists(config);
m_has_system_control = false;
}
address_space& msx_state::get_io_space()
@ -656,6 +678,8 @@ void msx2_base_state::msx2_base(ay8910_type ay8910_type, machine_config &config,
// real time clock
RP5C01(config, m_rtc, 32.768_kHz_XTAL);
m_has_system_control = true;
}
void msx2_base_state::msx2(ay8910_type ay8910_type, machine_config &config, const internal_layout &layout)

View File

@ -222,6 +222,8 @@ protected:
u8 m_secondary_slot[4];
u8 m_port_c_old;
u8 m_keylatch;
u8 m_system_control;
bool m_has_system_control;
output_finder<> m_caps_led;
output_finder<> m_code_led;
const XTAL m_main_xtal;
@ -337,7 +339,6 @@ protected:
optional_device<ym2413_device> m_ym2413;
required_device<rp5c01_device> m_rtc;
// rtc
u8 m_rtc_latch = 0;
};

View File

@ -370,6 +370,7 @@ void msx2_state::cpc400(machine_config &config)
// FDC: mb8877a, 1 3.5" DS?DD drive
// 1 Cartridge slot
// 1 Expansion slot
// The check for an external kanji rom always fails; deliberately? expects other type of kanji extension? bad dump?
add_internal_slot(config, MSX_SLOT_ROM, "mainrom", 0, 0, 0, 2, "mainrom");
add_internal_slot(config, MSX_SLOT_ROM, "hangul", 0, 1, 1, 2, "hangul");
@ -403,6 +404,7 @@ void msx2_state::cpc400s(machine_config &config)
// FDC: mb8877a, 1 3.5" DS?DD drive
// 1 Cartridge slot
// DW64MX1
// The check for an external kanji rom always fails; deliberately? expects other type of kanji extension? bad dump?
add_internal_slot(config, MSX_SLOT_ROM, "mainrom", 0, 0, 0, 2, "mainrom");
add_internal_slot(config, MSX_SLOT_ROM, "hangul1", 0, 1, 1, 1, "hangul", 0x4000);
@ -721,9 +723,8 @@ void msx2_state::mlg3(machine_config &config)
{
// YM2149 (in S3527)
// FDC: wd2793?, 1 3.5" DSDD drive
// S-1985 MSX Engine
// S3527 MSX Engine
// 4 Cartridge slots (3 internal, 1 taken by RS232 board)
// S3527
// RS232 with switch. What does the switch do?
add_internal_slot(config, MSX_SLOT_ROM, "mainrom", 0, 0, 2, "mainrom");