1 // license:BSD-3-Clause
2 // copyright-holders:68bit
3 /**********************************************************************
4 
5     SWTPC MP-S2 Dual Serial Interface
6     For 16 byte I/O address block.
7 
8 **********************************************************************/
9 
10 #include "emu.h"
11 #include "mps2.h"
12 
13 #include "bus/rs232/rs232.h"
14 #include "machine/6850acia.h"
15 #include "machine/input_merger.h"
16 
17 //**************************************************************************
18 //  TYPE DEFINITIONS
19 //**************************************************************************
20 
21 // ======================> ss50_mps2_device
22 
23 class ss50_mps2_device : public device_t, public ss50_card_interface
24 {
25 public:
26 	// construction/destruction
ss50_mps2_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)27 	ss50_mps2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
28 		: device_t(mconfig, SS50_MPS2, tag, owner, clock)
29 		, ss50_card_interface(mconfig, *this)
30 		, m_acia_upper(*this, "acia_upper")
31 		, m_tx_rate_upper_jumper(*this, "TX_BAUD_UPPER")
32 		, m_rx_rate_upper_jumper(*this, "RX_BAUD_UPPER")
33 		, m_acia_lower(*this, "acia_lower")
34 		, m_tx_rate_lower_jumper(*this, "TX_BAUD_LOWER")
35 		, m_rx_rate_lower_jumper(*this, "RX_BAUD_LOWER")
36 	{
37 	}
38 
39 protected:
40 	// device-specific overrides
41 	virtual ioport_constructor device_input_ports() const override;
42 	virtual void device_add_mconfig(machine_config &config) override;
device_start()43 	virtual void device_start() override { }
44 
45 	// interface-specific overrides
46 	virtual u8 register_read(offs_t offset) override;
47 	virtual void register_write(offs_t offset, u8 data) override;
48 	virtual DECLARE_WRITE_LINE_MEMBER(f110_w) override;
49 	virtual DECLARE_WRITE_LINE_MEMBER(f150_9600_w) override;
50 	virtual DECLARE_WRITE_LINE_MEMBER(f300_w) override;
51 	virtual DECLARE_WRITE_LINE_MEMBER(f600_4800_w) override;
52 	virtual DECLARE_WRITE_LINE_MEMBER(f600_1200_w) override;
53 
54 private:
55 	required_device<acia6850_device> m_acia_upper;
56 	required_ioport m_tx_rate_upper_jumper;
57 	required_ioport m_rx_rate_upper_jumper;
58 	required_device<acia6850_device> m_acia_lower;
59 	required_ioport m_tx_rate_lower_jumper;
60 	required_ioport m_rx_rate_lower_jumper;
61 };
62 
63 
64 static INPUT_PORTS_START( mps2 )
65 	PORT_START("TX_BAUD_UPPER")
66 	PORT_DIPNAME(0x1f, 0x1d, "Upper TX Baud Rate")
67 	PORT_DIPSETTING(0x1e, "110 / 440")
68 	PORT_DIPSETTING(0x1b, "300 / 1200")
69 	PORT_DIPSETTING(0x0f, "1200 / 4800")
70 	PORT_DIPSETTING(0x17, "4800 / 19200")
71 	PORT_DIPSETTING(0x1d, "9600 / 38400")
72 
73 	PORT_START("RX_BAUD_UPPER")
74 	PORT_DIPNAME(0x1f, 0x1d, "Upper RX Baud Rate")
75 	PORT_DIPSETTING(0x1e, "110 / 440")
76 	PORT_DIPSETTING(0x1b, "300 / 1200")
77 	PORT_DIPSETTING(0x0f, "1200 / 4800")
78 	PORT_DIPSETTING(0x17, "4800 / 19200")
79 	PORT_DIPSETTING(0x1d, "9600 / 38400")
80 
81 	PORT_START("TX_BAUD_LOWER")
82 	PORT_DIPNAME(0x1f, 0x1d, "Lower TX Baud Rate")
83 	PORT_DIPSETTING(0x1e, "110 / 440")
84 	PORT_DIPSETTING(0x1b, "300 / 1200")
85 	PORT_DIPSETTING(0x0f, "1200 / 4800")
86 	PORT_DIPSETTING(0x17, "4800 / 19200")
87 	PORT_DIPSETTING(0x1d, "9600 / 38400")
88 
89 	PORT_START("RX_BAUD_LOWER")
90 	PORT_DIPNAME(0x1f, 0x1d, "Lower RX Baud Rate")
91 	PORT_DIPSETTING(0x1e, "110 / 440")
92 	PORT_DIPSETTING(0x1b, "300 / 1200")
93 	PORT_DIPSETTING(0x0f, "1200 / 4800")
94 	PORT_DIPSETTING(0x17, "4800 / 19200")
95 	PORT_DIPSETTING(0x1d, "9600 / 38400")
96 
97 INPUT_PORTS_END
98 
99 
100 //-------------------------------------------------
101 //  input_ports - device-specific input ports
102 //-------------------------------------------------
103 
device_input_ports() const104 ioport_constructor ss50_mps2_device::device_input_ports() const
105 {
106 	return INPUT_PORTS_NAME(mps2);
107 }
108 
109 
110 static DEVICE_INPUT_DEFAULTS_START( terminal_upper )
111 	DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_9600)
112 	DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_9600)
113 	DEVICE_INPUT_DEFAULTS("RS232_STARTBITS", 0xff, RS232_STARTBITS_1)
114 	DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0xff, RS232_DATABITS_8)
115 	DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0xff, RS232_PARITY_NONE)
116 	DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0xff, RS232_STOPBITS_1)
117 DEVICE_INPUT_DEFAULTS_END
118 
DEVICE_INPUT_DEFAULTS_START(terminal_lower)119 static DEVICE_INPUT_DEFAULTS_START( terminal_lower )
120 	DEVICE_INPUT_DEFAULTS("RS232_RXBAUD", 0xff, RS232_BAUD_9600)
121 	DEVICE_INPUT_DEFAULTS("RS232_TXBAUD", 0xff, RS232_BAUD_9600)
122 	DEVICE_INPUT_DEFAULTS("RS232_STARTBITS", 0xff, RS232_STARTBITS_1)
123 	DEVICE_INPUT_DEFAULTS("RS232_DATABITS", 0xff, RS232_DATABITS_8)
124 	DEVICE_INPUT_DEFAULTS("RS232_PARITY", 0xff, RS232_PARITY_NONE)
125 	DEVICE_INPUT_DEFAULTS("RS232_STOPBITS", 0xff, RS232_STOPBITS_1)
126 DEVICE_INPUT_DEFAULTS_END
127 
128 //-------------------------------------------------
129 //  device_add_mconfig - add device-specific
130 //  machine configuration
131 //-------------------------------------------------
132 
133 void ss50_mps2_device::device_add_mconfig(machine_config &config)
134 {
135 	ACIA6850(config, m_acia_upper, 0);
136 	m_acia_upper->txd_handler().set("rs232_upper", FUNC(rs232_port_device::write_txd));
137 	m_acia_upper->rts_handler().set("rs232_upper", FUNC(rs232_port_device::write_rts));
138 	m_acia_upper->irq_handler().set("irq", FUNC(input_merger_device::in_w<0>));
139 
140 	rs232_port_device &rs232_upper(RS232_PORT(config, "rs232_upper", default_rs232_devices, "terminal"));
141 	rs232_upper.rxd_handler().set(m_acia_upper, FUNC(acia6850_device::write_rxd));
142 	rs232_upper.cts_handler().set(m_acia_upper, FUNC(acia6850_device::write_cts));
143 	rs232_upper.dcd_handler().set(m_acia_upper, FUNC(acia6850_device::write_dcd));
144 	rs232_upper.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal_upper));
145 
146 	ACIA6850(config, m_acia_lower, 0);
147 	m_acia_lower->txd_handler().set("rs232_lower", FUNC(rs232_port_device::write_txd));
148 	m_acia_lower->rts_handler().set("rs232_lower", FUNC(rs232_port_device::write_rts));
149 	m_acia_lower->irq_handler().set("irq", FUNC(input_merger_device::in_w<1>));
150 
151 	rs232_port_device &rs232_lower(RS232_PORT(config, "rs232_lower", default_rs232_devices, "terminal"));
152 	rs232_lower.rxd_handler().set(m_acia_lower, FUNC(acia6850_device::write_rxd));
153 	rs232_lower.cts_handler().set(m_acia_lower, FUNC(acia6850_device::write_cts));
154 	rs232_lower.dcd_handler().set(m_acia_lower, FUNC(acia6850_device::write_dcd));
155 	rs232_lower.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal_lower));
156 
157 	INPUT_MERGER_ANY_HIGH(config, "irq").output_handler().set(FUNC(ss50_mps2_device::write_irq));
158 }
159 
160 
161 //-------------------------------------------------
162 //  register_read - read from a port register
163 //-------------------------------------------------
164 
register_read(offs_t offset)165 u8 ss50_mps2_device::register_read(offs_t offset)
166 {
167 	if (offset < 2)
168 		return m_acia_upper->read(offset & 1);
169 
170 	if (offset < 4)
171 		return 0;
172 
173 	if (offset < 6)
174 		return m_acia_lower->read((offset - 4) & 1);
175 
176 	if (offset < 0xe)
177 		return 0;
178 
179 	// TODO there is also a 4 bit control line input port at
180 	// offset 0x0f, repeated at 0x0e.
181 	return 0;
182 }
183 
184 //-------------------------------------------------
185 //  register_write - write to a port register
186 //-------------------------------------------------
187 
register_write(offs_t offset,u8 data)188 void ss50_mps2_device::register_write(offs_t offset, u8 data)
189 {
190 	if (offset < 2)
191 		m_acia_upper->write(offset & 1, data);
192 
193 	if (offset < 4)
194 		return;
195 
196 	if (offset < 6)
197 		m_acia_lower->write((offset - 4) & 1, data);
198 }
199 
WRITE_LINE_MEMBER(ss50_mps2_device::f110_w)200 WRITE_LINE_MEMBER(ss50_mps2_device::f110_w)
201 {
202 	if (!BIT(m_tx_rate_upper_jumper->read(), 0))
203 		m_acia_upper->write_txc(state);
204 	if (!BIT(m_rx_rate_upper_jumper->read(), 0))
205 		m_acia_upper->write_rxc(state);
206 	if (!BIT(m_tx_rate_lower_jumper->read(), 0))
207 		m_acia_lower->write_txc(state);
208 	if (!BIT(m_rx_rate_lower_jumper->read(), 0))
209 		m_acia_lower->write_rxc(state);
210 }
211 
WRITE_LINE_MEMBER(ss50_mps2_device::f150_9600_w)212 WRITE_LINE_MEMBER(ss50_mps2_device::f150_9600_w)
213 {
214 	if (!BIT(m_tx_rate_upper_jumper->read(), 1))
215 		m_acia_upper->write_txc(state);
216 	if (!BIT(m_rx_rate_upper_jumper->read(), 1))
217 		m_acia_upper->write_rxc(state);
218 	if (!BIT(m_tx_rate_lower_jumper->read(), 1))
219 		m_acia_lower->write_txc(state);
220 	if (!BIT(m_rx_rate_lower_jumper->read(), 1))
221 		m_acia_lower->write_rxc(state);
222 }
223 
WRITE_LINE_MEMBER(ss50_mps2_device::f300_w)224 WRITE_LINE_MEMBER(ss50_mps2_device::f300_w)
225 {
226 	if (!BIT(m_tx_rate_upper_jumper->read(), 2))
227 		m_acia_upper->write_txc(state);
228 	if (!BIT(m_rx_rate_upper_jumper->read(), 2))
229 		m_acia_upper->write_rxc(state);
230 	if (!BIT(m_tx_rate_lower_jumper->read(), 2))
231 		m_acia_lower->write_txc(state);
232 	if (!BIT(m_rx_rate_lower_jumper->read(), 2))
233 		m_acia_lower->write_rxc(state);
234 }
235 
WRITE_LINE_MEMBER(ss50_mps2_device::f600_4800_w)236 WRITE_LINE_MEMBER(ss50_mps2_device::f600_4800_w)
237 {
238 	if (!BIT(m_tx_rate_upper_jumper->read(), 3))
239 		m_acia_upper->write_txc(state);
240 	if (!BIT(m_rx_rate_upper_jumper->read(), 3))
241 		m_acia_upper->write_rxc(state);
242 	if (!BIT(m_tx_rate_lower_jumper->read(), 3))
243 		m_acia_lower->write_txc(state);
244 	if (!BIT(m_rx_rate_lower_jumper->read(), 3))
245 		m_acia_lower->write_rxc(state);
246 }
247 
WRITE_LINE_MEMBER(ss50_mps2_device::f600_1200_w)248 WRITE_LINE_MEMBER(ss50_mps2_device::f600_1200_w)
249 {
250 	if (!BIT(m_tx_rate_upper_jumper->read(), 4))
251 		m_acia_upper->write_txc(state);
252 	if (!BIT(m_rx_rate_upper_jumper->read(), 4))
253 		m_acia_upper->write_rxc(state);
254 	if (!BIT(m_tx_rate_lower_jumper->read(), 4))
255 		m_acia_lower->write_txc(state);
256 	if (!BIT(m_rx_rate_lower_jumper->read(), 4))
257 		m_acia_lower->write_rxc(state);
258 }
259 
260 
261 // device type definition
262 DEFINE_DEVICE_TYPE_PRIVATE(SS50_MPS2, ss50_card_interface, ss50_mps2_device, "ss50_mps2", "MP-S2 Dual Serial Interface")
263