diff options
Diffstat (limited to 'src/devices/bus/nes/nes_ines.inc')
-rw-r--r-- | src/devices/bus/nes/nes_ines.inc | 939 |
1 files changed, 939 insertions, 0 deletions
diff --git a/src/devices/bus/nes/nes_ines.inc b/src/devices/bus/nes/nes_ines.inc new file mode 100644 index 00000000000..ceb9581b82f --- /dev/null +++ b/src/devices/bus/nes/nes_ines.inc @@ -0,0 +1,939 @@ +// license:BSD-3-Clause +// copyright-holders:Fabio Priuli +/***************************************************************************************** + + 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, BTL_ACTION53 }, // 28 - Multi-discrete PCB designed by Tepples for Action 53 + // 29 Unused + // 30 UNROM 512 + Flash, currently unsupported + { 31, BTL_2A03_PURITANS }, // 31 - PCB designed by infinitelives & rainwarrior for 2A03 Puritans Album + { 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 }, // Datach Reader games -> must go in the Datach subslot + { 158, TENGEN_800037 }, + { 159, BANDAI_LZ93EX1 }, // with 24c01 + { 160, SACHEN_SA009 }, + // 161 Unused + { 162, WAIXING_FS304}, // not confirmed, but a lot of chinese releases use it like this... + { 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, NOCASH_NOCHR }, + // 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, submapper = 0, local_options; + bool ines20 = FALSE, prg16k; + std::string mapinfo; + int pcb_id = 0, mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0; + int crc_hack = 0; + bool bus_conflict = FALSE; + + // 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 (hashfile_extrainfo(*this, mapinfo)) + { + if (4 == sscanf(mapinfo.c_str(),"%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.c_str()); + } + } + else + { + logerror("NES: No extrainfo found\n"); + } + + // use extended iNES2.0 info if available! + if (ines20) + { + mapper |= (header[8] & 0x0f) << 8; + // read submappers (based on 20140116 specs) + submapper = (header[8] & 0xf0 >> 8); + prg_size += ((header[9] & 0x0f) << 8) * 0x4000; + vrom_size += ((header[9] & 0xf0) << 4) * 0x2000; + } + ines_mapr_setup(mapper, &pcb_id); + + // handle submappers + if (submapper) + { + // 001: MMC1 + if (mapper == 1 && submapper == 3) + pcb_id = STD_SXROM_A; + else if (mapper == 1 && submapper == 5) + logerror("Unimplemented iNES2.0 submapper: SEROM/SHROM/SH1ROM.\n"); + // 002, 003, 007: UxROM, CNROM, AxROM + else if (mapper == 2 && submapper == 2) + bus_conflict = TRUE; + else if (mapper == 3 && submapper == 2) + bus_conflict = TRUE; + else if (mapper == 7 && submapper == 2) + bus_conflict = TRUE; + // 021, 023, 025: VRC4 / VRC2 + else if (mapper == 21 || mapper == 23 || mapper == 25) + { + // 021, 023, 025: VRC4 + int line_1 = submapper & 0x07; + int line_2 = (submapper & 0x08) ? line_1 + 1 : line_1 - 1; + if (line_2 >= 0 && line_2 <= 7) + { + pcb_id = KONAMI_VRC4; + m_cart->set_vrc_lines(line_1, line_2, 0); + } + else if (submapper == 15) + { + pcb_id = KONAMI_VRC2; + m_cart->set_vrc_lines(1, 0, 0); + } + } + // 032: Irem G101 + else if (mapper == 32 && submapper == 1) + { + m_cart->set_mirroring(PPU_MIRROR_HIGH); // Major League has hardwired mirroring + } + // iNES Mapper 034 + else if (mapper == 34 && submapper == 1) + { + pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards + } + // iNES Mapper 068 / Sunsoft 4 + else if (mapper == 68 && submapper == 1) + { + submapper = 0; + logerror("Unimplemented iNES2.0 submapper: SUNSOFT-DCS.\n"); + } + // iNES Mapper 071 + else if (mapper == 71 && submapper == 1) + { + m_cart->set_pcb_ctrl_mirror(TRUE); // Mapper 71 is used for 2 diff boards + } + // iNES Mapper 078 + else if (mapper == 78) + { + if (submapper == 1) + pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards + else if (submapper == 3) + pcb_id = IREM_HOLYDIVR; + } + // iNES Mapper 185 + else if (mapper == 185) + { + int ce_state = (submapper & 0x0c) >> 2; + m_cart->set_ce(0x03, ce_state); + } + // iNES Mapper 232 + else if (mapper == 210 && submapper == 1) + { + submapper = 0; + logerror("Unimplemented iNES2.0 submapper: CAMERICA-BF9096.\n"); + } + else if (submapper) + { + submapper = 0; + logerror("Undocumented iNES2.0 submapper, please report it to the MESS boards!\n"); + } + } + + // 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) >> 4) - 1); + // VRAM + vram_size = 0; + if ((header[11] & 0x0f) > 0) + vram_size = 0x80 << ((header[11] & 0x0f) - 1); + if ((header[11] & 0xf0) > 0) + vram_size |= 0x80 << (((header[11] & 0xf0) >> 4) - 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_NROM: + if (prg_size == 3 * 0x4000) // NROM368 are padded with 2k empty data at start to accomplish with iNES standard + { + m_pcb_id = STD_NROM368; + fseek(0x810, SEEK_SET); + prg_size = 0xb800; + } + break; + + case NOCASH_NOCHR: + // this mapper uses mirroring flags differently + m_cart->set_four_screen_vram(FALSE); + switch (local_options & 0x09) + { + case 0x00: + m_cart->set_mirroring(PPU_MIRROR_HORZ); + break; + case 0x01: + m_cart->set_mirroring(PPU_MIRROR_VERT); + break; + case 0x08: + m_cart->set_mirroring(PPU_MIRROR_LOW); + break; + case 0x09: + m_cart->set_mirroring(PPU_MIRROR_HIGH); + break; + } + break; + + case STD_CNROM: + if (mapper == 185 && !submapper) + { + 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, Othello) + 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 && !submapper) + m_cart->set_vrc_lines(1, 0, 0); + if (mapper == 23 && crc_hack && !submapper) + { + // 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 && !submapper) // 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 && !submapper) // 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 && !submapper) + m_cart->set_mirroring(PPU_MIRROR_HIGH); // Major League has hardwired mirroring + else if (!submapper) + 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 && !submapper) + m_cart->set_pcb_ctrl_mirror(TRUE); // Mapper 71 is used for 2 diff boards + break; + + case STD_BXROM: + if (crc_hack && !submapper) + 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 && !submapper) + 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... + + case BANDAI_DATACH: + fatalerror("Bandai Datach games have to be mounted in the Datach subslot!\n"); + break; + } + + // 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(bus_conflict); + + // 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); + logerror("-- Mirroring %s\n", BIT(header[6], 0) ? "Vertical" : "Horizontal"); + 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] & 0xf0) >> 4); + logerror("-- PRG WRAM: %d\n", header[10] & 0x0f); + logerror("-- CHR NVWRAM: %d\n", (header[11] & 0xf0) >> 4); + logerror("-- CHR WRAM: %d\n", header[11] & 0x0f); + 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(prg_size, tag()); + if (vrom_size) + m_cart->vrom_alloc(vrom_size, tag()); + + // 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); + osd_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); + osd_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(vram_size); + if (prgram_size || m_cart->get_trainer()) + { + if (prgram_size) + m_cart->prgram_alloc(prgram_size); + else + m_cart->prgram_alloc(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; + dynamic_buffer temp_nvram(tot_size); + battery_load(&temp_nvram[0], tot_size, 0x00); + if (battery_size) + { + //printf("here %d\n", battery_size); + m_cart->battery_alloc(battery_size); + memcpy(m_cart->get_battery_base(), &temp_nvram[0], battery_size); + } + if (mapper_sram_size) + memcpy(m_cart->get_mapper_sram_base(), &temp_nvram[battery_size], m_cart->get_mapper_sram_size()); + } +} + +const char * nes_cart_slot_device::get_default_card_ines(UINT8 *ROM, UINT32 len) +{ + UINT8 mapper, submapper = 0; + bool ines20 = FALSE; + std::string mapinfo; + int pcb_id = 0, mapint1 = 0, mapint2 = 0, mapint3 = 0, mapint4 = 0; + int crc_hack = 0; + + 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 (hashfile_extrainfo(*this, mapinfo)) + { + if (4 == sscanf(mapinfo.c_str(),"%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; + // read submappers (based on 20140116 specs) + submapper = (ROM[8] & 0xf0 >> 8); + } + + ines_mapr_setup(mapper, &pcb_id); + + // handle submappers + if (submapper) + { + // 001: MMC1 + if (mapper == 1 && submapper == 3) + pcb_id = STD_SXROM_A; + else if (mapper == 1 && submapper == 5) + logerror("Unimplemented iNES2.0 submapper: SEROM/SHROM/SH1ROM.\n"); + // 021, 023, 025: VRC4 / VRC2 + else if (mapper == 21 || mapper == 23 || mapper == 25) + { + // 021, 023, 025: VRC4 + int line_1 = submapper & 0x07; + int line_2 = (submapper & 0x08) ? line_1 + 1 : line_1 - 1; + if (line_2 >= 0 && line_2 <= 7) + pcb_id = KONAMI_VRC4; + else if (submapper == 15) + pcb_id = KONAMI_VRC2; + } + // iNES Mapper 034 + else if (mapper == 34 && submapper == 1) + { + pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards + } + // iNES Mapper 078 + else if (mapper == 78) + { + if (submapper == 1) + pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards + else if (submapper == 3) + pcb_id = IREM_HOLYDIVR; + } + } + + // solve mapper conflicts + switch (pcb_id) + { + case STD_NROM: + if (ROM[4] == 3) + pcb_id = STD_NROM368; + break; + + case KONAMI_VRC2: + if (mapper == 23 && crc_hack && !submapper) + pcb_id = KONAMI_VRC4; // this allows for konami_irq to be installed at reset + break; + + case STD_BXROM: + if (crc_hack && !submapper) + pcb_id = AVE_NINA01; // Mapper 34 is used for 2 diff boards + break; + + case BANDAI_LZ93: + if (crc_hack) + pcb_id = BANDAI_FJUMP2; // Mapper 153 is used for 2 diff boards + break; + + case IREM_HOLYDIVR: + if (crc_hack && !submapper) + pcb_id = JALECO_JF16; // Mapper 78 is used for 2 diff boards + break; + + case WAIXING_WXZS: + if (crc_hack) + pcb_id = WAIXING_DQ8; // Mapper 242 is used for 2 diff boards + break; + + case BMC_GOLD_7IN1: + if (crc_hack) + pcb_id = BMC_MARIOPARTY_7IN1; // Mapper 52 is used for 2 diff boards + break; + + case BTL_MARIOBABY: + if (crc_hack) + pcb_id = BTL_AISENSHINICOL; // Mapper 42 is used for 2 diff boards + break; + } + + return nes_get_slot(pcb_id); +} |