From 51199e59d771124860d81d6fe4c5b0a396581773 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Fri, 5 Jul 2019 22:46:22 +0800 Subject: [PATCH 1/6] NES 2.0: Add preliminary support for iNES 2.0 format Currently reads and sets the following: - mapper number up to 4095, prg rom size, chr rom size - chr ram (volatile + non-volatile), region (ntsc, pal, dendy or multi-region) todo: submapper handling, w-ram and prg nvram at least... --- src/boards/unrom512.c | 6 +- src/cart.h | 8 +- src/ines.c | 241 +++++++++++++++++++++++++++--------------- src/ines.h | 9 +- src/unif.c | 2 +- 5 files changed, 176 insertions(+), 90 deletions(-) diff --git a/src/boards/unrom512.c b/src/boards/unrom512.c index 59ac51d..5e703b0 100644 --- a/src/boards/unrom512.c +++ b/src/boards/unrom512.c @@ -217,9 +217,9 @@ void UNROM512_Init(CartInfo *info) { flash_bank = 0; flash_save = info->battery; - if (info->vram_size == 8192) + if (info->chrRam == 8192) chrram_mask = 0; - else if (info->vram_size == 16384) + else if (info->chrRam == 16384) chrram_mask = 0x20; else chrram_mask = 0x60; @@ -236,7 +236,7 @@ void UNROM512_Init(CartInfo *info) { SetupCartMirroring(MI_0, 0, NULL); break; case 3: /* hard four screen, last 8k of 32k RAM (flags: 4-screen + vertical) */ - SetupCartMirroring(4, 1, VROM + (info->vram_size - 8192)); + SetupCartMirroring(4, 1, VROM + (info->chrRam - 8192)); break; } bus_conflict = !info->battery; diff --git a/src/cart.h b/src/cart.h index 16ab243..66f3e83 100644 --- a/src/cart.h +++ b/src/cart.h @@ -10,6 +10,7 @@ typedef struct { uint32 SaveGameLen[4]; /* How much memory to save/load. */ /* Set by iNES/UNIF loading code. */ + int iNES2; /* iNES version */ int mapper; /* mapper used */ int submapper; /* submapper used */ /* TODO: */ int mirror; /* As set in the header or chunk. @@ -19,7 +20,12 @@ typedef struct { * set to mapper 4. */ int battery; /* Presence of an actual battery. */ - int vram_size; + int prgRam; /* prg ram size (volatile) */ + int chrRam; /* chr ram size (volatile) */ + int prgRam_battery; /* prg ram size (non-volatile or battery backed) */ + int chrRam_battery; /* chr ram size (non-volatile or battery backed) */ + int region; /* video system timing (ntsc, pal, dendy */ + uint8 MD5[16]; uint32 CRC32; /* Should be set by the iNES/UNIF loading * code, used by mapper/board code, maybe diff --git a/src/ines.c b/src/ines.c index 656337a..68371f2 100644 --- a/src/ines.c +++ b/src/ines.c @@ -57,7 +57,9 @@ uint32 VROM_size = 0; static int CHRRAMSize = -1; static int iNES_Init(int num); +static int iNES2 = 0; static int MapperNo = 0; +static int subMapper = 0; static DECLFR(TrainerRead) { return(trainerpoo[A & 0x1FF]); @@ -376,7 +378,7 @@ static void CheckHInfo(void) { if (tofix & 8) strcat(gigastr, "This game should not have any CHR ROM. "); strcat(gigastr, "\n"); - FCEU_printf("%s", gigastr); + FCEU_printf("%s\n", gigastr); } } @@ -661,14 +663,19 @@ static BMAPPINGLocal bmap[] = { int iNESLoad(const char *name, FCEUFILE *fp) { struct md5_context md5; - char* mappername; - uint32 mappertest; + char* mappername = NULL; + uint32 filesize = fp->fp->size; + uint32 mappertest = 0; + uint32 prgRom = 0; + uint32 chrRom = 0; if (FCEU_fread(&head, 1, 16, fp) != 16) return 0; + filesize -= 16; /* remove header size from total size */ + if (memcmp(&head, "NES\x1a", 4)) { - FCEU_PrintError("Missing header or invalid iNES format file!\n"); + FCEU_PrintError("Not an iNES file!\n"); return 0; } @@ -689,20 +696,51 @@ int iNESLoad(const char *name, FCEUFILE *fp) { memset((char*)(&head) + 0xA, 0, 0x6); } - MapperNo = (head.ROM_type >> 4); - MapperNo |= (head.ROM_type2 & 0xF0); - if (head.ROM_type & 8) { - Mirroring = 2; - } else - Mirroring = (head.ROM_type & 1); + Mirroring = 0; + ROM_size = 0; + VROM_size = 0; + iNES2 = 0; + MapperNo = 0; + subMapper = 0; - if (!head.ROM_size) - ROM_size = 256; - else - ROM_size = uppow2(head.ROM_size); + MapperNo = (head.ROM_type >> 4) | (head.ROM_type2 & 0xF0); + Mirroring = (head.ROM_type & 8) ? 2 : (head.ROM_type & 1); + prgRom = head.ROM_size; + chrRom = head.VROM_size; - VROM_size = uppow2(head.VROM_size); + if ((head.ROM_type2 & 0x0C) == 0x08) { + iNES2 = 1; + MapperNo |= ((uint32)head.ROM_type3 << 8) & 0xF00; + prgRom |= ((uint32)head.upper_PRG_CHR_size << 8) & 0xF00; + chrRom |= ((uint32)head.upper_PRG_CHR_size << 4) & 0xF00; + subMapper = head.ROM_type3 >> 4 & 0x0F; + iNESCart.prgRam = (head.PRGRAM_size & 0x0F) ? (64 << (head.PRGRAM_size & 0x0F)) : 0; + iNESCart.chrRam = (head.CHRRAM_size & 0x0F) ? (64 << (head.CHRRAM_size & 0x0F)) : 0; + iNESCart.prgRam_battery = (head.PRGRAM_size & 0xF0) ? (64 << ((head.PRGRAM_size & 0xF0) >> 4)) : 0; + iNESCart.chrRam_battery = (head.CHRRAM_size & 0xF0) ? (64 << ((head.CHRRAM_size & 0xF0) >> 4)) : 0; + iNESCart.region = head.Region; + } else { + if (!prgRom) + prgRom = 256; + } + + if (head.ROM_type & 4) { /* Trainer */ + trainerpoo = (uint8*)FCEU_gmalloc(512); + FCEU_fread(trainerpoo, 512, 1, fp); + filesize -= 512; + } + + if (((prgRom * 0x4000) + (chrRom * 0x2000)) > filesize) { + FCEU_PrintError(" File length is too short to contain all data reported from header by %llu\n", ((prgRom * 0x4000) + (chrRom * 0x2000)) - filesize); + return 0; + } else if (((prgRom * 0x4000) + (chrRom * 0x2000)) < filesize) + FCEU_PrintError(" File contains %llu bytes of unused data\n", filesize - ((prgRom * 0x4000) + (chrRom * 0x2000))); + + ROM_size = uppow2(prgRom); + + if (chrRom) + VROM_size = uppow2(chrRom); if ((ROM = (uint8*)FCEU_malloc(ROM_size << 14)) == NULL) return 0; @@ -717,36 +755,23 @@ int iNESLoad(const char *name, FCEUFILE *fp) { memset(VROM, 0xFF, VROM_size << 13); } - if (head.ROM_type & 4) { /* Trainer */ - trainerpoo = (uint8*)FCEU_gmalloc(512); - FCEU_fread(trainerpoo, 512, 1, fp); - } - ResetCartMapping(); ResetExState(0, 0); SetupCartPRGMapping(0, ROM, ROM_size << 14, 0); - if (head.ROM_size) - FCEU_fread(ROM, 0x4000, head.ROM_size, fp); - else - FCEU_fread(ROM, 0x4000, ROM_size, fp); + FCEU_fread(ROM, 0x4000, prgRom, fp); if (VROM_size) - FCEU_fread(VROM, 0x2000, VROM_size, fp); + FCEU_fread(VROM, 0x2000, chrRom, fp); md5_starts(&md5); - if (head.ROM_size) { - md5_update(&md5, ROM, head.ROM_size << 14); - iNESGameCRC32 = CalcCRC32(0, ROM, head.ROM_size << 14); - } else { - md5_update(&md5, ROM, ROM_size << 14); - iNESGameCRC32 = CalcCRC32(0, ROM, ROM_size << 14); - } + md5_update(&md5, ROM, prgRom << 14); + iNESGameCRC32 = CalcCRC32(0, ROM, prgRom << 14); if (VROM_size) { - iNESGameCRC32 = CalcCRC32(iNESGameCRC32, VROM, VROM_size << 13); - md5_update(&md5, VROM, VROM_size << 13); + iNESGameCRC32 = CalcCRC32(iNESGameCRC32, VROM, chrRom << 13); + md5_update(&md5, VROM, chrRom << 13); } md5_finish(&md5, iNESCart.MD5); memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5)); @@ -755,14 +780,7 @@ int iNESLoad(const char *name, FCEUFILE *fp) { SetInput(); CheckHInfo(); - mappername = "Not Listed"; - for (mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) { - if (bmap[mappertest].number == MapperNo) { - mappername = (char*)bmap[mappertest].name; - break; - } - } { int x; uint64 partialmd5 = 0; @@ -787,43 +805,92 @@ int iNESLoad(const char *name, FCEUFILE *fp) { else SetupCartMirroring(Mirroring & 1, (Mirroring & 4) >> 2, 0); + iNESCart.iNES2 = iNES2; + iNESCart.mapper = MapperNo; + iNESCart.submapper = subMapper; iNESCart.battery = (head.ROM_type & 2) ? 1 : 0; iNESCart.mirror = Mirroring; + mappername = "Not Listed"; + + for (mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) { + if (bmap[mappertest].number == MapperNo) { + mappername = (char*)bmap[mappertest].name; + break; + } + } + + if (iNES2) FCEU_printf(" NES 2.0 extended iNES.\n"); FCEU_printf(" ROM CRC32: 0x%08lx\n", iNESGameCRC32); FCEU_printf(" ROM MD5: 0x%s\n", md5_asciistr(iNESCart.MD5)); - FCEU_printf(" PRG ROM: %3d x 16KiB\n", head.ROM_size ? head.ROM_size : 256); - FCEU_printf(" CHR ROM: %3d x 8KiB\n", head.VROM_size); + FCEU_printf(" PRG ROM: %3d x 16KiB\n", prgRom); + FCEU_printf(" CHR ROM: %3d x 8KiB\n", chrRom); - if (!iNES_Init(MapperNo)) - FCEU_PrintError("iNES mapper #%d is not supported at all.", MapperNo); - iNESCart.mapper = MapperNo; + if (iNES2) { + const char *tv_region[] = { "NTSC", "PAL", "Multi-region", "Dendy" }; + unsigned PRGRAM = iNESCart.prgRam + iNESCart.prgRam_battery; + unsigned CHRRAM = iNESCart.chrRam + iNESCart.chrRam_battery; - FCEU_printf(" \n"); - FCEU_printf(" Mapper #: %3d\n", MapperNo); - FCEU_printf(" Mapper name: %s\n", mappername); - FCEU_printf(" Mirroring: %s\n", Mirroring == 2 ? "None (Four-screen)" : Mirroring ? "Vertical" : "Horizontal"); - FCEU_printf(" Battery-backed: %s\n", (head.ROM_type & 2) ? "Yes" : "No"); - FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); + FCEU_printf(" Mapper #: %3d\n", MapperNo); + FCEU_printf(" Sub Mapper #: %3d\n", subMapper); + FCEU_printf(" Mapper name: %s\n", mappername); + if (PRGRAM || CHRRAM) { + FCEU_printf(" PRG RAM: %d KiB\n", PRGRAM / 1024); + FCEU_printf(" CHR RAM: %d KiB\n", CHRRAM / 1024); + if (head.ROM_type & 0x02) { + FCEU_printf(" PRG RAM backed by battery: %d KiB\n", iNESCart.prgRam_battery / 1024); + FCEU_printf(" CHR RAM backed by battery: %d KiB\n", iNESCart.chrRam_battery / 1024); + } + } + FCEU_printf(" Mirroring: %s\n", Mirroring == 2 ? "None (Four-screen)" : Mirroring ? "Vertical" : "Horizontal"); + FCEU_printf(" System: %s\n", tv_region[(iNESCart.region & 3)]); + FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); + } else { + FCEU_printf(" Mapper #: %3d\n", MapperNo); + FCEU_printf(" Mapper name: %s\n", mappername); + FCEU_printf(" Mirroring: %s\n", Mirroring == 2 ? "None (Four-screen)" : Mirroring ? "Vertical" : "Horizontal"); + FCEU_printf(" Battery-backed: %s\n", (head.ROM_type & 2) ? "Yes" : "No"); + FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); + } + + if (!iNES_Init(MapperNo)) { + FCEU_printf("\n"); + FCEU_PrintError(" iNES mapper #%d is not supported at all.\n", MapperNo); + return 0; + } GameInterface = iNESGI; - FCEU_printf("\n"); - if (strstr(name, "(E)") || strstr(name, "(e)") - || strstr(name, "(Europe)") || strstr(name, "(PAL)") - || strstr(name, "(F)") || strstr(name, "(f)") - || strstr(name, "(G)") || strstr(name, "(g)") - || strstr(name, "(I)") || strstr(name, "(i)") - || strstr(name, "(S)") || strstr(name, "(s)") - || strstr(name, "(France)") || strstr(name, "(Germany)") - || strstr(name, "(Italy)") || strstr(name, "(Spain)") - || strstr(name, "(Sweden)") || strstr(name, "(Sw)") - || strstr(name, "(Australia)") || strstr(name, "(A)") - || strstr(name, "(a)")) { - FCEUI_SetVidSystem(1); + if (iNES2) { + switch (iNESCart.region & 0x03) { + /* 0: RP2C02 ("NTSC NES") + * 1: RP2C07 ("Licensed PAL NES") + * 2: Multiple-region + * 3: UMC 6527P ("Dendy") + */ + case 0: case 2: FCEUI_SetVidSystem(0); break; + case 1: FCEUI_SetVidSystem(1); break; + case 3: dendy = 1; FCEUI_SetVidSystem(0); break; + } + } else { + if (strstr(name, "(E)") || strstr(name, "(e)") || + strstr(name, "(Europe)") || strstr(name, "(PAL)") || + strstr(name, "(F)") || strstr(name, "(f)") || + strstr(name, "(G)") || strstr(name, "(g)") || + strstr(name, "(I)") || strstr(name, "(i)") || + strstr(name, "(S)") || strstr(name, "(s)") || + strstr(name, "(France)") || strstr(name, "(Germany)") || + strstr(name, "(Italy)") || strstr(name, "(Spain)") || + strstr(name, "(Sweden)") || strstr(name, "(Sw)") || + strstr(name, "(Australia)") || strstr(name, "(A)") || + strstr(name, "(a)")) { + iNESCart.region = 1; + FCEUI_SetVidSystem(1); + } else { + iNESCart.region = 0; + FCEUI_SetVidSystem(0); + } } - else - FCEUI_SetVidSystem(0); return 1; } @@ -840,24 +907,30 @@ static int iNES_Init(int num) { if (num == tmp->number) { UNIFchrrama = 0; /* need here for compatibility with UNIF mapper code */ if (!VROM_size) { - switch (num) { /* FIXME, mapper or game data base with the board parameters and ROM/RAM sizes */ - case 13: CHRRAMSize = 16 * 1024; break; - case 6: - case 28: - case 29: - case 30: - case 45: - case 96: CHRRAMSize = 32 * 1024; break; - case 176: CHRRAMSize = 128 * 1024; break; - default: CHRRAMSize = 8 * 1024; break; + if (iNESCart.iNES2) { + CHRRAMSize = iNESCart.chrRam + iNESCart.chrRam_battery; + } else { + switch (num) { /* FIXME, mapper or game data base with the board parameters and ROM/RAM sizes */ + case 13: CHRRAMSize = 16 * 1024; break; + case 6: + case 28: + case 29: + case 30: + case 45: + case 96: CHRRAMSize = 32 * 1024; break; + case 176: CHRRAMSize = 128 * 1024; break; + default: CHRRAMSize = 8 * 1024; break; + } + iNESCart.chrRam = CHRRAMSize; + FCEU_printf(" CHR-RAM: %3d KiB\n", CHRRAMSize / 1024); + } + if (CHRRAMSize) { /* TODO: CHR-RAM are sometimes handled in mappers e.g. MMC1 using submapper 1/2/4 and CHR-RAM can be zero here */ + if ((VROM = (uint8*)malloc(CHRRAMSize)) == NULL) return 0; + FCEU_MemoryRand(VROM, CHRRAMSize); + UNIFchrrama = VROM; + SetupCartCHRMapping(0, VROM, CHRRAMSize, 1); + AddExState(VROM, CHRRAMSize, 0, "CHRR"); } - iNESCart.vram_size = CHRRAMSize; - if ((VROM = (uint8*)malloc(CHRRAMSize)) == NULL) return 0; - FCEU_MemoryRand(VROM, CHRRAMSize); - UNIFchrrama = VROM; - SetupCartCHRMapping(0, VROM, CHRRAMSize, 1); - AddExState(VROM, CHRRAMSize, 0, "CHRR"); - FCEU_printf(" CHR RAM: %3d x 1KiB\n", CHRRAMSize / 1024); } if (head.ROM_type & 8) AddExState(ExtraNTARAM, 2048, 0, "EXNR"); diff --git a/src/ines.h b/src/ines.h index 1d6dee7..2b29b29 100644 --- a/src/ines.h +++ b/src/ines.h @@ -28,7 +28,14 @@ typedef struct { uint8 VROM_size; uint8 ROM_type; uint8 ROM_type2; - uint8 reserve[8]; + uint8 ROM_type3; + uint8 upper_PRG_CHR_size; + uint8 PRGRAM_size; + uint8 CHRRAM_size; + uint8 Region; + uint8 VS_hardware; + uint8 MiscRoms; + uint8 ExpDevice; } iNES_HEADER; extern uint8 *ROM; diff --git a/src/unif.c b/src/unif.c index 6072129..ce3c61a 100644 --- a/src/unif.c +++ b/src/unif.c @@ -353,7 +353,7 @@ static void CheckHashInfo(void) { FCEU_PrintError(" For now, the information will be corrected in RAM.\n"); if (unif_db[x].boardname != NULL && strcmp((char*)unif_db[x].boardname, (char*)sboardname) != 0) { FCEU_printf(" Boardname should be set to %s\n", unif_db[x].boardname); - sboardname = unif_db[x].boardname; + sboardname = (uint8*)unif_db[x].boardname; } if (unif_db[x].submapper >= 0 && unif_db[x].submapper != submapper) { FCEU_PrintError(" Submapper should be set to %d\n", unif_db[x].submapper); From 8f19234f55f32e2804424e5e14aa02e8620494ee Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Mon, 8 Jul 2019 21:42:20 +0800 Subject: [PATCH 2/6] Start assigning NES 2.0 mapper numbers to UNIF boards (256+ boards) --- src/ines.c | 96 +++++++++++++- src/unif.c | 384 +++++++++++++++++++++++++++-------------------------- 2 files changed, 283 insertions(+), 197 deletions(-) diff --git a/src/ines.c b/src/ines.c index 68371f2..1db9530 100644 --- a/src/ines.c +++ b/src/ines.c @@ -651,14 +651,96 @@ static BMAPPINGLocal bmap[] = { {(uint8_t*)"", 254, Mapper254_Init}, {(uint8_t*)"", 255, Mapper255_Init}, /* Duplicate of M225? */ - {(uint8_t*)"BMC-HPxx", 260, BMCHPxx_Init}, - {(uint8_t*)"UNL-SHERO", 262, UNLSHeroes_Init}, + /* -------------- ----NES 2.0 -------------------------- */ + + /* NES 2.0 BOARDS THAT DO NOT HAVE UNIF ASSOCIATION */ + {(uint8_t*)"OK-411", 361, GN45_Init}, /* OK-411 is emulated together with GN-45 */ {(uint8_t*)"HUMMER/JY-052", 281, Mapper281_Init}, - {(uint8_t*)"GN-45", 366, GN45_Init}, - {(uint8_t*)"DREAMTECH01", 521, DreamTech01_Init}, + {(uint8_t*)"GN-45", 366, GN45_Init}, - {(uint8_t*)"", 0, NULL} + /* UNIF to NES 2.0 BOARDS */ + + {(uint8_t*)"OneBus", 256, UNLOneBus_Init }, + {(uint8_t*)"158B", 258, UNL158B_Init }, + {(uint8_t*)"F-15", 259, BMCF15_Init }, + {(uint8_t*)"HPxx / HP2018-A", 260, BMCHPxx_Init }, + {(uint8_t*)"810544-C-A1", 261, BMC810544CA1_Init }, + {(uint8_t*)"SHERO", 262, UNLSHeroes_Init }, + {(uint8_t*)"KOF97", 263, UNLKOF97_Init }, + {(uint8_t*)"YOKO", 264, UNLYOKO_Init }, + {(uint8_t*)"T-262", 265, BMCT262_Init }, + {(uint8_t*)"CITYFIGHT", 266, UNLCITYFIGHT_Init }, + {(uint8_t*)"COOLBOY", 268, COOLBOY_Init }, +/* {(uint8_t*)"MINDKIDS", 268, MINDKIDS_Init }, */ + {(uint8_t*)"80013-B", 274, BMC80013B_Init }, + {(uint8_t*)"GS-2004", 283, BMCGS2004_Init }, +/* {(uint8_t*)"GS-2013", 283, BMCGS2013_Init }, */ + {(uint8_t*)"A65AS", 285, BMCA65AS_Init }, + {(uint8_t*)"BS-5", 286, BMCBS5_Init }, + {(uint8_t*)"411120-C", 287, BMC411120C_Init }, +/* {(uint8_t*)"K-3088", 287, BMCK3088_Init }, */ + {(uint8_t*)"60311C", 289, BMC60311C_Init }, + {(uint8_t*)"NTD-03", 290, BMCNTD03_Init }, + {(uint8_t*)"DRAGONFIGHTER", 292, UNLBMW8544_Init }, + {(uint8_t*)"13in1JY110", 295, BMC13in1JY110_Init }, + {(uint8_t*)"TF1201", 298, UNLTF1201_Init }, + {(uint8_t*)"11160", 299, BMC11160_Init }, + {(uint8_t*)"190in1", 300, BMC190in1_Init }, + {(uint8_t*)"8157", 301, UNL8157_Init }, + {(uint8_t*)"KS7057", 302, UNLKS7057_Init }, + {(uint8_t*)"KS7017", 303, UNLKS7017_Init }, + {(uint8_t*)"SMB2J", 304, UNLSMB2J_Init }, + {(uint8_t*)"KS7031", 305, UNLKS7031_Init }, + {(uint8_t*)"KS7016", 306, UNLKS7016_Init }, + {(uint8_t*)"KS7037", 307, UNLKS7037_Init }, + {(uint8_t*)"TH2131-1", 308, UNLTH21311_Init }, + {(uint8_t*)"LH51", 309, LH51_Init }, + {(uint8_t*)"KS7013B", 312, UNLKS7013B_Init }, + {(uint8_t*)"RESET-TXROM", 313, BMCRESETTXROM_Init }, + {(uint8_t*)"64in1NoRepeat", 314, BMC64in1nr_Init }, + {(uint8_t*)"830134C", 315, BMC830134C_Init }, + {(uint8_t*)"HP898F", 319, BMCHP898F_Init }, + {(uint8_t*)"830425C-4391T", 320, BMC830425C4391T_Init }, + {(uint8_t*)"K-3033", 322, BMCK3033_Init }, + {(uint8_t*)"FARID_SLROM_8-IN-1", 323, FARIDSLROM8IN1_Init }, + {(uint8_t*)"FARID_UNROM_8-IN-1", 324, FARIDUNROM_Init }, + {(uint8_t*)"MALISB", 325, UNLMaliSB_Init }, + {(uint8_t*)"10-24-C-A1", 327, BMC1024CA1_Init }, + {(uint8_t*)"RT-01", 328, UNLRT01_Init }, + {(uint8_t*)"EDU2000", 329, UNLEDU2000_Init }, + {(uint8_t*)"12-IN-1", 331, BMC12IN1_Init }, + {(uint8_t*)"WS", 332, BMCWS_Init }, + {(uint8_t*)"NEWSTAR-GRM070-8IN1", 333, BMC8IN1_Init }, + {(uint8_t*)"CTC-09", 335, BMCCTC09_Init }, + {(uint8_t*)"K-3046", 336, BMCK3046_Init }, + {(uint8_t*)"CTC-12IN1", 337, BMCCTC12IN1_Init }, + {(uint8_t*)"SA005-A", 338, BMCSA005A_Init }, + {(uint8_t*)"K-3006", 339, BMCK3006_Init }, + {(uint8_t*)"K-3036", 340, BMCK3036_Init }, + {(uint8_t*)"TJ-03", 341, BMCTJ03_Init }, + {(uint8_t*)"GN-26", 344, BMCGN26_Init }, + {(uint8_t*)"L6IN1", 345, BMCL6IN1_Init }, + {(uint8_t*)"KS7012", 346, UNLKS7012_Init }, + {(uint8_t*)"KS7030", 347, UNLKS7030_Init }, + {(uint8_t*)"830118C", 348, BMC830118C_Init }, + {(uint8_t*)"G-146", 349, BMCG146_Init }, + {(uint8_t*)"891227", 350, BMC891227_Init }, + {(uint8_t*)"3D-BLOCK", 355, UNL3DBlock_Init }, + {(uint8_t*)"SA-9602B", 513, SA9602B_Init }, + {(uint8_t*)"DANCE2000", 518, UNLD2000_Init }, + {(uint8_t*)"EH8813A", 519, UNLEH8813A_Init }, + {(uint8_t*)"DREAMTECH01", 521, DreamTech01_Init }, + {(uint8_t*)"LH10", 522, LH10_Init }, + {(uint8_t*)"900218", 524, BTL900218_Init }, + {(uint8_t*)"KS7021A", 525, UNLKS7021A_Init }, + {(uint8_t*)"BJ-56", 526, UNLBJ56_Init }, + {(uint8_t*)"AX-40G", 527, UNLAX40G_Init }, + {(uint8_t*)"T-230", 529, UNLT230_Init }, + {(uint8_t*)"AX5705", 530, UNLAX5705_Init }, + {(uint8_t*)"LH53", 535, LH53_Init }, + + {(uint8_t*)"", 0, NULL} }; int iNESLoad(const char *name, FCEUFILE *fp) { @@ -917,8 +999,10 @@ static int iNES_Init(int num) { case 29: case 30: case 45: - case 96: CHRRAMSize = 32 * 1024; break; + case 96: + case 513: CHRRAMSize = 32 * 1024; break; case 176: CHRRAMSize = 128 * 1024; break; + case 268: CHRRAMSize = 256 * 1024; break; default: CHRRAMSize = 8 * 1024; break; } iNESCart.chrRam = CHRRAMSize; diff --git a/src/unif.c b/src/unif.c index ce3c61a..7f8e672 100644 --- a/src/unif.c +++ b/src/unif.c @@ -47,6 +47,7 @@ typedef struct { typedef struct { char *name; + int ines_mapper; void (*init)(CartInfo *); int flags; } BMAPPING; @@ -378,6 +379,7 @@ static void CheckHashInfo(void) { } +#define NO_INES -1 #define BMCFLAG_FORCE4 0x01 #define BMCFLAG_16KCHRR 0x02 #define BMCFLAG_32KCHRR 0x04 @@ -385,201 +387,201 @@ static void CheckHashInfo(void) { #define BMCFLAG_256KCHRR 0x10 static BMAPPING bmap[] = { - { "11160", BMC11160_Init, 0 }, - { "12-IN-1", BMC12IN1_Init, 0 }, - { "13in1JY110", BMC13in1JY110_Init, 0 }, - { "190in1", BMC190in1_Init, 0 }, - { "22211", UNL22211_Init, 0 }, - { "3D-BLOCK", UNL3DBlock_Init, 0 }, - { "411120-C", BMC411120C_Init, 0 }, - { "42in1ResetSwitch", Mapper226_Init, 0 }, - { "43272", UNL43272_Init, 0 }, - { "603-5052", UNL6035052_Init, 0 }, - { "64in1NoRepeat", BMC64in1nr_Init, 0 }, - { "70in1", BMC70in1_Init, 0 }, - { "70in1B", BMC70in1B_Init, 0 }, - { "810544-C-A1", BMC810544CA1_Init, 0 }, - { "8157", UNL8157_Init, 0 }, - { "8237", UNL8237_Init, 0 }, - { "8237A", UNL8237A_Init, 0 }, - { "830118C", BMC830118C_Init, 0 }, - { "A65AS", BMCA65AS_Init, 0 }, - { "AC08", AC08_Init, 0 }, - { "ANROM", ANROM_Init, 0 }, - { "AX5705", UNLAX5705_Init, 0 }, - { "BB", UNLBB_Init, 0 }, - { "BS-5", BMCBS5_Init, 0 }, - { "CC-21", UNLCC21_Init, 0 }, - { "CITYFIGHT", UNLCITYFIGHT_Init, 0 }, - { "10-24-C-A1", BMC1024CA1_Init, 0 }, - { "CNROM", CNROM_Init, 0 }, - { "CPROM", CPROM_Init, BMCFLAG_16KCHRR }, - { "D1038", BMCD1038_Init, 0 }, - { "DANCE", UNLOneBus_Init, 0 }, /* redundant */ - { "DANCE2000", UNLD2000_Init, 0 }, - { "DREAMTECH01", DreamTech01_Init, 0 }, - { "EDU2000", UNLEDU2000_Init, 0 }, - { "EKROM", EKROM_Init, 0 }, - { "ELROM", ELROM_Init, 0 }, - { "ETROM", ETROM_Init, 0 }, - { "EWROM", EWROM_Init, 0 }, - { "FK23C", BMCFK23C_Init, BMCFLAG_256KCHRR }, - { "FK23CA", BMCFK23CA_Init, BMCFLAG_256KCHRR }, - { "FS304", UNLFS304_Init, 0 }, - { "G-146", BMCG146_Init, 0 }, - { "GK-192", BMCGK192_Init, 0 }, - { "GS-2004", BMCGS2004_Init, 0 }, - { "GS-2013", BMCGS2013_Init, 0 }, - { "Ghostbusters63in1", BMCGhostbusters63in1_Init, 0 }, - { "H2288", UNLH2288_Init, 0 }, - { "HKROM", HKROM_Init, 0 }, - { "KOF97", UNLKOF97_Init, 0 }, - { "KONAMI-QTAI", Mapper190_Init, 0 }, - { "KS7012", UNLKS7012_Init, 0 }, - { "KS7013B", UNLKS7013B_Init, 0 }, - { "KS7016", UNLKS7016_Init, 0 }, - { "KS7017", UNLKS7017_Init, 0 }, - { "KS7030", UNLKS7030_Init, 0 }, - { "KS7031", UNLKS7031_Init, 0 }, - { "KS7032", UNLKS7032_Init, 0 }, - { "KS7037", UNLKS7037_Init, 0 }, - { "KS7057", UNLKS7057_Init, 0 }, - { "LE05", LE05_Init, 0 }, - { "LH10", LH10_Init, 0 }, - { "LH32", LH32_Init, 0 }, - { "LH53", LH53_Init, 0 }, - { "MALISB", UNLMaliSB_Init, 0 }, - { "MARIO1-MALEE2", MALEE_Init, 0 }, - { "MHROM", MHROM_Init, 0 }, - { "N625092", UNLN625092_Init, 0 }, - { "NROM", NROM_Init, 0 }, - { "NROM-128", NROM_Init, 0 }, - { "NROM-256", NROM_Init, 0 }, - { "NTBROM", Mapper68_Init, 0 }, - { "NTD-03", BMCNTD03_Init, 0 }, - { "NovelDiamond9999999in1", Novel_Init, 0 }, - { "OneBus", UNLOneBus_Init, 0 }, - { "PEC-586", UNLPEC586Init, 0 }, - { "RROM", NROM_Init, 0 }, - { "RROM-128", NROM_Init, 0 }, - { "SA-002", TCU02_Init, 0 }, - { "SA-0036", SA0036_Init, 0 }, - { "SA-0037", SA0037_Init, 0 }, - { "SA-009", SA009_Init, 0 }, - { "SA-016-1M", SA0161M_Init, 0 }, - { "SA-72007", SA72007_Init, 0 }, - { "SA-72008", SA72008_Init, 0 }, - { "SA-9602B", SA9602B_Init, BMCFLAG_32KCHRR }, - { "SA-NROM", TCA01_Init, 0 }, - { "SAROM", SAROM_Init, 0 }, - { "SBROM", SBROM_Init, 0 }, - { "SC-127", UNLSC127_Init, 0 }, - { "SCROM", SCROM_Init, 0 }, - { "SEROM", SEROM_Init, 0 }, - { "SGROM", SGROM_Init, 0 }, - { "SHERO", UNLSHeroes_Init, 0 }, - { "SKROM", SKROM_Init, 0 }, - { "SL12", UNLSL12_Init, 0 }, - { "SL1632", UNLSL1632_Init, 0 }, - { "SL1ROM", SL1ROM_Init, 0 }, - { "SLROM", SLROM_Init, 0 }, - { "SMB2J", UNLSMB2J_Init, 0 }, - { "SNROM", SNROM_Init, 0 }, - { "SOROM", SOROM_Init, 0 }, - { "SSS-NROM-256", SSSNROM_Init, 0 }, - { "SUNSOFT_UNROM", SUNSOFT_UNROM_Init, 0 }, /* fix me, real pcb name, real pcb type */ - { "Sachen-74LS374N", S74LS374N_Init, 0 }, - { "Sachen-74LS374NA", S74LS374NA_Init, 0 }, /* seems to be custom mapper */ - { "Sachen-8259A", S8259A_Init, 0 }, - { "Sachen-8259B", S8259B_Init, 0 }, - { "Sachen-8259C", S8259C_Init, 0 }, - { "Sachen-8259D", S8259D_Init, 0 }, - { "Super24in1SC03", Super24_Init, 0 }, - { "SuperHIK8in1", Mapper45_Init, 0 }, - { "Supervision16in1", Supervision16_Init, 0 }, - { "T-227-1", BMCT2271_Init, 0 }, - { "T-230", UNLT230_Init, 0 }, - { "T-262", BMCT262_Init, 0 }, - { "TBROM", TBROM_Init, 0 }, - { "TC-U01-1.5M", TCU01_Init, 0 }, - { "TEK90", Mapper90_Init, 0 }, - { "TEROM", TEROM_Init, 0 }, - { "TF1201", UNLTF1201_Init, 0 }, - { "TFROM", TFROM_Init, 0 }, - { "TGROM", TGROM_Init, 0 }, - { "TKROM", TKROM_Init, 0 }, - { "TKSROM", TKSROM_Init, 0 }, - { "TLROM", TLROM_Init, 0 }, - { "TLSROM", TLSROM_Init, 0 }, - { "TQROM", TQROM_Init, 0 }, - { "TR1ROM", TFROM_Init, BMCFLAG_FORCE4 }, - { "TSROM", TSROM_Init, 0 }, - { "TVROM", TLROM_Init, BMCFLAG_FORCE4 }, - { "Transformer", Transformer_Init, 0 }, - { "UNROM", UNROM_Init, 0 }, - { "UNROM-512-8", UNROM512_Init, 0 }, - { "UNROM-512-16", UNROM512_Init, BMCFLAG_16KCHRR }, - { "UNROM-512-32", UNROM512_Init, BMCFLAG_32KCHRR }, - { "UOROM", UNROM_Init, 0 }, - { "VRC7", UNLVRC7_Init, 0 }, - { "YOKO", UNLYOKO_Init, 0 }, - { "COOLBOY", COOLBOY_Init, BMCFLAG_256KCHRR }, - { "158B", UNL158B_Init, 0 }, - { "DRAGONFIGHTER", UNLBMW8544_Init, 0 }, - { "EH8813A", UNLEH8813A_Init, 0 }, - { "HP898F", BMCHP898F_Init, 0 }, - { "F-15", BMCF15_Init, 0 }, - { "RT-01", UNLRT01_Init, 0 }, - { "81-01-31-C", BMC810131C_Init, 0 }, - { "8-IN-1", BMC8IN1_Init, 0 }, - { "RET-CUFROM", Mapper29_Init, BMCFLAG_32KCHRR }, - { "60311C", BMC60311C_Init, 0 }, - { "WS", BMCWS_Init, 0 }, - { "HPxx", BMCHPxx_Init, 0 }, - { "HP2018-A", BMCHPxx_Init, 0 }, - { "CHINA_ER_SAN2", Mapper19_Init, 0 }, /* http://forums.nesdev.com/viewtopic.php?t=16465&p=216531 */ - { "WAIXING-FW01", Mapper227_Init, 0 }, /* https://wiki.nesdev.com/w/index.php/Talk:INES_Mapper_242 */ - { "WAIXING-FS005", BMCFK23C_Init, 0 }, /* https://wiki.nesdev.com/w/index.php/INES_Mapper_176 */ - { "80013-B", BMC80013B_Init, 0 }, - { "TH2131-1", UNLTH21311_Init, 0 }, - { "LH51", LH51_Init, 0 }, - { "RESETNROM-XIN1", BMCRESETNROMXIN1_Init, 0 }, - { " BMC-RESET-TXROM", BMCRESETTXROM_Init, 0 }, - { "RESET-TXROM", BMCRESETTXROM_Init, 0 }, - { "K-3088", BMCK3088_Init, 0 }, - { "FARID_SLROM_8-IN-1", FARIDSLROM8IN1_Init, 0 }, - { "830425C-4391T", BMC830425C4391T_Init, 0 }, - { "TJ-03", BMCTJ03_Init, 0 }, - { "CTC-09", BMCCTC09_Init, 0 }, - { "K-3046", BMCK3046_Init, 0 }, - { "SA005-A", BMCSA005A_Init, 0 }, - { "K-3006", BMCK3006_Init, 0 }, - { "K-3036", BMCK3036_Init, 0 }, - { "MINDKIDS", MINDKIDS_Init, BMCFLAG_256KCHRR }, - { "KS7021A", UNLKS7021A_Init, 0 }, - { "KS106C", BMCKS106C_Init, 0 }, - { "900218", BTL900218_Init, 0 }, - { "JC-016-2", Mapper205_Init, 0 }, - { "AX-40G", UNLAX40G_Init, 0 }, - { " BMC-STREETFIGTER-GAME4IN1", BMCSFGAME4IN1_Init, 0 }, - { "G631", BMCGhostbusters63in1_Init, 0 }, - { "BJ-56", UNLBJ56_Init, 0 }, - { "L6IN1", BMCL6IN1_Init, 0 }, - { "CTC-12IN1", BMCCTC12IN1_Init, 0 }, - { "891227", BMC891227_Init, 0 }, - { "NEWSTAR-GRM070-8IN1", BMC8IN1_Init, 0 }, - { "FARID_UNROM_8-IN-1", FARIDUNROM_Init, 0 }, - { "K-3033", BMCK3033_Init, 0 }, - { "830134C", BMC830134C_Init, 0 }, - { "GN-26", BMCGN26_Init, 0 }, - { "T4A54A", Mapper134_Init, 0 }, + { "11160", 299, BMC11160_Init, 0 }, + { "12-IN-1", 331, BMC12IN1_Init, 0 }, + { "13in1JY110", 295, BMC13in1JY110_Init, 0 }, + { "190in1", 300, BMC190in1_Init, 0 }, + { "22211", 132, UNL22211_Init, 0 }, + { "3D-BLOCK", 355, UNL3DBlock_Init, 0 }, + { "411120-C", 287, BMC411120C_Init, 0 }, + { "42in1ResetSwitch", 226, Mapper226_Init, 0 }, + { "43272", 227, UNL43272_Init, 0 }, + { "603-5052", 238, UNL6035052_Init, 0 }, + { "64in1NoRepeat", 314, BMC64in1nr_Init, 0 }, + { "70in1", 236, BMC70in1_Init, 0 }, + { "70in1B", 236, BMC70in1B_Init, 0 }, + { "810544-C-A1", 261, BMC810544CA1_Init, 0 }, + { "8157", 301, UNL8157_Init, 0 }, + { "8237", 215, UNL8237_Init, 0 }, + { "8237A", 215, UNL8237A_Init, 0 }, + { "830118C", 348, BMC830118C_Init, 0 }, + { "A65AS", 285, BMCA65AS_Init, 0 }, + { "AC08", NO_INES, AC08_Init, 0 }, /* Mapper 42.. but not.. Used for Green Beret */ + { "ANROM", 7, ANROM_Init, 0 }, + { "AX5705", 530, UNLAX5705_Init, 0 }, + { "BB", 108, UNLBB_Init, 0 }, + { "BS-5", 286, BMCBS5_Init, 0 }, + { "CC-21", 27, UNLCC21_Init, 0 }, + { "CITYFIGHT", 266, UNLCITYFIGHT_Init, 0 }, + { "10-24-C-A1", 327, BMC1024CA1_Init, 0 }, + { "CNROM", 3, CNROM_Init, 0 }, + { "CPROM", 13, CPROM_Init, BMCFLAG_16KCHRR }, + { "D1038", 59, BMCD1038_Init, 0 }, + { "DANCE", 256, UNLOneBus_Init, 0 }, /* redundant */ + { "DANCE2000", 518, UNLD2000_Init, 0 }, + { "DREAMTECH01", 521, DreamTech01_Init, 0 }, + { "EDU2000", 329, UNLEDU2000_Init, 0 }, + { "EKROM", 5, EKROM_Init, 0 }, + { "ELROM", 5, ELROM_Init, 0 }, + { "ETROM", 5, ETROM_Init, 0 }, + { "EWROM", 5, EWROM_Init, 0 }, + { "FK23C", 176, BMCFK23C_Init, BMCFLAG_256KCHRR }, + { "FK23CA", 176, BMCFK23CA_Init, BMCFLAG_256KCHRR }, + { "FS304", 162, UNLFS304_Init, 0 }, + { "G-146", 349, BMCG146_Init, 0 }, + { "GK-192", NO_INES, BMCGK192_Init, 0 }, /* mapper 58? */ + { "GS-2004", 283, BMCGS2004_Init, 0 }, + { "GS-2013", 283, BMCGS2013_Init, 0 }, + { "Ghostbusters63in1", NO_INES, BMCGhostbusters63in1_Init, 0 }, /* 226 is non-split version */ + { "H2288", 123, UNLH2288_Init, 0 }, + { "HKROM", 4, HKROM_Init, 0 }, + { "KOF97", 263, UNLKOF97_Init, 0 }, + { "KONAMI-QTAI", NO_INES, Mapper190_Init, 0 }, + { "KS7012", 346, UNLKS7012_Init, 0 }, + { "KS7013B", 312, UNLKS7013B_Init, 0 }, + { "KS7016", 306, UNLKS7016_Init, 0 }, + { "KS7017", 303, UNLKS7017_Init, 0 }, + { "KS7030", 347, UNLKS7030_Init, 0 }, + { "KS7031", 305, UNLKS7031_Init, 0 }, + { "KS7032", 142, UNLKS7032_Init, 0 }, + { "KS7037", 307, UNLKS7037_Init, 0 }, + { "KS7057", 302, UNLKS7057_Init, 0 }, + { "LE05", NO_INES, LE05_Init, 0 }, + { "LH10", 522, LH10_Init, 0 }, + { "LH32", 125, LH32_Init, 0 }, + { "LH53", 535, LH53_Init, 0 }, + { "MALISB", 325, UNLMaliSB_Init, 0 }, + { "MARIO1-MALEE2", 42, MALEE_Init, 0 }, + { "MHROM", 66, MHROM_Init, 0 }, + { "N625092", 221, UNLN625092_Init, 0 }, + { "NROM", 0, NROM_Init, 0 }, + { "NROM-128", 0, NROM_Init, 0 }, + { "NROM-256", 0, NROM_Init, 0 }, + { "NTBROM", 68, Mapper68_Init, 0 }, + { "NTD-03", 290, BMCNTD03_Init, 0 }, + { "NovelDiamond9999999in1", 201, Novel_Init, 0 }, + { "OneBus", 256, UNLOneBus_Init, 0 }, + { "PEC-586", NO_INES, UNLPEC586Init, 0 }, + { "RROM", 0, NROM_Init, 0 }, + { "RROM-128", 0, NROM_Init, 0 }, + { "SA-002", 136, TCU02_Init, 0 }, + { "SA-0036", 149, SA0036_Init, 0 }, + { "SA-0037", 148, SA0037_Init, 0 }, + { "SA-009", 160, SA009_Init, 0 }, + { "SA-016-1M", 146, SA0161M_Init, 0 }, + { "SA-72007", 145, SA72007_Init, 0 }, + { "SA-72008", 133, SA72008_Init, 0 }, + { "SA-9602B", 513, SA9602B_Init, BMCFLAG_32KCHRR }, + { "SA-NROM", 143, TCA01_Init, 0 }, + { "SAROM", 1, SAROM_Init, 0 }, + { "SBROM", 1, SBROM_Init, 0 }, + { "SC-127", 35, UNLSC127_Init, 0 }, + { "SCROM", 1, SCROM_Init, 0 }, + { "SEROM", 1, SEROM_Init, 0 }, + { "SGROM", 1, SGROM_Init, 0 }, + { "SHERO", 262, UNLSHeroes_Init, 0 }, + { "SKROM", 1, SKROM_Init, 0 }, + { "SL12", 116, UNLSL12_Init, 0 }, + { "SL1632", 14, UNLSL1632_Init, 0 }, + { "SL1ROM", 1, SL1ROM_Init, 0 }, + { "SLROM", 1, SLROM_Init, 0 }, + { "SMB2J", 304, UNLSMB2J_Init, 0 }, + { "SNROM", 1, SNROM_Init, 0 }, + { "SOROM", 1, SOROM_Init, 0 }, + { "SSS-NROM-256", NO_INES, SSSNROM_Init, 0 }, + { "SUNSOFT_UNROM", 93, SUNSOFT_UNROM_Init, 0 }, /* fix me, real pcb name, real pcb type */ + { "Sachen-74LS374N", 150, S74LS374N_Init, 0 }, + { "Sachen-74LS374NA", 243, S74LS374NA_Init, 0 }, /* seems to be custom mapper */ + { "Sachen-8259A", 141, S8259A_Init, 0 }, + { "Sachen-8259B", 138, S8259B_Init, 0 }, + { "Sachen-8259C", 139, S8259C_Init, 0 }, + { "Sachen-8259D", 137, S8259D_Init, 0 }, + { "Super24in1SC03", 176, Super24_Init, 0 }, + { "SuperHIK8in1", 45, Mapper45_Init, 0 }, + { "Supervision16in1", 53, Supervision16_Init, 0 }, + { "T-227-1", NO_INES, BMCT2271_Init, 0 }, + { "T-230", 529, UNLT230_Init, 0 }, + { "T-262", 265, BMCT262_Init, 0 }, + { "TBROM", 4, TBROM_Init, 0 }, + { "TC-U01-1.5M", 147, TCU01_Init, 0 }, + { "TEK90", 90, Mapper90_Init, 0 }, + { "TEROM", 4, TEROM_Init, 0 }, + { "TF1201", 298, UNLTF1201_Init, 0 }, + { "TFROM", 4, TFROM_Init, 0 }, + { "TGROM", 4, TGROM_Init, 0 }, + { "TKROM", 4, TKROM_Init, 0 }, + { "TKSROM", 118, TKSROM_Init, 0 }, + { "TLROM", 4, TLROM_Init, 0 }, + { "TLSROM", 118, TLSROM_Init, 0 }, + { "TQROM", 119, TQROM_Init, 0 }, + { "TR1ROM", 4, TFROM_Init, BMCFLAG_FORCE4 }, + { "TSROM", 4, TSROM_Init, 0 }, + { "TVROM", 4, TLROM_Init, BMCFLAG_FORCE4 }, + { "Transformer", NO_INES, Transformer_Init, 0 }, + { "UNROM", 2, UNROM_Init, 0 }, + { "UNROM-512-8", 30, UNROM512_Init, 0 }, + { "UNROM-512-16", 30, UNROM512_Init, BMCFLAG_16KCHRR }, + { "UNROM-512-32", 30, UNROM512_Init, BMCFLAG_32KCHRR }, + { "UOROM", 2, UNROM_Init, 0 }, + { "VRC7", 85, UNLVRC7_Init, 0 }, + { "YOKO", 264, UNLYOKO_Init, 0 }, + { "COOLBOY", 268, COOLBOY_Init, BMCFLAG_256KCHRR }, + { "158B", 258, UNL158B_Init, 0 }, + { "DRAGONFIGHTER", 292, UNLBMW8544_Init, 0 }, + { "EH8813A", 519, UNLEH8813A_Init, 0 }, + { "HP898F", 319, BMCHP898F_Init, 0 }, + { "F-15", 259, BMCF15_Init, 0 }, + { "RT-01", 328, UNLRT01_Init, 0 }, + { "81-01-31-C", NO_INES, BMC810131C_Init, 0 }, + { "8-IN-1", 333, BMC8IN1_Init, 0 }, + { "RET-CUFROM", 29, Mapper29_Init, BMCFLAG_32KCHRR }, + { "60311C", 289, BMC60311C_Init, 0 }, + { "WS", 332, BMCWS_Init, 0 }, + { "HPxx", 260, BMCHPxx_Init, 0 }, + { "HP2018-A", 260, BMCHPxx_Init, 0 }, + { "CHINA_ER_SAN2", 19, Mapper19_Init, 0 }, + { "WAIXING-FW01", 227, Mapper227_Init, 0 }, + { "WAIXING-FS005", 176, BMCFK23C_Init, 0 }, + { "80013-B", 274, BMC80013B_Init, 0 }, + { "TH2131-1", 308, UNLTH21311_Init, 0 }, + { "LH51", 309, LH51_Init, 0 }, + { "RESETNROM-XIN1", NO_INES, BMCRESETNROMXIN1_Init, 0 }, /* split roms */ + { " BMC-RESET-TXROM", 313, BMCRESETTXROM_Init, 0 }, + { "RESET-TXROM", 313, BMCRESETTXROM_Init, 0 }, + { "K-3088", 287, BMCK3088_Init, 0 }, + { "FARID_SLROM_8-IN-1", 323, FARIDSLROM8IN1_Init, 0 }, + { "830425C-4391T", 320, BMC830425C4391T_Init, 0 }, + { "TJ-03", 341, BMCTJ03_Init, 0 }, + { "CTC-09", 335, BMCCTC09_Init, 0 }, + { "K-3046", 336, BMCK3046_Init, 0 }, + { "SA005-A", 338, BMCSA005A_Init, 0 }, + { "K-3006", 339, BMCK3006_Init, 0 }, + { "K-3036", 340, BMCK3036_Init, 0 }, + { "MINDKIDS", 268, MINDKIDS_Init, BMCFLAG_256KCHRR }, + { "KS7021A", 525, UNLKS7021A_Init, 0 }, + { "KS106C", NO_INES, BMCKS106C_Init, 0 }, /* split roms */ + { "900218", 524, BTL900218_Init, 0 }, + { "JC-016-2", 205, Mapper205_Init, 0 }, + { "AX-40G", 527, UNLAX40G_Init, 0 }, + { " BMC-STREETFIGTER-GAME4IN1", NO_INES, BMCSFGAME4IN1_Init, 0 }, /* mapper 49? */ + { "G631", 226, BMCGhostbusters63in1_Init, 0 }, /* duplicate, probably wrong name */ + { "BJ-56", 526, UNLBJ56_Init, 0 }, + { "L6IN1", 345, BMCL6IN1_Init, 0 }, + { "CTC-12IN1", 337, BMCCTC12IN1_Init, 0 }, + { "891227", 350, BMC891227_Init, 0 }, + { "NEWSTAR-GRM070-8IN1", 333, BMC8IN1_Init, 0 }, + { "FARID_UNROM_8-IN-1", 324, FARIDUNROM_Init, 0 }, + { "K-3033", 322, BMCK3033_Init, 0 }, + { "830134C", 315, BMC830134C_Init, 0 }, + { "GN-26", 344, BMCGN26_Init, 0 }, + { "T4A54A", 134, Mapper134_Init, 0 }, #ifdef COPYFAMI - { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, - { "COPYFAMI", MapperCopyFami_Init, 0 }, + { "COPYFAMI_MMC3", NO_INES, MapperCopyFamiMMC3_Init, 0 }, + { "COPYFAMI", NO_INES, MapperCopyFami_Init, 0 }, #endif - { NULL, NULL, 0 } + { NULL, NO_INES, NULL, 0 } }; static BFMAPPING bfunc[] = { From 2a7bd3727657b3281fa775127256b9e7c3dabce5 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Wed, 10 Jul 2019 11:11:01 +0800 Subject: [PATCH 3/6] UNIF: Change how roms are loaded in multiple prg/chr file versions - Part of migrating UNIF to NES 2.0 conversion, which should make each unif roms to be compatible with each other. Some roms have separate prg and chr banks, which mapper has to do separate banking for such file versions. - This change would also make the boards to be easily usuable iNes/Nes 2.0. --- src/unif.c | 93 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 72 insertions(+), 21 deletions(-) diff --git a/src/unif.c b/src/unif.c index 7f8e672..8f496cf 100644 --- a/src/unif.c +++ b/src/unif.c @@ -75,10 +75,16 @@ static UNIF_HEADER uchead; static uint8 *malloced[32]; static uint32 mallocedsizes[32]; +/* used to preserve the rom order as found in the rom file + * at least one mapper has bank 4 at the beginning for e.g. */ +static uint32 prg_idx[16]; +static uint32 chr_idx[16]; static uint32 prg_chip_count; static uint32 chr_chip_count; +static uint64 UNIF_PRGROMSize, UNIF_CHRROMSize; + static int FixRomSize(uint32 size, uint32 minimum) { uint32 x = 1; @@ -102,12 +108,20 @@ static void FreeUNIF(void) { free(malloced[x]); malloced[x] = 0; } } + if (ROM) { + free(ROM); ROM = 0; + } + if (VROM) { + free(VROM); VROM = 0; + } } static void ResetUNIF(void) { int x; for (x = 0; x < 32; x++) malloced[x] = 0; + for (x = 0; x < 16; x++) + prg_idx[x] = chr_idx[x] = 0; vramo = 0; boardname = 0; mirrortodo = 0; @@ -115,6 +129,10 @@ static void ResetUNIF(void) { UNIFchrrama = 0; prg_chip_count = 0; chr_chip_count = 0; + UNIF_PRGROMSize = 0; + UNIF_CHRROMSize = 0; + ROM_size = 0; + VROM_size = 0; } static uint8 exntar[2048]; @@ -268,7 +286,7 @@ static int LoadPRG(FCEUFILE *fp) { FCEU_printf(" PRG ROM %d size: %d\n", z, (int)uchead.info); if (malloced[z]) free(malloced[z]); - t = FixRomSize(uchead.info, 2048); + t = uchead.info; if (!(malloced[z] = (uint8*)FCEU_malloc(t))) return(0); mallocedsizes[z] = t; @@ -276,11 +294,12 @@ static int LoadPRG(FCEUFILE *fp) { if (FCEU_fread(malloced[z], 1, uchead.info, fp) != uchead.info) { FCEU_printf("Read Error!\n"); return(0); - } /* else - FCEU_printf("\n"); */ + } - SetupCartPRGMapping(z, malloced[z], t, 0); + UNIF_PRGROMSize += t; + prg_idx[prg_chip_count] = z; prg_chip_count++; + return(1); } @@ -304,7 +323,7 @@ static int LoadCHR(FCEUFILE *fp) { FCEU_printf(" CHR ROM %d size: %d\n", z, (int)uchead.info); if (malloced[16 + z]) free(malloced[16 + z]); - t = FixRomSize(uchead.info, 8192); + t = uchead.info; if (!(malloced[16 + z] = (uint8*)FCEU_malloc(t))) return(0); mallocedsizes[16 + z] = t; @@ -312,11 +331,12 @@ static int LoadCHR(FCEUFILE *fp) { if (FCEU_fread(malloced[16 + z], 1, uchead.info, fp) != uchead.info) { FCEU_printf("Read Error!\n"); return(0); - } /* else - FCEU_printf("\n"); */ + } - SetupCartCHRMapping(z, malloced[16 + z], t, 0); + UNIF_CHRROMSize += t; + chr_idx[chr_chip_count] = z; chr_chip_count++; + return(1); } @@ -497,6 +517,7 @@ static BMAPPING bmap[] = { { "Sachen-8259C", 139, S8259C_Init, 0 }, { "Sachen-8259D", 137, S8259D_Init, 0 }, { "Super24in1SC03", 176, Super24_Init, 0 }, + { "Super24in1SC03", 176, Super24_Init, 0 }, { "SuperHIK8in1", 45, Mapper45_Init, 0 }, { "Supervision16in1", 53, Supervision16_Init, 0 }, { "T-227-1", NO_INES, BMCT2271_Init, 0 }, @@ -563,7 +584,7 @@ static BMAPPING bmap[] = { { "900218", 524, BTL900218_Init, 0 }, { "JC-016-2", 205, Mapper205_Init, 0 }, { "AX-40G", 527, UNLAX40G_Init, 0 }, - { " BMC-STREETFIGTER-GAME4IN1", NO_INES, BMCSFGAME4IN1_Init, 0 }, /* mapper 49? */ + { " BMC-STREETFIGTER-GAME4IN1", NO_INES, BMCSFGAME4IN1_Init, 0 }, /* mapper 49? submapper 1*/ { "G631", 226, BMCGhostbusters63in1_Init, 0 }, /* duplicate, probably wrong name */ { "BJ-56", 526, UNLBJ56_Init, 0 }, { "L6IN1", 345, BMCL6IN1_Init, 0 }, @@ -633,7 +654,7 @@ static int InitializeBoard(void) { while (bmap[x].name) { if (!strcmp((char*)sboardname, (char*)bmap[x].name)) { - if (!malloced[16]) { + if (VROM_size == 0) { if (bmap[x].flags & BMCFLAG_16KCHRR) CHRRAMSize = 16; else if (bmap[x].flags & BMCFLAG_32KCHRR) @@ -690,6 +711,10 @@ static void UNIFGI(int h) { } int UNIFLoad(const char *name, FCEUFILE *fp) { + struct md5_context md5; + uint32 x = 0; + uint64 PRGptr = 0, CHRptr = 0; + FCEU_fseek(fp, 0, SEEK_SET); FCEU_fread(&unhead, 1, 4, fp); if (memcmp(&unhead, "UNIF", 4)) @@ -705,23 +730,49 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { goto aborto; if (!LoadUNIFChunks(fp)) goto aborto; - { - int x; - struct md5_context md5; - md5_starts(&md5); + ROM_size = FixRomSize(UNIF_PRGROMSize, 2048); + if (UNIF_CHRROMSize) + VROM_size = FixRomSize(UNIF_CHRROMSize, 8192); - for (x = 0; x < 32; x++) - if (malloced[x]) { - md5_update(&md5, malloced[x], mallocedsizes[x]); - } - md5_finish(&md5, UNIFCart.MD5); - FCEU_printf(" ROM MD5: 0x%s\n", md5_asciistr(UNIFCart.MD5)); - memcpy(GameInfo->MD5, UNIFCart.MD5, sizeof(UNIFCart.MD5)); + ROM = (uint8*)malloc(ROM_size); + if (VROM_size) + VROM = (uint8*)malloc(VROM_size); + + for (x = 0; x < 16; x++) { + if (malloced[prg_idx[x]]) { + memcpy(ROM + PRGptr, malloced[(prg_idx[x])], mallocedsizes[(prg_idx[x])]); + PRGptr += mallocedsizes[(prg_idx[x])]; + free(malloced[(prg_idx[x])]); + malloced[(prg_idx[x])] = 0; + } + + if (malloced[16 + (chr_idx[x])]) { + memcpy(VROM + CHRptr, malloced[16 + (chr_idx[x])], mallocedsizes[16 + (chr_idx[x])]); + CHRptr += mallocedsizes[16 + (chr_idx[x])]; + free(malloced[16 + (chr_idx[x])]); + malloced[16 + (chr_idx[x])] = 0; + } } + FCEU_printf(" PRG ROM: %d KiB\n", UNIF_PRGROMSize / 1024); + if (VROM_size) + FCEU_printf(" CHR ROM: %d KiB\n", UNIF_CHRROMSize / 1024); + + md5_starts(&md5); + md5_update(&md5, ROM, UNIF_PRGROMSize); + if (VROM_size) + md5_update(&md5, VROM, UNIF_CHRROMSize); + md5_finish(&md5, UNIFCart.MD5); + FCEU_printf(" ROM MD5: 0x%s\n", md5_asciistr(UNIFCart.MD5)); + memcpy(GameInfo->MD5, UNIFCart.MD5, sizeof(UNIFCart.MD5)); + CheckHashInfo(); + SetupCartPRGMapping(0, ROM, ROM_size, 0); + if (VROM_size) + SetupCartCHRMapping(0, VROM, VROM_size, 0); + if (!InitializeBoard()) goto aborto; From 429f6c45455ca7f969fff670b68ceaeef21aff20 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Thu, 11 Jul 2019 16:34:39 +0800 Subject: [PATCH 4/6] UNIF: Update boards based on last commit - fixes (if necessary), update and cleanup the following boards that now dont need alternate mappings: - this is part of migrating unif to be usuable in ines mappers - boards affected in this commit are: SUPERVISION16IN1, GS-2004, GS-2013, UNL-SMB2J, MARIO1-MALEE2, UNL-SA-9602B, UNL-KS106C / RESETNROM-XIN1 UNL-AC08, NES-NTBROM, BMC-K-3033, BMC-GN-26, BMC-GHOSTBUSTERS63IN1, BMC-830425C-4391T BMC-830134C, BMC-891227 / BMC-CTC-12IN1, BMC-JC-016-2, UNL-T4A54A, UNL-8157, BMC-T-262 (might have forgotten to list some...) --- src/boards/09-034a.c | 2 +- src/boards/68.c | 2 +- src/boards/8157.c | 12 +++--------- src/boards/830134C.c | 14 ++++++-------- src/boards/SA-9602B.c | 10 +++++----- src/boards/ac-08.c | 2 +- src/boards/bmc830425C4391t.c | 7 +++---- src/boards/bmcgamecard.c | 6 +++--- src/boards/bmck3033.c | 26 +++++++++++++++----------- src/boards/ghostbusters63in1.c | 6 +++--- src/boards/gn26.c | 15 ++++++++------- src/boards/gs-2004.c | 6 +++--- src/boards/gs-2013.c | 8 ++++---- src/boards/malee.c | 2 +- src/boards/mmc3.c | 28 ++++------------------------ src/boards/resetnromxin1.c | 4 ++-- src/boards/resettxrom.c | 14 ++------------ src/boards/supervision.c | 15 ++------------- src/boards/t-262.c | 11 ++--------- src/unif.c | 4 ++-- 20 files changed, 71 insertions(+), 123 deletions(-) diff --git a/src/boards/09-034a.c b/src/boards/09-034a.c index b39d595..12e5b79 100644 --- a/src/boards/09-034a.c +++ b/src/boards/09-034a.c @@ -44,7 +44,7 @@ static SFORMAT StateRegs[] = }; static void Sync(void) { - setprg8r(1, 0x6000, prg); + setprg8(0x6000, 4 | prg); setprg32(0x8000, 0); setchr8(0); } diff --git a/src/boards/68.c b/src/boards/68.c index 19da627..2e0ec8f 100644 --- a/src/boards/68.c +++ b/src/boards/68.c @@ -73,7 +73,7 @@ static void Sync(void) { setchr2(0x1800, chr_reg[3]); setprg8r(0x10, 0x6000, 0); setprg16r((PRGptr[1]) ? kogame : 0, 0x8000, prg_reg); - setprg16(0xC000, ~0); + setprg16(0xC000, 0x07); } static DECLFR(M68Read) { diff --git a/src/boards/8157.c b/src/boards/8157.c index 1d72957..b81c05f 100644 --- a/src/boards/8157.c +++ b/src/boards/8157.c @@ -37,15 +37,9 @@ static void Sync(void) { uint32 base = ((cmdreg & 0x060) | ((cmdreg & 0x100) >> 1)) >> 2; uint32 bank = (cmdreg & 0x01C) >> 2; uint32 lbank = (cmdreg & 0x200) ? 7 : ((cmdreg & 0x80) ? bank : 0); - if (PRGptr[1]) { - chip = base >> 3; - if (chip > PRGchip_max) chip &= PRGchip_max; - setprg16r(chip, 0x8000, bank); /* for versions with split ROMs */ - setprg16r(chip, 0xC000, lbank); - } else { - setprg16(0x8000, base | bank); - setprg16(0xC000, base | lbank); - } + + setprg16(0x8000, base | bank); + setprg16(0xC000, base | lbank); setmirror(((cmdreg & 2) >> 1) ^ 1); } diff --git a/src/boards/830134C.c b/src/boards/830134C.c index 7d546d5..5637c7a 100644 --- a/src/boards/830134C.c +++ b/src/boards/830134C.c @@ -28,22 +28,20 @@ #include "mmc3.h" static void BMC830134CCW(uint32 A, uint8 V) { - uint32 chip = (EXPREGS[0] & 0x03) & ~((EXPREGS[0] & 0x02) >> 1); - setchr1r(chip, A, (V & 0xFF) | ((EXPREGS[0] & 0x01) << 8) | ((EXPREGS[0] & 0x02) << 6) | ((EXPREGS[0] & 0x08) << 3)); + setchr1(A, (V & 0xFF) | ((EXPREGS[0] & 0x01) << 8) | ((EXPREGS[0] & 0x02) << 6) | ((EXPREGS[0] & 0x08) << 3)); } static void BMC830134CPW(uint32 A, uint8 V) { - uint32 chip = (EXPREGS[0] & 0x06) >> 1; if ((EXPREGS[0] & 0x06) == 0x06) { if (A == 0x8000) { - setprg8r(chip, A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); - setprg8r(chip, 0xC000, (V & 0x0F) | 0x32); + setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); + setprg8(0xC000, (V & 0x0F) | 0x32); } else if (A == 0xA000) { - setprg8r(chip, A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); - setprg8r(chip, 0xE000, (V & 0x0F) | 0x32); + setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); + setprg8(0xE000, (V & 0x0F) | 0x32); } } else - setprg8r(chip, A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); + setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3)); } static DECLFW(BMC830134CWrite) { diff --git a/src/boards/SA-9602B.c b/src/boards/SA-9602B.c index 7acd049..10b4315 100644 --- a/src/boards/SA-9602B.c +++ b/src/boards/SA-9602B.c @@ -22,12 +22,12 @@ #include "mmc3.h" static void SA9602BPW(uint32 A, uint8 V) { - setprg8r(EXPREGS[1], A, V & 0x3F); + setprg8(A, (EXPREGS[1] & 0xC0) | (V & 0x3F)); if (MMC3_cmd & 0x40) - setprg8r(0, 0x8000, ~(1)); + setprg8(0x8000, 62); else - setprg8r(0, 0xc000, ~(1)); - setprg8r(0, 0xe000, ~(0)); + setprg8(0xc000, 62); + setprg8(0xe000, 63); } static DECLFW(SA9602BWrite) { @@ -35,7 +35,7 @@ static DECLFW(SA9602BWrite) { case 0x8000: EXPREGS[0] = V; break; case 0x8001: if ((EXPREGS[0] & 7) < 6) { - EXPREGS[1] = V >> 6; + EXPREGS[1] = V; FixMMC3PRG(MMC3_cmd); } break; diff --git a/src/boards/ac-08.c b/src/boards/ac-08.c index 8dd16eb..081512e 100644 --- a/src/boards/ac-08.c +++ b/src/boards/ac-08.c @@ -34,7 +34,7 @@ static SFORMAT StateRegs[] = static void Sync(void) { setprg8(0x6000, reg); - setprg32r(1, 0x8000, 0); + setprg32(0x8000, 4); setchr8(0); setmirror(mirr); } diff --git a/src/boards/bmc830425C4391t.c b/src/boards/bmc830425C4391t.c index ce64fd2..108425a 100644 --- a/src/boards/bmc830425C4391t.c +++ b/src/boards/bmc830425C4391t.c @@ -39,17 +39,16 @@ static SFORMAT StateRegs[] = }; static void Sync(void) { - setprg16r(outer_bank, 0x8000, (inner_bank & bank_size)); - setprg16r(outer_bank, 0xC000, bank_size); + setprg16(0x8000, (outer_bank << 3) | (inner_bank & bank_size)); + setprg16(0xC000, (outer_bank << 3) | bank_size); setchr8(0); } static DECLFW(M320Write) { - const uint8 chip[] = { 0, 0, 1, 0, 2, 3, 4, 5 }; /* address mask is inconsistent with that is in the wiki. Mask should be * 0xFFE0 or Mermaid game will not work. */ if ((A & 0xFFE0) == 0xF0E0) { - outer_bank = chip[(A & 0x0F)]; + outer_bank = (A & 0x0F); bank_size = (A & 0x10) ? 0x07 : 0x0F; } inner_bank = (V & 0x0F); diff --git a/src/boards/bmcgamecard.c b/src/boards/bmcgamecard.c index 0cc58af..aab0e4c 100644 --- a/src/boards/bmcgamecard.c +++ b/src/boards/bmcgamecard.c @@ -41,12 +41,12 @@ static SFORMAT StateRegs[] = static void Sync(void) { uint8 mirroring = m350 ? ((latche >> 7) & 1) : ((latche >> 5) & 1); uint8 mode = m350 ? ((latche >> 5) & 0x03) : ((latche >> 6) & 0x03); - uint8 chip = m350 ? ((latche & 0x40) ? ((latche & 0x20) >> 5) : 0) : 0; + uint8 base = m350 ? ((latche & 0x40) ? (latche & 0x20) : 0) : 0; setchr8(0); setprg8(0x6000, 1); - setprg16r(PRGptr[1] ? chip : 0, 0x8000, (latche & 0x1F)); - setprg16r(PRGptr[1] ? chip : 0, 0xC000, (latche & 0x1F) | ((mode & 2) ? 0x07 : (mode & 1))); + setprg16r(0, 0x8000, base | (latche & 0x1F)); + setprg16r(0, 0xC000, base | ((latche & 0x1F) | ((mode & 2) ? 0x07 : (mode & 1)))); setmirror(mirroring ^ 1); } diff --git a/src/boards/bmck3033.c b/src/boards/bmck3033.c index 90ff0af..686d278 100644 --- a/src/boards/bmck3033.c +++ b/src/boards/bmck3033.c @@ -29,13 +29,16 @@ static void BMCK3033CW(uint32 A, uint8 V) { if (EXPREGS[2]) { - if (EXPREGS[3]) { // MMC3-256 - setchr1r(EXPREGS[1] & ~0x01, A, (V & 0xFF)); - } else { // MMC3-128 - setchr1r(EXPREGS[1], A, (V & 0x7F)); + if (EXPREGS[3]) { +/* FCEU_printf("MMC3-256: A:%04x V:%02x R1:%02x\n", A, V, EXPREGS[1]); */ + setchr1(A, (EXPREGS[1] << 8) | (V & 0xFF)); + } else { +/* FCEU_printf("MMC3-128: A:%04x V:%02x R1:%02x\n", A, V, EXPREGS[1]); */ + setchr1(A, (EXPREGS[1] << 7) | (V & 0x7F)); } - } else { // NROM - setchr1r(EXPREGS[1], A, (V & 0x7F)); + } else { +/* FCEU_printf("NROM: A:%04x V:%02x R1:%02x\n", A, V, EXPREGS[1]); */ + setchr1(A, (V & 0x7F)); } } @@ -43,19 +46,20 @@ static void BMCK3033PW(uint32 A, uint8 V) { if (EXPREGS[2]) { if (EXPREGS[3] ) { /* FCEU_printf("MMC3-256 A:%04x V:%02x chip:%02x\n", A, V, EXPREGS[1] & ~0x01); */ - setprg8r((EXPREGS[1] & ~0x01), A, (V & 0x1F)); + setprg8(A, (EXPREGS[1] << 5) | (V & 0x1F)); } else { /* FCEU_printf("MMC3-128 A:%04x V:%02x chip:%02x\n", A, V, EXPREGS[1]); */ - setprg8r(EXPREGS[1], A, (V & 0x0F)); + setprg8(A, (EXPREGS[1] << 4) | (V & 0x0F)); } } else { + uint32 base = (EXPREGS[1] << 3); if (EXPREGS[0] & 0x03) { /* FCEU_printf("NROM-256 base:%02x chip:%02x\n", EXPREGS[0] >> 1, EXPREGS[1]); */ - setprg32r(EXPREGS[1], 0x8000, EXPREGS[0] >> 1); + setprg32(0x8000, base | EXPREGS[0] >> 1); } else { /* FCEU_printf("NROM-128 base:%02x chip:%02x\n", EXPREGS[0], EXPREGS[1]); */ - setprg16r(EXPREGS[1], 0x8000, EXPREGS[0]); - setprg16r(EXPREGS[1], 0xC000, EXPREGS[0]); + setprg16(0x8000, base | EXPREGS[0]); + setprg16(0xC000, base | EXPREGS[0]); } } } diff --git a/src/boards/ghostbusters63in1.c b/src/boards/ghostbusters63in1.c index 2ca6ee1..bdd1f1e 100644 --- a/src/boards/ghostbusters63in1.c +++ b/src/boards/ghostbusters63in1.c @@ -35,10 +35,10 @@ static SFORMAT StateRegs[] = static void Sync(void) { if (reg[0] & 0x20) { - setprg16r(banks[bank], 0x8000, reg[0] & 0x1F); - setprg16r(banks[bank], 0xC000, reg[0] & 0x1F); + setprg16(0x8000, (banks[bank] << 5) | (reg[0] & 0x1F)); + setprg16(0xC000, (banks[bank] << 5) | (reg[0] & 0x1F)); } else - setprg32r(banks[bank], 0x8000, (reg[0] >> 1) & 0x0F); + setprg32(0x8000, ((banks[bank] << 5) | (reg[0] & 0x1F)) >> 1); if (reg[1] & 2) setchr8r(0x10, 0); else diff --git a/src/boards/gn26.c b/src/boards/gn26.c index b55967d..0af480b 100644 --- a/src/boards/gn26.c +++ b/src/boards/gn26.c @@ -27,19 +27,20 @@ #include "mmc3.h" static void BMCGN26CW(uint32 A, uint8 V) { - uint32 chip = (EXPREGS[0] & 0x03); - if (chip) chip -= 1; - setchr1r(chip, A, (V & 0xFF)); + uint32 base = (EXPREGS[0] & 0x03) << 7; + setchr1(A, base | (V & 0xFF)); } static void BMCGN26PW(uint32 A, uint8 V) { - uint32 chip = (EXPREGS[0] & 0x03); - if (chip) chip -= 1; /* Re-ordered -> 0:SF4 1:Contra Force 2:Revolution Hero */ + /* Re-ordered -> 0:SF4 1:Contra Force 2:Revolution Hero */ + uint32 table[] = { 0, 0, 1, 2 }; + uint32 base = table[(EXPREGS[0] & 0x03)]; + if (EXPREGS[0] & 4) { if (A == 0x8000) - setprg32r(chip, 0x8000, (V >> 2)); + setprg32(0x8000, (base << 2) | (V >> 2)); } else - setprg8r(chip, A, (V & 0x0F)); + setprg8(A, (base << 4) | (V & 0x0F)); } static DECLFW(BMCGN26Write) { diff --git a/src/boards/gs-2004.c b/src/boards/gs-2004.c index b292d90..fd964e5 100644 --- a/src/boards/gs-2004.c +++ b/src/boards/gs-2004.c @@ -29,7 +29,7 @@ static SFORMAT StateRegs[] = }; static void Sync(void) { - setprg8r(1, 0x6000, 0); + setprg8(0x6000, 32); setprg32(0x8000, reg); setchr8(0); } @@ -40,7 +40,7 @@ static DECLFW(BMCGS2004Write) { } static void BMCGS2004Power(void) { - reg = ~0; + reg = 0x07; Sync(); SetReadHandler(0x6000, 0x7FFF, CartBR); SetReadHandler(0x8000, 0xFFFF, CartBR); @@ -48,7 +48,7 @@ static void BMCGS2004Power(void) { } static void BMCGS2004Reset(void) { - reg = ~0; + reg = 0x07; } static void StateRestore(int version) { diff --git a/src/boards/gs-2013.c b/src/boards/gs-2013.c index fe81a53..e7cda5f 100644 --- a/src/boards/gs-2013.c +++ b/src/boards/gs-2013.c @@ -29,8 +29,8 @@ static SFORMAT StateRegs[] = }; static void Sync(void) { - setprg8r(0, 0x6000, ~0); - setprg32r((reg & 8) >> 3, 0x8000, reg); + setprg8(0x6000, 31); + setprg32(0x8000, reg); setchr8(0); } @@ -40,7 +40,7 @@ static DECLFW(BMCGS2013Write) { } static void BMCGS2013Power(void) { - reg = ~0; + reg = 0; Sync(); SetReadHandler(0x6000, 0x7FFF, CartBR); SetReadHandler(0x8000, 0xFFFF, CartBR); @@ -48,7 +48,7 @@ static void BMCGS2013Power(void) { } static void BMCGS2013Reset(void) { - reg = ~0; + reg = 0; } static void StateRestore(int version) { diff --git a/src/boards/malee.c b/src/boards/malee.c index 84c353a..a4a0721 100644 --- a/src/boards/malee.c +++ b/src/boards/malee.c @@ -31,7 +31,7 @@ static void MALEEPower(void) { SetReadHandler(0x6000, 0x67FF, CartBR); SetReadHandler(0x7000, 0x77FF, CartBR); SetWriteHandler(0x7000, 0x77FF, CartBW); - setprg2r(1, 0x6000, 0); + setprg2(0x6000, 16); setprg32(0x8000, 0); setchr8(0); } diff --git a/src/boards/mmc3.c b/src/boards/mmc3.c index 93d36b6..3c9d42a 100644 --- a/src/boards/mmc3.c +++ b/src/boards/mmc3.c @@ -914,22 +914,12 @@ void Mapper119_Init(CartInfo *info) { static void M134PW(uint32 A, uint8 V) { uint8 mask = (EXPREGS[0] & 0x04) ? 0x0F : 0x1F; - if (PRGptr[1]) { - chip = (EXPREGS[0] & 3); - if (chip > PRGchip_max) chip &= PRGchip_max; - setprg8r(chip, A, (V & mask)); - } else - setprg8(A, (V & mask) | ((EXPREGS[0] & 3) << 4)); + setprg8(A, (V & mask) | ((EXPREGS[0] & 3) << 4)); } static void M134CW(uint32 A, uint8 V) { uint8 mask = (EXPREGS[0] & 0x04) ? 0x7F : 0xFF; - if (CHRptr[1]) { - chip = (EXPREGS[0] & 0x30) >> 4; - if (chip > CHRchip_max) chip &= CHRchip_max; - setchr1r(chip, A, (V & mask)); - } else - setchr1(A, (V & mask) | ((EXPREGS[0] & 0x30) << 3)); + setchr1(A, (V & mask) | ((EXPREGS[0] & 0x30) << 3)); } static DECLFW(M134Write) { @@ -1212,22 +1202,12 @@ static uint8 block[] = {0, 0, 1, 2}; static void M205PW(uint32 A, uint8 V) { uint8 bank = V & ((EXPREGS[0] & 0x02) ? 0x0F : 0x1F); - if (PRGptr[1]) { - chip = block[EXPREGS[0]]; - if (chip > PRGchip_max) chip &= PRGchip_max; - setprg8r(chip, A, bank); - } else - setprg8(A, EXPREGS[0] << 4 | bank); + setprg8(A, EXPREGS[0] << 4 | bank); } static void M205CW(uint32 A, uint8 V) { uint8 bank = V & ((EXPREGS[0] & 0x02) ? 0x7F : 0xFF); - if (CHRptr[1]) { - chip = block[EXPREGS[0]]; - if (chip > CHRchip_max) chip &= CHRchip_max; - setchr1r(chip, A, bank); - } else - setchr1(A, (EXPREGS[0] << 7) | bank); + setchr1(A, (EXPREGS[0] << 7) | bank); } static DECLFW(M205Write0) { diff --git a/src/boards/resetnromxin1.c b/src/boards/resetnromxin1.c index 76c6e84..0f0372f 100644 --- a/src/boards/resetnromxin1.c +++ b/src/boards/resetnromxin1.c @@ -38,8 +38,8 @@ static SFORMAT StateRegs[] = }; static void Sync(void) { - setchr8r(gameblock, 0); - setprg32r(gameblock, 0x8000, 0); + setchr8(gameblock); + setprg32(0x8000, gameblock); } static void BMCRESETNROMXIN1Power(void) { diff --git a/src/boards/resettxrom.c b/src/boards/resettxrom.c index 039b5c8..8bef280 100644 --- a/src/boards/resettxrom.c +++ b/src/boards/resettxrom.c @@ -30,21 +30,11 @@ static uint8 chip; static void M313CW(uint32 A, uint8 V) { - if (CHRptr[1]) { - chip = EXPREGS[0]; - if (chip > CHRchip_max) chip &= CHRchip_max; - setchr1r(chip, A, (V & 0x7F)); - } else - setchr1(A, (EXPREGS[0] << 7) | (V & 0x7F)); + setchr1(A, (EXPREGS[0] << 7) | (V & 0x7F)); } static void M313PW(uint32 A, uint8 V) { - if (PRGptr[1]) { - chip = EXPREGS[0]; - if (chip > PRGchip_max) chip &= PRGchip_max; - setprg8r(chip, A, (V & 0x0F)); - } else - setprg8(A, (EXPREGS[0] << 4) | (V & 0x0F)); + setprg8(A, (EXPREGS[0] << 4) | (V & 0x0F)); } static void M313Reset(void) { diff --git a/src/boards/supervision.c b/src/boards/supervision.c index 46be8ed..43b67f5 100644 --- a/src/boards/supervision.c +++ b/src/boards/supervision.c @@ -30,23 +30,12 @@ static SFORMAT StateRegs[] = static void Sync(void) { setchr8(0); - if (PRGptr[1]) - setprg8r((cmd0 & 0xC) >> 2, 0x6000, ((cmd0 & 0x3) << 4) | 0xF); - else - setprg8(0x6000, (((cmd0 & 0xF) << 4) | 0xF) + 4); + setprg8(0x6000, (((cmd0 & 0xF) << 4) | 0xF) + 4); if (cmd0 & 0x10) { - if (PRGptr[1]) { - setprg16r((cmd0 & 0xC) >> 2, 0x8000, ((cmd0 & 0x3) << 3) | (cmd1 & 7)); - setprg16r((cmd0 & 0xC) >> 2, 0xc000, ((cmd0 & 0x3) << 3) | 7); - } else { setprg16(0x8000, (((cmd0 & 0xF) << 3) | (cmd1 & 7)) + 2); setprg16(0xc000, (((cmd0 & 0xF) << 3) | 7) + 2); - } } else - if (PRGptr[4]) - setprg32r(4, 0x8000, 0); - else - setprg32(0x8000, 0); + setprg32(0x8000, 0); setmirror(((cmd0 & 0x20) >> 5) ^ 1); } diff --git a/src/boards/t-262.c b/src/boards/t-262.c index 7806d56..5aaa515 100644 --- a/src/boards/t-262.c +++ b/src/boards/t-262.c @@ -34,15 +34,8 @@ static SFORMAT StateRegs[] = static void Sync(void) { setchr8(0); - if (PRGptr[1]) { - chip = base >> 3; - if (chip > PRGchip_max) chip &= PRGchip_max; - setprg16r(chip, 0x8000, bank); - setprg16r(chip, 0xC000, (mode ? bank : 7)); - } else { - setprg16(0x8000, base | bank); - setprg16(0xC000, base | (mode ? bank : 7)); - } + setprg16(0x8000, base | bank); + setprg16(0xC000, base | (mode ? bank : 7)); setmirror(mirr); } diff --git a/src/unif.c b/src/unif.c index 8f496cf..a4a5fc0 100644 --- a/src/unif.c +++ b/src/unif.c @@ -452,7 +452,7 @@ static BMAPPING bmap[] = { { "GK-192", NO_INES, BMCGK192_Init, 0 }, /* mapper 58? */ { "GS-2004", 283, BMCGS2004_Init, 0 }, { "GS-2013", 283, BMCGS2013_Init, 0 }, - { "Ghostbusters63in1", NO_INES, BMCGhostbusters63in1_Init, 0 }, /* 226 is non-split version */ + { "Ghostbusters63in1", NO_INES, BMCGhostbusters63in1_Init, 0 }, /* similar to 226 but different bank order */ { "H2288", 123, UNLH2288_Init, 0 }, { "HKROM", 4, HKROM_Init, 0 }, { "KOF97", 263, UNLKOF97_Init, 0 }, @@ -585,7 +585,7 @@ static BMAPPING bmap[] = { { "JC-016-2", 205, Mapper205_Init, 0 }, { "AX-40G", 527, UNLAX40G_Init, 0 }, { " BMC-STREETFIGTER-GAME4IN1", NO_INES, BMCSFGAME4IN1_Init, 0 }, /* mapper 49? submapper 1*/ - { "G631", 226, BMCGhostbusters63in1_Init, 0 }, /* duplicate, probably wrong name */ + { "G631", NO_INES, BMCGhostbusters63in1_Init, 0 }, /* duplicate, probably wrong name */ { "BJ-56", 526, UNLBJ56_Init, 0 }, { "L6IN1", 345, BMCL6IN1_Init, 0 }, { "CTC-12IN1", 337, BMCCTC12IN1_Init, 0 }, From 748f27571ded95ea2fa49d1a8b9bcf3bded171ae Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Thu, 11 Jul 2019 20:55:01 +0800 Subject: [PATCH 5/6] BMC-K-3088: Fix outer bank size --- src/boards/411120-c.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/boards/411120-c.c b/src/boards/411120-c.c index 706f192..765ce19 100644 --- a/src/boards/411120-c.c +++ b/src/boards/411120-c.c @@ -35,31 +35,18 @@ static uint8 reset_flag = 0; static uint8 chip, isK3088; static void BMC411120CCW(uint32 A, uint8 V) { - if (CHRptr[1]) { - chip = EXPREGS[0] & 7; - if (chip > CHRchip_max) chip &= CHRchip_max; - setchr1r(chip, A, V); - } else - setchr1(A, V | ((EXPREGS[0] & 3) << 7)); + uint32 mask = isK3088 ? 0x07 : 0x03; + setchr1(A, V | ((EXPREGS[0] & mask) << 7)); } static void BMC411120CPW(uint32 A, uint8 V) { - if (PRGptr[1]) { - chip = EXPREGS[0] & 7; - if (chip > PRGchip_max) chip &= PRGchip_max; - if (EXPREGS[0] & (isK3088 ? 8 : (8 | reset_flag))) { /* 32K Mode */ - if (A == 0x8000) - setprg32r(chip, A, ((EXPREGS[0] >> 4) & 3)); - } else /* MMC3 Mode */ - setprg8r(chip, A, (V & 0x0F)); - } else { - if (EXPREGS[0] & (isK3088 ? 8 : (8 | reset_flag))) { /* 32K Mode */ - if (A == 0x8000) - /* bit 0-1 of register should be used as outer bank regardless of banking modes */ - setprg32(A, ((EXPREGS[0] >> 4) & 3) | ((EXPREGS[0] & 3) << 2)); - } else /* MMC3 Mode */ - setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 3) << 4)); - } + uint32 mask = isK3088 ? 0x07 : 0x03; + if (EXPREGS[0] & (isK3088 ? 8 : (8 | reset_flag))) { /* 32K Mode */ + if (A == 0x8000) + /* bit 0-1 of register should be used as outer bank regardless of banking modes */ + setprg32(A, ((EXPREGS[0] >> 4) & 3) | ((EXPREGS[0] & mask) << 2)); + } else /* MMC3 Mode */ + setprg8(A, (V & 0x0F) | ((EXPREGS[0] & mask) << 4)); } static DECLFW(BMC411120CLoWrite) { From ec19b07b4d36cfe784bdac61260e1adb2e45527d Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Fri, 12 Jul 2019 23:35:11 +0800 Subject: [PATCH 6/6] Mapper 226: Updated and remove duplicate mapper - Updated mapper 226 to support 1.5mb carts, which in turn makes Unif Ghostbusters63n1 a duplicate. - Unif 42in1ResetSwitch switch to mapper 233 --- src/boards/bmc42in1r.c | 31 +++++++++-- src/boards/ghostbusters63in1.c | 96 ---------------------------------- src/cart.h | 6 ++- src/ines.c | 3 ++ src/unif.c | 11 ++-- 5 files changed, 43 insertions(+), 104 deletions(-) delete mode 100644 src/boards/ghostbusters63in1.c diff --git a/src/boards/bmc42in1r.c b/src/boards/bmc42in1r.c index 6f7a2b3..ce66030 100644 --- a/src/boards/bmc42in1r.c +++ b/src/boards/bmc42in1r.c @@ -3,6 +3,7 @@ * Copyright notice for this file: * Copyright (C) 2005 CaH4e3 * Copyright (C) 2009 qeed + * Copyright (C) 2019 Libretro Team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,10 +23,18 @@ * */ +/* Updated 2019-07-12 + * Mapper 266 - Updated and combine UNIF Ghostbusters63in1 board (1.5 MB carts), different bank order + * - some 1MB carts can switch game lists using Select + * Mapper 233 - UNIF 42in1ResetSwitch - reset-based switching + */ + #include "mapinc.h" +static uint8 reorder_banks = 0; static uint8 isresetbased = 0; static uint8 latche[2], reset; +static uint8 banks[4] = { 0, 0, 1, 2 }; static SFORMAT StateRegs[] = { { &reset, 1, "RST" }, @@ -34,11 +43,17 @@ static SFORMAT StateRegs[] = }; static void Sync(void) { - uint8 bank; + uint8 bank = 0; + uint8 base = ((latche[0] & 0x80) >> 7) | ((latche[1] & 1) << 1); + if (isresetbased) bank = (latche[0] & 0x1f) | (reset << 5) | ((latche[1] & 1) << 6); - else - bank = (latche[0] & 0x1f) | ((latche[0] & 0x80) >> 2) | ((latche[1] & 1) << 6); + else { + if (reorder_banks) /* for 1536 KB prg roms */ + base = banks[base]; + bank = (base << 5) | (latche[0] & 0x1f); + } + if (!(latche[0] & 0x20)) setprg32(0x8000, bank >> 1); else { @@ -65,19 +80,29 @@ static void StateRestore(int version) { Sync(); } +static void M226Reset(void) { + latche[0] = latche[1] = reset = 0; + Sync(); +} + void Mapper226_Init(CartInfo *info) { isresetbased = 0; + /* 1536KiB PRG roms have different bank order */ + reorder_banks = ((info->prgRom * 16) == 1536) ? 1 : 0; info->Power = M226Power; + info->Reset = M226Reset; AddExState(&StateRegs, ~0, 0, 0); GameStateRestore = StateRestore; } static void M233Reset(void) { + latche[0] = latche[1] = 0; reset ^= 1; Sync(); } void Mapper233_Init(CartInfo *info) { + reorder_banks = 0; isresetbased = 1; info->Power = M226Power; info->Reset = M233Reset; diff --git a/src/boards/ghostbusters63in1.c b/src/boards/ghostbusters63in1.c deleted file mode 100644 index bdd1f1e..0000000 --- a/src/boards/ghostbusters63in1.c +++ /dev/null @@ -1,96 +0,0 @@ -/* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2007 CaH4e3 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * 63in1 ghostbusters - */ - -#include "mapinc.h" - -static uint8 reg[2], bank; -static uint8 banks[4] = { 0, 0, 1, 2 }; -static uint8 *CHRROM = NULL; -static uint32 CHRROMSIZE; - -static SFORMAT StateRegs[] = -{ - { reg, 2, "REGS" }, - { &bank, 1, "BANK" }, - { 0 } -}; - -static void Sync(void) { - if (reg[0] & 0x20) { - setprg16(0x8000, (banks[bank] << 5) | (reg[0] & 0x1F)); - setprg16(0xC000, (banks[bank] << 5) | (reg[0] & 0x1F)); - } else - setprg32(0x8000, ((banks[bank] << 5) | (reg[0] & 0x1F)) >> 1); - if (reg[1] & 2) - setchr8r(0x10, 0); - else - setchr8(0); - setmirror((reg[0] & 0x40) >> 6); -} - -static DECLFW(BMCGhostbusters63in1Write) { - reg[A & 1] = V; - bank = ((reg[0] & 0x80) >> 7) | ((reg[1] & 1) << 1); -/* FCEU_printf("reg[0]=%02x, reg[1]=%02x, bank=%02x\n",reg[0],reg[1],bank); */ - Sync(); -} - -static DECLFR(BMCGhostbusters63in1Read) { - if (bank == 1) - return X.DB; - else - return CartBR(A); -} - -static void BMCGhostbusters63in1Power(void) { - reg[0] = reg[1] = 0; - Sync(); - SetReadHandler(0x8000, 0xFFFF, BMCGhostbusters63in1Read); - SetWriteHandler(0x8000, 0xFFFF, BMCGhostbusters63in1Write); -} - -static void BMCGhostbusters63in1Reset(void) { - reg[0] = reg[1] = 0; -} - -static void StateRestore(int version) { - Sync(); -} - -static void BMCGhostbusters63in1Close(void) { - if (CHRROM) - FCEU_gfree(CHRROM); - CHRROM = NULL; -} - -void BMCGhostbusters63in1_Init(CartInfo *info) { - info->Reset = BMCGhostbusters63in1Reset; - info->Power = BMCGhostbusters63in1Power; - info->Close = BMCGhostbusters63in1Close; - - CHRROMSIZE = 8192; /* dummy CHRROM, VRAM disable */ - CHRROM = (uint8*)FCEU_gmalloc(CHRROMSIZE); - SetupCartPRGMapping(0x10, CHRROM, CHRROMSIZE, 0); - AddExState(CHRROM, CHRROMSIZE, 0, "CROM"); - - GameStateRestore = StateRestore; - AddExState(&StateRegs, ~0, 0, 0); -} diff --git a/src/cart.h b/src/cart.h index 66f3e83..56875da 100644 --- a/src/cart.h +++ b/src/cart.h @@ -20,8 +20,10 @@ typedef struct { * set to mapper 4. */ int battery; /* Presence of an actual battery. */ - int prgRam; /* prg ram size (volatile) */ - int chrRam; /* chr ram size (volatile) */ + int prgRom; /* total prg rom size in 16 K chunks */ + int chrRom; /* total chr rom size in 8 K chunks */ + int prgRam; /* prg ram size (volatile) */ + int chrRam; /* chr ram size (volatile) */ int prgRam_battery; /* prg ram size (non-volatile or battery backed) */ int chrRam_battery; /* chr ram size (non-volatile or battery backed) */ int region; /* video system timing (ntsc, pal, dendy */ diff --git a/src/ines.c b/src/ines.c index 1db9530..781f4d3 100644 --- a/src/ines.c +++ b/src/ines.c @@ -819,6 +819,9 @@ int iNESLoad(const char *name, FCEUFILE *fp) { } else if (((prgRom * 0x4000) + (chrRom * 0x2000)) < filesize) FCEU_PrintError(" File contains %llu bytes of unused data\n", filesize - ((prgRom * 0x4000) + (chrRom * 0x2000))); + iNESCart.prgRom = prgRom; + iNESCart.chrRom = chrRom; + ROM_size = uppow2(prgRom); if (chrRom) diff --git a/src/unif.c b/src/unif.c index a4a5fc0..51502a4 100644 --- a/src/unif.c +++ b/src/unif.c @@ -414,7 +414,7 @@ static BMAPPING bmap[] = { { "22211", 132, UNL22211_Init, 0 }, { "3D-BLOCK", 355, UNL3DBlock_Init, 0 }, { "411120-C", 287, BMC411120C_Init, 0 }, - { "42in1ResetSwitch", 226, Mapper226_Init, 0 }, + { "42in1ResetSwitch", 233, Mapper233_Init, 0 }, { "43272", 227, UNL43272_Init, 0 }, { "603-5052", 238, UNL6035052_Init, 0 }, { "64in1NoRepeat", 314, BMC64in1nr_Init, 0 }, @@ -452,7 +452,7 @@ static BMAPPING bmap[] = { { "GK-192", NO_INES, BMCGK192_Init, 0 }, /* mapper 58? */ { "GS-2004", 283, BMCGS2004_Init, 0 }, { "GS-2013", 283, BMCGS2013_Init, 0 }, - { "Ghostbusters63in1", NO_INES, BMCGhostbusters63in1_Init, 0 }, /* similar to 226 but different bank order */ + { "Ghostbusters63in1", 226, Mapper226_Init, 0 }, { "H2288", 123, UNLH2288_Init, 0 }, { "HKROM", 4, HKROM_Init, 0 }, { "KOF97", 263, UNLKOF97_Init, 0 }, @@ -585,7 +585,7 @@ static BMAPPING bmap[] = { { "JC-016-2", 205, Mapper205_Init, 0 }, { "AX-40G", 527, UNLAX40G_Init, 0 }, { " BMC-STREETFIGTER-GAME4IN1", NO_INES, BMCSFGAME4IN1_Init, 0 }, /* mapper 49? submapper 1*/ - { "G631", NO_INES, BMCGhostbusters63in1_Init, 0 }, /* duplicate, probably wrong name */ + { "G631", 226, Mapper226_Init, 0 }, /* duplicate, probably wrong name */ { "BJ-56", 526, UNLBJ56_Init, 0 }, { "L6IN1", 345, BMCL6IN1_Init, 0 }, { "CTC-12IN1", 337, BMCCTC12IN1_Init, 0 }, @@ -731,6 +731,11 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { if (!LoadUNIFChunks(fp)) goto aborto; + UNIFCart.prgRom = (UNIF_PRGROMSize / 0x1000) + ((UNIF_PRGROMSize % 0x1000) ? 1 : 0); + UNIFCart.prgRom = (UNIFCart.prgRom >> 2) + ((UNIFCart.prgRom & 3) ? 1: 0); + UNIFCart.chrRom = (UNIF_CHRROMSize / 0x400) + ((UNIF_CHRROMSize % 0x400) ? 1 : 0); + UNIFCart.chrRom = (UNIFCart.chrRom >> 3) + ((UNIFCart.chrRom & 7) ? 1: 0); + ROM_size = FixRomSize(UNIF_PRGROMSize, 2048); if (UNIF_CHRROMSize) VROM_size = FixRomSize(UNIF_CHRROMSize, 8192);