New working machines

--------------------
RS-232 DCE-DCE Bridge

(nw) This is a simple machine for wiring together two things that want
to plug into an RS-232 port.  This means that for DCE-like things (e.g.
serial printers) there's no need to create an extra machine to allow
them to talk to the outside world with the null_modem device.  (Also
added some asserts, removed a FIXME, and put the swtpc8212 terminal in
the default RS-232 devices.)
This commit is contained in:
Vas Crabb 2019-11-02 02:07:50 +11:00
parent b1246642eb
commit 74bd9899a7
13 changed files with 410 additions and 10 deletions

View File

@ -2371,6 +2371,7 @@ files {
MAME_DIR .. "src/mame/drivers/4004clk.cpp",
MAME_DIR .. "src/mame/drivers/68ksbc.cpp",
MAME_DIR .. "src/mame/drivers/craft.cpp",
MAME_DIR .. "src/mame/drivers/dcebridge.cpp",
MAME_DIR .. "src/mame/drivers/homez80.cpp",
MAME_DIR .. "src/mame/drivers/p112.cpp",
MAME_DIR .. "src/mame/drivers/phunsy.cpp",

View File

@ -104,7 +104,7 @@ public:
virtual ~device_acorn_bus_interface();
// inline configuration
void set_acorn_bus(acorn_bus_device &bus) { m_bus = &bus; }
void set_acorn_bus(acorn_bus_device &bus) { assert(!device().started()); m_bus = &bus; }
protected:
device_acorn_bus_interface(const machine_config &mconfig, device_t &device);

View File

@ -210,6 +210,7 @@ void device_bml3bus_card_interface::interface_pre_start()
void device_bml3bus_card_interface::set_bml3bus(bml3bus_device &bus, const char *slottag)
{
assert(!m_bml3bus);
assert(!device().started());
// extract the slot number from the last digit of the slot tag
int tlen = strlen(slottag);

View File

@ -45,8 +45,6 @@ void c64_final_chesscard_device::device_add_mconfig(machine_config &config)
M65SC02(config, m_maincpu, 5_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &c64_final_chesscard_device::c64_fcc_map);
//config.set_perfect_quantum(m_maincpu); FIXME: not safe in a slot device - add barriers
GENERIC_LATCH_8(config, m_mainlatch).data_pending_callback().set(FUNC(c64_final_chesscard_device::mainlatch_int));
GENERIC_LATCH_8(config, m_sublatch).data_pending_callback().set_inputline(m_maincpu, INPUT_LINE_NMI);
}

View File

@ -130,6 +130,7 @@ device_nasbus_card_interface::~device_nasbus_card_interface()
void device_nasbus_card_interface::set_nasbus_device(nasbus_device &nasbus)
{
assert(!device().started());
m_nasbus = &nasbus;
}

View File

@ -3,8 +3,8 @@
#include "emu.h"
#include "null_modem.h"
null_modem_device::null_modem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, NULL_MODEM, tag, owner, clock),
null_modem_device::null_modem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NULL_MODEM, tag, owner, clock),
device_serial_interface(mconfig, *this),
device_rs232_port_interface(mconfig, *this),
m_stream(*this, "stream"),

View File

@ -168,6 +168,7 @@ device_rs232_port_interface::~device_rs232_port_interface()
#include "printer.h"
#include "pty.h"
#include "sun_kbd.h"
#include "swtpc8212.h"
#include "terminal.h"
#include "ie15.h"
@ -182,4 +183,5 @@ void default_rs232_devices(device_slot_interface &device)
device.option_add("pty", PSEUDO_TERMINAL);
device.option_add("sunkbd", SUN_KBD_ADAPTOR);
device.option_add("ie15", SERIAL_TERMINAL_IE15);
device.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212);
}

View File

@ -10,7 +10,6 @@
#include "mps.h"
#include "bus/rs232/rs232.h"
#include "bus/rs232/swtpc8212.h"
#include "machine/6850acia.h"
//**************************************************************************
@ -116,7 +115,6 @@ void ss50_mps_device::device_add_mconfig(machine_config &config)
rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal"));
rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd));
rs232.cts_handler().set(FUNC(ss50_mps_device::route_cts_r));
rs232.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212);
rs232.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal));
}

View File

@ -11,7 +11,6 @@
#include "mps2.h"
#include "bus/rs232/rs232.h"
#include "bus/rs232/swtpc8212.h"
#include "machine/6850acia.h"
#include "machine/input_merger.h"
@ -142,7 +141,6 @@ void ss50_mps2_device::device_add_mconfig(machine_config &config)
rs232_upper.rxd_handler().set(m_acia_upper, FUNC(acia6850_device::write_rxd));
rs232_upper.cts_handler().set(m_acia_upper, FUNC(acia6850_device::write_cts));
rs232_upper.dcd_handler().set(m_acia_upper, FUNC(acia6850_device::write_dcd));
rs232_upper.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212);
rs232_upper.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal_upper));
ACIA6850(config, m_acia_lower, 0);
@ -154,7 +152,6 @@ void ss50_mps2_device::device_add_mconfig(machine_config &config)
rs232_lower.rxd_handler().set(m_acia_lower, FUNC(acia6850_device::write_rxd));
rs232_lower.cts_handler().set(m_acia_lower, FUNC(acia6850_device::write_cts));
rs232_lower.dcd_handler().set(m_acia_lower, FUNC(acia6850_device::write_dcd));
rs232_lower.option_add("swtpc8212", SERIAL_TERMINAL_SWTPC8212);
rs232_lower.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal_lower));
INPUT_MERGER_ANY_HIGH(config, "irq").output_handler().set(FUNC(ss50_mps2_device::write_irq));

View File

@ -244,5 +244,6 @@ device_svi_slot_interface::~device_svi_slot_interface()
void device_svi_slot_interface::set_bus_device(svi_slot_bus_device &bus)
{
assert(!device().started());
m_bus = &bus;
}

View File

@ -0,0 +1,312 @@
// license:BSD-3-Clause
// copyright-holders:Vas Crabb
// Simple RS-232 DCE-DCE bridge
#include "emu.h"
#include "bus/rs232/rs232.h"
#include "dcebridge.lh"
namespace {
enum : ioport_value
{
DTR_SOURCE_MASK = 0x07,
DTR_SOURCE_DCD_REMOTE = 0x00,
DTR_SOURCE_DSR_REMOTE = 0x01,
DTR_SOURCE_CTS_REMOTE = 0x02,
DTR_SOURCE_DCD_LOCAL = 0x03,
DTR_SOURCE_DSR_LOCAL = 0x04,
DTR_SOURCE_CTS_LOCAL = 0x05,
DTR_SOURCE_ASSERT = 0x06,
DTR_SOURCE_DEASSERT = 0x07,
RTS_SOURCE_MASK = 0x38,
RTS_SOURCE_DCD_REMOTE = 0x00,
RTS_SOURCE_DSR_REMOTE = 0x08,
RTS_SOURCE_CTS_REMOTE = 0x10,
RTS_SOURCE_DCD_LOCAL = 0x18,
RTS_SOURCE_DSR_LOCAL = 0x20,
RTS_SOURCE_CTS_LOCAL = 0x28,
RTS_SOURCE_ASSERT = 0x30,
RTS_SOURCE_DEASSERT = 0x38,
};
class dcebridge_state : public driver_device
{
public:
dcebridge_state(machine_config const &mconfig, device_type &type, char const *tag)
: driver_device(mconfig, type, tag)
, m_ports(*this, "%c", 'a')
, m_conf(*this, "CONF_%c", 'A')
{
}
template <unsigned N> DECLARE_INPUT_CHANGED_MEMBER(dtr_source);
template <unsigned N> DECLARE_INPUT_CHANGED_MEMBER(rts_source);
void dcebridge(machine_config &config);
protected:
virtual void driver_start() override;
virtual void driver_reset() override;
private:
template <unsigned N> void dcd(int state);
template <unsigned N> void dsr(int state);
template <unsigned N> void cts(int state);
template <unsigned N> void update_dtr();
template <unsigned N> void update_rts();
required_device_array<rs232_port_device, 2> m_ports;
required_ioport_array<2> m_conf;
u8 m_dcd[2] = { 0U, 0U };
u8 m_dsr[2] = { 0U, 0U };
u8 m_cts[2] = { 0U, 0U };
};
template <unsigned N> INPUT_CHANGED_MEMBER(dcebridge_state::dtr_source)
{
update_dtr<N>();
}
template <unsigned N> INPUT_CHANGED_MEMBER(dcebridge_state::rts_source)
{
update_rts<N>();
}
void dcebridge_state::dcebridge(machine_config &config)
{
RS232_PORT(config, m_ports[0], default_rs232_devices, nullptr);
m_ports[0]->rxd_handler().set(m_ports[1], FUNC(rs232_port_device::write_txd));
m_ports[0]->dcd_handler().set(FUNC(dcebridge_state::dcd<0>));
m_ports[0]->dcd_handler().append_output("dcd_a");
m_ports[0]->dsr_handler().set(FUNC(dcebridge_state::dsr<0>));
m_ports[0]->dsr_handler().append_output("dsr_a");
m_ports[0]->ri_handler().set_output("ri_a");
m_ports[0]->cts_handler().set(FUNC(dcebridge_state::cts<0>));
m_ports[0]->cts_handler().append_output("cts_a");
RS232_PORT(config, m_ports[1], default_rs232_devices, "null_modem");
m_ports[1]->rxd_handler().set(m_ports[0], FUNC(rs232_port_device::write_txd));
m_ports[1]->dcd_handler().set(FUNC(dcebridge_state::dcd<1>));
m_ports[1]->dcd_handler().append_output("dcd_b");
m_ports[1]->dsr_handler().set(FUNC(dcebridge_state::dsr<1>));
m_ports[1]->dsr_handler().append_output("dsr_b");
m_ports[1]->ri_handler().set_output("ri_b");
m_ports[1]->cts_handler().set(FUNC(dcebridge_state::cts<1>));
m_ports[1]->cts_handler().append_output("cts_b");
config.set_default_layout(layout_dcebridge);
}
void dcebridge_state::driver_start()
{
save_item(NAME(m_dcd));
save_item(NAME(m_dsr));
save_item(NAME(m_cts));
}
void dcebridge_state::driver_reset()
{
update_dtr<0>();
update_rts<0>();
update_dtr<1>();
update_rts<1>();
}
template <unsigned N> void dcebridge_state::dcd(int state)
{
if (m_dcd[N] != state)
{
m_dcd[N] = state;
if (started())
{
ioport_value const conf_local(m_conf[N]->read());
if ((conf_local & DTR_SOURCE_MASK) == DTR_SOURCE_DCD_LOCAL)
m_ports[N]->write_dtr(state);
if ((conf_local & RTS_SOURCE_MASK) == DTR_SOURCE_DCD_LOCAL)
m_ports[N]->write_rts(state);
ioport_value const conf_remote(m_conf[N ^ 1U]->read());
if ((conf_remote & DTR_SOURCE_MASK) == DTR_SOURCE_DCD_REMOTE)
m_ports[N ^ 1U]->write_dtr(state);
if ((conf_remote & RTS_SOURCE_MASK) == DTR_SOURCE_DCD_REMOTE)
m_ports[N ^ 1U]->write_rts(state);
}
}
}
template <unsigned N> void dcebridge_state::dsr(int state)
{
if (m_dsr[N] != state)
{
m_dsr[N] = state;
if (started())
{
ioport_value const conf_local(m_conf[N]->read());
if ((conf_local & DTR_SOURCE_MASK) == DTR_SOURCE_DSR_LOCAL)
m_ports[N]->write_dtr(state);
if ((conf_local & RTS_SOURCE_MASK) == DTR_SOURCE_DSR_LOCAL)
m_ports[N]->write_rts(state);
ioport_value const conf_remote(m_conf[N ^ 1U]->read());
if ((conf_remote & DTR_SOURCE_MASK) == DTR_SOURCE_DSR_REMOTE)
m_ports[N ^ 1U]->write_dtr(state);
if ((conf_remote & RTS_SOURCE_MASK) == DTR_SOURCE_DSR_REMOTE)
m_ports[N ^ 1U]->write_rts(state);
}
}
}
template <unsigned N> void dcebridge_state::cts(int state)
{
if (m_cts[N] != state)
{
m_cts[N] = state;
if (started())
{
ioport_value const conf_local(m_conf[N]->read());
if ((conf_local & DTR_SOURCE_MASK) == DTR_SOURCE_CTS_LOCAL)
m_ports[N]->write_dtr(state);
if ((conf_local & RTS_SOURCE_MASK) == DTR_SOURCE_CTS_LOCAL)
m_ports[N]->write_rts(state);
ioport_value const conf_remote(m_conf[N ^ 1U]->read());
if ((conf_remote & DTR_SOURCE_MASK) == DTR_SOURCE_CTS_REMOTE)
m_ports[N ^ 1U]->write_dtr(state);
if ((conf_remote & RTS_SOURCE_MASK) == DTR_SOURCE_CTS_REMOTE)
m_ports[N ^ 1U]->write_rts(state);
}
}
}
template <unsigned N> void dcebridge_state::update_dtr()
{
ioport_value const conf(m_conf[N]->read());
switch (conf & DTR_SOURCE_MASK)
{
case DTR_SOURCE_DCD_REMOTE:
m_ports[N]->write_dtr(m_dcd[N ^ 1U]);
break;
case DTR_SOURCE_DSR_REMOTE:
m_ports[N]->write_dtr(m_dsr[N ^ 1U]);
break;
case DTR_SOURCE_CTS_REMOTE:
m_ports[N]->write_dtr(m_cts[N ^ 1U]);
break;
case DTR_SOURCE_DCD_LOCAL:
m_ports[N]->write_dtr(m_dcd[N]);
break;
case DTR_SOURCE_DSR_LOCAL:
m_ports[N]->write_dtr(m_dsr[N]);
break;
case DTR_SOURCE_CTS_LOCAL:
m_ports[N]->write_dtr(m_cts[N]);
break;
case DTR_SOURCE_ASSERT:
m_ports[N]->write_dtr(0);
break;
case DTR_SOURCE_DEASSERT:
m_ports[N]->write_dtr(1);
break;
}
}
template <unsigned N> void dcebridge_state::update_rts()
{
ioport_value const conf(m_conf[N]->read());
switch (conf & RTS_SOURCE_MASK)
{
case RTS_SOURCE_DCD_REMOTE:
m_ports[N]->write_rts(m_dcd[N ^ 1U]);
break;
case RTS_SOURCE_DSR_REMOTE:
m_ports[N]->write_rts(m_dsr[N ^ 1U]);
break;
case RTS_SOURCE_CTS_REMOTE:
m_ports[N]->write_rts(m_cts[N ^ 1U]);
break;
case RTS_SOURCE_DCD_LOCAL:
m_ports[N]->write_rts(m_dcd[N]);
break;
case RTS_SOURCE_DSR_LOCAL:
m_ports[N]->write_rts(m_dsr[N]);
break;
case RTS_SOURCE_CTS_LOCAL:
m_ports[N]->write_rts(m_cts[N]);
break;
case RTS_SOURCE_ASSERT:
m_ports[N]->write_rts(0);
break;
case RTS_SOURCE_DEASSERT:
m_ports[N]->write_rts(1);
break;
}
}
INPUT_PORTS_START(dcebridge)
PORT_START("CONF_A")
PORT_CONFNAME(DTR_SOURCE_MASK, DTR_SOURCE_DSR_REMOTE, "DTR A Source") PORT_CHANGED_MEMBER(DEVICE_SELF, dcebridge_state, dtr_source<0>, 0)
PORT_CONFSETTING(DTR_SOURCE_DCD_REMOTE, "DCD B")
PORT_CONFSETTING(DTR_SOURCE_DSR_REMOTE, "DSR B")
PORT_CONFSETTING(DTR_SOURCE_CTS_REMOTE, "CTS B")
PORT_CONFSETTING(DTR_SOURCE_DCD_LOCAL, "DCD A Loopback")
PORT_CONFSETTING(DTR_SOURCE_DSR_LOCAL, "DSR A Loopback")
PORT_CONFSETTING(DTR_SOURCE_CTS_LOCAL, "CTS A Loopback")
PORT_CONFSETTING(DTR_SOURCE_ASSERT, "Asserted")
PORT_CONFSETTING(DTR_SOURCE_DEASSERT, "Deasserted")
PORT_CONFNAME(RTS_SOURCE_MASK, RTS_SOURCE_CTS_REMOTE, "RTS A Source") PORT_CHANGED_MEMBER(DEVICE_SELF, dcebridge_state, rts_source<0>, 0)
PORT_CONFSETTING(RTS_SOURCE_DCD_REMOTE, "DCD B")
PORT_CONFSETTING(RTS_SOURCE_DSR_REMOTE, "DSR B")
PORT_CONFSETTING(RTS_SOURCE_CTS_REMOTE, "CTS B")
PORT_CONFSETTING(RTS_SOURCE_DCD_LOCAL, "DCD A Loopback")
PORT_CONFSETTING(RTS_SOURCE_DSR_LOCAL, "DSR A Loopback")
PORT_CONFSETTING(RTS_SOURCE_CTS_LOCAL, "CTS A Loopback")
PORT_CONFSETTING(RTS_SOURCE_ASSERT, "Asserted")
PORT_CONFSETTING(RTS_SOURCE_DEASSERT, "Deasserted")
PORT_START("CONF_B")
PORT_CONFNAME(DTR_SOURCE_MASK, DTR_SOURCE_DSR_REMOTE, "DTR B Source") PORT_CHANGED_MEMBER(DEVICE_SELF, dcebridge_state, dtr_source<1>, 0)
PORT_CONFSETTING(DTR_SOURCE_DCD_REMOTE, "DCD A")
PORT_CONFSETTING(DTR_SOURCE_DSR_REMOTE, "DSR A")
PORT_CONFSETTING(DTR_SOURCE_CTS_REMOTE, "CTS A")
PORT_CONFSETTING(DTR_SOURCE_DCD_LOCAL, "DCD B Loopback")
PORT_CONFSETTING(DTR_SOURCE_DSR_LOCAL, "DSR B Loopback")
PORT_CONFSETTING(DTR_SOURCE_CTS_LOCAL, "CTS B Loopback")
PORT_CONFSETTING(DTR_SOURCE_ASSERT, "Asserted")
PORT_CONFSETTING(DTR_SOURCE_DEASSERT, "Deasserted")
PORT_CONFNAME(RTS_SOURCE_MASK, RTS_SOURCE_CTS_REMOTE, "RTS B Source") PORT_CHANGED_MEMBER(DEVICE_SELF, dcebridge_state, rts_source<1>, 0)
PORT_CONFSETTING(RTS_SOURCE_DCD_REMOTE, "DCD A")
PORT_CONFSETTING(RTS_SOURCE_DSR_REMOTE, "DSR A")
PORT_CONFSETTING(RTS_SOURCE_CTS_REMOTE, "CTS A")
PORT_CONFSETTING(RTS_SOURCE_DCD_LOCAL, "DCD B Loopback")
PORT_CONFSETTING(RTS_SOURCE_DSR_LOCAL, "DSR B Loopback")
PORT_CONFSETTING(RTS_SOURCE_CTS_LOCAL, "CTS B Loopback")
PORT_CONFSETTING(RTS_SOURCE_ASSERT, "Asserted")
PORT_CONFSETTING(RTS_SOURCE_DEASSERT, "Deasserted")
INPUT_PORTS_END
ROM_START(dcebridge)
ROM_END
} // anonymous namespace
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
SYST( 197?, dcebridge, 0, 0, dcebridge, dcebridge, dcebridge_state, empty_init, "generic", "RS-232 DCE-DCE Bridge", MACHINE_NO_SOUND_HW )

View File

@ -0,0 +1,86 @@
<?xml version="1.0"?>
<!--
license:CC0
copyright-holders:Vas Crabb
RS-232 DCE-DCE bridge layout
-->
<mamelayout version="2">
<element name="led">
<disk state="0">
<color red="1.0" green="0.0" blue="0.0" />
</disk>
<disk state="1">
<color red="0.15" green="0.0" blue="0.0" />
</disk>
</element>
<element name="label_a">
<text string="A" />
</element>
<element name="label_b">
<text string="B" />
</element>
<element name="label_dcd">
<text string="DCD" />
</element>
<element name="label_dsr">
<text string="DSR" />
</element>
<element name="label_ri">
<text string="RI" />
</element>
<element name="label_cts">
<text string="CTS" />
</element>
<view name="Control Lines">
<bounds x="0" y="0" width="95" height="45" />
<element ref="label_a">
<bounds x="5" y="16" width="10" height="8" />
</element>
<element ref="label_b">
<bounds x="5" y="31" width="10" height="8" />
</element>
<element ref="label_dcd">
<bounds x="18" y="5" width="14" height="8" />
</element>
<element ref="label_dsr">
<bounds x="38" y="5" width="14" height="8" />
</element>
<element ref="label_ri">
<bounds x="58" y="5" width="14" height="8" />
</element>
<element ref="label_cts">
<bounds x="78" y="5" width="14" height="8" />
</element>
<element ref="led" name="dcd_a">
<bounds x="20" y="15" width="10" height="10" />
</element>
<element ref="led" name="dsr_a">
<bounds x="40" y="15" width="10" height="10" />
</element>
<element ref="led" name="ri_a">
<bounds x="60" y="15" width="10" height="10" />
</element>
<element ref="led" name="cts_a">
<bounds x="80" y="15" width="10" height="10" />
</element>
<element ref="led" name="dcd_b">
<bounds x="20" y="30" width="10" height="10" />
</element>
<element ref="led" name="dsr_b">
<bounds x="40" y="30" width="10" height="10" />
</element>
<element ref="led" name="ri_b">
<bounds x="60" y="30" width="10" height="10" />
</element>
<element ref="led" name="cts_b">
<bounds x="80" y="30" width="10" height="10" />
</element>
</view>
</mamelayout>

View File

@ -11319,6 +11319,9 @@ dceu // 1999 Sega Dreamcast (Europe)
dcjp // 1998 Sega Dreamcast (Japan)
dctream // 200? Treamcast
@source:dcebridge.cpp
dcebridge // generic
@source:dcheese.cpp
cecmatch // (c) 1993 Coastal Amusements
dcheese // (c) 1993 HAR