1 /*
2  * menu_c64cart.c - Implementation of the C64/C128 cartridge settings menu for the SDL UI.
3  *
4  * Written by
5  *  Marco van den Heuvel <blackystardust68@yahoo.com>
6  *  Hannu Nuotio <hannu.nuotio@tut.fi>
7  *
8  * This file is part of VICE, the Versatile Commodore Emulator.
9  * See README for copyright notice.
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24  *  02111-1307  USA.
25  *
26  */
27 
28 #include "vice.h"
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include "c64cart.h"
35 #include "cartridge.h"
36 #include "cartio.h"
37 #include "clockport.h"
38 #include "keyboard.h"
39 #include "lib.h"
40 #include "machine.h"
41 #include "menu_common.h"
42 #include "menu_c64_common_expansions.h"
43 #include "menu_c64cart.h"
44 #include "resources.h"
45 #include "ui.h"
46 #include "uifilereq.h"
47 #include "uimenu.h"
48 
UI_MENU_CALLBACK(attach_c64_cart_callback)49 static UI_MENU_CALLBACK(attach_c64_cart_callback)
50 {
51     char *name = NULL;
52 
53     if (activated) {
54         name = sdl_ui_file_selection_dialog("Select cartridge image", FILEREQ_MODE_CHOOSE_FILE);
55         if (name != NULL) {
56             if (cartridge_attach_image(vice_ptr_to_int(param), name) < 0) {
57                 ui_error("Cannot load cartridge image.");
58             }
59             lib_free(name);
60         }
61     }
62     return NULL;
63 }
64 
65 ui_menu_entry_t ui_c64cart_entry = {
66     NULL, MENU_ENTRY_DIALOG, (ui_callback_t)attach_c64_cart_callback,
67     (ui_callback_data_t)0
68 };
69 
countgroup(cartridge_info_t * cartlist,int flags)70 static int countgroup(cartridge_info_t *cartlist, int flags)
71 {
72     int num = 0;
73     while(cartlist->name) {
74         if (cartlist->flags & flags) {
75             num++;
76         }
77         cartlist++;
78     }
79     return num;
80 }
81 
makegroup(cartridge_info_t * cartlist,ui_menu_entry_t * entry,int flags)82 static void makegroup(cartridge_info_t *cartlist, ui_menu_entry_t *entry, int flags)
83 {
84     while(cartlist->name) {
85         if (cartlist->flags & flags) {
86             ui_c64cart_entry.string = cartlist->name;
87             ui_c64cart_entry.data = (ui_callback_data_t)(int_to_void_ptr(cartlist->crtid));
88             memcpy(entry, &ui_c64cart_entry, sizeof(ui_menu_entry_t));
89             entry++;
90         }
91         cartlist++;
92     }
93     memset(entry, 0, sizeof(ui_menu_entry_t));
94 }
95 
96 static ui_menu_entry_t *attach_raw_cart_menu = NULL;
97 
uicart_menu_create(void)98 void uicart_menu_create(void)
99 {
100     int num;
101     cartridge_info_t *cartlist = cartridge_get_info_list();
102 
103     num = countgroup(cartlist, CARTRIDGE_GROUP_GENERIC | CARTRIDGE_GROUP_FREEZER | CARTRIDGE_GROUP_GAME | CARTRIDGE_GROUP_UTIL);
104     attach_raw_cart_menu = lib_malloc(sizeof(ui_menu_entry_t) * (num + 1));
105     makegroup(cartlist, attach_raw_cart_menu, CARTRIDGE_GROUP_GENERIC | CARTRIDGE_GROUP_FREEZER | CARTRIDGE_GROUP_GAME | CARTRIDGE_GROUP_UTIL);
106     if (machine_class == VICE_MACHINE_SCPU64) {
107         scpu64cart_menu[1].data = attach_raw_cart_menu;
108     } else if (machine_class == VICE_MACHINE_C128) {
109         c128cart_menu[1].data = attach_raw_cart_menu;
110     } else {
111         c64cart_menu[1].data = attach_raw_cart_menu;
112     }
113 }
114 
115 
uicart_menu_shutdown(void)116 void uicart_menu_shutdown(void)
117 {
118     if (attach_raw_cart_menu != NULL) {
119         lib_free(attach_raw_cart_menu);
120     }
121 }
122 
123 
UI_MENU_CALLBACK(detach_c64_cart_callback)124 static UI_MENU_CALLBACK(detach_c64_cart_callback)
125 {
126     if (activated) {
127         cartridge_detach_image(-1);
128     }
129     return NULL;
130 }
131 
UI_MENU_CALLBACK(c64_cart_freeze_callback)132 static UI_MENU_CALLBACK(c64_cart_freeze_callback)
133 {
134     if (activated) {
135         keyboard_clear_keymatrix();
136         cartridge_trigger_freeze();
137     }
138     return NULL;
139 }
140 
UI_MENU_CALLBACK(set_c64_cart_default_callback)141 static UI_MENU_CALLBACK(set_c64_cart_default_callback)
142 {
143     if (activated) {
144         cartridge_set_default();
145     }
146     return NULL;
147 }
148 
149 /* FIXME: we need an error reporting system, so all this
150           stuff can go away. */
151 typedef struct c64_cart_flush_s {
152     int cartid;
153     char *enable_res;
154     char *image_res;
155 } c64_cart_flush_t;
156 
157 static c64_cart_flush_t carts[] = {
158     { CARTRIDGE_RAMCART, "RAMCART", "RAMCARTfilename" },
159     { CARTRIDGE_REU, "REU", "REUfilename" },
160     { CARTRIDGE_EXPERT, "ExpertCartridgeEnabled", "Expertfilename" },
161     { CARTRIDGE_DQBB, "DQBB", "DQBBfilename" },
162     { CARTRIDGE_ISEPIC, "IsepicCartridgeEnabled", "Isepicfilename" },
163     { CARTRIDGE_EASYFLASH, NULL, NULL },
164     { CARTRIDGE_GEORAM, "GEORAM", "GEORAMfilename" },
165     { CARTRIDGE_MMC64, "MMC64", "MMC64BIOSfilename" },
166     { CARTRIDGE_MMC_REPLAY, NULL, "MMCREEPROMImage" },
167     { CARTRIDGE_GMOD2, NULL, "GMod2EEPROMImage" },
168     { CARTRIDGE_RETRO_REPLAY, NULL, NULL },
169     { 0, NULL, NULL }
170 };
171 
UI_MENU_CALLBACK(c64_cart_flush_callback)172 static UI_MENU_CALLBACK(c64_cart_flush_callback)
173 {
174     int i;
175     int found = 0;
176     int enabled = 1;
177     const char *filename = "a";
178 
179     if (activated) {
180         int cartid = vice_ptr_to_int(param);
181 
182         if (cartridge_flush_image(cartid) < 0) {
183             /* find cartid in carts */
184             for (i = 0; carts[i].cartid != 0 && !found; i++) {
185                 if (carts[i].cartid == cartid) {
186                     found = 1;
187                 }
188             }
189             i--;
190 
191             /* check if cart was enabled */
192             if (found) {
193                 if (carts[i].enable_res) {
194                     resources_get_int(carts[i].enable_res, &enabled);
195                 }
196             }
197 
198             /* check if cart has image */
199             if (found) {
200                 if (carts[i].image_res) {
201                     resources_get_string(carts[i].image_res, &filename);
202                 }
203             }
204 
205             if (!enabled) {
206                 ui_error("Cartridge is not enabled.");
207             } else if (!filename) {
208                 ui_error("No name defined for cart image.");
209             } else if (!*filename) {
210                 ui_error("No name defined for cart image.");
211             } else {
212                 ui_error("Cannot save cartridge image.");
213             }
214         }
215     }
216     return NULL;
217 }
218 
UI_MENU_CALLBACK(c64_cart_save_callback)219 static UI_MENU_CALLBACK(c64_cart_save_callback)
220 {
221     if (activated) {
222         int cartid = vice_ptr_to_int(param);
223         char *name = NULL;
224 
225         name = sdl_ui_file_selection_dialog("Choose cartridge file", FILEREQ_MODE_SAVE_FILE);
226 
227         if (name != NULL) {
228             if (cartridge_save_image(cartid, name) < 0) {
229                 ui_error("Cannot save cartridge image.");
230             }
231             lib_free(name);
232         }
233     }
234     return NULL;
235 }
236 
237 /* RAMCART */
238 
239 UI_MENU_DEFINE_TOGGLE(RAMCART)
240 UI_MENU_DEFINE_TOGGLE(RAMCART_RO)
241 UI_MENU_DEFINE_RADIO(RAMCARTsize)
242 UI_MENU_DEFINE_FILE_STRING(RAMCARTfilename)
243 UI_MENU_DEFINE_TOGGLE(RAMCARTImageWrite)
244 
245 static const ui_menu_entry_t ramcart_menu[] = {
246     { "Enable " CARTRIDGE_NAME_RAMCART,
247       MENU_ENTRY_RESOURCE_TOGGLE,
248       toggle_RAMCART_callback,
249       NULL },
250     { "Read-only",
251       MENU_ENTRY_RESOURCE_TOGGLE,
252       toggle_RAMCART_RO_callback,
253       NULL },
254     SDL_MENU_ITEM_SEPARATOR,
255     SDL_MENU_ITEM_TITLE("Memory size"),
256     { "64kB",
257       MENU_ENTRY_RESOURCE_RADIO,
258       radio_RAMCARTsize_callback,
259       (ui_callback_data_t)64 },
260     { "128kB",
261       MENU_ENTRY_RESOURCE_RADIO,
262       radio_RAMCARTsize_callback,
263       (ui_callback_data_t)128 },
264     SDL_MENU_ITEM_SEPARATOR,
265     SDL_MENU_ITEM_TITLE("RAM image"),
266     { "Image file",
267       MENU_ENTRY_DIALOG,
268       file_string_RAMCARTfilename_callback,
269       (ui_callback_data_t)"Select " CARTRIDGE_NAME_RAMCART " image" },
270     { "Save image on detach",
271       MENU_ENTRY_RESOURCE_TOGGLE,
272       toggle_RAMCARTImageWrite_callback,
273       NULL },
274     { "Save image now",
275       MENU_ENTRY_OTHER,
276       c64_cart_flush_callback,
277       (ui_callback_data_t)CARTRIDGE_RAMCART },
278     { "Save image as",
279       MENU_ENTRY_OTHER,
280       c64_cart_save_callback,
281       (ui_callback_data_t)CARTRIDGE_RAMCART },
282     SDL_MENU_LIST_END
283 };
284 
285 
286 /* REU */
287 
288 UI_MENU_DEFINE_TOGGLE(REU)
289 UI_MENU_DEFINE_RADIO(REUsize)
290 UI_MENU_DEFINE_FILE_STRING(REUfilename)
291 UI_MENU_DEFINE_TOGGLE(REUImageWrite)
292 
293 static const ui_menu_entry_t reu_menu[] = {
294     { "Enable " CARTRIDGE_NAME_REU,
295       MENU_ENTRY_RESOURCE_TOGGLE,
296       toggle_REU_callback,
297       NULL },
298     SDL_MENU_ITEM_SEPARATOR,
299     SDL_MENU_ITEM_TITLE("Memory size"),
300     { "128kB",
301       MENU_ENTRY_RESOURCE_RADIO,
302       radio_REUsize_callback,
303       (ui_callback_data_t)128 },
304     { "256kB",
305       MENU_ENTRY_RESOURCE_RADIO,
306       radio_REUsize_callback,
307       (ui_callback_data_t)256 },
308     { "512kB",
309       MENU_ENTRY_RESOURCE_RADIO,
310       radio_REUsize_callback,
311       (ui_callback_data_t)512 },
312     { "1024kB",
313       MENU_ENTRY_RESOURCE_RADIO,
314       radio_REUsize_callback,
315       (ui_callback_data_t)1024 },
316     { "2048kB",
317       MENU_ENTRY_RESOURCE_RADIO,
318       radio_REUsize_callback,
319       (ui_callback_data_t)2048 },
320     { "4096kB",
321       MENU_ENTRY_RESOURCE_RADIO,
322       radio_REUsize_callback,
323       (ui_callback_data_t)4096 },
324     { "8192kB",
325       MENU_ENTRY_RESOURCE_RADIO,
326       radio_REUsize_callback,
327       (ui_callback_data_t)8192 },
328     { "16384kB",
329       MENU_ENTRY_RESOURCE_RADIO,
330       radio_REUsize_callback,
331       (ui_callback_data_t)16384 },
332     SDL_MENU_ITEM_SEPARATOR,
333     SDL_MENU_ITEM_TITLE("RAM image"),
334     { "Image file",
335       MENU_ENTRY_DIALOG,
336       file_string_REUfilename_callback,
337       (ui_callback_data_t)"Select " CARTRIDGE_NAME_REU " image" },
338     { "Save image on detach",
339       MENU_ENTRY_RESOURCE_TOGGLE,
340       toggle_REUImageWrite_callback,
341       NULL },
342     { "Save image now",
343       MENU_ENTRY_OTHER,
344       c64_cart_flush_callback,
345       (ui_callback_data_t)CARTRIDGE_REU },
346     { "Save image as",
347       MENU_ENTRY_OTHER,
348       c64_cart_save_callback,
349       (ui_callback_data_t)CARTRIDGE_REU },
350     SDL_MENU_LIST_END
351 };
352 
353 
354 /* Expert cartridge */
355 
356 UI_MENU_DEFINE_TOGGLE(ExpertCartridgeEnabled)
357 UI_MENU_DEFINE_RADIO(ExpertCartridgeMode)
358 UI_MENU_DEFINE_FILE_STRING(Expertfilename)
359 UI_MENU_DEFINE_TOGGLE(ExpertImageWrite)
360 
361 static const ui_menu_entry_t expert_cart_menu[] = {
362     { "Enable " CARTRIDGE_NAME_EXPERT,
363       MENU_ENTRY_RESOURCE_TOGGLE,
364       toggle_ExpertCartridgeEnabled_callback,
365       NULL },
366     SDL_MENU_ITEM_SEPARATOR,
367     SDL_MENU_ITEM_TITLE("Mode"),
368     { "Off",
369       MENU_ENTRY_RESOURCE_RADIO,
370       radio_ExpertCartridgeMode_callback,
371       (ui_callback_data_t)EXPERT_MODE_OFF },
372     { "Prg",
373       MENU_ENTRY_RESOURCE_RADIO,
374       radio_ExpertCartridgeMode_callback,
375       (ui_callback_data_t)EXPERT_MODE_PRG },
376     { "On",
377       MENU_ENTRY_RESOURCE_RADIO,
378       radio_ExpertCartridgeMode_callback,
379       (ui_callback_data_t)EXPERT_MODE_ON },
380     SDL_MENU_ITEM_SEPARATOR,
381     SDL_MENU_ITEM_TITLE("RAM image"),
382     { "Image file",
383       MENU_ENTRY_DIALOG,
384       file_string_Expertfilename_callback,
385       (ui_callback_data_t)"Select " CARTRIDGE_NAME_EXPERT " image" },
386     { "Save image on detach",
387       MENU_ENTRY_RESOURCE_TOGGLE,
388       toggle_ExpertImageWrite_callback,
389       NULL },
390     { "Save image now",
391       MENU_ENTRY_OTHER,
392       c64_cart_flush_callback,
393       (ui_callback_data_t)CARTRIDGE_EXPERT },
394     { "Save image as",
395       MENU_ENTRY_OTHER,
396       c64_cart_save_callback,
397       (ui_callback_data_t)CARTRIDGE_EXPERT },
398     SDL_MENU_LIST_END
399 };
400 
401 
402 /* Double Quick Brown Box */
403 
404 UI_MENU_DEFINE_TOGGLE(DQBB)
405 UI_MENU_DEFINE_FILE_STRING(DQBBfilename)
406 UI_MENU_DEFINE_TOGGLE(DQBBImageWrite)
407 
408 static const ui_menu_entry_t dqbb_cart_menu[] = {
409     { "Enable " CARTRIDGE_NAME_DQBB,
410       MENU_ENTRY_RESOURCE_TOGGLE,
411       toggle_DQBB_callback,
412       NULL },
413     SDL_MENU_ITEM_SEPARATOR,
414     SDL_MENU_ITEM_TITLE("RAM image"),
415     { "Image file",
416       MENU_ENTRY_DIALOG,
417       file_string_DQBBfilename_callback,
418       (ui_callback_data_t)"Select " CARTRIDGE_NAME_DQBB " image" },
419     { "Save image on detach",
420       MENU_ENTRY_RESOURCE_TOGGLE,
421       toggle_DQBBImageWrite_callback,
422       NULL },
423     { "Save image now",
424       MENU_ENTRY_OTHER,
425       c64_cart_flush_callback,
426       (ui_callback_data_t)CARTRIDGE_DQBB },
427     { "Save image as",
428       MENU_ENTRY_OTHER,
429       c64_cart_save_callback,
430       (ui_callback_data_t)CARTRIDGE_DQBB },
431     SDL_MENU_LIST_END
432 };
433 
434 
435 /* ISEPIC */
436 
437 UI_MENU_DEFINE_TOGGLE(IsepicCartridgeEnabled)
438 UI_MENU_DEFINE_TOGGLE(IsepicSwitch)
439 UI_MENU_DEFINE_FILE_STRING(Isepicfilename)
440 UI_MENU_DEFINE_TOGGLE(IsepicImageWrite)
441 
442 static const ui_menu_entry_t isepic_cart_menu[] = {
443     { "Enable " CARTRIDGE_NAME_ISEPIC,
444       MENU_ENTRY_RESOURCE_TOGGLE,
445       toggle_IsepicCartridgeEnabled_callback,
446       NULL },
447     { "Switch",
448       MENU_ENTRY_RESOURCE_TOGGLE,
449       toggle_IsepicSwitch_callback,
450       NULL },
451     SDL_MENU_ITEM_SEPARATOR,
452     SDL_MENU_ITEM_TITLE("RAM image"),
453     { "Image file",
454       MENU_ENTRY_DIALOG,
455       file_string_Isepicfilename_callback,
456       (ui_callback_data_t)"Select " CARTRIDGE_NAME_ISEPIC " image" },
457     { "Save image on detach",
458       MENU_ENTRY_RESOURCE_TOGGLE,
459       toggle_IsepicImageWrite_callback,
460       NULL },
461     { "Save image now",
462       MENU_ENTRY_OTHER,
463       c64_cart_flush_callback,
464       (ui_callback_data_t)CARTRIDGE_ISEPIC },
465     { "Save image as",
466       MENU_ENTRY_OTHER,
467       c64_cart_save_callback,
468       (ui_callback_data_t)CARTRIDGE_ISEPIC },
469     SDL_MENU_LIST_END
470 };
471 
472 
473 /* EasyFlash */
474 
475 UI_MENU_DEFINE_TOGGLE(EasyFlashJumper)
476 UI_MENU_DEFINE_TOGGLE(EasyFlashWriteCRT)
477 UI_MENU_DEFINE_TOGGLE(EasyFlashOptimizeCRT)
478 
479 
480 static const ui_menu_entry_t easyflash_cart_menu[] = {
481     { "Jumper",
482       MENU_ENTRY_RESOURCE_TOGGLE,
483       toggle_EasyFlashJumper_callback,
484       NULL },
485     { "Save image on detach",
486       MENU_ENTRY_RESOURCE_TOGGLE,
487       toggle_EasyFlashWriteCRT_callback,
488       NULL },
489     { "Optimize image on write",
490       MENU_ENTRY_RESOURCE_TOGGLE,
491       toggle_EasyFlashOptimizeCRT_callback,
492       NULL },
493     { "Save image now",
494       MENU_ENTRY_OTHER,
495       c64_cart_flush_callback,
496       (ui_callback_data_t)CARTRIDGE_EASYFLASH },
497     { "Save image as",
498       MENU_ENTRY_OTHER,
499       c64_cart_save_callback,
500       (ui_callback_data_t)CARTRIDGE_EASYFLASH },
501     SDL_MENU_LIST_END
502 };
503 
504 
505 /* GEORAM */
506 
507 UI_MENU_DEFINE_TOGGLE(GEORAM)
508 UI_MENU_DEFINE_RADIO(GEORAMsize)
509 UI_MENU_DEFINE_FILE_STRING(GEORAMfilename)
510 UI_MENU_DEFINE_TOGGLE(GEORAMImageWrite)
511 
512 static const ui_menu_entry_t georam_menu[] = {
513     { "Enable " CARTRIDGE_NAME_GEORAM,
514       MENU_ENTRY_RESOURCE_TOGGLE,
515       toggle_GEORAM_callback,
516       NULL },
517     SDL_MENU_ITEM_SEPARATOR,
518     SDL_MENU_ITEM_TITLE("Memory size"),
519     { "64kB",
520       MENU_ENTRY_RESOURCE_RADIO,
521       radio_GEORAMsize_callback,
522       (ui_callback_data_t)64 },
523     { "128kB",
524       MENU_ENTRY_RESOURCE_RADIO,
525       radio_GEORAMsize_callback,
526       (ui_callback_data_t)128 },
527     { "256kB",
528       MENU_ENTRY_RESOURCE_RADIO,
529       radio_GEORAMsize_callback,
530       (ui_callback_data_t)256 },
531     { "512kB",
532       MENU_ENTRY_RESOURCE_RADIO,
533       radio_GEORAMsize_callback,
534       (ui_callback_data_t)512 },
535     { "1024kB",
536       MENU_ENTRY_RESOURCE_RADIO,
537       radio_GEORAMsize_callback,
538       (ui_callback_data_t)1024 },
539     { "2048kB",
540       MENU_ENTRY_RESOURCE_RADIO,
541       radio_GEORAMsize_callback,
542       (ui_callback_data_t)2048 },
543     { "4096kB",
544       MENU_ENTRY_RESOURCE_RADIO,
545       radio_GEORAMsize_callback,
546       (ui_callback_data_t)4096 },
547     SDL_MENU_ITEM_SEPARATOR,
548     SDL_MENU_ITEM_TITLE("RAM image"),
549     { "Image file",
550       MENU_ENTRY_DIALOG,
551       file_string_GEORAMfilename_callback,
552       (ui_callback_data_t)"Select " CARTRIDGE_NAME_GEORAM " image" },
553     { "Save image on detach",
554       MENU_ENTRY_RESOURCE_TOGGLE,
555       toggle_GEORAMImageWrite_callback,
556       NULL },
557     { "Save image now",
558       MENU_ENTRY_OTHER,
559       c64_cart_flush_callback,
560       (ui_callback_data_t)CARTRIDGE_GEORAM },
561     { "Save image as",
562       MENU_ENTRY_OTHER,
563       c64_cart_save_callback,
564       (ui_callback_data_t)CARTRIDGE_GEORAM },
565     SDL_MENU_LIST_END
566 };
567 
568 
569 /* MMC64 */
570 
UI_MENU_DEFINE_RADIO(MMC64ClockPort)571 UI_MENU_DEFINE_RADIO(MMC64ClockPort)
572 
573 static ui_menu_entry_t mmc64_clockport_device_menu[CLOCKPORT_MAX_ENTRIES + 1];
574 
575 UI_MENU_DEFINE_RADIO(MMC64_sd_type)
576 
577 static const ui_menu_entry_t mmc64_sd_type_menu[] = {
578     { "Auto",
579       MENU_ENTRY_RESOURCE_RADIO,
580       radio_MMC64_sd_type_callback,
581       (ui_callback_data_t)0 },
582     { "MMC",
583       MENU_ENTRY_RESOURCE_RADIO,
584       radio_MMC64_sd_type_callback,
585       (ui_callback_data_t)1 },
586     { "SD",
587       MENU_ENTRY_RESOURCE_RADIO,
588       radio_MMC64_sd_type_callback,
589       (ui_callback_data_t)2 },
590     { "SDHC",
591       MENU_ENTRY_RESOURCE_RADIO,
592       radio_MMC64_sd_type_callback,
593       (ui_callback_data_t)3 },
594     SDL_MENU_LIST_END
595 };
596 
597 UI_MENU_DEFINE_TOGGLE(MMC64)
598 UI_MENU_DEFINE_RADIO(MMC64_revision)
599 UI_MENU_DEFINE_TOGGLE(MMC64_flashjumper)
600 UI_MENU_DEFINE_TOGGLE(MMC64_bios_write)
601 UI_MENU_DEFINE_FILE_STRING(MMC64BIOSfilename)
602 UI_MENU_DEFINE_TOGGLE(MMC64_RO)
603 UI_MENU_DEFINE_FILE_STRING(MMC64imagefilename)
604 
605 static const ui_menu_entry_t mmc64_cart_menu[] = {
606     { "Enable " CARTRIDGE_NAME_MMC64,
607       MENU_ENTRY_RESOURCE_TOGGLE,
608       toggle_MMC64_callback,
609       NULL },
610     SDL_MENU_ITEM_SEPARATOR,
611     SDL_MENU_ITEM_TITLE("Revision"),
612     { "Rev A",
613       MENU_ENTRY_RESOURCE_RADIO,
614       radio_MMC64_revision_callback,
615       (ui_callback_data_t)0 },
616     { "Rev B",
617       MENU_ENTRY_RESOURCE_RADIO,
618       radio_MMC64_revision_callback,
619       (ui_callback_data_t)1 },
620     SDL_MENU_ITEM_SEPARATOR,
621     { "BIOS flash jumper",
622       MENU_ENTRY_RESOURCE_TOGGLE,
623       toggle_MMC64_flashjumper_callback,
624       NULL },
625     SDL_MENU_ITEM_SEPARATOR,
626     SDL_MENU_ITEM_TITLE("BIOS image"),
627     { "BIOS image file",
628       MENU_ENTRY_DIALOG,
629       file_string_MMC64BIOSfilename_callback,
630       (ui_callback_data_t)"Select " CARTRIDGE_NAME_MMC64 " BIOS image" },
631     { "Save image on detach",
632       MENU_ENTRY_RESOURCE_TOGGLE,
633       toggle_MMC64_bios_write_callback,
634       NULL },
635     { "Save image now",
636       MENU_ENTRY_OTHER,
637       c64_cart_flush_callback,
638       (ui_callback_data_t)CARTRIDGE_MMC64 },
639     { "Save image as",
640       MENU_ENTRY_OTHER,
641       c64_cart_save_callback,
642       (ui_callback_data_t)CARTRIDGE_MMC64 },
643     SDL_MENU_ITEM_SEPARATOR,
644     SDL_MENU_ITEM_TITLE("MMC/SD image"),
645     { "MMC/SD image file",
646       MENU_ENTRY_DIALOG,
647       file_string_MMC64imagefilename_callback,
648       (ui_callback_data_t)"Select MMC/SD image" },
649     { "Image read-only",
650       MENU_ENTRY_RESOURCE_TOGGLE,
651       toggle_MMC64_RO_callback,
652       NULL },
653     { "Card type",
654       MENU_ENTRY_SUBMENU,
655       submenu_radio_callback,
656       (ui_callback_data_t)mmc64_sd_type_menu },
657     SDL_MENU_ITEM_SEPARATOR,
658     { "Clockport device",
659       MENU_ENTRY_SUBMENU,
660       submenu_callback,
661       (ui_callback_data_t)mmc64_clockport_device_menu },
662     SDL_MENU_LIST_END
663 };
664 
665 
666 /* MMC Replay */
667 
UI_MENU_DEFINE_RADIO(MMCRClockPort)668 UI_MENU_DEFINE_RADIO(MMCRClockPort)
669 
670 static ui_menu_entry_t mmcreplay_clockport_device_menu[CLOCKPORT_MAX_ENTRIES + 1];
671 
672 UI_MENU_DEFINE_RADIO(MMCRSDType)
673 
674 static const ui_menu_entry_t mmcreplay_sd_type_menu[] = {
675     { "Auto",
676       MENU_ENTRY_RESOURCE_RADIO,
677       radio_MMCRSDType_callback,
678       (ui_callback_data_t)0 },
679     { "MMC",
680       MENU_ENTRY_RESOURCE_RADIO,
681       radio_MMCRSDType_callback,
682       (ui_callback_data_t)1 },
683     { "SD",
684       MENU_ENTRY_RESOURCE_RADIO,
685       radio_MMCRSDType_callback,
686       (ui_callback_data_t)2 },
687     { "SDHC",
688       MENU_ENTRY_RESOURCE_RADIO,
689       radio_MMCRSDType_callback,
690       (ui_callback_data_t)3 },
691     SDL_MENU_LIST_END
692 };
693 
694 UI_MENU_DEFINE_FILE_STRING(MMCRCardImage)
695 UI_MENU_DEFINE_FILE_STRING(MMCREEPROMImage)
696 UI_MENU_DEFINE_TOGGLE(MMCRCardRW)
697 UI_MENU_DEFINE_TOGGLE(MMCREEPROMRW)
698 UI_MENU_DEFINE_TOGGLE(MMCRRescueMode)
699 UI_MENU_DEFINE_TOGGLE(MMCRImageWrite)
700 
701 static const ui_menu_entry_t mmcreplay_cart_menu[] = {
702     { "Rescue mode",
703       MENU_ENTRY_RESOURCE_TOGGLE,
704       toggle_MMCRRescueMode_callback,
705       NULL },
706     SDL_MENU_ITEM_SEPARATOR,
707     SDL_MENU_ITEM_TITLE("BIOS image"),
708     { "Save image on detach",
709       MENU_ENTRY_RESOURCE_TOGGLE,
710       toggle_MMCRImageWrite_callback,
711       NULL },
712     { "Save image now",
713       MENU_ENTRY_OTHER,
714       c64_cart_flush_callback,
715       (ui_callback_data_t)CARTRIDGE_MMC_REPLAY },
716     { "Save image as",
717       MENU_ENTRY_OTHER,
718       c64_cart_save_callback,
719       (ui_callback_data_t)CARTRIDGE_MMC_REPLAY },
720     SDL_MENU_ITEM_SEPARATOR,
721     SDL_MENU_ITEM_TITLE("EEPROM image"),
722     { "EEPROM image file",
723       MENU_ENTRY_DIALOG,
724       file_string_MMCREEPROMImage_callback,
725       (ui_callback_data_t)"Select " CARTRIDGE_NAME_MMC_REPLAY " EEPROM image" },
726     { "Enable writes to EEPROM image",
727       MENU_ENTRY_RESOURCE_TOGGLE,
728       toggle_MMCREEPROMRW_callback,
729       NULL },
730     SDL_MENU_ITEM_SEPARATOR,
731     SDL_MENU_ITEM_TITLE("MMC/SD image"),
732     { "Card image file",
733       MENU_ENTRY_DIALOG,
734       file_string_MMCRCardImage_callback,
735       (ui_callback_data_t)"Select card image" },
736     { "Enable writes to card image",
737       MENU_ENTRY_RESOURCE_TOGGLE,
738       toggle_MMCRCardRW_callback,
739       NULL },
740     { "Card type",
741       MENU_ENTRY_SUBMENU,
742       submenu_radio_callback,
743       (ui_callback_data_t)mmcreplay_sd_type_menu },
744     SDL_MENU_ITEM_SEPARATOR,
745     { "Clockport device",
746       MENU_ENTRY_SUBMENU,
747       submenu_callback,
748       (ui_callback_data_t)mmcreplay_clockport_device_menu },
749     SDL_MENU_LIST_END
750 };
751 
752 
753 /* Retro Replay */
754 
UI_MENU_DEFINE_RADIO(RRClockPort)755 UI_MENU_DEFINE_RADIO(RRClockPort)
756 
757 static ui_menu_entry_t retroreplay_clockport_device_menu[CLOCKPORT_MAX_ENTRIES + 1];
758 
759 UI_MENU_DEFINE_TOGGLE(RRBankJumper)
760 UI_MENU_DEFINE_RADIO(RRRevision)
761 UI_MENU_DEFINE_TOGGLE(RRFlashJumper)
762 UI_MENU_DEFINE_TOGGLE(RRBiosWrite)
763 
764 static const ui_menu_entry_t retroreplay_revision_menu[] = {
765     { "Retro Replay",
766       MENU_ENTRY_RESOURCE_RADIO,
767       radio_RRRevision_callback,
768       (ui_callback_data_t)0 },
769     { "Nordic Replay",
770       MENU_ENTRY_RESOURCE_RADIO,
771       radio_RRRevision_callback,
772       (ui_callback_data_t)1 },
773     SDL_MENU_LIST_END
774 };
775 
776 static const ui_menu_entry_t retroreplay_cart_menu[] = {
777     { "Revision",
778       MENU_ENTRY_SUBMENU,
779       submenu_radio_callback,
780       (ui_callback_data_t)retroreplay_revision_menu },
781     { "Bank jumper",
782       MENU_ENTRY_RESOURCE_TOGGLE,
783       toggle_RRBankJumper_callback,
784       NULL },
785     { "BIOS flash jumper",
786       MENU_ENTRY_RESOURCE_TOGGLE,
787       toggle_RRFlashJumper_callback,
788       NULL },
789     { "Save image on detach",
790       MENU_ENTRY_RESOURCE_TOGGLE,
791       toggle_RRBiosWrite_callback,
792       NULL },
793     { "Save image now",
794       MENU_ENTRY_OTHER,
795       c64_cart_flush_callback,
796       (ui_callback_data_t)CARTRIDGE_RETRO_REPLAY },
797     { "Save image as",
798       MENU_ENTRY_OTHER,
799       c64_cart_save_callback,
800       (ui_callback_data_t)CARTRIDGE_RETRO_REPLAY },
801     SDL_MENU_ITEM_SEPARATOR,
802     { "Clockport device",
803       MENU_ENTRY_SUBMENU,
804       submenu_callback,
805       (ui_callback_data_t)retroreplay_clockport_device_menu },
806     SDL_MENU_LIST_END
807 };
808 
809 
810 /* GMod2 */
811 
812 UI_MENU_DEFINE_FILE_STRING(GMod2EEPROMImage)
813 UI_MENU_DEFINE_TOGGLE(GMOD2EEPROMRW)
814 UI_MENU_DEFINE_TOGGLE(GMod2FlashWrite)
815 
816 static const ui_menu_entry_t gmod2_cart_menu[] = {
817     SDL_MENU_ITEM_TITLE("EEPROM image"),
818     { "EEPROM image file",
819       MENU_ENTRY_DIALOG,
820       file_string_GMod2EEPROMImage_callback,
821       (ui_callback_data_t)"Select " CARTRIDGE_NAME_GMOD2 " EEPROM image" },
822     { "Enable writes to EEPROM image",
823       MENU_ENTRY_RESOURCE_TOGGLE,
824       toggle_GMOD2EEPROMRW_callback,
825       NULL },
826     SDL_MENU_ITEM_SEPARATOR,
827     SDL_MENU_ITEM_TITLE("Flash image"),
828     { "Enable writes to flash image",
829       MENU_ENTRY_RESOURCE_TOGGLE,
830       toggle_GMod2FlashWrite_callback,
831       NULL },
832     SDL_MENU_LIST_END
833 };
834 
835 /* RRNET MK3 */
836 UI_MENU_DEFINE_TOGGLE(RRNETMK3_flashjumper)
837 UI_MENU_DEFINE_TOGGLE(RRNETMK3_bios_write)
838 
839 static const ui_menu_entry_t rrnet_mk3_cart_menu[] = {
840     { "BIOS flash jumper",
841       MENU_ENTRY_RESOURCE_TOGGLE,
842       toggle_RRNETMK3_flashjumper_callback,
843       NULL },
844     { "Save image on detach",
845       MENU_ENTRY_RESOURCE_TOGGLE,
846       toggle_RRNETMK3_bios_write_callback,
847       NULL },
848     { "Save image now",
849       MENU_ENTRY_OTHER,
850       c64_cart_flush_callback,
851       (ui_callback_data_t)CARTRIDGE_RRNETMK3 },
852     { "Save image as",
853       MENU_ENTRY_OTHER,
854       c64_cart_save_callback,
855       (ui_callback_data_t)CARTRIDGE_RRNETMK3 },
856     SDL_MENU_LIST_END
857 };
858 
859 
860 /* Magic Voice */
861 
862 UI_MENU_DEFINE_TOGGLE(MagicVoiceCartridgeEnabled)
863 UI_MENU_DEFINE_FILE_STRING(MagicVoiceImage)
864 
865 static const ui_menu_entry_t magicvoice_cart_menu[] = {
866     { "Enable " CARTRIDGE_NAME_MAGIC_VOICE,
867       MENU_ENTRY_RESOURCE_TOGGLE,
868       toggle_MagicVoiceCartridgeEnabled_callback,
869       NULL },
870     { "ROM image file",
871       MENU_ENTRY_DIALOG,
872       file_string_MagicVoiceImage_callback,
873       (ui_callback_data_t)"Select " CARTRIDGE_NAME_MAGIC_VOICE " ROM image" },
874     SDL_MENU_LIST_END
875 };
876 
877 
878 /* SFX Sound Expander */
879 
880 UI_MENU_DEFINE_TOGGLE(SFXSoundExpander)
881 UI_MENU_DEFINE_RADIO(SFXSoundExpanderChip)
882 
883 static const ui_menu_entry_t soundexpander_menu[] = {
884     { "Enable " CARTRIDGE_NAME_SFX_SOUND_EXPANDER,
885       MENU_ENTRY_RESOURCE_TOGGLE,
886       toggle_SFXSoundExpander_callback,
887       NULL },
888     SDL_MENU_ITEM_SEPARATOR,
889     SDL_MENU_ITEM_TITLE("YM chip type"),
890     { "3526",
891       MENU_ENTRY_RESOURCE_RADIO,
892       radio_SFXSoundExpanderChip_callback,
893       (ui_callback_data_t)3526 },
894     { "3812",
895       MENU_ENTRY_RESOURCE_RADIO,
896       radio_SFXSoundExpanderChip_callback,
897       (ui_callback_data_t)3812 },
898     SDL_MENU_LIST_END
899 };
900 
901 UI_MENU_DEFINE_RADIO(IOCollisionHandling)
902 
903 static const ui_menu_entry_t iocollision_menu[] = {
904     { "Detach all",
905       MENU_ENTRY_RESOURCE_RADIO,
906       radio_IOCollisionHandling_callback,
907       (ui_callback_data_t)IO_COLLISION_METHOD_DETACH_ALL },
908     { "Detach last",
909       MENU_ENTRY_RESOURCE_RADIO,
910       radio_IOCollisionHandling_callback,
911       (ui_callback_data_t)IO_COLLISION_METHOD_DETACH_LAST },
912     { "AND values",
913       MENU_ENTRY_RESOURCE_RADIO,
914       radio_IOCollisionHandling_callback,
915       (ui_callback_data_t)IO_COLLISION_METHOD_AND_WIRES },
916     SDL_MENU_LIST_END
917 };
918 
UI_MENU_CALLBACK(iocollision_show_type_callback)919 static UI_MENU_CALLBACK(iocollision_show_type_callback)
920 {
921     int type;
922 
923     resources_get_int("IOCollisionHandling", &type);
924     switch (type) {
925         case IO_COLLISION_METHOD_DETACH_ALL:
926             return MENU_SUBMENU_STRING " detach all";
927             break;
928         case IO_COLLISION_METHOD_DETACH_LAST:
929             return MENU_SUBMENU_STRING " detach last";
930             break;
931         case IO_COLLISION_METHOD_AND_WIRES:
932             return MENU_SUBMENU_STRING " AND values";
933             break;
934     }
935     return "n/a";
936 }
937 
938 /* Cartridge menu */
939 
940 UI_MENU_DEFINE_TOGGLE(CartridgeReset)
941 UI_MENU_DEFINE_TOGGLE(SFXSoundSampler)
942 UI_MENU_DEFINE_TOGGLE(CPMCart)
943 UI_MENU_DEFINE_TOGGLE(SSRamExpansion)
944 
945 ui_menu_entry_t c64cart_menu[] = {
946     { "Attach CRT image",
947       MENU_ENTRY_DIALOG,
948       attach_c64_cart_callback,
949       (ui_callback_data_t)CARTRIDGE_CRT },
950     /* CAUTION: the position of this item is hardcoded above */
951     { "Attach raw image",
952       MENU_ENTRY_SUBMENU,
953       submenu_callback,
954       NULL },
955     { "Detach cartridge image",
956       MENU_ENTRY_OTHER,
957       detach_c64_cart_callback,
958       NULL },
959     SDL_MENU_ITEM_SEPARATOR,
960     { "Cartridge freeze",
961       MENU_ENTRY_OTHER,
962       c64_cart_freeze_callback,
963       NULL },
964     { "Set current cartridge as default",
965       MENU_ENTRY_OTHER,
966       set_c64_cart_default_callback,
967       NULL },
968     { "I/O collision handling ($D000-$DFFF)",
969       MENU_ENTRY_SUBMENU,
970       iocollision_show_type_callback,
971       (ui_callback_data_t)iocollision_menu },
972     { "Reset on cartridge change",
973       MENU_ENTRY_RESOURCE_TOGGLE,
974       toggle_CartridgeReset_callback,
975       NULL },
976     SDL_MENU_ITEM_SEPARATOR,
977     SDL_MENU_ITEM_TITLE("Cartridge specific settings"),
978     { CARTRIDGE_NAME_RAMCART,
979       MENU_ENTRY_SUBMENU,
980       submenu_callback,
981       (ui_callback_data_t)ramcart_menu },
982     { CARTRIDGE_NAME_REU,
983       MENU_ENTRY_SUBMENU,
984       submenu_callback,
985       (ui_callback_data_t)reu_menu },
986     { CARTRIDGE_NAME_GEORAM,
987       MENU_ENTRY_SUBMENU,
988       submenu_callback,
989       (ui_callback_data_t)georam_menu },
990     { CARTRIDGE_NAME_IDE64,
991       MENU_ENTRY_SUBMENU,
992       submenu_callback,
993       (ui_callback_data_t)ide64_menu },
994     { CARTRIDGE_NAME_EXPERT,
995       MENU_ENTRY_SUBMENU,
996       submenu_callback,
997       (ui_callback_data_t)expert_cart_menu },
998     { CARTRIDGE_NAME_ISEPIC,
999       MENU_ENTRY_SUBMENU,
1000       submenu_callback,
1001       (ui_callback_data_t)isepic_cart_menu },
1002     { CARTRIDGE_NAME_DQBB,
1003       MENU_ENTRY_SUBMENU,
1004       submenu_callback,
1005       (ui_callback_data_t)dqbb_cart_menu },
1006     { CARTRIDGE_NAME_EASYFLASH,
1007       MENU_ENTRY_SUBMENU,
1008       submenu_callback,
1009       (ui_callback_data_t)easyflash_cart_menu },
1010     { CARTRIDGE_NAME_MMC64,
1011       MENU_ENTRY_SUBMENU,
1012       submenu_callback,
1013       (ui_callback_data_t)mmc64_cart_menu },
1014     { CARTRIDGE_NAME_MMC_REPLAY,
1015       MENU_ENTRY_SUBMENU,
1016       submenu_callback,
1017       (ui_callback_data_t)mmcreplay_cart_menu },
1018     { CARTRIDGE_NAME_RETRO_REPLAY,
1019       MENU_ENTRY_SUBMENU,
1020       submenu_callback,
1021       (ui_callback_data_t)retroreplay_cart_menu },
1022     { CARTRIDGE_NAME_GMOD2,
1023       MENU_ENTRY_SUBMENU,
1024       submenu_callback,
1025       (ui_callback_data_t)gmod2_cart_menu },
1026     { CARTRIDGE_NAME_RRNETMK3,
1027       MENU_ENTRY_SUBMENU,
1028       submenu_callback,
1029       (ui_callback_data_t)rrnet_mk3_cart_menu },
1030     { CARTRIDGE_NAME_MAGIC_VOICE,
1031       MENU_ENTRY_SUBMENU,
1032       submenu_callback,
1033       (ui_callback_data_t)magicvoice_cart_menu },
1034     { CARTRIDGE_NAME_SFX_SOUND_EXPANDER " settings",
1035       MENU_ENTRY_SUBMENU,
1036       submenu_callback,
1037       (ui_callback_data_t)soundexpander_menu },
1038     { CARTRIDGE_NAME_SFX_SOUND_SAMPLER,
1039       MENU_ENTRY_RESOURCE_TOGGLE,
1040       toggle_SFXSoundSampler_callback,
1041       NULL },
1042     { "CP/M Cartridge",
1043       MENU_ENTRY_RESOURCE_TOGGLE,
1044       toggle_CPMCart_callback,
1045       NULL },
1046     { "Super Snapshot 32k RAM",
1047       MENU_ENTRY_RESOURCE_TOGGLE,
1048       toggle_SSRamExpansion_callback,
1049       NULL },
1050     SDL_MENU_LIST_END
1051 };
1052 
1053 ui_menu_entry_t c128cart_menu[] = {
1054     { "Attach CRT image",
1055       MENU_ENTRY_DIALOG,
1056       attach_c64_cart_callback,
1057       (ui_callback_data_t)CARTRIDGE_CRT },
1058     /* CAUTION: the position of this item is hardcoded above */
1059     { "Attach raw image",
1060       MENU_ENTRY_SUBMENU,
1061       submenu_callback,
1062       NULL },
1063     { "Detach cartridge image",
1064       MENU_ENTRY_OTHER,
1065       detach_c64_cart_callback,
1066       NULL },
1067     SDL_MENU_ITEM_SEPARATOR,
1068     { "Cartridge freeze",
1069       MENU_ENTRY_OTHER,
1070       c64_cart_freeze_callback,
1071       NULL },
1072     { "Set current cartridge as default",
1073       MENU_ENTRY_OTHER,
1074       set_c64_cart_default_callback,
1075       NULL },
1076     { "I/O collision handling ($D000-$DFFF)",
1077       MENU_ENTRY_SUBMENU,
1078       iocollision_show_type_callback,
1079       (ui_callback_data_t)iocollision_menu },
1080     { "Reset on cartridge change",
1081       MENU_ENTRY_RESOURCE_TOGGLE,
1082       toggle_CartridgeReset_callback,
1083       NULL },
1084     SDL_MENU_ITEM_SEPARATOR,
1085     SDL_MENU_ITEM_TITLE("Cartridge specific settings"),
1086     { CARTRIDGE_NAME_RAMCART,
1087       MENU_ENTRY_SUBMENU,
1088       submenu_callback,
1089       (ui_callback_data_t)ramcart_menu },
1090     { CARTRIDGE_NAME_REU,
1091       MENU_ENTRY_SUBMENU,
1092       submenu_callback,
1093       (ui_callback_data_t)reu_menu },
1094     { CARTRIDGE_NAME_GEORAM,
1095       MENU_ENTRY_SUBMENU,
1096       submenu_callback,
1097       (ui_callback_data_t)georam_menu },
1098     { CARTRIDGE_NAME_IDE64,
1099       MENU_ENTRY_SUBMENU,
1100       submenu_callback,
1101       (ui_callback_data_t)ide64_menu },
1102     { CARTRIDGE_NAME_EXPERT,
1103       MENU_ENTRY_SUBMENU,
1104       submenu_callback,
1105       (ui_callback_data_t)expert_cart_menu },
1106     { CARTRIDGE_NAME_ISEPIC,
1107       MENU_ENTRY_SUBMENU,
1108       submenu_callback,
1109       (ui_callback_data_t)isepic_cart_menu },
1110     { CARTRIDGE_NAME_DQBB,
1111       MENU_ENTRY_SUBMENU,
1112       submenu_callback,
1113       (ui_callback_data_t)dqbb_cart_menu },
1114     { CARTRIDGE_NAME_EASYFLASH,
1115       MENU_ENTRY_SUBMENU,
1116       submenu_callback,
1117       (ui_callback_data_t)easyflash_cart_menu },
1118     { CARTRIDGE_NAME_MMC64,
1119       MENU_ENTRY_SUBMENU,
1120       submenu_callback,
1121       (ui_callback_data_t)mmc64_cart_menu },
1122     { CARTRIDGE_NAME_MMC_REPLAY,
1123       MENU_ENTRY_SUBMENU,
1124       submenu_callback,
1125       (ui_callback_data_t)mmcreplay_cart_menu },
1126     { CARTRIDGE_NAME_RETRO_REPLAY,
1127       MENU_ENTRY_SUBMENU,
1128       submenu_callback,
1129       (ui_callback_data_t)retroreplay_cart_menu },
1130     { CARTRIDGE_NAME_GMOD2,
1131       MENU_ENTRY_SUBMENU,
1132       submenu_callback,
1133       (ui_callback_data_t)gmod2_cart_menu },
1134     { CARTRIDGE_NAME_MAGIC_VOICE,
1135       MENU_ENTRY_SUBMENU,
1136       submenu_callback,
1137       (ui_callback_data_t)magicvoice_cart_menu },
1138     { CARTRIDGE_NAME_SFX_SOUND_EXPANDER " settings",
1139       MENU_ENTRY_SUBMENU,
1140       submenu_callback,
1141       (ui_callback_data_t)soundexpander_menu },
1142     { CARTRIDGE_NAME_SFX_SOUND_SAMPLER,
1143       MENU_ENTRY_RESOURCE_TOGGLE,
1144       toggle_SFXSoundSampler_callback,
1145       NULL },
1146     SDL_MENU_LIST_END
1147 };
1148 
1149 ui_menu_entry_t scpu64cart_menu[] = {
1150     { "Attach CRT image",
1151       MENU_ENTRY_DIALOG,
1152       attach_c64_cart_callback,
1153       (ui_callback_data_t)CARTRIDGE_CRT },
1154     /* CAUTION: the position of this item is hardcoded above */
1155     { "Attach raw image",
1156       MENU_ENTRY_SUBMENU,
1157       submenu_callback,
1158       NULL },
1159     { "Detach cartridge image",
1160       MENU_ENTRY_OTHER,
1161       detach_c64_cart_callback,
1162       NULL },
1163     SDL_MENU_ITEM_SEPARATOR,
1164     { "Set current cartridge as default",
1165       MENU_ENTRY_OTHER,
1166       set_c64_cart_default_callback,
1167       NULL },
1168     { "I/O collision handling ($D000-$DFFF)",
1169       MENU_ENTRY_SUBMENU,
1170       iocollision_show_type_callback,
1171       (ui_callback_data_t)iocollision_menu },
1172     { "Reset on cartridge change",
1173       MENU_ENTRY_RESOURCE_TOGGLE,
1174       toggle_CartridgeReset_callback,
1175       NULL },
1176     SDL_MENU_ITEM_SEPARATOR,
1177     SDL_MENU_ITEM_TITLE("Cartridge specific settings"),
1178     { CARTRIDGE_NAME_RAMCART,
1179       MENU_ENTRY_SUBMENU,
1180       submenu_callback,
1181       (ui_callback_data_t)ramcart_menu },
1182     { CARTRIDGE_NAME_REU,
1183       MENU_ENTRY_SUBMENU,
1184       submenu_callback,
1185       (ui_callback_data_t)reu_menu },
1186     { CARTRIDGE_NAME_GEORAM,
1187       MENU_ENTRY_SUBMENU,
1188       submenu_callback,
1189       (ui_callback_data_t)georam_menu },
1190     { CARTRIDGE_NAME_IDE64,
1191       MENU_ENTRY_SUBMENU,
1192       submenu_callback,
1193       (ui_callback_data_t)ide64_menu },
1194     { CARTRIDGE_NAME_EXPERT,
1195       MENU_ENTRY_SUBMENU,
1196       submenu_callback,
1197       (ui_callback_data_t)expert_cart_menu },
1198     { CARTRIDGE_NAME_ISEPIC,
1199       MENU_ENTRY_SUBMENU,
1200       submenu_callback,
1201       (ui_callback_data_t)isepic_cart_menu },
1202     { CARTRIDGE_NAME_DQBB,
1203       MENU_ENTRY_SUBMENU,
1204       submenu_callback,
1205       (ui_callback_data_t)dqbb_cart_menu },
1206     { CARTRIDGE_NAME_EASYFLASH,
1207       MENU_ENTRY_SUBMENU,
1208       submenu_callback,
1209       (ui_callback_data_t)easyflash_cart_menu },
1210     { CARTRIDGE_NAME_MMC64,
1211       MENU_ENTRY_SUBMENU,
1212       submenu_callback,
1213       (ui_callback_data_t)mmc64_cart_menu },
1214     { CARTRIDGE_NAME_MMC_REPLAY,
1215       MENU_ENTRY_SUBMENU,
1216       submenu_callback,
1217       (ui_callback_data_t)mmcreplay_cart_menu },
1218     { CARTRIDGE_NAME_RETRO_REPLAY,
1219       MENU_ENTRY_SUBMENU,
1220       submenu_callback,
1221       (ui_callback_data_t)retroreplay_cart_menu },
1222     { CARTRIDGE_NAME_GMOD2,
1223       MENU_ENTRY_SUBMENU,
1224       submenu_callback,
1225       (ui_callback_data_t)gmod2_cart_menu },
1226     { CARTRIDGE_NAME_MAGIC_VOICE,
1227       MENU_ENTRY_SUBMENU,
1228       submenu_callback,
1229       (ui_callback_data_t)magicvoice_cart_menu },
1230     { CARTRIDGE_NAME_SFX_SOUND_EXPANDER " settings",
1231       MENU_ENTRY_SUBMENU,
1232       submenu_callback,
1233       (ui_callback_data_t)soundexpander_menu },
1234     { CARTRIDGE_NAME_SFX_SOUND_SAMPLER,
1235       MENU_ENTRY_RESOURCE_TOGGLE,
1236       toggle_SFXSoundSampler_callback,
1237       NULL },
1238     SDL_MENU_LIST_END
1239 };
1240 
uiclockport_rr_mmc_menu_create(void)1241 void uiclockport_rr_mmc_menu_create(void)
1242 {
1243     int i;
1244 
1245     for (i = 0; clockport_supported_devices[i].name; ++i) {
1246         mmc64_clockport_device_menu[i].string = clockport_supported_devices[i].name;
1247         mmc64_clockport_device_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
1248         mmc64_clockport_device_menu[i].callback = radio_MMC64ClockPort_callback;
1249         mmc64_clockport_device_menu[i].data = (ui_callback_data_t)int_to_void_ptr(clockport_supported_devices[i].id);
1250 
1251         mmcreplay_clockport_device_menu[i].string = clockport_supported_devices[i].name;
1252         mmcreplay_clockport_device_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
1253         mmcreplay_clockport_device_menu[i].callback = radio_MMCRClockPort_callback;
1254         mmcreplay_clockport_device_menu[i].data = (ui_callback_data_t)int_to_void_ptr(clockport_supported_devices[i].id);
1255 
1256         retroreplay_clockport_device_menu[i].string = clockport_supported_devices[i].name;
1257         retroreplay_clockport_device_menu[i].type = MENU_ENTRY_RESOURCE_RADIO;
1258         retroreplay_clockport_device_menu[i].callback = radio_RRClockPort_callback;
1259         retroreplay_clockport_device_menu[i].data = (ui_callback_data_t)int_to_void_ptr(clockport_supported_devices[i].id);
1260     }
1261 
1262     mmc64_clockport_device_menu[i].string = NULL;
1263     mmc64_clockport_device_menu[i].type = MENU_ENTRY_TEXT;
1264     mmc64_clockport_device_menu[i].callback = NULL;
1265     mmc64_clockport_device_menu[i].data = NULL;
1266 
1267     mmcreplay_clockport_device_menu[i].string = NULL;
1268     mmcreplay_clockport_device_menu[i].type = MENU_ENTRY_TEXT;
1269     mmcreplay_clockport_device_menu[i].callback = NULL;
1270     mmcreplay_clockport_device_menu[i].data = NULL;
1271 
1272     retroreplay_clockport_device_menu[i].string = NULL;
1273     retroreplay_clockport_device_menu[i].type = MENU_ENTRY_TEXT;
1274     retroreplay_clockport_device_menu[i].callback = NULL;
1275     retroreplay_clockport_device_menu[i].data = NULL;
1276 }
1277