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