1 // license:BSD-3-Clause
2 // copyright-holders:Curt Coder
3 /**********************************************************************
4 
5     Commodore 64 Expansion Port emulation
6 
7 **********************************************************************/
8 
9 #include "emu.h"
10 #include "exp.h"
11 
12 
13 
14 //**************************************************************************
15 //  DEVICE DEFINITIONS
16 //**************************************************************************
17 
18 DEFINE_DEVICE_TYPE(C64_EXPANSION_SLOT, c64_expansion_slot_device, "c64_expansion_slot", "C64 expansion port")
19 
20 
21 
22 //**************************************************************************
23 //  DEVICE C64_EXPANSION CARD INTERFACE
24 //**************************************************************************
25 
26 //-------------------------------------------------
27 //  device_c64_expansion_card_interface - constructor
28 //-------------------------------------------------
29 
device_c64_expansion_card_interface(const machine_config & mconfig,device_t & device)30 device_c64_expansion_card_interface::device_c64_expansion_card_interface(const machine_config &mconfig, device_t &device) :
31 	device_interface(device, "c64exp"),
32 	m_roml(*this, "roml"),
33 	m_romh(*this, "romh"),
34 	m_romx(*this, "romx"),
35 	m_nvram(*this, "nvram"),
36 	m_game(1),
37 	m_exrom(1)
38 {
39 	m_slot = dynamic_cast<c64_expansion_slot_device *>(device.owner());
40 }
41 
42 
43 //-------------------------------------------------
44 //  ~device_c64_expansion_card_interface - destructor
45 //-------------------------------------------------
46 
~device_c64_expansion_card_interface()47 device_c64_expansion_card_interface::~device_c64_expansion_card_interface()
48 {
49 }
50 
51 
52 
53 //**************************************************************************
54 //  LIVE DEVICE
55 //**************************************************************************
56 
57 //-------------------------------------------------
58 //  c64_expansion_slot_device - constructor
59 //-------------------------------------------------
60 
c64_expansion_slot_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)61 c64_expansion_slot_device::c64_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
62 	device_t(mconfig, C64_EXPANSION_SLOT, tag, owner, clock),
63 	device_single_card_slot_interface<device_c64_expansion_card_interface>(mconfig, *this),
64 	device_image_interface(mconfig, *this),
65 	m_read_dma_cd(*this),
66 	m_write_dma_cd(*this),
67 	m_write_irq(*this),
68 	m_write_nmi(*this),
69 	m_write_dma(*this),
70 	m_write_reset(*this), m_card(nullptr), m_hiram(0)
71 {
72 }
73 
74 
75 //-------------------------------------------------
76 //  device_start - device-specific startup
77 //-------------------------------------------------
78 
device_start()79 void c64_expansion_slot_device::device_start()
80 {
81 	m_card = get_card_device();
82 
83 	// resolve callbacks
84 	m_read_dma_cd.resolve_safe(0);
85 	m_write_dma_cd.resolve_safe();
86 	m_write_irq.resolve_safe();
87 	m_write_nmi.resolve_safe();
88 	m_write_dma.resolve_safe();
89 	m_write_reset.resolve_safe();
90 }
91 
92 
93 //-------------------------------------------------
94 //  device_reset - device-specific reset
95 //-------------------------------------------------
96 
device_reset()97 void c64_expansion_slot_device::device_reset()
98 {
99 }
100 
101 
102 //-------------------------------------------------
103 //  call_load -
104 //-------------------------------------------------
105 
call_load()106 image_init_result c64_expansion_slot_device::call_load()
107 {
108 	if (m_card)
109 	{
110 		size_t size;
111 
112 		if (!loaded_through_softlist())
113 		{
114 			size = length();
115 
116 			if (is_filetype("80"))
117 			{
118 				fread(m_card->m_roml, size);
119 				m_card->m_exrom = (0);
120 
121 				if (size == 0x4000)
122 				{
123 					m_card->m_game = 0;
124 				}
125 			}
126 			else if (is_filetype("a0"))
127 			{
128 				fread(m_card->m_romh, 0x2000);
129 
130 				m_card->m_exrom = 0;
131 				m_card->m_game = 0;
132 			}
133 			else if (is_filetype("e0"))
134 			{
135 				fread(m_card->m_romh, 0x2000);
136 
137 				m_card->m_game = 0;
138 			}
139 			else if (is_filetype("crt"))
140 			{
141 				size_t roml_size = 0;
142 				size_t romh_size = 0;
143 				int exrom = 1;
144 				int game = 1;
145 
146 				if (cbm_crt_read_header(image_core_file(), &roml_size, &romh_size, &exrom, &game))
147 				{
148 					uint8_t *roml = nullptr;
149 					uint8_t *romh = nullptr;
150 
151 					m_card->m_roml.allocate(roml_size);
152 					m_card->m_romh.allocate(romh_size);
153 
154 					if (roml_size) roml = m_card->m_roml;
155 					if (romh_size) romh = m_card->m_roml;
156 
157 					cbm_crt_read_data(image_core_file(), roml, romh);
158 				}
159 
160 				m_card->m_exrom = exrom;
161 				m_card->m_game = game;
162 			}
163 		}
164 		else
165 		{
166 			size = get_software_region_length("uprom");
167 
168 			if (size)
169 			{
170 				// Ultimax (VIC-10) cartridge
171 				load_software_region("lorom", m_card->m_roml);
172 				load_software_region("uprom", m_card->m_romh);
173 
174 				m_card->m_exrom = 1;
175 				m_card->m_game = 0;
176 			}
177 			else
178 			{
179 				// Commodore 64/128 cartridge
180 				load_software_region("roml", m_card->m_roml);
181 				load_software_region("romh", m_card->m_romh);
182 				load_software_region("romx", m_card->m_romx);
183 				load_software_region("nvram", m_card->m_nvram);
184 
185 				if (get_feature("exrom") != nullptr) m_card->m_exrom = atol(get_feature("exrom"));
186 				if (get_feature("game") != nullptr) m_card->m_game = atol(get_feature("game"));
187 			}
188 		}
189 	}
190 
191 	return image_init_result::PASS;
192 }
193 
194 
195 //-------------------------------------------------
196 //  get_default_card_software -
197 //-------------------------------------------------
198 
get_default_card_software(get_default_card_software_hook & hook) const199 std::string c64_expansion_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
200 {
201 	if (hook.image_file())
202 	{
203 		if (hook.is_filetype("crt"))
204 			return cbm_crt_get_card(*hook.image_file());
205 	}
206 
207 	return software_get_default_slot("standard");
208 }
209 
210 
211 //-------------------------------------------------
212 //  cd_r - cartridge data read
213 //-------------------------------------------------
214 
cd_r(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)215 uint8_t c64_expansion_slot_device::cd_r(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
216 {
217 	if (m_card != nullptr)
218 	{
219 		data = m_card->c64_cd_r(offset, data, sphi2, ba, roml, romh, io1, io2);
220 	}
221 
222 	return data;
223 }
224 
225 
226 //-------------------------------------------------
227 //  cd_w - cartridge data write
228 //-------------------------------------------------
229 
cd_w(offs_t offset,uint8_t data,int sphi2,int ba,int roml,int romh,int io1,int io2)230 void c64_expansion_slot_device::cd_w(offs_t offset, uint8_t data, int sphi2, int ba, int roml, int romh, int io1, int io2)
231 {
232 	if (m_card != nullptr)
233 	{
234 		m_card->c64_cd_w(offset, data, sphi2, ba, roml, romh, io1, io2);
235 	}
236 }
237 
238 
239 //-------------------------------------------------
240 //  game_r - GAME read
241 //-------------------------------------------------
242 
game_r(offs_t offset,int sphi2,int ba,int rw,int loram,int hiram)243 int c64_expansion_slot_device::game_r(offs_t offset, int sphi2, int ba, int rw, int loram, int hiram)
244 {
245 	int state = 1;
246 
247 	m_hiram = hiram;
248 	m_loram = loram;
249 
250 	if (m_card != nullptr)
251 	{
252 		state = m_card->c64_game_r(offset, sphi2, ba, rw);
253 	}
254 
255 	return state;
256 }
257 
258 
259 //-------------------------------------------------
260 //  exrom_r - EXROM read
261 //-------------------------------------------------
262 
exrom_r(offs_t offset,int sphi2,int ba,int rw,int loram,int hiram)263 int c64_expansion_slot_device::exrom_r(offs_t offset, int sphi2, int ba, int rw, int loram, int hiram)
264 {
265 	int state = 1;
266 
267 	m_hiram = hiram;
268 	m_loram = loram;
269 
270 	if (m_card != nullptr)
271 	{
272 		state = m_card->c64_exrom_r(offset, sphi2, ba, rw);
273 	}
274 
275 	return state;
276 }
277 
278 
set_passthrough()279 void c64_expansion_slot_device::set_passthrough()
280 {
281 	irq_callback().set(DEVICE_SELF_OWNER, FUNC(c64_expansion_slot_device::irq_w));
282 	nmi_callback().set(DEVICE_SELF_OWNER, FUNC(c64_expansion_slot_device::nmi_w));
283 	reset_callback().set(DEVICE_SELF_OWNER, FUNC(c64_expansion_slot_device::reset_w));
284 	cd_input_callback().set(DEVICE_SELF_OWNER, FUNC(c64_expansion_slot_device::dma_cd_r));
285 	cd_output_callback().set(DEVICE_SELF_OWNER, FUNC(c64_expansion_slot_device::dma_cd_w));
286 	dma_callback().set(DEVICE_SELF_OWNER, FUNC(c64_expansion_slot_device::dma_w));
287 }
288 
289 //-------------------------------------------------
290 //  SLOT_INTERFACE( c64_expansion_cards )
291 //-------------------------------------------------
292 
293 
294 // slot devices
295 #include "16kb.h"
296 #include "buscard.h"
297 #include "buscard2.h"
298 #include "c128_comal80.h"
299 #include "c128_partner.h"
300 #include "comal80.h"
301 #include "cpm.h"
302 #include "currah_speech.h"
303 #include "dela_ep256.h"
304 #include "dela_ep64.h"
305 #include "dela_ep7x8.h"
306 #include "dinamic.h"
307 #include "dqbb.h"
308 #include "easy_calc_result.h"
309 #include "easyflash.h"
310 #include "epyx_fast_load.h"
311 #include "exos.h"
312 #include "fcc.h"
313 #include "final.h"
314 #include "final3.h"
315 #include "fun_play.h"
316 #include "georam.h"
317 #include "ide64.h"
318 #include "ieee488.h"
319 #include "kingsoft.h"
320 #include "mach5.h"
321 #include "magic_desk.h"
322 #include "magic_formel.h"
323 #include "magic_voice.h"
324 #include "midi_maplin.h"
325 #include "midi_namesoft.h"
326 #include "midi_passport.h"
327 #include "midi_sci.h"
328 #include "midi_siel.h"
329 #include "mikro_assembler.h"
330 #include "multiscreen.h"
331 #include "music64.h"
332 #include "neoram.h"
333 #include "ocean.h"
334 #include "pagefox.h"
335 #include "partner.h"
336 #include "prophet64.h"
337 #include "ps64.h"
338 #include "reu.h"
339 #include "rex.h"
340 #include "rex_ep256.h"
341 #include "ross.h"
342 #include "sfx_sound_expander.h"
343 #include "silverrock.h"
344 #include "simons_basic.h"
345 #include "speakeasy.h"
346 #include "stardos.h"
347 #include "std.h"
348 #include "structured_basic.h"
349 #include "super_explode.h"
350 #include "super_games.h"
351 #include "supercpu.h"
352 #include "sw8k.h"
353 #include "swiftlink.h"
354 #include "system3.h"
355 #include "tdos.h"
356 #include "turbo232.h"
357 #include "vizastar.h"
358 #include "vw64.h"
359 #include "warp_speed.h"
360 #include "westermann.h"
361 #include "xl80.h"
362 #include "zaxxon.h"
363 
c64_expansion_cards(device_slot_interface & device)364 void c64_expansion_cards(device_slot_interface &device)
365 {
366 	device.option_add("16k", C64_16KB);
367 	device.option_add("cpm", C64_CPM);
368 	device.option_add("dqbb", C64_DQBB);
369 	device.option_add("easyflash", C64_EASYFLASH);
370 	device.option_add("georam", C64_GEORAM);
371 	device.option_add("ide64", C64_IDE64);
372 	device.option_add("midimap", C64_MIDI_MAPLIN);
373 	device.option_add("midins", C64_MIDI_NAMESOFT);
374 	device.option_add("midipp", C64_MIDI_PASSPORT);
375 	device.option_add("midisci", C64_MIDI_SCI);
376 	device.option_add("midisiel", C64_MIDI_SIEL);
377 	device.option_add("music64", C64_MUSIC64);
378 	device.option_add("neoram", C64_NEORAM);
379 	device.option_add("reu1700", C64_REU1700);
380 	device.option_add("reu1750", C64_REU1750);
381 	device.option_add("reu1764", C64_REU1764);
382 	device.option_add("sfxse", C64_SFX_SOUND_EXPANDER);
383 	device.option_add("speakez", C64_SPEAKEASY);
384 	device.option_add("supercpu", C64_SUPERCPU);
385 	device.option_add("swiftlink", C64_SWIFTLINK);
386 	device.option_add("turbo232", C64_TURBO232);
387 	device.option_add("buscard", C64_BUSCARD);
388 	device.option_add("buscard2", C64_BUSCARD2);
389 
390 	// the following need ROMs from the software list
391 	device.option_add_internal("standard", C64_STD);
392 	device.option_add_internal("comal80", C64_COMAL80);
393 	device.option_add_internal("c128_comal80", C128_COMAL80);
394 	device.option_add_internal("cs64", C64_CURRAH_SPEECH);
395 	device.option_add_internal("dela_ep256", C64_DELA_EP256);
396 	device.option_add_internal("ep64", C64_DELA_EP64);
397 	device.option_add_internal("ep7x8", C64_DELA_EP7X8);
398 	device.option_add_internal("dinamic", C64_DINAMIC);
399 	device.option_add_internal("easycalcres", C64_EASY_CALC_RESULT);
400 	device.option_add_internal("epyxfastload", C64_EPYX_FAST_LOAD);
401 	device.option_add_internal("exos", C64_EXOS);
402 	device.option_add_internal("fcc", C64_FCC);
403 	device.option_add_internal("final", C64_FINAL);
404 	device.option_add_internal("final3", C64_FINAL3);
405 	device.option_add_internal("fun_play", C64_FUN_PLAY);
406 	device.option_add_internal("ieee488", C64_IEEE488);
407 	device.option_add_internal("kingsoft", C64_KINGSOFT);
408 	device.option_add_internal("mach5", C64_MACH5);
409 	device.option_add_internal("magic_desk", C64_MAGIC_DESK);
410 	device.option_add_internal("magic_formel", C64_MAGIC_FORMEL);
411 	device.option_add_internal("magic_voice", C64_MAGIC_VOICE);
412 	device.option_add_internal("mikroasm", C64_MIKRO_ASSEMBLER);
413 	device.option_add_internal("multiscreen", C64_MULTISCREEN);
414 	device.option_add_internal("ocean", C64_OCEAN);
415 	device.option_add_internal("pagefox", C64_PAGEFOX);
416 	device.option_add_internal("partner", C64_PARTNER);
417 	device.option_add_internal("partner128", C128_PARTNER);
418 	device.option_add_internal("prophet64", C64_PROPHET64);
419 	device.option_add_internal("ps64", C64_PS64);
420 	device.option_add_internal("rex", C64_REX);
421 	device.option_add_internal("rex_ep256", C64_REX_EP256);
422 	device.option_add_internal("ross", C64_ROSS);
423 	device.option_add_internal("silverrock", C64_SILVERROCK);
424 	device.option_add_internal("simons_basic", C64_SIMONS_BASIC);
425 	device.option_add_internal("stardos", C64_STARDOS);
426 	device.option_add_internal("struct_basic", C64_STRUCTURED_BASIC);
427 	device.option_add_internal("super_explode", C64_SUPER_EXPLODE);
428 	device.option_add_internal("super_games", C64_SUPER_GAMES);
429 	device.option_add_internal("sw8k", C64_SW8K);
430 	device.option_add_internal("system3", C64_SYSTEM3);
431 	device.option_add_internal("tdos", C64_TDOS);
432 	device.option_add_internal("vizastar", C64_VIZASTAR);
433 	device.option_add_internal("vizawrite", C64_VW64);
434 	device.option_add_internal("warp_speed", C64_WARP_SPEED);
435 	device.option_add_internal("westermann", C64_WESTERMANN);
436 	device.option_add_internal("zaxxon", C64_ZAXXON);
437 	device.option_add_internal("xl80", C64_XL80);
438 }
439