1 // license:BSD-3-Clause
2 // copyright-holders:AJR
3 /**********************************************************************
4 
5     SWTPC MP-S Serial Interface
6 
7 **********************************************************************/
8 
9 #include "emu.h"
10 #include "mps.h"
11 
12 #include "bus/rs232/rs232.h"
13 #include "machine/6850acia.h"
14 
15 //**************************************************************************
16 //  TYPE DEFINITIONS
17 //**************************************************************************
18 
19 // ======================> ss50_mps_device
20 
21 class ss50_mps_device : public device_t, public ss50_card_interface
22 {
23 public:
24 	// construction/destruction
ss50_mps_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)25 	ss50_mps_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
26 		: device_t(mconfig, SS50_MPS, tag, owner, clock)
27 		, ss50_card_interface(mconfig, *this)
28 		, m_acia(*this, "acia")
29 		, m_irq_jumper(*this, "IRQ")
30 		, m_rate_jumper(*this, "BAUD")
31 		, m_cts_route(*this, "CTS_ROUTE")
32 	{
33 	}
34 
35 	DECLARE_INPUT_CHANGED_MEMBER(cts_route_change);
36 
37 protected:
38 	// device-specific overrides
39 	virtual ioport_constructor device_input_ports() const override;
40 	virtual void device_add_mconfig(machine_config &config) override;
41 	virtual void device_start() override;
42 
43 	// interface-specific overrides
44 	virtual u8 register_read(offs_t offset) override;
45 	virtual void register_write(offs_t offset, u8 data) override;
46 	virtual DECLARE_WRITE_LINE_MEMBER(f110_w) override;
47 	virtual DECLARE_WRITE_LINE_MEMBER(f150_9600_w) override;
48 	virtual DECLARE_WRITE_LINE_MEMBER(f300_w) override;
49 	virtual DECLARE_WRITE_LINE_MEMBER(f600_4800_w) override;
50 	virtual DECLARE_WRITE_LINE_MEMBER(f600_1200_w) override;
51 
52 private:
53 	DECLARE_WRITE_LINE_MEMBER(acia_irq_w);
54 	DECLARE_WRITE_LINE_MEMBER(route_cts);
55 
56 	required_device<acia6850_device> m_acia;
57 	required_ioport m_irq_jumper;
58 	required_ioport m_rate_jumper;
59 	required_ioport m_cts_route;
60 	int m_cts;
61 };
62 
63 
64 static INPUT_PORTS_START( mps )
65 	PORT_START("IRQ")
66 	PORT_CONFNAME(1, 0, "IRQ")
DEF_STR(Off)67 	PORT_CONFSETTING(1, DEF_STR(Off))
68 	PORT_CONFSETTING(0, DEF_STR(On))
69 
70 	PORT_START("BAUD")
71 	PORT_CONFNAME(0x1f, 0x1d, "Baud Rate")
72 	PORT_CONFSETTING(0x1e, "110")
73 	PORT_CONFSETTING(0x1d, "150 / 9600")
74 	PORT_CONFSETTING(0x1b, "300")
75 	PORT_CONFSETTING(0x17, "600")
76 	PORT_CONFSETTING(0x0f, "1200")
77 
78 	PORT_START("CTS_ROUTE")
79 	PORT_CONFNAME(1, 0, "CTS route") PORT_CHANGED_MEMBER(DEVICE_SELF, ss50_mps_device, cts_route_change, 0)
80 	PORT_CONFSETTING(0, "Wired low (standard)")
81 	PORT_CONFSETTING(1, "Connected through (modified)")
82 
83 INPUT_PORTS_END
84 
85 
86 //-------------------------------------------------
87 //  input_ports - device-specific input ports
88 //-------------------------------------------------
89 
90 ioport_constructor ss50_mps_device::device_input_ports() const
91 {
92 	return INPUT_PORTS_NAME(mps);
93 }
94 
95 
96 static DEVICE_INPUT_DEFAULTS_START( terminal )
97 	DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_9600)
98 	DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_9600)
99 	DEVICE_INPUT_DEFAULTS("RS232_STARTBITS", 0xff, RS232_STARTBITS_1)
100 	DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0xff, RS232_DATABITS_8)
101 	DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0xff, RS232_PARITY_NONE)
102 	DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0xff, RS232_STOPBITS_1)
103 DEVICE_INPUT_DEFAULTS_END
104 
105 
106 //-------------------------------------------------
107 //  device_add_mconfig - add device-specific
108 //  machine configuration
109 //-------------------------------------------------
110 
device_add_mconfig(machine_config & config)111 void ss50_mps_device::device_add_mconfig(machine_config &config)
112 {
113 	ACIA6850(config, m_acia, 0);
114 	m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
115 	//m_acia->rts_handler().set(FUNC(ss50_mps_device::reader_control_w));
116 	m_acia->irq_handler().set(FUNC(ss50_mps_device::acia_irq_w));
117 
118 	rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal"));
119 	rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd));
120 	rs232.cts_handler().set(FUNC(ss50_mps_device::route_cts));
121 	rs232.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal));
122 }
123 
device_start()124 void ss50_mps_device::device_start()
125 {
126 	save_item(NAME(m_cts));
127 }
128 
129 //-------------------------------------------------
130 //  register_read - read from a port register
131 //-------------------------------------------------
132 
register_read(offs_t offset)133 u8 ss50_mps_device::register_read(offs_t offset)
134 {
135 	return m_acia->read(offset & 1);
136 }
137 
138 //-------------------------------------------------
139 //  register_write - write to a port register
140 //-------------------------------------------------
141 
register_write(offs_t offset,u8 data)142 void ss50_mps_device::register_write(offs_t offset, u8 data)
143 {
144 	m_acia->write(offset & 1, data);
145 }
146 
WRITE_LINE_MEMBER(ss50_mps_device::f110_w)147 WRITE_LINE_MEMBER(ss50_mps_device::f110_w)
148 {
149 	if (!BIT(m_rate_jumper->read(), 0))
150 	{
151 		m_acia->write_txc(state);
152 		m_acia->write_rxc(state);
153 	}
154 }
155 
WRITE_LINE_MEMBER(ss50_mps_device::f150_9600_w)156 WRITE_LINE_MEMBER(ss50_mps_device::f150_9600_w)
157 {
158 	if (!BIT(m_rate_jumper->read(), 1))
159 	{
160 		m_acia->write_txc(state);
161 		m_acia->write_rxc(state);
162 	}
163 }
164 
WRITE_LINE_MEMBER(ss50_mps_device::f300_w)165 WRITE_LINE_MEMBER(ss50_mps_device::f300_w)
166 {
167 	if (!BIT(m_rate_jumper->read(), 2))
168 	{
169 		m_acia->write_txc(state);
170 		m_acia->write_rxc(state);
171 	}
172 }
173 
WRITE_LINE_MEMBER(ss50_mps_device::f600_4800_w)174 WRITE_LINE_MEMBER(ss50_mps_device::f600_4800_w)
175 {
176 	if (!BIT(m_rate_jumper->read(), 3))
177 	{
178 		m_acia->write_txc(state);
179 		m_acia->write_rxc(state);
180 	}
181 }
182 
WRITE_LINE_MEMBER(ss50_mps_device::f600_1200_w)183 WRITE_LINE_MEMBER(ss50_mps_device::f600_1200_w)
184 {
185 	if (!BIT(m_rate_jumper->read(), 4))
186 	{
187 		m_acia->write_txc(state);
188 		m_acia->write_rxc(state);
189 	}
190 }
191 
WRITE_LINE_MEMBER(ss50_mps_device::acia_irq_w)192 WRITE_LINE_MEMBER(ss50_mps_device::acia_irq_w)
193 {
194 	if (!m_irq_jumper->read())
195 		write_irq(state);
196 }
197 
WRITE_LINE_MEMBER(ss50_mps_device::route_cts)198 WRITE_LINE_MEMBER(ss50_mps_device::route_cts)
199 {
200 	if (m_cts_route->read())
201 		m_acia->write_cts(state);
202 
203 	// Cache the state, in case the ioport setting changes.
204 	m_cts = state;
205 }
206 
INPUT_CHANGED_MEMBER(ss50_mps_device::cts_route_change)207 INPUT_CHANGED_MEMBER(ss50_mps_device::cts_route_change)
208 {
209 	if (newval)
210 		m_acia->write_cts(m_cts);
211 	else
212 		m_acia->write_cts(0);
213 }
214 
215 // device type definition
216 DEFINE_DEVICE_TYPE_PRIVATE(SS50_MPS, ss50_card_interface, ss50_mps_device, "ss50_mps", "MP-S Serial Interface")
217