diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 1379c572fa8..d6bc6cfedda 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2587,3 +2587,39 @@ if (BUSES["NEWBRAIN"]~=null) then MAME_DIR .. "src/devices/bus/newbrain/fdc.h", } end + +--------------------------------------------------- +-- +--@src/devices/bus/svi3x8/expander/expander.h,BUSES["SVI_EXPANDER"] = true +--------------------------------------------------- + +if (BUSES["SVI_EXPANDER"]~=null) then + files { + MAME_DIR .. "src/devices/bus/svi3x8/expander/expander.cpp", + MAME_DIR .. "src/devices/bus/svi3x8/expander/expander.h", + MAME_DIR .. "src/devices/bus/svi3x8/expander/modules.cpp", + MAME_DIR .. "src/devices/bus/svi3x8/expander/modules.h", + MAME_DIR .. "src/devices/bus/svi3x8/expander/sv601.cpp", + MAME_DIR .. "src/devices/bus/svi3x8/expander/sv601.h", + } +end + +--------------------------------------------------- +-- +--@src/devices/bus/svi3x8/slot/slot.h,BUSES["SVI_SLOT"] = true +--------------------------------------------------- + +if (BUSES["SVI_SLOT"]~=null) then + files { + MAME_DIR .. "src/devices/bus/svi3x8/slot/slot.cpp", + MAME_DIR .. "src/devices/bus/svi3x8/slot/slot.h", + MAME_DIR .. "src/devices/bus/svi3x8/slot/cards.cpp", + MAME_DIR .. "src/devices/bus/svi3x8/slot/cards.h", + MAME_DIR .. "src/devices/bus/svi3x8/slot/sv801.cpp", + MAME_DIR .. "src/devices/bus/svi3x8/slot/sv801.h", + MAME_DIR .. "src/devices/bus/svi3x8/slot/sv803.cpp", + MAME_DIR .. "src/devices/bus/svi3x8/slot/sv803.h", + MAME_DIR .. "src/devices/bus/svi3x8/slot/sv807.cpp", + MAME_DIR .. "src/devices/bus/svi3x8/slot/sv807.h", + } +end diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index cef8524680f..5687a044a41 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -652,6 +652,8 @@ BUSES["SMS_EXP"] = true BUSES["SNES"] = true BUSES["SNES_CTRL"] = true BUSES["SPC1000"] = true +BUSES["SVI_EXPANDER"] = true +BUSES["SVI_SLOT"] = true BUSES["TI99PEB"] = true BUSES["TI99X"] = true BUSES["TIKI100"] = true diff --git a/src/devices/bus/svi3x8/expander/expander.cpp b/src/devices/bus/svi3x8/expander/expander.cpp new file mode 100644 index 00000000000..faddf3f24ac --- /dev/null +++ b/src/devices/bus/svi3x8/expander/expander.cpp @@ -0,0 +1,151 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SVI 318/328 Expansion Slot + + 50-pin slot + +***************************************************************************/ + +#include "expander.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type SVI_EXPANDER = &device_creator; + + +//************************************************************************** +// SLOT DEVICE +//************************************************************************** + +//------------------------------------------------- +// svi_expander_device - constructor +//------------------------------------------------- + +svi_expander_device::svi_expander_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SVI_EXPANDER, "SVI 318/328 Expander Bus", tag, owner, clock, "svi_expander", __FILE__), + device_slot_interface(mconfig, *this), + m_module(nullptr), + m_int_handler(*this), + m_romdis_handler(*this), + m_ramdis_handler(*this), + m_ctrl1_handler(*this), + m_ctrl2_handler(*this) +{ +} + +//------------------------------------------------- +// svi_expander_device - destructor +//------------------------------------------------- + +svi_expander_device::~svi_expander_device() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void svi_expander_device::device_start() +{ + // get inserted module + m_module = dynamic_cast(get_card_device()); + + // resolve callbacks + m_int_handler.resolve_safe(); + m_romdis_handler.resolve_safe(); + m_ramdis_handler.resolve_safe(); + m_ctrl1_handler.resolve_safe(); + m_ctrl2_handler.resolve_safe(); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void svi_expander_device::device_reset() +{ +} + +//------------------------------------------------- +// host to module interface +//------------------------------------------------- + +READ8_MEMBER( svi_expander_device::mreq_r ) +{ + if (m_module) + return m_module->mreq_r(space, offset); + + return 0xff; +} + +WRITE8_MEMBER( svi_expander_device::mreq_w ) +{ + if (m_module) + m_module->mreq_w(space, offset, data); +} + +READ8_MEMBER( svi_expander_device::iorq_r ) +{ + if (m_module) + return m_module->iorq_r(space, offset); + + return 0xff; +} + +WRITE8_MEMBER( svi_expander_device::iorq_w ) +{ + if (m_module) + m_module->iorq_w(space, offset, data); +} + +WRITE_LINE_MEMBER( svi_expander_device::bk21_w ) +{ + if (m_module) + m_module->bk21_w(state); +} + +WRITE_LINE_MEMBER( svi_expander_device::bk22_w ) +{ + if (m_module) + m_module->bk22_w(state); +} + +WRITE_LINE_MEMBER( svi_expander_device::bk31_w ) +{ + if (m_module) + m_module->bk31_w(state); +} + +WRITE_LINE_MEMBER( svi_expander_device::bk32_w ) +{ + if (m_module) + m_module->bk32_w(state); +} + + +//************************************************************************** +// CARTRIDGE INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_svi_expander_interface - constructor +//------------------------------------------------- + +device_svi_expander_interface::device_svi_expander_interface(const machine_config &mconfig, device_t &device) : + device_slot_card_interface(mconfig, device) +{ + m_expander = dynamic_cast(device.owner()); +} + +//------------------------------------------------- +// ~device_expansion_interface - destructor +//------------------------------------------------- + +device_svi_expander_interface::~device_svi_expander_interface() +{ +} diff --git a/src/devices/bus/svi3x8/expander/expander.h b/src/devices/bus/svi3x8/expander/expander.h new file mode 100644 index 00000000000..a2bed1f609b --- /dev/null +++ b/src/devices/bus/svi3x8/expander/expander.h @@ -0,0 +1,162 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SVI 318/328 Expander Slot + + 50-pin slot + + 1 +5V 2 /CNTRL2 + 3 +12V 4 -12V + 5 /CNTRL1 6 /WAIT + 7 /RST 8 CPUCLK + 9 A15 10 A14 + 11 A13 12 A12 + 13 A11 14 A10 + 15 A9 16 A8 + 17 A7 18 A6 + 19 A5 20 A4 + 21 A3 22 A2 + 23 A1 24 A0 + 25 /RFSH 26 /EXCSR + 27 /M1 28 /EXCSW + 29 /WR 30 /MREQ + 31 /IORQ 32 /RD + 33 D0 34 D1 + 35 D2 36 D3 + 37 D4 38 D5 + 39 D6 40 D7 + 41 CSOUND 42 /INT + 43 /RAMDIS 44 /ROMDIS + 45 /BK32 46 /BK31 + 47 /BK22 48 /BK21 + 49 GND 50 GND + +***************************************************************************/ + +#pragma once + +#ifndef __SVI3X8_EXPANDER_H__ +#define __SVI3X8_EXPANDER_H__ + +#include "emu.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_SVI_EXPANDER_BUS_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, SVI_EXPANDER, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(svi_expander_modules, NULL, false) \ + +#define MCFG_SVI_EXPANDER_INT_HANDLER(_devcb) \ + devcb = &svi_expander_device::set_int_handler(*device, DEVCB_##_devcb); + +#define MCFG_SVI_EXPANDER_ROMDIS_HANDLER(_devcb) \ + devcb = &svi_expander_device::set_romdis_handler(*device, DEVCB_##_devcb); + +#define MCFG_SVI_EXPANDER_RAMDIS_HANDLER(_devcb) \ + devcb = &svi_expander_device::set_ramdis_handler(*device, DEVCB_##_devcb); + +#define MCFG_SVI_EXPANDER_CTRL1_HANDLER(_devcb) \ + devcb = &svi_expander_device::set_ctrl1_handler(*device, DEVCB_##_devcb); + +#define MCFG_SVI_EXPANDER_CTRL2_HANDLER(_devcb) \ + devcb = &svi_expander_device::set_ctrl2_handler(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class device_svi_expander_interface; + +// ======================> svi_expander_device + +class svi_expander_device : public device_t, public device_slot_interface +{ +public: + // construction/destruction + svi_expander_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~svi_expander_device(); + + // callbacks + template static devcb_base &set_int_handler(device_t &device, _Object object) + { return downcast(device).m_int_handler.set_callback(object); } + + template static devcb_base &set_romdis_handler(device_t &device, _Object object) + { return downcast(device).m_romdis_handler.set_callback(object); } + + template static devcb_base &set_ramdis_handler(device_t &device, _Object object) + { return downcast(device).m_ramdis_handler.set_callback(object); } + + template static devcb_base &set_ctrl1_handler(device_t &device, _Object object) + { return downcast(device).m_ctrl1_handler.set_callback(object); } + + template static devcb_base &set_ctrl2_handler(device_t &device, _Object object) + { return downcast(device).m_ctrl2_handler.set_callback(object); } + + // called from cart device + DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int_handler(state); } + DECLARE_WRITE_LINE_MEMBER( romdis_w ) { m_romdis_handler(state); } + DECLARE_WRITE_LINE_MEMBER( ramdis_w ) { m_ramdis_handler(state); } + DECLARE_WRITE_LINE_MEMBER( ctrl1_w ) { m_ctrl1_handler(state); } + DECLARE_WRITE_LINE_MEMBER( ctrl2_w ) { m_ctrl2_handler(state); } + + // called from host + DECLARE_READ8_MEMBER( mreq_r ); + DECLARE_WRITE8_MEMBER( mreq_w ); + DECLARE_READ8_MEMBER( iorq_r ); + DECLARE_WRITE8_MEMBER( iorq_w ); + + DECLARE_WRITE_LINE_MEMBER( bk21_w ); + DECLARE_WRITE_LINE_MEMBER( bk22_w ); + DECLARE_WRITE_LINE_MEMBER( bk31_w ); + DECLARE_WRITE_LINE_MEMBER( bk32_w ); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + device_svi_expander_interface *m_module; + + devcb_write_line m_int_handler; + devcb_write_line m_romdis_handler; + devcb_write_line m_ramdis_handler; + devcb_write_line m_ctrl1_handler; + devcb_write_line m_ctrl2_handler; +}; + +// ======================> device_svi_expander_interface + +class device_svi_expander_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_svi_expander_interface(const machine_config &mconfig, device_t &device); + virtual ~device_svi_expander_interface(); + + virtual DECLARE_READ8_MEMBER( mreq_r ) { return 0xff; }; + virtual DECLARE_WRITE8_MEMBER( mreq_w ){}; + virtual DECLARE_READ8_MEMBER( iorq_r ) { return 0xff; }; + virtual DECLARE_WRITE8_MEMBER( iorq_w ){}; + + virtual void bk21_w(int state) {}; + virtual void bk22_w(int state) {}; + virtual void bk31_w(int state) {}; + virtual void bk32_w(int state) {}; + +protected: + svi_expander_device *m_expander; +}; + +// device type definition +extern const device_type SVI_EXPANDER; + +// include here so drivers don't need to +#include "modules.h" + +#endif // __SVI3X8_EXPANDER_H__ diff --git a/src/devices/bus/svi3x8/expander/modules.cpp b/src/devices/bus/svi3x8/expander/modules.cpp new file mode 100644 index 00000000000..f613dcf4094 --- /dev/null +++ b/src/devices/bus/svi3x8/expander/modules.cpp @@ -0,0 +1,13 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SVI 318/328 Expander Bus Modules + +***************************************************************************/ + +#include "modules.h" + +SLOT_INTERFACE_START( svi_expander_modules ) + SLOT_INTERFACE("sv601", SV601) +SLOT_INTERFACE_END diff --git a/src/devices/bus/svi3x8/expander/modules.h b/src/devices/bus/svi3x8/expander/modules.h new file mode 100644 index 00000000000..953b7094935 --- /dev/null +++ b/src/devices/bus/svi3x8/expander/modules.h @@ -0,0 +1,19 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SVI 318/328 Expander Bus Modules + +***************************************************************************/ + +#pragma once + +#ifndef __SVI_EXPANDER_MODULES_H__ +#define __SVI_EXPANDER_MODULES_H__ + +#include "emu.h" +#include "sv601.h" + +SLOT_INTERFACE_EXTERN( svi_expander_modules ); + +#endif // __SVI_EXPANDER_MODULES_H__ diff --git a/src/devices/bus/svi3x8/expander/sv601.cpp b/src/devices/bus/svi3x8/expander/sv601.cpp new file mode 100644 index 00000000000..fadb45f9a26 --- /dev/null +++ b/src/devices/bus/svi3x8/expander/sv601.cpp @@ -0,0 +1,98 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SV-601 Super Expander for SVI-318/328 + +***************************************************************************/ + +#include "sv601.h" + + +//************************************************************************** +// CONSTANTS/MACROS +//************************************************************************** + +#define VERBOSE 0 + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type SV601 = &device_creator; + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +static MACHINE_CONFIG_FRAGMENT( sv601 ) + MCFG_SVI_SLOT_BUS_ADD + MCFG_SVI_SLOT_INT_HANDLER(WRITELINE(sv601_device, int_w)) + MCFG_SVI_SLOT_ROMDIS_HANDLER(WRITELINE(sv601_device, romdis_w)) + MCFG_SVI_SLOT_RAMDIS_HANDLER(WRITELINE(sv601_device, ramdis_w)) + MCFG_SVI_SLOT_ADD("0", NULL) + MCFG_SVI_SLOT_ADD("1", NULL) + MCFG_SVI_SLOT_ADD("2", NULL) + MCFG_SVI_SLOT_ADD("3", NULL) + MCFG_SVI_SLOT_ADD("4", NULL) + MCFG_SVI_SLOT_ADD("5", NULL) + MCFG_SVI_SLOT_ADD("6", NULL) +MACHINE_CONFIG_END + +machine_config_constructor sv601_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( sv601 ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// sv601_device - constructor +//------------------------------------------------- + +sv601_device::sv601_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SV601, "SV-601 Super Expander", tag, owner, clock, "sv601", __FILE__), + device_svi_expander_interface(mconfig, *this), + m_slotbus(*this, "slotbus") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void sv601_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void sv601_device::device_reset() +{ +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +WRITE_LINE_MEMBER( sv601_device::int_w ) { m_expander->int_w(state); } +WRITE_LINE_MEMBER( sv601_device::romdis_w ) { m_expander->romdis_w(state); } +WRITE_LINE_MEMBER( sv601_device::ramdis_w ) { m_expander->ramdis_w(state); } + +READ8_MEMBER( sv601_device::mreq_r ) { return m_slotbus->mreq_r(space, offset); } +WRITE8_MEMBER( sv601_device::mreq_w ) { m_slotbus->mreq_w(space, offset, data); } +READ8_MEMBER( sv601_device::iorq_r ) { return m_slotbus->iorq_r(space, offset); } +WRITE8_MEMBER( sv601_device::iorq_w ) { m_slotbus->iorq_w(space, offset, data); } + +void sv601_device::bk21_w(int state) { m_slotbus->bk21_w(state); } +void sv601_device::bk22_w(int state) { m_slotbus->bk22_w(state); } +void sv601_device::bk31_w(int state) { m_slotbus->bk31_w(state); } +void sv601_device::bk32_w(int state) { m_slotbus->bk32_w(state); } diff --git a/src/devices/bus/svi3x8/expander/sv601.h b/src/devices/bus/svi3x8/expander/sv601.h new file mode 100644 index 00000000000..bf1133cfedb --- /dev/null +++ b/src/devices/bus/svi3x8/expander/sv601.h @@ -0,0 +1,59 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SV-601 Super Expander for SVI-318/328 + +***************************************************************************/ + +#pragma once + +#ifndef __SVI3X8_EXPANDER_SV601_H__ +#define __SVI3X8_EXPANDER_SV601_H__ + +#include "emu.h" +#include "expander.h" +#include "bus/svi3x8/slot/slot.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> sv601_device + +class sv601_device : public device_t, public device_svi_expander_interface +{ +public: + // construction/destruction + sv601_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // from slots + WRITE_LINE_MEMBER( int_w ); + WRITE_LINE_MEMBER( romdis_w ); + WRITE_LINE_MEMBER( ramdis_w ); + + // from host + virtual DECLARE_READ8_MEMBER( mreq_r ) override; + virtual DECLARE_WRITE8_MEMBER( mreq_w ) override; + virtual DECLARE_READ8_MEMBER( iorq_r ) override; + virtual DECLARE_WRITE8_MEMBER( iorq_w ) override; + + virtual void bk21_w(int state) override; + virtual void bk22_w(int state) override; + virtual void bk31_w(int state) override; + virtual void bk32_w(int state) override; + +protected: + virtual machine_config_constructor device_mconfig_additions() const override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + required_device m_slotbus; +}; + +// device type definition +extern const device_type SV601; + +#endif // __SVI3X8_EXPANDER_SV601_H__ diff --git a/src/devices/bus/svi3x8/slot/cards.cpp b/src/devices/bus/svi3x8/slot/cards.cpp new file mode 100644 index 00000000000..e86317dedb4 --- /dev/null +++ b/src/devices/bus/svi3x8/slot/cards.cpp @@ -0,0 +1,15 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SVI 318/328 Slot Cards + +***************************************************************************/ + +#include "cards.h" + +SLOT_INTERFACE_START( svi_slot_cards ) + SLOT_INTERFACE("sv801", SV801) + SLOT_INTERFACE("sv803", SV803) + SLOT_INTERFACE("sv807", SV807) +SLOT_INTERFACE_END diff --git a/src/devices/bus/svi3x8/slot/cards.h b/src/devices/bus/svi3x8/slot/cards.h new file mode 100644 index 00000000000..22d601a22fa --- /dev/null +++ b/src/devices/bus/svi3x8/slot/cards.h @@ -0,0 +1,21 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SVI 318/328 Slot Cards + +***************************************************************************/ + +#pragma once + +#ifndef __SVI3X8_SLOT_CARDS_H__ +#define __SVI3X8_SLOT_CARDS_H__ + +#include "emu.h" +#include "sv801.h" +#include "sv803.h" +#include "sv807.h" + +SLOT_INTERFACE_EXTERN( svi_slot_cards ); + +#endif // __SVI3X8_SLOT_CARDS_H__ diff --git a/src/devices/bus/svi3x8/slot/slot.cpp b/src/devices/bus/svi3x8/slot/slot.cpp new file mode 100644 index 00000000000..5ab951e18f1 --- /dev/null +++ b/src/devices/bus/svi3x8/slot/slot.cpp @@ -0,0 +1,284 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SVI 318/328 Expansion Slot + +***************************************************************************/ + +#include "slot.h" + + +//************************************************************************** +// SLOT BUS DEVICE +//************************************************************************** + +const device_type SVI_SLOT_BUS = &device_creator; + +//------------------------------------------------- +// svi_slot_bus_device - constructor +//------------------------------------------------- + +svi_slot_bus_device::svi_slot_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SVI_SLOT_BUS, "SVI Slot Bus", tag, owner, clock, "svislotbus", __FILE__), + m_int_handler(*this), + m_romdis_handler(*this), + m_ramdis_handler(*this) +{ +} + +//------------------------------------------------- +// svi_slot_bus_device - destructor +//------------------------------------------------- + +svi_slot_bus_device::~svi_slot_bus_device() +{ + m_dev.detach_all(); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void svi_slot_bus_device::device_start() +{ + // resolve callbacks + m_int_handler.resolve_safe(); + m_romdis_handler.resolve_safe(); + m_ramdis_handler.resolve_safe(); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void svi_slot_bus_device::device_reset() +{ +} + +//------------------------------------------------- +// add_card - add new card to our bus +//------------------------------------------------- + +void svi_slot_bus_device::add_card(device_svi_slot_interface *card) +{ + card->set_bus_device(this); + m_dev.append(*card); +} + +//------------------------------------------------- +// mreq_r - memory read from slot +//------------------------------------------------- + +READ8_MEMBER( svi_slot_bus_device::mreq_r ) +{ + device_svi_slot_interface *entry = m_dev.first(); + UINT8 data = 0xff; + + romdis_w(1); + ramdis_w(1); + + while (entry) + { + data &= entry->mreq_r(space, offset); + entry = entry->next(); + } + + return data; +} + +//------------------------------------------------- +// mreq_w - memory write to slot +//------------------------------------------------- + +WRITE8_MEMBER( svi_slot_bus_device::mreq_w ) +{ + device_svi_slot_interface *entry = m_dev.first(); + + romdis_w(1); + ramdis_w(1); + + while (entry) + { + entry->mreq_w(space, offset, data); + entry = entry->next(); + } +} + +//------------------------------------------------- +// iorq_r - memory read from slot +//------------------------------------------------- + +READ8_MEMBER( svi_slot_bus_device::iorq_r ) +{ + device_svi_slot_interface *entry = m_dev.first(); + UINT8 data = 0xff; + + while (entry) + { + data &= entry->iorq_r(space, offset); + entry = entry->next(); + } + + return data; +} + +//------------------------------------------------- +// iorq_w - memory write to slot +//------------------------------------------------- + +WRITE8_MEMBER( svi_slot_bus_device::iorq_w ) +{ + device_svi_slot_interface *entry = m_dev.first(); + + while (entry) + { + entry->iorq_w(space, offset, data); + entry = entry->next(); + } +} + +//------------------------------------------------- +// bk21_w - signal from host to slots +//------------------------------------------------- + +WRITE_LINE_MEMBER( svi_slot_bus_device::bk21_w ) +{ + device_svi_slot_interface *entry = m_dev.first(); + + while (entry) + { + entry->bk21_w(state); + entry = entry->next(); + } +} + +//------------------------------------------------- +// bk22_w - signal from host to slots +//------------------------------------------------- + +WRITE_LINE_MEMBER( svi_slot_bus_device::bk22_w ) +{ + device_svi_slot_interface *entry = m_dev.first(); + + while (entry) + { + entry->bk22_w(state); + entry = entry->next(); + } +} + +//------------------------------------------------- +// bk31_w - signal from host to slots +//------------------------------------------------- + +WRITE_LINE_MEMBER( svi_slot_bus_device::bk31_w ) +{ + device_svi_slot_interface *entry = m_dev.first(); + + while (entry) + { + entry->bk31_w(state); + entry = entry->next(); + } +} + +//------------------------------------------------- +// bk32_w - signal from host to slots +//------------------------------------------------- + +WRITE_LINE_MEMBER( svi_slot_bus_device::bk32_w ) +{ + device_svi_slot_interface *entry = m_dev.first(); + + while (entry) + { + entry->bk32_w(state); + entry = entry->next(); + } +} + + +//************************************************************************** +// SVI SLOT DEVICE +//************************************************************************** + +const device_type SVI_SLOT = &device_creator; + +//------------------------------------------------- +// svi_slot_device - constructor +//------------------------------------------------- + +svi_slot_device::svi_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SVI_SLOT, "SVI Slot", tag, owner, clock, "svislot", __FILE__), + device_slot_interface(mconfig, *this), + m_bus_tag(nullptr) +{ +} + +//------------------------------------------------- +// set_bus - set owner bus tag +//------------------------------------------------- + +void svi_slot_device::set_bus(device_t &device, device_t *owner, const char *bus_tag) +{ + svi_slot_device &card = dynamic_cast(device); + card.m_owner = owner; + card.m_bus_tag = bus_tag; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void svi_slot_device::device_start() +{ + device_svi_slot_interface *dev = dynamic_cast(get_card_device()); + + if (dev) + { + svi_slot_bus_device *bus = downcast(m_owner->subdevice(m_bus_tag)); + bus->add_card(dev); + } +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void svi_slot_device::device_reset() +{ +} + + +//************************************************************************** +// CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_svi_slot_interface - constructor +//------------------------------------------------- + +device_svi_slot_interface::device_svi_slot_interface(const machine_config &mconfig, device_t &device) : + device_slot_card_interface(mconfig, device), + m_next(nullptr), + m_bus(nullptr) +{ +} + +//------------------------------------------------- +// ~device_svi_slot_interface - destructor +//------------------------------------------------- + +device_svi_slot_interface::~device_svi_slot_interface() +{ +} + +//------------------------------------------------- +// set_bus_device - set bus we are attached to +//------------------------------------------------- + +void device_svi_slot_interface::set_bus_device(svi_slot_bus_device *bus) +{ + m_bus = bus; +} diff --git a/src/devices/bus/svi3x8/slot/slot.h b/src/devices/bus/svi3x8/slot/slot.h new file mode 100644 index 00000000000..6cea923f6f6 --- /dev/null +++ b/src/devices/bus/svi3x8/slot/slot.h @@ -0,0 +1,178 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SVI 318/328 Expansion Slot + + 50-pin slot + + 1 +5V 2 +5V + 3 +12V 4 -12V + 5 GND 6 /WAIT + 7 /RST 8 CPUCLK + 9 A15 10 A14 + 11 A13 12 A12 + 13 A11 14 A10 + 15 A9 16 A8 + 17 A7 18 A6 + 19 A5 20 A4 + 21 A3 22 A2 + 23 A1 24 A0 + 25 /RFSH 26 GND + 27 /M1 28 GND + 29 /WR 30 /MREQ + 31 /IORQ 32 /RD + 33 D0 34 D1 + 35 D2 36 D3 + 37 D4 38 D5 + 39 D6 40 D7 + 41 CSOUND 42 /INT + 43 /RAMDIS 44 /ROMDIS + 45 /BK32 46 /BK31 + 47 /BK22 48 /BK21 + 49 GND 50 GND + +***************************************************************************/ + +#pragma once + +#ifndef __SVI3X8_SLOT_H__ +#define __SVI3X8_SLOT_H__ + +#include "emu.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_SVI_SLOT_BUS_ADD \ + MCFG_DEVICE_ADD("slotbus", SVI_SLOT_BUS, 0) + +#define MCFG_SVI_SLOT_ADD(_tag, _def_slot) \ + MCFG_DEVICE_ADD(_tag, SVI_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(svi_slot_cards, _def_slot, false) \ + svi_slot_device::set_bus(*device, owner, "slotbus"); + +#define MCFG_SVI_SLOT_INT_HANDLER(_devcb) \ + devcb = &svi_slot_bus_device::set_int_handler(*device, DEVCB_##_devcb); + +#define MCFG_SVI_SLOT_ROMDIS_HANDLER(_devcb) \ + devcb = &svi_slot_bus_device::set_romdis_handler(*device, DEVCB_##_devcb); + +#define MCFG_SVI_SLOT_RAMDIS_HANDLER(_devcb) \ + devcb = &svi_slot_bus_device::set_ramdis_handler(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class device_svi_slot_interface; + +// ======================> svi_slot_bus_device + +class svi_slot_bus_device : public device_t +{ +public: + // construction/destruction + svi_slot_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~svi_slot_bus_device(); + + // callbacks + template static devcb_base &set_int_handler(device_t &device, _Object object) + { return downcast(device).m_int_handler.set_callback(object); } + + template static devcb_base &set_romdis_handler(device_t &device, _Object object) + { return downcast(device).m_romdis_handler.set_callback(object); } + + template static devcb_base &set_ramdis_handler(device_t &device, _Object object) + { return downcast(device).m_ramdis_handler.set_callback(object); } + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + void add_card(device_svi_slot_interface *card); + + // from slot + DECLARE_WRITE_LINE_MEMBER( romdis_w ) { m_romdis_handler(state); }; + DECLARE_WRITE_LINE_MEMBER( ramdis_w ) { m_ramdis_handler(state); }; + + // from host + DECLARE_READ8_MEMBER( mreq_r ); + DECLARE_WRITE8_MEMBER( mreq_w ); + DECLARE_READ8_MEMBER( iorq_r ); + DECLARE_WRITE8_MEMBER( iorq_w ); + + DECLARE_WRITE_LINE_MEMBER( bk21_w ); + DECLARE_WRITE_LINE_MEMBER( bk22_w ); + DECLARE_WRITE_LINE_MEMBER( bk31_w ); + DECLARE_WRITE_LINE_MEMBER( bk32_w ); + +private: + simple_list m_dev; + + devcb_write_line m_int_handler; + devcb_write_line m_romdis_handler; + devcb_write_line m_ramdis_handler; +}; + +// device type definition +extern const device_type SVI_SLOT_BUS; + +// ======================> svi_slot_device + +class svi_slot_device : public device_t, public device_slot_interface +{ +public: + // construction/destruction + svi_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // inline configuration + static void set_bus(device_t &device, device_t *owner, const char *bus_tag); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // configuration + const char *m_bus_tag; +}; + +// device type definition +extern const device_type SVI_SLOT; + +// ======================> svi_slot_device + +class device_svi_slot_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_svi_slot_interface(const machine_config &mconfig, device_t &device); + virtual ~device_svi_slot_interface(); + + void set_bus_device(svi_slot_bus_device *bus); + + device_svi_slot_interface *next() const { return m_next; } + device_svi_slot_interface *m_next; + + virtual DECLARE_READ8_MEMBER( mreq_r ) { return 0xff; }; + virtual DECLARE_WRITE8_MEMBER( mreq_w ) {}; + virtual DECLARE_READ8_MEMBER( iorq_r ) { return 0xff; }; + virtual DECLARE_WRITE8_MEMBER( iorq_w ) {}; + + virtual DECLARE_WRITE_LINE_MEMBER( bk21_w ) {}; + virtual DECLARE_WRITE_LINE_MEMBER( bk22_w ) {}; + virtual DECLARE_WRITE_LINE_MEMBER( bk31_w ) {}; + virtual DECLARE_WRITE_LINE_MEMBER( bk32_w ) {}; + +protected: + svi_slot_bus_device *m_bus; +}; + +// include here so drivers don't need to +#include "cards.h" + +#endif // __SVI3X8_SLOT_H__ diff --git a/src/devices/bus/svi3x8/slot/sv801.cpp b/src/devices/bus/svi3x8/slot/sv801.cpp new file mode 100644 index 00000000000..544c68e2988 --- /dev/null +++ b/src/devices/bus/svi3x8/slot/sv801.cpp @@ -0,0 +1,144 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SV-801 Disk Controller + +***************************************************************************/ + +#include "sv801.h" +#include "softlist.h" +#include "formats/svi_dsk.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type SV801 = &device_creator; + +//------------------------------------------------- +// machine_config_additions - device-specific +// machine configurations +//------------------------------------------------- + +FLOPPY_FORMATS_MEMBER( sv801_device::floppy_formats ) + FLOPPY_SVI_FORMAT +FLOPPY_FORMATS_END + +static SLOT_INTERFACE_START( svi_floppies ) + SLOT_INTERFACE("dd", FLOPPY_525_DD) +SLOT_INTERFACE_END + +static MACHINE_CONFIG_FRAGMENT( sv801 ) + MCFG_FD1793_ADD("fdc", XTAL_1MHz) + MCFG_WD_FDC_INTRQ_CALLBACK(WRITELINE(sv801_device, intrq_w)) + MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(sv801_device, drq_w)) + + MCFG_FLOPPY_DRIVE_ADD("fdc:0", svi_floppies, "dd", sv801_device::floppy_formats) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", svi_floppies, "dd", sv801_device::floppy_formats) + + MCFG_SOFTWARE_LIST_ADD("disk_list", "svi318_flop") +MACHINE_CONFIG_END + +machine_config_constructor sv801_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( sv801 ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// sv801_device - constructor +//------------------------------------------------- + +sv801_device::sv801_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SV801, "SV-801 Disk Controller", tag, owner, clock, "sv801", __FILE__), + device_svi_slot_interface(mconfig, *this), + m_fdc(*this, "fdc"), + m_floppy0(*this, "fdc:0"), + m_floppy1(*this, "fdc:1"), + m_floppy(nullptr), + m_irq(0), m_drq(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void sv801_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void sv801_device::device_reset() +{ +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +WRITE_LINE_MEMBER( sv801_device::intrq_w ) +{ + m_irq = state; +} + +WRITE_LINE_MEMBER( sv801_device::drq_w ) +{ + m_drq = state; +} + +WRITE8_MEMBER( sv801_device::motor_w ) +{ + m_floppy = nullptr; + + if (BIT(data, 0)) m_floppy = m_floppy0->get_device(); + if (BIT(data, 1)) m_floppy = m_floppy1->get_device(); + + m_fdc->set_floppy(m_floppy); + + if (m_floppy0->get_device()) + m_floppy0->get_device()->mon_w(!BIT(data, 2)); + if (m_floppy1->get_device()) + m_floppy1->get_device()->mon_w(!BIT(data, 3)); +} + +READ8_MEMBER( sv801_device::iorq_r ) +{ + switch (offset) + { + case 0x30: return m_fdc->status_r(space, 0); + case 0x31: return m_fdc->track_r(space, 0); + case 0x32: return m_fdc->sector_r(space, 0); + case 0x33: return m_fdc->data_r(space, 0); + case 0x34: return (m_drq << 6) | (m_irq << 7); + } + + return 0xff; +} + +WRITE8_MEMBER( sv801_device::iorq_w ) +{ + switch (offset) + { + case 0x30: m_fdc->cmd_w(space, 0, data); break; + case 0x31: m_fdc->track_w(space, 0, data); break; + case 0x32: m_fdc->sector_w(space, 0, data); break; + case 0x33: m_fdc->data_w(space, 0, data); break; + case 0x34: motor_w(space, 0, data); break; + case 0x38: + m_fdc->dden_w(BIT(data, 0)); + if (m_floppy) + m_floppy->ss_w(BIT(data, 1)); + break; + } +} diff --git a/src/devices/bus/svi3x8/slot/sv801.h b/src/devices/bus/svi3x8/slot/sv801.h new file mode 100644 index 00000000000..2f670f05ad1 --- /dev/null +++ b/src/devices/bus/svi3x8/slot/sv801.h @@ -0,0 +1,61 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SV-801 Disk Controller + +***************************************************************************/ + +#pragma once + +#ifndef __SVI3X8_SLOT_SV801_H__ +#define __SVI3X8_SLOT_SV801_H__ + +#include "emu.h" +#include "slot.h" +#include "machine/wd_fdc.h" +#include "imagedev/floppy.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> sv801_device + +class sv801_device : public device_t, public device_svi_slot_interface +{ +public: + // construction/destruction + sv801_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + DECLARE_FLOPPY_FORMATS(floppy_formats); + + virtual DECLARE_READ8_MEMBER( iorq_r ) override; + virtual DECLARE_WRITE8_MEMBER( iorq_w ) override; + + DECLARE_WRITE_LINE_MEMBER( intrq_w ); + DECLARE_WRITE_LINE_MEMBER( drq_w ); + +protected: + virtual machine_config_constructor device_mconfig_additions() const override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + DECLARE_WRITE8_MEMBER( motor_w ); + + required_device m_fdc; + required_device m_floppy0; + required_device m_floppy1; + + floppy_image_device *m_floppy; + + int m_irq; + int m_drq; +}; + +// device type definition +extern const device_type SV801; + +#endif // __SVI3X8_SLOT_SV801_H__ diff --git a/src/devices/bus/svi3x8/slot/sv803.cpp b/src/devices/bus/svi3x8/slot/sv803.cpp new file mode 100644 index 00000000000..7035efeaa7a --- /dev/null +++ b/src/devices/bus/svi3x8/slot/sv803.cpp @@ -0,0 +1,68 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SV-803 16k memory expansion for SVI-318 + +***************************************************************************/ + +#include "sv803.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type SV803 = &device_creator; + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// sv803_device - constructor +//------------------------------------------------- + +sv803_device::sv803_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SV803, "SV-803 16k RAM Cartridge", tag, owner, clock, "sv803", __FILE__), + device_svi_slot_interface(mconfig, *this) +{ + m_ram = std::make_unique(0x4000); + memset(m_ram.get(), 0xff, 0x4000); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void sv803_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void sv803_device::device_reset() +{ +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +READ8_MEMBER( sv803_device::mreq_r ) +{ + if (offset >= 0x8000 && offset <= 0xbfff) + return m_ram[offset - 0x8000]; + + return 0xff; +} + +WRITE8_MEMBER( sv803_device::mreq_w ) +{ + if (offset >= 0x8000 && offset <= 0xbfff) + m_ram[offset - 0x8000] = data; +} diff --git a/src/devices/bus/svi3x8/slot/sv803.h b/src/devices/bus/svi3x8/slot/sv803.h new file mode 100644 index 00000000000..9dea0ea9180 --- /dev/null +++ b/src/devices/bus/svi3x8/slot/sv803.h @@ -0,0 +1,44 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SV-803 16k memory expansion for SVI-318 + +***************************************************************************/ + +#pragma once + +#ifndef __SVI3X8_SLOT_SV803_H__ +#define __SVI3X8_SLOT_SV803_H__ + +#include "emu.h" +#include "slot.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> sv803_device + +class sv803_device : public device_t, public device_svi_slot_interface +{ +public: + // construction/destruction + sv803_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual DECLARE_READ8_MEMBER( mreq_r ) override; + virtual DECLARE_WRITE8_MEMBER( mreq_w ) override; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + std::unique_ptr m_ram; +}; + +// device type definition +extern const device_type SV803; + +#endif // __SVI3X8_SLOT_SV803_H__ diff --git a/src/devices/bus/svi3x8/slot/sv807.cpp b/src/devices/bus/svi3x8/slot/sv807.cpp new file mode 100644 index 00000000000..14cf5001674 --- /dev/null +++ b/src/devices/bus/svi3x8/slot/sv807.cpp @@ -0,0 +1,163 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SV-807 64k memory expansion for SVI-318/328 + + TODO: + - Switch S6 (but needs to be off for the SVI anyway) + +***************************************************************************/ + +#include "sv807.h" + + +//************************************************************************** +// CONSTANTS / MACROS +//************************************************************************** + +#define BK21_ACTIVE ((m_bk21 == 0) && (m_switch->read() & 0x01)) +#define BK22_ACTIVE ((m_bk22 == 0) && (m_switch->read() & 0x02)) +#define BK31_ACTIVE ((m_bk31 == 0) && (m_switch->read() & 0x04)) +#define BK32_ACTIVE ((m_bk32 == 0) && (m_switch->read() & 0x08)) +#define BK02_ACTIVE (m_switch->read() & 0x10) + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type SV807 = &device_creator; + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +static INPUT_PORTS_START( sv807_switches ) + PORT_START("S") + PORT_DIPNAME(0x01, 0x00, "Bank/Page 21") + PORT_DIPLOCATION("S:1") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x01, "On") + PORT_DIPNAME(0x02, 0x02, "Bank/Page 22") + PORT_DIPLOCATION("S:2") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x02, "On") + PORT_DIPNAME(0x04, 0x04, "Bank/Page 31") + PORT_DIPLOCATION("S:3") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x04, "On") + PORT_DIPNAME(0x08, 0x00, "Bank/Page 32") + PORT_DIPLOCATION("S:4") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x08, "On") + PORT_DIPNAME(0x10, 0x00, "Bank/Page 02") + PORT_DIPLOCATION("S:5") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x10, "On") + PORT_DIPNAME(0x20, 0x00, "48k/32k") + PORT_DIPLOCATION("S:6") + PORT_DIPSETTING(0x00, "Off") + PORT_DIPSETTING(0x20, "On") +INPUT_PORTS_END + +ioport_constructor sv807_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( sv807_switches ); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// sv807_device - constructor +//------------------------------------------------- + +sv807_device::sv807_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SV803, "SV-807 64k RAM Cartridge", tag, owner, clock, "sv807", __FILE__), + device_svi_slot_interface(mconfig, *this), + m_switch(*this, "S"), + m_bk21(1), m_bk22(1), m_bk31(1), m_bk32(1) +{ + m_ram_bank1 = std::make_unique(0x8000); + m_ram_bank2 = std::make_unique(0x8000); + memset(m_ram_bank1.get(), 0xff, 0x8000); + memset(m_ram_bank2.get(), 0xff, 0x8000); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void sv807_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void sv807_device::device_reset() +{ +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +// test setup: S2 = enabled (22), S3 = enabled (31) + +READ8_MEMBER( sv807_device::mreq_r ) +{ + if ((BK21_ACTIVE || BK31_ACTIVE) && offset < 0x8000) + { + m_bus->romdis_w(0); + return m_ram_bank1[offset]; + } + + if ((BK22_ACTIVE || BK32_ACTIVE || BK02_ACTIVE) && offset >= 0x8000) + { + m_bus->ramdis_w(0); + return m_ram_bank2[offset - 0x8000]; + } + + return 0xff; +} + +WRITE8_MEMBER( sv807_device::mreq_w ) +{ + if ((BK21_ACTIVE || BK31_ACTIVE) && offset < 0x8000) + { + m_bus->romdis_w(0); + m_ram_bank1[offset] = data; + } + + if ((BK22_ACTIVE || BK32_ACTIVE || BK02_ACTIVE) && offset >= 0x8000) + { + m_bus->ramdis_w(0); + m_ram_bank2[offset - 0x8000] = data; + } +} + +void sv807_device::bk21_w(int state) +{ + m_bk21 = state; +} + +void sv807_device::bk22_w(int state) +{ + m_bk22 = state; +} + +void sv807_device::bk31_w(int state) +{ + m_bk31 = state; +} + +void sv807_device::bk32_w(int state) +{ + m_bk32 = state; +} diff --git a/src/devices/bus/svi3x8/slot/sv807.h b/src/devices/bus/svi3x8/slot/sv807.h new file mode 100644 index 00000000000..deebb9bf79e --- /dev/null +++ b/src/devices/bus/svi3x8/slot/sv807.h @@ -0,0 +1,60 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + SV-807 64k memory expansion for SVI-318/328 + +***************************************************************************/ + +#pragma once + +#ifndef __SVI3X8_SLOT_SV807_H__ +#define __SVI3X8_SLOT_SV807_H__ + +#include "emu.h" +#include "slot.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> sv807_device + +class sv807_device : public device_t, public device_svi_slot_interface +{ +public: + // construction/destruction + sv807_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + + virtual DECLARE_READ8_MEMBER( mreq_r ) override; + virtual DECLARE_WRITE8_MEMBER( mreq_w ) override; + + virtual void bk21_w(int state) override; + virtual void bk22_w(int state) override; + virtual void bk31_w(int state) override; + virtual void bk32_w(int state) override; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + +private: + required_ioport m_switch; + + std::unique_ptr m_ram_bank1; + std::unique_ptr m_ram_bank2; + + int m_bk21; + int m_bk22; + int m_bk31; + int m_bk32; +}; + +// device type definition +extern const device_type SV807; + +#endif // __SVI3X8_SLOT_SV807_H__ diff --git a/src/mame/drivers/svi318.cpp b/src/mame/drivers/svi318.cpp index 2529508e2b3..b2a6a2975f3 100644 --- a/src/mame/drivers/svi318.cpp +++ b/src/mame/drivers/svi318.cpp @@ -22,9 +22,17 @@ #include "formats/svi_cas.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" +#include "bus/svi3x8/expander/expander.h" #include "softlist.h" +//************************************************************************** +// CONSTANTS & MACROS +//************************************************************************** + +#define IS_SVI328 (m_ram->size() == 64 * 1024) + + //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -39,18 +47,32 @@ public: m_basic(*this, "basic"), m_speaker(*this, "speaker"), m_cassette(*this, "cassette"), - m_cart(*this, "cartslot"), + m_cart_rom(*this, "cartslot"), + m_expander(*this, "exp"), m_keyboard(*this, "KEY"), m_buttons(*this, "BUTTONS"), + m_intvdp(0), m_intexp(0), + m_romdis(1), m_ramdis(1), + m_cart(1), m_bk21(1), m_keyboard_row(0) {} DECLARE_READ8_MEMBER( ppi_port_a_r ); DECLARE_READ8_MEMBER( ppi_port_b_r ); DECLARE_WRITE8_MEMBER( ppi_port_c_w ); - DECLARE_WRITE8_MEMBER( psg_port_b_w ); + DECLARE_WRITE8_MEMBER( bank_w ); DECLARE_WRITE_LINE_MEMBER( intvdp_w ); + READ8_MEMBER( page1_r ); + WRITE8_MEMBER( page1_w ); + READ8_MEMBER( page2_r ); + WRITE8_MEMBER( page2_w ); + + // from expander bus + DECLARE_WRITE_LINE_MEMBER( intexp_w ); + DECLARE_WRITE_LINE_MEMBER( romdis_w ); + DECLARE_WRITE_LINE_MEMBER( ramdis_w ); + DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cartridge); protected: @@ -58,17 +80,23 @@ protected: virtual void machine_reset() override; private: - void reset_memory_configuration(); - required_device m_maincpu; required_device m_ram; required_memory_region m_basic; required_device m_speaker; required_device m_cassette; - required_device m_cart; + required_device m_cart_rom; + required_device m_expander; required_ioport_array<16> m_keyboard; required_ioport m_buttons; + int m_intvdp; + int m_intexp; + int m_romdis; + int m_ramdis; + int m_cart; + int m_bk21; + UINT8 m_keyboard_row; }; @@ -79,10 +107,13 @@ private: static ADDRESS_MAP_START( svi3x8_mem, AS_PROGRAM, 8, svi3x8_state ) ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x0000, 0x7fff) AM_READWRITE(page1_r, page1_w) + AM_RANGE(0x8000, 0xffff) AM_READWRITE(page2_r, page2_w) ADDRESS_MAP_END static ADDRESS_MAP_START( svi3x8_io, AS_IO, 8, svi3x8_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) + AM_RANGE(0x00, 0x7f) AM_DEVREADWRITE("exp", svi_expander_device, iorq_r, iorq_w) AM_RANGE(0x80, 0x80) AM_MIRROR(0x22) AM_DEVWRITE("vdp", tms9928a_device, vram_write) AM_RANGE(0x81, 0x81) AM_MIRROR(0x22) AM_DEVWRITE("vdp", tms9928a_device, register_write) AM_RANGE(0x84, 0x84) AM_MIRROR(0x22) AM_DEVREAD("vdp", tms9928a_device, vram_read) @@ -261,7 +292,8 @@ WRITE_LINE_MEMBER( svi3x8_state::intvdp_w ) { // note: schematics show a CNTRL line that allows switching between // IRQ and NMI for the interrupt - m_maincpu->set_input_line(INPUT_LINE_IRQ0, state); + m_intvdp = state; + m_maincpu->set_input_line(INPUT_LINE_IRQ0, (m_intvdp || m_intexp) ? ASSERT_LINE : CLEAR_LINE); } @@ -269,69 +301,90 @@ WRITE_LINE_MEMBER( svi3x8_state::intvdp_w ) // MACHINE EMULATION //************************************************************************** -void svi3x8_state::reset_memory_configuration() -{ - m_maincpu->space(AS_PROGRAM).install_rom(0x0000, 0x7fff, m_basic->base()); - - if (m_ram->size() == 64 * 1024) - { - // SVI-328 - m_maincpu->space(AS_PROGRAM).install_ram(0x8000, 0xffff, m_ram->pointer()); - } - else - { - // SVI-318 - m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x8000, 0xbfff); - m_maincpu->space(AS_PROGRAM).install_ram(0xc000, 0xffff, m_ram->pointer()); - } -} - void svi3x8_state::machine_start() { // register for save states + save_item(NAME(m_intvdp)); + save_item(NAME(m_intexp)); + save_item(NAME(m_romdis)); + save_item(NAME(m_ramdis)); + save_item(NAME(m_cart)); + save_item(NAME(m_bk21)); save_item(NAME(m_keyboard_row)); } void svi3x8_state::machine_reset() { - reset_memory_configuration(); + m_intvdp = 0; + m_intexp = 0; + m_romdis = 1; + m_ramdis = 1; + m_cart = 1; + m_bk21 = 1; } -WRITE8_MEMBER( svi3x8_state::psg_port_b_w ) +READ8_MEMBER( svi3x8_state::page1_r) { - reset_memory_configuration(); + if (m_cart == 0) + return m_cart_rom->exists() ? m_cart_rom->read_rom(space, offset) : 0xff; - // CART - if (BIT(data, 0) == 0) - { - if (m_cart->exists()) - m_maincpu->space(AS_PROGRAM).install_rom(0x0000, 0x7fff, m_cart->get_rom_base()); - else - m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x7fff); - } - else - { - // BK21 (SV-328) - if (BIT(data, 1) == 0) - { - if (m_ram->size() == 64 * 1024) - m_maincpu->space(AS_PROGRAM).install_ram(0x0000, 0x7fff, m_ram->pointer() + 0x8000); - else - m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x7fff); - } + UINT8 data = m_expander->mreq_r(space, offset); - // BK22 (SV-807) - if (BIT(data, 2) == 0) - m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x8000, 0xffff); + if (m_romdis == 1) + data = m_basic->u8(offset); - // BK31 (SV-807) - if (BIT(data, 3) == 0) - m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x0000, 0x7fff); + if (m_bk21 == 0 && IS_SVI328) + data = m_ram->read(offset); - // BK32 (SV-807) - if (BIT(data, 4) == 0) - m_maincpu->space(AS_PROGRAM).unmap_readwrite(0x8000, 0xffff); - } + return data; +} + +WRITE8_MEMBER( svi3x8_state::page1_w) +{ + if (m_cart == 0) + return; + + m_expander->mreq_w(space, offset, data); + + if (m_bk21 == 0 && IS_SVI328) + m_ram->write(offset, data); +} + +READ8_MEMBER( svi3x8_state::page2_r) +{ + offset += 0x8000; + + UINT8 data = m_expander->mreq_r(space, offset); + + if (m_ramdis == 1 && (offset >= 0x4000 || IS_SVI328)) + return m_ram->read(IS_SVI328 ? offset : offset - 0xc000); + + return data; +} + +WRITE8_MEMBER( svi3x8_state::page2_w ) +{ + offset += 0x8000; + + m_expander->mreq_w(space, offset, data); + + if (m_ramdis == 1 && (offset >= 0x4000 || IS_SVI328)) + m_ram->write(IS_SVI328 ? offset : offset - 0xc000, data); +} + +WRITE8_MEMBER( svi3x8_state::bank_w ) +{ + logerror("bank_w: %02x\n", data); + + m_cart = BIT(data, 0); + m_bk21 = BIT(data, 1); + + m_expander->bk21_w(BIT(data, 1)); + m_expander->bk22_w(BIT(data, 2)); + m_expander->bk31_w(BIT(data, 3)); + m_expander->bk32_w(BIT(data, 4)); + + // TODO: handle ROM2/ROM3 enable (bit 6 + 7) output().set_value("led_caps_lock", BIT(data, 5)); } @@ -372,6 +425,22 @@ WRITE8_MEMBER( svi3x8_state::ppi_port_c_w ) m_speaker->level_w(BIT(data, 7)); } +WRITE_LINE_MEMBER( svi3x8_state::intexp_w ) +{ + m_intexp = state; + m_maincpu->set_input_line(INPUT_LINE_IRQ0, (m_intvdp || m_intexp) ? ASSERT_LINE : CLEAR_LINE); +} + +WRITE_LINE_MEMBER( svi3x8_state::romdis_w ) +{ + m_romdis = state; +} + +WRITE_LINE_MEMBER( svi3x8_state::ramdis_w ) +{ + m_ramdis = state; +} + //************************************************************************** // CARTRIDGE @@ -379,7 +448,7 @@ WRITE8_MEMBER( svi3x8_state::ppi_port_c_w ) DEVICE_IMAGE_LOAD_MEMBER( svi3x8_state, cartridge ) { - UINT32 size = m_cart->common_get_size("rom"); + UINT32 size = m_cart_rom->common_get_size("rom"); if (size != 0x8000) { @@ -387,8 +456,8 @@ DEVICE_IMAGE_LOAD_MEMBER( svi3x8_state, cartridge ) return IMAGE_INIT_FAIL; } - m_cart->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom"); + m_cart_rom->rom_alloc(size, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); + m_cart_rom->common_load_rom(m_cart_rom->get_rom_base(), size, "rom"); return IMAGE_INIT_PASS; } @@ -427,7 +496,7 @@ static MACHINE_CONFIG_START( svi318, svi3x8_state ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) MCFG_SOUND_ADD("psg", AY8910, XTAL_10_738635MHz / 6) MCFG_AY8910_PORT_A_READ_CB(IOPORT("JOY")) - MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(svi3x8_state, psg_port_b_w)) + MCFG_AY8910_PORT_B_WRITE_CB(WRITE8(svi3x8_state, bank_w)) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75) // cassette @@ -442,6 +511,12 @@ static MACHINE_CONFIG_START( svi318, svi3x8_state ) MCFG_GENERIC_EXTENSIONS("bin,rom") MCFG_GENERIC_LOAD(svi3x8_state, cartridge) MCFG_SOFTWARE_LIST_ADD("cart_list", "svi318_cart") + + // expander bus + MCFG_SVI_EXPANDER_BUS_ADD("exp") + MCFG_SVI_EXPANDER_INT_HANDLER(WRITELINE(svi3x8_state, intexp_w)) + MCFG_SVI_EXPANDER_ROMDIS_HANDLER(WRITELINE(svi3x8_state, romdis_w)) + MCFG_SVI_EXPANDER_RAMDIS_HANDLER(WRITELINE(svi3x8_state, ramdis_w)) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( svi318n, svi318 )