/***************************************************************************************** NES MMC Emulation Support for iNES Mappers ****************************************************************************************/ /* Set to generate prg & chr files when the cart is loaded */ #define SPLIT_PRG 0 #define SPLIT_CHR 0 /************************************************************* mmc_list Supported mappers and corresponding pcb id *************************************************************/ struct nes_mmc { int iNesMapper; /* iNES Mapper # */ int pcb_id; }; static const nes_mmc mmc_list[] = { /* INES DESC LOW_W, LOW_R, MED_W, HIGH_W, PPU_latch, scanline CB, hblank CB */ { 0, STD_NROM }, { 1, STD_SXROM }, { 2, STD_UXROM }, { 3, STD_CNROM }, { 4, STD_TXROM }, { 5, STD_EXROM }, { 6, FFE4_BOARD }, { 7, STD_AXROM }, { 8, FFE3_BOARD }, { 9, STD_PXROM }, { 10, STD_FXROM }, { 11, DIS_74X377 }, { 12, REXSOFT_DBZ5 }, { 13, STD_CPROM }, { 14, REXSOFT_SL1632 }, { 15, WAIXING_WXZS2 }, { 16, BANDAI_LZ93EX2 }, // with 24c02 { 17, FFE8_BOARD }, { 18, JALECO_SS88006 }, { 19, NAMCOT_163 }, { 21, KONAMI_VRC4 }, { 22, KONAMI_VRC2 }, { 23, KONAMI_VRC2 }, { 24, KONAMI_VRC6 }, { 25, KONAMI_VRC4 }, { 26, KONAMI_VRC6 }, { 27, UNL_WORLDHERO }, // 27 World Hero board - Unsupported // 28 Unused // 29 Unused // 30 Unused // 31 Unused { 32, IREM_G101 }, { 33, TAITO_TC0190FMC }, { 34, STD_BXROM }, { 35, UNL_SC127 }, { 36, TXC_STRIKEW }, { 37, PAL_ZZ }, { 38, DIS_74X161X138 }, { 39, UNL_STUDYNGAME }, { 40, BTL_SMB2JA }, { 41, CALTRON_6IN1 }, { 42, BTL_MARIOBABY }, // ai senshi nicole too, changed by crc_hack { 43, UNL_SMB2J }, { 44, BMC_SUPERBIG_7IN1 }, { 45, BMC_HIK8IN1 }, { 46, RUMBLESTATION_BOARD }, { 47, NES_QJ }, { 48, TAITO_TC0190FMCP }, { 49, BMC_SUPERHIK_4IN1 }, { 50, BTL_SMB2JB }, { 51, BMC_BALLGAMES_11IN1 }, { 52, BMC_GOLD_7IN1 }, { 53, SVISION16_BOARD }, { 54, BMC_NOVEL1 }, // 55 Genius SMB - No info (nor images) available { 56, KAISER_KS202 }, { 57, BMC_GKA }, { 58, BMC_GKB }, // 59 Unused // 60 4-in-1, 35-in-1 Reset based { 61, RCM_TF9IN1 }, { 62, BMC_SUPER_700IN1 }, { 63, BMC_CH001 }, // Powerful 255 { 64, TENGEN_800032 }, { 65, IREM_H3001 }, { 66, STD_GXROM }, { 67, SUNSOFT_3 }, { 68, SUNSOFT_DCS }, { 69, SUNSOFT_FME7 }, { 70, DIS_74X161X161X32 }, { 71, CAMERICA_BF9093 }, { 72, JALECO_JF17 }, { 73, KONAMI_VRC3 }, { 74, WAIXING_TYPE_A }, { 75, KONAMI_VRC1 }, { 76, NAMCOT_3446 }, { 77, IREM_LROG017 }, { 78, IREM_HOLYDIVR }, { 79, AVE_NINA06 }, { 80, TAITO_X1_005 }, // 81 Unused { 82, TAITO_X1_017 }, { 83, CONY_BOARD }, // 84 Pasofami hacked images? { 85, KONAMI_VRC7 }, { 86, JALECO_JF13 }, { 87, DIS_74X139X74 }, { 88, NAMCOT_34X3 }, { 89, SUNSOFT_2 }, { 90, JYCOMPANY_A }, { 91, UNL_MK2 }, { 92, JALECO_JF19 }, { 93, SUNSOFT_2 }, { 94, STD_UN1ROM }, { 95, NAMCOT_3425 }, { 96, BANDAI_OEKAKIDS }, { 97, IREM_TAM_S1 }, // 98 Unused // 99 VS. system - Not going to be implemented (use MAME instead) // 100 images hacked to work with nesticle? // 101 Unused (Urusei Yatsura had been assigned to this mapper, but it's Mapper 87) // 102 Unused { 103, UNL_2708 }, // 103 Bootleg cart 2708 (Doki Doki Panic - FDS Conversion) - Unsupported { 104, CAMERICA_GOLDENFIVE }, { 105, STD_EVENT }, { 106, BTL_SMB3 }, { 107, MAGICSERIES_MD }, { 108, WHIRLWIND_2706 }, // 109 Unused // 110 Unused // 111 Ninja Ryuukenden Chinese? - Unsupported { 112, NTDEC_ASDER }, { 113, HES_BOARD }, { 114, SUPERGAME_LIONKING }, { 115, KASING_BOARD }, { 116, SOMARI_SL12 }, { 117, FUTUREMEDIA_BOARD }, { 118, STD_TXSROM }, { 119, STD_TQROM }, { 120, BTL_TOBIDASE }, { 121, KAY_BOARD }, // 122 Unused { 123, UNL_H2288 }, // 124 Unused // 125 Unused { 126, BMC_PJOY84 }, // 127 Unused // 128 Unused // 129 Unused // 130 Unused // 131 Unused { 132, TXC_22211 }, { 133, SACHEN_SA72008 }, { 134, BMC_FAMILY_4646 }, // 135 Unused { 136, SACHEN_TCU02 }, { 137, SACHEN_8259D }, { 138, SACHEN_8259B }, { 139, SACHEN_8259C }, { 140, JALECO_JF11 }, { 141, SACHEN_8259A }, { 142, KAISER_KS7032}, { 143, SACHEN_TCA01 }, { 144, AGCI_50282 }, { 145, SACHEN_SA72007 }, { 146, AVE_NINA06 }, // basically same as Mapper 79 (Nina006) { 147, SACHEN_TCU01 }, { 148, SACHEN_SA0037 }, { 149, SACHEN_SA0036 }, { 150, SACHEN_74LS374 }, // 151 VS. system by Konami - Not going to be implemented (use MAME instead) { 152, DIS_74X161X161X32 }, { 153, BANDAI_LZ93 }, { 154, NAMCOT_34X3 }, { 155, STD_SXROM_A }, // diff compared to MMC1 concern WRAM { 156, OPENCORP_DAOU306 }, { 157, BANDAI_DATACH }, // no Datach Reader -> we fall back to mapper 16 { 158, TENGEN_800037 }, { 159, BANDAI_LZ93EX1 }, // with 24c01 { 160, SACHEN_SA009 }, // 161 Unused // 162 Unused { 163, NANJING_BOARD}, { 164, WAIXING_FFV }, { 165, WAIXING_SH2 }, { 166, SUBOR_TYPE1 }, { 167, SUBOR_TYPE0 }, { 168, UNL_RACERMATE }, // 169 Unused // 170 Fujiya { 171, KAISER_KS7058 }, { 172, TXC_DUMARACING }, { 173, TXC_MJBLOCK }, // 174 Unused { 175, KAISER_KS7022}, { 176, UNL_XIAOZY }, { 177, HENGG_SRICH }, { 178, WAIXING_SGZLZ }, { 179, HENGG_XHZS }, { 180, UXROM_CC }, // 181 Unused { 182, HOSENKAN_BOARD }, { 183, BTL_SHUIGUAN }, { 184, SUNSOFT_1 }, { 185, STD_CNROM }, { 186, FUKUTAKE_BOARD }, { 187, UNL_KOF96 }, { 188, BANDAI_KARAOKE }, { 189, TXC_TW }, // 190 Unused { 191, WAIXING_TYPE_B }, { 192, WAIXING_TYPE_C }, { 193, NTDEC_FIGHTINGHERO }, { 194, WAIXING_TYPE_D }, { 195, WAIXING_TYPE_E }, { 196, BTL_SBROS11 }, { 197, UNL_SF3 }, { 198, WAIXING_TYPE_F }, { 199, WAIXING_TYPE_G }, { 200, BMC_36IN1 }, { 201, BMC_21IN1 }, { 202, BMC_150IN1 }, { 203, BMC_35IN1 }, { 204, BMC_64IN1 }, { 205, BMC_15IN1 }, { 206, NAMCOT_34X3 }, { 207, TAITO_X1_005 }, { 208, GOUDER_37017 }, { 209, JYCOMPANY_C }, { 210, NAMCOT_175 }, { 211, JYCOMPANY_B }, { 212, BMC_SUPERHIK_300IN1 }, { 213, BMC_NOVEL2 }, { 214, BMC_SUPERGUN_20IN1 }, { 215, SUPERGAME_BOOGERMAN }, { 216, RCM_GS2015 }, { 217, BMC_GOLDENCARD_6IN1 }, // 218 Unused // 219 UNL-A9746 (according to Cah4e3's code, no dump available (yet) // 220 Unused { 221, UNL_N625092 }, { 222, BTL_DRAGONNINJA }, { 223, WAIXING_TYPE_I }, // (according to NEStopia source, it's MMC3 with more WRAM) { 224, WAIXING_TYPE_J }, // (according to NEStopia source, it's MMC3 with more WRAM) { 225, BMC_72IN1 }, { 226, BMC_76IN1 }, { 227, BMC_1200IN1 }, { 228, ACTENT_ACT52 }, { 229, BMC_31IN1 }, { 230, BMC_22GAMES }, { 231, BMC_20IN1 }, { 232, CAMERICA_BF9096 }, { 233, BMC_SUPER22 }, { 234, AVE_MAXI15 }, { 235, BMC_GOLD150 }, // 235 Golden Game x-in-1 - Unsupported // 236 Game 800-in-1 - Unsupported // 237 Unused { 238, UNL_603_5052 }, // 239 Unused { 240, CNE_SHLZ }, { 241, TXC_COMMANDOS }, { 242, WAIXING_WXZS }, { 243, SACHEN_74LS374_ALT }, { 244, CNE_DECATHLON }, { 245, WAIXING_TYPE_H }, { 246, CNE_FSB }, // 247 Unused // 248 Unused { 249, WAIXING_SECURITY }, { 250, NITRA_TDA }, // 251 Shen Hua Jian Yun III?? - Unsupported { 252, WAIXING_SGZ }, // 253 Super 8-in-1 99 King Fighter?? - Unsupported { 254, BTL_PIKACHUY2K }, { 255, BMC_110IN1 }, }; const nes_mmc *nes_mapper_lookup( int mapper ) { int i; for (i = 0; i < ARRAY_LENGTH(mmc_list); i++) { if (mmc_list[i].iNesMapper == mapper) return &mmc_list[i]; } return NULL; } #if 0 int nes_get_mmc_id( running_machine &machine, int mapper ) { const nes_mmc *mmc = nes_mapper_lookup(mapper); if (mmc == NULL) fatalerror("Unimplemented Mapper %d\n", mapper); return mmc->pcb_id; } #endif /************************************************************* ines_mapr_setup setup the board specific pcb_id for a given mapper *************************************************************/ void ines_mapr_setup( int mapper, int *pcb_id ) { const nes_mmc *mmc = nes_mapper_lookup(mapper); if (mmc == NULL) fatalerror("Unimplemented Mapper %d\n", mapper); *pcb_id = mmc->pcb_id; } /************************************************************* call_load_ines *************************************************************/ void nes_cart_slot_device::call_load_ines() { UINT32 vram_size = 0, prgram_size = 0, battery_size = 0, mapper_sram_size = 0; UINT32 prg_size, vrom_size; UINT8 header[0x10]; UINT8 mapper, local_options; bool ines20 = FALSE, prg16k; const char *mapinfo = NULL; int pcb_id = 0, mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0; int crc_hack = 0; // check if the image is recognized by nes.hsi mapinfo = hashfile_extrainfo(*this); // read out the header fseek(0, SEEK_SET); fread(&header, 0x10); // SETUP step 1: getting PRG, VROM, VRAM sizes prg16k = (header[4] == 1); prg_size = prg16k ? 2 * 0x4000 : header[4] * 0x4000; vrom_size = header[5] * 0x2000; vram_size = 0x4000; // SETUP step 2: getting PCB and other settings mapper = (header[6] & 0xf0) >> 4; local_options = header[6] & 0x0f; switch (header[7] & 0xc) { case 0x4: case 0xc: // probably the header got corrupted: don't trust upper bits for mapper break; case 0x8: // it's iNES 2.0 format ines20 = TRUE; case 0x0: default: mapper |= header[7] & 0xf0; break; } // use info from nes.hsi if available! if (mapinfo) { if (4 == sscanf(mapinfo,"%d %d %d %d", &mapint1, &mapint2, &mapint3, &mapint4)) { /* image is present in nes.hsi: overwrite the header settings with these */ mapper = mapint1; local_options = mapint2 & 0x0f; crc_hack = (mapint2 & 0xf0) >> 4; // this is used to differentiate among variants of the same Mapper (see below) prg16k = (mapint3 == 1); prg_size = prg16k ? 2 * 0x4000 : mapint3 * 0x4000; vrom_size = mapint4 * 0x2000; logerror("NES.HSI info: %d %d %d %d\n", mapint1, mapint2, mapint3, mapint4); } else { logerror("NES: [%s], Invalid mapinfo found\n", mapinfo); } } else { logerror("NES: No extrainfo found\n"); } // use extended iNES2.0 info if available! if (ines20) { mapper |= (header[8] & 0x0f) << 8; // header[8] & 0xf0 is used for submappers, but I haven't found any specific image to implement this prg_size += ((header[9] & 0x0f) << 8) * 0x4000; vrom_size += ((header[9] & 0xf0) << 4) * 0x2000; } ines_mapr_setup(mapper, &pcb_id); // SETUP step 3: storing the info needed for emulation m_pcb_id = pcb_id; m_cart->set_mirroring(BIT(local_options, 0) ? PPU_MIRROR_VERT : PPU_MIRROR_HORZ); if (BIT(local_options, 1)) battery_size = NES_BATTERY_SIZE; // with original iNES format we can only support 8K WRAM battery m_cart->set_trainer(BIT(local_options, 2) ? TRUE : FALSE); m_cart->set_four_screen_vram(BIT(local_options, 3) ? TRUE : FALSE); if (ines20) { // PRGRAM/BWRAM (not fully supported, also due to lack of 2.0 files) if ((header[10] & 0x0f) > 0) prgram_size = 0x80 << ((header[10] & 0x0f) - 1); if ((header[10] & 0xf0) > 0) battery_size = 0x80 << ((header[10] & 0xf0) - 5); // VRAM vram_size = 0; if ((header[11] & 0x0f) > 0) vram_size = 0x80 << ((header[11] & 0x0f) - 1); // header[11] & 0xf0 is the size of battery backed VRAM, found so far in Racermate II only and not supported yet } else { // PRGRAM size is 8k for most games, but pirate carts often use different sizes, // so its size has been added recently to the iNES format spec, but almost no image uses it prgram_size = header[8] ? header[8] * 0x2000 : 0x2000; } // a few mappers correspond to multiple PCBs, so we need a few additional checks and tweaks switch (m_pcb_id) { case STD_CNROM: if (mapper == 185) { switch (crc_hack) { case 0x0: // pin26: CE, pin27: CE (B-Wings, Bird Week) m_cart->set_ce(0x03, 0x03); break; case 0x4: // pin26: CE, pin27: /CE (Mighty Bomb Jack, Spy Vs. Spy) m_cart->set_ce(0x03, 0x01); break; case 0x8: // pin26: /CE, pin27: CE (Sansu 1, 2, 3 Nen) m_cart->set_ce(0x03, 0x02); break; case 0xc: // pin26: /CE, pin27: /CE (Seicross v2.0) m_cart->set_ce(0x03, 0x00); break; } } break; case KONAMI_VRC2: if (mapper == 22) m_cart->set_vrc_lines(0, 1, 1); if (mapper == 23 && !crc_hack) m_cart->set_vrc_lines(1, 0, 0); if (mapper == 23 && crc_hack) { // here there are also Akumajou Special, Crisis Force, Parodius da!, Tiny Toons which are VRC-4 m_cart->set_vrc_lines(3, 2, 0); m_pcb_id = KONAMI_VRC4; // this allows for konami_irq to be installed at reset } break; case KONAMI_VRC4: if (mapper == 21) // Wai Wai World 2 & Ganbare Goemon Gaiden 2 (the latter with crc_hack) m_cart->set_vrc_lines(crc_hack ? 7 : 2, crc_hack ? 6 : 1, 0); if (mapper == 25) // here there is also Ganbare Goemon Gaiden which is VRC-2 m_cart->set_vrc_lines(crc_hack ? 2 : 0, crc_hack ? 3 : 1, 0); break; case KONAMI_VRC6: if (mapper == 24) m_cart->set_vrc_lines(1, 0, 0); if (mapper == 26) m_cart->set_vrc_lines(0, 1, 0); break; case IREM_G101: if (crc_hack) m_cart->set_mirroring(PPU_MIRROR_HIGH); // Major League has hardwired mirroring else m_cart->set_pcb_ctrl_mirror(TRUE); break; case DIS_74X161X161X32: if (mapper == 70) m_cart->set_mirroring(PPU_MIRROR_VERT); // only hardwired mirroring makes different mappers 70 & 152 else m_cart->set_pcb_ctrl_mirror(TRUE); break; case SUNSOFT_2: if (mapper == 93) m_cart->set_mirroring(PPU_MIRROR_VERT); // only hardwired mirroring makes different mappers 89 & 93 else m_cart->set_pcb_ctrl_mirror(TRUE); break; case HES_BOARD: if (crc_hack) m_cart->set_pcb_ctrl_mirror(TRUE); // Mapper 113 is used for 2 diff boards break; case CAMERICA_BF9093: if (crc_hack) m_cart->set_pcb_ctrl_mirror(TRUE); // Mapper 71 is used for 2 diff boards break; case STD_BXROM: if (crc_hack) m_pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards break; case BANDAI_LZ93: if (crc_hack) m_pcb_id = BANDAI_FJUMP2; // Mapper 153 is used for 2 diff boards break; case IREM_HOLYDIVR: if (crc_hack) m_pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards break; case WAIXING_WXZS: if (crc_hack) m_pcb_id = WAIXING_DQ8; // Mapper 242 is used for 2 diff boards break; case BMC_GOLD_7IN1: if (crc_hack) m_pcb_id = BMC_MARIOPARTY_7IN1; // Mapper 52 is used for 2 diff boards break; case BTL_MARIOBABY: if (crc_hack) m_pcb_id = BTL_AISENSHINICOL; // Mapper 42 is used for 2 diff boards break; case TAITO_X1_017: mapper_sram_size = m_cart->get_mapper_sram_size(); break; case TAITO_X1_005: if (mapper == 207) m_cart->set_x1_005_alt(TRUE); mapper_sram_size = m_cart->get_mapper_sram_size(); break; case NAMCOT_163: mapper_sram_size = m_cart->get_mapper_sram_size(); break; //FIXME: we also have to fix Action 52 PRG loading somewhere... } // Finally turn off bus conflict emulation, because the pirate variants of the boards are bus conflict free and games would glitch m_cart->set_bus_conflict(FALSE); // SETUP step 4: logging what we have found if (!ines20) { logerror("Loaded game in iNES format:\n"); logerror("-- Mapper %d\n", mapper); logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000); logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000); logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000); if (battery_size) logerror("-- Battery found\n"); if (m_cart->get_trainer()) logerror("-- Trainer found\n"); if (m_cart->get_four_screen_vram()) logerror("-- 4-screen VRAM\n"); logerror("-- TV System: %s\n", ((header[10] & 3) == 0) ? "NTSC" : (header[10] & 1) ? "Both NTSC and PAL" : "PAL"); } else { logerror("Loaded game in Extended iNES format:\n"); logerror("-- Mapper: %d\n", mapper); logerror("-- Submapper: %d\n", (header[8] & 0xf0) >> 4); logerror("-- PRG 0x%x (%d x 16k chunks)\n", prg_size, prg_size / 0x4000); logerror("-- VROM 0x%x (%d x 8k chunks)\n", vrom_size, vrom_size / 0x2000); logerror("-- VRAM 0x%x (%d x 8k chunks)\n", vram_size, vram_size / 0x2000); logerror("-- PRG NVWRAM: %d\n", header[10] & 0x0f); logerror("-- PRG WRAM: %d\n", (header[10] & 0xf0) >> 4); logerror("-- CHR NVWRAM: %d\n", header[11] & 0x0f); logerror("-- CHR WRAM: %d\n", (header[11] & 0xf0) >> 4); logerror("-- TV System: %s\n", (header[12] & 2) ? "Both NTSC and PAL" : (header[12] & 1) ? "PAL" : "NTSC"); } // SETUP step 5: allocate pointers for PRG/VROM if (prg_size) m_cart->prg_alloc(machine(), prg_size); if (vrom_size) m_cart->vrom_alloc(machine(), vrom_size); // if there is a trainer, skip it for the moment if (m_cart->get_trainer()) fseek(0x210, SEEK_SET); // SETUP step 6: at last load the data! // Read in the program chunks if (prg16k) { fread(m_cart->get_prg_base(), 0x4000); memcpy(m_cart->get_prg_base() + 0x4000, m_cart->get_prg_base(), 0x4000); } else fread(m_cart->get_prg_base(), m_cart->get_prg_size()); #if SPLIT_PRG { FILE *prgout; char outname[255]; sprintf(outname, "%s.prg", filename()); prgout = fopen(outname, "wb"); if (prgout) { fwrite(m_cart->get_prg_base(), 1, 0x4000 * m_cart->get_prg_size(), prgout); mame_printf_error("Created PRG chunk\n"); } fclose(prgout); } #endif // Read in any chr chunks if (m_cart->get_vrom_size()) fread(m_cart->get_vrom_base(), m_cart->get_vrom_size()); #if SPLIT_CHR if (state->m_chr_chunks > 0) { FILE *chrout; char outname[255]; sprintf(outname, "%s.chr", filename()); chrout= fopen(outname, "wb"); if (chrout) { fwrite(m_cart->get_vrom_base(), 1, m_cart->get_vrom_size(), chrout); mame_printf_error("Created CHR chunk\n"); } fclose(chrout); } #endif // SETUP steps 7: allocate the remaining pointer, when needed if (vram_size) m_cart->vram_alloc(machine(), vram_size); if (prgram_size || m_cart->get_trainer()) { if (prgram_size) m_cart->prgram_alloc(machine(), prgram_size); else m_cart->prgram_alloc(machine(), 0x2000); if (m_cart->get_trainer()) { fseek(0x10, SEEK_SET); fread(m_cart->get_prgram_base() + 0x1000, 0x200); } } // Attempt to load a battery file for this ROM // A few boards have internal RAM with a battery (MMC6, Taito X1-005 & X1-017, etc.) if (battery_size || mapper_sram_size) { UINT32 tot_size = battery_size + mapper_sram_size; UINT8 *temp_nvram = auto_alloc_array(machine(), UINT8, tot_size); battery_load(temp_nvram, tot_size, 0x00); if (battery_size) { m_cart->battery_alloc(machine(), battery_size); memcpy(m_cart->get_battery_base(), temp_nvram, battery_size); } if (mapper_sram_size) memcpy(m_cart->get_mapper_sram_base(), temp_nvram + battery_size, m_cart->get_mapper_sram_size()); if (temp_nvram) auto_free(machine(), temp_nvram); } } const char * nes_cart_slot_device::get_default_card_ines(UINT8 *ROM, UINT32 len) { UINT8 mapper; bool ines20 = FALSE; const char *mapinfo = NULL; int pcb_id = 0, mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0; int crc_hack = 0; // check if the image is recognized by nes.hsi // mapinfo = hashfile_extrainfo(*this); mapper = (ROM[6] & 0xf0) >> 4; switch (ROM[7] & 0xc) { case 0x4: case 0xc: // probably the header got corrupted: don't trust upper bits for mapper break; case 0x8: // it's iNES 2.0 format ines20 = TRUE; case 0x0: default: mapper |= ROM[7] & 0xf0; break; } // use info from nes.hsi if available! if (mapinfo) { if (4 == sscanf(mapinfo,"%d %d %d %d", &mapint1, &mapint2, &mapint3, &mapint4)) { /* image is present in nes.hsi: overwrite the header settings with these */ mapper = mapint1; crc_hack = (mapint2 & 0xf0) >> 4; // this is used to differentiate among variants of the same Mapper (see below) } } // use extended iNES2.0 info if available! if (ines20) { mapper |= (ROM[8] & 0x0f) << 8; // ROM[8] & 0xf0 is used for submappers, but I haven't found any specific image to implement this } ines_mapr_setup(mapper, &pcb_id); // solve mapper conflicts switch (pcb_id) { case KONAMI_VRC2: if (mapper == 23 && crc_hack) m_pcb_id = KONAMI_VRC4; // this allows for konami_irq to be installed at reset break; case STD_BXROM: if (crc_hack) m_pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards break; case BANDAI_LZ93: if (crc_hack) m_pcb_id = BANDAI_FJUMP2; // Mapper 153 is used for 2 diff boards break; case IREM_HOLYDIVR: if (crc_hack) m_pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards break; case WAIXING_WXZS: if (crc_hack) m_pcb_id = WAIXING_DQ8; // Mapper 242 is used for 2 diff boards break; case BMC_GOLD_7IN1: if (crc_hack) m_pcb_id = BMC_MARIOPARTY_7IN1; // Mapper 52 is used for 2 diff boards break; case BTL_MARIOBABY: if (crc_hack) m_pcb_id = BTL_AISENSHINICOL; // Mapper 42 is used for 2 diff boards break; } return nes_get_slot(pcb_id); }