1 /*
2 * vic20cartmem.c -- VIC20 Cartridge memory handling.
3 *
4 * Written by
5 * Daniel Kahlin <daniel@kahlin.net>
6 *
7 * This file is part of VICE, the Versatile Commodore Emulator.
8 * See README for copyright notice.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 * 02111-1307 USA.
24 *
25 */
26
27 #include "vice.h"
28
29 #include <stdio.h>
30
31 #include "behrbonz.h"
32 #include "c64acia.h"
33 #include "cartridge.h"
34 #include "digimax.h"
35 #include "ds12c887rtc.h"
36 #include "finalexpansion.h"
37 #include "georam.h"
38 #include "ioramcart.h"
39 #include "megacart.h"
40 #include "machine.h"
41 #include "mem.h"
42 #include "resources.h"
43 #include "sfx_soundexpander.h"
44 #include "sfx_soundsampler.h"
45 #include "sidcart.h"
46 #ifdef HAVE_RAWNET
47 #define CARTRIDGE_INCLUDE_PRIVATE_API
48 #define CARTRIDGE_INCLUDE_PUBLIC_API
49 #include "ethernetcart.h"
50 #undef CARTRIDGE_INCLUDE_PRIVATE_API
51 #undef CARTRIDGE_INCLUDE_PUBLIC_API
52 #endif
53 #include "types.h"
54 #include "ultimem.h"
55 #include "vic20mem.h"
56 #include "vic20cart.h"
57 #include "vic20cartmem.h"
58 #include "vic20-generic.h"
59 #include "vic20-ieee488.h"
60 #include "vic20-midi.h"
61 #include "vic-fp.h"
62
63
64 /* ------------------------------------------------------------------------- */
65
66 int mem_cartridge_type = CARTRIDGE_NONE;
67 int mem_cart_blocks = 0;
68
69 /* ------------------------------------------------------------------------- */
70
cartridge_read_ram123(uint16_t addr)71 uint8_t cartridge_read_ram123(uint16_t addr)
72 {
73 switch (mem_cartridge_type) {
74 case CARTRIDGE_VIC20_GENERIC:
75 vic20_cpu_last_data = generic_ram123_read(addr);
76 break;
77 case CARTRIDGE_VIC20_UM:
78 vic20_cpu_last_data = vic_um_ram123_read(addr);
79 break;
80 case CARTRIDGE_VIC20_FP:
81 vic20_cpu_last_data = vic_fp_ram123_read(addr);
82 break;
83 case CARTRIDGE_VIC20_MEGACART:
84 vic20_cpu_last_data = megacart_ram123_read(addr);
85 break;
86 case CARTRIDGE_VIC20_FINAL_EXPANSION:
87 vic20_cpu_last_data = finalexpansion_ram123_read(addr);
88 break;
89 default:
90 vic20_cpu_last_data = vic20_v_bus_last_data;
91 break;
92 }
93 vic20_mem_v_bus_read(addr);
94 return vic20_cpu_last_data;
95 }
96
cartridge_peek_ram123(uint16_t addr)97 uint8_t cartridge_peek_ram123(uint16_t addr)
98 {
99 switch (mem_cartridge_type) {
100 case CARTRIDGE_VIC20_GENERIC:
101 return generic_ram123_read(addr);
102 case CARTRIDGE_VIC20_UM:
103 return vic_um_ram123_read(addr);
104 case CARTRIDGE_VIC20_FP:
105 return vic_fp_ram123_read(addr);
106 case CARTRIDGE_VIC20_MEGACART:
107 return megacart_ram123_read(addr);
108 case CARTRIDGE_VIC20_FINAL_EXPANSION:
109 return finalexpansion_ram123_read(addr);
110 default:
111 break;
112 }
113 return 0;
114 }
115
cartridge_store_ram123(uint16_t addr,uint8_t value)116 void cartridge_store_ram123(uint16_t addr, uint8_t value)
117 {
118 vic20_cpu_last_data = value;
119 switch (mem_cartridge_type) {
120 case CARTRIDGE_VIC20_GENERIC:
121 generic_ram123_store(addr, value);
122 break;
123 case CARTRIDGE_VIC20_UM:
124 vic_um_ram123_store(addr, value);
125 break;
126 case CARTRIDGE_VIC20_FP:
127 vic_fp_ram123_store(addr, value);
128 break;
129 case CARTRIDGE_VIC20_MEGACART:
130 megacart_ram123_store(addr, value);
131 break;
132 case CARTRIDGE_VIC20_FINAL_EXPANSION:
133 finalexpansion_ram123_store(addr, value);
134 break;
135 }
136 vic20_mem_v_bus_store(addr);
137 }
138
cartridge_read_blk1(uint16_t addr)139 uint8_t cartridge_read_blk1(uint16_t addr)
140 {
141 switch (mem_cartridge_type) {
142 case CARTRIDGE_VIC20_BEHRBONZ:
143 vic20_cpu_last_data = behrbonz_blk13_read(addr);
144 break;
145 case CARTRIDGE_VIC20_GENERIC:
146 vic20_cpu_last_data = generic_blk1_read(addr);
147 break;
148 case CARTRIDGE_VIC20_UM:
149 vic20_cpu_last_data = vic_um_blk1_read(addr);
150 break;
151 case CARTRIDGE_VIC20_FP:
152 vic20_cpu_last_data = vic_fp_blk1_read(addr);
153 break;
154 case CARTRIDGE_VIC20_MEGACART:
155 vic20_cpu_last_data = megacart_blk123_read(addr);
156 break;
157 case CARTRIDGE_VIC20_FINAL_EXPANSION:
158 vic20_cpu_last_data = finalexpansion_blk1_read(addr);
159 break;
160 }
161 return vic20_cpu_last_data;
162 }
163
cartridge_peek_blk1(uint16_t addr)164 uint8_t cartridge_peek_blk1(uint16_t addr)
165 {
166 switch (mem_cartridge_type) {
167 case CARTRIDGE_VIC20_BEHRBONZ:
168 return behrbonz_blk13_read(addr);
169 case CARTRIDGE_VIC20_GENERIC:
170 return generic_blk1_read(addr);
171 case CARTRIDGE_VIC20_UM:
172 return vic_um_blk1_read(addr);
173 case CARTRIDGE_VIC20_FP:
174 return vic_fp_blk1_read(addr);
175 case CARTRIDGE_VIC20_MEGACART:
176 return megacart_blk123_read(addr);
177 case CARTRIDGE_VIC20_FINAL_EXPANSION:
178 return finalexpansion_blk1_read(addr);
179 }
180 return 0;
181 }
182
cartridge_store_blk1(uint16_t addr,uint8_t value)183 void cartridge_store_blk1(uint16_t addr, uint8_t value)
184 {
185 vic20_cpu_last_data = value;
186 switch (mem_cartridge_type) {
187 case CARTRIDGE_VIC20_GENERIC:
188 generic_blk1_store(addr, value);
189 break;
190 case CARTRIDGE_VIC20_UM:
191 vic_um_blk1_store(addr, value);
192 break;
193 case CARTRIDGE_VIC20_FP:
194 vic_fp_blk1_store(addr, value);
195 break;
196 case CARTRIDGE_VIC20_MEGACART:
197 megacart_blk123_store(addr, value);
198 break;
199 case CARTRIDGE_VIC20_FINAL_EXPANSION:
200 finalexpansion_blk1_store(addr, value);
201 break;
202 }
203 }
204
cartridge_read_blk2(uint16_t addr)205 uint8_t cartridge_read_blk2(uint16_t addr)
206 {
207 switch (mem_cartridge_type) {
208 case CARTRIDGE_VIC20_BEHRBONZ:
209 vic20_cpu_last_data = behrbonz_blk25_read(addr);
210 break;
211 case CARTRIDGE_VIC20_GENERIC:
212 vic20_cpu_last_data = generic_blk2_read(addr);
213 break;
214 case CARTRIDGE_VIC20_UM:
215 vic20_cpu_last_data = vic_um_blk23_read(addr);
216 break;
217 case CARTRIDGE_VIC20_FP:
218 vic20_cpu_last_data = vic_fp_blk23_read(addr);
219 break;
220 case CARTRIDGE_VIC20_MEGACART:
221 vic20_cpu_last_data = megacart_blk123_read(addr);
222 break;
223 case CARTRIDGE_VIC20_FINAL_EXPANSION:
224 vic20_cpu_last_data = finalexpansion_blk2_read(addr);
225 break;
226 }
227 return vic20_cpu_last_data;
228 }
229
cartridge_peek_blk2(uint16_t addr)230 uint8_t cartridge_peek_blk2(uint16_t addr)
231 {
232 switch (mem_cartridge_type) {
233 case CARTRIDGE_VIC20_BEHRBONZ:
234 return behrbonz_blk25_read(addr);
235 case CARTRIDGE_VIC20_GENERIC:
236 return generic_blk2_read(addr);
237 case CARTRIDGE_VIC20_UM:
238 return vic_um_blk23_read(addr);
239 case CARTRIDGE_VIC20_FP:
240 return vic_fp_blk23_read(addr);
241 case CARTRIDGE_VIC20_MEGACART:
242 return megacart_blk123_read(addr);
243 case CARTRIDGE_VIC20_FINAL_EXPANSION:
244 return finalexpansion_blk2_read(addr);
245 }
246 return 0;
247 }
248
cartridge_store_blk2(uint16_t addr,uint8_t value)249 void cartridge_store_blk2(uint16_t addr, uint8_t value)
250 {
251 vic20_cpu_last_data = value;
252 switch (mem_cartridge_type) {
253 case CARTRIDGE_VIC20_GENERIC:
254 generic_blk2_store(addr, value);
255 break;
256 case CARTRIDGE_VIC20_UM:
257 vic_um_blk23_store(addr, value);
258 break;
259 case CARTRIDGE_VIC20_FP:
260 vic_fp_blk23_store(addr, value);
261 break;
262 case CARTRIDGE_VIC20_MEGACART:
263 megacart_blk123_store(addr, value);
264 break;
265 case CARTRIDGE_VIC20_FINAL_EXPANSION:
266 finalexpansion_blk2_store(addr, value);
267 break;
268 }
269 }
270
cartridge_read_blk3(uint16_t addr)271 uint8_t cartridge_read_blk3(uint16_t addr)
272 {
273 switch (mem_cartridge_type) {
274 case CARTRIDGE_VIC20_BEHRBONZ:
275 vic20_cpu_last_data = behrbonz_blk13_read(addr);
276 break;
277 case CARTRIDGE_VIC20_GENERIC:
278 vic20_cpu_last_data = generic_blk3_read(addr);
279 break;
280 case CARTRIDGE_VIC20_UM:
281 vic20_cpu_last_data = vic_um_blk23_read(addr);
282 break;
283 case CARTRIDGE_VIC20_FP:
284 vic20_cpu_last_data = vic_fp_blk23_read(addr);
285 break;
286 case CARTRIDGE_VIC20_MEGACART:
287 vic20_cpu_last_data = megacart_blk123_read(addr);
288 break;
289 case CARTRIDGE_VIC20_FINAL_EXPANSION:
290 vic20_cpu_last_data = finalexpansion_blk3_read(addr);
291 break;
292 }
293 return vic20_cpu_last_data;
294 }
295
cartridge_peek_blk3(uint16_t addr)296 uint8_t cartridge_peek_blk3(uint16_t addr)
297 {
298 switch (mem_cartridge_type) {
299 case CARTRIDGE_VIC20_BEHRBONZ:
300 return behrbonz_blk13_read(addr);
301 case CARTRIDGE_VIC20_GENERIC:
302 return generic_blk3_read(addr);
303 case CARTRIDGE_VIC20_UM:
304 return vic_um_blk23_read(addr);
305 case CARTRIDGE_VIC20_FP:
306 return vic_fp_blk23_read(addr);
307 case CARTRIDGE_VIC20_MEGACART:
308 return megacart_blk123_read(addr);
309 case CARTRIDGE_VIC20_FINAL_EXPANSION:
310 return finalexpansion_blk3_read(addr);
311 }
312 return 0;
313 }
314
cartridge_store_blk3(uint16_t addr,uint8_t value)315 void cartridge_store_blk3(uint16_t addr, uint8_t value)
316 {
317 vic20_cpu_last_data = value;
318 switch (mem_cartridge_type) {
319 case CARTRIDGE_VIC20_GENERIC:
320 generic_blk3_store(addr, value);
321 break;
322 case CARTRIDGE_VIC20_UM:
323 vic_um_blk23_store(addr, value);
324 break;
325 case CARTRIDGE_VIC20_FP:
326 vic_fp_blk23_store(addr, value);
327 break;
328 case CARTRIDGE_VIC20_MEGACART:
329 megacart_blk123_store(addr, value);
330 break;
331 case CARTRIDGE_VIC20_FINAL_EXPANSION:
332 finalexpansion_blk3_store(addr, value);
333 break;
334 }
335 }
336
cartridge_read_blk5(uint16_t addr)337 uint8_t cartridge_read_blk5(uint16_t addr)
338 {
339 switch (mem_cartridge_type) {
340 case CARTRIDGE_VIC20_BEHRBONZ:
341 vic20_cpu_last_data = behrbonz_blk25_read(addr);
342 break;
343 case CARTRIDGE_VIC20_GENERIC:
344 vic20_cpu_last_data = generic_blk5_read(addr);
345 break;
346 case CARTRIDGE_VIC20_UM:
347 vic20_cpu_last_data = vic_um_blk5_read(addr);
348 break;
349 case CARTRIDGE_VIC20_FP:
350 vic20_cpu_last_data = vic_fp_blk5_read(addr);
351 break;
352 case CARTRIDGE_VIC20_MEGACART:
353 vic20_cpu_last_data = megacart_blk5_read(addr);
354 break;
355 case CARTRIDGE_VIC20_FINAL_EXPANSION:
356 vic20_cpu_last_data = finalexpansion_blk5_read(addr);
357 break;
358 }
359 return vic20_cpu_last_data;
360 }
361
cartridge_peek_blk5(uint16_t addr)362 uint8_t cartridge_peek_blk5(uint16_t addr)
363 {
364 switch (mem_cartridge_type) {
365 case CARTRIDGE_VIC20_BEHRBONZ:
366 return behrbonz_blk25_read(addr);
367 case CARTRIDGE_VIC20_GENERIC:
368 return generic_blk5_read(addr);
369 case CARTRIDGE_VIC20_UM:
370 return vic_um_blk5_read(addr);
371 case CARTRIDGE_VIC20_FP:
372 return vic_fp_blk5_read(addr);
373 case CARTRIDGE_VIC20_MEGACART:
374 return megacart_blk5_read(addr);
375 case CARTRIDGE_VIC20_FINAL_EXPANSION:
376 return finalexpansion_blk5_read(addr);
377 }
378 return 0;
379 }
380
cartridge_store_blk5(uint16_t addr,uint8_t value)381 void cartridge_store_blk5(uint16_t addr, uint8_t value)
382 {
383 vic20_cpu_last_data = value;
384 switch (mem_cartridge_type) {
385 case CARTRIDGE_VIC20_GENERIC:
386 generic_blk5_store(addr, value);
387 break;
388 case CARTRIDGE_VIC20_UM:
389 vic_um_blk5_store(addr, value);
390 break;
391 case CARTRIDGE_VIC20_FP:
392 vic_fp_blk5_store(addr, value);
393 break;
394 case CARTRIDGE_VIC20_MEGACART:
395 megacart_blk5_store(addr, value);
396 break;
397 case CARTRIDGE_VIC20_FINAL_EXPANSION:
398 finalexpansion_blk5_store(addr, value);
399 break;
400 }
401 }
402
403 /* ------------------------------------------------------------------------- */
404
cartridge_init(void)405 void cartridge_init(void)
406 {
407 behrbonz_init();
408 generic_init();
409 megacart_init();
410 finalexpansion_init();
411 vic_fp_init();
412 #ifdef HAVE_RAWNET
413 ethernetcart_init();
414 #endif
415 aciacart_init();
416 georam_init();
417 }
418
cartridge_reset(void)419 void cartridge_reset(void)
420 {
421 switch (mem_cartridge_type) {
422 case CARTRIDGE_VIC20_BEHRBONZ:
423 behrbonz_reset();
424 break;
425 case CARTRIDGE_VIC20_GENERIC:
426 generic_reset();
427 break;
428 case CARTRIDGE_VIC20_UM:
429 vic_um_reset();
430 break;
431 case CARTRIDGE_VIC20_FP:
432 vic_fp_reset();
433 break;
434 case CARTRIDGE_VIC20_MEGACART:
435 megacart_reset();
436 break;
437 case CARTRIDGE_VIC20_FINAL_EXPANSION:
438 finalexpansion_reset();
439 break;
440 }
441 #ifdef HAVE_RAWNET
442 if (ethernetcart_cart_enabled()) {
443 ethernetcart_reset();
444 }
445 #endif
446 if (aciacart_cart_enabled()) {
447 aciacart_reset();
448 }
449 if (digimax_cart_enabled()) {
450 digimax_reset();
451 }
452 if (ds12c887rtc_cart_enabled()) {
453 ds12c887rtc_reset();
454 }
455 if (sfx_soundexpander_cart_enabled()) {
456 sfx_soundexpander_reset();
457 }
458 if (sfx_soundsampler_cart_enabled()) {
459 sfx_soundsampler_reset();
460 }
461 if (georam_cart_enabled()) {
462 georam_reset();
463 }
464 }
465
cartridge_attach(int type,uint8_t * rawcart)466 void cartridge_attach(int type, uint8_t *rawcart)
467 {
468 int cartridge_reset;
469
470 mem_cartridge_type = type;
471 #if 0
472 switch (type) {
473 case CARTRIDGE_VIC20_GENERIC:
474 generic_config_setup(rawcart);
475 break;
476 case CARTRIDGE_VIC20_UM:
477 vic_um_config_setup(rawcart);
478 break;
479 case CARTRIDGE_VIC20_FP:
480 vic_fp_config_setup(rawcart);
481 break;
482 case CARTRIDGE_VIC20_MEGACART:
483 megacart_config_setup(rawcart);
484 break;
485 case CARTRIDGE_VIC20_FINAL_EXPANSION:
486 finalexpansion_config_setup(rawcart);
487 break;
488 default:
489 mem_cartridge_type = CARTRIDGE_NONE;
490 }
491 #endif
492
493 resources_get_int("CartridgeReset", &cartridge_reset);
494
495 if (cartridge_reset != 0) {
496 /* "Turn off machine before inserting cartridge" */
497 machine_trigger_reset(MACHINE_RESET_MODE_HARD);
498 }
499 }
500
cart_detach_all(void)501 static void cart_detach_all(void)
502 {
503 /* vic20 carts */
504 behrbonz_detach();
505 generic_detach();
506 finalexpansion_detach();
507 ioramcart_io2_detach();
508 ioramcart_io3_detach();
509 megacart_detach();
510 vic_um_detach();
511 vic20_ieee488_detach();
512 #ifdef HAVE_MIDI
513 vic20_midi_detach();
514 #endif
515 sidcart_detach();
516 vic_fp_detach();
517
518 /* c64 through mascuerade carts */
519 aciacart_detach();
520 digimax_detach();
521 ds12c887rtc_detach();
522 georam_detach();
523 sfx_soundexpander_detach();
524 sfx_soundsampler_detach();
525 #ifdef HAVE_RAWNET
526 ethernetcart_detach();
527 #endif
528 }
529
cartridge_detach(int type)530 void cartridge_detach(int type)
531 {
532 int cartridge_reset;
533
534 switch (type) {
535 case -1:
536 cart_detach_all();
537 break;
538 case CARTRIDGE_VIC20_BEHRBONZ:
539 behrbonz_detach();
540 break;
541 case CARTRIDGE_VIC20_GENERIC:
542 generic_detach();
543 break;
544 case CARTRIDGE_VIC20_UM:
545 vic_um_detach();
546 break;
547 case CARTRIDGE_VIC20_FP:
548 vic_fp_detach();
549 break;
550 case CARTRIDGE_VIC20_MEGACART:
551 megacart_detach();
552 break;
553 case CARTRIDGE_VIC20_FINAL_EXPANSION:
554 finalexpansion_detach();
555 break;
556 }
557 mem_cartridge_type = CARTRIDGE_NONE;
558 /* this is probably redundant as it is also performed by the
559 local detach functions. */
560 mem_cart_blocks = 0;
561 mem_initialize_memory();
562
563 resources_get_int("CartridgeReset", &cartridge_reset);
564
565 if (cartridge_reset != 0) {
566 /* "Turn off machine before removing cartridge" */
567 machine_trigger_reset(MACHINE_RESET_MODE_HARD);
568 }
569 }
570
571 /* ------------------------------------------------------------------------- */
572
cartridge_sound_chip_init(void)573 void cartridge_sound_chip_init(void)
574 {
575 digimax_sound_chip_init();
576 sfx_soundexpander_sound_chip_init();
577 sfx_soundsampler_sound_chip_init();
578 }
579