1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli
3 /*****************************************************************************************
4
5 NES Cart PCBs Emulation
6
7 ****************************************************************************************/
8
9 struct nes_pcb
10 {
11 const char *slot_opt;
12 int pcb_id;
13 };
14
15 // Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
16 static const nes_pcb pcb_list[] =
17 {
18 { "nrom", STD_NROM },
19 { "hvc_basic", HVC_FAMBASIC },
20 { "nrom368", STD_NROM368 },
21 { "nrom_gg", GG_NROM },
22 { "uxrom", STD_UXROM },
23 { "unrom_cc", UXROM_CC },
24 { "cnrom", STD_CNROM },
25 { "bandai_pt554", BANDAI_PT554 },
26 { "cprom", STD_CPROM },
27 { "axrom", STD_AXROM },
28 { "pxrom", STD_PXROM },
29 { "fxrom", STD_FXROM },
30 { "bnrom", STD_BXROM },
31 { "gxrom", STD_GXROM },
32 { "un1rom", STD_UN1ROM },
33 { "sxrom", STD_SXROM },
34 { "sorom", STD_SOROM },
35 { "sxrom_a", STD_SXROM_A },
36 { "sorom_a", STD_SOROM_A },
37 { "txrom", STD_TXROM },
38 { "hkrom", STD_HKROM },
39 { "tqrom", STD_TQROM },
40 { "txsrom", STD_TXSROM },
41 { "exrom", STD_EXROM },
42 { "disksys", STD_DISKSYS },
43 { "pal_zz", PAL_ZZ },
44 { "nes_qj", NES_QJ },
45 { "nes_event", STD_EVENT },
46 { "discrete_74x139", DIS_74X139X74 },
47 { "discrete_74x377", DIS_74X377 },
48 { "discrete_74x161", DIS_74X161X161X32 },
49 { "bitcorp_dis", DIS_74X161X138 },
50 { "lz93d50", BANDAI_LZ93 },
51 { "lz93d50_ep1", BANDAI_LZ93EX1 },
52 { "lz93d50_ep2", BANDAI_LZ93EX2 },
53 { "fcg", BANDAI_FCG },
54 { "fjump2", BANDAI_FJUMP2 },
55 { "datach", BANDAI_DATACH },
56 { "karastudio", BANDAI_KARAOKE },
57 { "oekakids", BANDAI_OEKAKIDS },
58 { "g101", IREM_G101 },
59 { "lrog017", IREM_LROG017 },
60 { "h3001", IREM_H3001 },
61 { "holydivr", IREM_HOLYDIVR },
62 { "tam_s1", IREM_TAM_S1 },
63 { "jf11", JALECO_JF11 },
64 { "jf13", JALECO_JF13 },
65 { "jf16", JALECO_JF16 },
66 { "jf17", JALECO_JF17 },
67 { "jf17pcm", JALECO_JF17_ADPCM },
68 { "jf19", JALECO_JF19 },
69 { "jf19pcm", JALECO_JF19_ADPCM },
70 { "ss88006", JALECO_SS88006 },
71 { "jf23", JALECO_JF23 },
72 { "jf24", JALECO_JF24 },
73 { "jf29", JALECO_JF29 },
74 { "jf33", JALECO_JF33 },
75 { "vrc1", KONAMI_VRC1 },
76 { "vrc2", KONAMI_VRC2 },
77 { "vrc3", KONAMI_VRC3 },
78 { "vrc4", KONAMI_VRC4 },
79 { "vrc6", KONAMI_VRC6 },
80 { "vrc7", KONAMI_VRC7 },
81 { "namcot_163", NAMCOT_163 },
82 { "namcot_175", NAMCOT_175 },
83 { "namcot_340", NAMCOT_340 },
84 { "namcot_3433", NAMCOT_34X3 }, // DxROM is a Nintendo board for US versions of the 3433/3443 games
85 { "namcot_3425", NAMCOT_3425 },
86 { "namcot_3446", NAMCOT_3446 },
87 { "sunsoft1", SUNSOFT_1 },
88 { "sunsoft2", SUNSOFT_2 },
89 { "sunsoft3", SUNSOFT_3 },
90 { "sunsoft4", SUNSOFT_4 },
91 { "sunsoft_dcs", SUNSOFT_DCS },
92 { "sunsoft_fme7", SUNSOFT_FME7 }, // JxROM is a Nintendo board for US versions of the Sunsoft FME7 games
93 { "sunsoft5a", SUNSOFT_FME7 },
94 { "sunsoft5b", SUNSOFT_5 },
95 { "tc0190fmc", TAITO_TC0190FMC },
96 { "tc0190fmcp", TAITO_TC0190FMCP },
97 { "tc0350fmr", TAITO_TC0190FMC },
98 { "x1_005", TAITO_X1_005 }, // two variants exist, depending on pin17 & pin31 connections
99 { "x1_017", TAITO_X1_017 },
100 { "nina001", AVE_NINA01 },
101 { "nina006", AVE_NINA06 },
102 { "maxi15", AVE_MAXI15 },
103 { "bf9093", CAMERICA_BF9093 },
104 { "bf9096", CAMERICA_BF9096 },
105 { "goldenfive", CAMERICA_GOLDENFIVE },
106 { "ade" , CAMERICA_ALADDIN },
107 { "cne_decathl", CNE_DECATHLON },
108 { "cne_fsb", CNE_FSB },
109 { "cne_shlz", CNE_SHLZ },
110 { "nanjing", NANJING_BOARD }, // mapper 163
111 { "ntdec_asder", NTDEC_ASDER }, // mapper 112
112 { "ntdec_fh", NTDEC_FIGHTINGHERO }, // mapper 193
113 { "sa009", SACHEN_SA009 },
114 { "sa0036", SACHEN_SA0036 },
115 { "sa0037", SACHEN_SA0037 },
116 { "sa72007", SACHEN_SA72007 },
117 { "sa72008", SACHEN_SA72008 },
118 { "tca01", SACHEN_TCA01 },
119 { "s8259a", SACHEN_8259A },
120 { "s8259b", SACHEN_8259B },
121 { "s8259c", SACHEN_8259C },
122 { "s8259d", SACHEN_8259D },
123 { "s74x374", SACHEN_74LS374 },
124 { "s74x374a", SACHEN_74LS374_ALT }, /* FIXME: Made up boards some different handling */
125 { "tcu01", SACHEN_TCU01 },
126 { "tcu02", SACHEN_TCU02 },
127 { "sa9602b", SACHEN_SA9602B },
128 { "tengen_800008", TENGEN_800008 }, /* FIXME: Is this the same as mapper 3? */
129 { "tengen_800032", TENGEN_800032 },
130 { "tengen_800037", TENGEN_800037 },
131 { "txc_22211", TXC_22211 },
132 { "txc_dumarc", TXC_DUMARACING },
133 { "txc_mjblock", TXC_MJBLOCK },
134 { "txc_strikew", TXC_STRIKEW },
135 { "txc_commandos", TXC_COMMANDOS },
136 { "waixing_a", WAIXING_TYPE_A },
137 { "waixing_a1", WAIXING_TYPE_A1 }, /* FIXME: Made up boards the different CHRRAM banks (see Ji Jia Zhan Shi }, */
138 { "waixing_b", WAIXING_TYPE_B },
139 { "waixing_c", WAIXING_TYPE_C },
140 { "waixing_d", WAIXING_TYPE_D },
141 { "waixing_e", WAIXING_TYPE_E },
142 { "waixing_f", WAIXING_TYPE_F },
143 { "waixing_g", WAIXING_TYPE_G },
144 { "waixing_h", WAIXING_TYPE_H },
145 { "waixing_h1", WAIXING_TYPE_H1 },
146 { "waixing_i", WAIXING_TYPE_I },
147 { "waixing_j", WAIXING_TYPE_J },
148 { "waixing_sgz", WAIXING_SGZ },
149 { "waixing_sgzlz", WAIXING_SGZLZ },
150 { "waixing_sec", WAIXING_SECURITY },
151 { "waixing_ffv", WAIXING_FFV },
152 { "waixing_wxzs", WAIXING_WXZS },
153 { "waixing_wxzs2", WAIXING_WXZS2 },
154 { "waixing_dq8", WAIXING_DQ8 },
155 { "waixing_sh2", WAIXING_SH2 },
156 { "fs304", WAIXING_FS304 }, // used in Zelda 3 by Waixing
157 { "cony", CONY_BOARD },
158 { "yoko", YOKO_BOARD },
159 { "hengg_srich", HENGG_SRICH },
160 { "hengg_xhzs", HENGG_XHZS },
161 { "hengg_shjy3", HENGG_SHJY3 }, // mapper 253
162 { "hes", HES_BOARD },
163 { "hosenkan", HOSENKAN_BOARD },
164 { "ks7058", KAISER_KS7058 },
165 { "ks202", KAISER_KS202 }, // mapper 56
166 { "ks7022", KAISER_KS7022 }, // mapper 175
167 { "ks7017", KAISER_KS7017 },
168 { "ks7032", KAISER_KS7032 }, // mapper 142
169 { "ks7031", KAISER_KS7031 }, // used in Dracula II (FDS Conversion)
170 { "ks7012", KAISER_KS7012 }, // used in Zanac (FDS Conversion)
171 { "ks7013b", KAISER_KS7013B }, // used in Highway Star (FDS Conversion)
172 { "ks7016", KAISER_KS7016 }, // used in Exciting Basketball (FDS Conversion)
173 { "ks7037", KAISER_KS7037 }, // Metroid FDS Chinese
174 { "gs2015", RCM_GS2015 },
175 { "gs2004", RCM_GS2004 },
176 { "gs2013", RCM_GS2013 },
177 { "tf9in1", RCM_TF9IN1 },
178 { "3dblock", RCM_3DBLOCK }, // NROM + IRQ?
179 { "racermate", UNL_RACERMATE }, // mapper 168
180 { "agci_50282", AGCI_50282 },
181 { "dreamtech01", DREAMTECH_BOARD },
182 { "fukutake", FUKUTAKE_BOARD },
183 { "futuremedia", FUTUREMEDIA_BOARD },
184 { "magicseries", MAGICSERIES_MD },
185 { "daou_306", OPENCORP_DAOU306 },
186 { "subor0", SUBOR_TYPE0 },
187 { "subor1", SUBOR_TYPE1 },
188 { "subor2", SUBOR_TYPE2 },
189 { "cc21", UNL_CC21 },
190 { "xiaozy", UNL_XIAOZY },
191 { "edu2k", UNL_EDU2K },
192 { "t230", UNL_T230 },
193 { "mk2", UNL_MK2 },
194 { "zemina", ZEMINA_BOARD },
195 // misc bootleg boards
196 { "ax5705", UNL_AX5705 },
197 { "sc127", UNL_SC127 },
198 { "mariobaby", BTL_MARIOBABY },
199 { "asnicol", BTL_AISENSHINICOL },
200 { "smb3pirate", BTL_SMB3 },
201 { "btl_dninja", BTL_DRAGONNINJA },
202 { "whirl2706", WHIRLWIND_2706 },
203 { "smb2j", UNL_SMB2J },
204 { "smb2ja", BTL_SMB2JA },
205 { "smb2jb", BTL_SMB2JB },
206 { "09034a", BTL_09034A },
207 { "tobidase", BTL_TOBIDASE }, // mapper 120
208 { "dbz5", REXSOFT_DBZ5 },
209 { "sl1632", REXSOFT_SL1632 },
210 { "somari", SOMARI_SL12 }, // mapper 116
211 { "nitra", NITRA_TDA },
212 { "ks7057", UNL_KS7057 }, // mapper 196 alt (for Street Fighter VI / Fight Street VI },
213 { "sbros11", BTL_SBROS11 },
214 { "family4646", BMC_FAMILY_4646 },
215 { "pikay2k", BTL_PIKACHUY2K }, // mapper 254
216 { "8237", UNL_8237 },
217 { "sg_lionk", SUPERGAME_LIONKING },
218 { "sg_boog", SUPERGAME_BOOGERMAN },
219 { "kasing", KASING_BOARD },
220 { "kay", KAY_BOARD },
221 { "h2288", UNL_H2288 },
222 { "unl_6035052", UNL_603_5052 }, // mapper 238?
223 { "txc_tw", TXC_TW },
224 { "kof97", UNL_KOF97 },
225 { "kof96", UNL_KOF96 },
226 { "sfight3", UNL_SF3 },
227 { "gouder", GOUDER_37017 },
228 { "benshieng", BMC_BENSHIENG },
229 { "action52", ACTENT_ACT52 },
230 { "caltron6in1", CALTRON_6IN1 },
231 { "rumblestation", RUMBLESTATION_BOARD }, // mapper 46
232 { "svision16", SVISION16_BOARD },
233 { "n625092", UNL_N625092 },
234 { "a65as", BMC_A65AS },
235 { "t262", BMC_T262 },
236 { "novel1", BMC_NOVEL1 },
237 { "novel2", BMC_NOVEL2 }, // mapper 213... same as BMC-NOVELDIAMOND9999999IN1 board?
238 { "studyngame", UNL_STUDYNGAME }, // mapper 39
239 { "sgun20in1", BMC_SUPERGUN_20IN1 },
240 { "bmc_vt5201", BMC_VT5201 }, // mapper 60 otherwise
241 { "bmc_d1038", BMC_VT5201 }, // mapper 60?
242 { "810544c", BMC_810544 },
243 { "ntd03", BMC_NTD_03 },
244 { "bmc_gb63", BMC_G63IN1 },
245 { "bmc_gka", BMC_GKA },
246 { "bmc_gkb", BMC_GKB },
247 { "bmc_ws", BMC_WS },
248 { "bmc_hik300", BMC_SUPERHIK_300IN1 },
249 { "bmc_s700", BMC_SUPER_700IN1 },
250 { "bmc_ball11", BMC_BALLGAMES_11IN1 },
251 { "bmc_22games", BMC_22GAMES },
252 { "bmc_64y2k", BMC_64IN1NR },
253 { "bmc_12in1", BMC_12IN1 },
254 { "bmc_20in1", BMC_20IN1 },
255 { "bmc_21in1", BMC_21IN1 },
256 { "bmc_31in1", BMC_31IN1 },
257 { "bmc_35in1", BMC_35IN1 },
258 { "bmc_36in1", BMC_36IN1 },
259 { "bmc_64in1", BMC_64IN1 },
260 { "bmc_70in1", BMC_70IN1 },
261 { "bmc_72in1", BMC_72IN1 },
262 { "bmc_76in1", BMC_76IN1 },
263 { "bmc_s42in1", BMC_76IN1 },
264 { "bmc_110in1", BMC_110IN1 },
265 { "bmc_150in1", BMC_150IN1 },
266 { "bmc_190in1", BMC_190IN1 },
267 { "bmc_800in1", BMC_800IN1 },
268 { "bmc_1200in1", BMC_1200IN1 },
269 { "bmc_8157", BMC_8157 },
270 { "bmc_g146", BMC_G146 },
271 { "bmc_11160", BMC_11160 },
272 { "fk23c", BMC_FK23C },
273 { "fk23ca", BMC_FK23CA },
274 { "s24in1c03", BMC_S24IN1SC03 },
275 { "bmc_15in1", BMC_15IN1 },
276 { "bmc_sbig7in1", BMC_SUPERBIG_7IN1 },
277 { "bmc_hik8in1", BMC_HIK8IN1 },
278 { "bmc_hik4in1", BMC_SUPERHIK_4IN1 },
279 { "bmc_mario7in1", BMC_MARIOPARTY_7IN1 },
280 { "bmc_gold7in1", BMC_GOLD_7IN1 },
281 { "bmc_gc6in1", BMC_GOLDENCARD_6IN1 },
282 { "bmc_411120c", BMC_411120C },
283 { "bmc_830118c", BMC_830118C },
284 { "pjoy84", BMC_PJOY84 },
285 { "bmc_gold150", BMC_GOLD150 },
286 { "bmc_gold260", BMC_GOLD260 },
287 { "bmc_power255", BMC_CH001 },
288 { "bmc_s22games", BMC_SUPER22 },
289 { "bmc_reset4", BMC_4IN1RESET },
290 { "bmc_reset42", BMC_42IN1RESET },
291 { "jyc_a", JYCOMPANY_A },
292 { "jyc_b", JYCOMPANY_B },
293 { "jyc_c", JYCOMPANY_C },
294 { "tek90", JYCOMPANY_A },
295 { "sa9602b", SACHEN_SA9602B },
296 { "unl_shero", SACHEN_SHERO },
297 { "mmalee2", UNL_MMALEE },
298 { "unl_2708", UNL_2708 },
299 { "unl_lh10", UNL_LH10 },
300 { "unl_lh32", UNL_LH32 },
301 { "unl_lh53", UNL_LH53 },
302 { "unl_ac08", UNL_AC08 },
303 { "unl_bb", UNL_BB },
304 { "unl_malisb", UNL_MALISB },
305 { "sgpipe", BTL_SHUIGUAN },
306 { "rt01", UNL_RT01 }, // Russian Test Cart
307 { "unl_whero", UNL_WORLDHERO },
308 { "unl_43272", UNL_43272 },
309 { "tf1201", UNL_TF1201 },
310 { "unl_cfight", UNL_CITYFIGHT },
311 { "nocash_nochr", NOCASH_NOCHR },
312 { "nes_action53", BTL_ACTION53 },
313 { "nes_2a03pur", BTL_2A03_PURITANS },
314 { "ffe3", FFE3_BOARD },
315 { "ffe4", FFE4_BOARD },
316 { "ffe8", FFE8_BOARD },
317 { "8237a", UNSUPPORTED_BOARD },
318 { "ninjaryu", UNSUPPORTED_BOARD },
319 { "unl_dance", UNSUPPORTED_BOARD },
320 { "bmc_hik_kof", UNSUPPORTED_BOARD },
321 { "onebus", UNSUPPORTED_BOARD },
322 { "coolboy", UNSUPPORTED_BOARD },
323 { "btl_900218", UNSUPPORTED_BOARD }, // pirate The Lord of King, to be emulated soon
324 { "a9746", UNSUPPORTED_BOARD },
325 { "pec586", UNSUPPORTED_BOARD },
326 { "bmc_f15", UNSUPPORTED_BOARD }, // 150-in-1 Unchained Melody
327 { "bmc_hp898f", UNSUPPORTED_BOARD }, // Primasoft 9999999-in-1
328 { "bmc_8in1", UNSUPPORTED_BOARD }, // Super 8-in-1 (Incl. Rockin' Kats)
329 { "unl_eh8813a", UNSUPPORTED_BOARD }, // Dr. Mario II
330 { "unl_158b", UNSUPPORTED_BOARD }, // Blood of Jurassic
331 { "unl_drgnfgt", UNSUPPORTED_BOARD }, // Dragon Fighter by Flying Star
332 { "test", TEST_BOARD },
333 { "unknown", UNKNOWN_BOARD } // a few pirate dumps uses the wrong mapper...
334 };
335
nes_pcb_lookup(const char * slot)336 static const nes_pcb *nes_pcb_lookup( const char *slot )
337 {
338 for (auto & elem : pcb_list)
339 {
340 if (!core_stricmp(elem.slot_opt, slot))
341 return &elem;
342 }
343 return nullptr;
344 }
345
nes_id_lookup(int id)346 static const nes_pcb *nes_id_lookup( int id )
347 {
348 for (auto & elem : pcb_list)
349 {
350 if (elem.pcb_id == id)
351 return &elem;
352 }
353 return nullptr;
354 }
355
nes_get_pcb_id(const char * slot)356 int nes_cart_slot_device::nes_get_pcb_id( const char *slot )
357 {
358 const nes_pcb *pcb = nes_pcb_lookup(slot);
359
360 if (pcb == nullptr)
361 fatalerror("Unimplemented PCB type %s\n", slot);
362
363 return pcb->pcb_id;
364 }
365
366
nes_get_slot(int pcb_id)367 const char * nes_cart_slot_device::nes_get_slot( int pcb_id )
368 {
369 const nes_pcb *pcb = nes_id_lookup(pcb_id);
370
371 if (pcb == nullptr)
372 fatalerror("Unimplemented PCB ID %d\n", pcb_id);
373
374 return pcb->slot_opt;
375 }
376
377
378 /*************************************************************
379
380 nes_pcb_reset
381
382 Resets the mmc bankswitch areas to their defaults.
383 It returns a value "err" that indicates if it was
384 successful. Possible values for err are:
385
386 0 = success
387 1 = no pcb found
388 2 = pcb not supported
389
390 *************************************************************/
391
392 struct nes_cart_lines
393 {
394 const char *tag;
395 int line;
396 };
397
398 static const struct nes_cart_lines nes_cart_lines_table[] =
399 {
400 { "PRG A0", 0 },
401 { "PRG A1", 1 },
402 { "PRG A2", 2 },
403 { "PRG A3", 3 },
404 { "PRG A4", 4 },
405 { "PRG A5", 5 },
406 { "PRG A6", 6 },
407 { "PRG A7", 7 },
408 { "CHR A10", 10 },
409 { "CHR A11", 11 },
410 { "CHR A12", 12 },
411 { "CHR A13", 13 },
412 { "CHR A14", 14 },
413 { "CHR A15", 15 },
414 { "CHR A16", 16 },
415 { "CHR A17", 17 },
416 { "NC", 127 },
417 { nullptr }
418 };
419
nes_cart_get_line(const char * feature)420 static int nes_cart_get_line( const char *feature )
421 {
422 const struct nes_cart_lines *nes_line = &nes_cart_lines_table[0];
423
424 if (feature == nullptr)
425 return 128;
426
427 while (nes_line->tag)
428 {
429 if (strcmp(nes_line->tag, feature) == 0)
430 break;
431
432 nes_line++;
433 }
434
435 return nes_line->line;
436 }
437
438 struct n163_vol_lines
439 {
440 const char *tag;
441 int line;
442 };
443
444 static const struct n163_vol_lines n163_vol_table[] =
445 {
446 { "SUBMAPPER 0", 0 },
447 { "SUBMAPPER 1", 1 },
448 { "SUBMAPPER 2", 2 },
449 { "SUBMAPPER 3", 3 },
450 { "SUBMAPPER 4", 4 },
451 { "SUBMAPPER 5", 5 },
452 { nullptr }
453 };
454
n163_get_submapper_num(const char * feature)455 static int n163_get_submapper_num( const char *feature )
456 {
457 const struct n163_vol_lines *n163_line = &n163_vol_table[0];
458
459 if (feature == nullptr)
460 return 128;
461
462 while (n163_line->tag)
463 {
464 if (strcmp(n163_line->tag, feature) == 0)
465 break;
466
467 n163_line++;
468 }
469
470 return n163_line->line;
471 }
472
call_load_pcb()473 void nes_cart_slot_device::call_load_pcb()
474 {
475 uint32_t vram_size = 0, prgram_size = 0, battery_size = 0, mapper_sram_size = 0;
476 // SETUP step 1: getting PRG, VROM, VRAM sizes
477 uint32_t prg_size = get_software_region_length("prg");
478 uint32_t vrom_size = get_software_region_length("chr");
479 vram_size = get_software_region_length("vram");
480 vram_size += get_software_region_length("vram2");
481
482 // validate the xml fields
483 if (!prg_size)
484 fatalerror("No PRG entry for this software! Please check if the xml list got corrupted\n");
485 if (prg_size < 0x8000)
486 fatalerror("PRG entry is too small! Please check if the xml list got corrupted\n");
487
488 // SETUP step 2: getting PCB and other settings
489 if (get_feature("slot"))
490 m_pcb_id = nes_get_pcb_id(get_feature("slot"));
491 else
492 m_pcb_id = NO_BOARD;
493
494 // SETUP step 3: storing the info needed for emulation
495 if (get_software_region("bwram") != nullptr)
496 battery_size = get_software_region_length("bwram");
497
498 if (get_software_region("wram") != nullptr)
499 prgram_size = get_software_region_length("wram");
500
501 if (get_feature("mirroring"))
502 {
503 const char *mirroring = get_feature("mirroring");
504 if (!strcmp(mirroring, "horizontal"))
505 m_cart->set_mirroring(PPU_MIRROR_HORZ);
506 if (!strcmp(mirroring, "vertical"))
507 m_cart->set_mirroring(PPU_MIRROR_VERT);
508 if (!strcmp(mirroring, "high"))
509 m_cart->set_mirroring(PPU_MIRROR_HIGH);
510 if (!strcmp(mirroring, "low"))
511 m_cart->set_mirroring(PPU_MIRROR_LOW);
512 if (!strcmp(mirroring, "4screen"))
513 {
514 // A few boards uses 4-screen mirroring: Gauntlet (DDROM or TRR1ROM or Tengen 800004),
515 // Rad Racer II (TVROM), and Napoleon Senki (IREM LROG017 with 74*161/161/21/138)
516 m_cart->set_four_screen_vram(true);
517 m_cart->set_mirroring(PPU_MIRROR_4SCREEN);
518 }
519 if (!strcmp(mirroring, "pcb_controlled"))
520 {
521 // A few boards have variants with hardcoded mirroring and variants with mapper
522 // controlled mirroring. We use a variable to avoid the need of dupe devices.
523 // See e.g. HES 6-in-1 vs other HES games, Irem Major League vs other G-101 games,
524 // Sunsoft-2 Shanghai vs Mito Koumon, Camerica BF9093 games vs BF9097 games, etc.
525 // Boards where all games control mirroring do not make real use of this.
526 m_cart->set_pcb_ctrl_mirror(true);
527 }
528 }
529
530 /* Check for pins in specific boards which require them */
531 if (m_pcb_id == STD_CNROM)
532 {
533 int mask = 0, state = 0;
534
535 if (get_feature("chr-pin26") != nullptr)
536 {
537 mask |= 0x01;
538 state |= !strcmp(get_feature("chr-pin26"), "CE") ? 0x01 : 0;
539 }
540 if (get_feature("chr-pin27") != nullptr)
541 {
542 mask |= 0x02;
543 state |= !strcmp(get_feature("chr-pin27"), "CE") ? 0x02 : 0;
544 }
545
546 m_cart->set_ce(mask, state);
547 }
548
549 if (m_pcb_id == TAITO_X1_005 && get_feature("x1-pin17") != nullptr && get_feature("x1-pin31") != nullptr)
550 {
551 if (!strcmp(get_feature("x1-pin17"), "CIRAM A10") && !strcmp(get_feature("x1-pin31"), "NC"))
552 m_cart->set_x1_005_alt(true);
553 }
554
555 if (m_pcb_id == KONAMI_VRC2)
556 {
557 m_cart->set_vrc_lines(nes_cart_get_line(get_feature("vrc2-pin3")),
558 nes_cart_get_line(get_feature("vrc2-pin4")),
559 (nes_cart_get_line(get_feature("vrc2-pin21")) != 10) ? 1 : 0);
560 // osd_printf_error("VRC-2, pin3: A%d, pin4: A%d, pin21: %d\n", nes_cart_get_line(get_feature("vrc2-pin3")), nes_cart_get_line(get_feature("vrc2-pin4")),
561 // nes_cart_get_line(get_feature("vrc2-pin21")));
562 }
563
564 if (m_pcb_id == KONAMI_VRC4)
565 {
566 m_cart->set_vrc_lines(nes_cart_get_line(get_feature("vrc4-pin3")),
567 nes_cart_get_line(get_feature("vrc4-pin4")),
568 0);
569 // osd_printf_error("VRC-4, pin3: A%d, pin4: A%d\n", nes_cart_get_line(get_feature("vrc4-pin3"), nes_cart_get_line(get_feature("vrc4-pin4"));
570 }
571
572 if (m_pcb_id == KONAMI_VRC6)
573 {
574 m_cart->set_vrc_lines(nes_cart_get_line(get_feature("vrc6-pin9")),
575 nes_cart_get_line(get_feature("vrc6-pin10")),
576 0);
577 // osd_printf_error("VRC-6, pin9: A%d, pin10: A%d\n", nes_cart_get_line(get_feature("vrc6-pin9"), nes_cart_get_line(get_feature("vrc6-pin10"));
578 }
579
580 if (m_pcb_id == STD_HKROM || m_pcb_id == TAITO_X1_017)
581 mapper_sram_size = m_cart->get_mapper_sram_size();
582
583 if (m_pcb_id == TAITO_X1_005 || m_pcb_id == NAMCOT_163)
584 {
585 if (get_feature("batt"))
586 mapper_sram_size = m_cart->get_mapper_sram_size();
587 }
588
589 if (m_pcb_id == NAMCOT_163)
590 {
591 if (get_feature("n163-vol"))
592 m_cart->set_n163_vol(n163_get_submapper_num(get_feature("n163-vol")));
593 }
594
595
596 // pirate variants of boards with bus conflict are often not suffering from it
597 // and actually games glitch if bus conflict is emulated...
598 if (get_feature("bus_conflict") && !strcmp(get_feature("bus_conflict"), "no"))
599 m_cart->set_bus_conflict(false);
600
601
602 // SETUP step 4: logging what we have found
603 logerror("Loaded game from softlist:\n");
604 if (get_feature("pcb"))
605 {
606 logerror("-- PCB: %s", get_feature("pcb"));
607 if (m_pcb_id == UNSUPPORTED_BOARD)
608 logerror(" (currently not supported by MESS)");
609 logerror("\n");
610 }
611 logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000);
612 logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000);
613 logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000);
614 logerror("-- PRG NVWRAM: %d\n", battery_size + mapper_sram_size);
615 logerror("-- PRG WRAM: %d\n", prgram_size);
616
617 // SETUP steps 5/6: allocate pointers for PRG/VROM and load the data!
618 m_cart->prg_alloc(prg_size, tag());
619 memcpy(m_cart->get_prg_base(), get_software_region("prg"), prg_size);
620 if (vrom_size)
621 {
622 m_cart->vrom_alloc(vrom_size, tag());
623 memcpy(m_cart->get_vrom_base(), get_software_region("chr"), vrom_size);
624 }
625
626 // SETUP steps 7: allocate the remaining pointer, when needed
627 if (vram_size)
628 m_cart->vram_alloc(vram_size);
629 if (prgram_size)
630 m_cart->prgram_alloc(prgram_size);
631
632 // also nes_smb2j_device needs WRAM initialized to 0xff? check!
633 if (m_pcb_id == UNL_SMB2J)
634 memset(m_cart->get_prgram_base(), 0xff, prgram_size);
635
636 // Attempt to load a battery file for this ROM
637 // A few boards have internal RAM with a battery (MMC6, Taito X1-005 & X1-017, etc.)
638 if (battery_size || mapper_sram_size)
639 {
640 uint32_t tot_size = battery_size + mapper_sram_size;
641 std::vector<uint8_t> temp_nvram(tot_size);
642
643 // some games relies on specific battery patterns to work
644 // (e.g. Silva Saga does not work with SRAM fully initialized to 0x00)
645 // and we use the info from xml here to prepare a default NVRAM
646 std::vector<uint8_t> default_nvram(tot_size);
647 if (battery_size)
648 memcpy(&default_nvram[0], get_software_region("bwram"), battery_size);
649 if (mapper_sram_size)
650 memset(&default_nvram[battery_size], 0, mapper_sram_size);
651
652 // load battery (using default if no battery exists)
653 battery_load(&temp_nvram[0], tot_size, &default_nvram[0]);
654
655 // copy battery into PCB arrays
656 if (battery_size)
657 {
658 m_cart->battery_alloc(battery_size);
659 memcpy(m_cart->get_battery_base(), &temp_nvram[0], battery_size);
660 }
661 if (mapper_sram_size)
662 memcpy(m_cart->get_mapper_sram_base(), &temp_nvram[battery_size], mapper_sram_size);
663 }
664 }
665