summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/msx_slot
diff options
context:
space:
mode:
author wilbertpol <wilbertpol@users.noreply.github.com>2022-11-08 04:00:55 +0000
committer GitHub <noreply@github.com>2022-11-08 15:00:55 +1100
commitac4af4b16b5790448728a0fb95cc8ca5939d2f40 (patch)
tree017f0f42a65072d04fceaba87180f19d327add41 /src/devices/bus/msx_slot
parentda85ebae03454a3c35063199e8249ea86a318db0 (diff)
msx/msx.cpp, bus/msx_cart, bus/msx_slot: Reimplemented memory using views. (#10473) [Wilbert Pol]
* Made some devices which were not present in all msx models optional; install software lists based on components of the system. * Updated hardware descriptions. * Implemented bruc100 firmware banking. * Added m5.00.011 version of Yamaha SFG05 cartridge. * Fixed phc28 RAM misconfiguration. * Added AX-230 internal games mapper. * Started adding support for FS-A1FM modem. * Updated input port definitions. * Added support for kanji font from raw FS-A1FX ROM dump. * Started adding support for RS-232. * Added support for Toshiba HX-M200 kanji cartridge - allows hx21 and hx22 to start their firmware. * Fixed most floppy problems. * Marked all ROMs that need verification as bad dumps. * Moved floppy controller and drive configuration from main state to msx_slot disk devices. New working machines --------------------------------------- Hitachi MB-H1 (MSX1, Japan) Mitsubishi ML-8000 (MSX1, Japan) Panasonic CF-2700 (MSX1, UK) Pioneer", "UC-V102 (MSX2, Japan) Sakhr AX-200 (MSX1, Arabic/English) Sakhr AX-230 (MSX1, Arabic) Sakhr AX-350 II (MSX2, Arabic) Sakhr AX-500 (MSX2, Arabic) Sanyo MPC-25FS (MSX2, Japan) Sanyo PHC-23 / Wavy23 (MSX2, Japan) Toshiba HX-32 (MSX1, Japan) Toshiba HX-51I (MSX1, Italy, Spain) Yamaha SX-100 (MSX1, Japan) Victor HC-80 (MSX2, Japan) New working clones --------------------------------------- Frael Bruc 100-2 (MSX1, Italy) Hitachi MB-H1E (MSX1, Japan) Philips NMS 8250/16 (MSX2, Spain) Sakhr AX-200M (MSX1, Arabic/English) Sakhr AX-350 II F (MSX2, Arabic) Sony HB-101 (MSX1, Japan) Sony HB-75 (MSX1, Japan) Sony HB-F500 2nd version (MSX2, Japan) Spectravideo SVI-728 (MSX1, Spanish) Talent DPC-200 (MSX1, Argentina, international keyboard) Toshiba HX-20E (MSX1, Spain)
Diffstat (limited to 'src/devices/bus/msx_slot')
-rw-r--r--src/devices/bus/msx_slot/ax230.cpp53
-rw-r--r--src/devices/bus/msx_slot/ax230.h38
-rw-r--r--src/devices/bus/msx_slot/bruc100.cpp50
-rw-r--r--src/devices/bus/msx_slot/bruc100.h35
-rw-r--r--src/devices/bus/msx_slot/bunsetsu.cpp34
-rw-r--r--src/devices/bus/msx_slot/bunsetsu.h11
-rw-r--r--src/devices/bus/msx_slot/cartridge.cpp68
-rw-r--r--src/devices/bus/msx_slot/cartridge.h12
-rw-r--r--src/devices/bus/msx_slot/disk.cpp1458
-rw-r--r--src/devices/bus/msx_slot/disk.h445
-rw-r--r--src/devices/bus/msx_slot/fs4600.cpp172
-rw-r--r--src/devices/bus/msx_slot/fs4600.h33
-rw-r--r--src/devices/bus/msx_slot/fsa1fm.cpp239
-rw-r--r--src/devices/bus/msx_slot/fsa1fm.h88
-rw-r--r--src/devices/bus/msx_slot/msx_rs232.cpp528
-rw-r--r--src/devices/bus/msx_slot/msx_rs232.h168
-rw-r--r--src/devices/bus/msx_slot/msx_write.cpp78
-rw-r--r--src/devices/bus/msx_slot/msx_write.h41
-rw-r--r--src/devices/bus/msx_slot/music.cpp17
-rw-r--r--src/devices/bus/msx_slot/music.h6
-rw-r--r--src/devices/bus/msx_slot/panasonic08.cpp195
-rw-r--r--src/devices/bus/msx_slot/panasonic08.h31
-rw-r--r--src/devices/bus/msx_slot/ram.cpp22
-rw-r--r--src/devices/bus/msx_slot/ram.h11
-rw-r--r--src/devices/bus/msx_slot/ram_mm.cpp59
-rw-r--r--src/devices/bus/msx_slot/ram_mm.h31
-rw-r--r--src/devices/bus/msx_slot/rom.cpp20
-rw-r--r--src/devices/bus/msx_slot/rom.h11
-rw-r--r--src/devices/bus/msx_slot/slot.cpp10
-rw-r--r--src/devices/bus/msx_slot/slot.h25
-rw-r--r--src/devices/bus/msx_slot/sony08.cpp176
-rw-r--r--src/devices/bus/msx_slot/sony08.h27
32 files changed, 3072 insertions, 1120 deletions
diff --git a/src/devices/bus/msx_slot/ax230.cpp b/src/devices/bus/msx_slot/ax230.cpp
new file mode 100644
index 00000000000..fe54510e893
--- /dev/null
+++ b/src/devices/bus/msx_slot/ax230.cpp
@@ -0,0 +1,53 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+/*
+
+ Emulation of the games mapper as found in AX-230 machines.
+
+*/
+
+#include "emu.h"
+#include "ax230.h"
+
+
+DEFINE_DEVICE_TYPE(MSX_SLOT_AX230, msx_slot_ax230_device, "msx_slot_ax230", "MSX Internal AX230")
+
+
+msx_slot_ax230_device::msx_slot_ax230_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, MSX_SLOT_AX230, tag, owner, clock)
+ , msx_internal_slot_interface(mconfig, *this)
+ , m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_rombank(*this, "rombank%u", 0U)
+ , m_region_offset(0)
+{
+}
+
+void msx_slot_ax230_device::device_start()
+{
+ // Sanity checks
+ if (m_rom_region->bytes() < m_region_offset + 0x100000)
+ {
+ fatalerror("Memory region '%s' is too small for the AX230 firmware\n", m_rom_region.finder_tag());
+ }
+
+ for (int i = 0; i < 4; i++)
+ {
+ m_rombank[i]->configure_entries(0, BANKS, m_rom_region->base() + m_region_offset, 0x2000);
+ }
+ page(1)->install_read_bank(0x4000, 0x5fff, m_rombank[0]);
+ page(1)->install_read_bank(0x6000, 0x7fff, m_rombank[1]);
+ page(1)->install_write_handler(0x6000, 0x7fff, write8sm_delegate(*this, FUNC(msx_slot_ax230_device::mapper_write)));
+ page(2)->install_read_bank(0x8000, 0x9fff, m_rombank[2]);
+ page(2)->install_read_bank(0xa000, 0xbfff, m_rombank[3]);
+}
+
+void msx_slot_ax230_device::device_reset()
+{
+ for (int i = 0; i < 4; i++)
+ m_rombank[i]->set_entry(0);
+}
+
+void msx_slot_ax230_device::mapper_write(offs_t offset, u8 data)
+{
+ m_rombank[(offset / 0x800) & 0x03]->set_entry(data & BANK_MASK);
+}
diff --git a/src/devices/bus/msx_slot/ax230.h b/src/devices/bus/msx_slot/ax230.h
new file mode 100644
index 00000000000..31f5fa3df8d
--- /dev/null
+++ b/src/devices/bus/msx_slot/ax230.h
@@ -0,0 +1,38 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+#ifndef MAME_BUS_MSX_SLOT_AX230_H
+#define MAME_BUS_MSX_SLOT_AX230_H
+
+#pragma once
+
+#include "slot.h"
+
+
+DECLARE_DEVICE_TYPE(MSX_SLOT_AX230, msx_slot_ax230_device)
+
+
+class msx_slot_ax230_device : public device_t, public msx_internal_slot_interface
+{
+public:
+ msx_slot_ax230_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // configuration helpers
+ void set_rom_start(const char *region, u32 offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ static constexpr u8 BANKS = 0x80;
+ static constexpr u8 BANK_MASK = BANKS - 1;
+
+ void mapper_write(offs_t offset, uint8_t data);
+
+ required_memory_region m_rom_region;
+ memory_bank_array_creator<4> m_rombank;
+ u32 m_region_offset;
+};
+
+
+#endif // MAME_BUS_MSX_SLOT_AX230_H
diff --git a/src/devices/bus/msx_slot/bruc100.cpp b/src/devices/bus/msx_slot/bruc100.cpp
new file mode 100644
index 00000000000..b5b8af39c26
--- /dev/null
+++ b/src/devices/bus/msx_slot/bruc100.cpp
@@ -0,0 +1,50 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+/*
+
+ Emulation of the firmware mapper as found in Frael Bruc 100 machines.
+
+*/
+
+#include "emu.h"
+#include "bruc100.h"
+
+
+DEFINE_DEVICE_TYPE(MSX_SLOT_BRUC100, msx_slot_bruc100_device, "msx_slot_bruc100", "MSX Internal BRUC100")
+
+
+msx_slot_bruc100_device::msx_slot_bruc100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, MSX_SLOT_BRUC100, tag, owner, clock)
+ , msx_internal_slot_interface(mconfig, *this)
+ , m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_rombank(*this, "rombank%u", 0U)
+ , m_region_offset(0)
+{
+}
+
+void msx_slot_bruc100_device::device_start()
+{
+ // Sanity checks
+ if (m_rom_region->bytes() < m_region_offset + 0x10000)
+ {
+ fatalerror("Memory region '%s' is too small for the BRUC100 firmware\n", m_rom_region.finder_tag());
+ }
+
+ m_rombank[0]->configure_entries(0, 2, m_rom_region->base() + m_region_offset, 0x8000);
+ m_rombank[1]->configure_entries(0, 2, m_rom_region->base() + m_region_offset + 0x4000, 0x8000);
+
+ page(0)->install_read_bank(0x0000, 0x3fff, m_rombank[0]);
+ page(1)->install_read_bank(0x4000, 0x7fff, m_rombank[1]);
+}
+
+void msx_slot_bruc100_device::device_reset()
+{
+ m_rombank[0]->set_entry(0);
+ m_rombank[1]->set_entry(0);
+}
+
+void msx_slot_bruc100_device::select_bank(u8 bank)
+{
+ m_rombank[0]->set_entry(bank);
+ m_rombank[1]->set_entry(bank);
+}
diff --git a/src/devices/bus/msx_slot/bruc100.h b/src/devices/bus/msx_slot/bruc100.h
new file mode 100644
index 00000000000..cf37efc7779
--- /dev/null
+++ b/src/devices/bus/msx_slot/bruc100.h
@@ -0,0 +1,35 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+#ifndef MAME_BUS_MSX_SLOT_BRUC100_H
+#define MAME_BUS_MSX_SLOT_BRUC100_H
+
+#pragma once
+
+#include "slot.h"
+
+
+DECLARE_DEVICE_TYPE(MSX_SLOT_BRUC100, msx_slot_bruc100_device)
+
+
+class msx_slot_bruc100_device : public device_t, public msx_internal_slot_interface
+{
+public:
+ msx_slot_bruc100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // configuration helpers
+ void set_rom_start(const char *region, u32 offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
+
+ void select_bank(u8 bank);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_memory_region m_rom_region;
+ memory_bank_array_creator<2> m_rombank;
+ u32 m_region_offset;
+};
+
+
+#endif // MAME_BUS_MSX_SLOT_BRUC100_H
diff --git a/src/devices/bus/msx_slot/bunsetsu.cpp b/src/devices/bus/msx_slot/bunsetsu.cpp
index 9c73a37dbd8..fce0d691ec7 100644
--- a/src/devices/bus/msx_slot/bunsetsu.cpp
+++ b/src/devices/bus/msx_slot/bunsetsu.cpp
@@ -11,43 +11,51 @@
DEFINE_DEVICE_TYPE(MSX_SLOT_BUNSETSU, msx_slot_bunsetsu_device, "msx_slot_bunsetsu", "MSX Internal BUNSETSU")
-msx_slot_bunsetsu_device::msx_slot_bunsetsu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_bunsetsu_device::msx_slot_bunsetsu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: msx_slot_rom_device(mconfig, MSX_SLOT_BUNSETSU, tag, owner, clock)
, m_bunsetsu_region(*this, finder_base::DUMMY_TAG)
, m_bunsetsu_address(0)
{
}
+void msx_slot_bunsetsu_device::device_start()
+{
+ msx_slot_rom_device::device_start();
+
+ save_item(NAME(m_bunsetsu_address));
+
+ page(2)->install_read_handler(0xbfff, 0xbfff, read8smo_delegate(*this, FUNC(msx_slot_bunsetsu_device::buns_read)));
+ page(2)->install_write_handler(0xbffc, 0xbffe, write8sm_delegate(*this, FUNC(msx_slot_bunsetsu_device::buns_write)));
+}
void msx_slot_bunsetsu_device::device_reset()
{
m_bunsetsu_address = 0;
}
-
-uint8_t msx_slot_bunsetsu_device::read(offs_t offset)
+u8 msx_slot_bunsetsu_device::buns_read()
{
- if (offset == 0xbfff)
- {
- return m_bunsetsu_region[m_bunsetsu_address++ & 0x1ffff];
- }
- return msx_slot_rom_device::read(offset);
-}
+ u8 data = m_bunsetsu_region[m_bunsetsu_address & 0x1ffff];
+ if (!machine().side_effects_disabled())
+ m_bunsetsu_address++;
+
+ return data;
+}
-void msx_slot_bunsetsu_device::write(offs_t offset, uint8_t data)
+void msx_slot_bunsetsu_device::buns_write(offs_t offset, u8 data)
{
switch (offset)
{
- case 0xbffc:
+ case 0:
m_bunsetsu_address = (m_bunsetsu_address & 0xffff00) | data;
break;
- case 0xbffd:
+ case 1:
m_bunsetsu_address = (m_bunsetsu_address & 0xff00ff) | (data << 8);
break;
- case 0xbffe:
+ case 2:
m_bunsetsu_address = (m_bunsetsu_address & 0x00ffff) | (data << 16);
break;
}
diff --git a/src/devices/bus/msx_slot/bunsetsu.h b/src/devices/bus/msx_slot/bunsetsu.h
index df0bcedb32f..7964b83778b 100644
--- a/src/devices/bus/msx_slot/bunsetsu.h
+++ b/src/devices/bus/msx_slot/bunsetsu.h
@@ -15,20 +15,21 @@ DECLARE_DEVICE_TYPE(MSX_SLOT_BUNSETSU, msx_slot_bunsetsu_device)
class msx_slot_bunsetsu_device : public msx_slot_rom_device
{
public:
- msx_slot_bunsetsu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_bunsetsu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
void set_bunsetsu_region_tag(const char *tag) { m_bunsetsu_region.set_tag(tag); }
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
-
protected:
+ virtual void device_start() override;
virtual void device_reset() override;
private:
+ u8 buns_read();
+ void buns_write(offs_t offset, u8 data);
+
required_region_ptr<uint8_t> m_bunsetsu_region;
- uint32_t m_bunsetsu_address;
+ u32 m_bunsetsu_address;
};
diff --git a/src/devices/bus/msx_slot/cartridge.cpp b/src/devices/bus/msx_slot/cartridge.cpp
index 667bbaf3cc7..b8d746b5a15 100644
--- a/src/devices/bus/msx_slot/cartridge.cpp
+++ b/src/devices/bus/msx_slot/cartridge.cpp
@@ -33,13 +33,13 @@ DEFINE_DEVICE_TYPE(MSX_SLOT_CARTRIDGE, msx_slot_cartridge_device,
DEFINE_DEVICE_TYPE(MSX_SLOT_YAMAHA_EXPANSION, msx_slot_yamaha_expansion_device, "msx_slot_yamaha_expansion", "MSX Yamaha Expansion slot")
-msx_slot_cartridge_device::msx_slot_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_cartridge_device::msx_slot_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: msx_slot_cartridge_device(mconfig, MSX_SLOT_CARTRIDGE, tag, owner, clock)
{
}
-msx_slot_cartridge_device::msx_slot_cartridge_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_cartridge_device::msx_slot_cartridge_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, device_cartrom_image_interface(mconfig, *this)
, device_slot_interface(mconfig, *this)
@@ -95,7 +95,10 @@ void msx_slot_cartridge_device::device_resolve_objects()
m_irq_handler.resolve_safe();
m_cartridge = dynamic_cast<msx_cart_interface *>(get_card_device());
if (m_cartridge)
+ {
m_cartridge->m_exp = this;
+ m_cartridge->set_views(page(0), page(1), page(2), page(3));
+ }
}
@@ -106,18 +109,18 @@ void msx_slot_cartridge_device::device_start()
image_init_result msx_slot_cartridge_device::call_load()
{
- if ( m_cartridge )
+ if (m_cartridge)
{
if (loaded_through_softlist())
{
- uint32_t length;
+ u32 length;
// Allocate and copy rom contents
length = get_software_region_length("rom");
- m_cartridge->rom_alloc( length );
+ m_cartridge->rom_alloc(length);
if (length > 0)
{
- uint8_t *rom_base = m_cartridge->get_rom_base();
+ u8 *rom_base = m_cartridge->get_rom_base();
memcpy(rom_base, get_software_region("rom"), length);
}
@@ -126,24 +129,33 @@ image_init_result msx_slot_cartridge_device::call_load()
m_cartridge->rom_vlm5030_alloc(length);
if (length > 0)
{
- uint8_t *rom_base = m_cartridge->get_rom_vlm5030_base();
+ u8 *rom_base = m_cartridge->get_rom_vlm5030_base();
memcpy(rom_base, get_software_region("vlm5030"), length);
}
// Allocate ram
length = get_software_region_length("ram");
- m_cartridge->ram_alloc( length );
+ m_cartridge->ram_alloc(length);
// Allocate sram
length = get_software_region_length("sram");
- m_cartridge->sram_alloc( length );
+ m_cartridge->sram_alloc(length);
+
+ // Allocate and copy kanji rom contents
+ length = get_software_region_length("kanji");
+ m_cartridge->kanji_alloc(length);
+ if (length > 0)
+ {
+ u8 *rom_base = m_cartridge->get_kanji_base();
+ memcpy(rom_base, get_software_region("kanji"), length);
+ }
}
else
{
- uint32_t length = this->length();
+ u32 length = this->length();
// determine how much space to allocate
- uint32_t length_aligned = 0x10000;
+ u32 length_aligned = 0x10000;
if (length <= 0x2000)
length_aligned = 0x2000;
@@ -155,7 +167,7 @@ image_init_result msx_slot_cartridge_device::call_load()
length_aligned = 0xc000;
else
{
- while (length_aligned < length )
+ while (length_aligned < length)
length_aligned *= 2;
}
@@ -206,7 +218,7 @@ WRITE_LINE_MEMBER(msx_slot_cartridge_device::irq_out)
}
-int msx_slot_cartridge_device::get_cart_type(const uint8_t *rom, uint32_t length)
+int msx_slot_cartridge_device::get_cart_type(const u8 *rom, u32 length)
{
if (length < 0x2000)
{
@@ -218,7 +230,7 @@ int msx_slot_cartridge_device::get_cart_type(const uint8_t *rom, uint32_t length
return NOMAPPER;
}
- if ( (rom[0x10] == 'Y') && (rom[0x11] == 'Z') && (length > 0x18000) )
+ if ((rom[0x10] == 'Y') && (rom[0x11] == 'Z') && (length > 0x18000))
{
return GAMEMASTER2;
}
@@ -287,7 +299,7 @@ std::string msx_slot_cartridge_device::get_default_card_software(get_default_car
int extrainfo_type = -1;
if (1 == sscanf(extrainfo.c_str(), "%d", &extrainfo_type))
{
- static const struct { int extrainfo; int mapper; } extrainfo_map[] = {
+ static const struct {int extrainfo; int mapper;} extrainfo_map[] = {
//{ 0, NOMAPPER },
{ 1, MSXDOS2 },
{ 2, KONAMI_SCC },
@@ -321,9 +333,9 @@ std::string msx_slot_cartridge_device::get_default_card_software(get_default_car
if (type == NOMAPPER)
{
// Not identified through hashfile, try automatic detection
- uint64_t length;
+ u64 length;
hook.image_file()->length(length); // FIXME: check error return, guard against excessively large files
- std::vector<uint8_t> rom(length);
+ std::vector<u8> rom(length);
size_t actual;
hook.image_file()->read(&rom[0], length, actual); // FIXME: check error return or read returning short
type = get_cart_type(&rom[0], length);
@@ -340,33 +352,13 @@ std::string msx_slot_cartridge_device::get_default_card_software(get_default_car
}
-uint8_t msx_slot_cartridge_device::read(offs_t offset)
-{
- if ( m_cartridge )
- {
- return m_cartridge->read_cart(offset);
- }
- return 0xFF;
-}
-
-
-void msx_slot_cartridge_device::write(offs_t offset, uint8_t data)
-{
- if ( m_cartridge )
- {
- m_cartridge->write_cart(offset, data);
- }
-}
-
-
-msx_slot_yamaha_expansion_device::msx_slot_yamaha_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_yamaha_expansion_device::msx_slot_yamaha_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: msx_slot_cartridge_device(mconfig, MSX_SLOT_YAMAHA_EXPANSION, tag, owner, clock)
{
}
-
void msx_slot_yamaha_expansion_device::device_start()
{
}
diff --git a/src/devices/bus/msx_slot/cartridge.h b/src/devices/bus/msx_slot/cartridge.h
index 68d827edc93..a66d4037081 100644
--- a/src/devices/bus/msx_slot/cartridge.h
+++ b/src/devices/bus/msx_slot/cartridge.h
@@ -21,7 +21,7 @@ class msx_slot_cartridge_device : public device_t
{
public:
// construction/destruction
- msx_slot_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
auto irq_handler() { return m_irq_handler.bind(); }
@@ -36,14 +36,10 @@ public:
// slot interface overrides
virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
- // msx_internal_slot-level overrides
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
-
DECLARE_WRITE_LINE_MEMBER(irq_out);
protected:
- msx_slot_cartridge_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_cartridge_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
// device-level overrides
virtual void device_resolve_objects() override;
@@ -52,7 +48,7 @@ protected:
devcb_write_line m_irq_handler;
msx_cart_interface *m_cartridge;
- static int get_cart_type(const uint8_t *rom, uint32_t length);
+ static int get_cart_type(const u8 *rom, u32 length);
};
@@ -60,7 +56,7 @@ class msx_slot_yamaha_expansion_device : public msx_slot_cartridge_device
{
public:
// construction/destruction
- msx_slot_yamaha_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_yamaha_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual const char *image_interface() const noexcept override { return "msx_yamaha_60pin"; }
virtual const char *image_type_name() const noexcept override { return "cartridge60pin"; }
diff --git a/src/devices/bus/msx_slot/disk.cpp b/src/devices/bus/msx_slot/disk.cpp
index 78a15b7d841..ddb3ee4f444 100644
--- a/src/devices/bus/msx_slot/disk.cpp
+++ b/src/devices/bus/msx_slot/disk.cpp
@@ -33,774 +33,1290 @@ set on 7FFDH bit 2 always to 0 (some use it as disk change reset)
#include "emu.h"
#include "disk.h"
+#include "formats/dmk_dsk.h"
+#include "formats/msx_dsk.h"
+
+
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1_FD1793, msx_slot_disk1_fd1793_device, "msx_slot_disk1_fd1793", "MSX Internal floppy type 1 - FD1793 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1_MB8877, msx_slot_disk1_mb8877_device, "msx_slot_disk1_mb8877", "MSX Internal floppy type 1 - MB8877 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_N, msx_slot_disk1_wd2793_n_device, "msx_slot_disk1_wd2793_n", "MSX Internal floppy type 1 - WD2793 no force ready - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_N_2_DRIVES, msx_slot_disk1_wd2793_n_2_drives_device, "msx_slot_disk1_wd2793_n_2_drives", "MSX Internal floppy type 1 - WD2793 no force ready - 2 DSDD Drives")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793, msx_slot_disk1_wd2793_device, "msx_slot_disk1_wd2793", "MSX Internal floppy type 1 - WD2793 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_0, msx_slot_disk1_wd2793_0_device, "msx_slot_disk1_wd2793_0", "MSX Internal floppy type 1 - WD2793 - No drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_SS, msx_slot_disk1_wd2793_ss_device, "msx_slot_disk1_wd2793_ss", "MSX Internal floppy type 1 - WD2793 - 1 SSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_2_DRIVES, msx_slot_disk1_wd2793_2_drives_device, "msx_slot_disk1_wd2793_2_drives", "MSX Internal floppy type 1 - WD2793 - 2 DSDD Drives")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK2_FD1793_SS, msx_slot_disk2_fd1793_ss_device, "msx_slot_disk2_fd1793_ss", "MSX Internal floppy type 2 - FD1793 - 1 SSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK2_MB8877, msx_slot_disk2_mb8877_device, "msx_slot_disk2_mb8877", "MSX Internal floppy type 2 - MB8877 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK2_MB8877_SS, msx_slot_disk2_mb8877_ss_device, "msx_slot_disk2_mb8877_ss", "MSX Internal floppy type 2 - MB8877 - 1 SSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK2_MB8877_2_DRIVES, msx_slot_disk2_mb8877_2_drives_device, "msx_slot_disk2_mb8877_2_drives", "MSX Internal floppy type 2 - MB8877 - 2 DSDD Drives")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK2_WD2793, msx_slot_disk2_wd2793_device, "msx_slot_disk2_wd2793", "MSX Internal floppy type 2 - WD2793 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK2_WD2793_2_DRIVES, msx_slot_disk2_wd2793_2_drives_device, "msx_slot_disk2_wd2793_2_drives", "MSX Internal floppy type 2 - WD2793 - 2 DSDD Drives")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK3_TC8566, msx_slot_disk3_tc8566_device, "msx_slot_disk3_tc8566", "MSX Internal floppy type 3 - TC8566 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK3_TC8566_2_DRIVES, msx_slot_disk3_tc8566_2_drives_device, "msx_slot_disk3_tc8566_2_drives", "MSX Internal floppy type 3 - TC8566 - 2 DSDD Drives")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK4_TC8566, msx_slot_disk4_tc8566_device, "msx_slot_disk4_tc8566", "MSX Internal floppy type 4 - TC8566 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK5_WD2793, msx_slot_disk5_wd2793_device, "msx_slot_disk5_wd2793", "MSX Internal floppy type 5 - WD2793 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK6_WD2793_N, msx_slot_disk6_wd2793_n_device, "msx_slot_disk6_wd2793_n", "MSX Internal floppy type 6 - WD2793 no force ready - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK7_MB8877, msx_slot_disk7_mb8877_device, "msx_slot_disk7_mb8877", "MSX Internal floppy type 7 - MB8877 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK8_MB8877, msx_slot_disk8_mb8877_device, "msx_slot_disk8_mb8877", "MSX Internal floppy type 8 - MB8877 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK8_WD2793_2_DRIVES, msx_slot_disk8_wd2793_2_drives_device, "msx_slot_disk8_wd2793_2_drives", "MSX Internal floppy type 8 - WD2793 - 2 DSDD Drives")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK9_WD2793_N, msx_slot_disk9_wd2793_n_device, "msx_slot_disk9_wd2793_n", "MSX Internal floppy type 9 - WD2793 no force ready - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK10_MB8877, msx_slot_disk10_mb8877_device, "msx_slot_disk10_mb8877", "MSX Internal floppy type 10 - MB8877 - 1 DSDD Drive")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK10_MB8877_2_DRIVES, msx_slot_disk10_mb8877_2_drives_device, "msx_slot_disk10_mb8877_2_drives", "MSX Internal floppy type 10 - MB8877 - 2 DSDD Drives")
+DEFINE_DEVICE_TYPE(MSX_SLOT_DISK11_WD2793, msx_slot_disk11_wd2793_device, "msx_slot_disk11_wd2793", "MSX Internal floppy type 11 - WD2793 - 1 DSDD Drive")
+
+
+static void msx_floppies(device_slot_interface &device)
+{
+ device.option_add("35dd", FLOPPY_35_DD);
+ device.option_add("35ssdd", FLOPPY_35_SSDD);
+}
-
-DEFINE_DEVICE_TYPE(MSX_SLOT_DISK1, msx_slot_disk1_device, "msx_slot_disk1", "MSX Internal floppy type 1")
-DEFINE_DEVICE_TYPE(MSX_SLOT_DISK2, msx_slot_disk2_device, "msx_slot_disk2", "MSX Internal floppy type 2")
-DEFINE_DEVICE_TYPE(MSX_SLOT_DISK3, msx_slot_disk3_device, "msx_slot_disk3", "MSX Internal floppy type 3")
-DEFINE_DEVICE_TYPE(MSX_SLOT_DISK4, msx_slot_disk4_device, "msx_slot_disk4", "MSX Internal floppy type 4")
-DEFINE_DEVICE_TYPE(MSX_SLOT_DISK5, msx_slot_disk5_device, "msx_slot_disk5", "MSX Internal floppy type 5")
-DEFINE_DEVICE_TYPE(MSX_SLOT_DISK6, msx_slot_disk6_device, "msx_slot_disk6", "MSX Internal floppy type 6")
+void msx_slot_disk_device::floppy_formats(format_registration &fr)
+{
+ fr.add_mfm_containers();
+ fr.add(FLOPPY_MSX_FORMAT);
+ fr.add(FLOPPY_DMK_FORMAT);
+}
-msx_slot_disk_device::msx_slot_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_disk_device::msx_slot_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: msx_slot_rom_device(mconfig, type, tag, owner, clock)
- , m_floppy0(nullptr)
- , m_floppy1(nullptr)
- , m_floppy2(nullptr)
- , m_floppy3(nullptr)
+ , m_floppy0(*this, "fdc:0")
+ , m_floppy1(*this, "fdc:1")
+ , m_floppy2(*this, "fdc:2")
+ , m_floppy3(*this, "fdc:3")
, m_floppy(nullptr)
- , m_fdc_tag(nullptr)
- , m_floppy0_tag(nullptr)
- , m_floppy1_tag(nullptr)
- , m_floppy2_tag(nullptr)
- , m_floppy3_tag(nullptr)
{
}
-
-void msx_slot_disk_device::device_start()
+void msx_slot_disk_device::add_drive_mconfig(machine_config &config, int nr_of_drives, bool double_sided)
{
- msx_slot_rom_device::device_start();
-
- if (m_fdc_tag == nullptr)
- {
- fatalerror("msx_slot_disk_device: no FDC tag specified\n");
- }
-
- m_floppy0 = m_floppy0_tag ? owner()->subdevice<floppy_connector>(m_floppy0_tag) : nullptr;
- m_floppy1 = m_floppy1_tag ? owner()->subdevice<floppy_connector>(m_floppy1_tag) : nullptr;
- m_floppy2 = m_floppy2_tag ? owner()->subdevice<floppy_connector>(m_floppy2_tag) : nullptr;
- m_floppy3 = m_floppy3_tag ? owner()->subdevice<floppy_connector>(m_floppy3_tag) : nullptr;
-
- if (m_floppy0 == nullptr && m_floppy1 == nullptr)
- {
- logerror("msx_slot_disk_device: Warning: both floppy0 and floppy1 were not found\n");
- }
+ if (nr_of_drives > NO_DRIVES)
+ FLOPPY_CONNECTOR(config, m_floppy0, msx_floppies, double_sided ? "35dd" : "35ssdd", msx_slot_disk_device::floppy_formats);
+ if (nr_of_drives > DRIVES_1)
+ FLOPPY_CONNECTOR(config, m_floppy1, msx_floppies, double_sided ? "35dd" : "35ssdd", msx_slot_disk_device::floppy_formats);
+ if (nr_of_drives > DRIVES_2)
+ FLOPPY_CONNECTOR(config, m_floppy1, msx_floppies, double_sided ? "35dd" : "35ssdd", msx_slot_disk_device::floppy_formats);
+ if (nr_of_drives > DRIVES_3)
+ FLOPPY_CONNECTOR(config, m_floppy1, msx_floppies, double_sided ? "35dd" : "35ssdd", msx_slot_disk_device::floppy_formats);
}
+
msx_slot_wd_disk_device::msx_slot_wd_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: msx_slot_disk_device(mconfig, type, tag, owner, clock)
- , m_fdc(nullptr)
+ , m_fdc(*this, "fdc")
, m_led(*this, "led0")
{
}
-
void msx_slot_wd_disk_device::device_start()
{
msx_slot_disk_device::device_start();
-
m_led.resolve();
- m_fdc = owner()->subdevice<wd_fdc_analog_device_base>(m_fdc_tag);
+}
- if (m_fdc == nullptr)
- {
- fatalerror("msx_slot_wd_disk_device: Unable to find FDC with tag '%s'\n", m_fdc_tag);
- }
+template <typename FDCType>
+void msx_slot_wd_disk_device::add_mconfig(machine_config &config, FDCType &&type, bool force_ready, int nr_of_drives, bool double_sided)
+{
+ std::forward<FDCType>(type)(config, m_fdc, 4_MHz_XTAL / 4);
+ m_fdc->set_force_ready(force_ready);
+ add_drive_mconfig(config, nr_of_drives, double_sided);
}
+
msx_slot_tc8566_disk_device::msx_slot_tc8566_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: msx_slot_disk_device(mconfig, type, tag, owner, clock)
- , m_fdc(nullptr)
+ , m_fdc(*this, "fdc")
{
}
-
-void msx_slot_tc8566_disk_device::device_start()
+void msx_slot_tc8566_disk_device::add_mconfig(machine_config &config, int nr_of_drives)
{
- msx_slot_disk_device::device_start();
+ TC8566AF(config, m_fdc, 16'000'000);
- m_fdc = owner()->subdevice<tc8566af_device>(m_fdc_tag);
-
- if (m_fdc == nullptr)
- {
- fatalerror("msx_slot_tc8566_disk_device: Unable to find FDC with tag '%s'\n", m_fdc_tag);
- }
+ add_drive_mconfig(config, nr_of_drives, DS);
}
-msx_slot_disk1_device::msx_slot_disk1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK1, tag, owner, clock)
+msx_slot_disk1_base_device::msx_slot_disk1_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_wd_disk_device(mconfig, type, tag, owner, clock)
, m_side_control(0)
, m_control(0)
{
}
-
-void msx_slot_disk1_device::device_start()
+void msx_slot_disk1_base_device::device_start()
{
msx_slot_wd_disk_device::device_start();
save_item(NAME(m_side_control));
save_item(NAME(m_control));
-}
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7ff8, 0x7ff8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(1)->install_read_handler(0x7ff9, 0x7ff9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(1)->install_read_handler(0x7ffa, 0x7ffa, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(1)->install_read_handler(0x7ffb, 0x7ffb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(1)->install_read_handler(0x7ffc, 0x7ffc, read8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::side_control_r)));
+ page(1)->install_read_handler(0x7ffd, 0x7ffd, read8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::control_r)));
+ page(1)->install_read_handler(0x7fff, 0x7fff, read8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::status_r)));
+ page(1)->install_write_handler(0x7ff8, 0x7ff8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(1)->install_write_handler(0x7ffa, 0x7ffa, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(1)->install_write_handler(0x7ffb, 0x7ffb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(1)->install_write_handler(0x7ffc, 0x7ffc, write8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::set_side_control)));
+ page(1)->install_write_handler(0x7ffd, 0x7ffd, write8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::set_control)));
+
+ if (page_configured(2))
+ {
+ // TODO No idea why, but without this the other handlers do not get recognized
+ page(2)->install_rom(0xbff8,0xbff8, rom_base());
+ page(2)->install_read_handler(0xbff8, 0xbff8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(2)->install_read_handler(0xbff9, 0xbff9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(2)->install_read_handler(0xbffa, 0xbffa, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(2)->install_read_handler(0xbffb, 0xbffb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(2)->install_read_handler(0xbffc, 0xbffc, read8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::side_control_r)));
+ page(2)->install_read_handler(0xbffd, 0xbffd, read8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::control_r)));
+ page(2)->install_read_handler(0xbfff, 0xbfff, read8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::status_r)));
+ page(2)->install_write_handler(0xbff8, 0xbff8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(2)->install_write_handler(0xbff9, 0xbff9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(2)->install_write_handler(0xbffa, 0xbffa, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(2)->install_write_handler(0xbffb, 0xbffb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(2)->install_write_handler(0xbffc, 0xbffc, write8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::set_side_control)));
+ page(2)->install_write_handler(0xbffd, 0xbffd, write8smo_delegate(*this, FUNC(msx_slot_disk1_base_device::set_control)));
+ }
+}
-void msx_slot_disk1_device::device_reset()
+void msx_slot_disk1_base_device::device_reset()
{
m_fdc->dden_w(false);
}
-
-void msx_slot_disk1_device::device_post_load()
+void msx_slot_disk1_base_device::device_post_load()
{
- uint8_t data = m_control;
-
- // To make sure the FDD busy led status gets set correctly
- m_control ^= 0x40;
-
- set_control(data);
+ set_control(m_control);
}
-
-void msx_slot_disk1_device::set_side_control(uint8_t data)
+void msx_slot_disk1_base_device::set_side_control(u8 data)
{
m_side_control = data;
if (m_floppy)
{
- m_floppy->ss_w(m_side_control & 0x01);
+ m_floppy->ss_w(BIT(m_side_control, 0));
}
}
-
-void msx_slot_disk1_device::set_control(uint8_t data)
+void msx_slot_disk1_base_device::set_control(u8 data)
{
- uint8_t old_m_control = m_control;
+ // 7------- motor on (0 = on)
+ // -6------ in-use / LED (0 = on)
+ // --5432-- unused
+ // ------1- drive 1 select (0 = selected)
+ // -------0 drive 0 select (0 = selected)
+
+ const u8 old_m_control = m_control;
m_control = data;
switch (m_control & 0x03)
{
- case 0:
- case 2:
- m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
- break;
-
- case 1:
- m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
- break;
-
- default:
- m_floppy = nullptr;
- break;
+ case 0:
+ case 2:
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+ break;
+
+ case 1:
+ m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
+ break;
+
+ default:
+ m_floppy = nullptr;
+ break;
}
if (m_floppy)
{
- m_floppy->mon_w((m_control & 0x80) ? 0 : 1);
- m_floppy->ss_w(m_side_control & 0x01);
+ m_floppy->mon_w(BIT(m_control, 7) ? 0 : 1);
+ m_floppy->ss_w(BIT(m_side_control, 0));
}
m_fdc->set_floppy(m_floppy);
if ((old_m_control ^ m_control) & 0x40)
- {
m_led = BIT(~m_control, 6);
- }
}
+u8 msx_slot_disk1_base_device::side_control_r()
+{
+ return 0xfe | (m_side_control & 0x01);
+}
-uint8_t msx_slot_disk1_device::read(offs_t offset)
+u8 msx_slot_disk1_base_device::control_r()
{
- switch (offset)
- {
- case 0x7ff8:
- case 0xbff8:
- return m_fdc->status_r();
+ return (m_control & 0x83) | 0x78;
+}
- case 0x7ff9:
- case 0xbff9:
- return m_fdc->track_r();
+u8 msx_slot_disk1_base_device::status_r()
+{
+ return 0x3f | (m_fdc->intrq_r() ? 0 : 0x40) | (m_fdc->drq_r() ? 0 : 0x80);
+}
- case 0x7ffa:
- case 0xbffa:
- return m_fdc->sector_r();
- case 0x7ffb:
- case 0xbffb:
- return m_fdc->data_r();
+msx_slot_disk1_fd1793_device::msx_slot_disk1_fd1793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk1_base_device(mconfig, MSX_SLOT_DISK1_FD1793, tag, owner, clock)
+{
+}
- case 0x7ffc:
- case 0xbffc:
- return 0xfe | (m_side_control & 0x01);
+void msx_slot_disk1_fd1793_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, FD1793, NO_FORCE_READY, DRIVES_1, DS);
+}
- case 0x7ffd:
- case 0xbffd:
- return ( m_control & 0x83 ) | 0x78;
- case 0x7fff:
- case 0xbfff:
- return 0x3f | (m_fdc->intrq_r() ? 0 : 0x40) | (m_fdc->drq_r() ? 0 : 0x80);
- }
+msx_slot_disk1_mb8877_device::msx_slot_disk1_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk1_base_device(mconfig, MSX_SLOT_DISK1_MB8877, tag, owner, clock)
+{
+}
- return msx_slot_rom_device::read(offset);
+void msx_slot_disk1_mb8877_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, MB8877, FORCE_READY, DRIVES_1, DS);
}
-void msx_slot_disk1_device::write(offs_t offset, uint8_t data)
+msx_slot_disk1_wd2793_n_device::msx_slot_disk1_wd2793_n_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk1_base_device(mconfig, MSX_SLOT_DISK1_WD2793_N, tag, owner, clock)
{
- switch (offset)
- {
- case 0x7ff8:
- case 0xbff8:
- m_fdc->cmd_w(data);
- break;
-
- case 0x7ff9:
- case 0xbff9:
- m_fdc->track_w(data);
- break;
-
- case 0x7ffa:
- case 0xbffa:
- m_fdc->sector_w(data);
- break;
-
- case 0x7ffb:
- case 0xbffb:
- m_fdc->data_w(data);
- break;
-
- case 0x7ffc:
- case 0xbffc:
- set_side_control(data);
- break;
-
- case 0x7ffd:
- case 0xbffd:
- set_control(data);
- break;
-
- default:
- logerror("msx_slot_disk1_device::write: Unmapped write writing %02x to %04x\n", data, offset);
- break;
+}
- }
+void msx_slot_disk1_wd2793_n_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, NO_FORCE_READY, DRIVES_1, DS);
}
-msx_slot_disk2_device::msx_slot_disk2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK2, tag, owner, clock)
- , m_control(0)
+msx_slot_disk1_wd2793_n_2_drives_device::msx_slot_disk1_wd2793_n_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk1_base_device(mconfig, MSX_SLOT_DISK1_WD2793_N_2_DRIVES, tag, owner, clock)
+{
+}
+
+void msx_slot_disk1_wd2793_n_2_drives_device::device_add_mconfig(machine_config &config)
{
+ add_mconfig(config, WD2793, NO_FORCE_READY, DRIVES_2, DS);
}
-void msx_slot_disk2_device::device_start()
+msx_slot_disk1_wd2793_device::msx_slot_disk1_wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk1_base_device(mconfig, MSX_SLOT_DISK1_WD2793, tag, owner, clock)
{
- msx_slot_wd_disk_device::device_start();
+}
- save_item(NAME(m_control));
+void msx_slot_disk1_wd2793_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, FORCE_READY, DRIVES_1, DS);
}
-void msx_slot_disk2_device::device_reset()
+msx_slot_disk1_wd2793_0_device::msx_slot_disk1_wd2793_0_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk1_base_device(mconfig, MSX_SLOT_DISK1_WD2793_0, tag, owner, clock)
{
- m_fdc->dden_w(false);
}
+void msx_slot_disk1_wd2793_0_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, FORCE_READY, NO_DRIVES, DS);
+}
+
+
+msx_slot_disk1_wd2793_ss_device::msx_slot_disk1_wd2793_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk1_base_device(mconfig, MSX_SLOT_DISK1_WD2793_SS, tag, owner, clock)
+{
+}
-void msx_slot_disk2_device::device_post_load()
+void msx_slot_disk1_wd2793_ss_device::device_add_mconfig(machine_config &config)
{
- uint8_t data = m_control;
+ add_mconfig(config, WD2793, FORCE_READY, DRIVES_1, SS);
+}
+
- // To make sure the FDD busy led status gets set correctly
- m_control ^= 0x40;
+msx_slot_disk1_wd2793_2_drives_device::msx_slot_disk1_wd2793_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk1_base_device(mconfig, MSX_SLOT_DISK1_WD2793_2_DRIVES, tag, owner, clock)
+{
+}
- set_control(data);
+void msx_slot_disk1_wd2793_2_drives_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, FORCE_READY, DRIVES_2, DS);
}
-void msx_slot_disk2_device::set_control(uint8_t data)
+
+
+msx_slot_disk2_base_device::msx_slot_disk2_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_wd_disk_device(mconfig, type, tag, owner, clock)
+ , m_control(0)
{
- uint8_t old_m_control = m_control;
+}
+
+void msx_slot_disk2_base_device::device_start()
+{
+ msx_slot_wd_disk_device::device_start();
+
+ save_item(NAME(m_control));
+
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7fb8, 0x7fb8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(1)->install_read_handler(0x7fb9, 0x7fb9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(1)->install_read_handler(0x7fba, 0x7fba, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(1)->install_read_handler(0x7fbb, 0x7fbb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(1)->install_read_handler(0x7fbc, 0x7fbc, read8smo_delegate(*this, FUNC(msx_slot_disk2_base_device::status_r)));
+ page(1)->install_write_handler(0x7fb8, 0x7fb8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(1)->install_write_handler(0x7fb9, 0x7fb9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(1)->install_write_handler(0x7fba, 0x7fba, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(1)->install_write_handler(0x7fbb, 0x7fbb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(1)->install_write_handler(0x7fbc, 0x7fbc, write8smo_delegate(*this, FUNC(msx_slot_disk2_base_device::set_control)));
+
+ // TODO No idea why, but without this the other handlers do not get recognized
+ page(2)->install_rom(0xbfb8,0xbfb8, rom_base());
+ page(2)->install_read_handler(0xbfb8, 0xbfb8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(2)->install_read_handler(0xbfb9, 0xbfb9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(2)->install_read_handler(0xbfba, 0xbfba, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(2)->install_read_handler(0xbfbb, 0xbfbb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(2)->install_read_handler(0xbfbc, 0xbfbc, read8smo_delegate(*this, FUNC(msx_slot_disk2_base_device::status_r)));
+ page(2)->install_write_handler(0xbfb8, 0xbfb8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(2)->install_write_handler(0xbfb9, 0xbfb9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(2)->install_write_handler(0xbfba, 0xbfba, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(2)->install_write_handler(0xbfbb, 0xbfbb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(2)->install_write_handler(0xbfbc, 0xbfbc, write8smo_delegate(*this, FUNC(msx_slot_disk2_base_device::set_control)));
+}
+
+void msx_slot_disk2_base_device::device_reset()
+{
+ m_fdc->dden_w(false);
+}
+
+void msx_slot_disk2_base_device::device_post_load()
+{
+ set_control(m_control);
+}
+
+void msx_slot_disk2_base_device::set_control(u8 data)
+{
+ const u8 old_m_control = m_control;
m_control = data;
switch (m_control & 3)
{
- case 1:
- m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
- break;
+ case 1:
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+ break;
- case 2:
- m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
- break;
+ case 2:
+ m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
+ break;
- default:
- m_floppy = nullptr;
- break;
+ default:
+ m_floppy = nullptr;
+ break;
}
if (m_floppy)
{
- m_floppy->mon_w((m_control & 0x08) ? 0 : 1);
- m_floppy->ss_w((m_control & 0x04) ? 1 : 0);
+ m_floppy->mon_w(BIT(m_control, 3) ? 0 : 1);
+ m_floppy->ss_w(BIT(m_control, 2) ? 1 : 0);
}
m_fdc->set_floppy(m_floppy);
if ((old_m_control ^ m_control) & 0x40)
- {
m_led = BIT(~m_control, 6);
- }
}
-
-uint8_t msx_slot_disk2_device::read(offs_t offset)
+u8 msx_slot_disk2_base_device::status_r()
{
- switch (offset)
- {
- case 0x7fb8:
- case 0xbfb8:
- return m_fdc->status_r();
-
- case 0x7fb9:
- case 0xbfb9:
- return m_fdc->track_r();
-
- case 0x7fba:
- case 0xbfba:
- return m_fdc->sector_r();
+ return 0x3f | (m_fdc->drq_r() ? 0 : 0x40) | (m_fdc->intrq_r() ? 0x80 : 0);
+}
- case 0x7fbb:
- case 0xbfbb:
- return m_fdc->data_r();
- case 0x7fbc:
- case 0xbfbc:
- return 0x3f | (m_fdc->drq_r() ? 0 : 0x40) | (m_fdc->intrq_r() ? 0x80 : 0);
- }
+msx_slot_disk2_fd1793_ss_device::msx_slot_disk2_fd1793_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk2_base_device(mconfig, MSX_SLOT_DISK2_FD1793_SS, tag, owner, clock)
+{
+}
- return msx_slot_rom_device::read(offset);
+void msx_slot_disk2_fd1793_ss_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, FD1793, FORCE_READY, DRIVES_1, SS);
}
-void msx_slot_disk2_device::write(offs_t offset, uint8_t data)
+msx_slot_disk2_mb8877_device::msx_slot_disk2_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk2_base_device(mconfig, MSX_SLOT_DISK2_MB8877, tag, owner, clock)
{
- switch (offset)
- {
- case 0x7fb8:
- case 0xbfb8:
- m_fdc->cmd_w(data);
- break;
-
- case 0x7fb9:
- case 0xbfb9:
- m_fdc->track_w(data);
- break;
-
- case 0x7fba:
- case 0xbfba:
- m_fdc->sector_w(data);
- break;
-
- case 0x7fbb:
- case 0xbfbb:
- m_fdc->data_w(data);
- break;
-
- case 0x7fbc:
- case 0xbfbc:
- set_control(data);
- break;
-
- default:
- logerror("msx_slot_disk2_device::write: Unmapped write writing %02x to %04x\n", data, offset);
- break;
- }
}
+void msx_slot_disk2_mb8877_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, MB8877, FORCE_READY, DRIVES_1, DS);
+}
+msx_slot_disk2_mb8877_ss_device::msx_slot_disk2_mb8877_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk2_base_device(mconfig, MSX_SLOT_DISK2_MB8877_SS, tag, owner, clock)
+{
+}
+void msx_slot_disk2_mb8877_ss_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, MB8877, FORCE_READY, DRIVES_1, SS);
+}
-msx_slot_disk3_device::msx_slot_disk3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : msx_slot_tc8566_disk_device(mconfig, MSX_SLOT_DISK3, tag, owner, clock)
+msx_slot_disk2_mb8877_2_drives_device::msx_slot_disk2_mb8877_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk2_base_device(mconfig, MSX_SLOT_DISK2_MB8877_2_DRIVES, tag, owner, clock)
{
}
-
-void msx_slot_disk3_device::write(offs_t offset, uint8_t data)
+void msx_slot_disk2_mb8877_2_drives_device::device_add_mconfig(machine_config &config)
{
- switch (offset)
- {
- case 0x7ff8: // CR0 : 0 - 0 - MEN1 - MEN0 - 0 - -FRST - 0 - DSA
- m_fdc->dor_w(data);
- break;
+ add_mconfig(config, MB8877, FORCE_READY, DRIVES_2, DS);
+}
- case 0x7ff9: // CR1 : 0 - 0 - C4E - C4 - SBME - SBM - TCE - FDCTC
- m_fdc->cr1_w(data);
- break;
- case 0x7ffb: // Data Register
- m_fdc->fifo_w(data);
- break;
+msx_slot_disk2_wd2793_device::msx_slot_disk2_wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk2_base_device(mconfig, MSX_SLOT_DISK2_WD2793, tag, owner, clock)
+{
+}
- default:
- logerror("msx_slot_disk3_device::write: Unmapped write writing %02x to %04x\n", data, offset);
- break;
- }
+void msx_slot_disk2_wd2793_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, FORCE_READY, DRIVES_1, DS);
}
-uint8_t msx_slot_disk3_device::read(offs_t offset)
+msx_slot_disk2_wd2793_2_drives_device::msx_slot_disk2_wd2793_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk2_base_device(mconfig, MSX_SLOT_DISK2_WD2793_2_DRIVES, tag, owner, clock)
{
- switch (offset)
- {
- case 0x7ffa: // Status Register
- return m_fdc->msr_r();
- case 0x7ffb: // Data Register
- return m_fdc->fifo_r();
- }
+}
- return msx_slot_rom_device::read(offset);
+void msx_slot_disk2_wd2793_2_drives_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, FORCE_READY, DRIVES_2, DS);
}
-msx_slot_disk4_device::msx_slot_disk4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : msx_slot_tc8566_disk_device(mconfig, MSX_SLOT_DISK4, tag, owner, clock)
+
+msx_slot_disk3_tc8566_device::msx_slot_disk3_tc8566_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk3_tc8566_device(mconfig, MSX_SLOT_DISK3_TC8566, tag, owner, clock)
{
}
+msx_slot_disk3_tc8566_device::msx_slot_disk3_tc8566_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_tc8566_disk_device(mconfig, type, tag, owner, clock)
+{
+}
-void msx_slot_disk4_device::write(offs_t offset, uint8_t data)
+void msx_slot_disk3_tc8566_device::device_add_mconfig(machine_config &config)
{
- switch (offset)
- {
- case 0x7ff1: // FDD : x - x - MC1 - MC0 - x - x - x - x
- break;
+ add_mconfig(config, DRIVES_1);
+}
- case 0x7ff2: // CR0 : 0 - 0 - MEN1 - MEN0 - 0 - -FRST - 0 - DSA
- m_fdc->dor_w(data);
- break;
+void msx_slot_disk3_tc8566_device::device_start()
+{
+ msx_slot_tc8566_disk_device::device_start();
+
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7ffa, 0x7ffa, read8smo_delegate(*m_fdc, FUNC(tc8566af_device::msr_r)));
+ page(1)->install_read_handler(0x7ffb, 0x7ffb, read8smo_delegate(*m_fdc, FUNC(tc8566af_device::fifo_r)));
+ page(1)->install_write_handler(0x7ff8, 0x7ff8, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::dor_w)));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::cr1_w)));
+ page(1)->install_write_handler(0x7ffb, 0x7ffb, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::fifo_w)));
+ // TODO No idea why, but without this the other handlers do not get recognized
+ page(2)->install_rom(0xbffa,0xbffa, rom_base());
+ page(2)->install_read_handler(0xbffa, 0xbffa, read8smo_delegate(*m_fdc, FUNC(tc8566af_device::msr_r)));
+ page(2)->install_read_handler(0xbffb, 0xbffb, read8smo_delegate(*m_fdc, FUNC(tc8566af_device::fifo_r)));
+ page(2)->install_write_handler(0xbff8, 0xbff8, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::dor_w)));
+ page(2)->install_write_handler(0xbff9, 0xbff9, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::cr1_w)));
+ page(2)->install_write_handler(0xbffb, 0xbffb, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::fifo_w)));
+}
- case 0x7ff3: // CR1 : 0 - 0 - C4E - C4 - SBME - SBM - TCE - FDCTC
- m_fdc->cr1_w(data);
- break;
- case 0x7ff5: // Data Register
- m_fdc->fifo_w(data);
- break;
+msx_slot_disk3_tc8566_2_drives_device::msx_slot_disk3_tc8566_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk3_tc8566_device(mconfig, MSX_SLOT_DISK3_TC8566_2_DRIVES, tag, owner, clock)
+{
+}
- default:
- logerror("msx_slot_disk4_device::write: Unmapped write writing %02x to %04x\n", data, offset);
- break;
- }
+void msx_slot_disk3_tc8566_2_drives_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, DRIVES_2);
}
-uint8_t msx_slot_disk4_device::read(offs_t offset)
+
+
+
+
+msx_slot_disk4_tc8566_device::msx_slot_disk4_tc8566_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : msx_slot_tc8566_disk_device(mconfig, MSX_SLOT_DISK4_TC8566, tag, owner, clock)
{
- switch (offset)
- {
- case 0x7ff1: // FDD : x - x - MC1 - MC0 - x - x - x - x
- logerror("msx_slot_disk4_device::write: Unmapped read from Media Change register\n");
- break;
-
- case 0x7ff4: // Status Register
- return m_fdc->msr_r();
- case 0x7ff5: // Data Register
- return m_fdc->fifo_r();
- }
+}
- return msx_slot_rom_device::read(offset);
+void msx_slot_disk4_tc8566_device::device_start()
+{
+ msx_slot_tc8566_disk_device::device_start();
+
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ // 0x7ff1 media change register
+ page(1)->install_write_handler(0x7ff2, 0x7ff2, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::dor_w)));
+ page(1)->install_write_handler(0x7ff3, 0x7ff3, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::cr1_w)));
+ page(1)->install_read_handler(0x7ff4, 0x7ff4, read8smo_delegate(*m_fdc, FUNC(tc8566af_device::msr_r)));
+ page(1)->install_read_handler(0x7ff5, 0x7ff5, read8smo_delegate(*m_fdc, FUNC(tc8566af_device::fifo_r)));
+ page(1)->install_write_handler(0x7ff5, 0x7ff5, write8smo_delegate(*m_fdc, FUNC(tc8566af_device::fifo_w)));
+}
+
+void msx_slot_disk4_tc8566_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, DRIVES_1);
}
-msx_slot_disk5_device::msx_slot_disk5_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK5, tag, owner, clock)
+msx_slot_disk5_wd2793_device::msx_slot_disk5_wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK5_WD2793, tag, owner, clock)
, m_control(0)
{
}
+void msx_slot_disk5_wd2793_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, FORCE_READY, DRIVES_1, DS);
+}
-void msx_slot_disk5_device::device_start()
+void msx_slot_disk5_wd2793_device::device_start()
{
msx_slot_wd_disk_device::device_start();
save_item(NAME(m_control));
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+
// Install IO read/write handlers
- io_space().install_write_handler(0xd0, 0xd4, write8sm_delegate(*this, FUNC(msx_slot_disk5_device::io_write)));
- io_space().install_read_handler(0xd0, 0xd4, read8sm_delegate(*this, FUNC(msx_slot_disk5_device::io_read)));
+ io_space().install_write_handler(0xd0, 0xd0, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ io_space().install_write_handler(0xd1, 0xd1, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ io_space().install_write_handler(0xd2, 0xd2, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ io_space().install_write_handler(0xd3, 0xd3, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ io_space().install_write_handler(0xd4, 0xd4, write8smo_delegate(*this, FUNC(msx_slot_disk5_wd2793_device::control_w)));
+ io_space().install_read_handler(0xd0, 0xd0, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ io_space().install_read_handler(0xd1, 0xd1, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ io_space().install_read_handler(0xd2, 0xd2, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ io_space().install_read_handler(0xd3, 0xd3, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ io_space().install_read_handler(0xd4, 0xd4, read8smo_delegate(*this, FUNC(msx_slot_disk5_wd2793_device::status_r)));
}
-
-void msx_slot_disk5_device::device_reset()
+void msx_slot_disk5_wd2793_device::device_reset()
{
m_fdc->dden_w(false);
}
-
-void msx_slot_disk5_device::device_post_load()
+void msx_slot_disk5_wd2793_device::device_post_load()
{
- set_control(m_control);
+ control_w(m_control);
}
-
-void msx_slot_disk5_device::set_control(uint8_t control)
+void msx_slot_disk5_wd2793_device::control_w(u8 control)
{
m_control = control;
switch (m_control & 0x0f)
{
- case 0x01:
- m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
- break;
+ case 0x01:
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+ break;
- case 0x02:
- m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
- break;
+ case 0x02:
+ m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
+ break;
- case 0x04:
- m_floppy = m_floppy2 ? m_floppy2->get_device() : nullptr;
- break;
+ case 0x04:
+ m_floppy = m_floppy2 ? m_floppy2->get_device() : nullptr;
+ break;
- case 0x08:
- m_floppy = m_floppy3 ? m_floppy3->get_device() : nullptr;
- break;
+ case 0x08:
+ m_floppy = m_floppy3 ? m_floppy3->get_device() : nullptr;
+ break;
- default:
- m_floppy = nullptr;
- break;
+ default:
+ m_floppy = nullptr;
+ break;
}
if (m_floppy)
{
- m_floppy->mon_w((m_control & 0x20) ? 0 : 1);
- m_floppy->ss_w((m_control & 0x10) ? 1 : 0);
+ m_floppy->mon_w(BIT(m_control, 5) ? 0 : 1);
+ m_floppy->ss_w(BIT(m_control, 4) ? 1 : 0);
}
m_fdc->set_floppy(m_floppy);
}
+u8 msx_slot_disk5_wd2793_device::status_r()
+{
+ return 0x3f | (m_fdc->drq_r() ? 0 : 0x40) | (m_fdc->intrq_r() ? 0x80 : 0);
+}
+
+
+
+msx_slot_disk6_wd2793_n_device::msx_slot_disk6_wd2793_n_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK6_WD2793_N, tag, owner, clock)
+ , m_side_motor(0)
+ , m_drive_select0(0)
+ , m_drive_select1(0)
+{
+}
+
+void msx_slot_disk6_wd2793_n_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, NO_FORCE_READY, DRIVES_1, DS);
+}
-uint8_t msx_slot_disk5_device::io_read(offs_t offset)
+void msx_slot_disk6_wd2793_n_device::device_start()
{
- switch (offset)
+ msx_slot_wd_disk_device::device_start();
+
+ save_item(NAME(m_side_motor));
+ save_item(NAME(m_drive_select0));
+ save_item(NAME(m_drive_select1));
+
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7ff0, 0x7ff0, 0, 0x0008, 0, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(1)->install_read_handler(0x7ff1, 0x7ff1, 0, 0x0008, 0, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(1)->install_read_handler(0x7ff2, 0x7ff2, 0, 0x0008, 0, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(1)->install_read_handler(0x7ff3, 0x7ff3, 0, 0x0008, 0, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(1)->install_read_handler(0x7ff4, 0x7ff4, 0, 0x0008, 0, read8smo_delegate(*this, FUNC(msx_slot_disk6_wd2793_n_device::side_motor_r)));
+ page(1)->install_read_handler(0x7ff5, 0x7ff5, 0, 0x0008, 0, read8smo_delegate(*this, FUNC(msx_slot_disk6_wd2793_n_device::select0_r)));
+ page(1)->install_read_handler(0x7ff6, 0x7ff6, 0, 0x0008, 0, read8smo_delegate(*this, FUNC(msx_slot_disk6_wd2793_n_device::select1_r)));
+ page(1)->install_read_handler(0x7ff7, 0x7ff7, 0, 0x0008, 0, read8smo_delegate(*this, FUNC(msx_slot_disk6_wd2793_n_device::status_r)));
+ page(1)->install_write_handler(0x7ff0, 0x7ff0, 0, 0x0008, 0, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(1)->install_write_handler(0x7ff1, 0x7ff1, 0, 0x0008, 0, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(1)->install_write_handler(0x7ff2, 0x7ff2, 0, 0x0008, 0, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(1)->install_write_handler(0x7ff3, 0x7ff3, 0, 0x0008, 0, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(1)->install_write_handler(0x7ff4, 0x7ff4, 0, 0x0008, 0, write8smo_delegate(*this, FUNC(msx_slot_disk6_wd2793_n_device::side_motor_w)));
+ page(1)->install_write_handler(0x7ff5, 0x7ff5, 0, 0x0008, 0, write8smo_delegate(*this, FUNC(msx_slot_disk6_wd2793_n_device::select0_w)));
+ page(1)->install_write_handler(0x7ff6, 0x7ff6, 0, 0x0008, 0, write8smo_delegate(*this, FUNC(msx_slot_disk6_wd2793_n_device::select1_w)));
+}
+
+void msx_slot_disk6_wd2793_n_device::device_reset()
+{
+ m_fdc->dden_w(false);
+}
+
+void msx_slot_disk6_wd2793_n_device::device_post_load()
+{
+ select_drive();
+}
+
+void msx_slot_disk6_wd2793_n_device::select_drive()
+{
+ if (m_drive_select1)
{
- case 0x00:
- return m_fdc->status_r();
+ m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
+ if (!m_floppy)
+ {
+ m_drive_select1 = 0;
+ }
+ }
- case 0x01:
- return m_fdc->track_r();
+ if (m_drive_select0)
+ {
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+ if (!m_floppy)
+ {
+ m_drive_select0 = 0;
+ }
+ }
- case 0x02:
- return m_fdc->sector_r();
+ m_fdc->set_floppy(m_floppy);
- case 0x03:
- return m_fdc->data_r();
+ set_side_motor();
+}
- case 0x04:
- return 0x3f | (m_fdc->drq_r() ? 0 : 0x40) | (m_fdc->intrq_r() ? 0x80 : 0);
+void msx_slot_disk6_wd2793_n_device::set_side_motor()
+{
+ if (m_floppy)
+ {
+ m_floppy->mon_w(BIT(m_side_motor, 1) ? 0 : 1);
+ m_floppy->ss_w(BIT(m_side_motor, 0));
}
+}
- return 0xff;
+u8 msx_slot_disk6_wd2793_n_device::side_motor_r()
+{
+ // bit 0 = side control
+ // bit 1 = motor control
+ return 0xfc | m_side_motor;
}
+u8 msx_slot_disk6_wd2793_n_device::select0_r()
+{
+ // This reads back a 1 in bit 0 if drive0 is present and selected
+ return 0xfe | m_drive_select0;
+}
-void msx_slot_disk5_device::io_write(offs_t offset, uint8_t data)
+u8 msx_slot_disk6_wd2793_n_device::select1_r()
{
- switch (offset)
- {
- case 0x00:
- m_fdc->cmd_w(data);
- break;
+ // This reads back a 1 in bit 0 if drive1 is present and selected
+ return 0xfe | m_drive_select1;
+}
- case 0x01:
- m_fdc->track_w(data);
- break;
+u8 msx_slot_disk6_wd2793_n_device::status_r()
+{
+ return 0x3f | (m_fdc->intrq_r() ? 0 : 0x40) | (m_fdc->drq_r() ? 0 : 0x80);
+}
+
+void msx_slot_disk6_wd2793_n_device::side_motor_w(u8 data)
+{
+ // Side and motor control
+ // bit 0 = side select
+ // bit 1 = motor on/off
+ m_side_motor = data;
+ set_side_motor();
+}
+
+void msx_slot_disk6_wd2793_n_device::select0_w(u8 data)
+{
+ // bit 0 - select drive 0
+ m_drive_select0 = data;
+ select_drive();
+}
+
+void msx_slot_disk6_wd2793_n_device::select1_w(u8 data)
+{
+ // bit 1 - select drive 1
+ m_drive_select1 = data;
+ select_drive();
+}
- case 0x02:
- m_fdc->sector_w(data);
- break;
- case 0x03:
- m_fdc->data_w(data);
- break;
- case 0x04:
- set_control(data);
- break;
+msx_slot_disk7_mb8877_device::msx_slot_disk7_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK7_MB8877, tag, owner, clock)
+ , m_drive_side_motor(0)
+{
+}
+
+void msx_slot_disk7_mb8877_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, MB8877, FORCE_READY, DRIVES_1, DS);
+}
+
+void msx_slot_disk7_mb8877_device::device_start()
+{
+ msx_slot_wd_disk_device::device_start();
+
+ save_item(NAME(m_drive_side_motor));
+
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7ff8, 0x7ff8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(1)->install_read_handler(0x7ff9, 0x7ff9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(1)->install_read_handler(0x7ffa, 0x7ffa, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(1)->install_read_handler(0x7ffb, 0x7ffb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(1)->install_read_handler(0x7ffc, 0x7ffc, read8smo_delegate(*this, FUNC(msx_slot_disk7_mb8877_device::status_r)));
+ page(1)->install_write_handler(0x7ff8, 0x7ff8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(1)->install_write_handler(0x7ffa, 0x7ffa, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(1)->install_write_handler(0x7ffb, 0x7ffb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(1)->install_write_handler(0x7ffc, 0x7ffc, write8smo_delegate(*this, FUNC(msx_slot_disk7_mb8877_device::side_motor_w)));
+
+ // TODO No idea why, but without this the other handlers do not get recognized
+ page(2)->install_rom(0xbff8, 0xbff8, rom_base());
+ page(2)->install_read_handler(0xbff8, 0xbff8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(2)->install_read_handler(0xbff9, 0xbff9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(2)->install_read_handler(0xbffa, 0xbffa, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(2)->install_read_handler(0xbffb, 0xbffb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(2)->install_read_handler(0xbffc, 0xbffc, read8smo_delegate(*this, FUNC(msx_slot_disk7_mb8877_device::status_r)));
+ page(2)->install_write_handler(0xbff8, 0xbff8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(2)->install_write_handler(0xbff9, 0xbff9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(2)->install_write_handler(0xbffa, 0xbffa, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(2)->install_write_handler(0xbffb, 0xbffb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(2)->install_write_handler(0xbffc, 0xbffc, write8smo_delegate(*this, FUNC(msx_slot_disk7_mb8877_device::side_motor_w)));
+}
+
+void msx_slot_disk7_mb8877_device::device_reset()
+{
+ m_fdc->dden_w(false);
+}
+
+void msx_slot_disk7_mb8877_device::device_post_load()
+{
+ select_drive();
+}
+
+void msx_slot_disk7_mb8877_device::select_drive()
+{
+ m_floppy = nullptr;
+
+ switch (m_drive_side_motor & 0x03)
+ {
+ case 0:
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+ break;
+ case 1:
+ m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
+ break;
+ }
+
+ m_fdc->set_floppy(m_floppy);
+}
+
+void msx_slot_disk7_mb8877_device::set_drive_side_motor()
+{
+ select_drive();
+
+ if (m_floppy)
+ {
+ m_floppy->mon_w(BIT(m_drive_side_motor, 3) ? 0 : 1);
+ m_floppy->ss_w(BIT(m_drive_side_motor, 2));
}
}
+void msx_slot_disk7_mb8877_device::side_motor_w(u8 data)
+{
+ // Drive, side and motor control
+ // bit 0,1 = drive select
+ // bit 2 = side select
+ // bit 3 = motor on/off
+ m_drive_side_motor = data;
+ set_drive_side_motor();
+}
+u8 msx_slot_disk7_mb8877_device::status_r()
+{
+ return (m_drive_side_motor & 0x0f)
+ | (m_floppy && m_floppy->dskchg_r() ? 0x00 : 0x10)
+ | (m_floppy && m_floppy->ready_r() ? 0x00 : 0x20)
+ | (m_fdc->intrq_r() ? 0x40 : 0x00)
+ | (m_fdc->drq_r() ? 0x80 : 0x00);
+}
-msx_slot_disk6_device::msx_slot_disk6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK6, tag, owner, clock)
- , m_side_motor(0)
- , m_drive_select0(0)
- , m_drive_select1(0)
+
+
+msx_slot_disk8_mb8877_device::msx_slot_disk8_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : msx_slot_disk8_mb8877_device(mconfig, MSX_SLOT_DISK8_MB8877, tag, owner, clock)
+{
+}
+
+msx_slot_disk8_mb8877_device::msx_slot_disk8_mb8877_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_wd_disk_device(mconfig, type, tag, owner, clock)
+ , m_control(0)
{
}
+void msx_slot_disk8_mb8877_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, MB8877, FORCE_READY, DRIVES_1, DS);
+}
-void msx_slot_disk6_device::device_start()
+void msx_slot_disk8_mb8877_device::device_start()
{
msx_slot_wd_disk_device::device_start();
- save_item(NAME(m_side_motor));
- save_item(NAME(m_drive_select0));
- save_item(NAME(m_drive_select1));
+ save_item(NAME(m_control));
+
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7f80, 0x7f80, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(1)->install_read_handler(0x7f81, 0x7f81, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(1)->install_read_handler(0x7f82, 0x7f82, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(1)->install_read_handler(0x7f83, 0x7f83, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(1)->install_read_handler(0x7f84, 0x7f84, read8smo_delegate(*this, FUNC(msx_slot_disk8_mb8877_device::status_r)));
+ page(1)->install_write_handler(0x7f80, 0x7f80, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(1)->install_write_handler(0x7f81, 0x7f81, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(1)->install_write_handler(0x7f82, 0x7f82, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(1)->install_write_handler(0x7f83, 0x7f83, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(1)->install_write_handler(0x7f84, 0x7f84, write8smo_delegate(*this, FUNC(msx_slot_disk8_mb8877_device::set_control)));
+
+ // TODO No idea why, but without this the other handlers do not get recognized
+ page(2)->install_rom(0xbf80,0xbf80, rom_base());
+ page(2)->install_read_handler(0xbf80, 0xbf80, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(2)->install_read_handler(0xbf81, 0xbf81, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(2)->install_read_handler(0xbf82, 0xbf82, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(2)->install_read_handler(0xbf83, 0xbf83, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(2)->install_read_handler(0xbf84, 0xbf84, read8smo_delegate(*this, FUNC(msx_slot_disk8_mb8877_device::status_r)));
+ page(2)->install_write_handler(0xbf80, 0xbf80, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(2)->install_write_handler(0xbf81, 0xbf81, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(2)->install_write_handler(0xbf82, 0xbf82, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(2)->install_write_handler(0xbf83, 0xbf83, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(2)->install_write_handler(0xbf84, 0xbf84, write8smo_delegate(*this, FUNC(msx_slot_disk8_mb8877_device::set_control)));
}
-void msx_slot_disk6_device::device_reset()
+void msx_slot_disk8_mb8877_device::device_reset()
{
m_fdc->dden_w(false);
}
-void msx_slot_disk6_device::device_post_load()
+void msx_slot_disk8_mb8877_device::device_post_load()
{
- select_drive();
+ set_control(m_control);
}
-void msx_slot_disk6_device::select_drive()
+void msx_slot_disk8_mb8877_device::set_control(u8 data)
{
- if (m_drive_select1)
+ const u8 old_m_control = m_control;
+
+ m_control = data;
+
+ switch (m_control & 3)
{
+ case 1:
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+ break;
+
+ case 2:
m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
- if (!m_floppy)
- {
- m_drive_select1 = 0;
- }
+ break;
+
+ default:
+ m_floppy = nullptr;
+ break;
}
- if (m_drive_select0)
+ if (m_floppy)
{
- m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
- if (!m_floppy)
- {
- m_drive_select0 = 0;
- }
+ m_floppy->mon_w(BIT(m_control, 3) ? 0 : 1);
+ m_floppy->ss_w(BIT(m_control, 2) ? 1 : 0);
}
m_fdc->set_floppy(m_floppy);
- set_side_motor();
+ if ((old_m_control ^ m_control) & 0x40)
+ {
+ m_led = BIT(~m_control, 6);
+ }
}
+u8 msx_slot_disk8_mb8877_device::status_r()
+{
+ return 0x3f | (m_fdc->drq_r() ? 0 : 0x40) | (m_fdc->intrq_r() ? 0x80 : 0);
+}
-void msx_slot_disk6_device::set_side_motor()
+
+msx_slot_disk8_wd2793_2_drives_device::msx_slot_disk8_wd2793_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : msx_slot_disk8_mb8877_device(mconfig, MSX_SLOT_DISK8_WD2793_2_DRIVES, tag, owner, clock)
{
+}
+
+void msx_slot_disk8_wd2793_2_drives_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, FORCE_READY, DRIVES_2, DS);
+}
+
+
+
+
+msx_slot_disk9_wd2793_n_device::msx_slot_disk9_wd2793_n_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK9_WD2793_N, tag, owner, clock)
+ , m_control(0)
+{
+}
+
+void msx_slot_disk9_wd2793_n_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, NO_FORCE_READY, DRIVES_1, DS);
+}
+
+void msx_slot_disk9_wd2793_n_device::device_start()
+{
+ msx_slot_wd_disk_device::device_start();
+
+ save_item(NAME(m_control));
+
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7ff8, 0x7ff8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(1)->install_read_handler(0x7ff9, 0x7ff9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(1)->install_read_handler(0x7ffa, 0x7ffa, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(1)->install_read_handler(0x7ffb, 0x7ffb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(1)->install_read_handler(0x7ffc, 0x7ffc, read8smo_delegate(*this, FUNC(msx_slot_disk9_wd2793_n_device::status_r)));
+ page(1)->install_write_handler(0x7ff8, 0x7ff8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(1)->install_write_handler(0x7ffa, 0x7ffa, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(1)->install_write_handler(0x7ffb, 0x7ffb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(1)->install_write_handler(0x7ffc, 0x7ffc, write8smo_delegate(*this, FUNC(msx_slot_disk9_wd2793_n_device::control_w)));
+}
+
+void msx_slot_disk9_wd2793_n_device::device_reset()
+{
+ m_fdc->dden_w(false);
+}
+
+void msx_slot_disk9_wd2793_n_device::device_post_load()
+{
+ control_w(m_control);
+}
+
+void msx_slot_disk9_wd2793_n_device::control_w(u8 data)
+{
+ const u8 old_m_control = m_control;
+
+ m_control = data;
+
+ switch (m_control & 0x03)
+ {
+ case 1:
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+ break;
+
+ case 2:
+ m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
+ break;
+
+ default:
+ m_floppy = nullptr;
+ break;
+ }
+
if (m_floppy)
{
- m_floppy->mon_w((m_side_motor & 0x02) ? 0 : 1);
- m_floppy->ss_w(m_side_motor & 0x01);
+ m_floppy->mon_w(BIT(m_control, 3) ? 0 : 1);
+ m_floppy->ss_w(BIT(m_control, 2));
}
+
+ m_fdc->set_floppy(m_floppy);
+
+ if ((old_m_control ^ m_control) & 0x40)
+ {
+ m_led = BIT(m_control, 6);
+ }
+}
+
+u8 msx_slot_disk9_wd2793_n_device::status_r()
+{
+ return 0x3f | (m_fdc->intrq_r() ? 0x80 : 0) | (m_fdc->drq_r() ? 0x40 : 0);
+}
+
+
+
+
+msx_slot_disk10_mb8877_device::msx_slot_disk10_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk10_mb8877_device(mconfig, MSX_SLOT_DISK10_MB8877, tag, owner, clock)
+{
}
+msx_slot_disk10_mb8877_device::msx_slot_disk10_mb8877_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_wd_disk_device(mconfig, type, tag, owner, clock)
+ , m_control(0)
+{
+}
-uint8_t msx_slot_disk6_device::read(offs_t offset)
+void msx_slot_disk10_mb8877_device::device_add_mconfig(machine_config &config)
{
- switch (offset)
+ add_mconfig(config, MB8877, FORCE_READY, DRIVES_1, DS);
+}
+
+void msx_slot_disk10_mb8877_device::device_start()
+{
+ msx_slot_wd_disk_device::device_start();
+
+ save_item(NAME(m_control));
+
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7ff8, 0x7ff8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(1)->install_read_handler(0x7ff9, 0x7ff9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(1)->install_read_handler(0x7ffa, 0x7ffa, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(1)->install_read_handler(0x7ffb, 0x7ffb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(1)->install_read_handler(0x7ffc, 0x7ffc, read8smo_delegate(*this, FUNC(msx_slot_disk10_mb8877_device::status_r)));
+ // TODO 0x7ffd return system control/status
+ page(1)->install_write_handler(0x7ff8, 0x7ff8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(1)->install_write_handler(0x7ffa, 0x7ffa, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(1)->install_write_handler(0x7ffb, 0x7ffb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(1)->install_write_handler(0x7ffc, 0x7ffc, write8smo_delegate(*this, FUNC(msx_slot_disk10_mb8877_device::control_w)));
+}
+
+void msx_slot_disk10_mb8877_device::device_reset()
+{
+ m_fdc->dden_w(false);
+}
+
+void msx_slot_disk10_mb8877_device::device_post_load()
+{
+ control_w(m_control);
+}
+
+void msx_slot_disk10_mb8877_device::control_w(u8 data)
+{
+ const u8 old_m_control = m_control;
+
+ m_control = data;
+
+ if (BIT(m_control, 2))
+ m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
+ else
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+
+ if (m_floppy && !BIT(m_control, 2))
+ m_floppy->mon_w(BIT(m_control, 0) ? 0 : 1);
+
+ if (m_floppy && BIT(m_control, 2))
+ m_floppy->mon_w(BIT(m_control, 1) ? 0 : 1);
+
+ if (m_floppy)
+ m_floppy->ss_w(BIT(m_control, 3));
+
+ m_fdc->set_floppy(m_floppy);
+
+ // TODO Verify
+ if ((old_m_control ^ m_control) & 0x40)
{
- case 0x7ff0: // status?
- case 0x7ff8:
- return m_fdc->status_r();
-
- case 0x7ff1: // track?
- case 0x7ff9:
- return m_fdc->track_r();
-
- case 0x7ff2: // sector?
- case 0x7ffa:
- return m_fdc->sector_r();
-
- case 0x7ff3: // data?
- case 0x7ffb:
- return m_fdc->data_r();
-
- case 0x7ff4:
- case 0x7ffc:
- // bit 0 = side control
- // bit 1 = motor control
- return 0xfc | m_side_motor;
- break;
-
- // This reads back a 1 in bit 0 if drive0 is present and selected
- case 0x7ff5:
- case 0x7ffd:
- return 0xfe | m_drive_select0;
-
- // This reads back a 1 in bit 0 if drive1 is present and selected
- case 0x7ff6:
- case 0x7ffe:
- return 0xfe | m_drive_select1;
-
- case 0x7ff7:
- case 0x7fff:
- return 0x3f | (m_fdc->intrq_r() ? 0 : 0x40) | (m_fdc->drq_r() ? 0 : 0x80);
+ m_led = BIT(m_control, 6);
}
+}
+
+u8 msx_slot_disk10_mb8877_device::status_r()
+{
+ return 0x23
+ | (m_control & 0x04)
+ | ((m_control & 0x08) ^ 0x08)
+ | ((m_floppy && m_floppy->mon_r()) ? 0 : 0x10)
+ | (m_fdc->drq_r() ? 0x40 : 0)
+ | (m_fdc->intrq_r() ? 0x80 : 0);
+}
+
+
+msx_slot_disk10_mb8877_2_drives_device::msx_slot_disk10_mb8877_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_disk10_mb8877_device(mconfig, MSX_SLOT_DISK10_MB8877_2_DRIVES, tag, owner, clock)
+{
+}
+
+void msx_slot_disk10_mb8877_2_drives_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, MB8877, FORCE_READY, DRIVES_2, DS);
+}
+
+
+
+msx_slot_disk11_wd2793_device::msx_slot_disk11_wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_wd_disk_device(mconfig, MSX_SLOT_DISK11_WD2793, tag, owner, clock)
+ , m_side_control(0)
+ , m_control(0)
+{
+}
+
+void msx_slot_disk11_wd2793_device::device_add_mconfig(machine_config &config)
+{
+ add_mconfig(config, WD2793, FORCE_READY, DRIVES_1, DS);
+}
+
+void msx_slot_disk11_wd2793_device::device_start()
+{
+ msx_slot_wd_disk_device::device_start();
+
+ save_item(NAME(m_side_control));
+ save_item(NAME(m_control));
- return msx_slot_rom_device::read(offset);
+ page(1)->install_rom(0x4000, 0x7fff, rom_base());
+ page(1)->install_read_handler(0x7ff8, 0x7ff8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(1)->install_read_handler(0x7ff9, 0x7ff9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(1)->install_read_handler(0x7ffa, 0x7ffa, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(1)->install_read_handler(0x7ffb, 0x7ffb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(1)->install_read_handler(0x7ffc, 0x7ffc, read8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::side_control_r)));
+ page(1)->install_read_handler(0x7ffd, 0x7ffd, read8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::control_r)));
+ page(1)->install_read_handler(0x7fff, 0x7fff, read8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::status_r)));
+ page(1)->install_write_handler(0x7ff8, 0x7ff8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(1)->install_write_handler(0x7ffa, 0x7ffa, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(1)->install_write_handler(0x7ffb, 0x7ffb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(1)->install_write_handler(0x7ffc, 0x7ffc, write8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::side_control_w)));
+ page(1)->install_write_handler(0x7ffd, 0x7ffd, write8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::control_w)));
+
+ // TODO No idea why, but without this the other handlers do not get recognized
+ page(2)->install_rom(0xbff8, 0xbff8, rom_base());
+ page(2)->install_read_handler(0xbff8, 0xbff8, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::status_r)));
+ page(2)->install_read_handler(0xbff9, 0xbff9, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_r)));
+ page(2)->install_read_handler(0xbffa, 0xbffa, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_r)));
+ page(2)->install_read_handler(0xbffb, 0xbffb, read8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_r)));
+ page(2)->install_read_handler(0xbffc, 0xbffc, read8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::side_control_r)));
+ page(2)->install_read_handler(0xbffd, 0xbffd, read8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::control_r)));
+ page(2)->install_read_handler(0xbfff, 0xbfff, read8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::status_r)));
+ page(2)->install_write_handler(0xbff8, 0xbff8, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::cmd_w)));
+ page(2)->install_write_handler(0xbff9, 0xbff9, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::track_w)));
+ page(2)->install_write_handler(0xbffa, 0xbffa, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::sector_w)));
+ page(2)->install_write_handler(0xbffb, 0xbffb, write8smo_delegate(*m_fdc, FUNC(wd_fdc_analog_device_base::data_w)));
+ page(2)->install_write_handler(0xbffc, 0xbffc, write8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::side_control_w)));
+ page(2)->install_write_handler(0xbffd, 0xbffd, write8smo_delegate(*this, FUNC(msx_slot_disk11_wd2793_device::control_w)));
}
+void msx_slot_disk11_wd2793_device::device_reset()
+{
+ m_fdc->dden_w(false);
+}
-void msx_slot_disk6_device::write(offs_t offset, uint8_t data)
+void msx_slot_disk11_wd2793_device::device_post_load()
{
- switch (offset)
+ control_w(m_control);
+}
+
+void msx_slot_disk11_wd2793_device::side_control_w(u8 data)
+{
+ m_side_control = data;
+
+ if (m_floppy)
+ m_floppy->ss_w(BIT(m_side_control, 0));
+}
+
+void msx_slot_disk11_wd2793_device::control_w(u8 data)
+{
+ const u8 old_m_control = m_control;
+
+ m_control = data;
+
+ m_floppy = nullptr;
+ switch (m_control & 0x03)
{
- case 0x7ff0: // cmd?
- case 0x7ff8:
- m_fdc->cmd_w(data);
- break;
-
- case 0x7ff1: // track?
- case 0x7ff9:
- m_fdc->track_w(data);
- break;
-
- case 0x7ff2: // sector?
- case 0x7ffa:
- m_fdc->sector_w(data);
- break;
-
- case 0x7ff3: // data?
- case 0x7ffb:
- m_fdc->data_w(data);
- break;
-
- // Side and motort control
- // bit 0 = side select
- // bit 1 = motor on/off
- case 0x7ff4:
- case 0x7ffc:
- m_side_motor = data;
- set_side_motor();
- break;
-
- // bit 0 - select drive 0
- case 0x7ff5:
- case 0x7ffd:
- m_drive_select0 = data;
- select_drive();
- break;
-
- // bit 1 - select drive 1
- case 0x7ff6:
- case 0x7ffe:
- m_drive_select1 = data;
- select_drive();
- break;
-
- default:
- logerror("msx_slot_disk6_device::write: Unmapped write writing %02x to %04x\n", data, offset);
- break;
+ case 0:
+ m_floppy = m_floppy0 ? m_floppy0->get_device() : nullptr;
+ break;
+
+ case 1:
+ m_floppy = m_floppy1 ? m_floppy1->get_device() : nullptr;
+ break;
}
+
+ if (m_floppy)
+ {
+ m_floppy->mon_w(BIT(m_control, 7) ? 0 : 1);
+ m_floppy->ss_w(BIT(m_side_control, 0));
+ }
+
+ m_fdc->set_floppy(m_floppy);
+
+ if ((old_m_control ^ m_control) & 0x40)
+ {
+ m_led = BIT(~m_control, 6);
+ }
+}
+
+u8 msx_slot_disk11_wd2793_device::side_control_r()
+{
+ return 0xfe | (m_side_control & 0x01);
+}
+
+u8 msx_slot_disk11_wd2793_device::control_r()
+{
+ return (m_control & 0x83) | 0x78;
+}
+
+u8 msx_slot_disk11_wd2793_device::status_r()
+{
+ // bit 4 is checked during reading (ready check?)
+ return 0x3f | (m_fdc->intrq_r() ? 0 : 0x40) | (m_fdc->drq_r() ? 0 : 0x80);
}
diff --git a/src/devices/bus/msx_slot/disk.h b/src/devices/bus/msx_slot/disk.h
index 184ea2caf66..5d96682b795 100644
--- a/src/devices/bus/msx_slot/disk.h
+++ b/src/devices/bus/msx_slot/disk.h
@@ -12,72 +12,81 @@
#include "imagedev/floppy.h"
-/* WD FDC accessed through 7ffx */
-DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1, msx_slot_disk1_device)
-/* WD FDC accessed through 7fbx */
-DECLARE_DEVICE_TYPE(MSX_SLOT_DISK2, msx_slot_disk2_device)
-/* TC8566 accessed through 7ff8-7fff */
-DECLARE_DEVICE_TYPE(MSX_SLOT_DISK3, msx_slot_disk3_device)
-/* TC8566 accessed through 7ff0-7ff7 (used in Turob-R, untested) */
-DECLARE_DEVICE_TYPE(MSX_SLOT_DISK4, msx_slot_disk4_device)
-/* WD FDC accessed through i/o ports 0xd0-0xd4 */
-DECLARE_DEVICE_TYPE(MSX_SLOT_DISK5, msx_slot_disk5_device)
-/* WD FDC accessed through 7ff0-7ff? (used in Toshiba HX34) */
-DECLARE_DEVICE_TYPE(MSX_SLOT_DISK6, msx_slot_disk6_device)
+// WD FDC accessed through 7ffx
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1_FD1793, msx_slot_disk1_fd1793_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1_MB8877, msx_slot_disk1_mb8877_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_N, msx_slot_disk1_wd2793_n_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_N_2_DRIVES, msx_slot_disk1_wd2793_n_2_drives_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793, msx_slot_disk1_wd2793_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_0, msx_slot_disk1_wd2793_0_device) // No drives, for nms8260
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_SS, msx_slot_disk1_wd2793_ss_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK1_WD2793_2_DRIVES, msx_slot_disk1_wd2793_2_drives_device)
+// WD FDC accessed through 7fbx
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK2_FD1793_SS, msx_slot_disk2_fd1793_ss_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK2_MB8877, msx_slot_disk2_mb8877_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK2_MB8877_SS, msx_slot_disk2_mb8877_ss_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK2_MB8877_2_DRIVES, msx_slot_disk2_mb8877_2_drives_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK2_WD2793, msx_slot_disk2_wd2793_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK2_WD2793_2_DRIVES, msx_slot_disk2_wd2793_2_drives_device)
+// TC8566 accessed through 7ff8-7fff
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK3_TC8566, msx_slot_disk3_tc8566_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK3_TC8566_2_DRIVES, msx_slot_disk3_tc8566_2_drives_device)
+// TC8566 accessed through 7ff0-7ff7 (used in Turob-R, untested)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK4_TC8566, msx_slot_disk4_tc8566_device)
+// WD FDC accessed through i/o ports 0xd0-0xd4
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK5_WD2793, msx_slot_disk5_wd2793_device)
+// WD FDC accessed through 7ff0-7ff? (used in Toshiba HX34)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK6_WD2793_N, msx_slot_disk6_wd2793_n_device)
+// MB FDC accessed through 7ff8-7ffc (used in Canon V-30F)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK7_MB8877, msx_slot_disk7_mb8877_device)
+// WD FDC accessed through 7f8x
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK8_MB8877, msx_slot_disk8_mb8877_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK8_WD2793_2_DRIVES, msx_slot_disk8_wd2793_2_drives_device)
+// WD FDC accessed through 7ffx, slightly different from DISK1 (used in PHC-77)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK9_WD2793_N, msx_slot_disk9_wd2793_n_device)
+// WD FDC accessed through 7ffx, slightly different from DISK1 (used in Victor HC-90 / HC-95)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK10_MB8877, msx_slot_disk10_mb8877_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK10_MB8877_2_DRIVES, msx_slot_disk10_mb8877_2_drives_device)
+// WD FDC accessed through 7ffx, slightly different from DISK1 (used in Yamaha YIS-805)
+DECLARE_DEVICE_TYPE(MSX_SLOT_DISK11_WD2793, msx_slot_disk11_wd2793_device)
class msx_slot_disk_device : public msx_slot_rom_device
{
-public:
- // configuration helpers
- void set_fdc_tag(const char *tag) { m_fdc_tag = tag; }
- void set_floppy0_tag(const char *tag) { m_floppy0_tag = tag; }
- void set_floppy1_tag(const char *tag) { m_floppy1_tag = tag; }
- void set_floppy2_tag(const char *tag) { m_floppy2_tag = tag; }
- void set_floppy3_tag(const char *tag) { m_floppy3_tag = tag; }
-
- void set_tags(const char *fdc_tag, const char *floppy0_tag, const char *floppy1_tag)
- {
- m_fdc_tag = fdc_tag;
- m_floppy0_tag = floppy0_tag;
- m_floppy1_tag = floppy1_tag;
- }
- void set_tags(const char *fdc_tag, const char *floppy0_tag, const char *floppy1_tag, const char *floppy2_tag, const char *floppy3_tag)
- {
- m_fdc_tag = fdc_tag;
- m_floppy0_tag = floppy0_tag;
- m_floppy1_tag = floppy1_tag;
- m_floppy2_tag = floppy2_tag;
- m_floppy3_tag = floppy3_tag;
- }
-
protected:
- msx_slot_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void device_start() override;
-
- floppy_connector *m_floppy0;
- floppy_connector *m_floppy1;
- floppy_connector *m_floppy2;
- floppy_connector *m_floppy3;
+ static constexpr int NO_DRIVES = 0;
+ static constexpr int DRIVES_1 = 1;
+ static constexpr int DRIVES_2 = 2;
+ static constexpr int DRIVES_3 = 3;
+ static constexpr int DRIVES_4 = 4;
+ static constexpr bool DS = true;
+ static constexpr bool SS = false;
+
+ msx_slot_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ static void floppy_formats(format_registration &fr);
+ void add_drive_mconfig(machine_config &config, int nr_of_drives, bool double_sided);
+
+ optional_device<floppy_connector> m_floppy0;
+ optional_device<floppy_connector> m_floppy1;
+ optional_device<floppy_connector> m_floppy2;
+ optional_device<floppy_connector> m_floppy3;
floppy_image_device *m_floppy;
-
- const char *m_fdc_tag;
- const char *m_floppy0_tag;
- const char *m_floppy1_tag;
- const char *m_floppy2_tag;
- const char *m_floppy3_tag;
};
class msx_slot_wd_disk_device : public msx_slot_disk_device
{
protected:
+ static constexpr bool FORCE_READY = true;
+ static constexpr bool NO_FORCE_READY = false;
+
msx_slot_wd_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
virtual void device_start() override;
+ template <typename FDCType> void add_mconfig(machine_config &config, FDCType &&type, bool force_ready, int nr_of_drives, bool double_sided);
- wd_fdc_analog_device_base *m_fdc;
+ required_device<wd_fdc_analog_device_base> m_fdc;
output_finder<> m_led;
};
@@ -87,115 +96,375 @@ class msx_slot_tc8566_disk_device : public msx_slot_disk_device
protected:
msx_slot_tc8566_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ void add_mconfig(machine_config &config, int nr_of_drives);
+
+ required_device<tc8566af_device> m_fdc;
+};
+
+
+class msx_slot_disk1_base_device : public msx_slot_wd_disk_device
+{
+protected:
+ msx_slot_disk1_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override;
+
+private:
+ void set_control(u8 data);
+ void set_side_control(u8 data);
+ u8 side_control_r();
+ u8 control_r();
+ u8 status_r();
+
+ u8 m_side_control;
+ u8 m_control;
+};
+
+class msx_slot_disk1_fd1793_device : public msx_slot_disk1_base_device
+{
+public:
+ msx_slot_disk1_fd1793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msx_slot_disk1_mb8877_device : public msx_slot_disk1_base_device
+{
+public:
+ msx_slot_disk1_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msx_slot_disk1_wd2793_n_device : public msx_slot_disk1_base_device
+{
+public:
+ msx_slot_disk1_wd2793_n_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msx_slot_disk1_wd2793_n_2_drives_device : public msx_slot_disk1_base_device
+{
+public:
+ msx_slot_disk1_wd2793_n_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msx_slot_disk1_wd2793_device : public msx_slot_disk1_base_device
+{
+public:
+ msx_slot_disk1_wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- tc8566af_device *m_fdc;
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
};
+class msx_slot_disk1_wd2793_0_device : public msx_slot_disk1_base_device
+{
+public:
+ msx_slot_disk1_wd2793_0_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msx_slot_disk1_wd2793_ss_device : public msx_slot_disk1_base_device
+{
+public:
+ msx_slot_disk1_wd2793_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
-class msx_slot_disk1_device : public msx_slot_wd_disk_device
+class msx_slot_disk1_wd2793_2_drives_device : public msx_slot_disk1_base_device
{
public:
- msx_slot_disk1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_disk1_wd2793_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+class msx_slot_disk2_base_device : public msx_slot_wd_disk_device
+{
protected:
+ msx_slot_disk2_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_post_load() override;
private:
- uint8_t m_side_control;
- uint8_t m_control;
+ void set_control(u8 data);
+ u8 status_r();
+
+ u8 m_control;
+};
+
+class msx_slot_disk2_fd1793_ss_device : public msx_slot_disk2_base_device
+{
+public:
+ msx_slot_disk2_fd1793_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- void set_control(uint8_t data);
- void set_side_control(uint8_t data);
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
};
+class msx_slot_disk2_mb8877_device : public msx_slot_disk2_base_device
+{
+public:
+ msx_slot_disk2_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msx_slot_disk2_mb8877_ss_device : public msx_slot_disk2_base_device
+{
+public:
+ msx_slot_disk2_mb8877_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
-class msx_slot_disk2_device : public msx_slot_wd_disk_device
+class msx_slot_disk2_mb8877_2_drives_device : public msx_slot_disk2_base_device
{
public:
- msx_slot_disk2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_disk2_mb8877_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msx_slot_disk2_wd2793_device : public msx_slot_disk2_base_device
+{
+public:
+ msx_slot_disk2_wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+class msx_slot_disk2_wd2793_2_drives_device : public msx_slot_disk2_base_device
+{
+public:
+ msx_slot_disk2_wd2793_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+
+
+class msx_slot_disk3_tc8566_device : public msx_slot_tc8566_disk_device
+{
+public:
+ msx_slot_disk3_tc8566_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ msx_slot_disk3_tc8566_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+};
+
+
+class msx_slot_disk3_tc8566_2_drives_device : public msx_slot_disk3_tc8566_device
+{
+public:
+ msx_slot_disk3_tc8566_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+
+class msx_slot_disk4_tc8566_device : public msx_slot_tc8566_disk_device
+{
+public:
+ msx_slot_disk4_tc8566_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual void device_start() override;
+};
+
+
+class msx_slot_disk5_wd2793_device : public msx_slot_wd_disk_device
+{
+public:
+ msx_slot_disk5_wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_post_load() override;
+ virtual void device_add_mconfig(machine_config &config) override;
private:
- uint8_t m_control;
+ void control_w(u8 control);
+ u8 status_r();
- void set_control(uint8_t data);
+ u8 m_control;
};
-class msx_slot_disk3_device : public msx_slot_tc8566_disk_device
+class msx_slot_disk6_wd2793_n_device : public msx_slot_wd_disk_device
{
public:
- msx_slot_disk3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_disk6_wd2793_n_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ void set_side_motor();
+ void select_drive();
+ u8 side_motor_r();
+ u8 select0_r();
+ u8 select1_r();
+ u8 status_r();
+ void side_motor_w(u8 data);
+ void select0_w(u8 data);
+ void select1_w(u8 data);
+
+ u8 m_side_motor;
+ u8 m_drive_select0;
+ u8 m_drive_select1;
};
-class msx_slot_disk4_device : public msx_slot_tc8566_disk_device
+class msx_slot_disk7_mb8877_device : public msx_slot_wd_disk_device
{
public:
- msx_slot_disk4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_disk7_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ void set_drive_side_motor();
+ void select_drive();
+ void side_motor_w(u8 data);
+ u8 status_r();
+
+ u8 m_drive_side_motor;
};
-class msx_slot_disk5_device : public msx_slot_wd_disk_device
+class msx_slot_disk8_mb8877_device : public msx_slot_wd_disk_device
{
public:
- msx_slot_disk5_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_disk8_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
+ msx_slot_disk8_mb8877_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_post_load() override;
+ virtual void device_add_mconfig(machine_config &config) override;
private:
- uint8_t io_read(offs_t offset);
- void io_write(offs_t offset, uint8_t data);
+ void set_control(u8 data);
+ u8 status_r();
- uint8_t m_control;
+ u8 m_control;
+};
- void set_control(uint8_t control);
+class msx_slot_disk8_wd2793_2_drives_device : public msx_slot_disk8_mb8877_device
+{
+public:
+ msx_slot_disk8_wd2793_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
};
-class msx_slot_disk6_device : public msx_slot_wd_disk_device
+class msx_slot_disk9_wd2793_n_device : public msx_slot_wd_disk_device
{
public:
- msx_slot_disk6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_disk9_wd2793_n_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ void control_w(u8 data);
+ u8 status_r();
+
+ u8 m_control;
+};
+
+
+class msx_slot_disk10_mb8877_device : public msx_slot_wd_disk_device
+{
+public:
+ msx_slot_disk10_mb8877_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
+ msx_slot_disk10_mb8877_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_post_load() override;
+ virtual void device_add_mconfig(machine_config &config) override;
private:
- uint8_t m_side_motor;
- uint8_t m_drive_select0;
- uint8_t m_drive_select1;
+ void control_w(u8 data);
+ u8 status_r();
- void set_side_motor();
- void select_drive();
+ u8 m_control;
};
+class msx_slot_disk10_mb8877_2_drives_device : public msx_slot_disk10_mb8877_device
+{
+public:
+ msx_slot_disk10_mb8877_2_drives_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_add_mconfig(machine_config &config) override;
+};
+
+
+class msx_slot_disk11_wd2793_device : public msx_slot_wd_disk_device
+{
+public:
+ msx_slot_disk11_wd2793_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ void control_w(u8 data);
+ void side_control_w(u8 data);
+ u8 side_control_r();
+ u8 control_r();
+ u8 status_r();
+
+ u8 m_side_control;
+ u8 m_control;
+};
#endif // MAME_BUS_MSX_SLOT_DISK_H
diff --git a/src/devices/bus/msx_slot/fs4600.cpp b/src/devices/bus/msx_slot/fs4600.cpp
index 0f328985f6f..ae6d472c1d5 100644
--- a/src/devices/bus/msx_slot/fs4600.cpp
+++ b/src/devices/bus/msx_slot/fs4600.cpp
@@ -11,28 +11,25 @@
DEFINE_DEVICE_TYPE(MSX_SLOT_FS4600, msx_slot_fs4600_device, "msx_slot_fs4600", "MSX Internal FS4600 Firmware")
-msx_slot_fs4600_device::msx_slot_fs4600_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_fs4600_device::msx_slot_fs4600_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, MSX_SLOT_FS4600, tag, owner, clock)
, msx_internal_slot_interface(mconfig, *this)
, m_nvram(*this, "nvram")
, m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_rombank(*this, "rombank%u", 0U)
+ , m_view0(*this, "view0")
+ , m_view1(*this, "view1")
+ , m_view2(*this, "view2")
, m_region_offset(0)
- , m_rom(nullptr)
- , m_selected_bank{ 0, 0, 0, 0 }
- , m_bank_base{ nullptr, nullptr, nullptr, nullptr }
, m_sram_address(0)
- , m_control(0)
{
- memset(m_sram, 0, sizeof(m_sram));
}
-
void msx_slot_fs4600_device::device_add_mconfig(machine_config &config)
{
- NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
+ NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
}
-
void msx_slot_fs4600_device::device_start()
{
// Sanity checks
@@ -41,102 +38,101 @@ void msx_slot_fs4600_device::device_start()
fatalerror("Memory region '%s' is too small for the FS4600 firmware\n", m_rom_region.finder_tag());
}
- m_rom = m_rom_region->base() + m_region_offset;
- m_nvram->set_base(m_sram, 0x1000);
+ m_sram.resize(SRAM_SIZE);
+ m_nvram->set_base(m_sram.data(), SRAM_SIZE);
- save_item(NAME(m_selected_bank));
save_item(NAME(m_sram_address));
- save_item(NAME(m_control));
- restore_banks();
+ for (int i = 0; i < 3; i++)
+ m_rombank[i]->configure_entries(0, 0x40, m_rom_region->base() + m_region_offset, 0x4000);
+
+ page(0)->install_view(0x0000, 0x3fff, m_view0);
+ m_view0[0].install_read_bank(0x0000, 0x3fff, m_rombank[0]);
+ m_view0[1].install_read_bank(0x0000, 0x3fff, m_rombank[0]);
+ m_view0[1].install_write_handler(0x3ffa, 0x3ffd, write8sm_delegate(*this, FUNC(msx_slot_fs4600_device::sram_w)));
+ m_view0[1].install_read_handler(0x3ffd, 0x3ffd, read8smo_delegate(*this, FUNC(msx_slot_fs4600_device::sram_r)));
+
+ page(1)->install_view(0x4000, 0x7fff, m_view1);
+ m_view1[0].install_read_bank(0x4000, 0x7fff, m_rombank[1]);
+ m_view1[0].install_write_handler(0x6000, 0x6000, write8smo_delegate(*this, FUNC(msx_slot_fs4600_device::bank_w<1>)));
+ m_view1[0].install_write_handler(0x6400, 0x6400, write8smo_delegate(*this, FUNC(msx_slot_fs4600_device::bank_w<0>)));
+ m_view1[0].install_write_handler(0x7000, 0x7000, write8smo_delegate(*this, FUNC(msx_slot_fs4600_device::bank_w<2>)));
+ m_view1[1].install_read_bank(0x4000, 0x7fff, m_rombank[1]);
+ m_view1[1].install_write_handler(0x7ffa, 0x7ffd, write8sm_delegate(*this, FUNC(msx_slot_fs4600_device::sram_w)));
+ m_view1[1].install_read_handler(0x7ffd, 0x7ffd, read8smo_delegate(*this, FUNC(msx_slot_fs4600_device::sram_r)));
+ m_view1[2].install_read_bank(0x4000, 0x7fff, m_rombank[1]);
+ m_view1[2].install_write_handler(0x6000, 0x6000, write8smo_delegate(*this, FUNC(msx_slot_fs4600_device::bank_w<1>)));
+ m_view1[2].install_write_handler(0x6400, 0x6400, write8smo_delegate(*this, FUNC(msx_slot_fs4600_device::bank_w<0>)));
+ m_view1[2].install_write_handler(0x7000, 0x7000, write8smo_delegate(*this, FUNC(msx_slot_fs4600_device::bank_w<2>)));
+ m_view1[2].install_read_handler(0x7ff0, 0x7ff5, read8sm_delegate(*this, FUNC(msx_slot_fs4600_device::bank_r)));
+ m_view1[3].install_read_bank(0x4000, 0x7fff, m_rombank[1]);
+ m_view1[3].install_read_handler(0x7ff0, 0x7ff5, read8sm_delegate(*this, FUNC(msx_slot_fs4600_device::bank_r)));
+ m_view1[3].install_write_handler(0x7ffa, 0x7ffd, write8sm_delegate(*this, FUNC(msx_slot_fs4600_device::sram_w)));
+ m_view1[3].install_read_handler(0x7ffd, 0x7ffd, read8smo_delegate(*this, FUNC(msx_slot_fs4600_device::sram_r)));
+
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*this, FUNC(msx_slot_fs4600_device::control_w)));
+
+ page(2)->install_view(0x8000, 0xbfff, m_view2);
+ m_view2[0].install_read_bank(0x8000, 0xbfff, m_rombank[2]);
+ m_view2[1].install_read_bank(0x8000, 0xbfff, m_rombank[2]);
+ m_view2[1].install_write_handler(0xbffa, 0xbffd, write8sm_delegate(*this, FUNC(msx_slot_fs4600_device::sram_w)));
+ m_view2[1].install_read_handler(0xbffd, 0xbffd, read8smo_delegate(*this, FUNC(msx_slot_fs4600_device::sram_r)));
}
-
-void msx_slot_fs4600_device::device_post_load()
+void msx_slot_fs4600_device::device_reset()
{
- restore_banks();
+ m_view0.select(0);
+ m_view1.select(0);
+ m_view2.select(0);
+ m_rombank[0]->set_entry(0);
+ m_rombank[1]->set_entry(0);
+ m_rombank[2]->set_entry(0);
}
+u8 msx_slot_fs4600_device::sram_r()
+{
+ u8 data = m_sram[m_sram_address & (SRAM_SIZE - 1)];
+ if (!machine().side_effects_disabled())
+ m_sram_address++;
+ return data;
+}
-void msx_slot_fs4600_device::restore_banks()
+void msx_slot_fs4600_device::sram_w(offs_t offset, u8 data)
{
- for (int i = 0; i < 4; i++)
+ switch (offset)
{
- m_bank_base[i] = m_rom + ( ( m_selected_bank[i] * 0x4000 ) & 0x0fffff );
+ case 0:
+ m_sram_address = (m_sram_address & 0x00ffff) | (data << 16);
+ break;
+
+ case 1:
+ m_sram_address = (m_sram_address & 0xff00ff) | (data << 8);
+ break;
+
+ case 2:
+ m_sram_address = (m_sram_address & 0xffff00) | data;
+ break;
+
+ case 3:
+ m_sram[m_sram_address++ & (SRAM_SIZE - 1)] = data;
+ break;
}
}
-
-uint8_t msx_slot_fs4600_device::read(offs_t offset)
+u8 msx_slot_fs4600_device::bank_r(offs_t offset)
{
- if ((m_control & 0x02) && ((offset & 0x3fff) == 0x3ffd))
- {
- return m_sram[m_sram_address++ & 0xfff];
- }
- if ((m_control & 0x04) && (offset& 0x7ff8) == 0x7ff0)
- {
- return m_selected_bank[(offset >> 1) & 0x03];
- }
- return m_bank_base[offset >> 14][offset & 0x3fff];
+ return m_rombank[offset >> 1]->entry();
}
+template <int Bank>
+void msx_slot_fs4600_device::bank_w(u8 data)
+{
+ m_rombank[Bank]->set_entry(data & 0x3f);
+}
-void msx_slot_fs4600_device::write(offs_t offset, uint8_t data)
+void msx_slot_fs4600_device::control_w(u8 data)
{
- if (offset == 0x7ff9)
- {
- m_control = data;
- }
- else
- {
- if (m_control & 0x02)
- {
- switch (offset & 0x3fff)
- {
- case 0x3ffa:
- m_sram_address = (m_sram_address & 0x00ffff) | (data << 16);
- break;
-
- case 0x3ffb:
- m_sram_address = (m_sram_address & 0xff00ff) | (data << 8);
- break;
-
- case 0x3ffc:
- m_sram_address = (m_sram_address & 0xffff00) | data;
- break;
-
- case 0x3ffd:
- m_sram[m_sram_address++ & 0xfff] = data;
- break;
-
- default:
- logerror("msx_slot_fs4600: Unhandled write %02x to %04x\n", data, offset);
- break;
- }
- }
- else
- {
- switch (offset)
- {
- case 0x6000:
- m_selected_bank[1] = data;
- m_bank_base[1] = m_rom + ( ( m_selected_bank[1] * 0x4000 ) & 0x0fffff );
- break;
-
- case 0x6400:
- m_selected_bank[0] = data;
- m_bank_base[0] = m_rom + ( ( m_selected_bank[0] * 0x4000 ) & 0x0fffff );
- break;
-
- case 0x7000:
- m_selected_bank[2] = data;
- m_bank_base[2] = m_rom + ( ( m_selected_bank[2] * 0x4000 ) & 0x0fffff );
- break;
-
- default:
- logerror("msx_slot_fs4600: Unhandled write %02x to %04x\n", data, offset);
- break;
- }
- }
- }
+ m_view0.select((data >> 1) & 0x01);
+ m_view1.select((data >> 1) & 0x03);
+ m_view2.select((data >> 1) & 0x01);
}
diff --git a/src/devices/bus/msx_slot/fs4600.h b/src/devices/bus/msx_slot/fs4600.h
index 4b571c2ef56..736ddab499a 100644
--- a/src/devices/bus/msx_slot/fs4600.h
+++ b/src/devices/bus/msx_slot/fs4600.h
@@ -15,32 +15,35 @@ DECLARE_DEVICE_TYPE(MSX_SLOT_FS4600, msx_slot_fs4600_device)
class msx_slot_fs4600_device : public device_t, public msx_internal_slot_interface
{
public:
- msx_slot_fs4600_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_fs4600_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
- void set_rom_start(const char *region, uint32_t offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
-
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+ void set_rom_start(const char *region, u32 offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
protected:
virtual void device_start() override;
- virtual void device_post_load() override;
+ virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
- void restore_banks();
-
private:
+ static constexpr size_t SRAM_SIZE = 0x1000;
+
+ void control_w(u8 data);
+ u8 sram_r();
+ void sram_w(offs_t offset, u8 data);
+ template <int Bank> void bank_w(u8 data);
+ u8 bank_r(offs_t offset);
+
required_device<nvram_device> m_nvram;
required_memory_region m_rom_region;
- uint32_t m_region_offset;
- const uint8_t *m_rom;
- uint8_t m_selected_bank[4];
- const uint8_t *m_bank_base[4];
- uint32_t m_sram_address;
- uint8_t m_sram[0x1000];
- uint8_t m_control;
+ memory_bank_array_creator<3> m_rombank;
+ memory_view m_view0;
+ memory_view m_view1;
+ memory_view m_view2;
+ u32 m_region_offset;
+ u32 m_sram_address;
+ std::vector<u8> m_sram;
};
diff --git a/src/devices/bus/msx_slot/fsa1fm.cpp b/src/devices/bus/msx_slot/fsa1fm.cpp
new file mode 100644
index 00000000000..8ec13f28e30
--- /dev/null
+++ b/src/devices/bus/msx_slot/fsa1fm.cpp
@@ -0,0 +1,239 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+/*
+
+ Emulation of the firmware mapper in the Panasonic FS-A1FM.
+
+*/
+
+#include "emu.h"
+#include "fsa1fm.h"
+
+
+DEFINE_DEVICE_TYPE(MSX_SLOT_FSA1FM, msx_slot_fsa1fm_device, "msx_slot_fs1afm", "MSX Internal FS-A1FM")
+DEFINE_DEVICE_TYPE(MSX_SLOT_FSA1FM2, msx_slot_fsa1fm2_device, "msx_slot_fs1afm2", "MSX Internal FS-A1FM part 2")
+
+
+msx_slot_fsa1fm2_device::msx_slot_fsa1fm2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, MSX_SLOT_FSA1FM2, tag, owner, clock)
+ , msx_internal_slot_interface(mconfig, *this)
+ , m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_bank(*this, "bank%u", 0U)
+ , m_view0(*this, "view0")
+ , m_view1(*this, "view1")
+ , m_view2(*this, "view2")
+ , m_view3(*this, "view3")
+ , m_view4(*this, "view4")
+ , m_view5(*this, "view5")
+ , m_region_offset(0)
+{
+}
+
+void msx_slot_fsa1fm2_device::device_start()
+{
+ // Sanity checks
+ if (m_rom_region->bytes() != 0x100000)
+ {
+ fatalerror("Memory region '%s' is not the correct size for the FS-A1FM firmware\n", m_rom_region.finder_tag());
+ }
+
+ m_ram.resize(RAM_SIZE);
+ m_empty_bank.resize(8 * 1024);
+ for (int i = 0; i < 8 * 1024; i++)
+ m_empty_bank[i] = 0xff;
+
+ save_item(NAME(m_selected_bank));
+ save_item(NAME(m_control));
+ save_item(NAME(m_ram_active));
+ save_pointer(m_ram.data(), "ram", RAM_SIZE);
+
+ for (int i = 0; i < 6; i++)
+ {
+ m_bank[i]->configure_entries(0, 0x80, m_rom_region->base() + m_region_offset, 0x2000);
+ m_bank[i]->configure_entries(0x80, 0x80, m_rom_region->base() + m_region_offset, 0x2000);
+ for (int j = 0; j < 4; j++)
+ {
+ m_bank[i]->configure_entry(0x80 + j, m_empty_bank.data()); // 0x80-0x83 empty
+ m_bank[i]->configure_entry(0x84 + j, m_ram.data()); // 0x84-0x87 ram
+ m_bank[i]->configure_entry(0x88 + j, m_empty_bank.data()); // 0x88-0x8b empty
+ m_bank[i]->configure_entry(0x8c + j, m_ram.data()); // 0x8c-0x8f ram
+ }
+ }
+
+ page(0)->install_view(0x0000, 0x1fff, m_view0);
+ m_view0[0].install_read_bank(0x0000, 0x1fff, m_bank[0]);
+ m_view0[1].install_readwrite_bank(0x0000, 0x1fff, m_bank[0]);
+
+ page(0)->install_view(0x2000, 0x3fff, m_view1);
+ m_view1[0].install_read_bank(0x2000, 0x3fff, m_bank[1]);
+ m_view1[1].install_readwrite_bank(0x2000, 0x3fff, m_bank[1]);
+
+ page(1)->install_view(0x4000, 0x5fff, m_view2);
+ m_view2[0].install_read_bank(0x4000, 0x5fff, m_bank[2]);
+ m_view2[1].install_readwrite_bank(0x4000, 0x5fff, m_bank[2]);
+
+ page(1)->install_view(0x6000, 0x7fff, m_view3);
+ m_view3[0].install_read_bank(0x6000, 0x7fff, m_bank[3]);
+ m_view3[1].install_readwrite_bank(0x6000, 0x7fff, m_bank[3]);
+ m_view3[2].install_read_bank(0x6000, 0x7fff, m_bank[3]);
+ m_view3[2].install_read_handler(0x7ff0, 0x7ff7, read8sm_delegate(*this, FUNC(msx_slot_fsa1fm2_device::bank_r)));
+ m_view3[3].install_readwrite_bank(0x6000, 0x7fff, m_bank[3]);
+ m_view3[3].install_read_handler(0x7ff0, 0x7ff7, read8sm_delegate(*this, FUNC(msx_slot_fsa1fm2_device::bank_r)));
+ page(1)->install_write_handler(0x6000, 0x6000, write8smo_delegate(*this, FUNC(msx_slot_fsa1fm2_device::bank_w<2>)));
+ page(1)->install_write_handler(0x6400, 0x6400, write8smo_delegate(*this, FUNC(msx_slot_fsa1fm2_device::bank_w<0>)));
+ page(1)->install_write_handler(0x6800, 0x6800, write8smo_delegate(*this, FUNC(msx_slot_fsa1fm2_device::bank_w<3>)));
+ page(1)->install_write_handler(0x6c00, 0x6c00, write8smo_delegate(*this, FUNC(msx_slot_fsa1fm2_device::bank_w<1>)));
+ page(1)->install_write_handler(0x7000, 0x7000, write8smo_delegate(*this, FUNC(msx_slot_fsa1fm2_device::bank_w<4>)));
+ page(1)->install_write_handler(0x7800, 0x7800, write8smo_delegate(*this, FUNC(msx_slot_fsa1fm2_device::bank_w<5>)));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*this, FUNC(msx_slot_fsa1fm2_device::control_w)));
+
+ page(2)->install_view(0x8000, 0x9fff, m_view4);
+ m_view4[0].install_read_bank(0x8000, 0x9fff, m_bank[4]);
+ m_view4[1].install_readwrite_bank(0x8000, 0x9fff, m_bank[4]);
+
+ page(2)->install_view(0xa000, 0xbfff, m_view5);
+ m_view5[0].install_read_bank(0xa000, 0xbfff, m_bank[5]);
+ m_view5[1].install_readwrite_bank(0xa000, 0xbfff, m_bank[5]);
+}
+
+void msx_slot_fsa1fm2_device::device_reset()
+{
+ m_view0.select(0);
+ m_view1.select(0);
+ m_view2.select(0);
+ m_view3.select(0);
+ m_view4.select(0);
+ m_view5.select(0);
+ m_control = 0;
+
+ for (int i = 0; i < 6 ; i++)
+ {
+ m_selected_bank[i] = 0xa8;
+ m_bank[i]->set_entry(0x28);
+ }
+}
+
+template <int Bank>
+void msx_slot_fsa1fm2_device::set_view()
+{
+ bool ram_active = (m_selected_bank[Bank] & 0xf4) == 0x84;
+ if (Bank == 0)
+ m_view0.select(ram_active ? 1 : 0);
+ if (Bank == 1)
+ m_view1.select(ram_active ? 1 : 0);
+ if (Bank == 2)
+ m_view2.select(ram_active ? 1 : 0);
+ if (Bank == 3)
+ m_view3.select((ram_active ? 1 : 0) | (BIT(m_control, 2) ? 2 : 0));
+ if (Bank == 4)
+ m_view4.select(ram_active ? 1 : 0);
+ if (Bank == 5)
+ m_view5.select(ram_active ? 1 : 0);
+}
+
+template <int Bank>
+void msx_slot_fsa1fm2_device::bank_w(u8 data)
+{
+ m_selected_bank[Bank] = data;
+ m_bank[Bank]->set_entry(data);
+ set_view<Bank>();
+}
+
+u8 msx_slot_fsa1fm2_device::bank_r(offs_t offset)
+{
+ return (offset < 6) ? m_selected_bank[offset] : 0;
+}
+
+void msx_slot_fsa1fm2_device::control_w(u8 data)
+{
+ // writing $04 enables read back of banking registers at 7ff0-7ff5
+ m_control = data;
+ set_view<3>();
+}
+
+
+
+
+msx_slot_fsa1fm_device::msx_slot_fsa1fm_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, MSX_SLOT_FSA1FM, tag, owner, clock)
+ , msx_internal_slot_interface(mconfig, *this)
+ , m_nvram(*this, "nvram")
+ , m_i8251(*this, "i8251")
+ , m_i8255(*this, "i8255")
+ , m_switch_port(*this, "SWITCH")
+ , m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_rombank(*this, "rombank")
+ , m_region_offset(0)
+{
+}
+
+static INPUT_PORTS_START(fsa1fm)
+ PORT_START("SWITCH")
+ PORT_CONFNAME(0x04, 0x00, "Firmware is")
+ PORT_CONFSETTING(0x04, "disabled")
+ PORT_CONFSETTING(0x00, "enabled")
+INPUT_PORTS_END
+
+ioport_constructor msx_slot_fsa1fm_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(fsa1fm);
+}
+
+void msx_slot_fsa1fm_device::device_add_mconfig(machine_config &config)
+{
+ NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
+
+ // Unknown how these are connected
+ I8251(config, m_i8251, 0);
+
+ I8255(config, m_i8255);
+ m_i8255->out_pa_callback().set(FUNC(msx_slot_fsa1fm_device::i8255_port_a_w));
+ m_i8255->out_pb_callback().set(FUNC(msx_slot_fsa1fm_device::i8255_port_b_w));
+ m_i8255->in_pc_callback().set(FUNC(msx_slot_fsa1fm_device::i8255_port_c_r));
+}
+
+void msx_slot_fsa1fm_device::device_start()
+{
+ // Sanity checks
+ if (m_rom_region->bytes() != 0x100000)
+ {
+ fatalerror("Memory region '%s' is not the correct size for the FS-A1FM firmware\n", m_rom_region.finder_tag());
+ }
+
+ m_sram.resize(SRAM_SIZE);
+ m_nvram->set_base(m_sram.data(), SRAM_SIZE);
+
+ m_rombank->configure_entries(0, 16, m_rom_region->base(), 0x2000);
+
+ page(1)->install_read_bank(0x4000, 0x5fff, m_rombank);
+ // SRAM is always visible?
+ page(1)->install_ram(0x6000, 0x7fff, m_sram.data());
+ page(1)->install_write_handler(0x7fc0, 0x7fc0, write8smo_delegate(*m_i8251, FUNC(i8251_device::data_w)));
+ page(1)->install_read_handler(0x7fc0, 0x7fc0, read8smo_delegate(*m_i8251, FUNC(i8251_device::data_r)));
+ page(1)->install_write_handler(0x7fc1, 0x7fc1, write8smo_delegate(*m_i8251, FUNC(i8251_device::control_w)));
+ page(1)->install_write_handler(0x7fc4, 0x7fc7, write8sm_delegate(*m_i8255, FUNC(i8255_device::write)));
+ page(1)->install_read_handler(0x7fc4, 0x7fc7, read8sm_delegate(*m_i8255, FUNC(i8255_device::read)));
+}
+
+void msx_slot_fsa1fm_device::device_reset()
+{
+ m_rombank->set_entry(0);
+}
+
+void msx_slot_fsa1fm_device::i8255_port_a_w(u8 data)
+{
+ // 0xc0 enables sram?
+ logerror("port A write %02x\n", data);
+ m_rombank->set_entry(data & 0x0f);
+}
+
+void msx_slot_fsa1fm_device::i8255_port_b_w(u8 data)
+{
+ logerror("port B write %02x\n", data);
+}
+
+u8 msx_slot_fsa1fm_device::i8255_port_c_r()
+{
+ logerror("port C read\n");
+ return m_switch_port->read();
+}
diff --git a/src/devices/bus/msx_slot/fsa1fm.h b/src/devices/bus/msx_slot/fsa1fm.h
new file mode 100644
index 00000000000..51028e18311
--- /dev/null
+++ b/src/devices/bus/msx_slot/fsa1fm.h
@@ -0,0 +1,88 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+#ifndef MAME_BUS_MSX_SLOT_FSA1FM_H
+#define MAME_BUS_MSX_SLOT_FSA1FM_H
+
+#pragma once
+
+#include "slot.h"
+#include "machine/i8251.h"
+#include "machine/i8255.h"
+#include "machine/nvram.h"
+
+
+DECLARE_DEVICE_TYPE(MSX_SLOT_FSA1FM, msx_slot_fsa1fm_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_FSA1FM2, msx_slot_fsa1fm2_device)
+
+
+class msx_slot_fsa1fm2_device : public device_t, public msx_internal_slot_interface
+{
+public:
+ msx_slot_fsa1fm2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // configuration helpers
+ void set_rom_start(const char *region, uint32_t offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ static constexpr size_t RAM_SIZE = 0x2000;
+
+ template <int Bank> void set_view();
+ template <int Bank> void bank_w(u8 data);
+ u8 bank_r(offs_t offset);
+ void control_w(u8 data);
+
+ required_memory_region m_rom_region;
+ memory_bank_array_creator<6> m_bank;
+ memory_view m_view0;
+ memory_view m_view1;
+ memory_view m_view2;
+ memory_view m_view3;
+ memory_view m_view4;
+ memory_view m_view5;
+ uint32_t m_region_offset;
+ uint8_t m_selected_bank[6];
+ bool m_ram_active[6];
+ uint8_t m_control;
+ std::vector<uint8_t> m_ram;
+ std::vector<uint8_t> m_empty_bank;
+};
+
+
+class msx_slot_fsa1fm_device : public device_t, public msx_internal_slot_interface
+{
+public:
+ msx_slot_fsa1fm_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // configuration helpers
+ void set_rom_start(const char *region, uint32_t offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ static constexpr size_t SRAM_SIZE = 0x2000;
+
+ void map_bank();
+ void i8255_port_a_w(u8 data);
+ void i8255_port_b_w(u8 data);
+ u8 i8255_port_c_r();
+
+ required_device<nvram_device> m_nvram;
+ required_device<i8251_device> m_i8251;
+ required_device<i8255_device> m_i8255;
+ required_ioport m_switch_port;
+ required_memory_region m_rom_region;
+ memory_bank_creator m_rombank;
+ u32 m_region_offset;
+ std::vector<u8> m_sram;
+};
+
+
+#endif // MAME_BUS_MSX_SLOT_FSA1FM_H
diff --git a/src/devices/bus/msx_slot/msx_rs232.cpp b/src/devices/bus/msx_slot/msx_rs232.cpp
new file mode 100644
index 00000000000..84e5334e235
--- /dev/null
+++ b/src/devices/bus/msx_slot/msx_rs232.cpp
@@ -0,0 +1,528 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+
+/*
+Emulation of MSX internal RS-232 modules
+
+TODO:
+- What does the Mitsubishi RS232 switch do? Disable the entire RS-232 unit?
+*/
+
+#include "emu.h"
+#include "msx_rs232.h"
+
+
+DEFINE_DEVICE_TYPE(MSX_SLOT_RS232, msx_slot_rs232_device, "msx_slot_rs232", "MSX Internal RS-232C")
+DEFINE_DEVICE_TYPE(MSX_SLOT_RS232_MITSUBISHI, msx_slot_rs232_mitsubishi_device, "msx_slot_rs232_mitsubishi", "Mitsubishi Internal RS-232C")
+DEFINE_DEVICE_TYPE(MSX_SLOT_RS232_SONY, msx_slot_rs232_sony_device, "msx_slot_rs232_sony", "Sony Internal RS-232C")
+DEFINE_DEVICE_TYPE(MSX_SLOT_RS232_SVI738, msx_slot_rs232_svi738_device, "msx_slot_rs232_svi738", "SVI-738 Internal RS-232C")
+DEFINE_DEVICE_TYPE(MSX_SLOT_RS232_TOSHIBA, msx_slot_rs232_toshiba_device, "msx_slot_rs232_toshiba", "Toshiba Internal RS-232C")
+DEFINE_DEVICE_TYPE(MSX_SLOT_RS232_TOSHIBA_HX3X, msx_slot_rs232_toshiba_hx3x_device, "msx_slot_rs232_toshiba_hx3x", "Toshiba HX-33/HX-34 Internal RS-232C and firmware")
+
+
+
+static INPUT_PORTS_START(msx_rs232_enable_switch)
+ PORT_START("SWITCH")
+ PORT_CONFNAME(0x01, 0x01, "RS-232C is")
+ PORT_CONFSETTING(0x00, "disabled")
+ PORT_CONFSETTING(0x01, "enabled")
+INPUT_PORTS_END
+
+
+msx_slot_rs232_base_device::msx_slot_rs232_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_rom_device(mconfig, type, tag, owner, clock)
+ , m_i8251(*this, "i8251")
+ , m_i8253(*this, "i8253")
+ , m_rs232(*this, "rs232")
+ , m_irq_handler(*this)
+ , m_irq_mask(0xff)
+ , m_out2(false)
+ , m_cts(false)
+ , m_dcd(false)
+ , m_ri(false)
+ , m_rxrdy(false)
+{
+}
+
+void msx_slot_rs232_base_device::device_add_mconfig(machine_config &config)
+{
+ // Config based on svi738 schematics, are they the same for other machines?
+
+ I8251(config, m_i8251, 1.8432_MHz_XTAL);
+ m_i8251->txd_handler().set(m_rs232, FUNC(rs232_port_device::write_txd));
+ m_i8251->dtr_handler().set(m_rs232, FUNC(rs232_port_device::write_dtr));
+ m_i8251->rts_handler().set(m_rs232, FUNC(rs232_port_device::write_rts));
+ m_i8251->rxrdy_handler().set(*this, FUNC(msx_slot_rs232_base_device::rxrdy_w));
+ m_i8251->txrdy_handler().set(*this, FUNC(msx_slot_rs232_base_device::txrdy_w));
+
+ PIT8253(config, m_i8253);
+ m_i8253->set_clk<0>(1.8432_MHz_XTAL);
+ m_i8253->set_clk<1>(1.8432_MHz_XTAL);
+ m_i8253->set_clk<2>(1.8432_MHz_XTAL);
+ m_i8253->out_handler<0>().set(m_i8251, FUNC(i8251_device::write_rxc));
+ m_i8253->out_handler<1>().set(m_i8251, FUNC(i8251_device::write_txc));
+ m_i8253->out_handler<2>().set(*this, FUNC(msx_slot_rs232_base_device::out2_w));
+
+ RS232_PORT(config, m_rs232, default_rs232_devices, nullptr);
+ m_rs232->rxd_handler().set(m_i8251, FUNC(i8251_device::write_rxd));
+ m_rs232->dcd_handler().set(*this, FUNC(msx_slot_rs232_base_device::dcd_w));
+ m_rs232->ri_handler().set(*this, FUNC(msx_slot_rs232_base_device::ri_w));
+ m_rs232->cts_handler().set(*this, FUNC(msx_slot_rs232_base_device::cts_w));
+ m_rs232->dsr_handler().set(m_i8251, FUNC(i8251_device::write_dsr));
+}
+
+void msx_slot_rs232_base_device::device_start()
+{
+ msx_slot_rom_device::device_start();
+
+ m_irq_handler.resolve_safe();
+
+ save_item(NAME(m_irq_mask));
+ save_item(NAME(m_out2));
+ save_item(NAME(m_cts));
+ save_item(NAME(m_dcd));
+ save_item(NAME(m_ri));
+ save_item(NAME(m_rxrdy));
+ save_item(NAME(m_txrdy));
+}
+
+void msx_slot_rs232_base_device::device_reset()
+{
+ m_irq_mask = 0xff;
+ m_out2 = false;
+ m_cts = false;
+ m_dcd = false;
+ m_ri =false;
+ m_rxrdy = false;
+}
+
+void msx_slot_rs232_base_device::irq_mask_w(offs_t offset, u8 data)
+{
+ // According to MSX datapack:
+ // 7654---- unused
+ // ----3--- timer interrupt from i8352 channel 2
+ // -----2-- sync character detect / break detect
+ // ------1- transmit data ready
+ // -------0 receive data ready
+ // but most rs232 interface only seem to support receive data ready irq
+ m_irq_mask = data;
+}
+
+WRITE_LINE_MEMBER(msx_slot_rs232_base_device::out2_w)
+{
+ m_out2 = state;
+ update_irq_state();
+}
+
+WRITE_LINE_MEMBER(msx_slot_rs232_base_device::cts_w)
+{
+ m_cts = state;
+ m_i8251->write_cts(state);
+}
+
+WRITE_LINE_MEMBER(msx_slot_rs232_base_device::dcd_w)
+{
+ m_dcd = state;
+ update_irq_state();
+}
+
+WRITE_LINE_MEMBER(msx_slot_rs232_base_device::ri_w)
+{
+ m_ri = state;
+}
+
+WRITE_LINE_MEMBER(msx_slot_rs232_base_device::rxrdy_w)
+{
+ m_rxrdy = state;
+ update_irq_state();
+}
+
+WRITE_LINE_MEMBER(msx_slot_rs232_base_device::txrdy_w)
+{
+ m_txrdy = state;
+ update_irq_state();
+}
+
+
+
+msx_slot_rs232_device::msx_slot_rs232_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_rs232_base_device(mconfig, MSX_SLOT_RS232, tag, owner, clock)
+{
+}
+
+void msx_slot_rs232_device::device_start()
+{
+ msx_slot_rs232_base_device::device_start();
+
+ // Install IO read/write handlers
+ io_space().install_readwrite_handler(0x80, 0x81, read8sm_delegate(*m_i8251, FUNC(i8251_device::read)), write8sm_delegate(*m_i8251, FUNC(i8251_device::write)));
+ io_space().install_readwrite_handler(0x82, 0x82, read8sm_delegate(*this, FUNC(msx_slot_rs232_device::status_r)), write8sm_delegate(*this, FUNC(msx_slot_rs232_device::irq_mask_w)));
+ io_space().install_readwrite_handler(0x84, 0x87, read8sm_delegate(*m_i8253, FUNC(pit8253_device::read)), write8sm_delegate(*m_i8253, FUNC(pit8253_device::write)));
+}
+
+u8 msx_slot_rs232_device::status_r(offs_t offset)
+{
+ // 7------- CTS
+ // -6------ 8253 channel 2 output
+ // --5432-- unused
+ // ------1- ring indicator
+ // -------0 carrier detect
+
+ u8 result = 0x00;
+
+ if (m_cts)
+ result |= 0x80;
+
+ if (m_out2)
+ result |= 0x40;
+
+ if (m_ri)
+ result |= 0x02;
+
+ if (m_dcd)
+ result |= 0x01;
+
+ return result;
+}
+
+void msx_slot_rs232_device::update_irq_state()
+{
+ m_irq_handler(m_rxrdy);
+}
+
+
+
+msx_slot_rs232_mitsubishi_device::msx_slot_rs232_mitsubishi_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_rs232_base_device(mconfig, MSX_SLOT_RS232_MITSUBISHI, tag, owner, clock)
+ , m_switch_port(*this, "SWITCH")
+{
+}
+
+ioport_constructor msx_slot_rs232_mitsubishi_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(msx_rs232_enable_switch);
+}
+
+void msx_slot_rs232_mitsubishi_device::device_start()
+{
+ msx_slot_rs232_base_device::device_start();
+
+ // Install IO read/write handlers
+ io_space().install_readwrite_handler(0x80, 0x81, read8sm_delegate(*m_i8251, FUNC(i8251_device::read)), write8sm_delegate(*m_i8251, FUNC(i8251_device::write)));
+ io_space().install_readwrite_handler(0x82, 0x82, read8sm_delegate(*this, FUNC(msx_slot_rs232_mitsubishi_device::status_r)), write8sm_delegate(*this, FUNC(msx_slot_rs232_mitsubishi_device::irq_mask_w)));
+ io_space().install_readwrite_handler(0x84, 0x87, read8sm_delegate(*m_i8253, FUNC(pit8253_device::read)), write8sm_delegate(*m_i8253, FUNC(pit8253_device::write)));
+}
+
+u8 msx_slot_rs232_mitsubishi_device::status_r(offs_t offset)
+{
+ // 7------- CTS
+ // -6------ 8253 channel 2 output
+ // --54321- unused
+ // -------0 carrier detect
+
+ uint8_t result = 0x00;
+
+ if (m_cts)
+ result |= 0x80;
+
+ if (m_out2)
+ result |= 0x40;
+
+ if (m_dcd)
+ result |= 0x01;
+
+ return result;
+}
+
+void msx_slot_rs232_mitsubishi_device::update_irq_state()
+{
+ if (!BIT(m_irq_mask, 0))
+ m_irq_handler(m_rxrdy);
+}
+
+
+
+msx_slot_rs232_sony_device::msx_slot_rs232_sony_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_rs232_base_device(mconfig, MSX_SLOT_RS232_SONY, tag, owner, clock)
+ , m_switch_port(*this, "SWITCH")
+{
+}
+
+ioport_constructor msx_slot_rs232_sony_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(msx_rs232_enable_switch);
+}
+
+void msx_slot_rs232_sony_device::device_start()
+{
+ msx_slot_rs232_base_device::device_start();
+
+ m_ram.resize(RAM_SIZE);
+ save_item(NAME(m_ram));
+
+ // TODO unmap rom from page 0
+ page(0)->install_ram(0x2000, 0x27ff, m_ram.data());
+ page(1)->install_rom(0x4000, 0x5fff, m_rom_region->base() + m_region_offset);
+ page(1)->install_ram(0x6000, 0x67ff, m_ram.data());
+ page(2)->install_ram(0xa000, 0xa7ff, m_ram.data());
+ page(2)->install_read_handler(0xbff8, 0xbff9, read8sm_delegate(*m_i8251, FUNC(i8251_device::read)));
+ page(2)->install_write_handler(0xbff8, 0xbff9, write8sm_delegate(*m_i8251, FUNC(i8251_device::write)));
+ page(2)->install_read_handler(0xbffa, 0xbffa, read8sm_delegate(*this, FUNC(msx_slot_rs232_sony_device::status_r)));
+ page(2)->install_write_handler(0xbffa, 0xbffa, write8sm_delegate(*this, FUNC(msx_slot_rs232_sony_device::irq_mask_w)));
+ page(2)->install_read_handler(0xbffc, 0xbfff, read8sm_delegate(*m_i8253, FUNC(pit8253_device::read)));
+ page(2)->install_write_handler(0xbffc, 0xbfff, write8sm_delegate(*m_i8253, FUNC(pit8253_device::write)));
+ page(3)->install_ram(0xe000, 0xe7ff, m_ram.data());
+}
+
+u8 msx_slot_rs232_sony_device::status_r(offs_t offset)
+{
+ // 7------- CTS
+ // -6------ 8253 channel 2 output
+ // --5----- unused
+ // ---4---- ??
+ // ----32-- unused
+ // ------1- ring indicator
+ // -------0 carrier detect
+
+ u8 result = 0x00;
+
+ if (m_cts)
+ result |= 0x80;
+
+ if (m_out2)
+ result |= 0x40;
+
+ if (m_ri)
+ result |= 0x02;
+
+ if (m_dcd)
+ result |= 0x01;
+
+ return result;
+}
+
+void msx_slot_rs232_sony_device::update_irq_state()
+{
+ if (!BIT(m_irq_mask, 0))
+ m_irq_handler(m_rxrdy);
+}
+
+
+
+msx_slot_rs232_svi738_device::msx_slot_rs232_svi738_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_rs232_base_device(mconfig, MSX_SLOT_RS232_SVI738, tag, owner, clock)
+{
+}
+
+void msx_slot_rs232_svi738_device::device_start()
+{
+ msx_slot_rs232_base_device::device_start();
+
+ // Install IO read/write handlers
+ io_space().install_readwrite_handler(0x80, 0x81, read8sm_delegate(*m_i8251, FUNC(i8251_device::read)), write8sm_delegate(*m_i8251, FUNC(i8251_device::write)));
+ io_space().install_read_handler(0x82, 0x82, read8sm_delegate(*this, FUNC(msx_slot_rs232_svi738_device::status_r)));
+ io_space().install_readwrite_handler(0x84, 0x87, read8sm_delegate(*m_i8253, FUNC(pit8253_device::read)), write8sm_delegate(*m_i8253, FUNC(pit8253_device::write)));
+}
+
+u8 msx_slot_rs232_svi738_device::status_r(offs_t offset)
+{
+ // 7------- CTS
+ // -6------ 8253 channel 2 output
+ // --54321- unused
+ // -------0 carrier detect
+
+ u8 result = 0x00;
+
+ if (m_cts)
+ result |= 0x80;
+
+ if (m_out2)
+ result |= 0x40;
+
+ if (m_dcd)
+ result |= 0x01;
+
+ return result;
+}
+
+void msx_slot_rs232_svi738_device::update_irq_state()
+{
+ m_irq_handler(m_rxrdy);
+}
+
+
+
+msx_slot_rs232_toshiba_device::msx_slot_rs232_toshiba_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_rs232_base_device(mconfig, MSX_SLOT_RS232_TOSHIBA, tag, owner, clock)
+ , m_switch_port(*this, "SWITCH")
+{
+}
+
+ioport_constructor msx_slot_rs232_toshiba_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(msx_rs232_enable_switch);
+}
+
+void msx_slot_rs232_toshiba_device::device_start()
+{
+ msx_slot_rs232_base_device::device_start();
+
+ // Install IO read/write handlers
+ io_space().install_readwrite_handler(0x80, 0x81, read8sm_delegate(*m_i8251, FUNC(i8251_device::read)), write8sm_delegate(*m_i8251, FUNC(i8251_device::write)));
+ io_space().install_readwrite_handler(0x82, 0x82, read8sm_delegate(*this, FUNC(msx_slot_rs232_toshiba_device::status_r)), write8sm_delegate(*this, FUNC(msx_slot_rs232_toshiba_device::irq_mask_w)));
+ io_space().install_readwrite_handler(0x84, 0x87, read8sm_delegate(*m_i8253, FUNC(pit8253_device::read)), write8sm_delegate(*m_i8253, FUNC(pit8253_device::write)));
+}
+
+u8 msx_slot_rs232_toshiba_device::status_r(offs_t offset)
+{
+ // 7------- CTS
+ // -6------ 8253 channel 2 output
+ // --54---- unused
+ // ----3--- switch detection
+ // -----2-- unused
+ // ------1- ring indicator
+ // -------0 carrier detect
+
+ u8 result = 0x00;
+
+ if (m_cts)
+ result |= 0x80;
+
+ if (m_out2)
+ result |= 0x40;
+
+ if (BIT(m_irq_mask, 0) && m_switch_port->read())
+ result |= 0x08;
+
+ if (m_ri)
+ result |= 0x02;
+
+ if (m_dcd)
+ result |= 0x01;
+
+ return result;
+}
+
+void msx_slot_rs232_toshiba_device::update_irq_state()
+{
+ if (!BIT(m_irq_mask, 0))
+ m_irq_handler(m_rxrdy);
+}
+
+
+
+msx_slot_rs232_toshiba_hx3x_device::msx_slot_rs232_toshiba_hx3x_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : msx_slot_rs232_base_device(mconfig, MSX_SLOT_RS232_TOSHIBA_HX3X, tag, owner, clock)
+ , m_switch_port(*this, "SWITCH")
+ , m_copy_port(*this, "COPY")
+ , m_nvram(*this, "nvram")
+ , m_rombank(*this, "rombank")
+ , m_view(*this, "view")
+{
+}
+
+static INPUT_PORTS_START(msx_hx3x_ports)
+ PORT_INCLUDE(msx_rs232_enable_switch)
+
+ PORT_START("COPY")
+ PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Copy")
+INPUT_PORTS_END
+
+ioport_constructor msx_slot_rs232_toshiba_hx3x_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(msx_hx3x_ports);
+}
+
+void msx_slot_rs232_toshiba_hx3x_device::device_add_mconfig(machine_config &config)
+{
+ msx_slot_rs232_base_device::device_add_mconfig(config);
+
+ NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
+}
+
+void msx_slot_rs232_toshiba_hx3x_device::device_start()
+{
+ msx_slot_rs232_base_device::device_start();
+
+ // Sanity checks
+ // 16KB for RS-232C rom and 4 16KB banks for firmware
+ if (m_rom_region->bytes() < m_region_offset + 0x14000)
+ {
+ fatalerror("Memory region '%s' is too small for rom slot '%s'\n", m_rom_region.finder_tag(), tag());
+ }
+
+ // Install IO read/write handlers
+ io_space().install_readwrite_handler(0x80, 0x81, read8sm_delegate(*m_i8251, FUNC(i8251_device::read)), write8sm_delegate(*m_i8251, FUNC(i8251_device::write)));
+ io_space().install_readwrite_handler(0x82, 0x82, read8sm_delegate(*this, FUNC(msx_slot_rs232_toshiba_hx3x_device::status_r)), write8sm_delegate(*this, FUNC(msx_slot_rs232_toshiba_hx3x_device::irq_mask_w)));
+ io_space().install_readwrite_handler(0x84, 0x87, read8sm_delegate(*m_i8253, FUNC(pit8253_device::read)), write8sm_delegate(*m_i8253, FUNC(pit8253_device::write)));
+
+ m_sram.resize(SRAM_SIZE);
+ m_nvram->set_base(m_sram.data(), SRAM_SIZE);
+
+ save_item(NAME(m_bank_reg));
+
+ m_rombank->configure_entries(0, 4, m_rom_region->base() + m_region_offset + 0x4000, 0x4000);
+
+ page(1)->install_write_handler(0x7fff, 0x7fff, write8smo_delegate(*this, FUNC(msx_slot_rs232_toshiba_hx3x_device::bank_w)));
+ page(1)->install_read_handler(0x7fff, 0x7fff, read8smo_delegate(*this, FUNC(msx_slot_rs232_toshiba_hx3x_device::bank_r)));
+ page(2)->install_view(0x8000, 0xbfff, m_view);
+ m_view[0].install_read_bank(0x8000, 0xbfff, m_rombank);
+ m_view[1].install_ram(0x8000, 0x87ff, 0x3800, m_sram.data());
+}
+
+void msx_slot_rs232_toshiba_hx3x_device::device_reset()
+{
+ msx_slot_rs232_base_device::device_reset();
+
+ m_bank_reg = 0;
+ m_view.select(0);
+ m_rombank->set_entry(0);
+}
+
+u8 msx_slot_rs232_toshiba_hx3x_device::status_r(offs_t offset)
+{
+ // 7------- CTS
+ // -6------ 8253 channel 2 output
+ // --54---- unused
+ // ----3--- switch detection
+ // -----2-- unused
+ // ------1- ring indicator
+ // -------0 carrier detect
+
+ u8 result = 0x00;
+
+ if (m_cts)
+ result |= 0x80;
+
+ if (m_out2)
+ result |= 0x40;
+
+ if (BIT(m_irq_mask, 0) && m_switch_port->read())
+ result |= 0x08;
+
+ if (m_ri)
+ result |= 0x02;
+
+ if (m_dcd)
+ result |= 0x01;
+
+ return result;
+}
+
+void msx_slot_rs232_toshiba_hx3x_device::update_irq_state()
+{
+ if (!BIT(m_irq_mask, 0))
+ m_irq_handler(m_rxrdy);
+}
+
+u8 msx_slot_rs232_toshiba_hx3x_device::bank_r()
+{
+ return (m_copy_port->read() & 0x80) | m_bank_reg;
+}
+
+void msx_slot_rs232_toshiba_hx3x_device::bank_w(u8 data)
+{
+ m_bank_reg = data & 0x7f;
+ m_rombank->set_entry(data & 0x03);
+ m_view.select(((data & 0x60) == 0x60) ? 1 : 0);
+}
diff --git a/src/devices/bus/msx_slot/msx_rs232.h b/src/devices/bus/msx_slot/msx_rs232.h
new file mode 100644
index 00000000000..2df9a653f38
--- /dev/null
+++ b/src/devices/bus/msx_slot/msx_rs232.h
@@ -0,0 +1,168 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+#ifndef MAME_BUS_MSX_SLOT_MSX_RS232_H
+#define MAME_BUS_MSX_SLOT_MSX_RS232_H
+
+#pragma once
+
+#include "rom.h"
+#include "bus/rs232/rs232.h"
+#include "machine/i8251.h"
+#include "machine/nvram.h"
+#include "machine/pit8253.h"
+
+class msx_slot_rs232_base_device : public msx_slot_rom_device
+{
+public:
+
+ // configuration helpers
+ auto irq_handler() { return m_irq_handler.bind(); }
+
+protected:
+ msx_slot_rs232_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ virtual void irq_mask_w(offs_t offset, u8 data);
+ virtual u8 status_r(offs_t offset) { return 0; }
+ virtual void update_irq_state() { }
+ DECLARE_WRITE_LINE_MEMBER(out2_w);
+ DECLARE_WRITE_LINE_MEMBER(cts_w);
+ DECLARE_WRITE_LINE_MEMBER(dcd_w);
+ DECLARE_WRITE_LINE_MEMBER(ri_w);
+ DECLARE_WRITE_LINE_MEMBER(rxrdy_w);
+ DECLARE_WRITE_LINE_MEMBER(txrdy_w);
+
+ required_device<i8251_device> m_i8251;
+ required_device<pit8253_device> m_i8253;
+ required_device<rs232_port_device> m_rs232;
+
+ devcb_write_line m_irq_handler;
+
+ u8 m_irq_mask;
+ bool m_out2;
+ bool m_cts;
+ bool m_dcd;
+ bool m_ri;
+ bool m_rxrdy;
+ bool m_txrdy;
+};
+
+
+class msx_slot_rs232_device : public msx_slot_rs232_base_device
+{
+public:
+ msx_slot_rs232_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_start() override;
+
+ virtual u8 status_r(offs_t offset) override;
+ virtual void update_irq_state() override;
+};
+
+
+class msx_slot_rs232_mitsubishi_device : public msx_slot_rs232_base_device
+{
+public:
+ msx_slot_rs232_mitsubishi_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_start() override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual u8 status_r(offs_t offset) override;
+ virtual void update_irq_state() override;
+
+ required_ioport m_switch_port;
+};
+
+
+class msx_slot_rs232_sony_device : public msx_slot_rs232_base_device
+{
+public:
+ msx_slot_rs232_sony_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_start() override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual uint8_t status_r(offs_t offset) override;
+ virtual void update_irq_state() override;
+
+ static constexpr size_t RAM_SIZE = 0x800;
+
+ required_ioport m_switch_port;
+ std::vector<u8> m_ram;
+};
+
+
+class msx_slot_rs232_svi738_device : public msx_slot_rs232_base_device
+{
+public:
+ msx_slot_rs232_svi738_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_start() override;
+
+ virtual u8 status_r(offs_t offset) override;
+ virtual void update_irq_state() override;
+};
+
+
+class msx_slot_rs232_toshiba_device : public msx_slot_rs232_base_device
+{
+public:
+ msx_slot_rs232_toshiba_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual void device_start() override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual uint8_t status_r(offs_t offset) override;
+ virtual void update_irq_state() override;
+
+ required_ioport m_switch_port;
+};
+
+
+class msx_slot_rs232_toshiba_hx3x_device : public msx_slot_rs232_base_device
+{
+public:
+ msx_slot_rs232_toshiba_hx3x_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ static constexpr size_t SRAM_SIZE = 0x800;
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual ioport_constructor device_input_ports() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ virtual uint8_t status_r(offs_t offset) override;
+ virtual void update_irq_state() override;
+
+ void bank_w(u8 data);
+ u8 bank_r();
+
+ required_ioport m_switch_port;
+ required_ioport m_copy_port;
+ required_device<nvram_device> m_nvram;
+ memory_bank_creator m_rombank;
+ memory_view m_view;
+ std::vector<u8> m_sram;
+ u8 m_bank_reg;
+};
+
+
+DECLARE_DEVICE_TYPE(MSX_SLOT_RS232, msx_slot_rs232_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_RS232_MITSUBISHI, msx_slot_rs232_mitsubishi_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_RS232_SONY, msx_slot_rs232_sony_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_RS232_SVI738, msx_slot_rs232_svi738_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_RS232_TOSHIBA, msx_slot_rs232_toshiba_device)
+DECLARE_DEVICE_TYPE(MSX_SLOT_RS232_TOSHIBA_HX3X, msx_slot_rs232_toshiba_hx3x_device)
+
+
+#endif // MAME_BUS_MSX_SLOT_MSX_RS232_H
diff --git a/src/devices/bus/msx_slot/msx_write.cpp b/src/devices/bus/msx_slot/msx_write.cpp
new file mode 100644
index 00000000000..483532dbe9c
--- /dev/null
+++ b/src/devices/bus/msx_slot/msx_write.cpp
@@ -0,0 +1,78 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+/*
+
+ Emulation of the firmware mapper in the Sanyo PHC-77.
+
+*/
+
+#include "emu.h"
+#include "msx_write.h"
+
+
+DEFINE_DEVICE_TYPE(MSX_SLOT_MSX_WRITE, msx_slot_msx_write_device, "msx_slot_msx_write", "MSX Internal MSX-Write")
+
+
+msx_slot_msx_write_device::msx_slot_msx_write_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, MSX_SLOT_MSX_WRITE, tag, owner, clock)
+ , msx_internal_slot_interface(mconfig, *this)
+ , m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_switch_port(*this, "SWITCH")
+ , m_rombank(*this, "rombank%u", 0U)
+ , m_view1(*this, "view1")
+ , m_view2(*this, "view2")
+ , m_region_offset(0)
+ , m_enabled(true)
+{
+}
+
+static INPUT_PORTS_START(msx_write)
+ PORT_START("SWITCH")
+ PORT_CONFNAME(0x01, 0x01, "Firmware is")
+ PORT_CONFSETTING(0x00, "disabled")
+ PORT_CONFSETTING(0x01, "enabled")
+INPUT_PORTS_END
+
+ioport_constructor msx_slot_msx_write_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(msx_write);
+}
+
+void msx_slot_msx_write_device::device_start()
+{
+ // Sanity checks
+ if (m_rom_region->bytes() != 0x80000)
+ {
+ fatalerror("Memory region '%s' is not the correct size for the MSX-Write firmware\n", m_rom_region.finder_tag());
+ }
+
+ m_rombank[0]->configure_entries(0, 0x20, m_rom_region->base() + m_region_offset, 0x4000);
+ m_rombank[1]->configure_entries(0, 0x20, m_rom_region->base() + m_region_offset, 0x4000);
+
+ page(1)->install_view(0x4000, 0x7fff, m_view1);
+ m_view1[0].install_read_bank(0x4000, 0x7fff, m_rombank[0]);
+ m_view1[0].install_write_handler(0x6fff, 0x6fff, write8smo_delegate(*this, FUNC(msx_slot_msx_write_device::bank_w<0>)));
+ m_view1[0].install_write_handler(0x7fff, 0x7fff, write8smo_delegate(*this, FUNC(msx_slot_msx_write_device::bank_w<1>)));
+ m_view1[1];
+
+ page(2)->install_view(0x8000, 0xbfff, m_view2);
+ m_view2[0].install_read_bank(0x8000, 0xbfff, m_rombank[1]);
+ m_view2[1];
+}
+
+void msx_slot_msx_write_device::device_reset()
+{
+ m_enabled = BIT(m_switch_port->read(), 0);
+
+ m_rombank[0]->set_entry(0);
+ m_rombank[1]->set_entry(1);
+
+ m_view1.select(m_enabled ? 0 : 1);
+ m_view2.select(m_enabled ? 0 : 1);
+}
+
+template <int Bank>
+void msx_slot_msx_write_device::bank_w(u8 data)
+{
+ m_rombank[Bank]->set_entry(data & 0x1f);
+}
diff --git a/src/devices/bus/msx_slot/msx_write.h b/src/devices/bus/msx_slot/msx_write.h
new file mode 100644
index 00000000000..70d8203df06
--- /dev/null
+++ b/src/devices/bus/msx_slot/msx_write.h
@@ -0,0 +1,41 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+#ifndef MAME_BUS_MSX_SLOT_MSX_WRITE_H
+#define MAME_BUS_MSX_SLOT_MSX_WRITE_H
+
+#pragma once
+
+#include "slot.h"
+#include "machine/nvram.h"
+
+
+DECLARE_DEVICE_TYPE(MSX_SLOT_MSX_WRITE, msx_slot_msx_write_device)
+
+
+class msx_slot_msx_write_device : public device_t, public msx_internal_slot_interface
+{
+public:
+ msx_slot_msx_write_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // configuration helpers
+ void set_rom_start(const char *region, u32 offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ template <int Bank> void bank_w(u8 data);
+
+ required_memory_region m_rom_region;
+ required_ioport m_switch_port;
+ memory_bank_array_creator<2> m_rombank;
+ memory_view m_view1;
+ memory_view m_view2;
+ u32 m_region_offset;
+ bool m_enabled;
+};
+
+
+#endif // MAME_BUS_MSX_SLOT_MSX_WRITE_H
diff --git a/src/devices/bus/msx_slot/music.cpp b/src/devices/bus/msx_slot/music.cpp
index 1c5daf86b67..9529643603a 100644
--- a/src/devices/bus/msx_slot/music.cpp
+++ b/src/devices/bus/msx_slot/music.cpp
@@ -7,14 +7,13 @@
DEFINE_DEVICE_TYPE(MSX_SLOT_MUSIC, msx_slot_music_device, "msx_slot_music", "MSX Internal MSX-MUSIC")
-msx_slot_music_device::msx_slot_music_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_music_device::msx_slot_music_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: msx_slot_rom_device(mconfig, MSX_SLOT_MUSIC, tag, owner, clock)
, m_ym2413(nullptr)
, m_ym2413_tag(nullptr)
{
}
-
void msx_slot_music_device::device_start()
{
msx_slot_rom_device::device_start();
@@ -32,17 +31,5 @@ void msx_slot_music_device::device_start()
}
// Install IO read/write handlers
- io_space().install_write_handler(0x7c, 0x7d, write8sm_delegate(*this, FUNC(msx_slot_music_device::write_ym2413)));
-}
-
-
-uint8_t msx_slot_music_device::read(offs_t offset)
-{
- return msx_slot_rom_device::read(offset);
-}
-
-
-void msx_slot_music_device::write_ym2413(offs_t offset, uint8_t data)
-{
- m_ym2413->write(offset & 1, data);
+ io_space().install_write_handler(0x7c, 0x7d, write8sm_delegate(*m_ym2413, FUNC(ym2413_device::write)));
}
diff --git a/src/devices/bus/msx_slot/music.h b/src/devices/bus/msx_slot/music.h
index 0d9240079ab..49073a53aa2 100644
--- a/src/devices/bus/msx_slot/music.h
+++ b/src/devices/bus/msx_slot/music.h
@@ -16,19 +16,15 @@ DECLARE_DEVICE_TYPE(MSX_SLOT_MUSIC, msx_slot_music_device)
class msx_slot_music_device : public msx_slot_rom_device
{
public:
- msx_slot_music_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_music_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
void set_ym2413_tag(const char *tag) { m_ym2413_tag = tag; }
- virtual uint8_t read(offs_t offset) override;
-
protected:
virtual void device_start() override;
private:
- void write_ym2413(offs_t offset, uint8_t data);
-
ym2413_device *m_ym2413;
const char *m_ym2413_tag;
};
diff --git a/src/devices/bus/msx_slot/panasonic08.cpp b/src/devices/bus/msx_slot/panasonic08.cpp
index 0c46350051e..c9410e906e6 100644
--- a/src/devices/bus/msx_slot/panasonic08.cpp
+++ b/src/devices/bus/msx_slot/panasonic08.cpp
@@ -4,9 +4,9 @@
Emulation of the firmware mapper as found in Panasonic FS-A1WX andFS-A1WSX machines.
-Todo:
-- Anything besides the basic mapping
-- SRAM?
+TODO:
+- SRAM has only 2 4KB pages
+- SRAM is not accessible at 4000-7fff?
*/
#include "emu.h"
@@ -16,149 +16,130 @@ Todo:
DEFINE_DEVICE_TYPE(MSX_SLOT_PANASONIC08, msx_slot_panasonic08_device, "msx_slot_panasonic08", "MSX Internal Panasonic08")
-msx_slot_panasonic08_device::msx_slot_panasonic08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_panasonic08_device::msx_slot_panasonic08_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, MSX_SLOT_PANASONIC08, tag, owner, clock)
, msx_internal_slot_interface(mconfig, *this)
, m_nvram(*this, "nvram")
, m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_bank(*this, "bank%u", 0U)
+ , m_view0(*this, "view0")
+ , m_view1(*this, "view1")
+ , m_view3(*this, "view3")
+ , m_view4(*this, "view4")
+ , m_view5(*this, "view5")
, m_region_offset(0)
- , m_rom(nullptr)
, m_control(0)
{
- for (int i = 0; i < 8; i++)
- {
- m_selected_bank[i] = 0;
- m_bank_base[i] = nullptr;
- }
}
-
void msx_slot_panasonic08_device::device_add_mconfig(machine_config &config)
{
- NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
+ NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
}
-
void msx_slot_panasonic08_device::device_start()
{
// Sanity checks
if (m_rom_region->bytes() < m_region_offset + 0x200000)
{
- fatalerror("Memory region '%s' is too small for the FS4600 firmware\n", m_rom_region.finder_tag());
+ fatalerror("Memory region '%s' is too small for the panasonic08 firmware\n", m_rom_region.finder_tag());
}
- m_sram.resize(0x4000);
-
- m_nvram->set_base(&m_sram[0], 0x4000);
+ m_sram.resize(SRAM_SIZE);
- m_rom = m_rom_region->base() + m_region_offset;
+ m_nvram->set_base(&m_sram[0], SRAM_SIZE);
save_item(NAME(m_selected_bank));
save_item(NAME(m_control));
- restore_banks();
-}
-
+ for (int i = 0; i < 6; i++)
+ {
+ m_bank[i]->configure_entries(0, 0x100, m_rom_region->base() + m_region_offset, 0x2000);
+ m_bank[i]->configure_entry(0x80, m_sram.data());
+ m_bank[i]->configure_entry(0x81, m_sram.data() + 0x2000);
+ m_bank[i]->configure_entry(0x82, m_sram.data());
+ m_bank[i]->configure_entry(0x83, m_sram.data() + 0x2000);
+ }
-void msx_slot_panasonic08_device::device_post_load()
-{
- restore_banks();
+ page(0)->install_view(0x0000, 0x1fff, m_view0);
+ m_view0[0].install_read_bank(0x0000, 0x1fff, m_bank[0]);
+ m_view0[1].install_readwrite_bank(0x0000, 0x1fff, m_bank[0]);
+
+ page(0)->install_view(0x2000, 0x3fff, m_view1);
+ m_view1[0].install_read_bank(0x2000, 0x3fff, m_bank[1]);
+ m_view1[1].install_readwrite_bank(0x2000, 0x3fff, m_bank[1]);
+
+ // no sram writing in 4000-7fff?
+ page(1)->install_read_bank(0x4000, 0x5fff, m_bank[2]);
+
+ page(1)->install_view(0x6000, 0x7fff, m_view3);
+ m_view3[0].install_read_bank(0x6000, 0x7fff, m_bank[3]);
+ m_view3[1].install_read_bank(0x6000, 0x7fff, m_bank[3]);
+ m_view3[1].install_read_handler(0x7ff0, 0x7ff7, read8sm_delegate(*this, FUNC(msx_slot_panasonic08_device::bank_r)));
+ page(1)->install_write_handler(0x6000, 0x6000, write8smo_delegate(*this, FUNC(msx_slot_panasonic08_device::bank_w<0>)));
+ page(1)->install_write_handler(0x6400, 0x6400, write8smo_delegate(*this, FUNC(msx_slot_panasonic08_device::bank_w<1>)));
+ page(1)->install_write_handler(0x6800, 0x6800, write8smo_delegate(*this, FUNC(msx_slot_panasonic08_device::bank_w<2>)));
+ page(1)->install_write_handler(0x6c00, 0x6c00, write8smo_delegate(*this, FUNC(msx_slot_panasonic08_device::bank_w<3>)));
+ page(1)->install_write_handler(0x7000, 0x7000, write8smo_delegate(*this, FUNC(msx_slot_panasonic08_device::bank_w<4>)));
+ page(1)->install_write_handler(0x7800, 0x7800, write8smo_delegate(*this, FUNC(msx_slot_panasonic08_device::bank_w<5>)));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*this, FUNC(msx_slot_panasonic08_device::control_w)));
+
+ page(2)->install_view(0x8000, 0x9fff, m_view4);
+ m_view4[0].install_read_bank(0x8000, 0x9fff, m_bank[4]);
+ m_view4[1].install_readwrite_bank(0x8000, 0x9fff, m_bank[4]);
+
+ page(2)->install_view(0xa000, 0xbfff, m_view5);
+ m_view5[0].install_read_bank(0xa000, 0xbfff, m_bank[5]);
+ m_view5[1].install_readwrite_bank(0xa000, 0xbfff, m_bank[5]);
}
-
-void msx_slot_panasonic08_device::map_bank(int bank)
+void msx_slot_panasonic08_device::device_reset()
{
- if (m_selected_bank[bank] >= 0x80 && m_selected_bank[bank] < 0x84) // Are these banks were sram is present? Mirroring?
- {
- logerror("panasonic08: mapping bank %d to sram\n", bank);
- m_bank_base[bank] = &m_sram[((m_selected_bank[bank] & 0x7f) * 0x2000) & 0x3fff];
- }
- else
+ m_control = 0;
+ for (int i = 0 ; i < 6; i++)
{
- m_bank_base[bank] = m_rom + ( ( m_selected_bank[bank] * 0x2000 ) & 0x1fffff );
+ m_selected_bank[i] = 0;
+ m_bank[i]->set_entry(0);
}
+ m_view0.select(0);
+ m_view1.select(0);
+ m_view3.select(0);
+ m_view4.select(0);
+ m_view5.select(0);
}
-
-void msx_slot_panasonic08_device::restore_banks()
+template <int Bank>
+void msx_slot_panasonic08_device::set_view()
{
- for (int i = 0; i < 8; i++)
- {
- map_bank(i);
- }
+ bool ram_active = (m_selected_bank[Bank] >= 0x80 && m_selected_bank[Bank] < 0x84);
+ if (Bank == 0)
+ m_view0.select(ram_active ? 1 : 0);
+ if (Bank == 1)
+ m_view1.select(ram_active ? 1 : 0);
+ if (Bank == 3)
+ m_view3.select(BIT(m_control, 2) ? 1 : 0);
+ if (Bank == 4)
+ m_view4.select(ram_active ? 1 : 0);
+ if (Bank == 5)
+ m_view5.select(ram_active ? 1 : 0);
}
-
-uint8_t msx_slot_panasonic08_device::read(offs_t offset)
+template <int Bank>
+void msx_slot_panasonic08_device::bank_w(u8 data)
{
- if (m_control & 0x04)
- {
- // 7ff0 - 6000
- // 7ff1 - 6400
- // 7ff2 - 6800
- // 7ff3 - 6c00
- // 7ff4 - 7000
- // 7ff5 - 7800
- if (offset >= 0x7ff0 && offset < 0x7ff6) // maybe 7ff8 would make more sense here??
- {
- return m_selected_bank[offset - 0x7ff0];
- }
- }
- return m_bank_base[offset >> 13][offset & 0x1fff];
+ m_selected_bank[Bank] = data;
+ m_bank[Bank]->set_entry(data);
+ set_view<Bank>();
}
-
-void msx_slot_panasonic08_device::write(offs_t offset, uint8_t data)
+u8 msx_slot_panasonic08_device::bank_r(offs_t offset)
{
- if ((offset & 0xc000) == 0x8000 || (offset & 0xc000) == 0x0000)
- {
- uint8_t bank = m_selected_bank[offset >> 13];
- if (bank >= 0x80 && bank < 0x84) // Are these banks were sram is present? Mirroring?
- {
- logerror("msx_slot_panasonic08: writing %02x to sram %04x, bank = %02x\n", data, offset & 0x1fff, bank);
- m_sram[((bank & 0x01) * 0x2000) + (offset & 0x1fff)] = data;
- }
- return;
- }
+ return (offset < 6) ? m_selected_bank[offset] : 0;
+}
- switch (offset)
- {
- case 0x6000: /* Switched 0x0000-0x1FFF */
- m_selected_bank[0] = data;
- map_bank(0);
- break;
-
- case 0x6400: /* Switches 0x2000-0x3FFF */
- m_selected_bank[1] = data;
- map_bank(1);
- break;
-
- case 0x6800: /* Switches 0x4000-0x5FFF */
- m_selected_bank[2] = data;
- map_bank(2);
- break;
-
- case 0x6c00: /* Switches 0x6000-0x7FFF */
- m_selected_bank[3] = data;
- map_bank(3);
- break;
-
- case 0x7000: /* Switches 0x8000-0x9FFF */
- m_selected_bank[4] = data;
- map_bank(4);
- break;
-
- case 0x7800: /* Switches 0xA000-0xBFFF */
- m_selected_bank[5] = data;
- map_bank(5);
- break;
-
- case 0x7ff9:
- m_control = data;
- break;
-
- default:
- logerror("msx_slot_panasonic08: Unhandled write %02x to %04x\n", data, offset);
- break;
- }
+void msx_slot_panasonic08_device::control_w(u8 data)
+{
+ // writing $04 enables read back of banking registers at 7ff0-7ff5
+ m_control = data;
+ set_view<3>();
}
diff --git a/src/devices/bus/msx_slot/panasonic08.h b/src/devices/bus/msx_slot/panasonic08.h
index b21a4964e3b..4357b4e8ad0 100644
--- a/src/devices/bus/msx_slot/panasonic08.h
+++ b/src/devices/bus/msx_slot/panasonic08.h
@@ -15,31 +15,36 @@ DECLARE_DEVICE_TYPE(MSX_SLOT_PANASONIC08, msx_slot_panasonic08_device)
class msx_slot_panasonic08_device : public device_t, public msx_internal_slot_interface
{
public:
- msx_slot_panasonic08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_panasonic08_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
- void set_rom_start(const char *region, uint32_t offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
-
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+ void set_rom_start(const char *region, u32 offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
protected:
virtual void device_start() override;
- virtual void device_post_load() override;
+ virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
private:
- void restore_banks();
- void map_bank(int bank);
+ static constexpr size_t SRAM_SIZE = 0x4000;
+
+ template <int Bank> void set_view();
+ template <int Bank> void bank_w(u8 data);
+ u8 bank_r(offs_t offset);
+ void control_w(u8 data);
required_device<nvram_device> m_nvram;
required_memory_region m_rom_region;
- uint32_t m_region_offset;
- const uint8_t *m_rom;
- uint8_t m_selected_bank[8];
- const uint8_t *m_bank_base[8];
- uint8_t m_control;
+ memory_bank_array_creator<6> m_bank;
+ memory_view m_view0;
+ memory_view m_view1;
+ memory_view m_view3;
+ memory_view m_view4;
+ memory_view m_view5;
+ u32 m_region_offset;
+ u8 m_selected_bank[6];
+ u8 m_control;
std::vector<uint8_t> m_sram;
};
diff --git a/src/devices/bus/msx_slot/ram.cpp b/src/devices/bus/msx_slot/ram.cpp
index 835a5551b92..92f9a57929d 100644
--- a/src/devices/bus/msx_slot/ram.cpp
+++ b/src/devices/bus/msx_slot/ram.cpp
@@ -6,7 +6,7 @@
DEFINE_DEVICE_TYPE(MSX_SLOT_RAM, msx_slot_ram_device, "msx_slot_ram", "MSX Internal RAM")
-msx_slot_ram_device::msx_slot_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_ram_device::msx_slot_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, MSX_SLOT_RAM, tag, owner, clock)
, msx_internal_slot_interface(mconfig, *this)
{
@@ -16,21 +16,13 @@ void msx_slot_ram_device::device_start()
{
m_ram.resize(m_size);
save_item(NAME(m_ram));
-}
-uint8_t msx_slot_ram_device::read(offs_t offset)
-{
- if ( offset >= m_start_address && offset < m_end_address )
- {
- return m_ram[ offset - m_start_address ];
- }
- return 0xFF;
-}
-
-void msx_slot_ram_device::write(offs_t offset, uint8_t data)
-{
- if ( offset >= m_start_address && offset < m_end_address )
+ u8 *ram = m_ram.data();
+ u32 start_address = m_start_address;
+ for (int i = m_start_address >> 14; i < 4 && i * 0x4000 < m_end_address; i++)
{
- m_ram[offset - m_start_address] = data;
+ page(i)->install_ram(start_address, std::min<u32>((i + 1) * 0x4000, m_end_address) - 1, ram);
+ start_address += 0x4000;
+ ram += 0x4000;
}
}
diff --git a/src/devices/bus/msx_slot/ram.h b/src/devices/bus/msx_slot/ram.h
index f96271ad066..9e8f08bc373 100644
--- a/src/devices/bus/msx_slot/ram.h
+++ b/src/devices/bus/msx_slot/ram.h
@@ -3,25 +3,24 @@
#ifndef MAME_BUS_MSX_SLOT_RAM_H
#define MAME_BUS_MSX_SLOT_RAM_H
+#pragma once
+
#include "slot.h"
class msx_slot_ram_device : public device_t,
public msx_internal_slot_interface
{
public:
- msx_slot_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// Set to 0xe000 for 8KB RAM
- void force_start_address(uint16_t start) { m_start_address = start; }
-
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+ void force_start_address(u16 start) { m_start_address = start; }
protected:
virtual void device_start() override;
private:
- std::vector<uint8_t> m_ram;
+ std::vector<u8> m_ram;
};
diff --git a/src/devices/bus/msx_slot/ram_mm.cpp b/src/devices/bus/msx_slot/ram_mm.cpp
index 84498f9afe1..24ef1b26fce 100644
--- a/src/devices/bus/msx_slot/ram_mm.cpp
+++ b/src/devices/bus/msx_slot/ram_mm.cpp
@@ -5,12 +5,13 @@
DEFINE_DEVICE_TYPE(MSX_SLOT_RAM_MM, msx_slot_ram_mm_device, "msx_slot_ram_mm", "MSX Internal Memory Mapped RAM")
-msx_slot_ram_mm_device::msx_slot_ram_mm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_ram_mm_device::msx_slot_ram_mm_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, MSX_SLOT_RAM_MM, tag, owner, clock)
, msx_internal_slot_interface(mconfig, *this)
, m_total_size(0)
, m_bank_mask(0)
, m_ramio_set_bits(0)
+ , m_rambank(*this, "mmbank%u", 0U)
{
}
@@ -21,62 +22,34 @@ void msx_slot_ram_mm_device::device_start()
{
case 64*1024: m_bank_mask = 0x03; break;
case 128*1024: m_bank_mask = 0x07; break;
- case 256*1024: m_bank_mask = 0x0F; break;
- case 512*1024: m_bank_mask = 0x1F; break;
- case 1024*1024: m_bank_mask = 0x3F; break;
- case 2048*1024: m_bank_mask = 0x7F; break;
- case 4096*1024: m_bank_mask = 0xFF; break;
+ case 256*1024: m_bank_mask = 0x0f; break;
+ case 512*1024: m_bank_mask = 0x1f; break;
+ case 1024*1024: m_bank_mask = 0x3f; break;
+ case 2048*1024: m_bank_mask = 0x7f; break;
+ case 4096*1024: m_bank_mask = 0xff; break;
default: fatalerror("Invalid memory mapper size specified\n");
}
m_ram.resize(m_total_size);
- for ( int i = 0; i < 4; i++ )
- {
- m_bank_selected[i] = 3 -i;
- m_bank_base[i] = &m_ram[0x4000 * m_bank_selected[i]];
- }
-
save_item(NAME(m_ram));
- save_item(NAME(m_bank_selected));
// Install IO read/write handlers
- io_space().install_read_handler(0xFC, 0xFF, read8sm_delegate(*this, FUNC(msx_slot_ram_mm_device::read_mapper_bank)));
- io_space().install_write_handler(0xFC, 0xFF, write8sm_delegate(*this, FUNC(msx_slot_ram_mm_device::write_mapper_bank)));
-}
-
-void msx_slot_ram_mm_device::device_post_load()
-{
- restore_banks();
-}
-
-void msx_slot_ram_mm_device::restore_banks()
-{
- for ( int i = 0; i < 3; i++ )
+ io_space().install_read_handler(0xfc, 0xff, read8sm_delegate(*this, FUNC(msx_slot_ram_mm_device::read_mapper_bank)));
+ io_space().install_write_handler(0xfc, 0xff, write8sm_delegate(*this, FUNC(msx_slot_ram_mm_device::write_mapper_bank)));
+ for (int i = 0; i < 4; i++)
{
- m_bank_base[i] = &m_ram[0x4000 * ( m_bank_selected[i] & m_bank_mask )];
+ m_rambank[i]->configure_entries(0, u32(m_bank_mask) + 1, m_ram.data(), 0x4000);
+ page(i)->install_readwrite_bank(0x4000 * i, (0x4000 * i) + 0x3fff, m_rambank[i]);
}
}
-uint8_t msx_slot_ram_mm_device::read(offs_t offset)
-{
- return m_bank_base[offset >> 14][offset & 0x3fff];
-}
-
-void msx_slot_ram_mm_device::write(offs_t offset, uint8_t data)
+u8 msx_slot_ram_mm_device::read_mapper_bank(offs_t offset)
{
- m_bank_base[offset >> 14][offset & 0x3fff] = data;
+ return m_rambank[offset & 3]->entry() | m_ramio_set_bits;
}
-uint8_t msx_slot_ram_mm_device::read_mapper_bank(offs_t offset)
+void msx_slot_ram_mm_device::write_mapper_bank(offs_t offset, u8 data)
{
- return m_bank_selected[offset & 3] | m_ramio_set_bits;
-}
-
-void msx_slot_ram_mm_device::write_mapper_bank(offs_t offset, uint8_t data)
-{
- offset &= 3;
-
- m_bank_selected[offset] = data;
- m_bank_base[offset] = &m_ram[0x4000 * ( m_bank_selected[offset] & m_bank_mask )];
+ m_rambank[offset & 0x03]->set_entry(data & m_bank_mask);
}
diff --git a/src/devices/bus/msx_slot/ram_mm.h b/src/devices/bus/msx_slot/ram_mm.h
index 55f13659a4c..4fb95109323 100644
--- a/src/devices/bus/msx_slot/ram_mm.h
+++ b/src/devices/bus/msx_slot/ram_mm.h
@@ -3,35 +3,30 @@
#ifndef MAME_BUS_MSX_SLOT_RAM_MM_H
#define MAME_BUS_MSX_SLOT_RAM_MM_H
+#pragma once
+
#include "slot.h"
class msx_slot_ram_mm_device : public device_t, public msx_internal_slot_interface
{
public:
- msx_slot_ram_mm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
- msx_slot_ram_mm_device &set_total_size(uint32_t total_size) { m_total_size = total_size; return *this; }
- msx_slot_ram_mm_device &set_ramio_bits(uint8_t ramio_set_bits) { m_ramio_set_bits = ramio_set_bits; return *this; }
+ msx_slot_ram_mm_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+ msx_slot_ram_mm_device &set_total_size(u32 total_size) { m_total_size = total_size; return *this; }
+ msx_slot_ram_mm_device &set_ramio_bits(u8 ramio_set_bits) { m_ramio_set_bits = ramio_set_bits; return *this; }
protected:
virtual void device_start() override;
- virtual void device_post_load() override;
-
- void restore_banks();
private:
- uint8_t read_mapper_bank(offs_t offset);
- void write_mapper_bank(offs_t offset, uint8_t data);
-
- std::vector<uint8_t> m_ram;
- uint32_t m_total_size;
- uint8_t m_bank_mask;
- uint8_t m_bank_selected[4];
- uint8_t *m_bank_base[4];
- uint8_t m_ramio_set_bits;
+ u8 read_mapper_bank(offs_t offset);
+ void write_mapper_bank(offs_t offset, u8 data);
+
+ std::vector<u8> m_ram;
+ u32 m_total_size;
+ u8 m_bank_mask;
+ u8 m_ramio_set_bits;
+ memory_bank_array_creator<4> m_rambank;
};
DECLARE_DEVICE_TYPE(MSX_SLOT_RAM_MM, msx_slot_ram_mm_device)
diff --git a/src/devices/bus/msx_slot/rom.cpp b/src/devices/bus/msx_slot/rom.cpp
index aafc37b345b..783e4313f30 100644
--- a/src/devices/bus/msx_slot/rom.cpp
+++ b/src/devices/bus/msx_slot/rom.cpp
@@ -7,22 +7,19 @@
DEFINE_DEVICE_TYPE(MSX_SLOT_ROM, msx_slot_rom_device, "msx_slot_rom", "MSX Internal ROM")
-msx_slot_rom_device::msx_slot_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_rom_device::msx_slot_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: msx_slot_rom_device(mconfig, MSX_SLOT_ROM, tag, owner, clock)
{
}
-
-msx_slot_rom_device::msx_slot_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_rom_device::msx_slot_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, msx_internal_slot_interface(mconfig, *this)
, m_rom_region(*this, finder_base::DUMMY_TAG)
, m_region_offset(0)
- , m_rom(nullptr)
{
}
-
void msx_slot_rom_device::device_start()
{
// Sanity checks
@@ -31,15 +28,10 @@ void msx_slot_rom_device::device_start()
fatalerror("Memory region '%s' is too small for rom slot '%s'\n", m_rom_region.finder_tag(), tag());
}
- m_rom = m_rom_region->base() + m_region_offset;
-}
-
-
-uint8_t msx_slot_rom_device::read(offs_t offset)
-{
- if (offset >= m_start_address && offset < m_end_address)
+ u8 *rom = m_rom_region->base() + m_region_offset;
+ for (int i = m_start_address >> 14; i < 4 && i * 0x4000 < m_end_address; i++)
{
- return m_rom[offset - m_start_address];
+ page(i)->install_rom(i * 0x4000, std::min<u32>((i + 1) * 0x4000, m_end_address) - 1, rom);
+ rom += 0x4000;
}
- return 0xFF;
}
diff --git a/src/devices/bus/msx_slot/rom.h b/src/devices/bus/msx_slot/rom.h
index 6bcd480a5a3..698487dae3f 100644
--- a/src/devices/bus/msx_slot/rom.h
+++ b/src/devices/bus/msx_slot/rom.h
@@ -11,22 +11,19 @@ class msx_slot_rom_device : public device_t,
public msx_internal_slot_interface
{
public:
- msx_slot_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
void set_rom_start(const char *region, uint32_t offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
- virtual uint8_t read(offs_t offset) override;
-
protected:
- msx_slot_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
virtual void device_start() override;
+ u8 *rom_base() { return m_rom_region->base() + m_region_offset; }
-private:
required_memory_region m_rom_region;
- uint32_t m_region_offset;
- const uint8_t *m_rom;
+ u32 m_region_offset;
};
DECLARE_DEVICE_TYPE(MSX_SLOT_ROM, msx_slot_rom_device)
diff --git a/src/devices/bus/msx_slot/slot.cpp b/src/devices/bus/msx_slot/slot.cpp
index 345cf6e0a5c..31c49773622 100644
--- a/src/devices/bus/msx_slot/slot.cpp
+++ b/src/devices/bus/msx_slot/slot.cpp
@@ -16,9 +16,19 @@ pages; and multiple pieces of rom/ram/components can occur in a single slot.
msx_internal_slot_interface::msx_internal_slot_interface(const machine_config &mconfig, device_t &device)
: m_mem_space(device, finder_base::DUMMY_TAG, -1)
, m_io_space(device, finder_base::DUMMY_TAG, -1)
+ , m_maincpu(device, finder_base::DUMMY_TAG)
, m_start_address(0)
, m_size(0)
, m_end_address(0)
+ , m_page{nullptr, nullptr, nullptr, nullptr}
{
(void)mconfig;
}
+
+void msx_internal_slot_interface::install(memory_view::memory_view_entry *page0, memory_view::memory_view_entry *page1, memory_view::memory_view_entry *page2, memory_view::memory_view_entry *page3)
+{
+ m_page[0] = page0;
+ m_page[1] = page1;
+ m_page[2] = page2;
+ m_page[3] = page3;
+}
diff --git a/src/devices/bus/msx_slot/slot.h b/src/devices/bus/msx_slot/slot.h
index 3a95c7b6b75..295f6e45e6d 100644
--- a/src/devices/bus/msx_slot/slot.h
+++ b/src/devices/bus/msx_slot/slot.h
@@ -25,22 +25,33 @@ public:
// configuration helpers
template <typename T> void set_memory_space(T &&tag, int spacenum) { m_mem_space.set_tag(std::forward<T>(tag), spacenum); }
template <typename T> void set_io_space(T &&tag, int spacenum) { m_io_space.set_tag(std::forward<T>(tag), spacenum); }
- void set_start_address(uint32_t start_address) { m_start_address = start_address; m_end_address = m_start_address + m_size; }
- void set_size(uint32_t size) { m_size = size; m_end_address = m_start_address + m_size; }
+ template <typename T> void set_maincpu(T &&tag) { m_maincpu.set_tag(std::forward<T>(tag)); }
+ void set_start_address(u32 start_address) { m_start_address = start_address; m_end_address = m_start_address + m_size; }
+ void set_size(u32 size) { m_size = size; m_end_address = m_start_address + m_size; }
- virtual uint8_t read(offs_t offset) { return 0xFF; }
- virtual void write(offs_t offset, uint8_t data) { }
+ void install(memory_view::memory_view_entry *page0, memory_view::memory_view_entry *page1, memory_view::memory_view_entry *page2, memory_view::memory_view_entry *page3);
address_space &memory_space() const { return *m_mem_space; }
address_space &io_space() const { return *m_io_space; }
+ cpu_device &maincpu() const { return *m_maincpu; }
+ bool page_configured(int i) { return bool(m_page[i]); }
+ memory_view::memory_view_entry *page(int i)
+ {
+ if (!m_page[i])
+ fatalerror("page %i view not configured\n", i);
+ return m_page[i];
+ }
protected:
required_address_space m_mem_space;
required_address_space m_io_space;
+ required_device<cpu_device> m_maincpu;
- uint32_t m_start_address;
- uint32_t m_size;
- uint32_t m_end_address;
+ u32 m_start_address;
+ u32 m_size;
+ u32 m_end_address;
+
+ memory_view::memory_view_entry *m_page[4];
};
#endif // MAME_BUS_MSX_SLOT_SLOT_H
diff --git a/src/devices/bus/msx_slot/sony08.cpp b/src/devices/bus/msx_slot/sony08.cpp
index 652ed134457..4030b0ccb6a 100644
--- a/src/devices/bus/msx_slot/sony08.cpp
+++ b/src/devices/bus/msx_slot/sony08.cpp
@@ -13,29 +13,24 @@
DEFINE_DEVICE_TYPE(MSX_SLOT_SONY08, msx_slot_sony08_device, "msx_slot_sony08", "MSX Internal SONY08")
-msx_slot_sony08_device::msx_slot_sony08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+msx_slot_sony08_device::msx_slot_sony08_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, MSX_SLOT_SONY08, tag, owner, clock)
, msx_internal_slot_interface(mconfig, *this)
, m_nvram(*this, "nvram")
, m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_rombank(*this, "rombank%u", 0U)
+ , m_view0(*this, "view0")
+ , m_view1(*this, "view1")
, m_region_offset(0)
- , m_rom(nullptr)
{
- for (int i = 0; i < 8; i++)
- {
- m_selected_bank[i] = 0;
- m_bank_base[i] = nullptr;
- }
- memset(m_sram, 0, sizeof(m_sram));
}
void msx_slot_sony08_device::device_add_mconfig(machine_config &config)
{
- NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
+ NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
}
-
void msx_slot_sony08_device::device_start()
{
// Sanity checks
@@ -44,129 +39,52 @@ void msx_slot_sony08_device::device_start()
fatalerror("Memory region '%s' is too small for the SONY08 firmware\n", m_rom_region.finder_tag());
}
- m_rom = m_rom_region->base() + m_region_offset;
-
- m_nvram->set_base(m_sram, 0x4000);
-
- save_item(NAME(m_selected_bank));
-
- restore_banks();
-}
-
-
-void msx_slot_sony08_device::device_post_load()
-{
- restore_banks();
-}
-
-
-void msx_slot_sony08_device::map_bank(int bank)
-{
- if (bank < 2)
- {
- return;
- }
-
- // Special banks
- if (bank == 6 || bank == 7)
- {
- m_bank_base[bank] = m_rom + 0x80000 + (m_selected_bank[bank] * 0x800);
- return;
- }
-
- m_bank_base[bank] = m_rom + ((m_selected_bank[bank] * 0x2000) & 0xFFFFF);
- if (bank == 2)
- {
- if (m_selected_bank[bank] & 0x80)
- {
- m_bank_base[0] = m_sram;
- m_bank_base[1] = m_sram + 0x2000;
- }
- else
- {
- m_bank_base[0] = nullptr;
- m_bank_base[1] = nullptr;
- }
- }
-}
-
-
-void msx_slot_sony08_device::restore_banks()
-{
- for (int i = 0; i < 8; i++)
- {
- map_bank(i);
- }
+ m_sram.resize(SRAM_SIZE);
+ m_nvram->set_base(m_sram.data(), SRAM_SIZE);
+
+ for (int i = 0; i < 4; i++)
+ m_rombank[i]->configure_entries(0, 0x80, m_rom_region->base() + m_region_offset, 0x2000);
+ m_rombank[4]->configure_entries(0, 0x100, m_rom_region->base() + m_region_offset + 0x80000, 0x800);
+ m_rombank[5]->configure_entries(0, 0x100, m_rom_region->base() + m_region_offset + 0x80000, 0x800);
+
+ page(0)->install_view(0x0000, 0x3fff, m_view0);
+ m_view0[0];
+ m_view0[1].install_ram(0x0000, 0x3fff, m_sram.data());
+
+ page(1)->install_read_bank(0x4000, 0x5fff, m_rombank[0]);
+ page(1)->install_write_handler(0x4fff, 0x4fff, write8smo_delegate(*this, FUNC(msx_slot_sony08_device::bank_w<0>)));
+ page(1)->install_view(0x6000, 0x7fff, m_view1);
+ m_view1[0].install_read_bank(0x6000, 0x7fff, m_rombank[1]);
+ m_view1[1].install_read_bank(0x6000, 0x6fff, m_rombank[1]);
+ m_view1[1].install_read_bank(0x7000, 0x77ff, m_rombank[4]);
+ m_view1[1].install_read_bank(0x7800, 0x7fff, m_rombank[5]);
+ page(1)->install_write_handler(0x6fff, 0x6fff, write8smo_delegate(*this, FUNC(msx_slot_sony08_device::bank_w<1>)));
+ page(1)->install_write_handler(0x77ff, 0x77ff, write8smo_delegate(*this, FUNC(msx_slot_sony08_device::bank_w<4>)));
+ page(1)->install_write_handler(0x7fff, 0x7fff, write8smo_delegate(*this, FUNC(msx_slot_sony08_device::bank_w<5>)));
+ page(2)->install_read_bank(0x8000, 0x9fff, m_rombank[2]);
+ page(2)->install_write_handler(0x8fff, 0x8fff, write8smo_delegate(*this, FUNC(msx_slot_sony08_device::bank_w<2>)));
+ page(2)->install_read_bank(0xa000, 0xbfff, m_rombank[3]);
+ page(2)->install_write_handler(0xafff, 0xafff, write8smo_delegate(*this, FUNC(msx_slot_sony08_device::bank_w<3>)));
}
-
-uint8_t msx_slot_sony08_device::read(offs_t offset)
+void msx_slot_sony08_device::device_reset()
{
- if (offset >= 0xc000)
- {
- return 0xFF;
- }
-
- if ((offset & 0xf000) == 0x7000 && (m_selected_bank[3] & 0x80))
- {
- return m_bank_base[6 + ((offset >> 11) & 0x01)][offset & 0x7ff];
- }
-
- const uint8_t *mem = m_bank_base[offset >> 13];
-
- if (mem)
- {
- return mem[offset & 0x1fff];
- }
- return 0xFF;
+ m_view0.select(0);
+ m_view1.select(0);
+ for (int i = 0; i < 6; i++)
+ m_rombank[i]->set_entry(0);
}
-
-void msx_slot_sony08_device::write(offs_t offset, uint8_t data)
+template <int Bank>
+void msx_slot_sony08_device::bank_w(u8 data)
{
- if (offset < 0x4000)
- {
- if (m_bank_base[0] != nullptr)
- {
- m_sram[offset & 0x3fff] = data;
- return;
- }
- }
-
- switch (offset)
- {
- case 0x4FFF:
- m_selected_bank[2] = data;
- map_bank(2);
- break;
-
- case 0x6FFF: // 6000-7FFF
- m_selected_bank[3] = data;
- map_bank(3);
- break;
-
- case 0x77FF:
- m_selected_bank[6] = data;
- map_bank(6);
- break;
-
- case 0x7FFF:
- m_selected_bank[7] = data;
- map_bank(7);
- break;
-
- case 0x8FFF:
- m_selected_bank[4] = data;
- map_bank(4);
- break;
-
- case 0xAFFF:
- m_selected_bank[5] = data;
- map_bank(5);
- break;
-
- default:
- logerror("Unhandled write %02x to %04x\n", data, offset);
- break;
- }
+ if (Bank >= 4)
+ m_rombank[Bank]->set_entry(data);
+ else
+ m_rombank[Bank]->set_entry(data & 0x7f);
+
+ if (Bank == 0)
+ m_view0.select(BIT(data, 7) ? 1 : 0);
+ if (Bank == 1)
+ m_view1.select(BIT(data, 7) ? 1 : 0);
}
diff --git a/src/devices/bus/msx_slot/sony08.h b/src/devices/bus/msx_slot/sony08.h
index 74c8fd95f35..22538a74a18 100644
--- a/src/devices/bus/msx_slot/sony08.h
+++ b/src/devices/bus/msx_slot/sony08.h
@@ -15,32 +15,29 @@ DECLARE_DEVICE_TYPE(MSX_SLOT_SONY08, msx_slot_sony08_device)
class msx_slot_sony08_device : public device_t, public msx_internal_slot_interface
{
public:
- msx_slot_sony08_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ msx_slot_sony08_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
// configuration helpers
- void set_rom_start(const char *region, uint32_t offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
-
- virtual uint8_t read(offs_t offset) override;
- virtual void write(offs_t offset, uint8_t data) override;
+ void set_rom_start(const char *region, u32 offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
protected:
virtual void device_start() override;
- virtual void device_post_load() override;
+ virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
- void restore_banks();
-
private:
+ static constexpr size_t SRAM_SIZE = 0x4000;
+
+ template <int Bank> void bank_w(u8 data);
+
required_device<nvram_device> m_nvram;
required_memory_region m_rom_region;
- uint32_t m_region_offset;
- const uint8_t *m_rom;
- uint8_t m_selected_bank[8];
- const uint8_t *m_bank_base[8];
- uint8_t m_sram[0x4000];
-
- void map_bank(int bank);
+ memory_bank_array_creator<6> m_rombank;
+ memory_view m_view0;
+ memory_view m_view1;
+ u32 m_region_offset;
+ std::vector<u8> m_sram;
};