Merge pull request #500 from NRS-NewRisingSun/mapper134fix

Mapper 134 and frame IRQ correction
This commit is contained in:
Autechre 2022-02-26 22:37:52 +01:00 committed by GitHub
commit c8043b1d31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 101 additions and 302 deletions

96
src/boards/134.c Normal file
View File

@ -0,0 +1,96 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2020 negativeExponent
*
* 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
*/
/* Chipset used on various PCBs named WX-KB4K, T4A54A, BS-5652... */
/* "Rockman 3" on YH-322 and "King of Fighters 97" on "Super 6-in-1" enable interrupts without initializing the frame IRQ register and therefore freeze on real hardware.
They can run if another game is selected that does initialize the frame IRQ register, then soft-resetting to the menu and selecting the previously-freezing games. */
#include "mapinc.h"
#include "mmc3.h"
static uint8 dip;
static void Mapper134_PRGWrap(uint32 A, uint8 V) {
int prgAND =EXPREGS[1] &0x04? 0x0F: 0x1F;
int prgOR =EXPREGS[1] <<4 &0x30 | EXPREGS[0] <<2 &0x40;
if (EXPREGS[1] &0x80) { /* NROM mode */
if (EXPREGS[1] &0x08) { /* NROM-128 mode */
setprg8(0x8000, (DRegBuf[6] &~1 |0) &prgAND | prgOR &~prgAND);
setprg8(0xA000, (DRegBuf[6] &~1 |1) &prgAND | prgOR &~prgAND);
setprg8(0xC000, (DRegBuf[6] &~1 |0) &prgAND | prgOR &~prgAND);
setprg8(0xE000, (DRegBuf[6] &~1 |1) &prgAND | prgOR &~prgAND);
} else { /* NROM-256 mode */
setprg8(0x8000, (DRegBuf[6] &~3 |0) &prgAND | prgOR &~prgAND);
setprg8(0xA000, (DRegBuf[6] &~3 |1) &prgAND | prgOR &~prgAND);
setprg8(0xC000, (DRegBuf[6] &~3 |2) &prgAND | prgOR &~prgAND);
setprg8(0xE000, (DRegBuf[6] &~3 |3) &prgAND | prgOR &~prgAND);
}
} else
setprg8(A, V &prgAND | prgOR &~prgAND);
}
static void Mapper134_CHRWrap(uint32 A, uint8 V) {
int chrAND =EXPREGS[1] &0x40? 0x7F: 0xFF;
int chrOR =EXPREGS[1] <<3 &0x180 | EXPREGS[0] <<4 &0x200;
if (EXPREGS[0] &0x08) V =EXPREGS[2] <<3 | A >>10 &7; /* In CNROM mode, outer bank register 2 replaces the MMC3's CHR registers, and CHR A10-A12 are PPU A10-A12. */
setchr1(A, V &chrAND | chrOR &~chrAND);
}
static DECLFR(Mapper134_Read) {
return EXPREGS[0] &0x40? dip: CartBR(A);
}
static DECLFW(Mapper134_Write) {
if (~EXPREGS[0] &0x80) {
EXPREGS[A &3] =V;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
} else
if ((A &3) ==2) {
EXPREGS[A &3] =EXPREGS[A &3] &~3 | V &3;
FixMMC3CHR(MMC3_cmd);
}
CartBW(A, V);
}
static void Mapper134_Reset(void) {
dip++;
dip &= 15;
EXPREGS[0] =EXPREGS[1] =EXPREGS[2] =EXPREGS[3] =0;
MMC3RegReset();
}
static void Mapper134_Power(void) {
dip =0;
EXPREGS[0] =EXPREGS[1] =EXPREGS[2] =EXPREGS[3] =0;
GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, Mapper134_Write);
SetReadHandler(0x8000, 0xFFFF, Mapper134_Read);
}
void Mapper134_Init(CartInfo *info) {
GenMMC3_Init(info, 256, 256, info->iNES2? (info->PRGRamSize + info->PRGRamSaveSize) /1024: 8, info->battery);
cwrap = Mapper134_CHRWrap;
pwrap = Mapper134_PRGWrap;
info->Power = Mapper134_Power;
info->Reset = Mapper134_Reset;
AddExState(EXPREGS, 4, 0, "EXPR");
AddExState(&dip, 1, 0, "DIPS");
}

View File

@ -1,253 +0,0 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2008 -2020 dragon2snow,loong2snow from www.nesbbs.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
*
*
*/
#include "mapinc.h"
#include "mmc3.h"
#include "crc32.h"
static uint8 *WRAM;
static uint32 WRAMSIZE;
static uint8 mmc3_reg[8];
static uint8 exRegs[8];
static uint8 pointer;
static uint8 locked;
static uint8 readDIP;
static uint16 prgAND;
static uint16 chrAND;
static uint16 prgOR;
static uint16 chrOR;
static uint8 nrom;
static uint8 nrom128;
static uint8 dipswitch;
static SFORMAT BS5652_StateRegs[] =
{
{ exRegs, 8, "REGS" },
{ mmc3_reg, 8, "MREG" },
{ &pointer, 1, "PNT0" },
{ &readDIP, 1, "RDIP" },
{ &prgAND, 2 | FCEUSTATE_RLSB, "PAND" },
{ &chrAND, 2 | FCEUSTATE_RLSB, "CAND" },
{ &prgOR, 2 | FCEUSTATE_RLSB, "PROR" },
{ &chrOR, 2 | FCEUSTATE_RLSB, "CHOR" },
{ &nrom, 1, "NROM" },
{ &nrom128, 1, "N128" },
{ &dipswitch, 1, "DIP0" },
{ 0 }
};
void Bs5652AnalyzeReg()
{
locked = exRegs[0] & 0x80;
readDIP = exRegs[0] & 0x40;
prgAND = exRegs[1] & 0x04 ? 0x0F : 0x1F;
chrAND = exRegs[1] & 0x40 ? 0x7F : 0xFF;
prgOR = (exRegs[1] & 0x03) << 4 | (exRegs[0] & 0x10) << 2;
chrOR = (exRegs[1] & 0x30) << 3 | (exRegs[0] & 0x20) << 4;
nrom = exRegs[0] & 0x08;
nrom128 = exRegs[1] & 0x08;
}
int Bs5652GetPRGBank(int bank)
{
if ((~bank & 1) && (pointer & 0x40)) bank ^= 2;
return (bank & 2) ? 0xFE | (bank & 1) : mmc3_reg[6 | (bank & 1)];
}
void Bs5652SyncPRG_GNROM(int A14, int AND, int OR) {
setprg8(0x8000, ((Bs5652GetPRGBank(0) &~A14) &AND) | OR);
setprg8(0xA000, ((Bs5652GetPRGBank(1) &~A14) &AND) | OR);
setprg8(0xC000, ((Bs5652GetPRGBank(0) | A14) &AND) | OR);
setprg8(0xE000, ((Bs5652GetPRGBank(1) | A14) &AND) | OR);
}
static void Bs5652CW(uint32 A, uint8 V) {
if (exRegs[0] & 0x08)
setchr8((exRegs[2] & 0x0F) | (exRegs[4] & 0x03) | (((exRegs[1] >> 4) & 7) << 4));
else
setchr1(A, (V & chrAND) | chrOR );
}
static void Bs5652PW(uint32 A, uint8 V) {
if (nrom)
{
if (exRegs[3] & 0x8) /* 20190504 up2 */
{
if ((exRegs[1] >> 3) & 0x01)
{
uint8 _bank = ((exRegs[2] >> 1) & 0x07) | ((exRegs[1] & 3) << 3);
setprg16(0x8000, _bank);
setprg16(0xC000, _bank);
}
else
{
setprg32(0x8000,((exRegs[2] >> 2) & 0x03) | ((exRegs[1] & 3) << 2));
}
}
else
{
Bs5652SyncPRG_GNROM(nrom128 ? 0 : 2, prgAND, prgOR);
}
}
else
{
if (((exRegs[1] >> 7) & 0x01))
{
setprg32(0x8000,((Bs5652GetPRGBank(0) >> 2) & 0x03) | ((exRegs[1] & 3) << 2));
}
else
setprg8(A, prgOR | (V & prgAND));
}
}
static DECLFW(Bs5652WriteHi) {
A = A & 0xE001;
if (A < 0xC000)
{
if(A==0x8000)
pointer = MMC3_cmd ^ V;
if(A==0x8001)
mmc3_reg[MMC3_cmd & 0x07] = V;
MMC3_CMDWrite(A, V);
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
else
{
MMC3_IRQWrite(A, V);
}
}
static DECLFW(Bs5652WriteLo) {
if (!locked) {
exRegs[A & 3] = V;
Bs5652AnalyzeReg();
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
else
{
if ((exRegs[0] & 0x08))
{
exRegs[4] = V;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
else
{
WRAM[A - 0x6000] = V;
}
}
}
static DECLFR(Bs5652ReadHi)
{
if (readDIP)
return dipswitch;
return CartBR(A);
}
static void Bs5652Power(void)
{
int i=0;
dipswitch = 0;
mmc3_reg[0] = 0x00; mmc3_reg[1] = 0x02;
mmc3_reg[2] = 0x04; mmc3_reg[3] = 0x05; mmc3_reg[4] = 0x06; mmc3_reg[5] = 0x07;
mmc3_reg[6] = 0x00; mmc3_reg[7] = 0x01;
for(i=0;i<4;i++)
exRegs[i]=0;
Bs5652AnalyzeReg();
GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, Bs5652WriteLo);
SetWriteHandler(0x8000, 0xFFFF, Bs5652WriteHi);
SetReadHandler(0x8000, 0xFFFF, Bs5652ReadHi);
}
static void Bs5652Reset(void)
{
int i=0;
dipswitch++;
mmc3_reg[0] = 0x00; mmc3_reg[1] = 0x02;
mmc3_reg[2] = 0x04; mmc3_reg[3] = 0x05; mmc3_reg[4] = 0x06; mmc3_reg[5] = 0x07;
mmc3_reg[6] = 0x00; mmc3_reg[7] = 0x01;
for(i=0;i<4;i++)
exRegs[i]=0;
Bs5652AnalyzeReg();
MMC3RegReset();
}
static void Bs5652Close(void)
{
GenMMC3Close();
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;
}
void Bs5652_Init(CartInfo *info)
{
uint32 unif_crc;
GenMMC3_Init(info, 512, 512, 0, 0);
pwrap = Bs5652PW;
cwrap = Bs5652CW;
info->Power = Bs5652Power;
info->Reset = Bs5652Reset;
info->Close = Bs5652Close;
WRAMSIZE = 8192;
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
unif_crc = CalcCRC32(0, PRGptr[0], PRGsize[0]);
if (unif_crc == 0xb97641b5) /* Fix my own error, unif CHR 0 error */
{
if ((CHRsize[0] == 0x2000) && (CHRsize[1] > 0x2000))
{
CHRsize[0] = CHRsize[1];
CHRptr[0] = (uint8*)FCEU_gmalloc(CHRsize[1]);
memcpy(CHRptr[0], CHRptr[1], CHRsize[1]);
SetupCartCHRMapping(0, CHRptr[0], CHRsize[0], 0);
}
}
AddExState(EXPREGS, 3, 0, "EXPR");
AddExState(BS5652_StateRegs, ~0, 0, 0);
}

View File

@ -881,49 +881,6 @@ void Mapper119_Init(CartInfo *info) {
AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR");
}
/* ---------------------------- Mapper 134 ------------------------------ */
/* ---------------------------- UNL-T4A54A ------------------------------ */
/* UNL-T4A54A, functionally the same as mapper 134.
* Writes @ $6801. Menu @ prg $20000, chr $00000 */
static void M134PW(uint32 A, uint8 V) {
uint8 mask = (EXPREGS[0] & 0x04) ? 0x0F : 0x1F;
setprg8(A, (V & mask) | ((EXPREGS[0] & 3) << 4));
}
static void M134CW(uint32 A, uint8 V) {
uint8 mask = (EXPREGS[0] & 0x04) ? 0x7F : 0xFF;
setchr1(A, (V & mask) | ((EXPREGS[0] & 0x30) << 3));
}
static DECLFW(M134Write) {
EXPREGS[0] = V;
FixMMC3CHR(MMC3_cmd);
FixMMC3PRG(MMC3_cmd);
}
static void M134Power(void) {
EXPREGS[0] = 0x01;
GenMMC3Power();
SetWriteHandler(0x6001, 0x6001, M134Write);
SetWriteHandler(0x6801, 0x6801, M134Write);
}
static void M134Reset(void) {
EXPREGS[0] = 0x01;
MMC3RegReset();
}
void Mapper134_Init(CartInfo *info) {
GenMMC3_Init(info, 256, 256, 0, 0);
pwrap = M134PW;
cwrap = M134CW;
info->Power = M134Power;
info->Reset = M134Reset;
AddExState(EXPREGS, 4, 0, "EXPR");
}
/* ---------------------------- Mapper 165 ------------------------------ */
static void M165CW(uint32 A, uint8 V) {

View File

@ -553,7 +553,7 @@ INES_BOARD_BEGIN()
/* INES_BOARD( "", 131, Mapper131_Init ) */
INES_BOARD( "TXC/UNL-22211", 132, Mapper132_Init )
INES_BOARD( "SA72008", 133, SA72008_Init )
INES_BOARD( "MMC3 BMC PIRATE", 134, Bs5652_Init )
INES_BOARD( "MMC3 BMC PIRATE", 134, Mapper134_Init )
/* INES_BOARD( "", 135, Mapper135_Init ) */
INES_BOARD( "Sachen 3011", 136, Mapper136_Init )
INES_BOARD( "S8259D", 137, S8259D_Init )
@ -705,7 +705,7 @@ INES_BOARD_BEGIN()
INES_BOARD( "Kasheng 2-in-1 ", 291, Mapper291_Init )
INES_BOARD( "DRAGONFIGHTER", 292, UNLBMW8544_Init )
INES_BOARD( "NewStar 12-in-1/7-in-1", 293, Mapper293_Init )
INES_BOARD( "MMC3 BMC PIRATE", 294, Bs5652_Init ) /* nesdev redirects this as mapper 134 */
INES_BOARD( "MMC3 BMC PIRATE", 294, Mapper134_Init ) /* nesdev redirects this as mapper 134 */
INES_BOARD( "YY860216C", 295, Mapper295_Init )
INES_BOARD( "TXC 01-22110-000", 297, Mapper297_Init )
INES_BOARD( "TF1201", 298, UNLTF1201_Init )

View File

@ -254,7 +254,6 @@ void Mapper283_Init(CartInfo *);
void Mapper291_Init(CartInfo *);
void Mapper295_Init(CartInfo *);
void Bs5652_Init(CartInfo *);
void J2282_Init(CartInfo *);
void Mapper267_Init(CartInfo *);

View File

@ -1028,7 +1028,6 @@ due to that whole MegaMan 2 Game Genie thing.
void FCEUSND_Reset(void) {
int x;
IRQFrameMode = 0x0;
fhcnt = fhinc;
fcnt = 0;
nreg = 1;
@ -1079,6 +1078,7 @@ void FCEUSND_Power(void) {
for (x = 0; x < 5; x++)
ChannelBC[x] = 0;
soundtsoffs = 0;
IRQFrameMode = 0x0; /* Only initialized by power-on reset, not by soft reset */
LoadDMCPeriod(DMCFormat & 0xF);
}

View File

@ -611,8 +611,8 @@ static BMAPPING bmap[] = {
{ "830134C", 315, BMC830134C_Init, 0 },
{ "GN-26", 344, BMCGN26_Init, 0 },
{ "KG256", NO_INES, KG256_Init, 0 },
{ "T4A54A", 134, Bs5652_Init, 0 },
{ "WX-KB4K", 134, Bs5652_Init, 0 },
{ "T4A54A", 134, Mapper134_Init, 0 },
{ "WX-KB4K", 134, Mapper134_Init, 0 },
{ "SB-5013", 359, Mapper359_Init, 0 },
{ "82112C", 540, Mapper540_Init, 0 },
{ "N49C-300", 369, Mapper369_Init, 0 },