1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4
5 IDE64 v4.1 cartridge emulation
6
7 **********************************************************************/
8
9 /*
10
11 TODO:
12
13 - fast loader does not work with 1541
14 - IDE unknown command (E8)
15 - FT245 USB
16 - CompactFlash slot
17 - ShortBus (ETH64, DUART, DigiMAX, ETFE)
18 - clock port (ETH64 II, RR-Net, SilverSurfer, MP3@64)
19
20 */
21
22 #include "emu.h"
23 #include "ide64.h"
24
25
26
27 //**************************************************************************
28 // MACROS/CONSTANTS
29 //**************************************************************************
30
31 #define AT29C010A_TAG "u3"
32 #define DS1302_TAG "u4"
33 #define FT245R_TAG "u21"
34 #define ATA_TAG "ata"
35
36
37
38 //**************************************************************************
39 // DEVICE DEFINITIONS
40 //**************************************************************************
41
42 DEFINE_DEVICE_TYPE(C64_IDE64, c64_ide64_cartridge_device, "c64_ide64", "C64 IDE64 cartridge")
43
44
45 //-------------------------------------------------
46 // device_add_mconfig - add device configuration
47 //-------------------------------------------------
48
device_add_mconfig(machine_config & config)49 void c64_ide64_cartridge_device::device_add_mconfig(machine_config &config)
50 {
51 ATMEL_29C010(config, m_flash_rom);
52 DS1302(config, m_rtc, 32.768_kHz_XTAL);
53
54 ATA_INTERFACE(config, m_ata).options(ata_devices, "hdd", nullptr, false);
55 }
56
57
58 //-------------------------------------------------
59 // INPUT_PORTS( c64_ide64 )
60 //-------------------------------------------------
61
62 static INPUT_PORTS_START( c64_ide64 )
63 PORT_START("JP1")
64 PORT_DIPNAME( 0x01, 0x01, "Flash ROM Write Protect" )
65 PORT_DIPSETTING( 0x00, "Disabled" )
66 PORT_DIPSETTING( 0x01, "Enabled" )
67 INPUT_PORTS_END
68
69
70 //-------------------------------------------------
71 // input_ports - device-specific input ports
72 //-------------------------------------------------
73
device_input_ports() const74 ioport_constructor c64_ide64_cartridge_device::device_input_ports() const
75 {
76 return INPUT_PORTS_NAME( c64_ide64 );
77 }
78
79
80
81 //**************************************************************************
82 // LIVE DEVICE
83 //**************************************************************************
84
85 //-------------------------------------------------
86 // c64_ide64_cartridge_device - constructor
87 //-------------------------------------------------
88
c64_ide64_cartridge_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)89 c64_ide64_cartridge_device::c64_ide64_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
90 device_t(mconfig, C64_IDE64, tag, owner, clock),
91 device_c64_expansion_card_interface(mconfig, *this),
92 m_flash_rom(*this, AT29C010A_TAG),
93 m_rtc(*this, DS1302_TAG),
94 m_ata(*this, ATA_TAG),
95 m_jp1(*this, "JP1"),
96 m_ram(*this, "ram"), m_bank(0), m_ata_data(0), m_wp(0), m_enable(0)
97 {
98 }
99
100
101 //-------------------------------------------------
102 // device_start - device-specific startup
103 //-------------------------------------------------
104
device_start()105 void c64_ide64_cartridge_device::device_start()
106 {
107 // allocate memory
108 m_ram.allocate(0x8000);
109
110 // state saving
111 save_item(NAME(m_bank));
112 save_item(NAME(m_ata_data));
113 save_item(NAME(m_enable));
114 }
115
116
117 //-------------------------------------------------
118 // device_reset - device-specific reset
119 //-------------------------------------------------
120
device_reset()121 void c64_ide64_cartridge_device::device_reset()
122 {
123 m_bank = 0;
124
125 m_enable = 1;
126
127 m_wp = m_jp1->read();
128 m_game = !m_wp;
129 m_exrom = !m_wp;
130 }
131
132
133 //-------------------------------------------------
134 // c64_cd_r - cartridge data read
135 //-------------------------------------------------
136
c64_cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)137 uint8_t c64_ide64_cartridge_device::c64_cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
138 {
139 if (!m_enable) return data;
140
141 int rom_oe = 1, ram_oe = 1;
142
143 if (!m_game && m_exrom && sphi2 && ba)
144 {
145 if (offset >= 0x1000 && offset < 0x8000)
146 {
147 ram_oe = 0;
148 }
149 else if (offset >= 0x8000 && offset < 0xc000)
150 {
151 rom_oe = 0;
152 }
153 else if (offset >= 0xc000 && offset < 0xd000)
154 {
155 ram_oe = 0;
156 }
157 }
158
159 if (!roml || !romh)
160 {
161 rom_oe = 0;
162 }
163
164 if (!io1 && sphi2 && ba)
165 {
166 // 0x20-0x2f IDE
167 // 0x30-0x37 I/O
168 // 0x5d-0x5e FT245
169 // 0x5f-0x5f DS1302
170 // 0x60-0xff ROM
171
172 uint8_t io1_offset = offset & 0xff;
173
174 if (io1_offset >= 0x20 && io1_offset < 0x28)
175 {
176 m_ata_data = m_ata->cs0_r(offset & 0x07);
177
178 data = m_ata_data & 0xff;
179 }
180 else if (io1_offset >= 0x28 && io1_offset < 0x30)
181 {
182 m_ata_data = m_ata->cs1_r(offset & 0x07);
183
184 data = m_ata_data & 0xff;
185 }
186 else if (io1_offset == 0x31)
187 {
188 data = m_ata_data >> 8;
189 }
190 else if (io1_offset == 0x32)
191 {
192 /*
193
194 bit description
195
196 0 EXROM
197 1 GAME
198 2 A14
199 3 A15
200 4 A16
201 5 v4.x
202 6
203 7
204
205 */
206
207 data = 0x20 | (m_bank << 2) | (m_game << 1) | m_exrom;
208 }
209 else if (io1_offset == 0x5f)
210 {
211 m_rtc->sclk_w(0);
212
213 data &= ~0x01;
214 data |= m_rtc->io_r();
215
216 m_rtc->sclk_w(1);
217 }
218 else if (io1_offset >= 0x60)
219 {
220 rom_oe = 0;
221 }
222 }
223
224 if (!rom_oe)
225 {
226 offs_t addr = (m_bank << 14) | (offset & 0x3fff);
227
228 data = m_flash_rom->read(addr);
229 }
230 else if (!ram_oe)
231 {
232 data = m_ram[offset & 0x7fff];
233 }
234
235 return data;
236 }
237
238
239 //-------------------------------------------------
240 // c64_cd_w - cartridge data write
241 //-------------------------------------------------
242
c64_cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)243 void c64_ide64_cartridge_device::c64_cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
244 {
245 if (!m_enable) return;
246
247 if (!m_game && m_exrom)
248 {
249 if (offset >= 0x1000 && offset < 0x8000)
250 {
251 m_ram[offset & 0x7fff] = data;
252 }
253 else if (offset >= 0xc000 && offset < 0xd000)
254 {
255 m_ram[offset & 0x7fff] = data;
256 }
257 }
258
259 if ((offset >= 0x8000 && offset < 0xc000) && !m_wp)
260 {
261 offs_t addr = (m_bank << 14) | (offset & 0x3fff);
262 m_flash_rom->write(addr, data);
263 }
264
265 if (!io1)
266 {
267 // 0x20-0x2f IDE
268 // 0x30-0x37 I/O
269 // 0x5d-0x5e FT245
270 // 0x5f-0x5f DS1302
271 // 0x60-0xff ROM
272
273 uint8_t io1_offset = offset & 0xff;
274
275 if (io1_offset >= 0x20 && io1_offset < 0x28)
276 {
277 m_ata_data = (m_ata_data & 0xff00) | data;
278
279 m_ata->cs0_w(offset & 0x07, m_ata_data);
280 }
281 else if (io1_offset >= 0x28 && io1_offset < 0x30)
282 {
283 m_ata_data = (m_ata_data & 0xff00) | data;
284
285 m_ata->cs1_w(offset & 0x07, m_ata_data);
286 }
287 else if (io1_offset == 0x31)
288 {
289 m_ata_data = (data << 8) | (m_ata_data & 0xff);
290 }
291 else if (io1_offset == 0x5f)
292 {
293 m_rtc->sclk_w(0);
294
295 m_rtc->io_w(BIT(data, 0));
296
297 m_rtc->sclk_w(1);
298 }
299 else if (io1_offset >= 0x60 && io1_offset < 0x68)
300 {
301 m_bank = offset & 0x07;
302 }
303 else if (io1_offset == 0xfb)
304 {
305 /*
306
307 bit description
308
309 0 disable cartridge
310 1 RTC CE
311 2
312 3
313 4
314 5
315 6
316 7
317
318 */
319
320 m_enable = !BIT(data, 0);
321 m_rtc->ce_w(BIT(data, 1));
322 }
323 else if (io1_offset >= 0xfc)
324 {
325 m_game = BIT(offset, 0);
326 m_exrom = BIT(offset, 1);
327 }
328 }
329 }
330
331
332 //-------------------------------------------------
333 // c64_game_r - GAME read
334 //-------------------------------------------------
335
c64_game_r(offs_t offset,int sphi2,int ba,int rw)336 int c64_ide64_cartridge_device::c64_game_r(offs_t offset, int sphi2, int ba, int rw)
337 {
338 return (sphi2 && ba) ? m_game : 1;
339 }
340
341
342 //-------------------------------------------------
343 // c64_exrom_r - EXROM read
344 //-------------------------------------------------
345
c64_exrom_r(offs_t offset,int sphi2,int ba,int rw)346 int c64_ide64_cartridge_device::c64_exrom_r(offs_t offset, int sphi2, int ba, int rw)
347 {
348 return (sphi2 && ba) ? m_exrom : 1;
349 }
350