From 1d33799c0c149ea942d17dfb8e32d6edb027b68e Mon Sep 17 00:00:00 2001 From: Oggom Date: Sun, 12 Jul 2015 01:06:14 +0200 Subject: [PATCH] Backport r174 - UNIF BMC-10-24-C-A1 - new dump 6-in-1 by ClusteR --- Fceuwin.dev | 6 +- src/boards/coolboy.c | 106 ++++++++++++++++++++----------- src/boards/et-100.c | 103 ++++++++++++++++++++++++++++++ src/boards/onebus.c | 4 +- src/drivers/libretro/fceu/unif.c | 1 + src/unif.c | 1 + src/unif.h | 1 + 7 files changed, 180 insertions(+), 42 deletions(-) create mode 100644 src/boards/et-100.c diff --git a/Fceuwin.dev b/Fceuwin.dev index 856654d..868b1c3 100644 --- a/Fceuwin.dev +++ b/Fceuwin.dev @@ -1,7 +1,7 @@ [Project] FileName=Fceuwin.dev Name=Fceu -UnitCount=298 +UnitCount=299 Type=0 Ver=1 ObjFiles= @@ -2658,9 +2658,9 @@ OverrideBuildCmd=0 BuildCmd= [Unit299] -FileName=src\boards\addrlatch.c +FileName=src\boards\et-100.c CompileCpp=0 -Folder=boards +Folder=boards/mmc3 based Compile=1 Link=1 Priority=1000 diff --git a/src/boards/coolboy.c b/src/boards/coolboy.c index a5c5ffa..bee3489 100644 --- a/src/boards/coolboy.c +++ b/src/boards/coolboy.c @@ -1,7 +1,7 @@ -/* FCE Ultra - NES/Famicom Emulator +/* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2015 CaH4e3 + * Copyright (C) 2015 CaH4e3, ClusteR * * 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 @@ -20,67 +20,95 @@ * CoolBoy 400-in-1 FK23C-mimic mapper 16Mb/32Mb PROM + 128K/256K CHR RAM, optional SRAM, optional NTRAM * only MMC3 mode * - * 6000 (õõ76x210) | 0õÑ0 - * 6001 (õõõ354õõ) + * 6000 (xx76x210) | 0xC0 + * 6001 (xxx354x) * 6002 = 0 * 6003 = 0 * + * hardware tested logic, don't try to understand lol */ #include "mapinc.h" #include "mmc3.h" static void COOLBOYCW(uint32 A, uint8 V) { - if(EXPREGS[3] & 0x10) - setchr8(EXPREGS[2] & 0xF); - else { - uint32 mask = 0xFF; - switch(EXPREGS[0] & 0xC0) { - case 0xC0: - mask = 0x7F; - break; + uint32 mask = 0xFF ^ (EXPREGS[0] & 0x80); + if (EXPREGS[3] & 0x10) { + if (EXPREGS[3] & 0x40) { // Weird mode + int cbase = (MMC3_cmd & 0x80) << 5; + switch (cbase ^ A) { // Don't even try do understand + case 0x0400: + case 0x0C00: V &= 0x7F; break; + } } - setchr1(A, V & mask); + setchr8((((EXPREGS[2] & 0x0F) | ((V & 0x80) >> 3)) & (mask >> 3)) | ((((EXPREGS[0] & 0x08) << 4) & ~mask) >> 3)); + } else { + if (EXPREGS[3] & 0x40) { // Weird mode, again + int cbase = (MMC3_cmd & 0x80) << 5; + switch (cbase ^ A) { // Don't even try do understand + case 0x0000: V = DRegBuf[0]; break; + case 0x0800: V = DRegBuf[1]; break; + case 0x0400: + case 0x0C00: V = 0; break; + } + } + setchr1(A, (V & mask) | (((EXPREGS[0] & 0x08) << 4) & (mask ^ 0xff))); } } static void COOLBOYPW(uint32 A, uint8 V) { - uint32 mask = 0x3F; + uint32 mask = ((0x3F | (EXPREGS[1] & 0x40) | ((EXPREGS[1] & 0x20) << 2)) ^ ((EXPREGS[0] & 0x40) >> 2)) ^ ((EXPREGS[1] & 0x80) >> 2); uint32 base = ((EXPREGS[0] & 0x07) >> 0) | ((EXPREGS[1] & 0x10) >> 1) | ((EXPREGS[1] & 0x0C) << 2) | ((EXPREGS[0] & 0x30) << 2); - switch(EXPREGS[0] & 0xC0) { - case 0x80: - mask = 0x1F; - break; - case 0xC0: - if(EXPREGS[3] & 0x10) { - mask = 0x01 | (EXPREGS[1] & 2); - } else { - mask = 0x0F; + + // Very weird mode + // Last banks are first in this mode, ignored when MMC3_cmd&0x40 + if ((EXPREGS[3] & 0x40) && (V >= 0xFE) && !((MMC3_cmd & 0x40) != 0)) { + switch (A & 0xE000) { + case 0xA000: + if ((MMC3_cmd & 0x40) != 0) V = 0; + break; + case 0xC000: + if ((MMC3_cmd & 0x40) == 0) V = 0; + break; + case 0xE000: + V = 0; + break; } - break; } - if(EXPREGS[3] & 0x10) - setprg8(A, (base << 4) | (V & mask) | ((EXPREGS[3] & (0x0E ^ (EXPREGS[1] & 2))) )); - else - setprg8(A, (base << 4) | (V & mask)); + + // Regular MMC3 mode, internal ROM size can be up to 2048kb! Minimal is 64kb + if (!(EXPREGS[3] & 0x10)) + setprg8(A, (((base << 4) & ~mask)) | (V & mask)); + else { // NROM mode + mask &= 0xF0; + uint8 emask; + if (!(EXPREGS[1] & 2)) // 4kb mode, 0xC000-0xFFFF is same as 0x8000-0xBFFF + emask = EXPREGS[3] & 0x0E; + else // 8kb mode, using second-last bank + emask = (EXPREGS[3] & 0x0C) | ((A >= 0xC000) ? 2 : 0); + emask |= (A >> 13) & 1; // does not depends on MMC3_cmd&0x40 + setprg8(A, (((base << 4) & ~mask) | (V & mask) | emask)); + } } static DECLFW(COOLBOYWrite) { if(A001B & 0x80) CartBW(A,V); - else - if((EXPREGS[3] & 0x80) == 0) { - EXPREGS[A & 3] = V; - FixMMC3PRG(MMC3_cmd); - FixMMC3CHR(MMC3_cmd); - uint32 base = ((EXPREGS[0] & 0x07) >> 0) | ((EXPREGS[1] & 0x10) >> 1) | ((EXPREGS[1] & 0x0C) << 2) | ((EXPREGS[0] & 0x30) << 2); - FCEU_printf("exp %02x %02x (base %03d)\n",A,V,base); - } + + if((EXPREGS[3] & 0x80) == 0) { + EXPREGS[A & 3] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } } static void COOLBOYReset(void) { MMC3RegReset(); EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; +// EXPREGS[0] = 0; +// EXPREGS[1] = 0x60; +// EXPREGS[2] = 0; +// EXPREGS[3] = 0; FixMMC3PRG(MMC3_cmd); FixMMC3CHR(MMC3_cmd); } @@ -88,6 +116,10 @@ static void COOLBOYReset(void) { static void COOLBOYPower(void) { GenMMC3Power(); EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; +// EXPREGS[0] = 0; +// EXPREGS[1] = 0x60; +// EXPREGS[2] = 0; +// EXPREGS[3] = 0; FixMMC3PRG(MMC3_cmd); FixMMC3CHR(MMC3_cmd); SetWriteHandler(0x5000, 0x5fff, CartBW); // some games access random unmapped areas and crashes because of KT-008 PCB hack in MMC3 source lol @@ -95,7 +127,7 @@ static void COOLBOYPower(void) { } void COOLBOY_Init(CartInfo *info) { - GenMMC3_Init(info, 512, 128, 8, 0); + GenMMC3_Init(info, 512, 256, 8, 0); pwrap = COOLBOYPW; cwrap = COOLBOYCW; info->Power = COOLBOYPower; diff --git a/src/boards/et-100.c b/src/boards/et-100.c new file mode 100644 index 0000000..70882ee --- /dev/null +++ b/src/boards/et-100.c @@ -0,0 +1,103 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2015 Cluster + * http://clusterrr.com + * clusterrr@clusterrr.com + * + * 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 + */ + +/* + MMC3-based multicart mapper with CHR RAM, CHR ROM and PRG RAM + + $6000-7FFF: A~[011xxxxx xxMRSBBB] Multicart reg + This register can only be written to if PRG-RAM is enabled and writable (see $A001) + and BBB = 000 (power on state) + + BBB = CHR+PRG block select bits (A19, A18, A17 for both PRG and CHR) + S = PRG block size (0=256k 1=128k) + R = CHR mode (0=CHR ROM 1=CHR RAM) + M = CHR block size (0=256k 1=128k) + ignored when S is 0 for some reason + + Example Game: + -------------------------- + 6 in 1 multicart (SMB3, TMNT2, Contra, Ninja Cat, Ninja Crusaders, Rainbow Islands 2) +*/ + +#include "mapinc.h" +#include "mmc3.h" + +static uint8 *CHRRAM = NULL; +static uint32 CHRRAMSize; + +static void BMC1024CA1PW(uint32 A, uint8 V) { + if ((EXPREGS[0]>>3)&1) + setprg8(A, (V&0x1F) | ((EXPREGS[0] & 7) << 4)); + else + setprg8(A, (V&0x0F) | ((EXPREGS[0] & 7) << 4)); +} + +static void BMC1024CA1CW(uint32 A, uint8 V) { + if ((EXPREGS[0]>>4)&1) + setchr1r(0x10, A, V); + else if (((EXPREGS[0]>>5)&1) && ((EXPREGS[0]>>3)&1)) + setchr1(A, V | ((EXPREGS[0] & 7) << 7)); + else + setchr1(A, (V&0x7F) | ((EXPREGS[0] & 7) << 7)); +} + +static DECLFW(BMC1024CA1Write) { + if (((A001B & 0xC0) == 0x80) && !(EXPREGS[0] & 7)) + { + EXPREGS[0] = A & 0x3F; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } else { + CartBW(A, V); + } +} + +static void BMC1024CA1Reset(void) { + EXPREGS[0] = 0; + MMC3RegReset(); +} + +static void BMC1024CA1Power(void) { + EXPREGS[0] = 0; + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, BMC1024CA1Write); +} + +static void BMC1024CA1Close(void) { + if (CHRRAM) + FCEU_gfree(CHRRAM); + CHRRAM = NULL; +} + +void BMC1024CA1_Init(CartInfo *info) { + GenMMC3_Init(info, 256, 256, 8, 0); + CHRRAMSize = 8192; + CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSize); + SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSize, 1); + AddExState(CHRRAM, CHRRAMSize, 0, "CHRR"); + pwrap = BMC1024CA1PW; + cwrap = BMC1024CA1CW; + info->Power = BMC1024CA1Power; + info->Reset = BMC1024CA1Reset; + info->Close = BMC1024CA1Close; + AddExState(EXPREGS, 1, 0, "EXPR"); +} diff --git a/src/boards/onebus.c b/src/boards/onebus.c index 8b92fb2..7cd23d7 100644 --- a/src/boards/onebus.c +++ b/src/boards/onebus.c @@ -113,7 +113,7 @@ static void CSync(void) { setchr1(0x1800 ^ cswap, block | (bank6 & mask)); setchr1(0x1c00 ^ cswap, block | (bank7 & mask)); - setmirror(mirror & 1); + setmirror((mirror ^ 1) & 1); } static void Sync(void) { @@ -158,7 +158,7 @@ static DECLFW(UNLOneBusWriteMMC3) { } break; } - case 0xa000: mirror = V ^ 1; CSync(); break; + case 0xa000: mirror = V; CSync(); break; case 0xc000: IRQLatch = V & 0xfe; break; case 0xc001: IRQReload = 1; break; case 0xe000: X6502_IRQEnd(FCEU_IQEXT); IRQa = 0; break; diff --git a/src/drivers/libretro/fceu/unif.c b/src/drivers/libretro/fceu/unif.c index 10151bc..0c1c6da 100644 --- a/src/drivers/libretro/fceu/unif.c +++ b/src/drivers/libretro/fceu/unif.c @@ -342,6 +342,7 @@ static BMAPPING bmap[] = { { "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 }, diff --git a/src/unif.c b/src/unif.c index af012be..5b305c3 100644 --- a/src/unif.c +++ b/src/unif.c @@ -342,6 +342,7 @@ static BMAPPING bmap[] = { { "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 }, diff --git a/src/unif.h b/src/unif.h index bca1ad1..6149eb4 100644 --- a/src/unif.h +++ b/src/unif.h @@ -46,6 +46,7 @@ void BMCGhostbusters63in1_Init(CartInfo *info); void BMCNTD03_Init(CartInfo *info); void BMCT2271_Init(CartInfo *info); void BMCT262_Init(CartInfo *info); +void BMC1024CA1_Init(CartInfo *info); void CNROM_Init(CartInfo *info); void CPROM_Init(CartInfo *info); void DreamTech01_Init(CartInfo *info);