diff options
author | 2022-11-08 04:00:55 +0000 | |
---|---|---|
committer | 2022-11-08 15:00:55 +1100 | |
commit | ac4af4b16b5790448728a0fb95cc8ca5939d2f40 (patch) | |
tree | 017f0f42a65072d04fceaba87180f19d327add41 /src/devices/bus | |
parent | da85ebae03454a3c35063199e8249ea86a318db0 (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')
84 files changed, 4624 insertions, 4020 deletions
diff --git a/src/devices/bus/msx_cart/arc.cpp b/src/devices/bus/msx_cart/arc.cpp index 6f5af572bd1..45d31457690 100644 --- a/src/devices/bus/msx_cart/arc.cpp +++ b/src/devices/bus/msx_cart/arc.cpp @@ -14,50 +14,38 @@ msx_cart_arc_device::msx_cart_arc_device(const machine_config &mconfig, const ch { } - void msx_cart_arc_device::device_start() { + save_item(NAME(m_7f)); + // Install IO read/write handlers io_space().install_write_handler(0x7f, 0x7f, write8smo_delegate(*this, FUNC(msx_cart_arc_device::io_7f_w))); io_space().install_read_handler(0x7f, 0x7f, read8smo_delegate(*this, FUNC(msx_cart_arc_device::io_7f_r))); } - void msx_cart_arc_device::device_reset() { m_7f = 0; } - void msx_cart_arc_device::initialize_cartridge() { if (get_rom_size() != 0x8000) { fatalerror("arc: Invalid ROM size\n"); } -} - -uint8_t msx_cart_arc_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000) - { - return get_rom_base()[offset - 0x4000]; - } - return 0xff; + page(1)->install_rom(0x4000, 0x7fff, get_rom_base()); + page(2)->install_rom(0x8000, 0xbfff, get_rom_base() + 0x4000); } - -void msx_cart_arc_device::io_7f_w(uint8_t data) +void msx_cart_arc_device::io_7f_w(u8 data) { if (data == 0x35) - { m_7f++; - } } - -uint8_t msx_cart_arc_device::io_7f_r() +u8 msx_cart_arc_device::io_7f_r() { return ((m_7f & 0x03) == 0x03) ? 0xda : 0xff; } diff --git a/src/devices/bus/msx_cart/arc.h b/src/devices/bus/msx_cart/arc.h index 69f4427a01f..a7a31a1e285 100644 --- a/src/devices/bus/msx_cart/arc.h +++ b/src/devices/bus/msx_cart/arc.h @@ -14,22 +14,20 @@ DECLARE_DEVICE_TYPE(MSX_CART_ARC, msx_cart_arc_device) class msx_cart_arc_device : public device_t, public msx_cart_interface { public: - msx_cart_arc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_arc_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; private: - void io_7f_w(uint8_t data); - uint8_t io_7f_r(); + void io_7f_w(u8 data); + u8 io_7f_r(); - uint8_t m_7f; + u8 m_7f; }; #endif // MAME_BUS_MSX_CART_ARC_H diff --git a/src/devices/bus/msx_cart/ascii.cpp b/src/devices/bus/msx_cart/ascii.cpp index 7d1b354b404..f183afca6f1 100644 --- a/src/devices/bus/msx_cart/ascii.cpp +++ b/src/devices/bus/msx_cart/ascii.cpp @@ -8,266 +8,125 @@ DEFINE_DEVICE_TYPE(MSX_CART_ASCII8, msx_cart_ascii8_device, "msx_car DEFINE_DEVICE_TYPE(MSX_CART_ASCII16, msx_cart_ascii16_device, "msx_cart_ascii16", "MSX Cartridge - ASCII16") DEFINE_DEVICE_TYPE(MSX_CART_ASCII8_SRAM, msx_cart_ascii8_sram_device, "msx_cart_ascii8_sram", "MSX Cartridge - ASCII8 w/SRAM") DEFINE_DEVICE_TYPE(MSX_CART_ASCII16_SRAM, msx_cart_ascii16_sram_device, "msx_cart_ascii16_sram", "MSX Cartridge - ASCII16 w/SRAM") -DEFINE_DEVICE_TYPE(MSX_CART_MSXWRITE, msx_cart_msxwrite_device, "msx_cart_msxwrite", "MSX Cartridge - MSXWRITE") -msx_cart_ascii8_device::msx_cart_ascii8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_ascii8_device::msx_cart_ascii8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_ASCII8, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) , m_bank_mask(0) { - for (int i = 0; i < 4; i++) - { - m_selected_bank[i] = 0; - m_bank_base[i] = nullptr; - } -} - - -void msx_cart_ascii8_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_ascii8_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_ascii8_device::restore_banks() -{ - for (int i = 0; i < 4; i++) - { - m_bank_base[i] = get_rom_base() + (m_selected_bank[i] & m_bank_mask ) * 0x2000; - } } - void msx_cart_ascii8_device::device_reset() { - for (auto & elem : m_selected_bank) - { - elem = 0; - } + for (int i = 0; i < 4; i++) + m_rombank[i]->set_entry(0); } - void msx_cart_ascii8_device::initialize_cartridge() { - uint32_t size = get_rom_size(); + u32 size = get_rom_size(); + u16 banks = size / BANK_SIZE; - if ( size > 256 * 0x2000 ) - { - fatalerror("ascii8: ROM is too big\n"); - } - - uint16_t banks = size / 0x2000; - - if (size != banks * 0x2000 || (~(banks - 1) % banks)) + if (size > 256 * BANK_SIZE || size != banks * BANK_SIZE || (~(banks - 1) % banks)) { fatalerror("ascii8: Invalid ROM size\n"); } m_bank_mask = banks - 1; - restore_banks(); -} - + for (int i = 0; i < 4; i++) + m_rombank[i]->configure_entries(0, banks, get_rom_base(), BANK_SIZE); -uint8_t msx_cart_ascii8_device::read_cart(offs_t offset) -{ - if ( offset >= 0x4000 && offset < 0xC000 ) - { - return m_bank_base[(offset - 0x4000) >> 13][offset & 0x1fff]; - } - return 0xff; + 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, 0x67ff, write8smo_delegate(*this, FUNC(msx_cart_ascii8_device::bank_w<0>))); + page(1)->install_write_handler(0x6800, 0x6fff, write8smo_delegate(*this, FUNC(msx_cart_ascii8_device::bank_w<1>))); + page(1)->install_write_handler(0x7000, 0x77ff, write8smo_delegate(*this, FUNC(msx_cart_ascii8_device::bank_w<2>))); + page(1)->install_write_handler(0x7800, 0x7fff, write8smo_delegate(*this, FUNC(msx_cart_ascii8_device::bank_w<3>))); + page(2)->install_read_bank(0x8000, 0x9fff, m_rombank[2]); + page(2)->install_read_bank(0xa000, 0xbfff, m_rombank[3]); } - -void msx_cart_ascii8_device::write_cart(offs_t offset, uint8_t data) +template <int Bank> +void msx_cart_ascii8_device::bank_w(u8 data) { - if (offset >= 0x6000 && offset < 0x8000) - { - uint8_t bank = (offset / 0x800) & 0x03; - - m_selected_bank[bank] = data; - m_bank_base[bank] = get_rom_base() + (m_selected_bank[bank] & m_bank_mask ) * 0x2000; - } + m_rombank[Bank]->set_entry(data & m_bank_mask); } -msx_cart_ascii16_device::msx_cart_ascii16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_ascii16_device::msx_cart_ascii16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_ASCII16, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) , m_bank_mask(0) { - for (int i = 0; i < 2; i++) - { - m_selected_bank[i] = 0; - m_bank_base[i] = nullptr; - } -} - - -void msx_cart_ascii16_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_ascii16_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_ascii16_device::restore_banks() -{ - for (int i = 0; i < 2; i++) - { - m_bank_base[i] = get_rom_base() + (m_selected_bank[i] & m_bank_mask) * 0x4000; - } } - void msx_cart_ascii16_device::device_reset() { - for (auto & elem : m_selected_bank) - { - elem = 0; - } + m_rombank[0]->set_entry(0); + m_rombank[1]->set_entry(0); } - void msx_cart_ascii16_device::initialize_cartridge() { - uint32_t size = get_rom_size(); - - if ( size > 256 * 0x4000 ) - { - fatalerror("ascii16: ROM is too big\n"); - } - - uint16_t banks = size / 0x4000; + u32 size = get_rom_size(); + u16 banks = size / BANK_SIZE; - if (size != banks * 0x4000 || (~(banks - 1) % banks)) + if (size > 256 * BANK_SIZE || size != banks * BANK_SIZE || (~(banks - 1) % banks)) { fatalerror("ascii16: Invalid ROM size\n"); } m_bank_mask = banks - 1; - restore_banks(); -} - + for (int i = 0; i < 2; i++) + m_rombank[i]->configure_entries(0, banks, get_rom_base(), BANK_SIZE); -uint8_t msx_cart_ascii16_device::read_cart(offs_t offset) -{ - if ( offset >= 0x4000 && offset < 0xC000 ) - { - return m_bank_base[offset >> 15][offset & 0x3fff]; - } - return 0xff; + page(1)->install_read_bank(0x4000, 0x7fff, m_rombank[0]); + page(1)->install_write_handler(0x6000, 0x67ff, write8smo_delegate(*this, FUNC(msx_cart_ascii16_device::bank_w<0>))); + page(1)->install_write_handler(0x7000, 0x77ff, write8smo_delegate(*this, FUNC(msx_cart_ascii16_device::bank_w<1>))); + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank[1]); } - -void msx_cart_ascii16_device::write_cart(offs_t offset, uint8_t data) +template <int Bank> +void msx_cart_ascii16_device::bank_w(u8 data) { - if (offset >= 0x6000 && offset < 0x6800) - { - m_selected_bank[0] = data; - m_bank_base[0] = get_rom_base() + (m_selected_bank[0] & m_bank_mask) * 0x4000; - } - - if (offset >= 0x7000 && offset < 0x7800) - { - m_selected_bank[1] = data; - m_bank_base[1] = get_rom_base() + (m_selected_bank[1] & m_bank_mask) * 0x4000; - } + m_rombank[Bank]->set_entry(data & m_bank_mask); } -msx_cart_ascii8_sram_device::msx_cart_ascii8_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_ascii8_sram_device::msx_cart_ascii8_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_ASCII8_SRAM, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) + , m_view2(*this, "view2") + , m_view3(*this, "view3") , m_bank_mask(0) , m_sram_select_mask(0) { - for (int i = 0; i < 4; i++) - { - m_selected_bank[i] = 0; - m_bank_base[i] = nullptr; - } -} - - -void msx_cart_ascii8_sram_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_ascii8_sram_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_ascii8_sram_device::setup_bank(uint8_t bank) -{ - if (m_selected_bank[bank] & ~(m_sram_select_mask | m_bank_mask)) - { - // Nothing is mapped - m_bank_base[bank] = nullptr; - } - else if (m_selected_bank[bank] & m_sram_select_mask) - { - // SRAM is selected - m_bank_base[bank] = get_sram_base(); - } - else - { - m_bank_base[bank] = get_rom_base() + (m_selected_bank[bank] & m_bank_mask ) * 0x2000; - } -} - - -void msx_cart_ascii8_sram_device::restore_banks() -{ - for (int i = 0; i < 4; i++) - { - setup_bank(i); - } } - void msx_cart_ascii8_sram_device::device_reset() { - for (auto & elem : m_selected_bank) - { - elem = 0; - } + for (int i = 0; i < 4; i++) + m_rombank[i]->set_entry(0); + m_view2.select(0); + m_view3.select(0); } - void msx_cart_ascii8_sram_device::initialize_cartridge() { - uint32_t size = get_rom_size(); + u32 size = get_rom_size(); + u16 banks = size / BANK_SIZE; - if ( size > 128 * 0x2000 ) - { - fatalerror("ascii8_sram: ROM is too big\n"); - } - - uint16_t banks = size / 0x2000; - - if (size != banks * 0x2000 || (~(banks - 1) % banks)) + if (size > 128 * BANK_SIZE || size != banks * BANK_SIZE || (~(banks - 1) % banks)) { fatalerror("ascii8_sram: Invalid ROM size\n"); } @@ -280,127 +139,74 @@ void msx_cart_ascii8_sram_device::initialize_cartridge() m_bank_mask = banks - 1; m_sram_select_mask = banks; - restore_banks(); -} - - -uint8_t msx_cart_ascii8_sram_device::read_cart(offs_t offset) -{ - if ( offset >= 0x4000 && offset < 0xC000 ) - { - uint8_t *bank_base = m_bank_base[(offset - 0x4000) >> 13]; + for (int i = 0; i < 4; i++) + m_rombank[i]->configure_entries(0, banks, get_rom_base(), BANK_SIZE); - if (bank_base != nullptr) - { - return bank_base[offset & 0x1fff]; - } - } - return 0xff; + 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_cart_ascii8_sram_device::mapper_write))); + page(2)->install_view(0x8000, 0x9fff, m_view2); + m_view2[0].install_read_bank(0x8000, 0x9fff, m_rombank[2]); + m_view2[1].install_ram(0x8000, 0x9fff, get_sram_base()); + page(2)->install_view(0xa000, 0xbfff, m_view3); + m_view3[0].install_read_bank(0xa000, 0xbfff, m_rombank[3]); + m_view3[1].install_ram(0xa000, 0xbfff, get_sram_base()); } - -void msx_cart_ascii8_sram_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_ascii8_sram_device::mapper_write(offs_t offset, u8 data) { - if (offset >= 0x6000 && offset < 0x8000) + u8 bank = (offset / 0x800) & 0x03; + if (data & m_sram_select_mask) { - uint8_t bank = (offset / 0x800) & 0x03; - - m_selected_bank[bank] = data; - setup_bank(bank); + if (bank == 2) + m_view2.select(1); + if (bank == 3) + m_view3.select(1); } - else if (offset >= 0x8000 && offset < 0xc000) + else { - uint8_t bank = (offset & 0x2000) ? 3 : 2; + if (bank == 2) + m_view2.select(0); + if (bank == 3) + m_view3.select(0); - if ((m_selected_bank[bank] & m_sram_select_mask) && !(m_selected_bank[bank] & ~(m_sram_select_mask | m_bank_mask))) - { - // Write to SRAM - m_bank_base[bank][offset & 0x1fff] = data; - } + m_rombank[bank]->set_entry(data & m_bank_mask); } } -msx_cart_ascii16_sram_device::msx_cart_ascii16_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + +msx_cart_ascii16_sram_device::msx_cart_ascii16_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_ASCII16_SRAM, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) + , m_view(*this, "view") , m_bank_mask(0) , m_sram_select_mask(0) { - for (int i = 0; i < 2; i++) - { - m_selected_bank[i] = 0; - m_bank_base[i] = nullptr; - } } - void msx_cart_ascii16_sram_device::device_start() { - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_ascii16_sram_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_ascii16_sram_device::setup_bank(uint8_t bank) -{ - if (m_selected_bank[bank] & ~(m_sram_select_mask | m_bank_mask)) - { - // Nothing is mapped - m_bank_base[bank] = nullptr; - } - else if (m_selected_bank[bank] & m_sram_select_mask) - { - // SRAM is selected - m_bank_base[bank] = get_sram_base(); - } - else - { - m_bank_base[bank] = get_rom_base() + (m_selected_bank[bank] & m_bank_mask) * 0x4000; - } -} - - -void msx_cart_ascii16_sram_device::restore_banks() -{ - for (int i = 0; i < 2; i++) - { - setup_bank(i); - } } - void msx_cart_ascii16_sram_device::device_reset() { - for (auto & elem : m_selected_bank) - { - elem = 0; - } + m_rombank[0]->set_entry(0); + m_view.select(0); + m_rombank[1]->set_entry(0); } - void msx_cart_ascii16_sram_device::initialize_cartridge() { - uint32_t size = get_rom_size(); + u32 size = get_rom_size(); + u16 banks = size / BANK_SIZE; - if ( size > 128 * 0x4000 ) - { - fatalerror("ascii16_sram: ROM is too big\n"); - } - - uint16_t banks = size / 0x4000; - - if (size != banks * 0x4000 || (~(banks - 1) % banks)) + if (size > 128 * BANK_SIZE || size != banks * BANK_SIZE || (~(banks - 1) % banks)) { fatalerror("ascii16_sram: Invalid ROM size\n"); } - if (get_sram_size() != 0x800) { fatalerror("ascii16_sram: Unsupported SRAM size\n"); @@ -409,147 +215,31 @@ void msx_cart_ascii16_sram_device::initialize_cartridge() m_bank_mask = banks - 1; m_sram_select_mask = banks; - restore_banks(); -} - - -uint8_t msx_cart_ascii16_sram_device::read_cart(offs_t offset) -{ - if ( offset >= 0x4000 && offset < 0xC000 ) - { - uint8_t bank = offset >> 15; - - if (m_bank_base[bank] != nullptr) - { - if (m_selected_bank[bank] & m_sram_select_mask) - { - return m_bank_base[bank][offset & 0x7ff]; - } - else - { - return m_bank_base[bank][offset & 0x3fff]; - } - } - } - return 0xff; -} - - -void msx_cart_ascii16_sram_device::write_cart(offs_t offset, uint8_t data) -{ - if (offset >= 0x6000 && offset < 0x6800) - { - m_selected_bank[0] = data; - setup_bank(0); - } - - if (offset >= 0x7000 && offset < 0x7800) - { - m_selected_bank[1] = data; - setup_bank(1); - } - - if (offset >= 0x8000 && offset < 0xc000) - { - if ((m_selected_bank[1] & m_sram_select_mask) && !(m_selected_bank[1] & ~(m_sram_select_mask | m_bank_mask))) - { - // Write to SRAM - m_bank_base[1][offset & 0x7ff] = data; - } - } -} - - - -msx_cart_msxwrite_device::msx_cart_msxwrite_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, MSX_CART_MSXWRITE, tag, owner, clock) - , msx_cart_interface(mconfig, *this) - , m_bank_mask(0) -{ for (int i = 0; i < 2; i++) - { - m_selected_bank[i] = 0; - m_bank_base[i] = nullptr; - } -} - + m_rombank[i]->configure_entries(0, banks, get_rom_base(), BANK_SIZE); -void msx_cart_msxwrite_device::device_start() -{ - save_item(NAME(m_selected_bank)); + page(1)->install_read_bank(0x4000, 0x7fff, m_rombank[0]); + page(1)->install_write_handler(0x6000, 0x67ff, write8smo_delegate(*this, FUNC(msx_cart_ascii16_sram_device::mapper_write_6000))); + page(1)->install_write_handler(0x7000, 0x77ff, write8smo_delegate(*this, FUNC(msx_cart_ascii16_sram_device::mapper_write_7000))); + page(2)->install_view(0x8000, 0xbfff, m_view); + m_view[0].install_read_bank(0x8000, 0xbfff, m_rombank[1]); + m_view[1].install_ram(0x8000, 0x87ff, 0x3800, get_sram_base()); } - -void msx_cart_msxwrite_device::device_post_load() +void msx_cart_ascii16_sram_device::mapper_write_6000(u8 data) { - restore_banks(); + m_rombank[0]->set_entry(data & m_bank_mask); } - -void msx_cart_msxwrite_device::restore_banks() +void msx_cart_ascii16_sram_device::mapper_write_7000(u8 data) { - for (int i = 0; i < 2; i++) + if (data & m_sram_select_mask) { - m_bank_base[i] = get_rom_base() + (m_selected_bank[i] & m_bank_mask) * 0x4000; + m_view.select(1); } -} - - -void msx_cart_msxwrite_device::device_reset() -{ - for (auto & elem : m_selected_bank) - { - elem = 0; - } -} - - -void msx_cart_msxwrite_device::initialize_cartridge() -{ - uint32_t size = get_rom_size(); - - if ( size > 256 * 0x4000 ) - { - fatalerror("msxwrite: ROM is too big\n"); - } - - uint16_t banks = size / 0x4000; - - if (size != banks * 0x4000 || (~(banks - 1) % banks)) - { - fatalerror("msxwrite: Invalid ROM size\n"); - } - - m_bank_mask = banks - 1; - - restore_banks(); -} - - -uint8_t msx_cart_msxwrite_device::read_cart(offs_t offset) -{ - if ( offset >= 0x4000 && offset < 0xC000 ) - { - return m_bank_base[offset >> 15][offset & 0x3fff]; - } - return 0xff; -} - - -void msx_cart_msxwrite_device::write_cart(offs_t offset, uint8_t data) -{ - // The rom writes to 6fff and 7fff for banking, unknown whether - // other locations also trigger banking. - switch (offset) + else { - case 0x6fff: - m_selected_bank[0] = data; - m_bank_base[0] = get_rom_base() + (m_selected_bank[0] & m_bank_mask) * 0x4000; - break; - - case 0x7fff: - m_selected_bank[1] = data; - m_bank_base[1] = get_rom_base() + (m_selected_bank[1] & m_bank_mask) * 0x4000; - break; + m_view.select(0); + m_rombank[1]->set_entry(data & m_bank_mask); } } diff --git a/src/devices/bus/msx_cart/ascii.h b/src/devices/bus/msx_cart/ascii.h index 0c5898fed40..9c41cac2789 100644 --- a/src/devices/bus/msx_cart/ascii.h +++ b/src/devices/bus/msx_cart/ascii.h @@ -12,84 +12,74 @@ DECLARE_DEVICE_TYPE(MSX_CART_ASCII8, msx_cart_ascii8_device) DECLARE_DEVICE_TYPE(MSX_CART_ASCII16, msx_cart_ascii16_device) DECLARE_DEVICE_TYPE(MSX_CART_ASCII8_SRAM, msx_cart_ascii8_sram_device) DECLARE_DEVICE_TYPE(MSX_CART_ASCII16_SRAM, msx_cart_ascii16_sram_device) -DECLARE_DEVICE_TYPE(MSX_CART_MSXWRITE, msx_cart_msxwrite_device) class msx_cart_ascii8_device : public device_t, public msx_cart_interface { public: - msx_cart_ascii8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_ascii8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_bank_mask; - uint8_t m_selected_bank[4]; - uint8_t *m_bank_base[4]; + static constexpr size_t BANK_SIZE = 0x2000; + + template <int Bank> void bank_w(u8 data); + + memory_bank_array_creator<4> m_rombank; + u8 m_bank_mask; }; class msx_cart_ascii16_device : public device_t, public msx_cart_interface { public: - msx_cart_ascii16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_ascii16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_bank_mask; - uint8_t m_selected_bank[2]; - uint8_t *m_bank_base[2]; + static constexpr size_t BANK_SIZE = 0x4000; + + template <int Bank> void bank_w(u8 data); + + memory_bank_array_creator<2> m_rombank; + u8 m_bank_mask; }; class msx_cart_ascii8_sram_device : public device_t, public msx_cart_interface { public: - msx_cart_ascii8_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_ascii8_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_bank_mask; - uint8_t m_selected_bank[4]; - uint8_t *m_bank_base[4]; - uint8_t m_sram_select_mask; + static constexpr size_t BANK_SIZE = 0x2000; + + void mapper_write(offs_t offset, u8 data); - void setup_bank(uint8_t bank); + memory_bank_array_creator<4> m_rombank; + memory_view m_view2; + memory_view m_view3; + u8 m_bank_mask; + u8 m_sram_select_mask; }; @@ -100,49 +90,22 @@ public: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_bank_mask; - uint8_t m_selected_bank[2]; - uint8_t *m_bank_base[2]; - uint8_t m_sram_select_mask; + static constexpr size_t BANK_SIZE = 0x4000; - void setup_bank(uint8_t bank); -}; - - -class msx_cart_msxwrite_device : public device_t, public msx_cart_interface -{ -public: - msx_cart_msxwrite_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - virtual void initialize_cartridge() override; - - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; + void mapper_write_6000(u8 data); + void mapper_write_7000(u8 data); -protected: - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); - -private: - uint8_t m_bank_mask; - uint8_t m_selected_bank[2]; - uint8_t *m_bank_base[2]; + memory_bank_array_creator<2> m_rombank; + memory_view m_view; + u8 m_bank_mask; + u8 m_sram_select_mask; }; + #endif // MAME_BUS_MSX_CART_ASCII_H diff --git a/src/devices/bus/msx_cart/cartridge.cpp b/src/devices/bus/msx_cart/cartridge.cpp index 4bda712eabe..a764f61f03c 100644 --- a/src/devices/bus/msx_cart/cartridge.cpp +++ b/src/devices/bus/msx_cart/cartridge.cpp @@ -16,6 +16,7 @@ #include "hfox.h" #include "holy_quran.h" #include "ink.h" +#include "kanji.h" #include "konami.h" #include "korean.h" #include "majutsushi.h" @@ -33,44 +34,45 @@ void msx_cart(device_slot_interface &device) { - device.option_add_internal("nomapper", MSX_CART_NOMAPPER); - device.option_add_internal("msxdos2", MSX_CART_MSXDOS2); - device.option_add_internal("konami_scc", MSX_CART_KONAMI_SCC); - device.option_add_internal("konami", MSX_CART_KONAMI); + device.option_add_internal("arc", MSX_CART_ARC); device.option_add_internal("ascii8", MSX_CART_ASCII8); - device.option_add_internal("ascii16", MSX_CART_ASCII16); - device.option_add_internal("gamemaster2", MSX_CART_GAMEMASTER2); device.option_add_internal("ascii8_sram", MSX_CART_ASCII8_SRAM); + device.option_add_internal("ascii16", MSX_CART_ASCII16); device.option_add_internal("ascii16_sram", MSX_CART_ASCII16_SRAM); - device.option_add_internal("rtype", MSX_CART_RTYPE); - device.option_add_internal("majutsushi", MSX_CART_MAJUTSUSHI); + device.option_add_internal("cross_blaim", MSX_CART_CROSSBLAIM); + device.option_add_internal("disk_vy0010", MSX_CART_VY0010); + device.option_add_internal("disk_fsfd1", MSX_CART_FSFD1); + device.option_add_internal("disk_fsfd1a", MSX_CART_FSFD1A); + device.option_add_internal("disk_fscf351", MSX_CART_FSCF351); + device.option_add_internal("dooly", MSX_CART_DOOLY); + device.option_add_internal("easispeech", MSX_CART_EASISPEECH); device.option_add_internal("fmpac", MSX_CART_FMPAC); device.option_add_internal("fs_sr022", MSX_CART_FS_SR022); - device.option_add_internal("superloderunner", MSX_CART_SUPERLODERUNNER); - device.option_add_internal("synthesizer", MSX_CART_SYNTHESIZER); - device.option_add_internal("easispeech", MSX_CART_EASISPEECH); - device.option_add_internal("cross_blaim", MSX_CART_CROSSBLAIM); + device.option_add_internal("gamemaster2", MSX_CART_GAMEMASTER2); + device.option_add_internal("halnote", MSX_CART_HALNOTE); + device.option_add_internal("hfox", MSX_CART_HFOX); + device.option_add_internal("holy_quran", MSX_CART_HOLY_QURAN); + device.option_add_internal("ink", MSX_CART_INK); + device.option_add_internal("kanji", MSX_CART_KANJI); + device.option_add_internal("keyboard_master", MSX_CART_KEYBOARD_MASTER); + device.option_add_internal("konami", MSX_CART_KONAMI); + device.option_add_internal("konami_scc", MSX_CART_KONAMI_SCC); device.option_add_internal("korean_80in1", MSX_CART_KOREAN_80IN1); device.option_add_internal("korean_90in1", MSX_CART_KOREAN_90IN1); device.option_add_internal("korean_126in1", MSX_CART_KOREAN_126IN1); + device.option_add_internal("majutsushi", MSX_CART_MAJUTSUSHI); + device.option_add_internal("msxaud_fsca1", MSX_CART_MSX_AUDIO_FSCA1); + device.option_add_internal("msxaud_hxmu900", MSX_CART_MSX_AUDIO_HXMU900); + device.option_add_internal("msxaud_nms1205", MSX_CART_MSX_AUDIO_NMS1205); + device.option_add_internal("msxdos2", MSX_CART_MSXDOS2); device.option_add_internal("msxwrite", MSX_CART_MSXWRITE); + device.option_add_internal("nomapper", MSX_CART_NOMAPPER); + device.option_add_internal("rtype", MSX_CART_RTYPE); device.option_add_internal("sound_snatcher", MSX_CART_SOUND_SNATCHER); device.option_add_internal("sound_sdsnatch", MSX_CART_SOUND_SDSNATCHER); - device.option_add_internal("msxaud_hxmu900", MSX_CART_MSX_AUDIO_HXMU900); - device.option_add_internal("msxaud_fsca1", MSX_CART_MSX_AUDIO_FSCA1); - device.option_add_internal("msxaud_nms1205", MSX_CART_MSX_AUDIO_NMS1205); device.option_add_internal("super_swangi", MSX_CART_SUPER_SWANGI); - device.option_add_internal("hfox", MSX_CART_HFOX); - device.option_add_internal("ink", MSX_CART_INK); - device.option_add_internal("keyboard_master", MSX_CART_KEYBOARD_MASTER); - device.option_add_internal("holy_quran", MSX_CART_HOLY_QURAN); - device.option_add_internal("dooly", MSX_CART_DOOLY); - device.option_add_internal("halnote", MSX_CART_HALNOTE); - device.option_add_internal("arc", MSX_CART_ARC); - device.option_add_internal("disk_vy0010", MSX_CART_VY0010); - device.option_add_internal("disk_fsfd1", MSX_CART_FSFD1); - device.option_add_internal("disk_fsfd1a", MSX_CART_FSFD1A); - device.option_add_internal("disk_fscf351", MSX_CART_FSCF351); + device.option_add_internal("superloderunner", MSX_CART_SUPERLODERUNNER); + device.option_add_internal("synthesizer", MSX_CART_SYNTHESIZER); device.option_add("bm_012", MSX_CART_BM_012); device.option_add("moonsound", MSX_CART_MOONSOUND); } @@ -80,32 +82,40 @@ msx_cart_interface::msx_cart_interface(const machine_config &mconfig, device_t & : device_interface(device, "msxcart") , m_exp(nullptr) { + for (int i = 0; i < 4; i++) + m_page[i] = nullptr; } -void msx_cart_interface::rom_alloc(uint32_t size) +void msx_cart_interface::rom_alloc(u32 size) { m_rom.resize(size); std::fill_n(m_rom.begin(), size, 0xff); } -void msx_cart_interface::rom_vlm5030_alloc(uint32_t size) +void msx_cart_interface::rom_vlm5030_alloc(u32 size) { m_rom_vlm5030.resize(size); std::fill_n(m_rom_vlm5030.begin(), size, 0xff); } -void msx_cart_interface::ram_alloc(uint32_t size) +void msx_cart_interface::ram_alloc(u32 size) { m_ram.resize(size); std::fill_n(m_ram.begin(), size, 0x00); } -void msx_cart_interface::sram_alloc(uint32_t size) +void msx_cart_interface::sram_alloc(u32 size) { m_sram.resize(size); std::fill_n(m_sram.begin(), size, 0x00); } +void msx_cart_interface::kanji_alloc(u32 size) +{ + m_kanji.resize(size); + std::fill_n(m_kanji.begin(), size, 0x00); +} + WRITE_LINE_MEMBER(msx_cart_interface::irq_out) { m_exp->irq_out(state); @@ -121,6 +131,19 @@ address_space &msx_cart_interface::io_space() const return m_exp->io_space(); } +cpu_device &msx_cart_interface::maincpu() const +{ + return m_exp->maincpu(); +} + +void msx_cart_interface::set_views(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; +} + // Several yamaha machines had 60 pin expansion slots. The pinouts of these slots was // exactly the same as the regular 50 pin cartridge slots. The lowest 10 pins are simply diff --git a/src/devices/bus/msx_cart/cartridge.h b/src/devices/bus/msx_cart/cartridge.h index 73759baf544..ac0fb3edb22 100644 --- a/src/devices/bus/msx_cart/cartridge.h +++ b/src/devices/bus/msx_cart/cartridge.h @@ -23,37 +23,42 @@ public: virtual void initialize_cartridge() { } virtual void interface_pre_start() override { assert(m_exp != nullptr); } - // reading and writing - virtual uint8_t read_cart(offs_t offset) { return 0xff; } - virtual void write_cart(offs_t offset, uint8_t data) { } + void set_views(memory_view::memory_view_entry *page0, memory_view::memory_view_entry *page1, memory_view::memory_view_entry *page2, memory_view::memory_view_entry *page3); DECLARE_WRITE_LINE_MEMBER(irq_out); address_space &memory_space() const; address_space &io_space() const; + cpu_device &maincpu() const; // ROM/RAM/SRAM management // Mainly used by the cartridge slot when loading images - void rom_alloc(uint32_t size); - void ram_alloc(uint32_t size); - void rom_vlm5030_alloc(uint32_t size); - void sram_alloc(uint32_t size); - - uint8_t* get_rom_base() { return &m_rom[0]; } - uint8_t* get_rom_vlm5030_base() { return &m_rom_vlm5030[0]; } - uint8_t* get_ram_base() { return &m_ram[0]; } - uint8_t* get_sram_base() { return &m_sram[0]; } - uint32_t get_rom_size() { return m_rom.size(); } - uint32_t get_rom_vlm5030_size() { return m_rom_vlm5030.size(); } - uint32_t get_ram_size() { return m_ram.size(); } - uint32_t get_sram_size() { return m_sram.size(); } + void rom_alloc(u32 size); + void ram_alloc(u32 size); + void rom_vlm5030_alloc(u32 size); + void sram_alloc(u32 size); + void kanji_alloc(u32 size); + + u8* get_rom_base() { return &m_rom[0]; } + u8* get_rom_vlm5030_base() { return &m_rom_vlm5030[0]; } + u8* get_ram_base() { return &m_ram[0]; } + u8* get_sram_base() { return &m_sram[0]; } + u8* get_kanji_base() { return &m_kanji[0]; } + u32 get_rom_size() { return m_rom.size(); } + u32 get_rom_vlm5030_size() { return m_rom_vlm5030.size(); } + u32 get_ram_size() { return m_ram.size(); } + u32 get_sram_size() { return m_sram.size(); } + u32 get_kanji_size() { return m_kanji.size(); } + memory_view::memory_view_entry *page(int i) { return m_page[i]; } protected: msx_cart_interface(const machine_config &mconfig, device_t &device); - std::vector<uint8_t> m_rom; - std::vector<uint8_t> m_ram; - std::vector<uint8_t> m_rom_vlm5030; - std::vector<uint8_t> m_sram; + std::vector<u8> m_rom; + std::vector<u8> m_ram; + std::vector<u8> m_rom_vlm5030; + std::vector<u8> m_sram; + std::vector<u8> m_kanji; + memory_view::memory_view_entry *m_page[4]; private: msx_slot_cartridge_device *m_exp; diff --git a/src/devices/bus/msx_cart/crossblaim.cpp b/src/devices/bus/msx_cart/crossblaim.cpp index 6494e492f5b..1d30ec07f4f 100644 --- a/src/devices/bus/msx_cart/crossblaim.cpp +++ b/src/devices/bus/msx_cart/crossblaim.cpp @@ -9,48 +9,10 @@ DEFINE_DEVICE_TYPE(MSX_CART_CROSSBLAIM, msx_cart_crossblaim_device, "msx_cart_cr msx_cart_crossblaim_device::msx_cart_crossblaim_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, MSX_CART_CROSSBLAIM, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_selected_bank(1) + , m_rombank(*this, "rombank") { - for (auto & elem : m_bank_base) - { - elem = nullptr; - } -} - - -void msx_cart_crossblaim_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_crossblaim_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_crossblaim_device::setup_bank() -{ - m_bank_base[0] = ( m_selected_bank & 2 ) ? nullptr : get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000; - m_bank_base[2] = get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000; - m_bank_base[3] = ( m_selected_bank & 2 ) ? nullptr : get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000; -} - - -void msx_cart_crossblaim_device::restore_banks() -{ - m_bank_base[1] = get_rom_base(); - setup_bank(); -} - - -void msx_cart_crossblaim_device::device_reset() -{ - m_selected_bank = 1; } - void msx_cart_crossblaim_device::initialize_cartridge() { if (get_rom_size() != 0x10000) @@ -58,29 +20,18 @@ void msx_cart_crossblaim_device::initialize_cartridge() fatalerror("crossblaim: Invalid ROM size\n"); } - restore_banks(); -} - + m_rombank->configure_entries(0, 4, get_rom_base(), 0x4000); -uint8_t msx_cart_crossblaim_device::read_cart(offs_t offset) -{ - uint8_t *bank_base = m_bank_base[offset >> 14]; - - if (bank_base != nullptr) - { - return bank_base[offset & 0x3fff]; - } - - return 0xff; + page(1)->install_rom(0x4000, 0x7fff, get_rom_base()); + page(1)->install_write_handler(0x4045, 0x4045, write8smo_delegate(*this, FUNC(msx_cart_crossblaim_device::mapper_write))); + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank); } - -void msx_cart_crossblaim_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_crossblaim_device::mapper_write(u8 data) { - m_selected_bank = data & 3; - if (m_selected_bank == 0) - { - m_selected_bank = 1; - } - setup_bank(); + data &= 0x03; + if (!data) + data = 1; + + m_rombank->set_entry(data); } diff --git a/src/devices/bus/msx_cart/crossblaim.h b/src/devices/bus/msx_cart/crossblaim.h index 04a44c1d905..617ff59d1cd 100644 --- a/src/devices/bus/msx_cart/crossblaim.h +++ b/src/devices/bus/msx_cart/crossblaim.h @@ -18,22 +18,14 @@ public: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); + virtual void device_start() override { } private: - uint8_t m_selected_bank; - uint8_t *m_bank_base[4]; + void mapper_write(u8 data); - void setup_bank(); + memory_bank_creator m_rombank; }; diff --git a/src/devices/bus/msx_cart/disk.cpp b/src/devices/bus/msx_cart/disk.cpp index b07d9dd6dc0..bff8716439f 100644 --- a/src/devices/bus/msx_cart/disk.cpp +++ b/src/devices/bus/msx_cart/disk.cpp @@ -102,6 +102,7 @@ #include "emu.h" #include "disk.h" +#include "formats/dmk_dsk.h" #include "formats/msx_dsk.h" #include "softlist_dev.h" @@ -115,6 +116,7 @@ void msx_cart_disk_device::floppy_formats(format_registration &fr) { fr.add_mfm_containers(); fr.add(FLOPPY_MSX_FORMAT); + fr.add(FLOPPY_DMK_FORMAT); } @@ -125,7 +127,7 @@ static void msx_floppies(device_slot_interface &device) } -msx_cart_disk_device::msx_cart_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +msx_cart_disk_device::msx_cart_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_floppy0(*this, "fdc:0") @@ -135,14 +137,14 @@ msx_cart_disk_device::msx_cart_disk_device(const machine_config &mconfig, device } -msx_cart_disk_wd_device::msx_cart_disk_wd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +msx_cart_disk_wd_device::msx_cart_disk_wd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : msx_cart_disk_device(mconfig, type, tag, owner, clock) , m_fdc(*this, "fdc") { } -msx_cart_disk_type1_device::msx_cart_disk_type1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +msx_cart_disk_type1_device::msx_cart_disk_type1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : msx_cart_disk_wd_device(mconfig, type, tag, owner, clock) , m_led(*this, "led0") , m_side_control(0) @@ -151,7 +153,7 @@ msx_cart_disk_type1_device::msx_cart_disk_type1_device(const machine_config &mco } -msx_cart_disk_type2_device::msx_cart_disk_type2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +msx_cart_disk_type2_device::msx_cart_disk_type2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : msx_cart_disk_wd_device(mconfig, type, tag, owner, clock) , m_led(*this, "led0") , m_control(0) @@ -159,32 +161,32 @@ msx_cart_disk_type2_device::msx_cart_disk_type2_device(const machine_config &mco } -msx_cart_vy0010_device::msx_cart_vy0010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_vy0010_device::msx_cart_vy0010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : msx_cart_disk_type1_device(mconfig, MSX_CART_VY0010, tag, owner, clock) { } -msx_cart_fsfd1_device::msx_cart_fsfd1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_fsfd1_device::msx_cart_fsfd1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : msx_cart_disk_type1_device(mconfig, MSX_CART_FSFD1, tag, owner, clock) { } -msx_cart_fscf351_device::msx_cart_fscf351_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_fscf351_device::msx_cart_fscf351_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : msx_cart_disk_type2_device(mconfig, MSX_CART_FSCF351, tag, owner, clock) { } -msx_cart_disk_tc8566_device::msx_cart_disk_tc8566_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +msx_cart_disk_tc8566_device::msx_cart_disk_tc8566_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : msx_cart_disk_device(mconfig, type, tag, owner, clock) , m_fdc(*this, "fdc") { } -msx_cart_fsfd1a_device::msx_cart_fsfd1a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_fsfd1a_device::msx_cart_fsfd1a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : msx_cart_disk_tc8566_device(mconfig, MSX_CART_FSFD1A, tag, owner, clock) { } @@ -192,7 +194,7 @@ msx_cart_fsfd1a_device::msx_cart_fsfd1a_device(const machine_config &mconfig, co void msx_cart_disk_device::initialize_cartridge() { - if ( get_rom_size() != 0x4000 ) + if (get_rom_size() != 0x4000) { fatalerror("msx_cart_disk_device: Invalid ROM size\n"); } @@ -219,6 +221,7 @@ void msx_cart_vy0010_device::device_add_mconfig(machine_config &config) SOFTWARE_LIST(config, "msx1_flop_list").set_compatible("msx1_flop"); } + void msx_cart_fsfd1_device::device_add_mconfig(machine_config &config) { WD2793(config, m_fdc, 4_MHz_XTAL / 4); @@ -276,6 +279,41 @@ void msx_cart_disk_type1_device::device_start() save_item(NAME(m_control)); } +void msx_cart_disk_type1_device::initialize_cartridge() +{ + msx_cart_disk_wd_device::initialize_cartridge(); + + page(1)->install_rom(0x4000, 0x7fff, get_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_cart_disk_type1_device::side_control_r))); + page(1)->install_read_handler(0x7ffd, 0x7ffd, read8smo_delegate(*this, FUNC(msx_cart_disk_type1_device::control_r))); + page(1)->install_read_handler(0x7fff, 0x7fff, read8smo_delegate(*this, FUNC(msx_cart_disk_type1_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_cart_disk_type1_device::set_side_control))); + page(1)->install_write_handler(0x7ffd, 0x7ffd, write8smo_delegate(*this, FUNC(msx_cart_disk_type1_device::set_control))); + + // TODO No idea why, but without this the other handlers do not get recognized + page(2)->install_rom(0xbff8,0xbff8, get_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_cart_disk_type1_device::side_control_r))); + page(2)->install_read_handler(0xbffd, 0xbffd, read8smo_delegate(*this, FUNC(msx_cart_disk_type1_device::control_r))); + page(2)->install_read_handler(0xbfff, 0xbfff, read8smo_delegate(*this, FUNC(msx_cart_disk_type1_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_cart_disk_type1_device::set_side_control))); + page(2)->install_write_handler(0xbffd, 0xbffd, write8smo_delegate(*this, FUNC(msx_cart_disk_type1_device::set_control))); +} void msx_cart_disk_type1_device::device_post_load() { @@ -287,7 +325,6 @@ void msx_cart_disk_type1_device::device_post_load() set_control(data); } - void msx_cart_disk_type1_device::set_control(uint8_t data) { uint8_t old_m_control = m_control; @@ -324,7 +361,6 @@ void msx_cart_disk_type1_device::set_control(uint8_t data) } } - void msx_cart_disk_type1_device::set_side_control(uint8_t data) { m_side_control = data; @@ -335,95 +371,28 @@ void msx_cart_disk_type1_device::set_side_control(uint8_t data) } } - void msx_cart_disk_type1_device::device_reset() { m_fdc->dden_w(false); } - -uint8_t msx_cart_disk_type1_device::read_cart(offs_t offset) +u8 msx_cart_disk_type1_device::side_control_r() { - switch (offset) - { - case 0x7ff8: - case 0xbff8: - return m_fdc->status_r(); - - case 0x7ff9: - case 0xbff9: - return m_fdc->track_r(); - - case 0x7ffa: - case 0xbffa: - return m_fdc->sector_r(); - - case 0x7ffb: - case 0xbffb: - return m_fdc->data_r(); - - case 0x7ffc: - case 0xbffc: - return 0xfe | (m_side_control & 0x01); - - 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); - } - - if (offset >= 0x4000 && offset < 0x8000) - { - return get_rom_base()[offset & 0x3fff]; - } - return 0xff; + return 0xfe | (m_side_control & 0x01); } - -void msx_cart_disk_type1_device::write_cart(offs_t offset, uint8_t data) +u8 msx_cart_disk_type1_device::control_r() { - 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; + return ( m_control & 0x83 ) | 0x78; +} - default: - logerror("msx_cart_disk_type1_device::write_cart: Unmapped write writing %02x to %04x\n", data, offset); - break; - } +u8 msx_cart_disk_type1_device::status_r() +{ + return 0x3f | (m_fdc->intrq_r() ? 0 : 0x40) | (m_fdc->drq_r() ? 0 : 0x80); } + void msx_cart_disk_type2_device::device_start() { m_led.resolve(); @@ -431,13 +400,11 @@ void msx_cart_disk_type2_device::device_start() save_item(NAME(m_control)); } - void msx_cart_disk_type2_device::device_reset() { m_fdc->dden_w(false); } - void msx_cart_disk_type2_device::device_post_load() { uint8_t data = m_control; @@ -448,8 +415,37 @@ void msx_cart_disk_type2_device::device_post_load() set_control(data); } +void msx_cart_disk_type2_device::initialize_cartridge() +{ + msx_cart_disk_wd_device::initialize_cartridge(); + + page(1)->install_rom(0x4000, 0x7fff, get_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_cart_disk_type2_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_cart_disk_type2_device::set_control))); -void msx_cart_disk_type2_device::set_control(uint8_t data) + // TODO No idea why, but without this the other handlers do not get recognized + page(2)->install_rom(0xbfb8,0xbfb8, get_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_cart_disk_type2_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_cart_disk_type2_device::set_control))); +} + +void msx_cart_disk_type2_device::set_control(u8 data) { uint8_t old_m_control = m_control; @@ -484,73 +480,9 @@ void msx_cart_disk_type2_device::set_control(uint8_t data) } } - -uint8_t msx_cart_disk_type2_device::read_cart(offs_t offset) -{ - 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(); - - 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); - } - - if (offset >= 0x4000 && offset < 0x8000) - { - return get_rom_base()[offset & 0x3fff]; - } - return 0xff; -} - - -void msx_cart_disk_type2_device::write_cart(offs_t offset, uint8_t data) +u8 msx_cart_disk_type2_device::status_r() { - 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_cart_disk_type2_device::write_cart: Unmapped write writing %02x to %04x\n", data, offset); - break; - } + return 0x3f | (m_fdc->drq_r() ? 0 : 0x40) | (m_fdc->intrq_r() ? 0x80 : 0); } @@ -565,49 +497,21 @@ void msx_cart_fsfd1a_device::device_reset() { } - -uint8_t msx_cart_fsfd1a_device::read_cart(offs_t offset) -{ - switch (offset) - { - case 0x7ffa: - case 0xbffa: - return m_fdc->msr_r(); - - case 0x7ffb: - case 0xbffb: - return m_fdc->fifo_r(); - } - - if (offset >= 0x4000 && offset < 0x8000) - { - return get_rom_base()[offset & 0x3fff]; - } - return 0xff; -} - - -void msx_cart_fsfd1a_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_fsfd1a_device::initialize_cartridge() { - switch (offset) - { - case 0x7ff8: - case 0xbff8: - m_fdc->dor_w(data); - break; - - case 0x7ff9: - case 0xbff9: - m_fdc->cr1_w(data); - break; + msx_cart_disk_tc8566_device::initialize_cartridge(); - case 0x7ffb: - case 0xbffb: - m_fdc->fifo_w(data); - break; - - default: - logerror("msx_cart_fsfd1a_device::write_cart: Unmapped write writing %02x to %04x\n", data, offset); - break; - } + page(1)->install_rom(0x4000, 0x7fff, get_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, get_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))); } diff --git a/src/devices/bus/msx_cart/disk.h b/src/devices/bus/msx_cart/disk.h index fd8d640157f..53407cfe0e7 100644 --- a/src/devices/bus/msx_cart/disk.h +++ b/src/devices/bus/msx_cart/disk.h @@ -23,7 +23,7 @@ public: virtual void initialize_cartridge() override; protected: - msx_cart_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + msx_cart_disk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); required_device<floppy_connector> m_floppy0; optional_device<floppy_connector> m_floppy1; @@ -36,7 +36,7 @@ protected: class msx_cart_disk_wd_device : public msx_cart_disk_device { protected: - msx_cart_disk_wd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + msx_cart_disk_wd_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); required_device<wd_fdc_analog_device_base> m_fdc; }; @@ -45,51 +45,54 @@ protected: class msx_cart_disk_type1_device : public msx_cart_disk_wd_device { public: - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; + virtual void initialize_cartridge() override; protected: - msx_cart_disk_type1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + msx_cart_disk_type1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); // device-level overrides virtual void device_start() override; virtual void device_reset() override; virtual void device_post_load() override; + u8 side_control_r(); + u8 control_r(); + u8 status_r(); + void set_side_control(u8 data); + void set_control(u8 data); + output_finder<> m_led; - uint8_t m_side_control; - uint8_t m_control; + u8 m_side_control; + u8 m_control; - void set_side_control(uint8_t data); - void set_control(uint8_t data); }; class msx_cart_disk_type2_device : public msx_cart_disk_wd_device { public: - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; + virtual void initialize_cartridge() override; protected: - msx_cart_disk_type2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + msx_cart_disk_type2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); // device-level overrides virtual void device_start() override; virtual void device_reset() override; virtual void device_post_load() override; - output_finder<> m_led; - uint8_t m_control; + void set_control(u8 data); + u8 status_r(); - void set_control(uint8_t data); + output_finder<> m_led; + u8 m_control; }; class msx_cart_vy0010_device : public msx_cart_disk_type1_device { public: - msx_cart_vy0010_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_vy0010_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: virtual void device_add_mconfig(machine_config &config) override; @@ -99,7 +102,7 @@ protected: class msx_cart_fsfd1_device : public msx_cart_disk_type1_device { public: - msx_cart_fsfd1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_fsfd1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: virtual void device_add_mconfig(machine_config &config) override; @@ -109,7 +112,7 @@ protected: class msx_cart_fscf351_device : public msx_cart_disk_type2_device { public: - msx_cart_fscf351_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_fscf351_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: virtual void device_add_mconfig(machine_config &config) override; @@ -119,7 +122,7 @@ protected: class msx_cart_disk_tc8566_device : public msx_cart_disk_device { protected: - msx_cart_disk_tc8566_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + msx_cart_disk_tc8566_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); required_device<tc8566af_device> m_fdc; }; @@ -128,17 +131,15 @@ protected: class msx_cart_fsfd1a_device : public msx_cart_disk_tc8566_device { public: - msx_cart_fsfd1a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_fsfd1a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual void initialize_cartridge() override; protected: + // device-level overrides virtual void device_start() override; virtual void device_reset() override; - - // device-level overrides virtual void device_add_mconfig(machine_config &config) override; - - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; }; diff --git a/src/devices/bus/msx_cart/dooly.cpp b/src/devices/bus/msx_cart/dooly.cpp index a0c4c7b4f83..7bbc15253a5 100644 --- a/src/devices/bus/msx_cart/dooly.cpp +++ b/src/devices/bus/msx_cart/dooly.cpp @@ -10,58 +10,52 @@ DEFINE_DEVICE_TYPE(MSX_CART_DOOLY, msx_cart_dooly_device, "msx_cart_dooly", "MSX msx_cart_dooly_device::msx_cart_dooly_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, MSX_CART_DOOLY, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_prot(0) + , m_view1(*this, "view1") + , m_view2(*this, "view2") { } - -void msx_cart_dooly_device::device_start() -{ - save_item(NAME(m_prot)); -} - - void msx_cart_dooly_device::device_reset() { - m_prot = 0; + m_view1.select(0); + m_view2.select(0); } - void msx_cart_dooly_device::initialize_cartridge() { if (get_rom_size() != 0x8000) { fatalerror("dooly: Invalid ROM size\n"); } -} + page(1)->install_view(0x4000, 0x7fff, m_view1); + m_view1[0].install_rom(0x4000, 0x7fff, get_rom_base()); + m_view1[1].install_read_handler(0x4000, 0x7fff, read8sm_delegate(*this, FUNC(msx_cart_dooly_device::mode4_page1_r))); + page(2)->install_view(0x8000, 0xbfff, m_view2); + m_view2[0].install_rom(0x8000, 0xbfff, get_rom_base() + 0x4000); + m_view2[1].install_read_handler(0x8000, 0xbfff, read8sm_delegate(*this, FUNC(msx_cart_dooly_device::mode4_page2_r))); -uint8_t msx_cart_dooly_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000) - { - uint8_t data = get_rom_base()[offset - 0x4000]; + page(1)->install_write_handler(0x4000, 0x7fff, write8smo_delegate(*this, FUNC(msx_cart_dooly_device::prot_w))); + page(2)->install_write_handler(0x8000, 0xbfff, write8smo_delegate(*this, FUNC(msx_cart_dooly_device::prot_w))); +} - switch (m_prot) - { - case 0x04: - data = bitswap<8>(data, 7, 6, 5, 4, 3, 1, 0, 2); - break; - } - return data; - } - return 0xff; +u8 msx_cart_dooly_device::mode4_page1_r(offs_t offset) +{ + return bitswap<8>(get_rom_base()[offset], 7, 6, 5, 4, 3, 1, 0, 2); } +u8 msx_cart_dooly_device::mode4_page2_r(offs_t offset) +{ + return bitswap<8>(get_rom_base()[0x4000 | offset], 7, 6, 5, 4, 3, 1, 0, 2); +} -void msx_cart_dooly_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_dooly_device::prot_w(u8 data) { - if (offset >= 0x4000 && offset < 0xc000) + data &= 0x07; + m_view1.select(BIT(data, 2) ? 1 : 0); + m_view2.select(BIT(data, 2) ? 1 : 0); + if (data != 0 && data != 4) { - m_prot = data & 0x07; - if (m_prot != 0 && m_prot != 4) - { - logerror("msx_cart_dooly_device: unhandled write %02x to %04x\n", data, offset); - } + logerror("msx_cart_dooly_device: unhandled protection mode %02x\n", data); } } diff --git a/src/devices/bus/msx_cart/dooly.h b/src/devices/bus/msx_cart/dooly.h index 76f58ae762d..ceb4a29dc17 100644 --- a/src/devices/bus/msx_cart/dooly.h +++ b/src/devices/bus/msx_cart/dooly.h @@ -14,20 +14,22 @@ DECLARE_DEVICE_TYPE(MSX_CART_DOOLY, msx_cart_dooly_device) class msx_cart_dooly_device : public device_t, public msx_cart_interface { public: - msx_cart_dooly_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_dooly_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; private: - uint8_t m_prot; + void prot_w(u8 data); + u8 mode4_page1_r(offs_t offset); + u8 mode4_page2_r(offs_t offset); + + memory_view m_view1; + memory_view m_view2; }; diff --git a/src/devices/bus/msx_cart/easi_speech.cpp b/src/devices/bus/msx_cart/easi_speech.cpp index 0a9d2d5551d..381b26f06ff 100644 --- a/src/devices/bus/msx_cart/easi_speech.cpp +++ b/src/devices/bus/msx_cart/easi_speech.cpp @@ -17,21 +17,21 @@ a$=usr0("hello") DEFINE_DEVICE_TYPE(MSX_CART_EASISPEECH, msx_cart_easispeech_device, "msx_cart_easispeech", "MSX Cartridge - Easi-Speech") -msx_cart_easispeech_device::msx_cart_easispeech_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_easispeech_device::msx_cart_easispeech_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_EASISPEECH, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_speech(*this, "speech") { } -ROM_START( msx_cart_easispeech ) - ROM_REGION( 0x10000, "speech", 0 ) - ROM_LOAD( "sp0256a-al2", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc) ) +ROM_START(msx_cart_easispeech) + ROM_REGION(0x10000, "speech", 0) + ROM_LOAD("sp0256a-al2", 0x1000, 0x0800, CRC(b504ac15) SHA1(e60fcb5fa16ff3f3b69d36c7a6e955744d3feafc) ) ROM_END const tiny_rom_entry *msx_cart_easispeech_device::device_rom_region() const { - return ROM_NAME( msx_cart_easispeech ); + return ROM_NAME(msx_cart_easispeech); } void msx_cart_easispeech_device::device_add_mconfig(machine_config &config) @@ -40,22 +40,27 @@ void msx_cart_easispeech_device::device_add_mconfig(machine_config &config) m_speech->add_route(ALL_OUTPUTS, ":speaker", 1.00); } -uint8_t msx_cart_easispeech_device::read_cart(offs_t offset) +void msx_cart_easispeech_device::initialize_cartridge() { - // standard ROM - if (offset >= 0x4000 && offset < 0x8000) - return get_rom_base()[offset & 0x1fff]; + if (get_rom_size() != 0x2000) + { + fatalerror("easispeech: Invalid ROM size\n"); + } - // d7: SP0256 LRQ - if (offset == 0x8000) - return m_speech->lrq_r() << 7; + page(1)->install_rom(0x4000, 0x5fff, 0x2000, get_rom_base()); - return 0xff; + // Without this line the read and write handler don't get picked up?? + page(2)->install_rom(0x8000, 0x8000, get_rom_base()); + page(2)->install_read_handler(0x8000, 0x8000, read8smo_delegate(*this, FUNC(msx_cart_easispeech_device::speech_r))); + page(2)->install_write_handler(0x8000, 0x8000, write8smo_delegate(*this, FUNC(msx_cart_easispeech_device::speech_w))); } -void msx_cart_easispeech_device::write_cart(offs_t offset, uint8_t data) +u8 msx_cart_easispeech_device::speech_r() { - // d2-d7: SP0256 A - if (offset == 0x8000) - m_speech->ald_w(bitswap<6>(data,3,5,7,6,4,2)); + return m_speech->lrq_r() << 7; +} + +void msx_cart_easispeech_device::speech_w(u8 data) +{ + m_speech->ald_w(bitswap<6>(data,3,5,7,6,4,2)); } diff --git a/src/devices/bus/msx_cart/easi_speech.h b/src/devices/bus/msx_cart/easi_speech.h index 2aba350c4c7..9c40a2c85d4 100644 --- a/src/devices/bus/msx_cart/easi_speech.h +++ b/src/devices/bus/msx_cart/easi_speech.h @@ -15,18 +15,20 @@ DECLARE_DEVICE_TYPE(MSX_CART_EASISPEECH, msx_cart_easispeech_device) class msx_cart_easispeech_device : public device_t, public msx_cart_interface { public: - msx_cart_easispeech_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_easispeech_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; + virtual void initialize_cartridge() override; protected: // device-level overrides - virtual void device_start() override { ; } + virtual void device_start() override { } virtual void device_add_mconfig(machine_config &config) override; virtual const tiny_rom_entry *device_rom_region() const override; private: + u8 speech_r(); + void speech_w(u8 data); + required_device<sp0256_device> m_speech; }; diff --git a/src/devices/bus/msx_cart/fmpac.cpp b/src/devices/bus/msx_cart/fmpac.cpp index 75af22353dc..ab32020980f 100644 --- a/src/devices/bus/msx_cart/fmpac.cpp +++ b/src/devices/bus/msx_cart/fmpac.cpp @@ -14,17 +14,16 @@ with: PAC2 BACKUP DATA. We only store the raw sram contents. DEFINE_DEVICE_TYPE(MSX_CART_FMPAC, msx_cart_fmpac_device, "msx_cart_fmpac", "MSX Cartridge - FM-PAC") -msx_cart_fmpac_device::msx_cart_fmpac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_fmpac_device::msx_cart_fmpac_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_FMPAC, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_ym2413(*this, "ym2413") - , m_selected_bank(0) - , m_bank_base(nullptr) + , m_rombank(*this, "rombank") + , m_view(*this, "view") , m_sram_active(false) , m_opll_active(false) - , m_1ffe(0) - , m_1fff(0) - , m_7ff6(0) + , m_sram_unlock{0, 0} + , m_control(0) { } @@ -39,130 +38,87 @@ void msx_cart_fmpac_device::device_add_mconfig(machine_config &config) void msx_cart_fmpac_device::device_start() { - save_item(NAME(m_selected_bank)); save_item(NAME(m_sram_active)); save_item(NAME(m_opll_active)); - save_item(NAME(m_1ffe)); - save_item(NAME(m_1fff)); - save_item(NAME(m_7ff6)); + save_item(NAME(m_sram_unlock)); + save_item(NAME(m_control)); // Install IO read/write handlers io_space().install_write_handler(0x7c, 0x7d, write8sm_delegate(*this, FUNC(msx_cart_fmpac_device::write_ym2413))); } - -void msx_cart_fmpac_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_fmpac_device::restore_banks() -{ - m_bank_base = get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000; -} - - void msx_cart_fmpac_device::device_reset() { - m_selected_bank = 0; m_sram_active = false; m_opll_active = false; - m_1ffe = 0; - m_1fff = 0; - m_7ff6 = 0; -} + m_sram_unlock[0] = 0; + m_sram_unlock[1] = 0; + m_control = 0; + m_view.select(0); + m_rombank->set_entry(0); +} void msx_cart_fmpac_device::initialize_cartridge() { - if ( get_rom_size() != 0x10000 ) + if (get_rom_size() != 0x10000) { fatalerror("fmpac: Invalid ROM size\n"); } - - if ( get_sram_size() != 0x2000 ) + if (get_sram_size() != 0x2000) { fatalerror("fmpac: Invalid SRAM size\n"); } - restore_banks(); + m_rombank->configure_entries(0, 4, get_rom_base(), 0x4000); + + page(1)->install_view(0x4000, 0x7fff, m_view); + m_view[0].install_read_bank(0x4000, 0x7fff, m_rombank); + m_view[0].install_write_handler(0x5ffe, 0x5fff, write8sm_delegate(*this, FUNC(msx_cart_fmpac_device::sram_unlock))); + m_view[0].install_write_handler(0x7ff4, 0x7ff5, write8sm_delegate(*this, FUNC(msx_cart_fmpac_device::write_ym2413))); + m_view[0].install_read_handler(0x7ff6, 0x7ff6, read8smo_delegate(*this, FUNC(msx_cart_fmpac_device::control_r))); + m_view[0].install_write_handler(0x7ff6, 0x7ff6, write8smo_delegate(*this, FUNC(msx_cart_fmpac_device::control_w))); + m_view[0].install_read_handler(0x7ff7, 0x7ff7, read8smo_delegate(*this, FUNC(msx_cart_fmpac_device::bank_r))); + m_view[0].install_write_handler(0x7ff7, 0x7ff7, write8smo_delegate(*this, FUNC(msx_cart_fmpac_device::bank_w))); + + m_view[1].install_ram(0x4000, 0x5fff, get_sram_base()); + m_view[1].install_write_handler(0x5ffe, 0x5fff, write8sm_delegate(*this, FUNC(msx_cart_fmpac_device::sram_unlock))); + m_view[1].install_write_handler(0x7ff4, 0x7ff5, write8sm_delegate(*this, FUNC(msx_cart_fmpac_device::write_ym2413))); + m_view[1].install_read_handler(0x7ff6, 0x7ff6, read8smo_delegate(*this, FUNC(msx_cart_fmpac_device::control_r))); + m_view[1].install_write_handler(0x7ff6, 0x7ff6, write8smo_delegate(*this, FUNC(msx_cart_fmpac_device::control_w))); + m_view[1].install_read_handler(0x7ff7, 0x7ff7, read8smo_delegate(*this, FUNC(msx_cart_fmpac_device::bank_r))); + m_view[1].install_write_handler(0x7ff7, 0x7ff7, write8smo_delegate(*this, FUNC(msx_cart_fmpac_device::bank_w))); } - -uint8_t msx_cart_fmpac_device::read_cart(offs_t offset) +void msx_cart_fmpac_device::sram_unlock(offs_t offset, u8 data) { - if (offset >= 0x4000 && offset < 0x8000) - { - if (offset == 0x7ff6) - { - return m_7ff6; - } - if (offset == 0x7ff7) - { - return m_selected_bank & 0x03; - } - if (m_sram_active) - { - if (offset & 0x2000) - { - return 0xff; - } - return get_sram_base()[offset & 0x1fff]; - } - else - { - return m_bank_base[offset & 0x3fff]; - } - } - return 0xff; + m_sram_unlock[offset] = data; + m_sram_active = m_sram_unlock[0] == 0x4d && m_sram_unlock[1] == 0x69; + m_view.select(m_sram_active ? 1 : 0); } - -void msx_cart_fmpac_device::write_cart(offs_t offset, uint8_t data) +u8 msx_cart_fmpac_device::control_r() { - if (offset >= 0x4000 && offset < 0x6000) - { - if (m_sram_active) - { - get_sram_base()[offset & 0x1fff] = data; - } - if (offset == 0x5ffe) - { - m_1ffe = data; - } - if (offset == 0x5fff) - { - m_1fff = data; - } - m_sram_active = (m_1ffe == 0x4d) && (m_1fff == 0x69); - } + return m_control; +} - switch (offset) - { - case 0x7ff4: - case 0x7ff5: - if (m_opll_active) - { - m_ym2413->write(offset & 1, data); - } - break; - - case 0x7ff6: - m_7ff6 = data & 0x11; - m_opll_active = (m_7ff6 & 0x01); - break; - - case 0x7ff7: - m_selected_bank = data; - restore_banks(); - break; - } +void msx_cart_fmpac_device::control_w(u8 data) +{ + m_control = data & 0x11; + m_opll_active = BIT(data, 0); +} +u8 msx_cart_fmpac_device::bank_r() +{ + return m_rombank->entry(); } +void msx_cart_fmpac_device::bank_w(u8 data) +{ + m_rombank->set_entry(data); +} -void msx_cart_fmpac_device::write_ym2413(offs_t offset, uint8_t data) +void msx_cart_fmpac_device::write_ym2413(offs_t offset, u8 data) { if (m_opll_active) { diff --git a/src/devices/bus/msx_cart/fmpac.h b/src/devices/bus/msx_cart/fmpac.h index 9175849eaba..c12937c80a8 100644 --- a/src/devices/bus/msx_cart/fmpac.h +++ b/src/devices/bus/msx_cart/fmpac.h @@ -15,35 +15,33 @@ DECLARE_DEVICE_TYPE(MSX_CART_FMPAC, msx_cart_fmpac_device) class msx_cart_fmpac_device : public device_t, public msx_cart_interface { public: - msx_cart_fmpac_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_fmpac_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: virtual void device_start() override; virtual void device_reset() override; - virtual void device_post_load() override; // device-level overrides virtual void device_add_mconfig(machine_config &config) override; - void restore_banks(); - private: - void write_ym2413(offs_t offset, uint8_t data); + void write_ym2413(offs_t offset, u8 data); + void sram_unlock(offs_t offset, u8 data); + u8 control_r(); + void control_w(u8 data); + u8 bank_r(); + void bank_w(u8 data); required_device<ym2413_device> m_ym2413; + memory_bank_creator m_rombank; + memory_view m_view; - uint8_t m_selected_bank; - uint8_t *m_bank_base; bool m_sram_active; bool m_opll_active; - uint8_t m_1ffe; - uint8_t m_1fff; - uint8_t m_7ff6; + u8 m_sram_unlock[2]; + u8 m_control; }; diff --git a/src/devices/bus/msx_cart/fs_sr022.cpp b/src/devices/bus/msx_cart/fs_sr022.cpp index bb84a759214..fd19f43547a 100644 --- a/src/devices/bus/msx_cart/fs_sr022.cpp +++ b/src/devices/bus/msx_cart/fs_sr022.cpp @@ -15,19 +15,16 @@ msx_cart_fs_sr022_device::msx_cart_fs_sr022_device(const machine_config &mconfig { } - void msx_cart_fs_sr022_device::device_start() { save_item(NAME(m_bunsetsu_address)); } - void msx_cart_fs_sr022_device::device_reset() { m_bunsetsu_address = 0; } - void msx_cart_fs_sr022_device::initialize_cartridge() { if (get_rom_size() != 0x40000) @@ -35,36 +32,34 @@ void msx_cart_fs_sr022_device::initialize_cartridge() fatalerror("fs_sr022: Invalid ROM size\n"); } m_bunsetsu_rom = get_rom_base() + 0x20000; -} + page(1)->install_rom(0x4000, 0x7fff, get_rom_base()); + page(2)->install_rom(0x8000, 0xbfff, get_rom_base() + 0x4000); + page(2)->install_read_handler(0xbfff, 0xbfff, read8smo_delegate(*this, FUNC(msx_cart_fs_sr022_device::buns_r))); + page(2)->install_write_handler(0xbffc, 0xbffe, write8sm_delegate(*this, FUNC(msx_cart_fs_sr022_device::buns_w))); +} -uint8_t msx_cart_fs_sr022_device::read_cart(offs_t offset) +u8 msx_cart_fs_sr022_device::buns_r() { - if (offset >= 0x4000 && offset < 0xc000) - { - if (offset == 0xbfff) { - return m_bunsetsu_rom[m_bunsetsu_address++ & 0x1ffff]; - } - - return get_rom_base()[offset - 0x4000]; - } - return 0xff; + u8 data = m_bunsetsu_rom[m_bunsetsu_address & 0x1ffff]; + if (!machine().side_effects_disabled()) + m_bunsetsu_address++; + return data; } - -void msx_cart_fs_sr022_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_fs_sr022_device::buns_w(offs_t offset, uint8_t 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_cart/fs_sr022.h b/src/devices/bus/msx_cart/fs_sr022.h index 2456b90a101..677dd723e17 100644 --- a/src/devices/bus/msx_cart/fs_sr022.h +++ b/src/devices/bus/msx_cart/fs_sr022.h @@ -18,17 +18,17 @@ public: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; private: - const uint8_t *m_bunsetsu_rom; - uint32_t m_bunsetsu_address; + u8 buns_r(); + void buns_w(offs_t offset, u8 data); + + u8 *m_bunsetsu_rom; + u32 m_bunsetsu_address; }; diff --git a/src/devices/bus/msx_cart/halnote.cpp b/src/devices/bus/msx_cart/halnote.cpp index 43f7947ec2c..5bbed142a27 100644 --- a/src/devices/bus/msx_cart/halnote.cpp +++ b/src/devices/bus/msx_cart/halnote.cpp @@ -7,154 +7,92 @@ DEFINE_DEVICE_TYPE(MSX_CART_HALNOTE, msx_cart_halnote_device, "msx_cart_halnote", "MSX Cartridge - Halnote") -msx_cart_halnote_device::msx_cart_halnote_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_halnote_device::msx_cart_halnote_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_HALNOTE, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_selected_bank{ 0, 0, 0, 0, 0, 0, 0, 0 } - , m_bank_base{ nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr } + , m_rombank(*this, "rombank%u", 0U) + , m_view0(*this, "view0") + , m_view1(*this, "view1") { } - -void msx_cart_halnote_device::device_start() +void msx_cart_halnote_device::device_reset() { - save_item(NAME(m_selected_bank)); -} + for (int i = 0; i < 6; i++) + m_rombank[i]->set_entry(0); - -void msx_cart_halnote_device::device_post_load() -{ - restore_banks(); + m_view0.disable(); + m_view1.select(0); } - -void msx_cart_halnote_device::map_bank(int bank) +void msx_cart_halnote_device::initialize_cartridge() { - if (bank < 2) + if (get_rom_size() != 0x100000) { - return; + fatalerror("halnote: Invalid ROM size\n"); } - - // Special banks - if (bank == 6 || bank == 7) + if (get_sram_size() != 0x4000) { - m_bank_base[bank] = get_rom_base() + 0x80000 + (m_selected_bank[bank] * 0x800); - return; + fatalerror("halnote: Invalid SRAM size\n"); } - m_bank_base[bank] = get_rom_base() + ((m_selected_bank[bank] * 0x2000) & 0xFFFFF); - if (bank == 2) + for (int i = 0; i < 4; i++) { - if (m_selected_bank[bank] & 0x80) - { - m_bank_base[0] = get_sram_base(); - m_bank_base[1] = get_sram_base() + 0x2000; - } - else - { - m_bank_base[0] = nullptr; - m_bank_base[1] = nullptr; - } + m_rombank[i]->configure_entries(0, 0x80, get_rom_base(), 0x2000); } + m_rombank[4]->configure_entries(0, 0x100, get_rom_base() + 0x80000, 0x800); + m_rombank[5]->configure_entries(0, 0x100, get_rom_base() + 0x80000, 0x800); + + page(0)->install_view(0x0000, 0x3fff, m_view0); + m_view0[0]; + m_view0[1].install_ram(0x0000, 0x3fff, get_sram_base()); + page(1)->install_read_bank(0x4000, 0x5fff, m_rombank[0]); + page(1)->install_write_handler(0x4fff, 0x4fff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank0_w))); + page(1)->install_view(0x6000, 0x7fff, m_view1); + m_view1[0].install_read_bank(0x6000, 0x7fff, m_rombank[1]); + m_view1[0].install_write_handler(0x6fff, 0x6fff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank1_w))); + m_view1[0].install_write_handler(0x77ff, 0x77ff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank4_w))); + m_view1[0].install_write_handler(0x7fff, 0x7fff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank5_w))); + m_view1[1].install_read_bank(0x6000, 0x6fff, m_rombank[1]); + m_view1[1].install_write_handler(0x6fff, 0x6fff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank1_w))); + m_view1[1].install_read_bank(0x7000, 0x77ff, m_rombank[4]); + m_view1[1].install_write_handler(0x77ff, 0x77ff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank4_w))); + m_view1[1].install_read_bank(0x7800, 0x7fff, m_rombank[5]); + m_view1[1].install_write_handler(0x7fff, 0x7fff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank5_w))); + page(2)->install_read_bank(0x8000, 0x9fff, m_rombank[2]); + page(2)->install_write_handler(0x8fff, 0x8fff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank2_w))); + page(2)->install_read_bank(0xa000, 0xbfff, m_rombank[3]); + page(2)->install_write_handler(0xafff, 0xafff, write8smo_delegate(*this, FUNC(msx_cart_halnote_device::bank3_w))); } - -void msx_cart_halnote_device::restore_banks() +void msx_cart_halnote_device::bank0_w(u8 data) { - for (int i = 0; i < 8; i++) - { - map_bank(i); - } + m_rombank[0]->set_entry(data & 0x7f); + m_view0.select(BIT(data, 7) ? 1 : 0); } - -void msx_cart_halnote_device::device_reset() +void msx_cart_halnote_device::bank1_w(u8 data) { - for (auto & elem : m_selected_bank) - { - elem = 0; - } + m_rombank[1]->set_entry(data & 0x7f); } - -void msx_cart_halnote_device::initialize_cartridge() +void msx_cart_halnote_device::bank2_w(u8 data) { - if (get_rom_size() != 0x100000) - { - fatalerror("halnote: Invalid ROM size\n"); - } - - restore_banks(); + m_rombank[2]->set_entry(data & 0x7f); } - -uint8_t msx_cart_halnote_device::read_cart(offs_t offset) +void msx_cart_halnote_device::bank3_w(u8 data) { - 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_rombank[3]->set_entry(data & 0x7f); + m_view1.select(BIT(data, 7) ? 1 : 0); } - -void msx_cart_halnote_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_halnote_device::bank4_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; + m_rombank[4]->set_entry(data); +} - default: - logerror("msx_cart_halnote_device: Unhandled write %02x to %04x\n", data, offset); - break; - } +void msx_cart_halnote_device::bank5_w(u8 data) +{ + m_rombank[5]->set_entry(data); } diff --git a/src/devices/bus/msx_cart/halnote.h b/src/devices/bus/msx_cart/halnote.h index a9c1972afeb..eaaef27e7a5 100644 --- a/src/devices/bus/msx_cart/halnote.h +++ b/src/devices/bus/msx_cart/halnote.h @@ -14,26 +14,28 @@ DECLARE_DEVICE_TYPE(MSX_CART_HALNOTE, msx_cart_halnote_device) class msx_cart_halnote_device : public device_t, public msx_cart_interface { public: - msx_cart_halnote_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_halnote_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_selected_bank[8]; - uint8_t *m_bank_base[8]; - - void map_bank(int bank); + static constexpr u8 BANK_MASK = (0x100000 / 0x2000) - 1; + + void bank0_w(u8 data); + void bank1_w(u8 data); + void bank2_w(u8 data); + void bank3_w(u8 data); + void bank4_w(u8 data); + void bank5_w(u8 data); + + memory_bank_array_creator<6> m_rombank; + memory_view m_view0; + memory_view m_view1; }; diff --git a/src/devices/bus/msx_cart/hfox.cpp b/src/devices/bus/msx_cart/hfox.cpp index 007155b6e5b..5945e399e35 100644 --- a/src/devices/bus/msx_cart/hfox.cpp +++ b/src/devices/bus/msx_cart/hfox.cpp @@ -7,77 +7,42 @@ DEFINE_DEVICE_TYPE(MSX_CART_HFOX, msx_cart_hfox_device, "msx_cart_hfox", "MSX Cartridge - Hurry Fox") -msx_cart_hfox_device::msx_cart_hfox_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_hfox_device::msx_cart_hfox_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_HFOX, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_selected_bank{ 0, 0 } - , m_bank_base{ nullptr, nullptr } + , m_rombank(*this, "rombank%u", 0U) { } - -void msx_cart_hfox_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_hfox_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_hfox_device::restore_banks() -{ - m_bank_base[0] = get_rom_base() + ((m_selected_bank[0] & 0x01) * 0x8000); - m_bank_base[1] = get_rom_base() + ((m_selected_bank[1] & 0x01) * 0x8000) + 0x4000; -} - - void msx_cart_hfox_device::device_reset() { - m_selected_bank[0] = m_selected_bank[1] = 0; + m_rombank[0]->set_entry(0); + m_rombank[1]->set_entry(0); } - void msx_cart_hfox_device::initialize_cartridge() { - if (get_rom_size() < 0x10000) + u32 size = get_rom_size(); + u16 banks = size / 0x8000; + + if (size > 256 * 0x8000 || size < 0x10000 || size != banks * 0x8000 || (~(banks - 1) % banks)) { fatalerror("hfox: Invalid ROM size\n"); } - restore_banks(); -} + m_bank_mask = banks - 1; + m_rombank[0]->configure_entries(0, 4, get_rom_base(), 0x8000); + m_rombank[1]->configure_entries(0, 4, get_rom_base() + 0x4000, 0x8000); -uint8_t msx_cart_hfox_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000) - { - return m_bank_base[offset >> 15][offset & 0x3fff]; - } - return 0xff; + page(1)->install_read_bank(0x4000, 0x7fff, m_rombank[0]); + page(1)->install_write_handler(0x6000, 0x6000, write8smo_delegate(*this, FUNC(msx_cart_hfox_device::bank_w<0>))); + page(1)->install_write_handler(0x7000, 0x7000, write8smo_delegate(*this, FUNC(msx_cart_hfox_device::bank_w<1>))); + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank[1]); } - -void msx_cart_hfox_device::write_cart(offs_t offset, uint8_t data) +template <int Bank> +void msx_cart_hfox_device::bank_w(u8 data) { - switch (offset) - { - case 0x6000: - m_selected_bank[0] = data; - restore_banks(); - break; - - case 0x7000: - m_selected_bank[1] = data; - restore_banks(); - break; - - default: - logerror("msx_cart_hfox_device: unhandled write %02x to %04x\n", data, offset); - break; - } + m_rombank[Bank]->set_entry(data & m_bank_mask); } diff --git a/src/devices/bus/msx_cart/hfox.h b/src/devices/bus/msx_cart/hfox.h index 6254bae3610..eda1562bf04 100644 --- a/src/devices/bus/msx_cart/hfox.h +++ b/src/devices/bus/msx_cart/hfox.h @@ -3,6 +3,8 @@ #ifndef MAME_BUS_MSX_CART_HFOX_H #define MAME_BUS_MSX_CART_HFOX_H +#pragma once + #include "bus/msx_cart/cartridge.h" @@ -16,20 +18,17 @@ public: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_selected_bank[2]; - uint8_t *m_bank_base[2]; + template <int Bank> void bank_w(u8 data); + + memory_bank_array_creator<2> m_rombank; + + u8 m_bank_mask; }; diff --git a/src/devices/bus/msx_cart/holy_quran.cpp b/src/devices/bus/msx_cart/holy_quran.cpp index fbfb799fad5..cc87db1b435 100644 --- a/src/devices/bus/msx_cart/holy_quran.cpp +++ b/src/devices/bus/msx_cart/holy_quran.cpp @@ -16,85 +16,91 @@ GCMK-16X PCB, 2 ROM chips, Yamaha XE297A0 mapper chip. DEFINE_DEVICE_TYPE(MSX_CART_HOLY_QURAN, msx_cart_holy_quran_device, "msx_cart_holy_quran", "MSX Cartridge - Holy Quran") -msx_cart_holy_quran_device::msx_cart_holy_quran_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_holy_quran_device::msx_cart_holy_quran_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_HOLY_QURAN, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) + , m_view1(*this, "view1") + , m_view2(*this, "view2") { } -void msx_cart_holy_quran_device::device_start() -{ - // zerofill - m_decrypt = false; - std::fill_n(&m_selected_bank[0], 4, 0); - std::fill_n(&m_bank_base[0], 4, nullptr); - - // register for savestates - save_item(NAME(m_selected_bank)); - save_item(NAME(m_decrypt)); - - // protection uses a simple rotation on databus, some lines inverted - for (int i = 0; i < 0x100; i++) - m_lookup_prot[i] = bitswap<8>(i,6,2,4,0,1,5,7,3) ^ 0x4d; -} - void msx_cart_holy_quran_device::initialize_cartridge() { - if (get_rom_size() != 0x100000) + u32 size = get_rom_size(); + u16 banks = size / BANK_SIZE; + + if (size > 256 * BANK_SIZE || size < 0x10000 || size != banks * BANK_SIZE || (~(banks - 1) % banks)) { fatalerror("holy_quran: Invalid ROM size\n"); } - restore_banks(); -} + m_bank_mask = banks - 1; -void msx_cart_holy_quran_device::device_reset() -{ - m_decrypt = false; + m_decrypted.resize(size); + + u8 lookup_prot[256]; + // protection uses a simple rotation on databus, some lines inverted + for (int i = 0; i < 0x100; i++) + lookup_prot[i] = bitswap<8>(i,6,2,4,0,1,5,7,3) ^ 0x4d; + + for (u32 i = 0; i < size; i++) + m_decrypted[i] = lookup_prot[m_rom[i]]; - std::fill_n(&m_selected_bank[0], 4, 0); - restore_banks(); + for (int i = 0; i < 4; i++) + m_rombank[i]->configure_entries(0, banks, m_decrypted.data(), BANK_SIZE); + + page(1)->install_view(0x4000, 0x7fff, m_view1); + m_view1[0].install_read_handler(0x4000, 0x7fff, read8sm_delegate(*this, FUNC(msx_cart_holy_quran_device::read))); + m_view1[1].install_read_bank(0x4000, 0x5fff, m_rombank[0]); + m_view1[1].install_read_bank(0x6000, 0x7fff, m_rombank[1]); + m_view1[1].install_write_handler(0x5000, 0x5000, write8smo_delegate(*this, FUNC(msx_cart_holy_quran_device::bank_w<0>))); + m_view1[1].install_write_handler(0x5400, 0x5400, write8smo_delegate(*this, FUNC(msx_cart_holy_quran_device::bank_w<1>))); + m_view1[1].install_write_handler(0x5800, 0x5800, write8smo_delegate(*this, FUNC(msx_cart_holy_quran_device::bank_w<2>))); + m_view1[1].install_write_handler(0x5c00, 0x5c00, write8smo_delegate(*this, FUNC(msx_cart_holy_quran_device::bank_w<3>))); + + page(2)->install_view(0x8000, 0xbfff, m_view2); + m_view2[0].install_read_handler(0x8000, 0xbfff, read8sm_delegate(*this, FUNC(msx_cart_holy_quran_device::read2))); + m_view2[1].install_read_bank(0x8000, 0x9fff, m_rombank[2]); + m_view2[1].install_read_bank(0xa000, 0xbfff, m_rombank[3]); } -void msx_cart_holy_quran_device::restore_banks() +void msx_cart_holy_quran_device::device_reset() { + m_view1.select(0); + m_view2.select(0); for (int i = 0; i < 4; i++) - m_bank_base[i] = get_rom_base() + (m_selected_bank[i] & 0x7f) * 0x2000; + m_rombank[i]->set_entry(0); } - -// mapper interface - -uint8_t msx_cart_holy_quran_device::read_cart(offs_t offset) +u8 msx_cart_holy_quran_device::read(offs_t offset) { - if (offset >= 0x4000 && offset < 0xc000) + u8 data = m_rom[offset]; + // The decryption should actually start working after the first M1 cycle executing something from the cartridge. + if (offset + 0x4000 == ((m_rom[3] << 8) | m_rom[2]) && !machine().side_effects_disabled()) { - uint8_t data = m_bank_base[(offset - 0x4000) >> 13][offset & 0x1fff]; - - if (m_decrypt) - return m_lookup_prot[data]; - - // The decryption should actually start working after the first M1 cycle executing something from the cartridge. - if (offset == ((m_rom[3] << 8) | m_rom[2]) && !machine().side_effects_disabled()) - m_decrypt = true; - - return data; + // Switch to decrypted contents + m_view1.select(1); + m_view2.select(1); } - - return 0xff; + return data; } -void msx_cart_holy_quran_device::write_cart(offs_t offset, uint8_t data) +u8 msx_cart_holy_quran_device::read2(offs_t offset) { - switch (offset) + u8 data = m_rom[offset + 0x4000]; + // The decryption should actually start working after the first M1 cycle executing something from the cartridge. + if (offset + 0x8000 == ((m_rom[3] << 8) | m_rom[2]) && !machine().side_effects_disabled()) { - case 0x5000: case 0x5400: case 0x5800: case 0x5c00: - m_selected_bank[offset >> 10 & 3] = data; - restore_banks(); - break; - - default: - logerror("msx_cart_holy_quran_device: unhandled write %02x to %04x\n", data, offset); - break; + // Switch to decrypted contents + m_view1.select(1); + m_view2.select(1); } + return data; +} + +template <int Bank> +void msx_cart_holy_quran_device::bank_w(u8 data) +{ + m_rombank[Bank]->set_entry(data & m_bank_mask); } diff --git a/src/devices/bus/msx_cart/holy_quran.h b/src/devices/bus/msx_cart/holy_quran.h index 25b1ddf8f50..0e8d73afbef 100644 --- a/src/devices/bus/msx_cart/holy_quran.h +++ b/src/devices/bus/msx_cart/holy_quran.h @@ -14,26 +14,28 @@ DECLARE_DEVICE_TYPE(MSX_CART_HOLY_QURAN, msx_cart_holy_quran_device) class msx_cart_holy_quran_device : public device_t, public msx_cart_interface { public: - msx_cart_holy_quran_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_holy_quran_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override { restore_banks(); } - - void restore_banks(); private: - uint8_t m_lookup_prot[256]; - uint8_t m_selected_bank[4]; - uint8_t *m_bank_base[4]; - bool m_decrypt; + static constexpr size_t BANK_SIZE = 0x2000; + + u8 read(offs_t offset); + u8 read2(offs_t offset); + template <int Bank> void bank_w(u8 data); + + memory_bank_array_creator<4> m_rombank; + memory_view m_view1; + memory_view m_view2; + + std::vector<u8> m_decrypted; + u8 m_bank_mask; }; diff --git a/src/devices/bus/msx_cart/ink.cpp b/src/devices/bus/msx_cart/ink.cpp index e3053a5da7d..abf48b37154 100644 --- a/src/devices/bus/msx_cart/ink.cpp +++ b/src/devices/bus/msx_cart/ink.cpp @@ -22,13 +22,13 @@ msx_cart_ink_device::msx_cart_ink_device(const machine_config &mconfig, const ch { } -ROM_START( msx_cart_ink ) +ROM_START(msx_cart_ink) ROM_REGION(0x80000, "flash", ROMREGION_ERASEFF) ROM_END const tiny_rom_entry *msx_cart_ink_device::device_rom_region() const { - return ROM_NAME( msx_cart_ink ); + return ROM_NAME(msx_cart_ink); } void msx_cart_ink_device::device_add_mconfig(machine_config &config) @@ -38,18 +38,24 @@ void msx_cart_ink_device::device_add_mconfig(machine_config &config) void msx_cart_ink_device::initialize_cartridge() { - size_t size = get_rom_size() > 0x80000 ? 0x80000 : get_rom_size(); - memcpy(memregion("flash")->base(), get_rom_base(), size); + size_t size = std::min<size_t>(0x80000, get_rom_size()); + + u8 *flash = memregion("flash")->base(); + memcpy(flash, get_rom_base(), size); + + page(0)->install_rom(0x0000, 0x3fff, flash); + page(1)->install_rom(0x4000, 0x7fff, flash + 0x4000); + page(2)->install_rom(0x8000, 0xbfff, flash + 0x8000); + page(3)->install_rom(0xc000, 0xffff, flash + 0xc000); + page(0)->install_write_handler(0x0000, 0x3fff, write8sm_delegate(*this, FUNC(msx_cart_ink_device::write_page<0>))); + page(1)->install_write_handler(0x4000, 0x7fff, write8sm_delegate(*this, FUNC(msx_cart_ink_device::write_page<1>))); + page(2)->install_write_handler(0x8000, 0xbfff, write8sm_delegate(*this, FUNC(msx_cart_ink_device::write_page<2>))); + page(3)->install_write_handler(0xc000, 0xffff, write8sm_delegate(*this, FUNC(msx_cart_ink_device::write_page<3>))); } - -uint8_t msx_cart_ink_device::read_cart(offs_t offset) -{ - return m_flash->read(offset); -} - -void msx_cart_ink_device::write_cart(offs_t offset, uint8_t data) +template <int Page> +void msx_cart_ink_device::write_page(offs_t offset, u8 data) { // /RD connects to flashrom A16-A18 - m_flash->write(offset | 0x70000, data); + m_flash->write(offset | 0x70000 | (Page * 0x4000), data); } diff --git a/src/devices/bus/msx_cart/ink.h b/src/devices/bus/msx_cart/ink.h index 933385c575d..eb857dd147d 100644 --- a/src/devices/bus/msx_cart/ink.h +++ b/src/devices/bus/msx_cart/ink.h @@ -19,17 +19,16 @@ public: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override { ; } + virtual void device_start() override { } virtual void device_add_mconfig(machine_config &config) override; virtual const tiny_rom_entry *device_rom_region() const override; private: required_device<amd_29f040_device> m_flash; + + template <int Page> void write_page(offs_t offset, u8 data); }; diff --git a/src/devices/bus/msx_cart/kanji.cpp b/src/devices/bus/msx_cart/kanji.cpp new file mode 100644 index 00000000000..215121d7559 --- /dev/null +++ b/src/devices/bus/msx_cart/kanji.cpp @@ -0,0 +1,147 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +/********************************************************************************** + +TODO: +- Verify real contents of the kanji roms. The current dumps seem to have + been read from inside a running MSX machine. The content retrieved that + way may not be how they are stored in the rom. + +**********************************************************************************/ + +#include "emu.h" +#include "kanji.h" + +#include "speaker.h" + + +#define VERBOSE 0 +#include "logmacro.h" + + +DEFINE_DEVICE_TYPE(MSX_CART_KANJI, msx_cart_kanji_device, "msx_cart_kanji", "MSX Cartridge - Kanji") +DEFINE_DEVICE_TYPE(MSX_CART_MSXWRITE, msx_cart_msxwrite_device, "msx_cart_msxwrite", "MSX Cartridge - MSXWRITE") + + +msx_cart_kanji_device::msx_cart_kanji_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : msx_cart_kanji_device(mconfig, MSX_CART_KANJI, tag, owner, clock) +{ +} + +msx_cart_kanji_device::msx_cart_kanji_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , msx_cart_interface(mconfig, *this) + , m_kanji_mask(0) + , m_kanji_address(0) +{ +} + +void msx_cart_kanji_device::device_reset() +{ + m_kanji_address = 0; +} + +void msx_cart_kanji_device::device_start() +{ + save_item(NAME(m_kanji_address)); +} + +void msx_cart_kanji_device::initialize_cartridge() +{ + u32 size = get_kanji_size(); + + if (size != 0x20000) + { + fatalerror("kanji: Invalid ROM size\n"); + } + + m_kanji_mask = size - 1; + + // Install IO read/write handlers + io_space().install_write_handler(0xd8, 0xd9, write8sm_delegate(*this, FUNC(msx_cart_kanji_device::kanji_w))); + io_space().install_read_handler(0xd9, 0xd9, read8sm_delegate(*this, FUNC(msx_cart_kanji_device::kanji_r))); +} + +u8 msx_cart_kanji_device::kanji_r(offs_t offset) +{ + u8 result = get_kanji_base()[m_kanji_address]; + + if (!machine().side_effects_disabled()) + { + m_kanji_address = (m_kanji_address & ~0x1f) | ((m_kanji_address + 1) & 0x1f); + } + return result; +} + +void msx_cart_kanji_device::kanji_w(offs_t offset, u8 data) +{ + if (offset) + m_kanji_address = (m_kanji_address & 0x007e0) | ((data & 0x3f) << 11); + else + m_kanji_address = (m_kanji_address & 0x1f800) | ((data & 0x3f) << 5); + + m_kanji_address = m_kanji_address & m_kanji_mask; +} + + + +static INPUT_PORTS_START(msxwrite_kanji_enable_switch) + PORT_START("KANJI") + PORT_CONFNAME(0x01, 0x01, "Kanji is") + PORT_CONFSETTING(0x00, "disabled") + PORT_CONFSETTING(0x01, "enabled") +INPUT_PORTS_END + + +msx_cart_msxwrite_device::msx_cart_msxwrite_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : msx_cart_kanji_device(mconfig, MSX_CART_MSXWRITE, tag, owner, clock) + , m_rombank(*this, "rombank%u", 0U) + , m_kanji_switch(*this, "KANJI") + , m_bank_mask(0) +{ +} + +ioport_constructor msx_cart_msxwrite_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(msxwrite_kanji_enable_switch); +} + +void msx_cart_msxwrite_device::device_reset() +{ + msx_cart_kanji_device::device_reset(); + + m_rombank[0]->set_entry(0); + m_rombank[1]->set_entry(0); + + if (BIT(m_kanji_switch->read(), 0)) + msx_cart_kanji_device::initialize_cartridge(); +} + +void msx_cart_msxwrite_device::initialize_cartridge() +{ + u32 size = get_rom_size(); + u16 banks = size / BANK_SIZE; + + if (size > 256 * BANK_SIZE || size != banks * BANK_SIZE || (~(banks - 1) % banks)) + { + fatalerror("msxwrite: Invalid ROM size\n"); + } + + m_bank_mask = banks - 1; + + for (int i = 0; i < 2; i++) + m_rombank[i]->configure_entries(0, banks, get_rom_base(), BANK_SIZE); + + page(1)->install_read_bank(0x4000, 0x7fff, m_rombank[0]); + // The rom writes to 6fff and 7fff for banking, unknown whether + // other locations also trigger banking. + page(1)->install_write_handler(0x6fff, 0x6fff, write8smo_delegate(*this, FUNC(msx_cart_msxwrite_device::bank_w<0>))); + page(1)->install_write_handler(0x7fff, 0x7fff, write8smo_delegate(*this, FUNC(msx_cart_msxwrite_device::bank_w<1>))); + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank[1]); +} + +template <int Bank> +void msx_cart_msxwrite_device::bank_w(u8 data) +{ + m_rombank[Bank]->set_entry(data & m_bank_mask); +} diff --git a/src/devices/bus/msx_cart/kanji.h b/src/devices/bus/msx_cart/kanji.h new file mode 100644 index 00000000000..ed420750056 --- /dev/null +++ b/src/devices/bus/msx_cart/kanji.h @@ -0,0 +1,59 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +#ifndef MAME_BUS_MSX_CART_KANJI_H +#define MAME_BUS_MSX_CART_KANJI_H + +#pragma once + +#include "bus/msx_cart/cartridge.h" + + +DECLARE_DEVICE_TYPE(MSX_CART_KANJI, msx_cart_kanji_device) +DECLARE_DEVICE_TYPE(MSX_CART_MSXWRITE, msx_cart_msxwrite_device) + + +class msx_cart_kanji_device : public device_t, public msx_cart_interface +{ +public: + msx_cart_kanji_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual void initialize_cartridge() override; + +protected: + msx_cart_kanji_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + u8 kanji_r(offs_t offset); + void kanji_w(offs_t offset, u8 data); + + u32 m_kanji_mask; + u32 m_kanji_address; +}; + + +class msx_cart_msxwrite_device : public msx_cart_kanji_device +{ +public: + msx_cart_msxwrite_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual void initialize_cartridge() override; + +protected: + // device-level overrides + virtual void device_reset() override; + virtual ioport_constructor device_input_ports() const override; + +private: + static constexpr size_t BANK_SIZE = 0x4000; + + template <int Bank> void bank_w(u8 data); + + memory_bank_array_creator<2> m_rombank; + required_ioport m_kanji_switch; + u8 m_bank_mask; +}; + +#endif // MAME_BUS_MSX_CART_KANJI_H diff --git a/src/devices/bus/msx_cart/konami.cpp b/src/devices/bus/msx_cart/konami.cpp index 5954cb95091..d9774e138e2 100644 --- a/src/devices/bus/msx_cart/konami.cpp +++ b/src/devices/bus/msx_cart/konami.cpp @@ -15,112 +15,53 @@ DEFINE_DEVICE_TYPE(MSX_CART_SOUND_SDSNATCHER, msx_cart_konami_sound_sdsnatcher_d DEFINE_DEVICE_TYPE(MSX_CART_KEYBOARD_MASTER, msx_cart_keyboard_master_device, "msx_cart_keyboard_master", "MSX Cartridge - Keyboard Master") -msx_cart_konami_device::msx_cart_konami_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_konami_device::msx_cart_konami_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_KONAMI, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) , m_bank_mask(0) { - for (int i = 0; i < 4; i++) - { - m_selected_bank[i] = i; - } - for (auto & elem : m_bank_base) - { - elem = nullptr; - } -} - - -void msx_cart_konami_device::device_start() -{ - save_item(NAME(m_selected_bank)); } - -void msx_cart_konami_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_konami_device::restore_banks() -{ - m_bank_base[0] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000; - m_bank_base[1] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000; - m_bank_base[2] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000; - m_bank_base[3] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000; - m_bank_base[4] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000; - m_bank_base[5] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000; - m_bank_base[6] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000; - m_bank_base[7] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000; -} - - void msx_cart_konami_device::device_reset() { for (int i = 0; i < 4; i++) - { - m_selected_bank[i] = i; - } + m_rombank[i]->set_entry(i); } - void msx_cart_konami_device::initialize_cartridge() { - uint32_t size = get_rom_size(); + u32 size = get_rom_size(); + u16 banks = size / 0x2000; - if ( get_rom_size() > 256 * 0x2000 ) - { - fatalerror("konami: ROM is too big\n"); - } - - uint16_t banks = size / 0x2000; - - if (size != banks * 0x2000 || (~(banks - 1) % banks)) + if (size > 256 * 0x2000 || size < 4 * 0x2000 || size != banks * 0x2000 || (~(banks - 1) % banks)) { fatalerror("konami: Invalid ROM size\n"); } m_bank_mask = banks - 1; - restore_banks(); -} - + for (int i = 0; i < 4; i++) + m_rombank[i]->configure_entries(0, banks, get_rom_base(), 0x2000); -uint8_t msx_cart_konami_device::read_cart(offs_t offset) -{ - return m_bank_base[offset >> 13][offset & 0x1fff]; + page(0)->install_read_bank(0x0000, 0x1fff, m_rombank[0]); + page(0)->install_read_bank(0x2000, 0x3fff, m_rombank[1]); + page(1)->install_read_bank(0x4000, 0x5fff, m_rombank[0]); + page(1)->install_write_handler(0x4000, 0x47ff, 0, 0x1000, 0, write8smo_delegate(*this, FUNC(msx_cart_konami_device::bank_w<0>))); + page(1)->install_read_bank(0x6000, 0x7fff, m_rombank[1]); + page(1)->install_write_handler(0x6000, 0x67ff, 0, 0x1000, 0, write8smo_delegate(*this, FUNC(msx_cart_konami_device::bank_w<1>))); + page(2)->install_read_bank(0x8000, 0x9fff, m_rombank[2]); + page(2)->install_write_handler(0x8000, 0x87ff, 0, 0x1000, 0, write8smo_delegate(*this, FUNC(msx_cart_konami_device::bank_w<2>))); + page(2)->install_read_bank(0xa000, 0xbfff, m_rombank[3]); + page(2)->install_write_handler(0xa000, 0xa7ff, 0, 0x1000, 0, write8smo_delegate(*this, FUNC(msx_cart_konami_device::bank_w<3>))); + page(3)->install_read_bank(0xc000, 0xdfff, m_rombank[2]); + page(3)->install_read_bank(0xe000, 0xffff, m_rombank[3]); } - -void msx_cart_konami_device::write_cart(offs_t offset, uint8_t data) +template <int Bank> +void msx_cart_konami_device::bank_w(u8 data) { - switch (offset & 0xe000) - { - case 0x4000: - m_selected_bank[0] = data; - m_bank_base[0] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000; - m_bank_base[2] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000; - break; - - case 0x6000: - m_selected_bank[1] = data; - m_bank_base[1] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000; - m_bank_base[3] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000; - break; - - case 0x8000: - m_selected_bank[2] = data; - m_bank_base[4] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000; - m_bank_base[6] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000; - break; - - case 0xa000: - m_selected_bank[3] = data; - m_bank_base[5] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000; - m_bank_base[7] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000; - break; - } + m_rombank[Bank]->set_entry(data & m_bank_mask); } @@ -130,20 +71,12 @@ msx_cart_konami_scc_device::msx_cart_konami_scc_device(const machine_config &mco : device_t(mconfig, MSX_CART_KONAMI_SCC, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_k051649(*this, "k051649") + , m_rombank(*this, "rombank%u", 0U) + , m_scc_view(*this, "scc_view") , m_bank_mask(0) - , m_scc_active(false) { - for (int i = 0; i < 4; i++) - { - m_selected_bank[i] = i; - } - for (auto & elem : m_bank_base) - { - elem = nullptr; - } } - void msx_cart_konami_scc_device::device_add_mconfig(machine_config &config) { // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. @@ -151,147 +84,61 @@ void msx_cart_konami_scc_device::device_add_mconfig(machine_config &config) K051649(config, m_k051649, XTAL(10'738'635)/3).add_route(ALL_OUTPUTS, "mono", 0.15); } - -void msx_cart_konami_scc_device::device_start() -{ - save_item(NAME(m_selected_bank)); - save_item(NAME(m_scc_active)); -} - - -void msx_cart_konami_scc_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_konami_scc_device::restore_banks() -{ - m_bank_base[0] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000; - m_bank_base[1] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000; - m_bank_base[2] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000; - m_bank_base[3] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000; - m_bank_base[4] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000; - m_bank_base[5] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000; - m_bank_base[6] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000; - m_bank_base[7] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000; -} - - void msx_cart_konami_scc_device::device_reset() { + m_scc_view.select(0); for (int i = 0; i < 4; i++) - { - m_selected_bank[i] = i; - } - m_scc_active = false; + m_rombank[i]->set_entry(i); } - void msx_cart_konami_scc_device::initialize_cartridge() { - uint32_t size = get_rom_size(); + u32 size = get_rom_size(); + u16 banks = size / 0x2000; - if ( get_rom_size() > 256 * 0x2000 ) - { - fatalerror("konami_scc: ROM is too big\n"); - } - - uint16_t banks = size / 0x2000; - - if (size != banks * 0x2000 || (~(banks - 1) % banks)) + if (size > 256 * 0x2000 || size < 0x8000 || size != banks * 0x2000 || (~(banks - 1) % banks)) { fatalerror("konami_scc: Invalid ROM size\n"); } m_bank_mask = banks - 1; - restore_banks(); -} - - -uint8_t msx_cart_konami_scc_device::read_cart(offs_t offset) -{ - if ( m_scc_active && offset >= 0x9800 && offset < 0xa000 ) - { - if (offset & 0x80) - { - if ((offset & 0xff) >= 0xe0) - { - return m_k051649->k051649_test_r(); - } - return 0xff; - } - else - { - return m_k051649->k051649_waveform_r(offset & 0x7f); - } - } + for (int i = 0; i < 4; i++) + m_rombank[i]->configure_entries(0, banks, get_rom_base(), 0x2000); - return m_bank_base[offset >> 13][offset & 0x1fff]; + page(0)->install_read_bank(0x0000, 0x1fff, m_rombank[2]); + page(0)->install_read_bank(0x2000, 0x3fff, m_rombank[3]); + page(1)->install_read_bank(0x4000, 0x5fff, m_rombank[0]); + page(1)->install_write_handler(0x5000, 0x57ff, write8smo_delegate(*this, FUNC(msx_cart_konami_scc_device::bank_w<0>))); + page(1)->install_read_bank(0x6000, 0x7fff, m_rombank[1]); + page(1)->install_write_handler(0x7000, 0x77ff, write8smo_delegate(*this, FUNC(msx_cart_konami_scc_device::bank_w<1>))); + page(2)->install_view(0x8000, 0x9fff, m_scc_view); + m_scc_view[0].install_read_bank(0x8000, 0x9fff, m_rombank[2]); + m_scc_view[0].install_write_handler(0x9000, 0x97ff, write8smo_delegate(*this, FUNC(msx_cart_konami_scc_device::bank_w<2>))); + m_scc_view[1].install_read_bank(0x8000, 0x9fff, m_rombank[2]); + m_scc_view[1].install_write_handler(0x9000, 0x97ff, write8smo_delegate(*this, FUNC(msx_cart_konami_scc_device::bank_w<2>))); + m_scc_view[1].install_read_handler(0x9800, 0x987f, 0, 0x0700, 0, read8sm_delegate(m_k051649, FUNC(k051649_device::k051649_waveform_r))); + m_scc_view[1].install_write_handler(0x9800, 0x987f, 0, 0x0700, 0, write8sm_delegate(m_k051649, FUNC(k051649_device::k051649_waveform_w))); + m_scc_view[1].install_write_handler(0x9880, 0x9889, 0, 0x0710, 0, write8sm_delegate(m_k051649, FUNC(k051649_device::k051649_frequency_w))); + m_scc_view[1].install_write_handler(0x988a, 0x988e, 0, 0x0710, 0, write8sm_delegate(m_k051649, FUNC(k051649_device::k051649_volume_w))); + m_scc_view[1].install_write_handler(0x988f, 0x988f, 0, 0x0710, 0, write8smo_delegate(m_k051649, FUNC(k051649_device::k051649_keyonoff_w))); + m_scc_view[1].install_read_handler(0x98c0, 0x98c0, 0, 0x071f, 0, read8smo_delegate(m_k051649, FUNC(k051649_device::k051649_test_r))); + m_scc_view[1].install_write_handler(0x98c0, 0x98c0, 0, 0x071f, 0, write8smo_delegate(m_k051649, FUNC(k051649_device::k051649_test_w))); + page(2)->install_read_bank(0x8000, 0x9fff, m_rombank[2]); + page(2)->install_write_handler(0x9000, 0x97ff, write8smo_delegate(*this, FUNC(msx_cart_konami_scc_device::bank_w<2>))); + page(2)->install_read_bank(0xa000, 0xbfff, m_rombank[3]); + page(2)->install_write_handler(0xb000, 0xb7ff, write8smo_delegate(*this, FUNC(msx_cart_konami_scc_device::bank_w<3>))); + page(3)->install_read_bank(0xc000, 0xdfff, m_rombank[0]); + page(3)->install_read_bank(0xe000, 0xffff, m_rombank[1]); } - -void msx_cart_konami_scc_device::write_cart(offs_t offset, uint8_t data) +template <int Bank> +void msx_cart_konami_scc_device::bank_w(u8 data) { - switch (offset & 0xf800) + m_rombank[Bank]->set_entry(data & m_bank_mask); + if (Bank == 2) { - case 0x5000: - m_selected_bank[0] = data; - m_bank_base[2] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000; - m_bank_base[6] = get_rom_base() + ( m_selected_bank[0] & m_bank_mask ) * 0x2000; - break; - - case 0x7000: - m_selected_bank[1] = data; - m_bank_base[3] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000; - m_bank_base[7] = get_rom_base() + ( m_selected_bank[1] & m_bank_mask ) * 0x2000; - break; - - case 0x9000: - m_selected_bank[2] = data; - m_scc_active = ( ( data & 0x3f ) == 0x3f ); - m_bank_base[0] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000; - m_bank_base[4] = get_rom_base() + ( m_selected_bank[2] & m_bank_mask ) * 0x2000; - break; - - case 0x9800: - if ( m_scc_active ) - { - offset &= 0xff; - - if (offset < 0x80) - { - m_k051649->k051649_waveform_w(offset, data); - } - else if (offset < 0xa0) - { - offset &= 0x0f; - if (offset < 0x0a) - { - m_k051649->k051649_frequency_w(offset, data); - } - else if (offset < 0x0f) - { - m_k051649->k051649_volume_w(offset - 0xa, data); - } - else - { - m_k051649->k051649_keyonoff_w(data); - } - } - else if (offset >= 0xe0) - { - m_k051649->k051649_test_w(data); - } - } - break; - - case 0xb000: - m_selected_bank[3] = data; - m_bank_base[1] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000; - m_bank_base[5] = get_rom_base() + ( m_selected_bank[3] & m_bank_mask ) * 0x2000; - break; + m_scc_view.select(((data & 0x3f) == 0x3f) ? 1 : 0); } } @@ -300,261 +147,131 @@ void msx_cart_konami_scc_device::write_cart(offs_t offset, uint8_t data) -msx_cart_gamemaster2_device::msx_cart_gamemaster2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_gamemaster2_device::msx_cart_gamemaster2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_GAMEMASTER2, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) + , m_rambank(*this, "rambank%u", 0U) + , m_view0(*this, "view0") + , m_view1(*this, "view1") + , m_view2(*this, "view2") { - for (auto & elem : m_selected_bank) - { - elem = 0; - } - for (auto & elem : m_bank_base) - { - elem = nullptr; - } -} - - -void msx_cart_gamemaster2_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_gamemaster2_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_gamemaster2_device::setup_bank(uint8_t bank) -{ - switch (bank) - { - case 0: - if (m_selected_bank[0] & 0x10) - { - m_bank_base[1] = get_sram_base() + ((m_selected_bank[0] & 0x20) ? 0x1000 : 0); - m_bank_base[3] = get_sram_base() + ((m_selected_bank[0] & 0x20) ? 0x1000 : 0); - } - else - { - m_bank_base[1] = get_rom_base() + ( m_selected_bank[0] & 0x0f ) * 0x2000; - m_bank_base[3] = get_rom_base() + ( m_selected_bank[0] & 0x0f ) * 0x2000; - } - break; - - case 1: - if (m_selected_bank[1] & 0x10) - { - m_bank_base[4] = get_sram_base() + ((m_selected_bank[1] & 0x20) ? 0x1000 : 0); - m_bank_base[6] = get_sram_base() + ((m_selected_bank[1] & 0x20) ? 0x1000 : 0); - } - else - { - m_bank_base[4] = get_rom_base() + ( m_selected_bank[1] & 0x0f ) * 0x2000; - m_bank_base[6] = get_rom_base() + ( m_selected_bank[1] & 0x0f ) * 0x2000; - } - break; - - case 2: - if (m_selected_bank[2] & 0x10) - { - m_bank_base[5] = get_sram_base() + ((m_selected_bank[2] & 0x20) ? 0x1000 : 0); - m_bank_base[7] = get_sram_base() + ((m_selected_bank[2] & 0x20) ? 0x1000 : 0); - } - else - { - m_bank_base[5] = get_rom_base() + ( m_selected_bank[2] & 0x0f ) * 0x2000; - m_bank_base[7] = get_rom_base() + ( m_selected_bank[2] & 0x0f ) * 0x2000; - } - break; - } -} - - -void msx_cart_gamemaster2_device::restore_banks() -{ - m_bank_base[0] = get_rom_base(); - m_bank_base[2] = get_rom_base(); - setup_bank(0); - setup_bank(1); - setup_bank(2); } - void msx_cart_gamemaster2_device::device_reset() { - for (int i = 0; i < 3; i++) - { - m_selected_bank[i] = i + 1; - } + m_rombank[0]->set_entry(1); + m_rombank[1]->set_entry(1); + m_rombank[2]->set_entry(2); + m_view0.select(0); + m_view1.select(0); + m_view2.select(0); } - void msx_cart_gamemaster2_device::initialize_cartridge() { - if ( get_rom_size() != 0x20000 ) + u32 size = get_rom_size(); + u16 banks = size / 0x2000; + + if (size != 0x20000) { fatalerror("gamemaster2: Invalid ROM size\n"); } - if (get_sram_size() != 0x2000) { fatalerror("gamemaster2: Invalid SRAM size\n"); } - restore_banks(); -} + for (int i = 0; i < 3; i++) + { + m_rombank[i]->configure_entries(0, banks, get_rom_base(), 0x2000); + m_rambank[i]->configure_entries(0, 2, get_sram_base(), 0x1000); + } + page(1)->install_rom(0x4000, 0x5fff, get_rom_base()); -uint8_t msx_cart_gamemaster2_device::read_cart(offs_t offset) -{ - uint8_t bank = offset >> 13; + page(1)->install_view(0x6000, 0x7fff, m_view0); + m_view0[0].install_read_bank(0x6000, 0x7fff, m_rombank[0]); + m_view0[0].install_write_handler(0x6000, 0x6fff, write8smo_delegate(*this, FUNC(msx_cart_gamemaster2_device::bank_w<0>))); + m_view0[1].install_read_bank(0x6000, 0x6fff, 0x1000, m_rambank[0]); + m_view0[1].install_write_handler(0x6000, 0x6fff, write8smo_delegate(*this, FUNC(msx_cart_gamemaster2_device::bank_w<0>))); - switch (bank) - { - case 1: - case 3: - if (m_selected_bank[0] & 0x10) - { - return m_bank_base[bank][offset & 0x0fff]; - } - break; - - case 4: - case 6: - if (m_selected_bank[1] & 0x10) - { - return m_bank_base[bank][offset & 0x0fff]; - } - break; - - case 5: - case 7: - if (m_selected_bank[2] & 0x10) - { - return m_bank_base[bank][offset & 0x0fff]; - } - break; - } - return m_bank_base[bank][offset & 0x1fff]; -} + page(2)->install_view(0x8000, 0x9fff, m_view1); + m_view1[0].install_read_bank(0x8000, 0x9fff, m_rombank[1]); + m_view1[0].install_write_handler(0x8000, 0x8fff, write8smo_delegate(*this, FUNC(msx_cart_gamemaster2_device::bank_w<1>))); + m_view1[1].install_read_bank(0x8000, 0x8fff, 0x1000, m_rambank[1]); + m_view1[1].install_write_handler(0x8000, 0x8fff, write8smo_delegate(*this, FUNC(msx_cart_gamemaster2_device::bank_w<1>))); + page(2)->install_view(0xa000, 0xbfff, m_view2); + m_view2[0].install_read_bank(0xa000, 0xbfff, m_rombank[2]); + m_view2[0].install_write_handler(0xa000, 0xafff, write8smo_delegate(*this, FUNC(msx_cart_gamemaster2_device::bank_w<2>))); + m_view2[1].install_read_bank(0xa000, 0xafff, m_rambank[2]); + m_view2[1].install_write_handler(0xa000, 0xafff, write8smo_delegate(*this, FUNC(msx_cart_gamemaster2_device::bank_w<2>))); + m_view2[1].install_readwrite_bank(0xb000, 0xbfff, m_rambank[2]); +} -void msx_cart_gamemaster2_device::write_cart(offs_t offset, uint8_t data) +template <int Bank> +void msx_cart_gamemaster2_device::bank_w(u8 data) { - switch (offset & 0xf000) - { - case 0x6000: - m_selected_bank[0] = data; - setup_bank(0); - break; - - case 0x8000: - m_selected_bank[1] = data; - setup_bank(1); - break; - - case 0xa000: - m_selected_bank[2] = data; - setup_bank(2); - break; - - case 0xb000: - if (m_selected_bank[2] & 0x10) - { - m_bank_base[5][offset & 0x0fff] = data; - } - break; - } + m_rombank[Bank]->set_entry(data & 0x0f); + m_rambank[Bank]->set_entry(BIT(data, 5) ? 1 : 0); + if (Bank == 0) + m_view0.select(BIT(data, 4) ? 1 : 0); + if (Bank == 1) + m_view1.select(BIT(data, 4) ? 1 : 0); + if (Bank == 2) + m_view2.select(BIT(data, 4) ? 1 : 0); } -msx_cart_synthesizer_device::msx_cart_synthesizer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_synthesizer_device::msx_cart_synthesizer_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_SYNTHESIZER, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_bank_base(nullptr) , m_dac(*this, "dac") { } - void msx_cart_synthesizer_device::device_add_mconfig(machine_config &config) { // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. SPEAKER(config, "speaker").front_center(); - DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.1); // unknown DAC -} - - -void msx_cart_synthesizer_device::device_start() -{ + DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.3); // unknown DAC } - void msx_cart_synthesizer_device::initialize_cartridge() { - if ( get_rom_size() != 0x8000 ) + if (get_rom_size() != 0x8000) { fatalerror("synthesizer: Invalid ROM size\n"); } - m_bank_base = get_rom_base(); -} - - -uint8_t msx_cart_synthesizer_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000 ) - { - return m_bank_base[offset - 0x4000]; - } - return 0xff; -} - - -void msx_cart_synthesizer_device::write_cart(offs_t offset, uint8_t data) -{ - if ((offset & 0xc010) == 0x4000) - { - m_dac->write(data); - } + page(1)->install_rom(0x4000, 0x7fff, get_rom_base()); + page(1)->install_write_handler(0x4000, 0x4000, 0, 0x3fef, 0, write8smo_delegate(m_dac, FUNC(dac_byte_interface::write))); + page(2)->install_rom(0x8000, 0xbfff, get_rom_base() + 0x4000); } -msx_cart_konami_sound_device::msx_cart_konami_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) +msx_cart_konami_sound_device::msx_cart_konami_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 min_rambank, u8 max_rambank) : device_t(mconfig, type, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_k052539(*this, "k052539") - , m_scc_active(false) - , m_sccplus_active(false) - , m_scc_mode(0) + , m_rambank(*this, "rambank%u", 0U) + , m_view0(*this, "view0") + , m_view1(*this, "view1") + , m_view2(*this, "view2") + , m_view3(*this, "view3") + , m_min_rambank(min_rambank) + , m_max_rambank(max_rambank) + , m_selected_bank{0, 0, 0, 0} + , m_control(0) { - for (auto & elem : m_selected_bank) - { - elem = 0; - } - for (auto & elem : m_bank_base) - { - elem = nullptr; - } - for (auto & elem : m_ram_bank) - { - elem = nullptr; - } - for (auto & elem : m_ram_enabled) - { - elem = false; - } } - void msx_cart_konami_sound_device::device_add_mconfig(machine_config &config) { // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. @@ -562,330 +279,208 @@ void msx_cart_konami_sound_device::device_add_mconfig(machine_config &config) K051649(config, m_k052539, XTAL(10'738'635)/3).add_route(ALL_OUTPUTS, "mono", 0.15); } - void msx_cart_konami_sound_device::device_start() { save_item(NAME(m_selected_bank)); - save_item(NAME(m_scc_active)); - save_item(NAME(m_sccplus_active)); - save_item(NAME(m_ram_enabled)); -} - - -void msx_cart_konami_sound_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_konami_sound_device::restore_banks() -{ - for (int i = 0; i < 4; i++) - { - setup_bank(i); - } -} - - -void msx_cart_konami_sound_device::setup_bank(uint8_t bank) -{ - switch (bank) - { - case 0: - m_bank_base[2] = m_ram_bank[m_selected_bank[0] & 0x0f]; - m_bank_base[6] = m_ram_bank[m_selected_bank[0] & 0x0f]; - break; - - case 1: - m_bank_base[3] = m_ram_bank[m_selected_bank[1] & 0x0f]; - m_bank_base[7] = m_ram_bank[m_selected_bank[1] & 0x0f]; - break; - - case 2: - m_bank_base[0] = m_ram_bank[m_selected_bank[2] & 0x0f]; - m_bank_base[4] = m_ram_bank[m_selected_bank[2] & 0x0f]; - break; - - case 3: - m_bank_base[1] = m_ram_bank[m_selected_bank[3] & 0x0f]; - m_bank_base[5] = m_ram_bank[m_selected_bank[3] & 0x0f]; - break; - } + save_item(NAME(m_control)); } - void msx_cart_konami_sound_device::device_reset() { + m_control = 0; for (int i = 0; i < 4; i++) { m_selected_bank[i] = i; - m_ram_enabled[i] = false; } - m_scc_active = false; - m_sccplus_active = false; + switch_bank<0>(); + switch_bank<1>(); + switch_bank<2>(); + switch_bank<3>(); } - void msx_cart_konami_sound_device::initialize_cartridge() { - restore_banks(); -} - - -uint8_t msx_cart_konami_sound_device::read_cart(offs_t offset) -{ - if ( m_scc_active && offset >= 0x9800 && offset < 0x9fe0 ) - { - offset &= 0xff; - if (offset < 0x80) - { - return m_k052539->k051649_waveform_r(offset); - } - if (offset < 0xa0) - { - return 0xff; - } - if (offset < 0xc0) - { - return m_k052539->k051649_waveform_r(offset & 0x9f); - } - if (offset < 0xe0) - { - return m_k052539->k051649_test_r(); - } - return 0xff; - } - else if ( m_sccplus_active && offset >= 0xb800 && offset < 0xbfe0) - { - offset &= 0xff; - - if (offset < 0xa0) - { - return m_k052539->k052539_waveform_r(offset); - } - if (offset >= 0xc0 && offset < 0xe0) - { - return m_k052539->k051649_test_r(); - } - return 0xff; - } - - uint8_t *base = m_bank_base[offset >> 13]; - - if (base != nullptr) - { - return base[offset & 0x1fff]; - } - return 0xff; -} - - -void msx_cart_konami_sound_device::write_cart(offs_t offset, uint8_t data) -{ - switch (offset & 0xe000) + for (int i = 0; i < 4; i++) { - case 0x4000: - if (m_ram_enabled[0] && m_bank_base[2] != nullptr) - { - m_bank_base[2][offset & 0x1fff] = data; - } - if ((offset & 0x1800) == 0x1000) - { - m_selected_bank[0] = data; - setup_bank(0); - } - break; - - case 0x6000: - if (m_ram_enabled[1] && m_bank_base[3] != nullptr) - { - m_bank_base[3][offset & 0x1fff] = data; - } - if ((offset & 0x1800) == 0x1000) - { - m_selected_bank[1] = data; - setup_bank(1); - } - break; - - case 0x8000: - if (m_ram_enabled[2] && m_bank_base[0] != nullptr) - { - m_bank_base[0][offset & 0x1fff] = data; - } - switch (offset & 0x1800) - { - case 0x1000: // 0x9000-0x97ff - m_selected_bank[2] = data; - m_scc_active = ( ( data & 0x3f ) == 0x3f ); - setup_bank(2); - break; - - case 0x1800: // 0x9800-0x9fff - if ( m_scc_active ) - { - offset &= 0xff; - - if (offset < 0x80) - { - m_k052539->k051649_waveform_w(offset, data); - } - else if (offset < 0xa0) - { - offset &= 0x0f; - if (offset < 0x0a) - { - m_k052539->k051649_frequency_w(offset, data); - } - else if (offset < 0x0f) - { - m_k052539->k051649_volume_w(offset - 0xa, data); - } - else - { - m_k052539->k051649_keyonoff_w(data); - } - } - else if (offset >= 0xe0) - { - m_k052539->k051649_test_w(data); - } - } - break; - } - break; - - case 0xa000: - if (m_ram_enabled[3] && m_bank_base[1] != nullptr) - { - m_bank_base[1][offset & 0x1fff] = data; - } - switch (offset & 0x1800) - { - // 0xb000-0xb7ff - case 0x1000: - m_selected_bank[3] = data; - setup_bank(3); - break; - - // 0xb800-0xbfff - case 0x1800: - if ((offset & 0x7fe) == 0x7fe) - { - // 0xbffe-0xbfff - /* write to mode register */ - m_scc_mode = data; - - m_ram_enabled[0] = ((m_scc_mode & 0x10) || (m_scc_mode & 0x01)); - m_ram_enabled[1] = ((m_scc_mode & 0x10) || (m_scc_mode & 0x02)); - m_ram_enabled[2] = ((m_scc_mode & 0x10) || ((m_scc_mode & 0x04) && (m_scc_mode & 0x20))); - m_ram_enabled[3] = (m_scc_mode & 0x10); - - m_scc_active = ((m_selected_bank[2] & 0x3f) == 0x3f) && !(m_scc_mode & 0x20); - m_sccplus_active = (m_selected_bank[3] & 0x80) && (m_scc_mode & 0x20); - } - else - { - if (m_sccplus_active) - { - offset &= 0xff; - if (offset < 0xa0) - { - m_k052539->k052539_waveform_w(offset, data); - } - else if (offset < 0xc0) - { - offset &= 0x0f; - if (offset < 0x0a) - { - m_k052539->k051649_frequency_w(offset, data); - } - else if (offset < 0x0f) - { - m_k052539->k051649_volume_w(offset - 0x0a, data); - } - else if (offset == 0x0f) - { - m_k052539->k051649_keyonoff_w(data); - } - } - else if (offset < 0xe0) - { - m_k052539->k051649_test_w(data); - } - } - } - break; - } - break; - } -} - - -msx_cart_konami_sound_snatcher_device::msx_cart_konami_sound_snatcher_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : msx_cart_konami_sound_device(mconfig, MSX_CART_SOUND_SNATCHER, tag, owner, clock) + m_rambank[i]->configure_entries(0, 8, get_ram_base(), 0x2000); + } + + // TODO Mirrors at 0000-3fff and c000-ffff + + page(1)->install_view(0x4000, 0x5fff, m_view0); + m_view0[VIEW_READ].install_read_bank(0x4000, 0x5fff, m_rambank[0]); + m_view0[VIEW_READ].install_write_handler(0x5000, 0x57ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<0>))); + m_view0[VIEW_RAM].install_readwrite_bank(0x4000, 0x5fff, m_rambank[0]); + m_view0[VIEW_INVALID].install_write_handler(0x5000, 0x57ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<0>))); + m_view0[VIEW_INVALID | VIEW_RAM]; + + page(1)->install_view(0x6000, 0x7fff, m_view1); + m_view1[VIEW_READ].install_read_bank(0x6000, 0x7fff, m_rambank[1]); + m_view1[VIEW_READ].install_write_handler(0x7000, 0x77ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<1>))); + m_view1[VIEW_RAM].install_readwrite_bank(0x6000, 0x7fff, m_rambank[1]); + m_view1[VIEW_INVALID].install_write_handler(0x7000, 0x77ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<1>))); + m_view1[VIEW_INVALID | VIEW_RAM]; + + page(2)->install_view(0x8000, 0x9fff, m_view2); + m_view2[VIEW_READ].install_read_bank(0x8000, 0x9fff, m_rambank[2]); + m_view2[VIEW_READ].install_write_handler(0x9000, 0x97ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<2>))); + m_view2[VIEW_RAM].install_readwrite_bank(0x8000, 0x9fff, m_rambank[2]); + m_view2[VIEW_INVALID].install_write_handler(0x9000, 0x97ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<2>))); + m_view2[VIEW_INVALID | VIEW_RAM]; + m_view2[VIEW_SCC | VIEW_READ].install_read_bank(0x8000, 0x9fff, m_rambank[2]); + m_view2[VIEW_SCC | VIEW_READ].install_write_handler(0x9000, 0x97ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<2>))); + m_view2[VIEW_SCC | VIEW_READ].install_read_handler(0x9800, 0x987f, 0, 0x0700, 0, read8sm_delegate(m_k052539, FUNC(k051649_device::k051649_waveform_r))); + m_view2[VIEW_SCC | VIEW_READ].install_write_handler(0x9800, 0x987f, 0, 0x0700, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_waveform_w))); + m_view2[VIEW_SCC | VIEW_READ].install_write_handler(0x9880, 0x9889, 0, 0x0710, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_frequency_w))); + m_view2[VIEW_SCC | VIEW_READ].install_write_handler(0x988a, 0x988e, 0, 0x0710, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_volume_w))); + m_view2[VIEW_SCC | VIEW_READ].install_write_handler(0x988f, 0x988f, 0, 0x0710, 0, write8smo_delegate(m_k052539, FUNC(k051649_device::k051649_keyonoff_w))); + m_view2[VIEW_SCC | VIEW_READ].install_read_handler(0x98c0, 0x98c0, 0, 0x071f, 0, read8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_r))); + m_view2[VIEW_SCC | VIEW_READ].install_write_handler(0x98c0, 0x98c0, 0, 0x071f, 0, write8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_w))); + m_view2[VIEW_SCC | VIEW_RAM].install_readwrite_bank(0x8000, 0x9fff, m_rambank[2]); + m_view2[VIEW_SCC | VIEW_RAM].install_read_handler(0x9800, 0x987f, 0, 0x0700, 0, read8sm_delegate(m_k052539, FUNC(k051649_device::k051649_waveform_r))); + m_view2[VIEW_SCC | VIEW_RAM].install_read_handler(0x98c0, 0x98c0, 0, 0x071f, 0, read8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_r))); + m_view2[VIEW_SCC | VIEW_INVALID].install_write_handler(0x9000, 0x97ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<2>))); + m_view2[VIEW_SCC | VIEW_INVALID].install_read_handler(0x9800, 0x987f, 0, 0x0700, 0, read8sm_delegate(m_k052539, FUNC(k051649_device::k051649_waveform_r))); + m_view2[VIEW_SCC | VIEW_INVALID].install_write_handler(0x9800, 0x987f, 0, 0x0700, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_waveform_w))); + m_view2[VIEW_SCC | VIEW_INVALID].install_write_handler(0x9880, 0x9889, 0, 0x0710, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_frequency_w))); + m_view2[VIEW_SCC | VIEW_INVALID].install_write_handler(0x988a, 0x988e, 0, 0x0710, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_volume_w))); + m_view2[VIEW_SCC | VIEW_INVALID].install_write_handler(0x988f, 0x988f, 0, 0x0710, 0, write8smo_delegate(m_k052539, FUNC(k051649_device::k051649_keyonoff_w))); + m_view2[VIEW_SCC | VIEW_INVALID].install_read_handler(0x98c0, 0x98c0, 0, 0x071f, 0, read8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_r))); + m_view2[VIEW_SCC | VIEW_INVALID].install_write_handler(0x98c0, 0x98c0, 0, 0x071f, 0, write8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_w))); + m_view2[VIEW_SCC | VIEW_INVALID | VIEW_RAM]; + m_view2[VIEW_SCC | VIEW_INVALID | VIEW_RAM].install_read_handler(0x9800, 0x987f, 0, 0x0700, 0, read8sm_delegate(m_k052539, FUNC(k051649_device::k051649_waveform_r))); + m_view2[VIEW_SCC | VIEW_INVALID | VIEW_RAM].install_read_handler(0x98c0, 0x98c0, 0, 0x071f, 0, read8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_r))); + + page(2)->install_view(0xa000, 0xbfff, m_view3); + m_view3[VIEW_READ].install_read_bank(0xa000, 0xbfff, m_rambank[3]); + m_view3[VIEW_READ].install_write_handler(0xb000, 0xb7ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<3>))); + m_view3[VIEW_RAM].install_readwrite_bank(0xa000, 0xbfff, m_rambank[3]); + m_view3[VIEW_INVALID].install_write_handler(0xb000, 0xb7ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<3>))); + m_view3[VIEW_INVALID | VIEW_RAM]; + m_view3[VIEW_SCC | VIEW_READ].install_read_bank(0xa000, 0xbfff, m_rambank[3]); + m_view3[VIEW_SCC | VIEW_READ].install_write_handler(0xb000, 0xb7ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<3>))); + m_view3[VIEW_SCC | VIEW_READ].install_read_handler(0xb800, 0xb89f, 0, 0x0700, 0, read8sm_delegate(m_k052539, FUNC(k051649_device::k052539_waveform_r))); + m_view3[VIEW_SCC | VIEW_READ].install_write_handler(0xb800, 0xb89f, 0, 0x0700, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k052539_waveform_w))); + m_view3[VIEW_SCC | VIEW_READ].install_write_handler(0xb8a0, 0xb8a9, 0, 0x0710, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_frequency_w))); + m_view3[VIEW_SCC | VIEW_READ].install_write_handler(0xb8aa, 0xb8ae, 0, 0x0710, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_volume_w))); + m_view3[VIEW_SCC | VIEW_READ].install_write_handler(0xb8af, 0xb8af, 0, 0x0710, 0, write8smo_delegate(m_k052539, FUNC(k051649_device::k051649_keyonoff_w))); + m_view3[VIEW_SCC | VIEW_READ].install_read_handler(0xb8c0, 0xb8c0, 0, 0x071f, 0, read8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_r))); + m_view3[VIEW_SCC | VIEW_READ].install_write_handler(0xb8c0, 0xb8c0, 0, 0x071f, 0, write8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_w))); + m_view3[VIEW_SCC | VIEW_RAM].install_readwrite_bank(0xa000, 0xbfff, m_rambank[3]); + m_view3[VIEW_SCC | VIEW_RAM].install_read_handler(0xb800, 0xb89f, 0, 0x0700, 0, read8sm_delegate(m_k052539, FUNC(k051649_device::k052539_waveform_r))); + m_view3[VIEW_SCC | VIEW_RAM].install_read_handler(0xb8c0, 0xb8c0, 0, 0x071f, 0, read8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_r))); + m_view3[VIEW_SCC | VIEW_INVALID].install_write_handler(0xb000, 0xb7ff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::bank_w<3>))); + m_view3[VIEW_SCC | VIEW_INVALID].install_read_handler(0xb800, 0xb89f, 0, 0x0700, 0, read8sm_delegate(m_k052539, FUNC(k051649_device::k052539_waveform_r))); + m_view3[VIEW_SCC | VIEW_INVALID].install_write_handler(0xb800, 0xb89f, 0, 0x0700, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k052539_waveform_w))); + m_view3[VIEW_SCC | VIEW_INVALID].install_write_handler(0xb8a0, 0xb8a9, 0, 0x0710, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_frequency_w))); + m_view3[VIEW_SCC | VIEW_INVALID].install_write_handler(0xb8aa, 0xb8ae, 0, 0x0710, 0, write8sm_delegate(m_k052539, FUNC(k051649_device::k051649_volume_w))); + m_view3[VIEW_SCC | VIEW_INVALID].install_write_handler(0xb8af, 0xb8af, 0, 0x0710, 0, write8smo_delegate(m_k052539, FUNC(k051649_device::k051649_keyonoff_w))); + m_view3[VIEW_SCC | VIEW_INVALID].install_read_handler(0xb8c0, 0xb8c0, 0, 0x071f, 0, read8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_r))); + m_view3[VIEW_SCC | VIEW_INVALID].install_write_handler(0xb8c0, 0xb8c0, 0, 0x071f, 0, write8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_w))); + m_view3[VIEW_SCC | VIEW_INVALID | VIEW_RAM]; + m_view3[VIEW_SCC | VIEW_INVALID| VIEW_RAM].install_read_handler(0xb800, 0xb89f, 0, 0x0700, 0, read8sm_delegate(m_k052539, FUNC(k051649_device::k052539_waveform_r))); + m_view3[VIEW_SCC | VIEW_INVALID| VIEW_RAM].install_read_handler(0xb8c0, 0xb8c0, 0, 0x071f, 0, read8smo_delegate(m_k052539, FUNC(k051649_device::k051649_test_r))); + + page(2)->install_write_handler(0xbffe, 0xbfff, write8smo_delegate(*this, FUNC(msx_cart_konami_sound_device::control_w))); +} + +void msx_cart_konami_sound_device::control_w(u8 data) +{ + m_control = data; + + switch_bank<0>(); + switch_bank<1>(); + switch_bank<2>(); + switch_bank<3>(); +} + +template <int Bank> +void msx_cart_konami_sound_device::switch_bank() +{ + u8 view = VIEW_READ; + if ((m_selected_bank[Bank] & 0x0f) >= m_min_rambank && (m_selected_bank[Bank] & 0x0f) <= m_max_rambank) + m_rambank[Bank]->set_entry(m_selected_bank[Bank] & 0x07); + else + view |= VIEW_INVALID; + if (BIT(m_control, 4)) + view |= VIEW_RAM; + else + { + if (Bank < 2 && BIT(m_control, Bank)) + view |= VIEW_RAM; + else if (Bank == 2 && BIT(m_control, Bank) && BIT(m_control, 5)) + view |= VIEW_RAM; + } + if (Bank == 2 && !BIT(m_control, 5) && (m_selected_bank[2] & 0x3f) == 0x3f) + view |= VIEW_SCC; + if (Bank == 3 && BIT(m_control, 5) && BIT(m_selected_bank[3], 7)) + view |= VIEW_SCC; + + if (Bank == 0) + m_view0.select(view); + if (Bank == 1) + m_view1.select(view); + if (Bank == 2) + m_view2.select(view); + if (Bank == 3) + m_view3.select(view); +} + +template <int Bank> +void msx_cart_konami_sound_device::bank_w(u8 data) +{ + m_selected_bank[Bank] = data; + switch_bank<Bank>(); +} + + + +// The Snatcher Sound cartridge has 64KB RAM available by selecting ram banks 0-7 +msx_cart_konami_sound_snatcher_device::msx_cart_konami_sound_snatcher_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : msx_cart_konami_sound_device(mconfig, MSX_CART_SOUND_SNATCHER, tag, owner, clock, 0, 7) { } - void msx_cart_konami_sound_snatcher_device::initialize_cartridge() { - msx_cart_konami_sound_device::initialize_cartridge(); - if (get_ram_size() != 0x10000) { fatalerror("sound_snatcher: Invalid RAM size\n"); } - // The Snatcher Sound cartridge has 64KB RAM available by selecting ram banks 0-7 - - for (int i = 0; i < 8; i++) - { - m_ram_bank[i] = get_ram_base() + i * 0x2000; - } + msx_cart_konami_sound_device::initialize_cartridge(); } -msx_cart_konami_sound_sdsnatcher_device::msx_cart_konami_sound_sdsnatcher_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : msx_cart_konami_sound_device(mconfig, MSX_CART_SOUND_SDSNATCHER, tag, owner, clock) +// The SD Snatcher Sound cartrdige has 64KB RAM available by selecting ram banks 8-15 +msx_cart_konami_sound_sdsnatcher_device::msx_cart_konami_sound_sdsnatcher_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : msx_cart_konami_sound_device(mconfig, MSX_CART_SOUND_SDSNATCHER, tag, owner, clock, 8, 15) { } - void msx_cart_konami_sound_sdsnatcher_device::initialize_cartridge() { - msx_cart_konami_sound_device::initialize_cartridge(); - if (get_ram_size() != 0x10000) { fatalerror("sound_sdsnatcher: Invalid RAM size\n"); } - - // The SD Snatcher Sound cartrdige has 64KB RAM available by selecting ram banks 8-15 - - for (int i = 0; i < 8; i++) - { - m_ram_bank[8+i] = get_ram_base() + i * 0x2000; - } - + msx_cart_konami_sound_device::initialize_cartridge(); } -msx_cart_keyboard_master_device::msx_cart_keyboard_master_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_keyboard_master_device::msx_cart_keyboard_master_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_KEYBOARD_MASTER, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_vlm5030(*this, "vlm5030") { } - void msx_cart_keyboard_master_device::vlm_map(address_map &map) { map(0x0000, 0xffff).r(FUNC(msx_cart_keyboard_master_device::read_vlm)); } - void msx_cart_keyboard_master_device::device_add_mconfig(machine_config &config) { // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. @@ -895,7 +490,6 @@ void msx_cart_keyboard_master_device::device_add_mconfig(machine_config &config) m_vlm5030->set_addrmap(0, &msx_cart_keyboard_master_device::vlm_map); } - void msx_cart_keyboard_master_device::device_start() { // Install IO read/write handlers @@ -904,40 +498,28 @@ void msx_cart_keyboard_master_device::device_start() io_space().install_read_handler(0x00, 0x00, read8smo_delegate(*this, FUNC(msx_cart_keyboard_master_device::io_00_r))); } - void msx_cart_keyboard_master_device::initialize_cartridge() { if (get_rom_size() != 0x4000) { fatalerror("keyboard_master: Invalid ROM size\n"); } -} - -uint8_t msx_cart_keyboard_master_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0x8000) - { - return m_rom[offset & 0x3fff]; - } - return 0xff; + page(1)->install_rom(0x4000, 0x7fff, get_rom_base()); } - uint8_t msx_cart_keyboard_master_device::read_vlm(offs_t offset) { return m_rom_vlm5030[offset]; } - void msx_cart_keyboard_master_device::io_20_w(uint8_t data) { - m_vlm5030->rst((data & 0x01) ? 1 : 0); - m_vlm5030->vcu((data & 0x04) ? 1 : 0); - m_vlm5030->st((data & 0x02) ? 1 : 0); + m_vlm5030->rst(BIT(data, 0) ? 1 : 0); + m_vlm5030->vcu(BIT(data, 2) ? 1 : 0); + m_vlm5030->st(BIT(data, 1) ? 1 : 0); } - uint8_t msx_cart_keyboard_master_device::io_00_r() { return m_vlm5030->bsy() ? 0x10 : 0x00; diff --git a/src/devices/bus/msx_cart/konami.h b/src/devices/bus/msx_cart/konami.h index 58ad4f3cfb7..c2bdd25c478 100644 --- a/src/devices/bus/msx_cart/konami.h +++ b/src/devices/bus/msx_cart/konami.h @@ -3,6 +3,8 @@ #ifndef MAME_BUS_MSX_CART_KONAMI_H #define MAME_BUS_MSX_CART_KONAMI_H +#pragma once + #include "bus/msx_cart/cartridge.h" #include "sound/k051649.h" #include "sound/vlm5030.h" @@ -21,25 +23,20 @@ DECLARE_DEVICE_TYPE(MSX_CART_KEYBOARD_MASTER, msx_cart_keyboard_master_device) class msx_cart_konami_device : public device_t, public msx_cart_interface { public: - msx_cart_konami_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_konami_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_bank_mask; - uint8_t m_selected_bank[4]; - uint8_t *m_bank_base[8]; + template <int Bank> void bank_w(u8 data); + + memory_bank_array_creator<4> m_rombank; + u8 m_bank_mask; }; @@ -50,73 +47,61 @@ public: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + 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; - void restore_banks(); - private: + template <int Bank> void bank_w(u8 data); + required_device<k051649_device> m_k051649; + memory_bank_array_creator<4> m_rombank; + memory_view m_scc_view; - uint8_t m_bank_mask; - uint8_t m_selected_bank[4]; - uint8_t *m_bank_base[8]; - bool m_scc_active; + u8 m_bank_mask; }; class msx_cart_gamemaster2_device : public device_t, public msx_cart_interface { public: - msx_cart_gamemaster2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_gamemaster2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_selected_bank[3]; - uint8_t *m_bank_base[8]; + template <int Bank> void bank_w(u8 data); - void setup_bank(uint8_t bank); + memory_bank_array_creator<3> m_rombank; + memory_bank_array_creator<3> m_rambank; + memory_view m_view0; + memory_view m_view1; + memory_view m_view2; }; class msx_cart_synthesizer_device : public device_t, public msx_cart_interface { public: - msx_cart_synthesizer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_synthesizer_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_add_mconfig(machine_config &config) override; private: - uint8_t *m_bank_base; required_device<dac_byte_interface> m_dac; }; @@ -126,42 +111,44 @@ class msx_cart_konami_sound_device : public device_t, public msx_cart_interface public: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: - msx_cart_konami_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + msx_cart_konami_sound_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 min_rambank, u8 max_rambank); // device-level overrides 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; - void restore_banks(); +private: + static constexpr u8 VIEW_READ = 0; + static constexpr u8 VIEW_RAM = 1; + static constexpr u8 VIEW_INVALID = 2; + static constexpr u8 VIEW_SCC = 4; - uint8_t *m_ram_bank[16]; + template <int Bank> void bank_w(u8 data); + template <int Bank> void switch_bank(); + void control_w(u8 data); -private: // This is actually a K052539 required_device<k051649_device> m_k052539; - - uint8_t m_selected_bank[4]; - uint8_t *m_bank_base[8]; - bool m_scc_active; - bool m_sccplus_active; - bool m_ram_enabled[4]; - uint8_t m_scc_mode; - - void setup_bank(uint8_t bank); + memory_bank_array_creator<4> m_rambank; + memory_view m_view0; + memory_view m_view1; + memory_view m_view2; + memory_view m_view3; + + u8 m_min_rambank; + u8 m_max_rambank; + u8 m_selected_bank[4]; + u8 m_control; }; class msx_cart_konami_sound_snatcher_device : public msx_cart_konami_sound_device { public: - msx_cart_konami_sound_snatcher_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_konami_sound_snatcher_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; }; @@ -170,7 +157,7 @@ public: class msx_cart_konami_sound_sdsnatcher_device : public msx_cart_konami_sound_device { public: - msx_cart_konami_sound_sdsnatcher_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_konami_sound_sdsnatcher_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; }; @@ -180,7 +167,7 @@ public: class msx_cart_keyboard_master_device : public device_t, public msx_cart_interface { public: - msx_cart_keyboard_master_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_keyboard_master_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides @@ -190,8 +177,6 @@ protected: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - private: required_device<vlm5030_device> m_vlm5030; diff --git a/src/devices/bus/msx_cart/korean.cpp b/src/devices/bus/msx_cart/korean.cpp index e12f15bd43d..6ba0ffe1d0f 100644 --- a/src/devices/bus/msx_cart/korean.cpp +++ b/src/devices/bus/msx_cart/korean.cpp @@ -11,290 +11,147 @@ DEFINE_DEVICE_TYPE(MSX_CART_KOREAN_126IN1, msx_cart_korean_126in1_device, "msx_c msx_cart_korean_80in1_device::msx_cart_korean_80in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, MSX_CART_KOREAN_80IN1, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) , m_bank_mask(0) - , m_selected_bank{ 0, 1, 2, 3 } - , m_bank_base{ nullptr, nullptr, nullptr, nullptr } { } - -void msx_cart_korean_80in1_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_korean_80in1_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_korean_80in1_device::setup_bank(uint8_t bank) -{ - m_bank_base[bank] = get_rom_base() + ( m_selected_bank[bank] & m_bank_mask ) * 0x2000; -} - - -void msx_cart_korean_80in1_device::restore_banks() -{ - for (int i = 0; i < 4; i++) - { - setup_bank(i); - } -} - - void msx_cart_korean_80in1_device::device_reset() { for (int i = 0; i < 4; i++) - { - m_selected_bank[i] = i; - } + m_rombank[i]->set_entry(i); } - void msx_cart_korean_80in1_device::initialize_cartridge() { - uint32_t size = get_rom_size(); + u32 size = get_rom_size(); + u16 banks = size / 0x2000; - if ( size > 256 * 0x2000 ) - { - fatalerror("korean_80in1: ROM is too big\n"); - } - - uint16_t banks = size / 0x2000; - - if (size != banks * 0x2000 || (~(banks - 1) % banks)) + if (size > 256 * 0x2000 || size < 0x8000 || size != banks * 0x2000 || (~(banks - 1) % banks)) { fatalerror("korean_80in1: Invalid ROM size\n"); } m_bank_mask = banks - 1; - restore_banks(); -} - - -uint8_t msx_cart_korean_80in1_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000) - { - return m_bank_base[(offset - 0x4000) >> 13][offset & 0x1fff]; - } + for (int i = 0; i < 4; i++) + m_rombank[i]->configure_entries(0, banks, get_rom_base(), 0x2000); - return 0xff; + page(1)->install_read_bank(0x4000, 0x5fff, m_rombank[0]); + page(1)->install_write_handler(0x4000, 0x4003, write8sm_delegate(*this, FUNC(msx_cart_korean_80in1_device::bank_w))); + page(1)->install_read_bank(0x6000, 0x7fff, m_rombank[1]); + page(2)->install_read_bank(0x8000, 0x9fff, m_rombank[2]); + page(2)->install_read_bank(0xa000, 0xbfff, m_rombank[3]); } - -void msx_cart_korean_80in1_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_korean_80in1_device::bank_w(offs_t offset, u8 data) { - if (offset >= 0x4000 && offset < 0x4004) - { - uint8_t bank = offset & 3; - - m_selected_bank[bank] = data; - setup_bank(bank); - } + m_rombank[offset & 0x03]->set_entry(data & m_bank_mask); } -msx_cart_korean_90in1_device::msx_cart_korean_90in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_korean_90in1_device::msx_cart_korean_90in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_KOREAN_90IN1, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) + , m_view(*this, "view") , m_bank_mask(0) - , m_selected_bank(0) - , m_bank_base{ nullptr, nullptr, nullptr, nullptr } { } - void msx_cart_korean_90in1_device::device_start() { - save_item(NAME(m_selected_bank)); - // Install IO read/write handlers io_space().install_write_handler(0x77, 0x77, write8smo_delegate(*this, FUNC(msx_cart_korean_90in1_device::banking))); } - -void msx_cart_korean_90in1_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_korean_90in1_device::restore_banks() -{ - uint8_t *base = get_rom_base(); - - switch (m_selected_bank & 0xc0) - { - case 0x80: - base += (m_selected_bank & 0x3e & m_bank_mask) * 0x4000; - m_bank_base[0] = base; - m_bank_base[1] = base + 0x2000; - m_bank_base[2] = base + 0x4000; - m_bank_base[3] = base + 0x6000; - break; - - case 0xc0: - base += (m_selected_bank & m_bank_mask) * 0x4000; - m_bank_base[0] = base; - m_bank_base[1] = base + 0x2000; - m_bank_base[2] = base + 0x2000; - m_bank_base[3] = base; - break; - - default: - base += (m_selected_bank & m_bank_mask) * 0x4000; - m_bank_base[0] = base; - m_bank_base[1] = base + 0x2000; - m_bank_base[2] = base; - m_bank_base[3] = base + 0x2000; - break; - } -} - - void msx_cart_korean_90in1_device::device_reset() { - m_selected_bank = 0; + m_view.select(0); + m_rombank[0]->set_entry(0); + m_rombank[1]->set_entry(0); + m_rombank[2]->set_entry(0); } - void msx_cart_korean_90in1_device::initialize_cartridge() { - uint32_t size = get_rom_size(); + u32 size = get_rom_size(); + u16 banks = size / 0x4000; - if ( size > 64 * 0x4000 ) - { - fatalerror("korean_90in1: ROM is too big\n"); - } - - uint16_t banks = size / 0x4000; - - if (size != banks * 0x4000 || (~(banks - 1) % banks)) + if (size > 64 * 0x4000 || size < 0x8000 || size != banks * 0x4000 || (~(banks - 1) % banks)) { fatalerror("korean_90in1: Invalid ROM size\n"); } m_bank_mask = banks - 1; - restore_banks(); -} + m_rombank[0]->configure_entries(0, banks, get_rom_base(), 0x4000); + m_rombank[1]->configure_entries(0, banks, get_rom_base(), 0x4000); + m_rombank[2]->configure_entries(0, banks, get_rom_base() + 0x2000, 0x4000); + page(1)->install_read_bank(0x4000, 0x7fff, m_rombank[0]); -uint8_t msx_cart_korean_90in1_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000) - { - return m_bank_base[(offset - 0x4000) >> 13][offset & 0x1fff]; - } - - return 0xff; + page(2)->install_view(0x8000, 0xbfff, m_view); + m_view[0].install_read_bank(0x8000, 0x9fff, m_rombank[1]); + m_view[0].install_read_bank(0xa000, 0xbfff, m_rombank[2]); + m_view[1].install_read_bank(0x8000, 0x9fff, m_rombank[2]); + m_view[1].install_read_bank(0xa000, 0xbfff, m_rombank[1]); } - -void msx_cart_korean_90in1_device::banking(uint8_t data) +void msx_cart_korean_90in1_device::banking(u8 data) { - m_selected_bank = data; - restore_banks(); + if (BIT(data, 7) && !BIT(data, 6)) + data &= 0xfe; + + m_rombank[0]->set_entry(data & m_bank_mask); + m_rombank[1]->set_entry((data + (BIT(data, 7) ? 1 : 0)) & m_bank_mask); + m_rombank[2]->set_entry((data + (BIT(data, 7) ? 1 : 0)) & m_bank_mask); + + m_view.select((BIT(data, 7) && BIT(data, 6)) ? 1 : 0); } -msx_cart_korean_126in1_device::msx_cart_korean_126in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_korean_126in1_device::msx_cart_korean_126in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_KOREAN_126IN1, tag, owner, clock) , msx_cart_interface(mconfig, *this) + , m_rombank(*this, "rombank%u", 0U) , m_bank_mask(0) - , m_selected_bank{ 0, 1 } - , m_bank_base{ nullptr, nullptr } -{ -} - - -void msx_cart_korean_126in1_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_korean_126in1_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_korean_126in1_device::setup_bank(uint8_t bank) { - m_bank_base[bank] = get_rom_base() + ( m_selected_bank[bank] & m_bank_mask ) * 0x4000; -} - - -void msx_cart_korean_126in1_device::restore_banks() -{ - for (int i = 0; i < 2; i++) - { - setup_bank(i); - } } - void msx_cart_korean_126in1_device::device_reset() { - for (int i = 0; i < 2; i++) - { - m_selected_bank[i] = i; - } + m_rombank[0]->set_entry(0); + m_rombank[1]->set_entry(1); } - void msx_cart_korean_126in1_device::initialize_cartridge() { - uint32_t size = get_rom_size(); + u32 size = get_rom_size(); + u16 banks = size / 0x4000; - if ( size > 256 * 0x4000 ) - { - fatalerror("korean_126in1: ROM is too big\n"); - } - - uint16_t banks = size / 0x4000; - - if (size != banks * 0x4000 || (~(banks - 1) % banks)) + if (size > 256 * 0x4000 || size < 0x8000 || size != banks * 0x4000 || (~(banks - 1) % banks)) { fatalerror("korean_126in1: Invalid ROM size\n"); } m_bank_mask = banks - 1; - restore_banks(); -} - - -uint8_t msx_cart_korean_126in1_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000) - { - return m_bank_base[offset >> 15][offset & 0x3fff]; - } + m_rombank[0]->configure_entries(0, banks, get_rom_base(), 0x4000); + m_rombank[1]->configure_entries(0, banks, get_rom_base(), 0x4000); - return 0xff; + page(1)->install_read_bank(0x4000, 0x7fff, m_rombank[0]); + page(1)->install_write_handler(0x4000, 0x4001, write8sm_delegate(*this, FUNC(msx_cart_korean_126in1_device::bank_w))); + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank[1]); } - -void msx_cart_korean_126in1_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_korean_126in1_device::bank_w(offs_t offset, uint8_t data) { - if (offset >= 0x4000 && offset < 0x4002) - { - uint8_t bank = offset & 1; - - m_selected_bank[bank] = data; - setup_bank(bank); - } + m_rombank[offset & 0x01]->set_entry(data & m_bank_mask); } diff --git a/src/devices/bus/msx_cart/korean.h b/src/devices/bus/msx_cart/korean.h index 62c5a6ba82b..dd8e0c31009 100644 --- a/src/devices/bus/msx_cart/korean.h +++ b/src/devices/bus/msx_cart/korean.h @@ -20,74 +20,58 @@ public: virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; private: - void restore_banks(); - void setup_bank(uint8_t bank); + void bank_w(offs_t offset, u8 data); - uint8_t m_bank_mask; - uint8_t m_selected_bank[4]; - uint8_t *m_bank_base[4]; + memory_bank_array_creator<4> m_rombank; + + u8 m_bank_mask; }; class msx_cart_korean_90in1_device : public device_t, public msx_cart_interface { public: - msx_cart_korean_90in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_korean_90in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; - virtual void device_post_load() override; private: - void banking(uint8_t data); + void banking(u8 data); - void restore_banks(); - - uint8_t m_bank_mask; - uint8_t m_selected_bank; - uint8_t *m_bank_base[4]; + memory_bank_array_creator<3> m_rombank; + memory_view m_view; + u8 m_bank_mask; }; class msx_cart_korean_126in1_device : public device_t, public msx_cart_interface { public: - msx_cart_korean_126in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_korean_126in1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; private: - void restore_banks(); - void setup_bank(uint8_t bank); + void bank_w(offs_t offset, u8 data); - uint8_t m_bank_mask; - uint8_t m_selected_bank[2]; - uint8_t *m_bank_base[2]; + memory_bank_array_creator<2> m_rombank; + u8 m_bank_mask; }; diff --git a/src/devices/bus/msx_cart/majutsushi.cpp b/src/devices/bus/msx_cart/majutsushi.cpp index c94f5a00dc5..65ae0bf42c0 100644 --- a/src/devices/bus/msx_cart/majutsushi.cpp +++ b/src/devices/bus/msx_cart/majutsushi.cpp @@ -9,22 +9,14 @@ DEFINE_DEVICE_TYPE(MSX_CART_MAJUTSUSHI, msx_cart_majutsushi_device, "msx_cart_majutsushi", "MSX Cartridge - Majutsushi") -msx_cart_majutsushi_device::msx_cart_majutsushi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_majutsushi_device::msx_cart_majutsushi_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_MAJUTSUSHI, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_dac(*this, "dac") + , m_rombank(*this, "rombank%u", 0U) { - for (auto & elem : m_selected_bank) - { - elem = 0; - } - for (auto & elem : m_bank_base) - { - elem = nullptr; - } } - void msx_cart_majutsushi_device::device_add_mconfig(machine_config &config) { // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. @@ -32,85 +24,32 @@ void msx_cart_majutsushi_device::device_add_mconfig(machine_config &config) DAC_8BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.05); // unknown DAC } - -void msx_cart_majutsushi_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_majutsushi_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_majutsushi_device::restore_banks() -{ - m_bank_base[0] = get_rom_base() + ( m_selected_bank[0] & 0x0f ) * 0x2000; - m_bank_base[1] = get_rom_base() + ( m_selected_bank[1] & 0x0f ) * 0x2000; - m_bank_base[2] = get_rom_base() + ( m_selected_bank[0] & 0x0f ) * 0x2000; - m_bank_base[3] = get_rom_base() + ( m_selected_bank[1] & 0x0f ) * 0x2000; - m_bank_base[4] = get_rom_base() + ( m_selected_bank[2] & 0x0f ) * 0x2000; - m_bank_base[5] = get_rom_base() + ( m_selected_bank[3] & 0x0f ) * 0x2000; - m_bank_base[6] = get_rom_base() + ( m_selected_bank[2] & 0x0f ) * 0x2000; - m_bank_base[7] = get_rom_base() + ( m_selected_bank[3] & 0x0f ) * 0x2000; -} - - -void msx_cart_majutsushi_device::device_reset() -{ - for (int i = 0; i < 4; i++) - { - m_selected_bank[i] = i; - } -} - - void msx_cart_majutsushi_device::initialize_cartridge() { - if ( get_rom_size() != 0x20000 ) + if (get_rom_size() != 0x20000) { fatalerror("majutsushi: Invalid ROM size\n"); } - restore_banks(); -} - + for (int i = 0; i < 3; i++) + m_rombank[i]->configure_entries(0, 16, get_rom_base(), 0x2000); -uint8_t msx_cart_majutsushi_device::read_cart(offs_t offset) -{ - return m_bank_base[offset >> 13][offset & 0x1fff]; + page(0)->install_rom(0x0000, 0x1fff, get_rom_base()); + page(0)->install_read_bank(0x2000, 0x3fff, m_rombank[0]); + page(1)->install_rom(0x4000, 0x5fff, get_rom_base()); + page(1)->install_write_handler(0x5000, 0x5000, 0, 0x0fff, 0, write8smo_delegate(m_dac, FUNC(dac_byte_interface::write))); + page(1)->install_read_bank(0x6000, 0x7fff, m_rombank[0]); + page(1)->install_write_handler(0x6000, 0x6000, 0, 0x1fff, 0, write8smo_delegate(*this, FUNC(msx_cart_majutsushi_device::bank_w<0>))); + page(2)->install_read_bank(0x8000, 0x9fff, m_rombank[1]); + page(2)->install_write_handler(0x8000, 0x8000, 0, 0x1fff, 0, write8smo_delegate(*this, FUNC(msx_cart_majutsushi_device::bank_w<1>))); + page(2)->install_read_bank(0xa000, 0xbfff, m_rombank[2]); + page(2)->install_write_handler(0xa000, 0xa000, 0, 0x1fff, 0, write8smo_delegate(*this, FUNC(msx_cart_majutsushi_device::bank_w<2>))); + page(3)->install_read_bank(0xc000, 0xdfff, m_rombank[1]); + page(3)->install_read_bank(0xe000, 0xffff, m_rombank[2]); } - -void msx_cart_majutsushi_device::write_cart(offs_t offset, uint8_t data) +template <int Bank> +void msx_cart_majutsushi_device::bank_w(u8 data) { - switch (offset & 0xe000) - { - case 0x4000: - if (offset & 0x1000) - { - m_dac->write(data); - } - break; - - case 0x6000: - m_selected_bank[1] = data & 0x0f; - m_bank_base[1] = get_rom_base() + m_selected_bank[1] * 0x2000; - m_bank_base[3] = get_rom_base() + m_selected_bank[1] * 0x2000; - break; - - case 0x8000: - m_selected_bank[2] = data & 0x0f; - m_bank_base[4] = get_rom_base() + m_selected_bank[2] * 0x2000; - m_bank_base[6] = get_rom_base() + m_selected_bank[2] * 0x2000; - break; - - case 0xa000: - m_selected_bank[3] = data & 0x0f; - m_bank_base[5] = get_rom_base() + m_selected_bank[3] * 0x2000; - m_bank_base[7] = get_rom_base() + m_selected_bank[3] * 0x2000; - break; - } + m_rombank[Bank]->set_entry(data & 0x0f); } diff --git a/src/devices/bus/msx_cart/majutsushi.h b/src/devices/bus/msx_cart/majutsushi.h index ebdf549272e..96ea5261ca6 100644 --- a/src/devices/bus/msx_cart/majutsushi.h +++ b/src/devices/bus/msx_cart/majutsushi.h @@ -15,28 +15,21 @@ DECLARE_DEVICE_TYPE(MSX_CART_MAJUTSUSHI, msx_cart_majutsushi_device) class msx_cart_majutsushi_device : public device_t, public msx_cart_interface { public: - msx_cart_majutsushi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_majutsushi_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_post_load() override; + virtual void device_start() override { } virtual void device_add_mconfig(machine_config &config) override; - void restore_banks(); - private: - required_device<dac_byte_interface> m_dac; + template <int Bank> void bank_w(u8 data); - uint8_t m_selected_bank[4]; - uint8_t *m_bank_base[8]; + required_device<dac_byte_interface> m_dac; + memory_bank_array_creator<3> m_rombank; }; diff --git a/src/devices/bus/msx_cart/moonsound.cpp b/src/devices/bus/msx_cart/moonsound.cpp index 07ae53f6fca..2ffa68fc1f6 100644 --- a/src/devices/bus/msx_cart/moonsound.cpp +++ b/src/devices/bus/msx_cart/moonsound.cpp @@ -21,21 +21,19 @@ TODO: DEFINE_DEVICE_TYPE(MSX_CART_MOONSOUND, msx_cart_moonsound_device, "msx_moonsound", "MSX Cartridge - MoonSound") -msx_cart_moonsound_device::msx_cart_moonsound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_moonsound_device::msx_cart_moonsound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_MOONSOUND, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_ymf278b(*this, "ymf278b") { } - void msx_cart_moonsound_device::ymf278b_map(address_map &map) { map(0x000000, 0x1fffff).rom(); map(0x200000, 0x3fffff).ram(); // 2MB sram for testing } - void msx_cart_moonsound_device::device_add_mconfig(machine_config &config) { // The moonsound cartridge has a separate stereo output. @@ -53,70 +51,48 @@ void msx_cart_moonsound_device::device_add_mconfig(machine_config &config) m_ymf278b->add_route(5, "rspeaker", 0.50); } - -ROM_START( msx_cart_moonsound ) +ROM_START(msx_cart_moonsound) ROM_REGION(0x400000, "ymf278b", 0) ROM_LOAD("yrw801.rom", 0x0, 0x200000, CRC(2a9d8d43) SHA1(32760893ce06dbe3930627755ba065cc3d8ec6ca)) ROM_END - const tiny_rom_entry *msx_cart_moonsound_device::device_rom_region() const { - return ROM_NAME( msx_cart_moonsound ); + return ROM_NAME(msx_cart_moonsound); } - void msx_cart_moonsound_device::device_start() { // Install IO read/write handlers io_space().install_readwrite_handler(0x7e, 0x7f, read8sm_delegate(*this, FUNC(msx_cart_moonsound_device::read_ymf278b_pcm)), write8sm_delegate(*this, FUNC(msx_cart_moonsound_device::write_ymf278b_pcm))); - io_space().install_readwrite_handler(0xc4, 0xc7, read8sm_delegate(*this, FUNC(msx_cart_moonsound_device::read_ymf278b_fm)), write8sm_delegate(*this, FUNC(msx_cart_moonsound_device::write_ymf278b_fm))); + io_space().install_readwrite_handler(0xc4, 0xc7, read8sm_delegate(m_ymf278b, FUNC(ymf278b_device::read)), write8sm_delegate(m_ymf278b, FUNC(ymf278b_device::write))); io_space().install_read_handler(0xc0, 0xc0, read8smo_delegate(*this, FUNC(msx_cart_moonsound_device::read_c0))); } - void msx_cart_moonsound_device::device_reset() { } - WRITE_LINE_MEMBER(msx_cart_moonsound_device::irq_w) { LOG("moonsound: irq state %d\n", state); irq_out(state); } - -void msx_cart_moonsound_device::write_ymf278b_fm(offs_t offset, uint8_t data) -{ - LOG("moonsound: write 0x%02x, data 0x%02x\n", 0xc4 + offset, data); - m_ymf278b->write(offset, data); -} - - -uint8_t msx_cart_moonsound_device::read_ymf278b_fm(offs_t offset) -{ - LOG("moonsound: read 0x%02x\n", 0xc4 + offset); - return m_ymf278b->read(offset); -} - - -void msx_cart_moonsound_device::write_ymf278b_pcm(offs_t offset, uint8_t data) +void msx_cart_moonsound_device::write_ymf278b_pcm(offs_t offset, u8 data) { LOG("moonsound: write 0x%02x, data 0x%02x\n", 0x7e + offset, data); m_ymf278b->write(4 + offset, data); } - -uint8_t msx_cart_moonsound_device::read_ymf278b_pcm(offs_t offset) +u8 msx_cart_moonsound_device::read_ymf278b_pcm(offs_t offset) { LOG("moonsound: read 0x%02x\n", 0x7e + offset); return m_ymf278b->read(4 + offset); } - // For detecting presence of moonsound cartridge -uint8_t msx_cart_moonsound_device::read_c0() +u8 msx_cart_moonsound_device::read_c0() { LOG("moonsound: read 0xc0\n"); return 0x00; diff --git a/src/devices/bus/msx_cart/moonsound.h b/src/devices/bus/msx_cart/moonsound.h index 62f614ae729..c5b1daa4287 100644 --- a/src/devices/bus/msx_cart/moonsound.h +++ b/src/devices/bus/msx_cart/moonsound.h @@ -15,7 +15,7 @@ DECLARE_DEVICE_TYPE(MSX_CART_MOONSOUND, msx_cart_moonsound_device) class msx_cart_moonsound_device : public device_t, public msx_cart_interface { public: - msx_cart_moonsound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_moonsound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides @@ -27,12 +27,9 @@ protected: private: DECLARE_WRITE_LINE_MEMBER(irq_w); - void write_ymf278b_fm(offs_t offset, uint8_t data); - uint8_t read_ymf278b_fm(offs_t offset); - void write_ymf278b_pcm(offs_t offset, uint8_t data); - uint8_t read_ymf278b_pcm(offs_t offset); - uint8_t read_c0(); - + void write_ymf278b_pcm(offs_t offset, u8 data); + u8 read_ymf278b_pcm(offs_t offset); + u8 read_c0(); void ymf278b_map(address_map &map); required_device<ymf278b_device> m_ymf278b; diff --git a/src/devices/bus/msx_cart/msx_audio.cpp b/src/devices/bus/msx_cart/msx_audio.cpp index 3f8fd1fd772..471fe4b3f2e 100644 --- a/src/devices/bus/msx_cart/msx_audio.cpp +++ b/src/devices/bus/msx_cart/msx_audio.cpp @@ -54,7 +54,7 @@ For testing the sample ram (playback of a cuckoo sound, the volume of the sound - CALL COPY PCM(#1,0) - CALL PLAY PCM(0) -See also http://www.mccm.hetlab.tk/millennium/milc/gc/topic_26.htm (dutch) +See also https://www.msxcomputermagazine.nl/mccm/millennium/milc/gc/topic_26.htm (dutch) and/or http://ngs.no.coocan.jp/doc/wiki.cgi/datapack?page=4.2+MSX-AUDIO+%B3%C8%C4%A5BASIC (japanese) @@ -72,14 +72,13 @@ DEFINE_DEVICE_TYPE(MSX_CART_MSX_AUDIO_NMS1205, msx_cart_msx_audio_nms1205_device DEFINE_DEVICE_TYPE(MSX_CART_MSX_AUDIO_FSCA1, msx_cart_msx_audio_fsca1_device, "msx_audio_fsca1", "MSX Cartridge - MSX-AUDIO FS-CA1") -msx_cart_msx_audio_hxmu900_device::msx_cart_msx_audio_hxmu900_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_msx_audio_hxmu900_device::msx_cart_msx_audio_hxmu900_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_MSX_AUDIO_HXMU900, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_y8950(*this, "y8950") { } - void msx_cart_msx_audio_hxmu900_device::device_add_mconfig(machine_config &config) { // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. @@ -92,7 +91,6 @@ void msx_cart_msx_audio_hxmu900_device::device_add_mconfig(machine_config &confi MSX_AUDIO_KBDC_PORT(config, "kbdc", msx_audio_keyboards, nullptr); } - void msx_cart_msx_audio_hxmu900_device::device_start() { // Install IO read/write handlers @@ -100,34 +98,24 @@ void msx_cart_msx_audio_hxmu900_device::device_start() io_space().install_read_handler(0xc0, 0xc1, read8sm_delegate(*m_y8950, FUNC(y8950_device::read))); } - void msx_cart_msx_audio_hxmu900_device::initialize_cartridge() { if (get_rom_size() < 0x8000) { fatalerror("msx_audio: Invalid ROM size\n"); } -} - -uint8_t msx_cart_msx_audio_hxmu900_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xC000) - { - return m_rom[offset - 0x4000]; - } - return 0xff; + page(1)->install_rom(0x4000, 0x7fff, get_rom_base()); + page(2)->install_rom(0x8000, 0xbfff, get_rom_base() + 0x4000); } - -ROM_START( msx_hxmu ) +ROM_START(msx_hxmu) ROM_REGION(0x8000, "y8950", ROMREGION_ERASE00) ROM_END - const tiny_rom_entry *msx_cart_msx_audio_hxmu900_device::device_rom_region() const { - return ROM_NAME( msx_hxmu ); + return ROM_NAME(msx_hxmu); } @@ -144,7 +132,6 @@ msx_cart_msx_audio_nms1205_device::msx_cart_msx_audio_nms1205_device(const machi { } - void msx_cart_msx_audio_nms1205_device::device_add_mconfig(machine_config &config) { // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. @@ -167,18 +154,15 @@ void msx_cart_msx_audio_nms1205_device::device_add_mconfig(machine_config &confi MIDI_PORT(config, m_mdout, midiout_slot, "midiout"); } - -ROM_START( msx_nms1205 ) +ROM_START(msx_nms1205) ROM_REGION(0x8000, "y8950", ROMREGION_ERASE00) ROM_END - const tiny_rom_entry *msx_cart_msx_audio_nms1205_device::device_rom_region() const { - return ROM_NAME( msx_nms1205 ); + return ROM_NAME(msx_nms1205); } - WRITE_LINE_MEMBER(msx_cart_msx_audio_nms1205_device::irq_write) { // Trigger IRQ on the maincpu @@ -188,7 +172,6 @@ WRITE_LINE_MEMBER(msx_cart_msx_audio_nms1205_device::irq_write) // m_out_irq_cb(state); } - WRITE_LINE_MEMBER(msx_cart_msx_audio_nms1205_device::midi_in) { // MIDI in signals is sent to both the 6850 and the MIDI thru output port @@ -196,7 +179,6 @@ WRITE_LINE_MEMBER(msx_cart_msx_audio_nms1205_device::midi_in) m_mdthru->write_txd(state); } - void msx_cart_msx_audio_nms1205_device::device_start() { // Install IO read/write handlers @@ -206,23 +188,14 @@ void msx_cart_msx_audio_nms1205_device::device_start() io_space().install_read_handler(0x04, 0x05, read8sm_delegate(*m_acia6850, FUNC(acia6850_device::read))); } - void msx_cart_msx_audio_nms1205_device::initialize_cartridge() { if (get_rom_size() < 0x8000) { fatalerror("msx_audio: Invalid ROM size\n"); } -} - - -uint8_t msx_cart_msx_audio_nms1205_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xC000) - { - return m_rom[offset - 0x4000]; - } - return 0xff; + page(1)->install_rom(0x4000, 0x7fff, get_rom_base()); + page(2)->install_rom(0x8000, 0xbfff, get_rom_base() + 0x4000); } @@ -237,12 +210,13 @@ msx_cart_msx_audio_fsca1_device::msx_cart_msx_audio_fsca1_device(const machine_c , m_y8950(*this, "y8950") , m_io_config(*this, "CONFIG") , m_region_y8950(*this, "y8950") - , m_7ffe(0) + , m_rombank(*this, "rombank%u", 0U) + , m_view0(*this, "view0") + , m_view1(*this, "view1") , m_7fff(0) { } - void msx_cart_msx_audio_fsca1_device::device_add_mconfig(machine_config &config) { // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'. @@ -257,8 +231,7 @@ void msx_cart_msx_audio_fsca1_device::device_add_mconfig(machine_config &config) MSX_AUDIO_KBDC_PORT(config, "kbdc", msx_audio_keyboards, nullptr); } - -static INPUT_PORTS_START( msx_audio_fsca1 ) +static INPUT_PORTS_START(msx_audio_fsca1) PORT_START("CONFIG") PORT_CONFNAME( 0x04, 0x04, "FS-CA1 Firmware switch") PORT_CONFSETTING( 0x04, "On" ) @@ -266,31 +239,35 @@ static INPUT_PORTS_START( msx_audio_fsca1 ) PORT_BIT(0xFB, IP_ACTIVE_HIGH, IPT_UNKNOWN) INPUT_PORTS_END - ioport_constructor msx_cart_msx_audio_fsca1_device::device_input_ports() const { - return INPUT_PORTS_NAME( msx_audio_fsca1 ); + return INPUT_PORTS_NAME(msx_audio_fsca1); } - -ROM_START( msx_fsca1 ) +ROM_START(msx_fsca1) ROM_REGION(0x8000, "y8950", ROMREGION_ERASE00) ROM_END - const tiny_rom_entry *msx_cart_msx_audio_fsca1_device::device_rom_region() const { - return ROM_NAME( msx_fsca1 ); + return ROM_NAME(msx_fsca1); } - void msx_cart_msx_audio_fsca1_device::device_start() { // Install IO read/write handlers io_space().install_write_handler(0xc0, 0xc3, write8sm_delegate(*this, FUNC(msx_cart_msx_audio_fsca1_device::write_y8950))); io_space().install_read_handler(0xc0, 0xc3, read8sm_delegate(*this, FUNC(msx_cart_msx_audio_fsca1_device::read_y8950))); + save_item(NAME(m_7fff)); } +void msx_cart_msx_audio_fsca1_device::device_reset() +{ + m_view0.select(0); + m_view1.select(0); + m_rombank[0]->set_entry(0); + m_rombank[1]->set_entry(0); +} void msx_cart_msx_audio_fsca1_device::initialize_cartridge() { @@ -298,82 +275,67 @@ void msx_cart_msx_audio_fsca1_device::initialize_cartridge() { fatalerror("msx_audio_fsca1: Invalid ROM size\n"); } -} - - -uint8_t msx_cart_msx_audio_fsca1_device::read_cart(offs_t offset) -{ - if (m_7ffe == 0 && (offset & 0xB000) == 0x3000) - { - return m_sram[offset & 0xfff]; - } - return m_rom[((m_7ffe & 0x03) << 15) | (offset & 0x7fff)]; -} + m_rombank[0]->configure_entries(0, 4, get_rom_base(), 0x8000); + m_rombank[1]->configure_entries(0, 4, get_rom_base() + 0x4000, 0x8000); -void msx_cart_msx_audio_fsca1_device::write_cart(offs_t offset, uint8_t data) -{ - if (offset == 0x7ffe) - { - m_7ffe = data; - return; - } + page(0)->install_view(0x0000, 0x3fff, m_view0); + m_view0[0].install_read_bank(0x0000, 0x3fff, m_rombank[0]); + m_view0[0].install_ram(0x3000, 0x3fff, get_sram_base()); + m_view0[1].install_read_bank(0x0000, 0x3fff, m_rombank[0]); - if (offset == 0x7fff) - { - m_7fff = data; - return; - } + page(1)->install_view(0x4000, 0x7fff, m_view1); + m_view1[0].install_read_bank(0x4000, 0x7ffd, m_rombank[1]); + m_view1[0].install_ram(0x7000, 0x7ffd, get_sram_base()); + m_view1[1].install_read_bank(0x4000, 0x7ffd, m_rombank[1]); + page(1)->install_write_handler(0x7ffe, 0x7ffe, write8smo_delegate(*this, FUNC(msx_cart_msx_audio_fsca1_device::bank_w))); + page(1)->install_write_handler(0x7fff, 0x7fff, write8smo_delegate(*this, FUNC(msx_cart_msx_audio_fsca1_device::write_7fff))); - if (m_7ffe == 0 && (offset & 0xb000) == 0x3000) - { - m_sram[offset & 0xfff] = data; - return; - } + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank[0]); + page(3)->install_read_bank(0xc000, 0xffff, m_rombank[1]); +} - logerror("msx_cart_msx_audio_fsca1_device: Unhandled write %02x to %04x\n", data, offset); +void msx_cart_msx_audio_fsca1_device::bank_w(u8 data) +{ + m_rombank[0]->set_entry(data & 0x03); + m_rombank[1]->set_entry(data & 0x03); + m_view0.select((data != 0) ? 1 : 0); + m_view1.select((data != 0) ? 1 : 0); } +void msx_cart_msx_audio_fsca1_device::write_7fff(u8 data) +{ + m_7fff = data; +} -void msx_cart_msx_audio_fsca1_device::write_y8950(offs_t offset, uint8_t data) +void msx_cart_msx_audio_fsca1_device::write_y8950(offs_t offset, u8 data) { if (offset & 2) { if (m_7fff & 0x02) - { m_y8950->write(offset, data); - } } else { if (m_7fff & 0x01) - { m_y8950->write(offset, data); - } } } - -uint8_t msx_cart_msx_audio_fsca1_device::read_y8950(offs_t offset) +u8 msx_cart_msx_audio_fsca1_device::read_y8950(offs_t offset) { if (offset & 2) - { return (m_7fff & 0x02) ? m_y8950->read(offset) : 0xff; - } else - { return (m_7fff & 0x01) ? m_y8950->read(offset) : 0xff; - } } - -void msx_cart_msx_audio_fsca1_device::y8950_io_w(uint8_t data) +void msx_cart_msx_audio_fsca1_device::y8950_io_w(u8 data) { logerror("msx_fsca1::y8950_io_w: %02x\n", data); } - -uint8_t msx_cart_msx_audio_fsca1_device::y8950_io_r() +u8 msx_cart_msx_audio_fsca1_device::y8950_io_r() { return m_io_config->read(); } diff --git a/src/devices/bus/msx_cart/msx_audio.h b/src/devices/bus/msx_cart/msx_audio.h index 490169244af..96c44d637d8 100644 --- a/src/devices/bus/msx_cart/msx_audio.h +++ b/src/devices/bus/msx_cart/msx_audio.h @@ -19,12 +19,10 @@ DECLARE_DEVICE_TYPE(MSX_CART_MSX_AUDIO_FSCA1, msx_cart_msx_audio_fsca1_device) class msx_cart_msx_audio_hxmu900_device : public device_t, public msx_cart_interface { public: - msx_cart_msx_audio_hxmu900_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_msx_audio_hxmu900_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - protected: virtual void device_start() override; @@ -40,12 +38,10 @@ private: class msx_cart_msx_audio_nms1205_device : public device_t, public msx_cart_interface { public: - msx_cart_msx_audio_nms1205_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_msx_audio_nms1205_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - protected: virtual void device_start() override; @@ -67,15 +63,13 @@ private: class msx_cart_msx_audio_fsca1_device : public device_t, public msx_cart_interface { public: - msx_cart_msx_audio_fsca1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_msx_audio_fsca1_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: virtual void device_start() override; + virtual void device_reset() override; // device-level overrides virtual void device_add_mconfig(machine_config &config) override; @@ -83,17 +77,20 @@ protected: virtual const tiny_rom_entry *device_rom_region() const override; private: - void write_y8950(offs_t offset, uint8_t data); - uint8_t read_y8950(offs_t offset); - - void y8950_io_w(uint8_t data); - uint8_t y8950_io_r(); + void write_y8950(offs_t offset, u8 data); + u8 read_y8950(offs_t offset); + void y8950_io_w(u8 data); + u8 y8950_io_r(); + void bank_w(u8 data); + void write_7fff(u8 data); required_device<y8950_device> m_y8950; required_ioport m_io_config; required_memory_region m_region_y8950; - uint8_t m_7ffe; - uint8_t m_7fff; + memory_bank_array_creator<2> m_rombank; + memory_view m_view0; + memory_view m_view1; + u8 m_7fff; }; #endif // MAME_BUS_MSX_CART_MSX_AUDIO_H diff --git a/src/devices/bus/msx_cart/msx_audio_kb.cpp b/src/devices/bus/msx_cart/msx_audio_kb.cpp index aba915ed718..94b712a9429 100644 --- a/src/devices/bus/msx_cart/msx_audio_kb.cpp +++ b/src/devices/bus/msx_cart/msx_audio_kb.cpp @@ -13,7 +13,7 @@ msx_audio_kb_port_interface::msx_audio_kb_port_interface(machine_config const &m } -msx_audio_kbdc_port_device::msx_audio_kbdc_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_audio_kbdc_port_device::msx_audio_kbdc_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_AUDIO_KBDC_PORT, tag, owner, clock) , device_single_card_slot_interface<msx_audio_kb_port_interface>(mconfig, *this) , m_keyboard(nullptr) @@ -27,14 +27,14 @@ void msx_audio_kbdc_port_device::device_start() } -void msx_audio_kbdc_port_device::write(uint8_t data) +void msx_audio_kbdc_port_device::write(u8 data) { if (m_keyboard) m_keyboard->write(data); } -uint8_t msx_audio_kbdc_port_device::read() +u8 msx_audio_kbdc_port_device::read() { if (m_keyboard) return m_keyboard->read(); @@ -50,7 +50,7 @@ DECLARE_DEVICE_TYPE(MSX_AUDIO_KB_NMS1160, msx_nms1160_device) class msx_hxmu901_device : public device_t, public msx_audio_kb_port_interface { public: - msx_hxmu901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + msx_hxmu901_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_AUDIO_KB_HXMU901, tag, owner, clock) , msx_audio_kb_port_interface(mconfig, *this) , m_row(0) @@ -60,9 +60,9 @@ public: virtual ioport_constructor device_input_ports() const override; - virtual uint8_t read() override + virtual u8 read() override { - uint8_t result = 0xff; + u8 result = 0xff; for (int i = 0; i < 8; i++) { @@ -74,7 +74,7 @@ public: return result; } - virtual void write(uint8_t data) override + virtual void write(u8 data) override { m_row = data; } @@ -88,7 +88,7 @@ private: }; -static INPUT_PORTS_START( hxmu901) +static INPUT_PORTS_START(hxmu901) PORT_START("KEY.0") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C#1") PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D1") @@ -173,14 +173,14 @@ INPUT_PORTS_END ioport_constructor msx_hxmu901_device::device_input_ports() const { - return INPUT_PORTS_NAME( hxmu901 ); + return INPUT_PORTS_NAME(hxmu901); } class msx_nms1160_device : public device_t, public msx_audio_kb_port_interface { public: - msx_nms1160_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + msx_nms1160_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_AUDIO_KB_NMS1160, tag, owner, clock) , msx_audio_kb_port_interface(mconfig, *this) , m_row(0) @@ -190,9 +190,9 @@ public: virtual ioport_constructor device_input_ports() const override; - virtual uint8_t read() override + virtual u8 read() override { - uint8_t result = 0xff; + u8 result = 0xff; for (int i = 0; i < 8; i++) { @@ -204,7 +204,7 @@ public: return result; } - virtual void write(uint8_t data) override + virtual void write(u8 data) override { logerror("msx_nms1160::write %02x\n", data); m_row = data; @@ -219,7 +219,7 @@ private: }; -static INPUT_PORTS_START( nms1160 ) +static INPUT_PORTS_START(nms1160) PORT_START("KEY.0") PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C1") PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C#1") @@ -302,7 +302,7 @@ INPUT_PORTS_END ioport_constructor msx_nms1160_device::device_input_ports() const { - return INPUT_PORTS_NAME( nms1160 ); + return INPUT_PORTS_NAME(nms1160); } diff --git a/src/devices/bus/msx_cart/msx_audio_kb.h b/src/devices/bus/msx_cart/msx_audio_kb.h index ecab5732c98..c347fd3add0 100644 --- a/src/devices/bus/msx_cart/msx_audio_kb.h +++ b/src/devices/bus/msx_cart/msx_audio_kb.h @@ -25,18 +25,18 @@ public: // construction/destruction template <typename T> msx_audio_kbdc_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt) - : msx_audio_kbdc_port_device(mconfig, tag, owner, (uint32_t)0) + : msx_audio_kbdc_port_device(mconfig, tag, owner, u32(0)) { option_reset(); opts(*this); set_default_option(dflt); set_fixed(false); } - msx_audio_kbdc_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_audio_kbdc_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); // Physical connection simply consists of 8 input and 8 output lines split across 2 connectors - void write(uint8_t data); - uint8_t read(); + void write(u8 data); + u8 read(); protected: // device-level overrides diff --git a/src/devices/bus/msx_cart/msxdos2.cpp b/src/devices/bus/msx_cart/msxdos2.cpp index 7f3e506b007..1deb7081051 100644 --- a/src/devices/bus/msx_cart/msxdos2.cpp +++ b/src/devices/bus/msx_cart/msxdos2.cpp @@ -3,42 +3,26 @@ #include "emu.h" #include "msxdos2.h" +// This is the bare minimum to get a msx-dos 2 rom working in a system +// TODO: +// - Add subslots for regular rom and kanji driver rom +// - Add support for 128KB and 256KB memory mapper versions + DEFINE_DEVICE_TYPE(MSX_CART_MSXDOS2, msx_cart_msxdos2_device, "msx_cart_msxdos2", "MSX Cartridge - MSXDOS2") -msx_cart_msxdos2_device::msx_cart_msxdos2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_msxdos2_device::msx_cart_msxdos2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_MSXDOS2, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_selected_bank(0) - , m_bank_base(nullptr) -{ -} - - -void msx_cart_msxdos2_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_msxdos2_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_msxdos2_device::restore_banks() + , m_rombank(*this, "rombank") { - m_bank_base = get_rom_base() + ( m_selected_bank & 0x03 ) * 0x4000; } - void msx_cart_msxdos2_device::device_reset() { - m_selected_bank = 0; + m_rombank->set_entry(1); } - void msx_cart_msxdos2_device::initialize_cartridge() { if (get_rom_size() != 0x10000) @@ -46,26 +30,13 @@ void msx_cart_msxdos2_device::initialize_cartridge() fatalerror("msxdos2: Invalid ROM size\n"); } - restore_banks(); -} - - -uint8_t msx_cart_msxdos2_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0x8000) - { - return m_bank_base[offset & 0x3fff]; - } + m_rombank->configure_entries(0, 4, get_rom_base(), 0x4000); - return 0xff; + page(1)->install_read_bank(0x4000, 0x7fff, m_rombank); + page(1)->install_write_handler(0x7ffe, 0x7ffe, write8smo_delegate(*this, FUNC(msx_cart_msxdos2_device::bank_w))); } - -void msx_cart_msxdos2_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_msxdos2_device::bank_w(u8 data) { - if (offset == 0x6000) - { - m_selected_bank = data; - restore_banks(); - } + m_rombank->set_entry(data & 0x03); } diff --git a/src/devices/bus/msx_cart/msxdos2.h b/src/devices/bus/msx_cart/msxdos2.h index dd5eb51d245..863638837c3 100644 --- a/src/devices/bus/msx_cart/msxdos2.h +++ b/src/devices/bus/msx_cart/msxdos2.h @@ -14,24 +14,19 @@ DECLARE_DEVICE_TYPE(MSX_CART_MSXDOS2, msx_cart_msxdos2_device) class msx_cart_msxdos2_device : public device_t, public msx_cart_interface { public: - msx_cart_msxdos2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_msxdos2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); private: - uint8_t m_selected_bank; - uint8_t *m_bank_base; + void bank_w(u8 data); + + memory_bank_creator m_rombank; }; diff --git a/src/devices/bus/msx_cart/nomapper.cpp b/src/devices/bus/msx_cart/nomapper.cpp index 24ebbb38e0d..ed4676237ca 100644 --- a/src/devices/bus/msx_cart/nomapper.cpp +++ b/src/devices/bus/msx_cart/nomapper.cpp @@ -7,7 +7,7 @@ DEFINE_DEVICE_TYPE(MSX_CART_NOMAPPER, msx_cart_nomapper_device, "msx_cart_nomapper", "MSX Cartridge - ROM") -msx_cart_nomapper_device::msx_cart_nomapper_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_nomapper_device::msx_cart_nomapper_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_NOMAPPER, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_start_address(0) @@ -15,22 +15,41 @@ msx_cart_nomapper_device::msx_cart_nomapper_device(const machine_config &mconfig { } -void msx_cart_nomapper_device::device_start() +void msx_cart_nomapper_device::install_memory() { + u32 start_address = m_start_address; + u32 rom_offset = 0; + + if (m_start_address != 0x0000 && m_start_address != 0x4000 && m_start_address != 0x8000 && m_start_address != 0xc000) + { + fatalerror("nomapper: Unsupported start address %04x\n", m_start_address); + } + + for (int i = 0; i < 4; i++) + { + if (start_address < (i + 1) * 0x4000 && start_address < m_end_address) + { + if (page(i)) + { + page(i)->install_rom(start_address, std::min<uint32_t>(start_address + 0x3fff, m_end_address - 1), get_rom_base() + rom_offset); + } + rom_offset += 0x4000; + start_address += 0x4000; + } + } } void msx_cart_nomapper_device::initialize_cartridge() { - uint32_t size = get_rom_size(); - uint8_t *rom = get_rom_base(); + u32 size = get_rom_size(); + u8 *rom = get_rom_base(); - // determine start address - // default to $4000 + // determine start address, default to 0x4000 m_start_address = 0x4000; switch (size) { - /* 8KB/16KB */ + // 8KB/16KB case 0x2000: case 0x4000: { uint16_t start = rom[3] << 8 | rom[2]; @@ -51,7 +70,7 @@ void msx_cart_nomapper_device::initialize_cartridge() break; } - /* 32KB */ + // 32KB case 0x8000: // take default, check when no "AB" at $0000, but "AB" at $4000 if (rom[0] != 'A' && rom[1] != 'B' && rom[0x4000] == 'A' && rom[0x4001] == 'B') @@ -65,7 +84,7 @@ void msx_cart_nomapper_device::initialize_cartridge() break; - /* 48KB */ + // 48KB case 0xc000: // "AB" at $0000, but no "AB" at $4000, not "AB": $0000 if (rom[0] == 'A' && rom[1] == 'B' && rom[0x4000] != 'A' && rom[0x4001] != 'B') @@ -75,20 +94,13 @@ void msx_cart_nomapper_device::initialize_cartridge() break; - /* 64KB */ + // 64KB default: m_start_address = 0; break; } - m_end_address = std::min<uint32_t>(m_start_address + size, 0x10000); -} + m_end_address = std::min<u32>(m_start_address + size, 0x10000); -uint8_t msx_cart_nomapper_device::read_cart(offs_t offset) -{ - if ( offset >= m_start_address && offset < m_end_address ) - { - return get_rom_base()[offset - m_start_address]; - } - return 0xff; + install_memory(); } diff --git a/src/devices/bus/msx_cart/nomapper.h b/src/devices/bus/msx_cart/nomapper.h index eb5e40e1d08..82407b11c16 100644 --- a/src/devices/bus/msx_cart/nomapper.h +++ b/src/devices/bus/msx_cart/nomapper.h @@ -17,15 +17,15 @@ public: msx_cart_nomapper_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // device-level overrides - virtual void device_start() override; + virtual void device_start() override { } virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - private: uint32_t m_start_address; uint32_t m_end_address; + + void install_memory(); }; #endif // MAME_BUS_MSX_CART_NOMAPPER_H diff --git a/src/devices/bus/msx_cart/rtype.cpp b/src/devices/bus/msx_cart/rtype.cpp index 6cda0efb4e8..affcc4c843d 100644 --- a/src/devices/bus/msx_cart/rtype.cpp +++ b/src/devices/bus/msx_cart/rtype.cpp @@ -6,77 +6,31 @@ DEFINE_DEVICE_TYPE(MSX_CART_RTYPE, msx_cart_rtype_device, "msx_cart_rtype", "MSX Cartridge - R-Type") -msx_cart_rtype_device::msx_cart_rtype_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_rtype_device::msx_cart_rtype_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_RTYPE, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_selected_bank(0) + , m_rombank(*this, "rombank") { - for (auto & elem : m_bank_base) - { - elem = nullptr; - } -} - - -void msx_cart_rtype_device::device_start() -{ - save_item(NAME(m_selected_bank)); } - -void msx_cart_rtype_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_rtype_device::restore_banks() -{ - m_bank_base[0] = get_rom_base() + 15 * 0x4000; - if (m_selected_bank & 0x10) - { - m_selected_bank &= 0x17; - } - m_bank_base[1] = get_rom_base() + m_selected_bank * 0x4000; -} - - -void msx_cart_rtype_device::device_reset() -{ - m_selected_bank = 15; -} - - void msx_cart_rtype_device::initialize_cartridge() { - if ( get_rom_size() != 0x80000 && get_rom_size() != 0x60000 ) + if (get_rom_size() != 0x80000 && get_rom_size() != 0x60000) { fatalerror("rtype: Invalid ROM size\n"); } - restore_banks(); -} - + m_rombank->configure_entries(0, 24, get_rom_base(), 0x4000); -uint8_t msx_cart_rtype_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000) - { - return m_bank_base[offset >> 15][offset & 0x3fff]; - } - return 0xff; + page(1)->install_rom(0x4000, 0x7fff, get_rom_base() + 15 * 0x4000); + page(1)->install_write_handler(0x7000, 0x7fff, write8smo_delegate(*this, FUNC(msx_cart_rtype_device::bank_w))); + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank); } - -void msx_cart_rtype_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_rtype_device::bank_w(u8 data) { - if (offset >= 0x7000 && offset < 0x8000) - { - m_selected_bank = data & 0x1f; - if (m_selected_bank & 0x10) - { - m_selected_bank &= 0x17; - } - m_bank_base[1] = get_rom_base() + m_selected_bank * 0x4000; - } + data &= 0x1f; + if (data & 0x10) + data &= 0x17; + m_rombank->set_entry(data); } diff --git a/src/devices/bus/msx_cart/rtype.h b/src/devices/bus/msx_cart/rtype.h index 31583455a0a..f6d7afd325a 100644 --- a/src/devices/bus/msx_cart/rtype.h +++ b/src/devices/bus/msx_cart/rtype.h @@ -14,24 +14,18 @@ DECLARE_DEVICE_TYPE(MSX_CART_RTYPE, msx_cart_rtype_device) class msx_cart_rtype_device : public device_t, public msx_cart_interface { public: - msx_cart_rtype_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_rtype_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); + virtual void device_start() override { } private: - uint8_t m_selected_bank; - uint8_t *m_bank_base[2]; + void bank_w(u8 data); + + memory_bank_creator m_rombank; }; diff --git a/src/devices/bus/msx_cart/super_swangi.cpp b/src/devices/bus/msx_cart/super_swangi.cpp index b3385f96e29..61025db82e2 100644 --- a/src/devices/bus/msx_cart/super_swangi.cpp +++ b/src/devices/bus/msx_cart/super_swangi.cpp @@ -10,37 +10,10 @@ DEFINE_DEVICE_TYPE(MSX_CART_SUPER_SWANGI, msx_cart_super_swangi_device, "msx_car msx_cart_super_swangi_device::msx_cart_super_swangi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, MSX_CART_SUPER_SWANGI, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_selected_bank(0) + , m_rombank(*this, "rombank") { - m_bank_base[0] = m_bank_base[1] = nullptr; } - -void msx_cart_super_swangi_device::device_start() -{ - save_item(NAME(m_selected_bank)); -} - - -void msx_cart_super_swangi_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_super_swangi_device::restore_banks() -{ - m_bank_base[0] = get_rom_base(); - m_bank_base[1] = get_rom_base() + (((m_selected_bank >> 1) * 0x4000) & 0xffff); -} - - -void msx_cart_super_swangi_device::device_reset() -{ - m_selected_bank = 0; -} - - void msx_cart_super_swangi_device::initialize_cartridge() { if (get_rom_size() < 0x10000) @@ -48,29 +21,14 @@ void msx_cart_super_swangi_device::initialize_cartridge() fatalerror("super_swangi: Invalid ROM size\n"); } - restore_banks(); -} + m_rombank->configure_entries(0, 4, get_rom_base(), 0x4000); - -uint8_t msx_cart_super_swangi_device::read_cart(offs_t offset) -{ - if (offset >= 0x4000 && offset < 0xc000) - { - return m_bank_base[offset >> 15][offset & 0x3fff]; - } - return 0xff; + page(1)->install_rom(0x4000, 0x7fff, get_rom_base()); + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank); + page(2)->install_write_handler(0x8000, 0x8000, write8smo_delegate(*this, FUNC(msx_cart_super_swangi_device::bank_w))); } - -void msx_cart_super_swangi_device::write_cart(offs_t offset, uint8_t data) +void msx_cart_super_swangi_device::bank_w(u8 data) { - if (offset == 0x8000) - { - m_selected_bank = data; - restore_banks(); - } - else - { - logerror("msx_cart_super_swangi_device: unhandled write %02x to %04x\n", data, offset); - } + m_rombank->set_entry((data >> 1) & 0x03); } diff --git a/src/devices/bus/msx_cart/super_swangi.h b/src/devices/bus/msx_cart/super_swangi.h index f0f5ee216bd..f0c3539c6ce 100644 --- a/src/devices/bus/msx_cart/super_swangi.h +++ b/src/devices/bus/msx_cart/super_swangi.h @@ -14,24 +14,18 @@ DECLARE_DEVICE_TYPE(MSX_CART_SUPER_SWANGI, msx_cart_super_swangi_device) class msx_cart_super_swangi_device : public device_t, public msx_cart_interface { public: - msx_cart_super_swangi_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_super_swangi_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - virtual void device_post_load() override; - - void restore_banks(); + virtual void device_start() override { } private: - uint8_t m_selected_bank; - uint8_t *m_bank_base[2]; + void bank_w(u8 data); + + memory_bank_creator m_rombank; }; diff --git a/src/devices/bus/msx_cart/superloderunner.cpp b/src/devices/bus/msx_cart/superloderunner.cpp index 168f9187f8d..70df5248f4e 100644 --- a/src/devices/bus/msx_cart/superloderunner.cpp +++ b/src/devices/bus/msx_cart/superloderunner.cpp @@ -6,36 +6,19 @@ DEFINE_DEVICE_TYPE(MSX_CART_SUPERLODERUNNER, msx_cart_superloderunner_device, "msx_cart_superloderunner", "MSX Cartridge - Super Lode Runner") -msx_cart_superloderunner_device::msx_cart_superloderunner_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_superloderunner_device::msx_cart_superloderunner_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, MSX_CART_SUPERLODERUNNER, tag, owner, clock) , msx_cart_interface(mconfig, *this) - , m_selected_bank(0) - , m_bank_base(nullptr) + , m_rombank(*this, "rombank") { } - void msx_cart_superloderunner_device::device_start() { - save_item(NAME(m_selected_bank)); - - // Install evil memory write handler - memory_space().install_write_handler(0x0000, 0x0000, write8smo_delegate(*this, FUNC(msx_cart_superloderunner_device::banking))); -} - - -void msx_cart_superloderunner_device::device_post_load() -{ - restore_banks(); -} - - -void msx_cart_superloderunner_device::restore_banks() -{ - m_bank_base = get_rom_base() + (m_selected_bank & 0x0f) * 0x4000; + // Install evil system wide memory write handler + memory_space().install_write_handler(0x0000, 0x0000, write8smo_delegate(*this, FUNC(msx_cart_superloderunner_device::bank_w))); } - void msx_cart_superloderunner_device::initialize_cartridge() { if (get_rom_size() != 0x20000) @@ -43,23 +26,12 @@ void msx_cart_superloderunner_device::initialize_cartridge() fatalerror("superloderunner: Invalid ROM size\n"); } - restore_banks(); -} + m_rombank->configure_entries(0, 8, get_rom_base(), 0x4000); - -uint8_t msx_cart_superloderunner_device::read_cart(offs_t offset) -{ - if (offset >= 0x8000 && offset < 0xc000) - { - return m_bank_base[offset & 0x3fff]; - } - - return 0xff; + page(2)->install_read_bank(0x8000, 0xbfff, m_rombank); } - -void msx_cart_superloderunner_device::banking(uint8_t data) +void msx_cart_superloderunner_device::bank_w(u8 data) { - m_selected_bank = data; - restore_banks(); + m_rombank->set_entry(data & 0x07); } diff --git a/src/devices/bus/msx_cart/superloderunner.h b/src/devices/bus/msx_cart/superloderunner.h index bd763ca2c08..91a41ab26ec 100644 --- a/src/devices/bus/msx_cart/superloderunner.h +++ b/src/devices/bus/msx_cart/superloderunner.h @@ -14,24 +14,18 @@ DECLARE_DEVICE_TYPE(MSX_CART_SUPERLODERUNNER, msx_cart_superloderunner_device) class msx_cart_superloderunner_device : public device_t, public msx_cart_interface { public: - msx_cart_superloderunner_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_superloderunner_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void initialize_cartridge() override; - virtual uint8_t read_cart(offs_t offset) override; - protected: // device-level overrides virtual void device_start() override; - virtual void device_post_load() override; - - void restore_banks(); private: - void banking(uint8_t data); + void bank_w(u8 data); - uint8_t m_selected_bank; - uint8_t *m_bank_base; + memory_bank_creator m_rombank; }; diff --git a/src/devices/bus/msx_cart/yamaha.cpp b/src/devices/bus/msx_cart/yamaha.cpp index b2cb15a37b0..80fc4281b89 100644 --- a/src/devices/bus/msx_cart/yamaha.cpp +++ b/src/devices/bus/msx_cart/yamaha.cpp @@ -17,7 +17,7 @@ DEFINE_DEVICE_TYPE(MSX_CART_SFG01, msx_cart_sfg01_device, "msx_cart_sfg01", "MSX DEFINE_DEVICE_TYPE(MSX_CART_SFG05, msx_cart_sfg05_device, "msx_cart_sfg05", "MSX Cartridge - SFG05") -msx_cart_sfg_device::msx_cart_sfg_device(const machine_config &mconfig, const device_type type, const char *tag, device_t *owner, uint32_t clock) +msx_cart_sfg_device::msx_cart_sfg_device(const machine_config &mconfig, const device_type type, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock) , msx_cart_interface(mconfig, *this) , m_region_sfg(*this, "sfg") @@ -30,19 +30,16 @@ msx_cart_sfg_device::msx_cart_sfg_device(const machine_config &mconfig, const de { } - -msx_cart_sfg01_device::msx_cart_sfg01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_sfg01_device::msx_cart_sfg01_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : msx_cart_sfg_device(mconfig, MSX_CART_SFG01, tag, owner, clock) { } - -msx_cart_sfg05_device::msx_cart_sfg05_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) +msx_cart_sfg05_device::msx_cart_sfg05_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : msx_cart_sfg_device(mconfig, MSX_CART_SFG05, tag, owner, clock) { } - void msx_cart_sfg_device::device_add_mconfig(machine_config &config) { // YM2151 (OPM) @@ -78,65 +75,76 @@ void msx_cart_sfg05_device::device_add_mconfig(machine_config &config) ym2164.add_route(1, "rspeaker", 0.80); } - -ROM_START( msx_sfg01 ) +ROM_START(msx_sfg01) ROM_REGION(0x4000, "sfg", 0) ROM_LOAD("sfg01.rom", 0x0, 0x4000, CRC(0995fb36) SHA1(434651305f92aa770a89e40b81125fb22d91603d)) // correct label is almost certainly "yamaha__ym2211-22702__48_18_89_b.ic104" though the datecode portion may vary between late 1983 and mid 1984 ROM_END - const tiny_rom_entry *msx_cart_sfg01_device::device_rom_region() const { - return ROM_NAME( msx_sfg01 ); + return ROM_NAME(msx_sfg01); } - -ROM_START( msx_sfg05 ) +ROM_START(msx_sfg05) ROM_REGION(0x8000, "sfg", 0) - ROM_SYSTEM_BIOS( 0, "sfg05", "SFG05 (original)" ) - ROMX_LOAD( "sfg05.rom", 0x0, 0x8000, CRC(2425c279) SHA1(d956167e234f60ad916120437120f86fc8c3c321), ROM_BIOS(0) ) // correct label MIGHT be "yamaha__ym2301-23959.ic104" but this needs redump/verification - ROM_SYSTEM_BIOS( 1, "sfg05a", "SFG05 (SFG01 upgrade)" ) // SFG01 PCB, Yamaha official upgrade, has YM2151 instead of YM2164 - ROMX_LOAD( "sfg05a.rom", 0x0, 0x8000, CRC(5bc237f8) SHA1(930338f45c08228108c0831cc4a26014c2674718), ROM_BIOS(1) ) // this came on a single eprom on a daughterboard on an SFG01 board which had been factory upgraded to SFG05 + // Version string starts at $02BD + ROM_SYSTEM_BIOS(0, "m5.01.011", "SFG05 (original) M5.01.011") + ROMX_LOAD( "sfg05.rom", 0x0, 0x8000, CRC(2425c279) SHA1(d956167e234f60ad916120437120f86fc8c3c321), ROM_BIOS(0)) // correct label MIGHT be "yamaha__ym2301-23959.ic104" but this needs redump/verification + ROM_SYSTEM_BIOS(1, "m5.00.013", "SFG05 (SFG01 upgrade) M5.00.013") // SFG01 PCB, Yamaha official upgrade, has YM2151 instead of YM2164 + ROMX_LOAD( "sfg05a.rom", 0x0, 0x8000, CRC(5bc237f8) SHA1(930338f45c08228108c0831cc4a26014c2674718), ROM_BIOS(1)) // this came on a single eprom on a daughterboard on an SFG01 board which had been factory upgraded to SFG05 + ROM_SYSTEM_BIOS(2, "m5.00.011", "SFG05 M5.00.011") // Found in Sakhr AX-200M + ROMX_LOAD("sfg05_m5_00_011.rom", 0x0, 0x8000, BAD_DUMP CRC(9d5e20c9) SHA1(fcc385b90c65575e29fc009aa00b5120fc4c251a), ROM_BIOS(2)) // Still seems to have I/O reads at $7ff0 - $7fff ROM_END - const tiny_rom_entry *msx_cart_sfg05_device::device_rom_region() const { - return ROM_NAME( msx_sfg05 ); + return ROM_NAME(msx_sfg05); } - void msx_cart_sfg_device::device_start() { // Set rom mask m_rom_mask = m_region_sfg->bytes() - 1; - // This should probably moved up in the bus/slot hierarchy for the msx driver - cpu_device *maincpu = machine().device<cpu_device>("maincpu"); - maincpu->set_irq_acknowledge_callback(*this, FUNC(msx_cart_sfg_device::irq_callback)); -} + maincpu().set_irq_acknowledge_callback(*this, FUNC(msx_cart_sfg_device::irq_callback)); + page(0)->install_rom(0x0000, 0x3fff, m_region_sfg->base()); + if (m_region_sfg->bytes() == 0x8000) + { + page(1)->install_rom(0x4000, 0x7fff, m_region_sfg->base() + 0x4000); + } + else + { + page(1)->install_rom(0x4000, 0x7fff, m_region_sfg->base()); + } + + for (int i = 0; i < 4; i++) + { + // These addresses deliberately overlap + page(i)->install_read_handler(0x4000 * i + 0x3ff0, 0x4000 * i + 0x3ff6, read8sm_delegate(*m_ym2148, FUNC(ym2148_device::read))); + page(i)->install_read_handler(0x4000 * i + 0x3ff0, 0x4000 * i + 0x3ff1, read8sm_delegate(*m_ym2151, FUNC(ym_generic_device::read))); + page(i)->install_write_handler(0x4000 * i + 0x3ff0, 0x4000 * i + 0x3ff6, write8sm_delegate(*m_ym2148, FUNC(ym2148_device::write))); + page(i)->install_write_handler(0x4000 * i + 0x3ff0, 0x4000 * i + 0x3ff1, write8sm_delegate(*m_ym2151, FUNC(ym_generic_device::write))); + } +} IRQ_CALLBACK_MEMBER(msx_cart_sfg_device::irq_callback) { return m_ym2148->get_irq_vector(); } - WRITE_LINE_MEMBER(msx_cart_sfg_device::ym2151_irq_w) { m_ym2151_irq_state = state ? ASSERT_LINE : CLEAR_LINE; check_irq(); } - WRITE_LINE_MEMBER(msx_cart_sfg_device::ym2148_irq_w) { m_ym2148_irq_state = state ? ASSERT_LINE : CLEAR_LINE; check_irq(); } - void msx_cart_sfg_device::check_irq() { if (m_ym2151_irq_state != CLEAR_LINE || m_ym2148_irq_state != CLEAR_LINE) @@ -148,61 +156,3 @@ void msx_cart_sfg_device::check_irq() irq_out(CLEAR_LINE); } } - - -uint8_t msx_cart_sfg_device::read_cart(offs_t offset) -{ - switch (offset & 0x3fff) - { - case 0x3ff0: // YM-2151 status read - case 0x3ff1: // YM-2151 status read mirror? - return m_ym2151->read(offset & 1); - - case 0x3ff2: // YM-2148 keyboard column read - case 0x3ff3: // YM-2148 -- - case 0x3ff4: // YM-2148 -- - case 0x3ff5: // YM-2148 MIDI UART data read register - case 0x3ff6: // YM-2148 MIDI UART status register - // ------x- - 1 = received a byte/receive buffer full? - // -------x - 1 = ready to send next byte/send buffer empty? - return m_ym2148->read(offset & 7); - } - - if (offset < 0x8000) - { - return m_region_sfg->as_u8(offset & m_rom_mask); - } - - return 0xff; -} - - -void msx_cart_sfg_device::write_cart(offs_t offset, uint8_t data) -{ - switch (offset & 0x3fff) - { - case 0x3ff0: // YM-2151 register - case 0x3ff1: // YM-2151 data - m_ym2151->write(offset & 1, data); - break; - - case 0x3ff2: // YM-2148 write keyboard row - case 0x3ff3: // YM-2148 MIDI IRQ vector - case 0x3ff4: // YM-2148 External IRQ vector - case 0x3ff5: // YM-2148 MIDI UART data write register - case 0x3ff6: // YM-2148 MIDI UART command register - // On startup the sfg01 writes 0x80 - // followed by 0x05. - // Other write seen in the code: 0x15 - // - // x------- - 1 = reset - // -----x-- - 1 = enable receiving / sending midi data - // -------x - 1 = enable receiving / sending midi data - m_ym2148->write(offset & 7, data); - break; - - default: - logerror("msx_cart_sfg_device::write_cart: write %02x to %04x\n", data, offset); - break; - } -} diff --git a/src/devices/bus/msx_cart/yamaha.h b/src/devices/bus/msx_cart/yamaha.h index cd4c036cab8..0b48f96b781 100644 --- a/src/devices/bus/msx_cart/yamaha.h +++ b/src/devices/bus/msx_cart/yamaha.h @@ -17,12 +17,8 @@ DECLARE_DEVICE_TYPE(MSX_CART_SFG05, msx_cart_sfg05_device) class msx_cart_sfg_device : public device_t, public msx_cart_interface { -public: - virtual uint8_t read_cart(offs_t offset) override; - virtual void write_cart(offs_t offset, uint8_t data) override; - protected: - msx_cart_sfg_device(const machine_config &mconfig, const device_type type, const char *tag, device_t *owner, uint32_t clock); + msx_cart_sfg_device(const machine_config &mconfig, const device_type type, const char *tag, device_t *owner, u32 clock); virtual void device_start() override; @@ -40,7 +36,7 @@ protected: required_device<ym2148_device> m_ym2148; int m_ym2151_irq_state; int m_ym2148_irq_state; - uint32_t m_rom_mask; + u32 m_rom_mask; void check_irq(); }; @@ -49,7 +45,7 @@ protected: class msx_cart_sfg01_device : public msx_cart_sfg_device { public: - msx_cart_sfg01_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_sfg01_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual const tiny_rom_entry *device_rom_region() const override; }; @@ -58,7 +54,7 @@ public: class msx_cart_sfg05_device : public msx_cart_sfg_device { public: - msx_cart_sfg05_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + msx_cart_sfg05_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual void device_add_mconfig(machine_config &config) override; virtual const tiny_rom_entry *device_rom_region() const override; 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; }; |