bus/msx/cart/msxdos2.cpp: Added full MSX-DOS2 support. (#10893)

New working software list items (msx1_cart.xml)
------------------------------
Japanese MSX-DOS 2.20 (Japan, 256KB)
Japanese MSX-DOS 2.20 (Japan, 256KB, alt)
Japanese MSX-DOS 2.20 (Japan, 256KB, alt 2)
Japanese MSX-DOS 2.20 (Japan, 128KB)
Japanese MSX-DOS 2.20 (Japan)
MSX-DOS 2.20 (Europe)
This commit is contained in:
wilbertpol 2023-02-14 18:29:14 +00:00 committed by GitHub
parent d8f70e6446
commit 9faa7d1138
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 374 additions and 45 deletions

View File

@ -3156,4 +3156,163 @@ LZ93A13 (32 pin) - 8KB banks
</part>
</software>
<software name="msxdos2j">
<description>Japanese MSX-DOS 2.20 (Japan, 256KB)</description>
<year>1989</year>
<publisher>ASCII</publisher>
<info name="alt_title" value="日本語 MSX-DOS 2"/>
<info name="serial" value="2307603"/>
<part name="cart" interface="msx_cart">
<feature name="slot" value="msxdos2j"/>
<feature name="bank_address" value="0x7ffe"/>
<dataarea name="rom" size="0x10000">
<rom name="ascii_msxdos22.rom" size="0x10000" crc="47eea028" sha1="42f4e3360eb134857b0efa82c1abedf342680124"/>
</dataarea>
<dataarea name="ram" size="0x40000"/>
</part>
<part name="flope" interface="floppy_3_5">
<feature name="part_id" value="English MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22de.dsk" size="368640" crc="9be0bfd1" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
<part name="flopj" interface="floppy_3_5">
<feature name="part_id" value="Japanese MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22dj.dsk" size="368640" crc="d9ef5567" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
</software>
<software name="msxdos2ja" cloneof="msxdos2j">
<description>Japanese MSX-DOS 2.20 (Japan, 256KB, alt)</description>
<year>1989</year>
<publisher>ASCII</publisher>
<info name="alt_title" value="日本語 MSX-DOS 2"/>
<info name="serial" value="2307603"/>
<part name="cart" interface="msx_cart">
<feature name="slot" value="msxdos2j"/>
<feature name="bank_address" value="0x7ffe"/>
<dataarea name="rom" size="0x10000">
<rom name="mdos22v3.rom" size="0x10000" crc="845f5ab6" sha1="6dcf76a0076f8c7f025979d7d060367fb5ed56bc"/>
</dataarea>
<dataarea name="ram" size="0x40000"/>
</part>
<part name="flope" interface="floppy_3_5">
<feature name="part_id" value="English MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22de.dsk" size="368640" crc="9be0bfd1" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
<part name="flopj" interface="floppy_3_5">
<feature name="part_id" value="Japanese MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22dj.dsk" size="368640" crc="d9ef5567" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
</software>
<software name="msxdos2jb" cloneof="msxdos2j">
<description>Japanese MSX-DOS 2.20 (Japan, 256KB, alt 2)</description>
<year>1989</year>
<publisher>ASCII</publisher>
<info name="alt_title" value="日本語 MSX-DOS 2"/>
<info name="serial" value="2307603"/>
<part name="cart" interface="msx_cart">
<feature name="slot" value="msxdos2j"/>
<feature name="bank_address" value="0x6000"/>
<dataarea name="rom" size="0x10000">
<rom name="mdos22v2.rom" size="0x10000" crc="8687c4f1" sha1="9155145d3e8522daf33f821f1ab68ce165960c1a"/>
</dataarea>
<dataarea name="ram" size="0x40000"/>
</part>
<part name="flope" interface="floppy_3_5">
<feature name="part_id" value="English MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22de.dsk" size="368640" crc="9be0bfd1" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
<part name="flopj" interface="floppy_3_5">
<feature name="part_id" value="Japanese MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22dj.dsk" size="368640" crc="d9ef5567" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
</software>
<software name="msxdos2j_128" cloneof="msxdos2j">
<description>Japanese MSX-DOS 2.20 (Japan, 128KB)</description>
<year>1988</year>
<publisher>ASCII</publisher>
<info name="alt_title" value="日本語 MSX-DOS 2"/>
<info name="serial" value="2307601"/>
<info name="gtin" value="04988606202515"/>
<part name="cart" interface="msx_cart">
<feature name="slot" value="msxdos2j"/>
<feature name="bank_address" value="0x6000"/>
<dataarea name="rom" size="0x10000">
<rom name="mdos22v1.rom" size="0x10000" crc="93cccc2d" sha1="ac26be7fc8386d12ed6a3de4f05fd462967599a8"/>
</dataarea>
<dataarea name="ram" size="0x20000"/>
</part>
<part name="flope" interface="floppy_3_5">
<feature name="part_id" value="English MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22de.dsk" size="368640" crc="9be0bfd1" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
<part name="flopj" interface="floppy_3_5">
<feature name="part_id" value="Japanese MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22dj.dsk" size="368640" crc="d9ef5567" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
</software>
<software name="msxdos2j_0" cloneof="msxdos2j">
<description>Japanese MSX-DOS 2.20 (Japan)</description>
<year>1988</year>
<publisher>ASCII</publisher>
<info name="alt_title" value="日本語 MSX-DOS 2"/>
<info name="serial" value="2307602"/>
<part name="cart" interface="msx_cart">
<feature name="slot" value="msxdos2j"/>
<feature name="bank_address" value="0x6000"/>
<dataarea name="rom" size="0x10000">
<rom name="mdos22v1.rom" size="0x10000" crc="93cccc2d" sha1="ac26be7fc8386d12ed6a3de4f05fd462967599a8"/>
</dataarea>
</part>
<part name="flope" interface="floppy_3_5">
<feature name="part_id" value="English MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22de.dsk" size="368640" crc="9be0bfd1" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
<part name="flopj" interface="floppy_3_5">
<feature name="part_id" value="Japanese MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22dj.dsk" size="368640" crc="d9ef5567" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
</software>
<software name="msxdos2e">
<description>MSX-DOS 2.20 (Europe)</description>
<year>1989</year>
<publisher>H.S.H.</publisher>
<part name="cart" interface="msx_cart">
<feature name="slot" value="msxdos2e"/>
<feature name="bank_address" value="0x6000"/>
<dataarea name="rom" size="0x10000">
<rom name="msxdos220.rom" size="0x10000" crc="1c430991" sha1="c36c9e0f96738a340381e23b4f97245388801a46"/>
</dataarea>
</part>
<part name="flope" interface="floppy_3_5">
<feature name="part_id" value="English MSX-DOS2"/>
<dataarea name="flop" size="368640">
<rom name="mdos22de.dsk" size="368640" crc="9be0bfd1" sha1="e29b70766f03a7f97082348d8ef3b410655c0612"/>
</dataarea>
</part>
</software>
</softwarelist>

View File

@ -65,7 +65,8 @@ void msx_cart(device_slot_interface &device)
device.option_add_internal("msxaud_fsca1", MSX_CART_MSX_AUDIO_FSCA1);
device.option_add_internal("msxaud_hxmu900", MSX_CART_MSX_AUDIO_HXMU900);
device.option_add_internal("msxaud_nms1205", MSX_CART_MSX_AUDIO_NMS1205);
device.option_add_internal("msxdos2", MSX_CART_MSXDOS2);
device.option_add_internal("msxdos2j", MSX_CART_MSXDOS2J);
device.option_add_internal("msxdos2e", MSX_CART_MSXDOS2E);
device.option_add_internal("msxwrite", MSX_CART_MSXWRITE);
device.option_add_internal("nomapper", MSX_CART_NOMAPPER);
device.option_add_internal("rtype", MSX_CART_RTYPE);

View File

@ -3,49 +3,238 @@
#include "emu.h"
#include "msxdos2.h"
// This is the bare minimum to get a msx-dos 2 rom working in a system
// TODO:
// - Add subslots for regular rom and kanji driver rom
// - Add support for 128KB and 256KB memory mapper versions
DEFINE_DEVICE_TYPE(MSX_CART_MSXDOS2, msx_cart_msxdos2_device, "msx_cart_msxdos2", "MSX Cartridge - MSXDOS2")
#include "bus/generic/slot.h"
msx_cart_msxdos2_device::msx_cart_msxdos2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, MSX_CART_MSXDOS2, tag, owner, clock)
, msx_cart_interface(mconfig, *this)
, m_rombank(*this, "rombank")
/*
Emulation of MSX-DOS2 cartridges.
Japanese MSX-DOS2 uses an expanded slot model:
- Subslot 1 - Memory mapper with no, 128KB, or 256KB RAM
- Subslot 2 - Kanji Basic ROM
- Subslot 3 - MSX-DOS2 banked ROM
European MSX-DOS2 releases only contain MSX-DOS2 banked ROM.
The rom banking address is either $6000 or $7ffe depending on the
version of the hardware.
*/
namespace {
class msx_cart_msxdos2_base_device : public device_t, public msx_cart_interface
{
protected:
msx_cart_msxdos2_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, msx_cart_interface(mconfig, *this)
, m_rombank(*this, "rombank")
, m_bank_address(0)
{ }
virtual void device_start() override { }
virtual void device_reset() override;
virtual image_init_result initialize_cartridge(std::string &message) override;
void bank_w(u8 data);
static inline constexpr unsigned PAGE_SIZE = 0x4000;
memory_bank_creator m_rombank;
u16 m_bank_address;
};
void msx_cart_msxdos2_base_device::device_reset()
{
m_rombank->set_entry(0);
}
void msx_cart_msxdos2_device::device_reset()
{
m_rombank->set_entry(1);
}
image_init_result msx_cart_msxdos2_device::initialize_cartridge(std::string &message)
image_init_result msx_cart_msxdos2_base_device::initialize_cartridge(std::string &message)
{
if (!cart_rom_region())
{
message = "msx_cart_msxdos2_device: Required region 'rom' was not found.";
message = "msx_cart_msxdos2: Required region 'rom' was not found.";
return image_init_result::FAIL;
}
if (cart_rom_region()->bytes() != 0x10000)
{
message = "msx_cart_msxdos2_device: Region 'rom' has unsupported size.";
message = "msx_cart_msxdos2: Region 'rom' has unsupported size.";
return image_init_result::FAIL;
}
m_rombank->configure_entries(0, 4, cart_rom_region()->base(), 0x4000);
const char *bank_address_str = get_feature("bank_address");
if (!bank_address_str)
{
message = "msx_cart_msxdos2: Feature 'bank_address' was not found.";
return image_init_result::FAIL;
}
m_bank_address = strtol(bank_address_str, nullptr, 0);
if (m_bank_address < 0x4000 || m_bank_address > 0x7fff)
{
message = "msx_cart_msxdos2: bank_address must be between 0x4000 and 0x7fff.";
return image_init_result::FAIL;
}
page(1)->install_read_bank(0x4000, 0x7fff, m_rombank);
page(1)->install_write_handler(0x7ffe, 0x7ffe, write8smo_delegate(*this, FUNC(msx_cart_msxdos2_device::bank_w)));
m_rombank->configure_entries(0, 4, cart_rom_region()->base(), PAGE_SIZE);
return image_init_result::PASS;
}
void msx_cart_msxdos2_device::bank_w(u8 data)
void msx_cart_msxdos2_base_device::bank_w(u8 data)
{
m_rombank->set_entry(data & 0x03);
}
class msx_cart_msxdos2j_device : public msx_cart_msxdos2_base_device
{
public:
msx_cart_msxdos2j_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: msx_cart_msxdos2_base_device(mconfig, MSX_CART_MSXDOS2J, tag, owner, clock)
, m_rambank(*this, "rambank%u", 0)
, m_view_page0(*this, "view_page0")
, m_view_page1(*this, "view_page1")
, m_view_page2(*this, "view_page2")
, m_view_page3(*this, "view_page3")
, m_secondary_slot(0)
, m_bank_mask(0)
{ }
virtual image_init_result initialize_cartridge(std::string &message) override;
protected:
virtual void device_start() override;
private:
u8 secondary_slot_r();
void secondary_slot_w(u8 data);
template <int Bank> void mm_bank_w(u8 data);
memory_bank_array_creator<4> m_rambank;
memory_view m_view_page0;
memory_view m_view_page1;
memory_view m_view_page2;
memory_view m_view_page3;
u8 m_secondary_slot;
u8 m_bank_mask;
};
void msx_cart_msxdos2j_device::device_start()
{
msx_cart_msxdos2_base_device::device_start();
save_item(NAME(m_secondary_slot));
}
image_init_result msx_cart_msxdos2j_device::initialize_cartridge(std::string &message)
{
image_init_result result = msx_cart_msxdos2_base_device::initialize_cartridge(message);
if (result != image_init_result::PASS)
return result;
u32 ram_size = cart_ram_region() ? cart_ram_region()->bytes() : 0;
if (ram_size > 256 * PAGE_SIZE || (ram_size & (PAGE_SIZE - 1)) != 0)
{
message = "msx_cart_msxdos2: Region 'ram' size must be a multiple of 0x4000 and at most 0x400000.";
return image_init_result::FAIL;
}
page(0)->install_view(0x0000, 0x3fff, m_view_page0);
page(1)->install_view(0x4000, 0x7fff, m_view_page1);
page(2)->install_view(0x8000, 0xbfff, m_view_page2);
page(3)->install_view(0xc000, 0xffff, m_view_page3);
page(3)->install_readwrite_handler(0xffff, 0xffff, read8smo_delegate(*this, FUNC(msx_cart_msxdos2j_device::secondary_slot_r)), write8smo_delegate(*this, FUNC(msx_cart_msxdos2j_device::secondary_slot_w)));
// Make sure all views we can select do exist.
for (int subslot = 0; subslot < 4; subslot++)
{
m_view_page0[subslot];
m_view_page1[subslot];
m_view_page2[subslot];
m_view_page3[subslot];
}
// Kanji driver
m_view_page1[2].install_rom(0x4000, 0x7fff, cart_rom_region()->base() + 0xc000);
// MSX-DOS2 rom
m_view_page1[3].install_read_bank(0x4000, 0x7fff, m_rombank);
m_view_page1[3].install_write_handler(m_bank_address, m_bank_address, write8smo_delegate(*this, FUNC(msx_cart_msxdos2j_device::bank_w)));
// On-cartridge memory mapper RAM
if (ram_size)
{
m_bank_mask = device_generic_cart_interface::map_non_power_of_two(
unsigned(ram_size / PAGE_SIZE),
[this] (unsigned entry, unsigned page)
{
for (int i = 0; i < 4; i++)
m_rambank[i]->configure_entry(entry, cart_ram_region()->base() + PAGE_SIZE * page);
}
);
m_view_page0[1].install_readwrite_bank(0x0000, 0x3fff, m_rambank[0]);
m_view_page1[1].install_readwrite_bank(0x4000, 0x7fff, m_rambank[1]);
m_view_page2[1].install_readwrite_bank(0x8000, 0xbfff, m_rambank[2]);
m_view_page3[1].install_readwrite_bank(0xc000, 0xffff, m_rambank[3]);
io_space().install_write_tap(0xfc, 0xfc, "bank0", [this] (offs_t, u8& data, u8){ this->mm_bank_w<0>(data); });
io_space().install_write_tap(0xfd, 0xfd, "bank1", [this] (offs_t, u8& data, u8){ this->mm_bank_w<1>(data); });
io_space().install_write_tap(0xfe, 0xfe, "bank2", [this] (offs_t, u8& data, u8){ this->mm_bank_w<2>(data); });
io_space().install_write_tap(0xff, 0xff, "bank3", [this] (offs_t, u8& data, u8){ this->mm_bank_w<3>(data); });
}
return image_init_result::PASS;
}
u8 msx_cart_msxdos2j_device::secondary_slot_r()
{
return ~m_secondary_slot;
}
void msx_cart_msxdos2j_device::secondary_slot_w(u8 data)
{
m_view_page0.select((data >> 0) & 0x03);
m_view_page1.select((data >> 2) & 0x03);
m_view_page2.select((data >> 4) & 0x03);
m_view_page3.select((data >> 6) & 0x03);
m_secondary_slot = data;
}
template <int Bank>
void msx_cart_msxdos2j_device::mm_bank_w(u8 data)
{
m_rambank[Bank]->set_entry(data & m_bank_mask);
}
class msx_cart_msxdos2e_device : public msx_cart_msxdos2_base_device
{
public:
msx_cart_msxdos2e_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: msx_cart_msxdos2_base_device(mconfig, MSX_CART_MSXDOS2E, tag, owner, clock)
{ }
virtual image_init_result initialize_cartridge(std::string &message) override;
};
image_init_result msx_cart_msxdos2e_device::initialize_cartridge(std::string &message)
{
image_init_result result = msx_cart_msxdos2_base_device::initialize_cartridge(message);
if (result != image_init_result::PASS)
return result;
page(1)->install_read_bank(0x4000, 0x7fff, m_rombank);
page(1)->install_write_handler(m_bank_address, m_bank_address, write8smo_delegate(*this, FUNC(msx_cart_msxdos2e_device::bank_w)));
return image_init_result::PASS;
}
} // anonymous namespace
DEFINE_DEVICE_TYPE_PRIVATE(MSX_CART_MSXDOS2J, msx_cart_interface, msx_cart_msxdos2j_device, "msx_cart_msxdos2j", "MSX Cartridge - MSXDOS2 Japan")
DEFINE_DEVICE_TYPE_PRIVATE(MSX_CART_MSXDOS2E, msx_cart_interface, msx_cart_msxdos2e_device, "msx_cart_msxdos2e", "MSX Cartridge - MSXDOS2 Europe")

View File

@ -7,27 +7,7 @@
#include "bus/msx/slot/cartridge.h"
DECLARE_DEVICE_TYPE(MSX_CART_MSXDOS2, msx_cart_msxdos2_device)
class msx_cart_msxdos2_device : public device_t, public msx_cart_interface
{
public:
msx_cart_msxdos2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual image_init_result initialize_cartridge(std::string &message) override;
protected:
// device-level overrides
virtual void device_start() override { }
virtual void device_reset() override;
private:
void bank_w(u8 data);
memory_bank_creator m_rombank;
};
DECLARE_DEVICE_TYPE(MSX_CART_MSXDOS2J, msx_cart_interface)
DECLARE_DEVICE_TYPE(MSX_CART_MSXDOS2E, msx_cart_interface)
#endif // MAME_BUS_MSX_CART_MSXDOS2_H