diff --git a/src/boards/8in1.c b/src/boards/8in1.c new file mode 100644 index 0000000..a03d667 --- /dev/null +++ b/src/boards/8in1.c @@ -0,0 +1,67 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2016 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 + * + * 8-in-1 Rockin' Kats, Snake, (PCB marked as "8 in 1"), similar to 12IN1, + * but with MMC3 on board, all games are hacked the same, Snake is buggy too! + * + * no reset-citcuit, so selected game can be reset, but to change it you must use power + * + */ + +#include "mapinc.h" +#include "mmc3.h" + +static void BMC8IN1CW(uint32 A, uint8 V) { + setchr1(A, ((EXPREGS[0] & 0xC) << 5) | (V & 0x7F)); +} + +static void BMC8IN1PW(uint32 A, uint8 V) { + if(EXPREGS[0] & 0x10) { // MMC3 mode + setprg8(A, ((EXPREGS[0] & 0xC) << 2) | (V & 0xF)); + } else { + setprg32(0x8000, EXPREGS[0] & 0xF); + } +} + +static DECLFW(BMC8IN1Write) { + if(A & 0x1000) { + EXPREGS[0] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } else { + if(A < 0xC000) + MMC3_CMDWrite(A, V); + else + MMC3_IRQWrite(A, V); + } +} + +static void BMC8IN1Power(void) { + EXPREGS[0] = 0; + GenMMC3Power(); + SetWriteHandler(0x8000, 0xFFFF, BMC8IN1Write); +} + +void BMC8IN1_Init(CartInfo *info) { + GenMMC3_Init(info, 128, 128, 0, 0); + cwrap = BMC8IN1CW; + pwrap = BMC8IN1PW; + info->Power = BMC8IN1Power; + AddExState(EXPREGS, 1, 0, "EXPR"); +} diff --git a/src/boards/addrlatch.c b/src/boards/addrlatch.c index dc0128e..b18ac2d 100644 --- a/src/boards/addrlatch.c +++ b/src/boards/addrlatch.c @@ -303,7 +303,7 @@ static void M212Sync(void) { } void Mapper212_Init(CartInfo *info) { - Latch_Init(info, M212Sync, M212Read, 0xFFFF, 0x8000, 0xFFFF, 0); + Latch_Init(info, M212Sync, M212Read, 0x0000, 0x8000, 0xFFFF, 0); } //------------------ Map 213 --------------------------- diff --git a/src/boards/et-4320.c b/src/boards/et-4320.c new file mode 100644 index 0000000..5e75a73 --- /dev/null +++ b/src/boards/et-4320.c @@ -0,0 +1,119 @@ +/* FCE Ultra - NES/Famicom Emulator +* +* Copyright notice for this file: +* Copyright (C) 2016 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 & mirroring mode (0=128k with normal MMC3, 1=256k with TxSROM-like single-screen mirroring) +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: +-------------------------- +7 in 1 multicart (Amarello, TMNT2, Contra, Ninja Cat, Ninja Crusaders, Rainbow Islands 2) +*/ + +#include "mapinc.h" +#include "mmc3.h" + +static uint8 *CHRRAM; +static uint32 CHRRAMSize; +static uint8 PPUCHRBus; +static uint8 TKSMIR[8]; + +static void BMC810131C_PW(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 BMC810131C_CW(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)); + + TKSMIR[A >> 10] = V >> 7; + if (((EXPREGS[0] >> 3) & 1) && (PPUCHRBus == (A >> 10))) + setmirror(MI_0 + (V >> 7)); +} + +static DECLFW(BMC810131C_Write) { + if (((A001B & 0xC0) == 0x80) && !(EXPREGS[0] & 7)) + { + EXPREGS[0] = A & 0x3F; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } + else { + CartBW(A, V); + } +} + +static void BMC810131C_Reset(void) { + EXPREGS[0] = 0; + MMC3RegReset(); +} + +static void BMC810131C_Power(void) { + EXPREGS[0] = 0; + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, BMC810131C_Write); +} + +static void BMC810131C_Close(void) { + if (CHRRAM) + FCEU_gfree(CHRRAM); + CHRRAM = NULL; +} + +static void TKSPPU(uint32 A) { + A &= 0x1FFF; + A >>= 10; + PPUCHRBus = A; + if ((EXPREGS[0] >> 3) & 1) + setmirror(MI_0 + TKSMIR[A]); +} + +void BMC810131C_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 = BMC810131C_PW; + cwrap = BMC810131C_CW; + PPU_hook = TKSPPU; + info->Power = BMC810131C_Power; + info->Reset = BMC810131C_Reset; + info->Close = BMC810131C_Close; + AddExState(EXPREGS, 1, 0, "EXPR"); +} diff --git a/src/boards/ks7016.c b/src/boards/ks7016.c new file mode 100644 index 0000000..fc14d7a --- /dev/null +++ b/src/boards/ks7016.c @@ -0,0 +1,85 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2016 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 + * + * FDS Conversion (Exciting Basket), weird banking addressing, seems because + * of used addressing scheme, made to disable the lower system banks from 6000 + * but the kaiser mapper chip and PCB are the same as usual + * probably need a hard eprom dump to verify actual banks layout + * + */ + +#include "mapinc.h" + +static uint8 preg; + +static SFORMAT StateRegs[] = +{ + { &preg, 1, "PREG" }, + { 0 } +}; + +static void Sync(void) { + setprg8(0x6000, preg); + setprg8(0x8000, 0xC); + setprg8(0xA000, 0xD); + setprg8(0xC000, 0xE); + setprg8(0xE000, 0xF); + setchr8(0); +} + +static DECLFW(UNLKS7016Write) { + unsigned short mask = (A & 0x30); + switch(A & 0xD943) { + case 0xD943: { + if(mask == 0x30) { + preg = 8 | 3; // or A, or no bus (all FF) + } else { + preg = (A >> 2) & 0xF; // can be anything but C-F + } + Sync(); + break; + } + case 0xD903: { // this case isn't usedby the game, but addressing does this as a side effect + if(mask == 0x30) { + preg = 8 | ((A >> 2) & 3); // also masked C-F from output + } else { + preg = 8 | 3; + } + Sync(); + break; + } + } +} + +static void UNLKS7016Power(void) { + preg = 8; + Sync(); + SetReadHandler(0x6000, 0xffff, CartBR); + SetWriteHandler(0x8000, 0xffff, UNLKS7016Write); +} + +static void StateRestore(int version) { + Sync(); +} + +void UNLKS7016_Init(CartInfo *info) { + info->Power = UNLKS7016Power; + GameStateRestore = StateRestore; + AddExState(&StateRegs, ~0, 0, 0); +} diff --git a/src/boards/mmc3.c b/src/boards/mmc3.c index 2f4bfb2..c3c4ae4 100644 --- a/src/boards/mmc3.c +++ b/src/boards/mmc3.c @@ -498,13 +498,18 @@ static void M45CW(uint32 A, uint8 V) { NV &= 0; // hack ;( don't know exactly how it should be NV |= EXPREGS[0] | ((EXPREGS[2] & 0xF0) << 4); setchr1(A, NV); - } + } else +// setchr8(0); // i don't know what cart need this, but a new one need other lol + setchr1(A, V); } static void M45PW(uint32 A, uint8 V) { - V &= (EXPREGS[3] & 0x3F) ^ 0x3F; - V |= EXPREGS[1]; - setprg8(A, V); + uint32 MV = V & ((EXPREGS[3] & 0x3F) ^ 0x3F); + MV |= EXPREGS[1]; + if(UNIFchrrama) + MV |= ((EXPREGS[2] & 0x40) << 2); + setprg8(A, MV); +// FCEU_printf("1:%02x 2:%02x 3:%02x A=%04x V=%03x\n",EXPREGS[1],EXPREGS[2],EXPREGS[3],A,MV); } static DECLFW(M45Write) { @@ -534,7 +539,6 @@ static void M45Reset(void) { } static void M45Power(void) { - setchr8(0); GenMMC3Power(); EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = EXPREGS[4] = EXPREGS[5] = 0; SetWriteHandler(0x5000, 0x7FFF, M45Write); diff --git a/src/unif.c b/src/unif.c index aec3f7f..1bdd39c 100644 --- a/src/unif.c +++ b/src/unif.c @@ -151,7 +151,7 @@ static int NAME(FCEUFILE *fp) { int index; int t; - FCEU_printf(" Name: "); + //FCEU_printf(" Name: "); index = 0; while ((t = FCEU_fgetc(fp)) > 0) @@ -159,7 +159,7 @@ static int NAME(FCEUFILE *fp) { namebuf[index++] = t; namebuf[index] = 0; - FCEU_printf("%s\n", namebuf); + FCEU_printf(" Name: %s\n", namebuf); if (!GameInfo->name) { GameInfo->name = malloc(strlen(namebuf) + 1); @@ -256,7 +256,7 @@ static int LoadPRG(FCEUFILE *fp) { if (z < 0 || z > 15) return(0); - FCEU_printf(" PRG ROM %d size: %d", z, (int)uchead.info); + FCEU_printf(" PRG ROM %d size: %d\n", z, (int)uchead.info); if (malloced[z]) free(malloced[z]); t = FixRomSize(uchead.info, 2048); @@ -267,8 +267,8 @@ 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"); + } /* else + FCEU_printf("\n"); */ SetupCartPRGMapping(z, malloced[z], t, 0); return(1); @@ -291,7 +291,7 @@ static int LoadCHR(FCEUFILE *fp) { z = uchead.ID[3] - '0'; if (z < 0 || z > 15) return(0); - FCEU_printf(" CHR ROM %d size: %d", z, (int)uchead.info); + 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); @@ -302,8 +302,8 @@ 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"); + } /* else + FCEU_printf("\n"); */ SetupCartCHRMapping(z, malloced[16 + z], t, 0); return(1); @@ -342,7 +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 }, + { "10-24-C-A1", BMC1024CA1_Init, 0 }, { "CNROM", CNROM_Init, 0 }, { "CPROM", CPROM_Init, BMCFLAG_16KCHRR }, { "D1038", BMCD1038_Init, 0 }, @@ -354,7 +354,7 @@ static BMAPPING bmap[] = { { "ELROM", ELROM_Init, 0 }, { "ETROM", ETROM_Init, 0 }, { "EWROM", EWROM_Init, 0 }, - { "FK23C", BMCFK23C_Init, BMCFLAG_256KCHRR }, + { "FK23C", BMCFK23C_Init, BMCFLAG_256KCHRR }, { "FK23CA", BMCFK23CA_Init, BMCFLAG_256KCHRR }, { "FS304", UNLFS304_Init, 0 }, { "G-146", BMCG146_Init, 0 }, @@ -368,6 +368,7 @@ static BMAPPING bmap[] = { { "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 }, @@ -456,6 +457,8 @@ static BMAPPING bmap[] = { { "EH8813A", UNLEH8813A_Init, 0 }, { "HP898F", BMCHP898F_Init, 0 }, { "F-15", BMCF15_Init, 0 }, + { "81-01-31-C", BMC810131C_Init, 0 }, + { "8-IN-1", BMC8IN1_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 1d5f960..e00ed5f 100644 --- a/src/unif.h +++ b/src/unif.h @@ -126,6 +126,7 @@ void UNLH2288_Init(CartInfo *info); void UNLKOF97_Init(CartInfo *info); void UNLKS7012_Init(CartInfo *info); void UNLKS7013B_Init(CartInfo *info); +void UNLKS7016_Init(CartInfo *info); void UNLKS7017_Init(CartInfo *info); void UNLKS7030_Init(CartInfo *info); void UNLKS7031_Init(CartInfo *info); @@ -152,6 +153,8 @@ void UNLBMW8544_Init(CartInfo *info); void UNLEH8813A_Init(CartInfo *info); void BMCHP898F_Init(CartInfo *info); void BMCF15_Init(CartInfo *info); +void BMC810131C_Init(CartInfo *info); +void BMC8IN1_Init(CartInfo *info); #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info);