summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/sg1000_exp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2019-03-26 11:13:37 +1100
committer Vas Crabb <vas@vastheman.com>2019-03-26 11:13:37 +1100
commit97b67170277437131adf6ed4d60139c172529e4f (patch)
tree7a5cbf608f191075f1612b1af15832c206a3fe2d /src/devices/bus/sg1000_exp
parentb380514764cf857469bae61c11143a19f79a74c5 (diff)
(nw) Clean up the mess on master
This effectively reverts b380514764cf857469bae61c11143a19f79a74c5 and c24473ddff715ecec2e258a6eb38960cf8c8e98e, restoring the state at 598cd5227223c3b04ca31f0dbc1981256d9ea3ff. Before pushing, please check that what you're about to push is sane. Check your local commit log and ensure there isn't anything out-of-place before pushing to mainline. When things like this happen, it wastes everyone's time. I really don't need this in a week when real work™ is busting my balls and I'm behind where I want to be with preparing for MAME release.
Diffstat (limited to 'src/devices/bus/sg1000_exp')
-rw-r--r--src/devices/bus/sg1000_exp/fm_unit.cpp13
-rw-r--r--src/devices/bus/sg1000_exp/kblink.cpp179
-rw-r--r--src/devices/bus/sg1000_exp/kblink.h82
-rw-r--r--src/devices/bus/sg1000_exp/sg1000exp.h26
-rw-r--r--src/devices/bus/sg1000_exp/sk1100.cpp45
-rw-r--r--src/devices/bus/sg1000_exp/sk1100.h3
-rw-r--r--src/devices/bus/sg1000_exp/sk1100prn.cpp125
-rw-r--r--src/devices/bus/sg1000_exp/sk1100prn.h88
8 files changed, 519 insertions, 42 deletions
diff --git a/src/devices/bus/sg1000_exp/fm_unit.cpp b/src/devices/bus/sg1000_exp/fm_unit.cpp
index ab759994f30..a7bdc4bcc5d 100644
--- a/src/devices/bus/sg1000_exp/fm_unit.cpp
+++ b/src/devices/bus/sg1000_exp/fm_unit.cpp
@@ -50,12 +50,13 @@ SMS version is not playing PSG sound on his Mark III with the FM unit.
DEFINE_DEVICE_TYPE(SEGA_FM_UNIT, sega_fm_unit_device, "sega_fm_unit", "SG-1000 FM Sound Unit")
-MACHINE_CONFIG_START(sega_fm_unit_device::device_add_mconfig)
- MCFG_DEVICE_ADD("ym2413", YM2413, XTAL(10'738'635)/3)
+void sega_fm_unit_device::device_add_mconfig(machine_config &config)
+{
+ YM2413(config, m_ym, XTAL(10'738'635)/3);
// if this output gain is changed, the gain set when unmute the output need
// to be changed too, probably along the gain set for SMSJ/SMSKRFM drivers.
- MCFG_SOUND_ROUTE(ALL_OUTPUTS, ":mono", 1.00)
-MACHINE_CONFIG_END
+ m_ym->add_route(ALL_OUTPUTS, ":mono", 1.00);
+}
//**************************************************************************
@@ -122,10 +123,10 @@ WRITE8_MEMBER(sega_fm_unit_device::peripheral_w)
switch (offset)
{
case 0: // register port
- m_ym->write(space, 0, data & 0x3f);
+ m_ym->write(0, data & 0x3f);
break;
case 1: // data port
- m_ym->write(space, 1, data);
+ m_ym->write(1, data);
break;
case 2: // control port
case 3: // mirror
diff --git a/src/devices/bus/sg1000_exp/kblink.cpp b/src/devices/bus/sg1000_exp/kblink.cpp
new file mode 100644
index 00000000000..039c7f91196
--- /dev/null
+++ b/src/devices/bus/sg1000_exp/kblink.cpp
@@ -0,0 +1,179 @@
+// license:BSD-3-Clause
+// copyright-holders:Enik Land
+/**********************************************************************
+
+ Sega SK-1100 keyboard link cable emulation
+
+The cable is used only to link two Mark III's through keyboard, what
+is supported by the game F-16 Fighting Falcon for its 2 players mode.
+
+Keyboard link cable info (originally from http://homepage3.nifty.com/st-2/,
+but taken from http://www.smspower.org/Games/F16FightingFalcon-SMS-Talk):
+
+- Cable is 7-pin DIN.
+- Crossover scheme of the cable to connect pins
+
+ From To
+ 1 1
+ 2 6
+ 3 3
+ 4 5
+ 5 4
+ 6 2
+ 7 7
+
+Pinout of the printer port (from Charles MacDonald's sc3000h-20040729.txt
+document, with the function of pin 6 corrected to /FAULT).
+Numbering in counterclockwise/anticlockwise direction:
+
+ 1 : Unused (not connected to anything)
+ 2 : PPI PC5 (DATA output)
+ 3 : PPI PC7 (/FEED output)
+ 4 : PPI PB6 (BUSY input)
+ 5 : PPI PC6 (/RESET output)
+ 6 : PPI PB5 (/FAULT input)
+ 7 : GND
+
+**********************************************************************/
+
+#include "emu.h"
+#include "kblink.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(SK1100_LINK_CABLE, sk1100_link_cable_device, "sk1100_link_cable", "SK-1100 Link Cable")
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sk1100_link_cable_device - constructor
+//-------------------------------------------------
+
+sk1100_link_cable_device::sk1100_link_cable_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SK1100_LINK_CABLE, tag, owner, clock),
+ device_sk1100_printer_port_interface(mconfig, *this),
+ m_stream(*this, "stream"),
+ m_input_count(0),
+ m_input_index(0),
+ m_timer_poll(nullptr),
+ m_timer_send(nullptr),
+ m_timer_read(nullptr),
+ m_update_received_data(true),
+ m_data(0),
+ m_reset(0),
+ m_feed(0),
+ m_busy(0),
+ m_fault(0)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sk1100_link_cable_device::device_start()
+{
+ m_timer_poll = timer_alloc(TIMER_POLL);
+ m_timer_send = timer_alloc(TIMER_SEND);
+ m_timer_read = timer_alloc(TIMER_READ);
+
+ /* register for state saving */
+ save_item(NAME(m_data));
+ save_item(NAME(m_reset));
+ save_item(NAME(m_feed));
+ save_item(NAME(m_busy));
+ save_item(NAME(m_fault));
+ save_item(NAME(m_update_received_data));
+ save_item(NAME(m_input_count));
+ save_item(NAME(m_input_index));
+ save_pointer(NAME(m_input_buffer), sizeof(m_input_buffer));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void sk1100_link_cable_device::device_reset()
+{
+ queue();
+}
+
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void sk1100_link_cable_device::device_add_mconfig(machine_config &config)
+{
+ BITBANGER(config, m_stream, 0);
+}
+
+
+void sk1100_link_cable_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_POLL:
+ queue();
+ break;
+
+ case TIMER_SEND:
+ m_stream->output(u8(param));
+ break;
+
+ case TIMER_READ:
+ m_update_received_data = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void sk1100_link_cable_device::queue()
+{
+ if (m_input_index == m_input_count)
+ {
+ m_input_index = 0;
+ m_input_count = m_stream->input(m_input_buffer, sizeof(m_input_buffer));
+ if (!m_input_count)
+ {
+ m_timer_poll->adjust(attotime::from_hz(XTAL(10'738'635)/3));
+ }
+ }
+}
+
+void sk1100_link_cable_device::set_data_read()
+{
+ // Check if a new byte from the input buffer was read for this timeslice.
+ if (m_update_received_data == true)
+ {
+ if (m_input_count != 0)
+ {
+ u8 byte = m_input_buffer[m_input_index++];
+ // there is no way to read what was sent from peer as feed bit.
+ m_fault = BIT(byte, 0); // sent from peer as data bit
+ m_busy = BIT(byte, 1); // sent from peer as reset bit
+ queue();
+ }
+ // Set to read next byte only after the end of this timeslice.
+ m_update_received_data = false;
+ m_timer_read->adjust(attotime::zero);
+ }
+}
+
+void sk1100_link_cable_device::set_data_transfer()
+{
+ u8 byte = (m_feed << 2) | (m_reset << 1) | m_data;
+ m_timer_send->adjust(attotime::zero, byte);
+}
+
+
diff --git a/src/devices/bus/sg1000_exp/kblink.h b/src/devices/bus/sg1000_exp/kblink.h
new file mode 100644
index 00000000000..65e5782f4a2
--- /dev/null
+++ b/src/devices/bus/sg1000_exp/kblink.h
@@ -0,0 +1,82 @@
+// license:BSD-3-Clause
+// copyright-holders:Enik Land
+/**********************************************************************
+
+ Sega SK-1100 keyboard link cable emulation
+
+The cable is used only to link two Mark III's through keyboard, what
+is supported by the game F-16 Fighting Falcon for its 2 players mode.
+
+**********************************************************************/
+
+#ifndef MAME_BUS_SG1000_EXP_SK1100_KBLINK_H
+#define MAME_BUS_SG1000_EXP_SK1100_KBLINK_H
+
+#pragma once
+
+
+#include "sk1100prn.h"
+#include "imagedev/bitbngr.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sk1100_link_cable_device
+
+class sk1100_link_cable_device : public device_t,
+ public device_sk1100_printer_port_interface
+{
+public:
+ // construction/destruction
+ sk1100_link_cable_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ // device_sk1100_link_cable_interface overrides
+
+ virtual DECLARE_WRITE_LINE_MEMBER( input_data ) override { m_data = state; set_data_transfer(); }
+ virtual DECLARE_WRITE_LINE_MEMBER( input_reset ) override { m_reset = state; set_data_transfer(); }
+ virtual DECLARE_WRITE_LINE_MEMBER( input_feed ) override { m_feed = state; set_data_transfer(); }
+
+ virtual DECLARE_READ_LINE_MEMBER( output_fault ) override { set_data_read(); return m_fault; }
+ virtual DECLARE_READ_LINE_MEMBER( output_busy ) override { set_data_read(); return m_busy; }
+
+private:
+ static constexpr int TIMER_POLL = 1;
+ static constexpr int TIMER_SEND = 2;
+ static constexpr int TIMER_READ = 3;
+
+ void queue();
+ void set_data_transfer();
+ void set_data_read();
+
+ required_device<bitbanger_device> m_stream;
+
+ u8 m_input_buffer[1000];
+ u32 m_input_count;
+ u32 m_input_index;
+ emu_timer *m_timer_poll;
+ emu_timer *m_timer_send;
+ emu_timer *m_timer_read;
+ bool m_update_received_data;
+ int m_data;
+ int m_reset;
+ int m_feed;
+ int m_busy;
+ int m_fault;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(SK1100_LINK_CABLE, sk1100_link_cable_device)
+
+
+#endif // MAME_BUS_SG1000_EXP_SK1100_KBLINK_H
diff --git a/src/devices/bus/sg1000_exp/sg1000exp.h b/src/devices/bus/sg1000_exp/sg1000exp.h
index 9a21c263407..c132b48d9dd 100644
--- a/src/devices/bus/sg1000_exp/sg1000exp.h
+++ b/src/devices/bus/sg1000_exp/sg1000exp.h
@@ -15,20 +15,6 @@
#pragma once
-
-
-//**************************************************************************
-// INTERFACE CONFIGURATION MACROS
-//**************************************************************************
-
-#define MCFG_SG1000_EXPANSION_ADD(_tag, _slot_intf, _def_slot, _fixed) \
- MCFG_DEVICE_ADD(_tag, SG1000_EXPANSION_SLOT, 0) \
- MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed)
-#define MCFG_SG1000_EXPANSION_MODIFY(_tag) \
- MCFG_DEVICE_MODIFY(_tag)
-
-
-
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
@@ -41,7 +27,17 @@ class sg1000_expansion_slot_device : public device_t, public device_slot_interfa
{
public:
// construction/destruction
- sg1000_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ template <typename T>
+ sg1000_expansion_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt, bool const fixed)
+ : sg1000_expansion_slot_device(mconfig, tag, owner, 0)
+ {
+ option_reset();
+ opts(*this);
+ set_default_option(dflt);
+ set_fixed(fixed);
+ }
+
+ sg1000_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
virtual ~sg1000_expansion_slot_device();
DECLARE_READ8_MEMBER(read);
diff --git a/src/devices/bus/sg1000_exp/sk1100.cpp b/src/devices/bus/sg1000_exp/sk1100.cpp
index e23fe34caed..1bb0a01adfd 100644
--- a/src/devices/bus/sg1000_exp/sk1100.cpp
+++ b/src/devices/bus/sg1000_exp/sk1100.cpp
@@ -12,7 +12,6 @@ Release data from the Sega Retro project:
TODO:
- SP-400 serial printer
-- Link between two Mark III's through keyboard, supported by F-16 Fighting Falcon
**********************************************************************/
@@ -110,23 +109,23 @@ static INPUT_PORTS_START( sk1100_keys )
PORT_START("PB0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(')
- PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("PB1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')')
- PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("PB2")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0')
- PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("PB3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=')
- PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("PB4")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('^')
- PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED )
+ PORT_BIT( 0x0e, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("PB5")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xc2\xa5") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(0x00a5)
@@ -154,24 +153,25 @@ ioport_constructor sega_sk1100_device::device_input_ports() const
}
-MACHINE_CONFIG_START(sega_sk1100_device::device_add_mconfig)
+void sega_sk1100_device::device_add_mconfig(machine_config &config)
+{
/* devices */
I8255(config, m_ppi);
m_ppi->in_pa_callback().set(FUNC(sega_sk1100_device::ppi_pa_r));
m_ppi->in_pb_callback().set(FUNC(sega_sk1100_device::ppi_pb_r));
m_ppi->out_pc_callback().set(FUNC(sega_sk1100_device::ppi_pc_w));
-// MCFG_PRINTER_ADD("sp400") /* serial printer */
+ CASSETTE(config, m_cassette);
+ m_cassette->set_formats(sc3000_cassette_formats);
+ m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED);
+ m_cassette->set_interface("sc3000_cass");
- MCFG_CASSETTE_ADD("cassette")
- MCFG_CASSETTE_FORMATS(sc3000_cassette_formats)
- MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED)
- MCFG_CASSETTE_INTERFACE("sc3000_cass")
+ SK1100_PRINTER_PORT(config, m_printer_port, sk1100_printer_port_devices, nullptr);
/* software lists */
- MCFG_SOFTWARE_LIST_ADD("sc3k_cart_list","sc3000_cart")
- MCFG_SOFTWARE_LIST_ADD("cass_list","sc3000_cass")
-MACHINE_CONFIG_END
+ SOFTWARE_LIST(config, "sc3k_cart_list").set_original("sc3000_cart");
+ SOFTWARE_LIST(config, "cass_list").set_original("sc3000_cass");
+}
//**************************************************************************
// LIVE DEVICE
@@ -186,6 +186,7 @@ sega_sk1100_device::sega_sk1100_device(const machine_config &mconfig, const char
device_sg1000_expansion_slot_interface(mconfig, *this),
m_cassette(*this, "cassette"),
m_ppi(*this, UPD9255_0_TAG),
+ m_printer_port(*this, "printer"),
m_pa(*this, {"PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7"}),
m_pb(*this, {"PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7"}),
m_keylatch(0)
@@ -262,7 +263,7 @@ READ8_MEMBER( sega_sk1100_device::ppi_pb_r )
PB2 Keyboard input
PB3 Keyboard input
PB4 /CONT input from cartridge terminal B-11
- PB5 FAULT input from printer
+ PB5 /FAULT input from printer
PB6 BUSY input from printer
PB7 Cassette tape input
*/
@@ -273,8 +274,9 @@ READ8_MEMBER( sega_sk1100_device::ppi_pb_r )
/* cartridge contact */
data |= 0x10;
- /* printer */
- data |= 0x60;
+ /* printer port */
+ data |= m_printer_port->fault_r() << 5;
+ data |= m_printer_port->busy_r() << 6;
/* tape input */
if (m_cassette->input() > +0.0) data |= 0x80;
@@ -301,7 +303,10 @@ WRITE8_MEMBER( sega_sk1100_device::ppi_pc_w )
m_keylatch = data & 0x07;
/* cassette */
- m_cassette->output( BIT(data, 4) ? +1.0 : -1.0);
+ m_cassette->output(BIT(data, 4) ? +1.0 : -1.0);
- /* TODO printer */
+ /* printer port */
+ m_printer_port->data_w(BIT(data, 5));
+ m_printer_port->reset_w(BIT(data, 6));
+ m_printer_port->feed_w(BIT(data, 7));
}
diff --git a/src/devices/bus/sg1000_exp/sk1100.h b/src/devices/bus/sg1000_exp/sk1100.h
index 4845fe09e1c..13ff5780f64 100644
--- a/src/devices/bus/sg1000_exp/sk1100.h
+++ b/src/devices/bus/sg1000_exp/sk1100.h
@@ -13,9 +13,9 @@
#include "sg1000exp.h"
+#include "sk1100prn.h"
#include "formats/sc3000_bit.h"
#include "imagedev/cassette.h"
-#include "imagedev/printer.h"
#include "machine/i8255.h"
@@ -55,6 +55,7 @@ private:
required_device<cassette_image_device> m_cassette;
required_device<i8255_device> m_ppi;
+ required_device<sk1100_printer_port_device> m_printer_port;
required_ioport_array<8> m_pa;
required_ioport_array<8> m_pb;
diff --git a/src/devices/bus/sg1000_exp/sk1100prn.cpp b/src/devices/bus/sg1000_exp/sk1100prn.cpp
new file mode 100644
index 00000000000..b902ce3992f
--- /dev/null
+++ b/src/devices/bus/sg1000_exp/sk1100prn.cpp
@@ -0,0 +1,125 @@
+// license:BSD-3-Clause
+// copyright-holders:Enik Land
+/**********************************************************************
+
+ Sega SK-1100 keyboard printer port emulation
+
+**********************************************************************/
+
+#include "emu.h"
+#include "sk1100prn.h"
+// slot devices
+//#include "sp400.h"
+#include "kblink.h"
+
+
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(SK1100_PRINTER_PORT, sk1100_printer_port_device, "sk1100_printer_port", "Sega SK-1100 Printer Port")
+
+
+
+//**************************************************************************
+// CARD INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// device_sk1100_printer_port_interface - constructor
+//-------------------------------------------------
+
+device_sk1100_printer_port_interface::device_sk1100_printer_port_interface(const machine_config &mconfig, device_t &device)
+ : device_slot_card_interface(mconfig,device)
+{
+}
+
+
+//-------------------------------------------------
+// ~device_sk1100_printer_port_interface - destructor
+//-------------------------------------------------
+
+device_sk1100_printer_port_interface::~device_sk1100_printer_port_interface()
+{
+}
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// sk1100_printer_port_device - constructor
+//-------------------------------------------------
+
+sk1100_printer_port_device::sk1100_printer_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SK1100_PRINTER_PORT, tag, owner, clock),
+ device_slot_interface(mconfig, *this),
+ m_device(nullptr)
+{
+}
+
+
+//-------------------------------------------------
+// sk1100_printer_port_device - destructor
+//-------------------------------------------------
+
+sk1100_printer_port_device::~sk1100_printer_port_device()
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void sk1100_printer_port_device::device_start()
+{
+ m_device = dynamic_cast<device_sk1100_printer_port_interface *>(get_card_device());
+}
+
+WRITE_LINE_MEMBER(sk1100_printer_port_device::data_w)
+{
+ if (m_device)
+ m_device->input_data(state);
+}
+
+WRITE_LINE_MEMBER(sk1100_printer_port_device::reset_w)
+{
+ if (m_device)
+ m_device->input_reset(state);
+}
+
+WRITE_LINE_MEMBER(sk1100_printer_port_device::feed_w)
+{
+ if (m_device)
+ m_device->input_feed(state);
+}
+
+READ_LINE_MEMBER(sk1100_printer_port_device::fault_r)
+{
+ if (m_device)
+ return m_device->output_fault();
+ else
+ return 1;
+}
+
+READ_LINE_MEMBER(sk1100_printer_port_device::busy_r)
+{
+ if (m_device)
+ return m_device->output_busy();
+ else
+ return 1;
+}
+
+//-------------------------------------------------
+// SLOT_INTERFACE( sk1100_printer_port_devices )
+//-------------------------------------------------
+
+void sk1100_printer_port_devices(device_slot_interface &device)
+{
+ //device.option_add("sp400", SP400_PRINTER); /* serial printer */
+ device.option_add("kblink", SK1100_LINK_CABLE);
+}
diff --git a/src/devices/bus/sg1000_exp/sk1100prn.h b/src/devices/bus/sg1000_exp/sk1100prn.h
new file mode 100644
index 00000000000..b926f311f29
--- /dev/null
+++ b/src/devices/bus/sg1000_exp/sk1100prn.h
@@ -0,0 +1,88 @@
+// license:BSD-3-Clause
+// copyright-holders:Enik Land
+/**********************************************************************
+
+ Sega SK-1100 keyboard printer port emulation
+
+**********************************************************************
+
+
+**********************************************************************/
+
+#ifndef MAME_BUS_SG1000_EXP_SK1100_PRN_H
+#define MAME_BUS_SG1000_EXP_SK1100_PRN_H
+
+#pragma once
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> sk1100_printer_port_device
+
+class device_sk1100_printer_port_interface;
+
+class sk1100_printer_port_device : public device_t, public device_slot_interface
+{
+public:
+ // construction/destruction
+ template <typename T>
+ sk1100_printer_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt)
+ : sk1100_printer_port_device(mconfig, tag, owner, 0)
+ {
+ option_reset();
+ opts(*this);
+ set_default_option(dflt);
+ set_fixed(false);
+ }
+
+ sk1100_printer_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ virtual ~sk1100_printer_port_device();
+
+ DECLARE_READ_LINE_MEMBER(fault_r);
+ DECLARE_READ_LINE_MEMBER(busy_r);
+
+ DECLARE_WRITE_LINE_MEMBER(data_w);
+ DECLARE_WRITE_LINE_MEMBER(reset_w);
+ DECLARE_WRITE_LINE_MEMBER(feed_w);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+private:
+ device_sk1100_printer_port_interface *m_device;
+};
+
+
+// ======================> device_sk1100_printer_port_interface
+
+// class representing interface-specific live sk1100_printer_port peripheral
+class device_sk1100_printer_port_interface : public device_slot_card_interface
+{
+ friend class sk1100_printer_port_device;
+public:
+ // construction/destruction
+ virtual ~device_sk1100_printer_port_interface();
+
+protected:
+ device_sk1100_printer_port_interface(const machine_config &mconfig, device_t &device);
+
+ virtual DECLARE_WRITE_LINE_MEMBER( input_data ) { }
+ virtual DECLARE_WRITE_LINE_MEMBER( input_reset ) { }
+ virtual DECLARE_WRITE_LINE_MEMBER( input_feed ) { }
+
+ virtual DECLARE_READ_LINE_MEMBER( output_fault ) { return 1; }
+ virtual DECLARE_READ_LINE_MEMBER( output_busy ) { return 1; }
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(SK1100_PRINTER_PORT, sk1100_printer_port_device)
+
+
+void sk1100_printer_port_devices(device_slot_interface &device);
+
+
+#endif // MAME_BUS_SG1000_EXP_SK1100_PRN_H