From 305d7a048d614bdfcb0490ffec48528a193325d8 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Thu, 23 Jan 2020 08:27:48 +0800 Subject: [PATCH] Add new mappers Added iNES 1.0/2.0 mappers 134 - replaced Mapper134_init with Bs5652_Init 391 - NC7000M 402 - 831019C J-2282 Added UNIF boards: AB-G1L BS-110 WELL-NO-DG450 KG256 --- src/boards/AbG1l.c | 156 +++++++++++++++++++++++++ src/boards/BS110.c | 210 +++++++++++++++++++++++++++++++++ src/boards/Bs5652.c | 260 +++++++++++++++++++++++++++++++++++++++++ src/boards/KG256.c | 111 ++++++++++++++++++ src/boards/NC7000M.c | 198 +++++++++++++++++++++++++++++++ src/boards/addrlatch.c | 32 +++++ src/ines.c | 5 +- src/ines.h | 4 + src/unif.c | 6 +- src/unif.h | 5 + 10 files changed, 985 insertions(+), 2 deletions(-) create mode 100644 src/boards/AbG1l.c create mode 100644 src/boards/BS110.c create mode 100644 src/boards/Bs5652.c create mode 100644 src/boards/KG256.c create mode 100644 src/boards/NC7000M.c diff --git a/src/boards/AbG1l.c b/src/boards/AbG1l.c new file mode 100644 index 0000000..7305336 --- /dev/null +++ b/src/boards/AbG1l.c @@ -0,0 +1,156 @@ +/* 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" + +static uint8 regs[4]; +static uint8 hrd_flag; +static void(*Sync)(void); + +static SFORMAT StateRegs[] = +{ + { &hrd_flag, 1, "FLAG" }, + { regs, 4, "REGS" }, + { 0 } +}; + +static void SyncAbG1l(void) { + + if (regs[1] & 0x10) + setprg32(0x8000,(regs[1] & 0xC0) >> 6); + else + { + setprg16(0x8000, (regs[1] & 0xE0) >> 5); + setprg16(0xC000, (regs[1] & 0xE0) >> 5); + } + + setchr8(regs[1]); + setmirror((regs[1] & 0x8) ? 0 : 1); + +} + +static DECLFW(AbG1lWriteHi) { + regs[0] = V; + setchr8(((regs[2] & 0xC0) >> 7) << 2 | (regs[0] & 0x03)); + Sync(); +} + +static DECLFW(AbG1lWriteLo) { + regs[A & 0x03] = V; + Sync(); +} + +static DECLFR(AbG1lReadLo) { + return hrd_flag; +} + +static void AbG1lPower(void) { + hrd_flag = 0; + + regs[0] = 0; + regs[1] = 0; + regs[2] = 0; + + Sync(); + SetWriteHandler(0x8000, 0xFFFF, AbG1lWriteHi); + SetWriteHandler(0x6001, 0x6002, AbG1lWriteLo); + SetReadHandler(0x6000, 0x7FFF, AbG1lReadLo); + SetReadHandler(0x8000, 0xFFFF, CartBR); +} + +static void StateRestore(int version) { + Sync(); +} + +static void AbG1lReset(void) { + hrd_flag++; + hrd_flag &= 3; + + regs[0] = 0; + regs[1] = 0; + regs[2] = 0; + + Sync(); +} + +void AbG1l_Init(CartInfo *info) { + + Sync = SyncAbG1l; + + hrd_flag = 0; + + Sync(); + + info->Power = AbG1lPower; + info->Reset = AbG1lReset; + AddExState(&StateRegs, ~0, 0, 0); + GameStateRestore = StateRestore; +} + + +static void SyncWellNoDG450(void) { + + if (regs[1] & 0x10) + setprg32(0x8000, (regs[1]) >> 6); + else + { + setprg16(0x8000, (regs[1]) >> 5); + setprg16(0xC000, (regs[1]) >> 5); + } + + setchr8(regs[1] & 0x0F); + setmirror((regs[1] & 0x8) ? 0 : 1); +} + +static void WellNoDG450Power(void) { + hrd_flag = 0; + + regs[0] = 0; + regs[1] = 0; + regs[2] = 0; + + Sync(); + + SetWriteHandler(0x6001, 0x6002, AbG1lWriteLo); + SetReadHandler(0x6000, 0x7FFF, AbG1lReadLo); + SetReadHandler(0x8000, 0xFFFF, CartBR); +} + +static void WellNoDG450Reset(void) { + hrd_flag++; + hrd_flag &= 3; + + regs[0] = 0; + regs[1] = 0; + regs[2] = 0; + + Sync(); +} + +void WellNoDG450_Init(CartInfo *info) { + Sync = SyncWellNoDG450; + info->Power = WellNoDG450Power; + info->Reset = WellNoDG450Reset; + AddExState(&StateRegs, ~0, 0, 0); + GameStateRestore = StateRestore; +} diff --git a/src/boards/BS110.c b/src/boards/BS110.c new file mode 100644 index 0000000..caf02bf --- /dev/null +++ b/src/boards/BS110.c @@ -0,0 +1,210 @@ +/* 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" + + +extern uint8 *WRAM; +extern uint32 WRAMSIZE; + +//extern uint8 *CHRRAM; +//extern uint32 CHRRAMSIZE; + +uint8 mmc3_reg[8]; +uint8 exRegs[8]; +uint8 pointer; +uint8 locked; +uint8 readDIP; +uint16 prgAND; +uint16 chrAND; +uint16 prgOR; +uint16 chrOR; +uint8 nrom; +uint8 nrom128; +uint8 dipswitch; + + +static SFORMAT BS110_StateRegs[] = +{ + { exRegs, 8, "REGS" }, + { mmc3_reg, 8, "MMC3R" }, + { &pointer, 1, "POINT" }, + { &readDIP, 1, "RDIP" }, + { &prgAND, 1, "PRGAND" }, + { &chrAND, 1, "CHRAND" }, + { &prgOR, 1, "PRGOR" }, + { &chrOR, 1, "CHROR" }, + { &nrom, 1, "NROM" }, + { &nrom128, 1, "N128" }, + { &dipswitch, 1, "DIP" }, + { 0 } +}; + +int BS110GetPRGBank(int bank) +{ + if (~bank & 1 && (pointer & 0x40)) bank ^= 2; + return bank & 2 ? 0xFE | bank & 1 : mmc3_reg[6 | bank & 1]; +} + +void BS110SyncPRG_GNROM(int A14, int AND, int OR) { + setprg8(0x8000, (BS110GetPRGBank(0) &~A14) &AND | OR); + setprg8(0xA000, (BS110GetPRGBank(1) &~A14) &AND | OR); + setprg8(0xC000, (BS110GetPRGBank(0) | A14) &AND | OR); + setprg8(0xE000, (BS110GetPRGBank(1) | A14) &AND | OR); +} + +static void BS110CW(uint32 A, uint8 V) { + + uint8 block = ((exRegs[1]) & 0x03); + uint8 mask = 0x7F; + setchr1(A, (block << 7) | (V & mask)); + +} + +static void BS110PW(uint32 A, uint8 V) { + if ((exRegs[1] >> 2) & 0x01) + { + uint8 mask = 0x0F; + uint8 block = (exRegs[1] & 3) << 4; + if ((exRegs[1] >> 3) & 0x01) + { + setprg8(0x8000, (BS110GetPRGBank(0)) & mask | block); + setprg8(0xA000, (BS110GetPRGBank(1)) & mask | block); + setprg8(0xC000, (BS110GetPRGBank(0)) & mask | block); + setprg8(0xE000, (BS110GetPRGBank(1)) & mask | block); + } + else + { + + setprg8(0x8000, (BS110GetPRGBank(0)) & mask | block); + setprg8(0xA000, (BS110GetPRGBank(1)) & mask | block); + setprg8(0xC000, (BS110GetPRGBank(0) | 2) & mask | block); + setprg8(0xE000, (BS110GetPRGBank(1) | 2) & mask | block); + } + } + else + { + uint8 mask = 0x0F; + uint8 block = (exRegs[1] & 3) << 4; + setprg8(A, block | (V & mask)); + } +} + + +static DECLFW(BS110WriteHi) { + + 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(BS110WriteLo) { + + exRegs[1] = A; + exRegs[0] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + +} +static DECLFR(BS110ReadHi) +{ + if ((A == 0xCB00) && ((exRegs[1] & 0x0F) == 0x08)) + return dipswitch; + else + return CartBR(A); + +} + +static void BS110Power(void) { + 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; + int i = 0; + + for (i = 0;i<4;i++) + { + exRegs[i] = 0; + } + + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, BS110WriteLo); + SetWriteHandler(0x8000, 0xFFFF, BS110WriteHi); + SetReadHandler(0x8000, 0xFFFF, BS110ReadHi); +} + +static void BS110Reset(void) { + + 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; + int i = 0; + + for (i = 0;i<4;i++) + { + exRegs[i] = 0; + } + + MMC3RegReset(); +} +static void BS110Close(void) { + if (WRAM) + FCEU_gfree(WRAM); + WRAM = NULL; +} + +void BS110_Init(CartInfo *info) { + GenMMC3_Init(info, 512, 512, 0, 0); + pwrap = BS110PW; + cwrap = BS110CW; + info->Power = BS110Power; + info->Reset = BS110Reset; + info->Close = BS110Close; + + WRAMSIZE = 8192; + WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + AddExState(WRAM, WRAMSIZE, 0, "WRAM"); + + //CHRRAMSIZE = 8192; + //CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE); + //SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1); + //AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR"); + + AddExState(EXPREGS, 3, 0, "EXPR"); + AddExState(BS110_StateRegs, ~0, 0, 0); +} diff --git a/src/boards/Bs5652.c b/src/boards/Bs5652.c new file mode 100644 index 0000000..4f86c83 --- /dev/null +++ b/src/boards/Bs5652.c @@ -0,0 +1,260 @@ +/* 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" + +extern uint8 *WRAM; +extern uint32 WRAMSIZE; + +//extern uint8 *CHRRAM; +//extern uint32 CHRRAMSIZE; + +uint8 mmc3_reg[8]; +uint8 exRegs[8]; +uint8 pointer; +uint8 locked; +uint8 readDIP; +uint16 prgAND; +uint16 chrAND; +uint16 prgOR; +uint16 chrOR; +uint8 nrom; +uint8 nrom128; +uint8 dipswitch; + + +static SFORMAT BS5652_StateRegs[] = +{ + { exRegs, 8, "REGS" }, + { mmc3_reg, 8, "MMC3R" }, + { &pointer, 1, "POINT" }, + { &readDIP, 1, "RDIP" }, + { &prgAND, 1, "PRGAND" }, + { &chrAND, 1, "CHRAND" }, + { &prgOR, 1, "PRGOR" }, + { &chrOR, 1, "CHROR" }, + { &nrom, 1, "NROM" }, + { &nrom128, 1, "N128" }, + { &dipswitch, 1, "DIP" }, + { 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; + chrOR = (exRegs[1] & 0x30) << 3 ; + 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; + } + else + return CartBR(A); +} + +static void Bs5652Power(void) { + 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; + int i=0; + + 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) { + + 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; + int i=0; + + for(i=0;i<4;i++) + { + exRegs[i]=0; + } + + Bs5652AnalyzeReg(); + + MMC3RegReset(); +} +static void Bs5652Close(void) { + if (WRAM) + FCEU_gfree(WRAM); + WRAM = NULL; +} + +void Bs5652_Init(CartInfo *info) { + 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"); + + //CHRRAMSIZE = 8192; + //CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE); + //SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1); + //AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR"); + + uint32 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); +} diff --git a/src/boards/KG256.c b/src/boards/KG256.c new file mode 100644 index 0000000..6d27740 --- /dev/null +++ b/src/boards/KG256.c @@ -0,0 +1,111 @@ +/* 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" + +static uint8 regs[4]; + +static SFORMAT StateRegs[] = +{ + { regs, 4, "REGS" }, + { 0 } +}; + +static void Sync(void) { + + int r = 0; + if ((regs[1]) & 0x20) + { + r = 1; + } + if ((regs[1] >> 4) & 0x01) + { + setprg16(0x8000, regs[1] & 0x07 | (r) << 3); + setprg16(0xC000, regs[1] & 0x07 | (r) << 3); + setchr8(regs[0] & 0x07 | (r) << 3); + } + else + { + setprg32(0x8000, (regs[1] >> 1) & 0x03 | (r) << 2); + setchr8(regs[2] & 0x01 | (r) << 3); + } + + uint8 mirr = (((regs[0] >> 4 & 0x1))); + + if (mirr) + setmirror(0); + else + setmirror(1); + +} + +static DECLFW(KG256WriteHi) { + regs[2] = V; + Sync(); +} + +static DECLFW(KG256WriteLo) { + regs[A & 0x03] = V; + Sync(); +} + +static void KG256Power(void) { + + regs[0] = 0; + regs[1] = 0; + regs[2] = 0; + regs[3] = 0; + + SetWriteHandler(0x8000, 0xFFFF, KG256WriteHi); + SetWriteHandler(0x6000, 0x7FFF, KG256WriteLo); + SetReadHandler(0x8000, 0xFFFF, CartBR); + + Sync(); + +} + +static void StateRestore(int version) { + Sync(); +} + +static void KG256Reset(void) { + + regs[0] = 0; + regs[1] = 0; + regs[2] = 0; + + Sync(); +} + +void KG256_Init(CartInfo *info) { + + Sync(); + + info->Power = KG256Power; + info->Reset = KG256Reset; + AddExState(&StateRegs, ~0, 0, 0); + GameStateRestore = StateRestore; +} + + + diff --git a/src/boards/NC7000M.c b/src/boards/NC7000M.c new file mode 100644 index 0000000..736b5a1 --- /dev/null +++ b/src/boards/NC7000M.c @@ -0,0 +1,198 @@ +/* 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" + + +extern uint8 *WRAM; +extern uint32 WRAMSIZE; + +//extern uint8 *CHRRAM; +//extern uint32 CHRRAMSIZE; + + +uint8 mmc3_reg[8]; +uint8 exRegs[8]; +uint8 pointer; +uint8 locked; +uint8 readDIP; +uint16 prgAND; +uint16 chrAND; +uint16 prgOR; +uint16 chrOR; +uint8 nrom; +uint8 nrom256; +uint16 reg; + + +static SFORMAT NC7000M_StateRegs[] = +{ + { exRegs, 8, "REGS" }, + { mmc3_reg, 8, "MMC3R" }, + { &pointer, 1, "POINT" }, + { &readDIP, 1, "RDIP" }, + { &prgAND, 1, "PRGAND" }, + { &chrAND, 1, "CHRAND" }, + { &prgOR, 1, "PRGOR" }, + { &chrOR, 1, "CHROR" }, + { &nrom, 1, "NROM" }, + { &nrom256, 1, "N256" }, + { ®, 1, "REG" }, + { 0 } +}; + +void NC7000MAnalyzeReg() +{ + locked = (reg & 0x80); + prgAND = (reg & 0x08 ? 0x0F : 0x1F); + chrAND = (reg & 0x40 ? 0x7F : 0xFF); + prgOR = (reg << 4 & 0x30); + chrOR = (reg << 3 & 0x080 | reg & 0x100); + nrom = (reg & 0x20); + nrom256 = (reg & 0x04); +} + +int NC7000MGetPRGBank(int bank) +{ + if (~bank & 1 && (pointer & 0x40)) bank ^= 2; + return bank & 2 ? 0xFE | bank & 1 : mmc3_reg[6 | bank & 1]; +} + +void NC7000MSyncPRG_GNROM(int A14, int AND, int OR) { + setprg8(0x8000, (NC7000MGetPRGBank(0) &~A14) &AND | OR); + setprg8(0xA000, (NC7000MGetPRGBank(1) &~A14) &AND | OR); + setprg8(0xC000, (NC7000MGetPRGBank(0) | A14) &AND | OR); + setprg8(0xE000, (NC7000MGetPRGBank(1) | A14) &AND | OR); +} + +static void NC7000MCW(uint32 A, uint8 V) { + + setchr1(A, (V & chrAND) | (chrOR &~chrAND)); +} + +static void NC7000MPW(uint32 A, uint8 V) { + + if (nrom) + { + NC7000MSyncPRG_GNROM(nrom256 ? 2 : 0, prgAND, prgOR &~prgAND); + } + else + { + setprg8(A, (prgOR &~prgAND) | (V & prgAND)); + } +} + + +static DECLFW(NC7000MWriteHi) { + + 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(NC7000MWriteLo) { + + if (!(reg & 0x80)) { + reg = V | A & 0x100; + NC7000MAnalyzeReg(); + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } + else + { + WRAM[A - 0x6000] = V; + } +} +static DECLFR(NC7000MReadHi) +{ + return CartBR(A); +} + +static void NC7000MPower(void) { + 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; + + reg = 0x0000; + + NC7000MAnalyzeReg(); + + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, NC7000MWriteLo); + SetWriteHandler(0x8000, 0xFFFF, NC7000MWriteHi); +} + +static void NC7000MReset(void) { + + 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; + + reg = 0x0000; + + NC7000MAnalyzeReg(); + + MMC3RegReset(); +} +static void NC7000MClose(void) { + if (WRAM) + FCEU_gfree(WRAM); + WRAM = NULL; +} + +void NC7000M_Init(CartInfo *info) { + GenMMC3_Init(info, 512, 512, 0, 0); + pwrap = NC7000MPW; + cwrap = NC7000MCW; + info->Power = NC7000MPower; + info->Reset = NC7000MReset; + info->Close = NC7000MClose; + + WRAMSIZE = 8192; + WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + AddExState(WRAM, WRAMSIZE, 0, "WRAM"); + + //CHRRAMSIZE = 8192; + //CHRRAM = (uint8*)FCEU_gmalloc(CHRRAMSIZE); + //SetupCartCHRMapping(0x10, CHRRAM, CHRRAMSIZE, 1); + //AddExState(CHRRAM, CHRRAMSIZE, 0, "CHRR"); + + AddExState(EXPREGS, 3, 0, "EXPR"); + AddExState(NC7000M_StateRegs, ~0, 0, 0); +} diff --git a/src/boards/addrlatch.c b/src/boards/addrlatch.c index 878e7a3..8e02d7a 100644 --- a/src/boards/addrlatch.c +++ b/src/boards/addrlatch.c @@ -580,3 +580,35 @@ static void BMCSA005ASync(void) { void BMCSA005A_Init(CartInfo *info) { Latch_Init(info, BMCSA005ASync, NULL, 0x0000, 0x8000, 0xFFFF, 0); } + + +//-------------- 831019C J-2282 ------------------------ + +static void J2282Sync(void) { + setchr8(0); + + if ((latche & 0x40)) + { + uint8 bank = (latche >> 0) & 0x1F; + setprg16(0x8000, bank); + setprg16(0xC000, bank); + } + else + { + if (latche & 0x800) + { + setprg8(0x6000, ((latche << 1) & 0x3F) | 3); + } + uint8 bank = (latche >> 1) & 0x1F; + setprg32(0x8000, bank); + } + + if (latche & 0x80) + setmirror(0); + else + setmirror(1); +} + +void J2282_Init(CartInfo *info) { + Latch_Init(info, J2282Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0); +} diff --git a/src/ines.c b/src/ines.c index 781f4d3..d505a74 100644 --- a/src/ines.c +++ b/src/ines.c @@ -528,7 +528,8 @@ static BMAPPINGLocal bmap[] = { /* {(uint8_t*)"", 131, Mapper131_Init}, */ {(uint8_t*)"TXC/MGENIUS 22111", 132, UNL22211_Init}, {(uint8_t*)"SA72008", 133, SA72008_Init}, - {(uint8_t*)"MMC3 BMC PIRATE", 134, Mapper134_Init}, + //{(uint8_t*)"MMC3 BMC PIRATE", 134, Mapper134_Init}, + {(uint8_t*)"MMC3 BMC PIRATE", 134, Bs5652_Init}, /* {(uint8_t*)"", 135, Mapper135_Init}, */ {(uint8_t*)"TCU02", 136, TCU02_Init}, {(uint8_t*)"S8259D", 137, S8259D_Init}, @@ -727,6 +728,8 @@ static BMAPPINGLocal bmap[] = { {(uint8_t*)"G-146", 349, BMCG146_Init }, {(uint8_t*)"891227", 350, BMC891227_Init }, {(uint8_t*)"3D-BLOCK", 355, UNL3DBlock_Init }, + {(uint8_t*)"NC7000M", 391, NC7000M_Init }, + {(uint8_t*)"831019C J-2282", 402, J2282_Init }, {(uint8_t*)"SA-9602B", 513, SA9602B_Init }, {(uint8_t*)"DANCE2000", 518, UNLD2000_Init }, {(uint8_t*)"EH8813A", 519, UNLEH8813A_Init }, diff --git a/src/ines.h b/src/ines.h index 2b29b29..0121528 100644 --- a/src/ines.h +++ b/src/ines.h @@ -239,4 +239,8 @@ void Mapper255_Init(CartInfo *); void GN45_Init(CartInfo *info); /* m361, m366 */ void Mapper281_Init(CartInfo *); +void Bs5652_Init(CartInfo *); +void NC7000M_Init(CartInfo *); +void J2282_Init(CartInfo *); + #endif diff --git a/src/unif.c b/src/unif.c index b7f62a7..61dcea1 100644 --- a/src/unif.c +++ b/src/unif.c @@ -426,10 +426,12 @@ static BMAPPING bmap[] = { { "8237A", 215, UNL8237A_Init, 0 }, { "830118C", 348, BMC830118C_Init, 0 }, { "A65AS", 285, BMCA65AS_Init, 0 }, + { "AB-G1L", NO_INES, AbG1l_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-110",NO_INES, BS110_Init, 0 }, { "BS-5", 286, BMCBS5_Init, 0 }, { "CC-21", 27, UNLCC21_Init, 0 }, { "CITYFIGHT", 266, UNLCITYFIGHT_Init, 0 }, @@ -545,6 +547,7 @@ static BMAPPING bmap[] = { { "UNROM-512-32", 30, UNROM512_Init, BMCFLAG_32KCHRR }, { "UOROM", 2, UNROM_Init, 0 }, { "VRC7", 85, UNLVRC7_Init, 0 }, + { "WELL-NO-DG450",NO_INES, WellNoDG450_Init, 0 }, { "YOKO", 264, UNLYOKO_Init, 0 }, { "COOLBOY", 268, COOLBOY_Init, BMCFLAG_256KCHRR }, { "158B", 258, UNL158B_Init, 0 }, @@ -595,7 +598,8 @@ static BMAPPING bmap[] = { { "K-3033", 322, BMCK3033_Init, 0 }, { "830134C", 315, BMC830134C_Init, 0 }, { "GN-26", 344, BMCGN26_Init, 0 }, - { "T4A54A", 134, Mapper134_Init, 0 }, + { "KG256", NO_INES,KG256_Init, 0 }, + { "T4A54A", 134, Mapper134_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", NO_INES, MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 661fff3..b7dce10 100644 --- a/src/unif.h +++ b/src/unif.h @@ -192,6 +192,11 @@ void BMCK3033_Init(CartInfo *info); /* mm22 */ void BMC830134C_Init(CartInfo *info); /* m315 */ void BMCGN26_Init(CartInfo *info); /* m344 */ +void BS110_Init(CartInfo *info); +void WellNoDG450_Init(CartInfo *info); +void AbG1l_Init(CartInfo *info); +void KG256_Init(CartInfo *info); + #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); void MapperCopyFami_Init(CartInfo *info);