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/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) { 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/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/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 deleted file mode 100644 index 2ca6ee1..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) { - setprg16r(banks[bank], 0x8000, reg[0] & 0x1F); - setprg16r(banks[bank], 0xC000, reg[0] & 0x1F); - } else - setprg32r(banks[bank], 0x8000, (reg[0] >> 1) & 0x0F); - 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/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/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..56875da 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,14 @@ typedef struct { * set to mapper 4. */ int battery; /* Presence of an actual battery. */ - int vram_size; + 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 */ + 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..781f4d3 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); } } @@ -649,26 +651,113 @@ 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) { 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 +778,54 @@ 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))); + + iNESCart.prgRom = prgRom; + iNESCart.chrRom = chrRom; + + ROM_size = uppow2(prgRom); + + if (chrRom) + VROM_size = uppow2(chrRom); if ((ROM = (uint8*)FCEU_malloc(ROM_size << 14)) == NULL) return 0; @@ -717,36 +840,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 +865,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 +890,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 +992,32 @@ 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: + 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; + 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..51502a4 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; @@ -74,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; @@ -101,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; @@ -114,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]; @@ -267,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; @@ -275,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); } @@ -303,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; @@ -311,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); } @@ -353,7 +374,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); @@ -378,6 +399,7 @@ static void CheckHashInfo(void) { } +#define NO_INES -1 #define BMCFLAG_FORCE4 0x01 #define BMCFLAG_16KCHRR 0x02 #define BMCFLAG_32KCHRR 0x04 @@ -385,201 +407,202 @@ 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", 233, Mapper233_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", 226, Mapper226_Init, 0 }, + { "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 }, + { "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? submapper 1*/ + { "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 }, + { "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[] = { @@ -631,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) @@ -688,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)) @@ -703,23 +730,54 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { goto aborto; if (!LoadUNIFChunks(fp)) goto aborto; - { - int x; - struct md5_context md5; - md5_starts(&md5); + 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); - 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_size = FixRomSize(UNIF_PRGROMSize, 2048); + if (UNIF_CHRROMSize) + VROM_size = FixRomSize(UNIF_CHRROMSize, 8192); + + 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;