1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4
5 CMD Turbo232 RS-232 cartridge emulation
6
7 **********************************************************************/
8
9 /*
10
11 http://ar.c64.org/wiki/Turbo232_Programming.txt
12
13 */
14
15 #include "emu.h"
16 #include "turbo232.h"
17
18
19
20 //**************************************************************************
21 // MACROS/CONSTANTS
22 //**************************************************************************
23
24 #define MOS6551_TAG "mos6551"
25 #define RS232_TAG "rs232"
26
27
28
29 //**************************************************************************
30 // DEVICE DEFINITIONS
31 //**************************************************************************
32
33 DEFINE_DEVICE_TYPE(C64_TURBO232, c64_turbo232_cartridge_device, "c64_turbo232", "C64 Turbo232 cartridge")
34
35
36 //-------------------------------------------------
37 // device_add_mconfig - add device configuration
38 //-------------------------------------------------
39
device_add_mconfig(machine_config & config)40 void c64_turbo232_cartridge_device::device_add_mconfig(machine_config &config)
41 {
42 MOS6551(config, m_acia, 0);
43 m_acia->set_xtal(3.6864_MHz_XTAL);
44 m_acia->irq_handler().set(FUNC(c64_turbo232_cartridge_device::acia_irq_w));
45 m_acia->txd_handler().set(RS232_TAG, FUNC(rs232_port_device::write_txd));
46
47 rs232_port_device &rs232(RS232_PORT(config, RS232_TAG, default_rs232_devices, nullptr));
48 rs232.rxd_handler().set(m_acia, FUNC(mos6551_device::write_rxd));
49 rs232.dcd_handler().set(m_acia, FUNC(mos6551_device::write_dcd));
50 rs232.dsr_handler().set(m_acia, FUNC(mos6551_device::write_dsr));
51 rs232.cts_handler().set(m_acia, FUNC(mos6551_device::write_cts));
52 }
53
54
55 //-------------------------------------------------
56 // INPUT_PORTS( c64_turbo232 )
57 //-------------------------------------------------
58
59 static INPUT_PORTS_START( c64_turbo232 )
60 PORT_START("CS")
61 PORT_DIPNAME( 0x03, 0x01, "Base Address" )
62 PORT_DIPSETTING( 0x00, "$D700 (C128)" )
63 PORT_DIPSETTING( 0x01, "$DE00" )
64 PORT_DIPSETTING( 0x02, "$DF00" )
65
66 PORT_START("IRQ")
67 PORT_DIPNAME( 0x01, 0x01, "Interrupt" )
68 PORT_DIPSETTING( 0x00, "IRQ" )
69 PORT_DIPSETTING( 0x01, "NMI" )
70 INPUT_PORTS_END
71
72
73 //-------------------------------------------------
74 // input_ports - device-specific input ports
75 //-------------------------------------------------
76
device_input_ports() const77 ioport_constructor c64_turbo232_cartridge_device::device_input_ports() const
78 {
79 return INPUT_PORTS_NAME( c64_turbo232 );
80 }
81
82
83
84 //**************************************************************************
85 // LIVE DEVICE
86 //**************************************************************************
87
88 //-------------------------------------------------
89 // c64_turbo232_cartridge_device - constructor
90 //-------------------------------------------------
91
c64_turbo232_cartridge_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)92 c64_turbo232_cartridge_device::c64_turbo232_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
93 device_t(mconfig, C64_TURBO232, tag, owner, clock),
94 device_c64_expansion_card_interface(mconfig, *this),
95 m_acia(*this, MOS6551_TAG),
96 m_rs232(*this, RS232_TAG),
97 m_io_cs(*this, "CS"),
98 m_io_irq(*this, "IRQ"), m_cs(0), m_irq(0), m_es(0)
99 {
100 }
101
102
103 //-------------------------------------------------
104 // device_start - device-specific startup
105 //-------------------------------------------------
106
device_start()107 void c64_turbo232_cartridge_device::device_start()
108 {
109 }
110
111
112 //-------------------------------------------------
113 // device_reset - device-specific reset
114 //-------------------------------------------------
115
device_reset()116 void c64_turbo232_cartridge_device::device_reset()
117 {
118 m_acia->reset();
119
120 m_cs = m_io_cs->read();
121 m_irq = m_io_irq->read();
122
123 m_es = 0;
124 }
125
126
127 //-------------------------------------------------
128 // c64_cd_r - cartridge data read
129 //-------------------------------------------------
130
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)131 uint8_t c64_turbo232_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
132 {
133 if (((m_cs == DE00) && !io1) || ((m_cs == DF00) && !io2) ||
134 ((m_cs == D700) && ((offset & 0xff00) == 0xd700)))
135 {
136 if (!(offset & 0xe0))
137 {
138 switch (offset & 0x07)
139 {
140 case 0: case 1: case 2: case 3:
141 data = m_acia->read(offset & 0x03);
142 break;
143
144 case 7:
145 data = m_es;
146 }
147 }
148 }
149
150 return data;
151 }
152
153
154 //-------------------------------------------------
155 // c64_cd_w - cartridge data write
156 //-------------------------------------------------
157
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)158 void c64_turbo232_cartridge_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
159 {
160 if (((m_cs == DE00) && !io1) || ((m_cs == DF00) && !io2) ||
161 ((m_cs == D700) && ((offset & 0xff00) == 0xd700)))
162 {
163 if (!(offset & 0xe0))
164 {
165 switch (offset & 0x07)
166 {
167 case 0: case 1: case 2:
168 m_acia->write(offset & 0x03, data);
169 break;
170
171 case 3:
172 m_acia->write(offset & 0x03, data);
173
174 if (data & 0x0f)
175 m_es &= ~ES_M;
176 else
177 m_es |= ES_M;
178 break;
179
180 case 7:
181 if (m_es & ES_M)
182 {
183 data = m_es;
184
185 switch (m_es & ES_S_MASK)
186 {
187 case ES_S_230400: m_acia->set_xtal(XTAL(3'686'400)); break;
188 case ES_S_115200: m_acia->set_xtal(XTAL(3'686'400)/2); break;
189 case ES_S_57600: m_acia->set_xtal(XTAL(3'686'400)/4); break;
190 case ES_S_UNDEFINED: m_acia->set_xtal(0); break;
191 }
192 }
193 }
194 }
195 }
196 }
197
198
199 //-------------------------------------------------
200 // acia_irq_w -
201 //-------------------------------------------------
202
WRITE_LINE_MEMBER(c64_turbo232_cartridge_device::acia_irq_w)203 WRITE_LINE_MEMBER( c64_turbo232_cartridge_device::acia_irq_w )
204 {
205 switch (m_irq)
206 {
207 case IRQ: m_slot->irq_w(state); break;
208 case NMI: m_slot->nmi_w(state); break;
209 }
210 }
211