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