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