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