Merge pull request #2 from libretro/master

Classicmods rebase
This commit is contained in:
Wes Smith
2019-09-03 16:53:58 -04:00
committed by GitHub
81 changed files with 6363 additions and 826 deletions

View File

@@ -17,7 +17,7 @@ env:
- PLATFORM=linux_x64 - PLATFORM=linux_x64
- PLATFORM=ngc - PLATFORM=ngc
- PLATFORM=wii - PLATFORM=wii
- PLATFORM=wiiu # - PLATFORM=wiiu
before_script: before_script:
- pwd - pwd
- mkdir -p ~/bin - mkdir -p ~/bin

View File

@@ -1,19 +1,8 @@
ifeq ($(LIBRETRO_COMM_DIR),)
LIBRETRO_COMM_DIR := $(CORE_DIR)/drivers/libretro/libretro-common LIBRETRO_COMM_DIR := $(CORE_DIR)/drivers/libretro/libretro-common
INCFLAGS := -I$(CORE_DIR)/drivers/libretro -I$(LIBRETRO_COMM_DIR)/include -I$(CORE_DIR) -I$(CORE_DIR)/input -I$(CORE_DIR)/boards -I$(CORE_DIR)/mappers
COREDEFINES = -D__LIBRETRO__ -DSOUND_QUALITY=0 -DPATH_MAX=1024 -DFCEU_VERSION_NUMERIC=9813 -DFRONTEND_SUPPORTS_RGB565
INCLUDE_STDINT = 0
ifneq (,$(findstring msvc200,$(platform)))
INCLUDE_STDINT = 1
endif
ifeq ($(INCLUDE_STDINT), 1)
INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc
endif
ifneq (,$(findstring msvc,$(platform)))
COREDEFINES += -DINLINE=_inline
endif endif
INCFLAGS := -I$(CORE_DIR)/drivers/libretro -I$(LIBRETRO_COMM_DIR)/include -I$(CORE_DIR) -I$(CORE_DIR)/input -I$(CORE_DIR)/boards
COREDEFINES = -D__LIBRETRO__ -DSOUND_QUALITY=0 -DPATH_MAX=1024 -DFCEU_VERSION_NUMERIC=9813 -DFRONTEND_SUPPORTS_RGB565
ifeq ($(PSS_STYLE),2) ifeq ($(PSS_STYLE),2)
COREDEFINES += -DPSS_STYLE=2 COREDEFINES += -DPSS_STYLE=2
@@ -21,8 +10,12 @@ else
COREDEFINES += -DPSS_STYLE=1 COREDEFINES += -DPSS_STYLE=1
endif endif
ifeq ($(TUP_CWD),)
FCEU_SRC_DIRS := $(CORE_DIR)/boards $(CORE_DIR)/input $(CORE_DIR)/mappers FCEU_SRC_DIRS := $(CORE_DIR)/boards $(CORE_DIR)/input $(CORE_DIR)/mappers
SOURCES_C := $(foreach dir,$(FCEU_SRC_DIRS),$(wildcard $(dir)/*.c)) SOURCES_C := $(foreach dir,$(FCEU_SRC_DIRS),$(wildcard $(dir)/*.c))
else
SOURCES_C = $(CORE_DIR)/boards/*.c $(CORE_DIR)/input/*.c
endif
ifeq ($(HAVE_GRIFFIN),1) ifeq ($(HAVE_GRIFFIN),1)
SOURCES_C += $(CORE_DIR)/drivers/libretro/griffin.c SOURCES_C += $(CORE_DIR)/drivers/libretro/griffin.c
@@ -63,4 +56,5 @@ endif
SOURCES_C += \ SOURCES_C += \
$(CORE_DIR)/ines.c \ $(CORE_DIR)/ines.c \
$(CORE_DIR)/unif.c $(CORE_DIR)/x6502.c $(CORE_DIR)/unif.c $(CORE_DIR)/x6502.c \
$(CORE_DIR)/drivers/libretro/libretro_dipswitch.c

View File

@@ -279,7 +279,7 @@ else ifeq ($(platform), wiiu)
TARGET := $(TARGET_NAME)_libretro_$(platform).a TARGET := $(TARGET_NAME)_libretro_$(platform).a
CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT) CC = $(DEVKITPPC)/bin/powerpc-eabi-gcc$(EXE_EXT)
AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT)
PLATFORM_DEFINES := -DGEKKO -DHW_RVL -mwup -mcpu=750 -meabi -mhard-float PLATFORM_DEFINES := -DGEKKO -DHW_RVL -mcpu=750 -meabi -mhard-float
PLATFORM_DEFINES += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int PLATFORM_DEFINES += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int
ENDIANNESS_DEFINES += -DMSB_FIRST ENDIANNESS_DEFINES += -DMSB_FIRST
STATIC_LINKING=1 STATIC_LINKING=1
@@ -417,16 +417,6 @@ else ifeq ($(platform), gcw0)
PLATFORM_DEFINES += -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float PLATFORM_DEFINES += -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float
EXTERNAL_ZLIB = 1 EXTERNAL_ZLIB = 1
# Genode
else ifeq ($(platform), genode)
TARGET := $(TARGET_NAME)_libretro.lib.so
CC := $(shell pkg-config genode-base --variable=cc)
LD := $(shell pkg-config genode-base --variable=ld)
CFLAGS += $(shell pkg-config --cflags genode-libc)
LDFLAGS += -shared --version-script=src/drivers/libretro/link.T
LDFLAGS += $(shell pkg-config --libs genode-lib genode-libc)
LIBM =
# Windows MSVC 2017 all architectures # Windows MSVC 2017 all architectures
else ifneq (,$(findstring windows_msvc2017,$(platform))) else ifneq (,$(findstring windows_msvc2017,$(platform)))
CC = cl.exe CC = cl.exe
@@ -653,7 +643,7 @@ CFLAGS += -D_CRT_SECURE_NO_DEPRECATE
# Windows # Windows
else else
TARGET := $(TARGET_NAME)_libretro.dll TARGET := $(TARGET_NAME)_libretro.dll
CC = gcc CC ?= gcc
SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=src/drivers/libretro/link.T SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=src/drivers/libretro/link.T
PSS_STYLE :=2 PSS_STYLE :=2
endif endif
@@ -692,6 +682,12 @@ else
endif endif
endif endif
ifneq ($(SANITIZER),)
CFLAGS += -fsanitize=$(SANITIZER)
CXXFLAGS += -fsanitize=$(SANITIZER)
LDFLAGS += -fsanitize=$(SANITIZER)
endif
ifeq ($(EXTERNAL_ZLIB), 1) ifeq ($(EXTERNAL_ZLIB), 1)
CFLAGS += -DHAVE_EXTERNAL_ZLIB CFLAGS += -DHAVE_EXTERNAL_ZLIB
endif endif
@@ -704,6 +700,19 @@ CORE_DIR := src
include Makefile.common include Makefile.common
INCLUDE_STDINT = 0
ifneq (,$(findstring msvc200,$(platform)))
INCLUDE_STDINT = 1
endif
ifeq ($(INCLUDE_STDINT), 1)
INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc
endif
ifneq (,$(findstring msvc,$(platform)))
COREDEFINES += -DINLINE=_inline
endif
CFLAGS += -DWANT_GRIFFIN CFLAGS += -DWANT_GRIFFIN
OBJECTS := $(SOURCES_C:.c=.o) OBJECTS := $(SOURCES_C:.c=.o)
@@ -724,7 +733,7 @@ else
WARNING_DEFINES = -Wno-write-strings WARNING_DEFINES = -Wno-write-strings
endif endif
CFLAGS += $(COREDEFINES) $(fpic) $(WARNING_DEFINES) $(DEFINES) $(ENDIANNESS_DEFINES) CFLAGS += $(fpic) $(WARNING_DEFINES) $(DEFINES) $(ENDIANNESS_DEFINES)
LDFLAGS += $(LIBM) LDFLAGS += $(LIBM)
ifeq ($(platform), psp1) ifeq ($(platform), psp1)
@@ -745,9 +754,6 @@ else ifeq ($(platform), switch)
OBJOUT = -o OBJOUT = -o
LINKOUT = -o LINKOUT = -o
# libtransistor.mk sets LD for us # libtransistor.mk sets LD for us
else ifeq ($(platform), genode)
OBJOUT = -o
LINKOUT = -o
else else
OBJOUT = -o OBJOUT = -o
LINKOUT = -o LINKOUT = -o

3
Tupfile Normal file
View File

@@ -0,0 +1,3 @@
TARGET_NAME=fceumm
CORE_DIR=$(TUP_CWD)/src
include_rules

View File

@@ -44,7 +44,7 @@ static SFORMAT StateRegs[] =
}; };
static void Sync(void) { static void Sync(void) {
setprg8r(1, 0x6000, prg); setprg8(0x6000, 4 | prg);
setprg32(0x8000, 0); setprg32(0x8000, 0);
setchr8(0); setchr8(0);
} }

105
src/boards/126.c Normal file
View File

@@ -0,0 +1,105 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* Mapper 126, PowerJoy 84-in-1 Multicart (PJ-008*/
/* reference from nestopia since not available in nesdev */
#include "mapinc.h"
#include "mmc3.h"
static uint16 GetExChrExBank() {
uint16 bank = (uint16)EXPREGS[0];
return ((~bank << 0 & 0x080 & ((uint16)EXPREGS[2])) | (bank << 4 & 0x080 & bank) |
(bank << 3 & 0x100) | (bank << 5 & 0x200));
}
static void UpdateChrBank(void) {
uint16 bank = (uint16)EXPREGS[2] & 0x0F;
bank |= GetExChrExBank() >> 3;
setchr8(bank);
}
static void M126CW(uint32 A, uint8 V) {
if (!(EXPREGS[3] & 0x10)) {
uint16 bank = (uint16)V & (((uint16)EXPREGS[0] & 0x80) - 1);
bank |= GetExChrExBank();
setchr1(A, bank);
}
}
static void M126PW(uint32 A, uint8 V) {
uint16 bank = (uint16)V;
uint16 preg = (uint16)EXPREGS[0];
bank &= ((~preg >> 2) & 0x10) | 0x0F;
bank |= ((preg & (0x06 | (preg & 0x40) >> 6)) << 4) | ((preg & 0x10) << 3);
if (!(EXPREGS[3] & 0x03))
setprg8(A, bank);
else if ((A - 0x8000) == ((MMC3_cmd << 8) & 0x4000)) { /* TODO: Clean this */
if ((EXPREGS[3] & 0x3) == 0x3)
setprg32(0x8000, (bank >> 2));
else {
setprg16(0x8000, (bank >> 1));
setprg16(0xc000, (bank >> 1));
}
}
}
static DECLFW(M126Write) {
A &= 0x03;
if(A == 0x01 || A == 0x02 || ((A == 0x00 || A == 0x03) && !(EXPREGS[3] & 0x80))) {
if (EXPREGS[A] != V) {
EXPREGS[A] = V;
if (EXPREGS[3] & 0x10)
UpdateChrBank();
else
FixMMC3CHR(MMC3_cmd);
FixMMC3PRG(MMC3_cmd);
}
}
}
void M126StateRestore(int v) {
FixMMC3CHR(MMC3_cmd);
FixMMC3PRG(MMC3_cmd);
if (EXPREGS[3] & 0x10)
UpdateChrBank();
}
static void M126Reset(void) {
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
MMC3RegReset();
}
static void M126Power(void) {
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, M126Write);
}
void Mapper126_Init(CartInfo *info) {
GenMMC3_Init(info, 2048, 1023, 0, 0);
cwrap = M126CW;
pwrap = M126PW;
info->Power = M126Power;
info->Reset = M126Reset;
GameStateRestore = M126StateRestore;
AddExState(EXPREGS, 4, 0, "EXPR");
}

View File

@@ -59,6 +59,11 @@ static void M177Close(void) {
WRAM = NULL; WRAM = NULL;
} }
static void M177Reset(void) {
reg = 0;
Sync();
}
static void StateRestore(int version) { static void StateRestore(int version) {
Sync(); Sync();
} }
@@ -66,6 +71,7 @@ static void StateRestore(int version) {
void Mapper177_Init(CartInfo *info) { void Mapper177_Init(CartInfo *info) {
info->Power = M177Power; info->Power = M177Power;
info->Close = M177Close; info->Close = M177Close;
info->Reset = M177Reset;
GameStateRestore = StateRestore; GameStateRestore = StateRestore;
WRAMSIZE = 8192; WRAMSIZE = 8192;

50
src/boards/224.c Normal file
View File

@@ -0,0 +1,50 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* 2019-05-29 - Mapper 224, KT-008
* iNES Mapper 224 is used for the 晶科泰 (Jncota) KT-008 PCB.
* It's an MMC3 clone that supports 1024 KiB of PRG-ROM through an additional
* outer bank register at $5000.
* http://wiki.nesdev.com/w/index.php/INES_Mapper_224 */
#include "mapinc.h"
#include "mmc3.h"
static void M224PW(uint32 A, uint8 V) {
setprg8(A, (V & 0x3f) | ((EXPREGS[0] << 4) & 0x40));
}
static DECLFW(Mapper224Write) {
EXPREGS[0] = V;
FixMMC3PRG(MMC3_cmd);
}
static void M224Power(void) {
EXPREGS[0] = 0;
GenMMC3Power();
SetWriteHandler(0x5000, 0x5000, Mapper224Write);
}
void Mapper224_Init(CartInfo *info) {
GenMMC3_Init(info, 1024, 0, 8, 0);
pwrap = M224PW;
info->Power = M224Power;
AddExState(EXPREGS, 1, 0, "EXPR");
}

91
src/boards/237.c Normal file
View File

@@ -0,0 +1,91 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* Mapper 237 - "Teletubbies / Y2K" 420-in-1 pirate multicart.
* Dipswitch settings:
* 0: 42-in-1
* 1: 5,000-in-1
* 2: 420-in-1
* 3: 10,000,000-in-1 (lol)
*/
#include "mapinc.h"
static uint8 reg[2];
static uint8 dipswitch;
static SFORMAT StateRegs[] =
{
{ &reg[0], 1, "REG0" },
{ &reg[1], 1, "REG1" },
{ &dipswitch, 1, "DPSW" },
{ 0 }
};
static void Sync(void) {
uint8 bank = (reg[1] & 0x07);
uint8 base = (reg[1] & 0x18) | ((reg[0] & 0x04) << 3);
uint8 mode = (reg[1] & 0xC0) >> 6;
setchr8(0);
setprg16(0x8000, base | (bank & ~(mode & 1)));
setprg16(0xC000, base | ((mode & 0x02) ? (bank | (mode & 0x01)) : 0x07));
setmirror(((reg[1] & 0x20) >> 5) ^ 1);
}
static DECLFW(M237Write) {
if (!(reg[0] & 0x02)) {
reg[0] = A & 0x0F;
reg[1] = (reg[1] & 0x07) | (V & 0xF8);
}
reg[1] = (reg[1] & 0xF8) | (V & 0x07);
Sync();
}
static DECLFR(M237Read) {
if (!(reg[0] & 0x02) && (reg[0] & 0x01))
return dipswitch;
return CartBR(A);
}
static void M237Power(void) {
Sync();
SetReadHandler (0x8000, 0xFFFF, M237Read);
SetWriteHandler(0x8000, 0xFFFF, M237Write);
}
static void M237Reset(void) {
reg[0] = reg[1] = 0;
Sync();
}
static void StateRestore(int version) {
Sync();
}
void Mapper237_Init(CartInfo *info) {
dipswitch = 0;
if ((info->CRC32) == 0x272709b9) /* Teletubbies Y2K (420-in-1) */
dipswitch = 2;
info->Power = M237Power;
info->Reset = M237Reset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

79
src/boards/255.c Normal file
View File

@@ -0,0 +1,79 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*/
/* added 2019-5-23
* Mapper 255
* https://wiki.nesdev.com/w/index.php/INES_Mapper_225
* 115-in-1 [p1][!] CRC32 0xb39d30b4
* Seems to handle up to last game in the multicarts than m225 but causes
* graphics garbage past it, else games works fine */
#include "mapinc.h"
static uint8 preg, creg, mode, mirr;
static SFORMAT StateRegs[] =
{
{ &preg, 1, "PRG0" },
{ &creg, 1, "CHR0" },
{ &mode, 1, "MODE" },
{ &mirr, 1, "MIRR" },
{ 0 }
};
static void Sync(void) {
setprg16(0x8000, preg & ~mode);
setprg16(0xC000, preg | mode);
setchr8(creg);
setmirror(mirr ^ 1);
}
static DECLFW(M255Write) {
uint32 bank = (A >> 8 & 0x40);
preg = bank | ((A >> 6) & 0x3F);
creg = bank | (A & 0x3F);
mirr = (A >> 13) & 1;
mode = ((~A) >> 12 & 1);
Sync();
}
static void M255Power(void) {
preg = 0;
mode = 1;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M255Write);
}
static void M255Reset(void) {
preg = 0;
mode = 1;
Sync();
}
static void StateRestore(int version) {
Sync();
}
void Mapper255_Init(CartInfo *info) {
info->Reset = M255Reset;
info->Power = M255Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

187
src/boards/28.c Normal file
View File

@@ -0,0 +1,187 @@
/*
* Copyright (C) 2012-2017 FCEUX 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
* 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.
*
*/
/* added 2019-5-23
* Mapper 28 - Action 53
* http://wiki.nesdev.com/w/index.php/INES_Mapper_028 */
#include "mapinc.h"
static uint8 prg_mask_16k;
static uint8 reg, chr, prg, mode, outer;
static SFORMAT StateRegs[] = {
{&reg, 1, "REG"},
{&chr, 1, "CHR"},
{&prg, 1, "PRG"},
{&mode, 1, "MODE"},
{&outer, 1, "OUTR"},
{0}
};
void SyncMirror() {
switch (mode & 3) {
case 0: setmirror(MI_0); break;
case 1: setmirror(MI_1); break;
case 2: setmirror(MI_V); break;
case 3: setmirror(MI_H); break;
}
}
void Mirror(uint8 value)
{
if ((mode & 2) == 0) {
mode &= 0xfe;
mode |= value >> 4 & 1;
}
SyncMirror();
}
static void Sync() {
uint8 prglo;
uint8 prghi;
uint8 outb = outer << 1;
/* this can probably be rolled up, but i have no motivation to do so
* until it's been tested */
switch (mode & 0x3c) {
/* 32K modes */
case 0x00:
case 0x04:
prglo = outb;
prghi = outb | 1;
break;
case 0x10:
case 0x14:
prglo = (outb & ~2) | (prg << 1 & 2);
prghi = (outb & ~2) | (prg << 1 & 2) | 1;
break;
case 0x20:
case 0x24:
prglo = (outb & ~6) | (prg << 1 & 6);
prghi = (outb & ~6) | (prg << 1 & 6) | 1;
break;
case 0x30:
case 0x34:
prglo = (outb & ~14) | (prg << 1 & 14);
prghi = (outb & ~14) | (prg << 1 & 14) | 1;
break;
/* bottom fixed modes */
case 0x08:
prglo = outb;
prghi = outb | (prg & 1);
break;
case 0x18:
prglo = outb;
prghi = (outb & ~2) | (prg & 3);
break;
case 0x28:
prglo = outb;
prghi = (outb & ~6) | (prg & 7);
break;
case 0x38:
prglo = outb;
prghi = (outb & ~14) | (prg & 15);
break;
/* top fixed modes */
case 0x0c:
prglo = outb | (prg & 1);
prghi = outb | 1;
break;
case 0x1c:
prglo = (outb & ~2) | (prg & 3);
prghi = outb | 1;
break;
case 0x2c:
prglo = (outb & ~6) | (prg & 7);
prghi = outb | 1;
break;
case 0x3c:
prglo = (outb & ~14) | (prg & 15);
prghi = outb | 1;
break;
}
prglo &= prg_mask_16k;
prghi &= prg_mask_16k;
setprg16(0x8000, prglo);
setprg16(0xC000, prghi);
setchr8(chr);
}
static DECLFW(WriteEXP) {
reg = V & 0x81;
}
static DECLFW(WritePRG) {
switch (reg) {
case 0x00:
chr = V & 3;
Mirror(V);
Sync();
break;
case 0x01:
prg = V & 15;
Mirror(V);
Sync();
break;
case 0x80:
mode = V & 63;
SyncMirror();
Sync();
break;
case 0x81:
outer = V & 63;
Sync();
break;
}
}
static void M28Power(void) {
outer = 63;
prg = 15;
Sync();
prg_mask_16k = PRGsize[0] - 1;
SetWriteHandler(0x5000,0x5FFF,WriteEXP);
SetWriteHandler(0x8000,0xFFFF,WritePRG);
SetReadHandler(0x8000,0xFFFF,CartBR);
SetReadHandler(0x6000,0x7FFF,CartBR);
SetWriteHandler(0x6000,0x7FFF,CartBW);
}
static void M28Reset(void) {
outer = 63;
prg = 15;
Sync();
}
static void StateRestore(int version) {
Sync();
}
void Mapper28_Init(CartInfo* info) {
info->Power=M28Power;
info->Reset=M28Reset;
GameStateRestore=StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

66
src/boards/31.c Normal file
View File

@@ -0,0 +1,66 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*/
/* added 2019-5-23
* Mapper 31 - custom mapper by infiniteneslives
* https://wiki.nesdev.com/w/index.php/INES_Mapper_031 */
#include "mapinc.h"
static uint8 preg[8];
static SFORMAT StateRegs[] =
{
{ preg, 8, "PREG" },
{ 0 }
};
static void Sync(void) {
setprg4(0x8000, preg[0]);
setprg4(0x9000, preg[1]);
setprg4(0xA000, preg[2]);
setprg4(0xB000, preg[3]);
setprg4(0xC000, preg[4]);
setprg4(0xD000, preg[5]);
setprg4(0xE000, preg[6]);
setprg4(0xF000, preg[7]);
setchr8(0);
}
static DECLFW(M31Write) {
preg[A & 7] = V;
Sync();
}
static void M31Power(void) {
preg[7] = ~0;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x5000, 0x5FFF, M31Write);
}
static void StateRestore(int version) {
Sync();
}
void Mapper31_Init(CartInfo *info) {
info->Power = M31Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@@ -1,7 +1,8 @@
/* FCE Ultra - NES/Famicom Emulator /* FCEUmm - NES/Famicom Emulator
* *
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2012 CaH4e3 * Copyright (C) 2012 CaH4e3
* Copyright (C) 2019 Libretro Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -18,38 +19,65 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* *
* TXC/Micro Genius simplified mapper * TXC/Micro Genius simplified mapper
* updated 06-2019 http://wiki.nesdev.com/w/index.php/INES_Mapper_036
*
* Known games:
* - Strike Wolf (Asia) (Unl)
* - Policeman (Gluk Video) (unl)
* - F-15 City War (Spain) (Gluk Video) (Unl)
*/ */
#include "mapinc.h" #include "mapinc.h"
static uint8 latche; static uint8 regs[5];
static SFORMAT StateRegs[] = static SFORMAT StateRegs[] =
{ {
{ &latche, 1, "LATC" }, { regs, 5, "REGS" },
{ 0 } { 0 }
}; };
static void Sync(void) { static void Sync(void) {
setprg32(0x8000, latche >> 4); setprg32(0x8000, regs[0] >> 4);
setchr8(latche & 0xf); setchr8(regs[4] & 0x0F);
} }
static DECLFW(M36Write) { static DECLFW(M36Write4100) {
latche = V; switch(A & 0xE103) {
case 0x4100:
if(regs[3] & 0x10)
regs[0]++;
else
regs[0] = regs[2];
break;
case 0x4101:
case 0x4102:
case 0x4103:
regs[A & 0x03] = V;
break;
}
}
static DECLFW(M36Write4200) {
regs[4] = V;
Sync();
}
static DECLFW(M36WriteHi) {
Sync(); Sync();
} }
static DECLFR(M36Read) { static DECLFR(M36Read) {
return latche; /* Need by Strike Wolf, being simplified mapper, this cart still uses some TCX mapper features andrely on it */ return ((X.DB & 0xCF) | (regs[0] & 0x30));
} }
static void M36Power(void) { static void M36Power(void) {
latche = 0;
Sync(); Sync();
SetReadHandler(0x4100, 0x4100, M36Read); SetReadHandler(0x4100, 0x4100, M36Read);
SetReadHandler(0x8000, 0xFFFF, CartBR); SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFE, M36Write); /* Actually, BUS conflict there preventing from triggering the wrong banks */ SetWriteHandler(0x4100, 0x4103, M36Write4100);
SetWriteHandler(0x4200, 0x4200, M36Write4200);
SetWriteHandler(0x8000, 0xFFFF, M36WriteHi);
} }
static void M36Restore(int version) { static void M36Restore(int version) {

View File

@@ -2,6 +2,7 @@
* *
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2008 CaH4e3 * Copyright (C) 2008 CaH4e3
* Copyright (C) 2019 Libretro Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -18,25 +19,38 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/* actually cart ID is 811120-C, sorry ;) K-3094 - another ID */ /* NES 2.0 Mapper 287
* BMC-411120-C, actually cart ID is 811120-C, sorry ;) K-3094 - another ID
* - 4-in-1 (411120-C)
* - 4-in-1 (811120-C,411120-C) [p4][U]
*
* BMC-K-3088, similar to BMC-411120-C but without jumper or dipswitch
* - 19-in-1(K-3088)(810849-C)(Unl)
*/
#include "mapinc.h" #include "mapinc.h"
#include "mmc3.h" #include "mmc3.h"
static uint8 reset_flag = 0; static uint8 reset_flag = 0;
static uint8 isK3088;
static void BMC411120CCW(uint32 A, uint8 V) { static void BMC411120CCW(uint32 A, uint8 V) {
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) { static void BMC411120CPW(uint32 A, uint8 V) {
if (EXPREGS[0] & (8 | reset_flag)) uint32 mask = isK3088 ? 0x07 : 0x03;
setprg32(0x8000, ((EXPREGS[0] >> 4) & 3) | (0x0C)); if (EXPREGS[0] & (isK3088 ? 8 : (8 | reset_flag))) { /* 32K Mode */
else if (A == 0x8000)
setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 3) << 4)); /* 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) { static DECLFW(BMC411120CLoWrite) {
/* printf("Wr: A:%04x V:%02x\n", A, V); */
EXPREGS[0] = A; EXPREGS[0] = A;
FixMMC3PRG(MMC3_cmd); FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd); FixMMC3CHR(MMC3_cmd);
@@ -55,6 +69,17 @@ static void BMC411120CPower(void) {
} }
void BMC411120C_Init(CartInfo *info) { void BMC411120C_Init(CartInfo *info) {
isK3088 = 0;
GenMMC3_Init(info, 128, 128, 8, 0);
pwrap = BMC411120CPW;
cwrap = BMC411120CCW;
info->Power = BMC411120CPower;
info->Reset = BMC411120CReset;
AddExState(EXPREGS, 1, 0, "EXPR");
}
void BMCK3088_Init(CartInfo *info) {
isK3088 = 1;
GenMMC3_Init(info, 128, 128, 8, 0); GenMMC3_Init(info, 128, 128, 8, 0);
pwrap = BMC411120CPW; pwrap = BMC411120CPW;
cwrap = BMC411120CCW; cwrap = BMC411120CCW;

View File

@@ -73,7 +73,7 @@ static void Sync(void) {
setchr2(0x1800, chr_reg[3]); setchr2(0x1800, chr_reg[3]);
setprg8r(0x10, 0x6000, 0); setprg8r(0x10, 0x6000, 0);
setprg16r((PRGptr[1]) ? kogame : 0, 0x8000, prg_reg); setprg16r((PRGptr[1]) ? kogame : 0, 0x8000, prg_reg);
setprg16(0xC000, ~0); setprg16(0xC000, 0x07);
} }
static DECLFR(M68Read) { static DECLFR(M68Read) {

View File

@@ -135,7 +135,6 @@ static DECLFW(M69SWrite0) {
} }
static DECLFW(M69SWrite1) { static DECLFW(M69SWrite1) {
int x;
GameExpSound.Fill = AYSound; GameExpSound.Fill = AYSound;
GameExpSound.HiFill = AYSoundHQ; GameExpSound.HiFill = AYSoundHQ;
switch (sndcmd) { switch (sndcmd) {

View File

@@ -36,13 +36,9 @@ static void Sync(void) {
uint32 base = ((cmdreg & 0x060) | ((cmdreg & 0x100) >> 1)) >> 2; uint32 base = ((cmdreg & 0x060) | ((cmdreg & 0x100) >> 1)) >> 2;
uint32 bank = (cmdreg & 0x01C) >> 2; uint32 bank = (cmdreg & 0x01C) >> 2;
uint32 lbank = (cmdreg & 0x200) ? 7 : ((cmdreg & 0x80) ? bank : 0); uint32 lbank = (cmdreg & 0x200) ? 7 : ((cmdreg & 0x80) ? bank : 0);
if (PRGptr[1]) {
setprg16r(base >> 3, 0x8000, bank); /* for versions with split ROMs */ setprg16(0x8000, base | bank);
setprg16r(base >> 3, 0xC000, lbank); setprg16(0xC000, base | lbank);
} else {
setprg16(0x8000, base | bank);
setprg16(0xC000, base | lbank);
}
setmirror(((cmdreg & 2) >> 1) ^ 1); setmirror(((cmdreg & 2) >> 1) ^ 1);
} }

70
src/boards/830134C.c Normal file
View File

@@ -0,0 +1,70 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 315
* BMC-830134C
* Used for multicarts using 820732C- and 830134C-numbered PCBs such as 4-in-1 Street Blaster 5
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_315
*/
#include "mapinc.h"
#include "mmc3.h"
static void BMC830134CCW(uint32 A, uint8 V) {
setchr1(A, (V & 0xFF) | ((EXPREGS[0] & 0x01) << 8) | ((EXPREGS[0] & 0x02) << 6) | ((EXPREGS[0] & 0x08) << 3));
}
static void BMC830134CPW(uint32 A, uint8 V) {
if ((EXPREGS[0] & 0x06) == 0x06) {
if (A == 0x8000) {
setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3));
setprg8(0xC000, (V & 0x0F) | 0x32);
} else if (A == 0xA000) {
setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3));
setprg8(0xE000, (V & 0x0F) | 0x32);
}
} else
setprg8(A, (V & 0x0F) | ((EXPREGS[0] & 0x06) << 3));
}
static DECLFW(BMC830134CWrite) {
EXPREGS[0] = V;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void BMC830134CReset(void) {
EXPREGS[0] = 0;
MMC3RegReset();
}
static void BMC830134CPower(void) {
GenMMC3Power();
SetWriteHandler(0x6800, 0x68FF, BMC830134CWrite);
}
void BMC830134C_Init(CartInfo *info) {
GenMMC3_Init(info, 128, 256, 1, 0);
pwrap = BMC830134CPW;
cwrap = BMC830134CCW;
info->Power = BMC830134CPower;
info->Reset = BMC830134CReset;
AddExState(EXPREGS, 1, 0, "EXPR");
}

View File

@@ -3,6 +3,7 @@
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2002 Xodnizel * Copyright (C) 2002 Xodnizel
* Copyright (C) 2005 CaH4e3 * Copyright (C) 2005 CaH4e3
* Copyright (C) 2019 Libretro Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -25,10 +26,12 @@
/* Mapper 090 is simpliest mapper hardware and have not extended nametable control and latched chr banks in 4k mode /* Mapper 090 is simpliest mapper hardware and have not extended nametable control and latched chr banks in 4k mode
* Mapper 209 much compicated hardware with decribed above features disabled by default and switchable by command * Mapper 209 much compicated hardware with decribed above features disabled by default and switchable by command
* Mapper 211 the same mapper 209 but with forced nametable control * Mapper 211 the same mapper 209 but with forced nametable control
* Mapper 281 PRG ($8000-$8FFF) and CHR ($9000-$AFFF) bank select register bits that select 256 KiB banks are masked off.
*/ */
static int is209; static int is209;
static int is211; static int is211;
static int is281;
static uint8 IRQMode; /* from $c001 */ static uint8 IRQMode; /* from $c001 */
static uint8 IRQPre; /* from $c004 */ static uint8 IRQPre; /* from $c004 */
@@ -73,7 +76,7 @@ static SFORMAT Tek_StateRegs[] = {
}; };
static void mira(void) { static void mira(void) {
if ((tkcom[0] & 0x20 && is209) || is211) { if (((tkcom[0] & 0x20) && is209) || is211 || ((tkcom[1] & 0x08) && is281)) {
int x; int x;
if (tkcom[0] & 0x40) { /* Name tables are ROM-only */ if (tkcom[0] & 0x40) { /* Name tables are ROM-only */
for (x = 0; x < 4; x++) for (x = 0; x < 4; x++)
@@ -96,56 +99,64 @@ static void mira(void) {
} }
} }
static uint8 invertprg(uint8 bank, uint8 reverse) {
if (reverse)
return ((bank & 0x01) << 6 | (bank & 0x02) << 4 | (bank & 0x04) << 2 |
(bank & 0x10) >> 2 | (bank & 0x20) >> 4 | (bank & 0x40) >> 6);
else
return bank;
}
static void tekprom(void) { static void tekprom(void) {
uint32 bankmode = ((tkcom[3] & 6) << 5); uint8 prgshift = 0, prgmask = 0x3F, outb_sel = 0x06, last_bank = 0x3F;
switch (tkcom[0] & 7) { uint8 prgmode = tkcom[0] & 0x03;
case 00: uint8 invert = (tkcom[0] & 0x03) == 0x03 ? 1 : 0;
uint32 bankmode = 0;
switch (tkcom[0] & 0x03) {
case 0x00: prgshift = 3; prgmask = 0x0F; break;
case 0x01: prgshift = 4; prgmask = 0x1F; break;
default: prgshift = 5; prgmask = 0x3F; break;
}
if (is281) {
prgmask >>= 1;
outb_sel = 0x01;
}
bankmode = ((tkcom[3] & outb_sel) << prgshift);
last_bank = (tkcom[0] & 0x04) ? prgb[3] : prgmask;
switch (prgmode) {
case 0x00:
if (tkcom[0] & 0x80) if (tkcom[0] & 0x80)
setprg8(0x6000, (((prgb[3] << 2) + 3) & 0x3F) | bankmode); setprg8(0x6000, (((prgb[3] << 2) + 3) & 0x3F) | bankmode);
setprg32(0x8000, 0x0F | ((tkcom[3] & 6) << 3)); setprg32(0x8000, (last_bank & prgmask) | bankmode);
break; break;
case 01: case 0x01:
if (tkcom[0] & 0x80) if (tkcom[0] & 0x80)
setprg8(0x6000, (((prgb[3] << 1) + 1) & 0x3F) | bankmode); setprg8(0x6000, (((prgb[3] << 1) + 1) & 0x3F) | bankmode);
setprg16(0x8000, (prgb[1] & 0x1F) | ((tkcom[3] & 6) << 4)); setprg16(0x8000, (prgb[1] & prgmask) | bankmode);
setprg16(0xC000, 0x1F | ((tkcom[3] & 6) << 4)); setprg16(0xC000, (last_bank & prgmask) | bankmode);
break; break;
case 03: /* bit reversion */ case 0x02:
case 02: case 0x03:
if (tkcom[0] & 0x80) if (tkcom[0] & 0x80)
setprg8(0x6000, (prgb[3] & 0x3F) | bankmode); setprg8(0x6000, (invertprg(prgb[3], invert) & 0x3F) | bankmode);
setprg8(0x8000, (prgb[0] & 0x3F) | bankmode); setprg8(0x8000, (invertprg(prgb[0], invert) & prgmask) | bankmode);
setprg8(0xa000, (prgb[1] & 0x3F) | bankmode); setprg8(0xa000, (invertprg(prgb[1], invert) & prgmask) | bankmode);
setprg8(0xc000, (prgb[2] & 0x3F) | bankmode); setprg8(0xc000, (invertprg(prgb[2], invert) & prgmask) | bankmode);
setprg8(0xe000, 0x3F | bankmode); setprg8(0xe000, (invertprg(last_bank, invert) & prgmask) | bankmode);
break;
case 04:
if (tkcom[0] & 0x80)
setprg8(0x6000, (((prgb[3] << 2) + 3) & 0x3F) | bankmode);
setprg32(0x8000, (prgb[3] & 0x0F) | ((tkcom[3] & 6) << 3));
break;
case 05:
if (tkcom[0] & 0x80)
setprg8(0x6000, (((prgb[3] << 1) + 1) & 0x3F) | bankmode);
setprg16(0x8000, (prgb[1] & 0x1F) | ((tkcom[3] & 6) << 4));
setprg16(0xC000, (prgb[3] & 0x1F) | ((tkcom[3] & 6) << 4));
break;
case 07: /* bit reversion */
case 06:
if (tkcom[0] & 0x80)
setprg8(0x6000, (prgb[3] & 0x3F) | bankmode);
setprg8(0x8000, (prgb[0] & 0x3F) | bankmode);
setprg8(0xa000, (prgb[1] & 0x3F) | bankmode);
setprg8(0xc000, (prgb[2] & 0x3F) | bankmode);
setprg8(0xe000, (prgb[3] & 0x3F) | bankmode);
break; break;
} }
} }
static void tekvrom(void) { static void tekvrom(void) {
int x, bank = 0, mask = 0xFFFF; int x, bank = 0, mask = 0xFFFF;
if (!(tkcom[3] & 0x20)) { if (!(tkcom[3] & 0x20) || is281) {
bank = (tkcom[3] & 1) | ((tkcom[3] & 0x18) >> 2); if (is281)
bank = tkcom[3] & 1;
else
bank = (tkcom[3] & 1) | ((tkcom[3] & 0x18) >> 2);
switch (tkcom[0] & 0x18) { switch (tkcom[0] & 0x18) {
case 0x00: bank <<= 5; mask = 0x1F; break; case 0x00: bank <<= 5; mask = 0x1F; break;
case 0x08: bank <<= 6; mask = 0x3F; break; case 0x08: bank <<= 6; mask = 0x3F; break;
@@ -445,6 +456,7 @@ static void M90Power(void) {
void Mapper90_Init(CartInfo *info) { void Mapper90_Init(CartInfo *info) {
is211 = 0; is211 = 0;
is209 = 0; is209 = 0;
is281 = 0;
info->Reset = togglie; info->Reset = togglie;
info->Power = M90Power; info->Power = M90Power;
PPU_hook = M90PPU; PPU_hook = M90PPU;
@@ -457,6 +469,7 @@ void Mapper90_Init(CartInfo *info) {
void Mapper209_Init(CartInfo *info) { void Mapper209_Init(CartInfo *info) {
is211 = 0; is211 = 0;
is209 = 1; is209 = 1;
is281 = 0;
info->Reset = togglie; info->Reset = togglie;
info->Power = M90Power; info->Power = M90Power;
PPU_hook = M90PPU; PPU_hook = M90PPU;
@@ -468,6 +481,20 @@ void Mapper209_Init(CartInfo *info) {
void Mapper211_Init(CartInfo *info) { void Mapper211_Init(CartInfo *info) {
is211 = 1; is211 = 1;
is281 = 0;
info->Reset = togglie;
info->Power = M90Power;
PPU_hook = M90PPU;
MapIRQHook = CPUWrap;
GameHBIRQHook2 = SLWrap;
GameStateRestore = M90Restore;
AddExState(Tek_StateRegs, ~0, 0, 0);
}
void Mapper281_Init(CartInfo *info) {
is211 = 0;
is209 = 0;
is281 = 1;
info->Reset = togglie; info->Reset = togglie;
info->Power = M90Power; info->Power = M90Power;
PPU_hook = M90PPU; PPU_hook = M90PPU;

View File

@@ -23,7 +23,7 @@
#include "mapinc.h" #include "mapinc.h"
static uint8 reg, mirr; static uint8 latche, reg, mirr;
static int32 IRQa, IRQCount, IRQLatch; static int32 IRQa, IRQCount, IRQLatch;
static uint8 *WRAM = NULL; static uint8 *WRAM = NULL;
static uint32 WRAMSIZE; static uint32 WRAMSIZE;
@@ -35,6 +35,7 @@ static SFORMAT StateRegs[] =
{ &IRQa, 4, "IRQA" }, { &IRQa, 4, "IRQA" },
{ &IRQCount, 4, "IRQC" }, { &IRQCount, 4, "IRQC" },
{ &IRQLatch, 4, "IRQL" }, { &IRQLatch, 4, "IRQL" },
{ &latche, 1, "LATC" },
{ 0 } { 0 }
}; };
@@ -47,8 +48,9 @@ static void Sync(void) {
static DECLFW(UNLKS7017Write) { static DECLFW(UNLKS7017Write) {
/* FCEU_printf("bs %04x %02x\n",A,V); */ /* FCEU_printf("bs %04x %02x\n",A,V); */
if ((A & 0xFF00) == 0x4A00) { if ((A & 0xFF00) == 0x4A00) {
reg = ((A >> 2) & 3) | ((A >> 4) & 4); latche = ((A >> 2) & 3) | ((A >> 4) & 4);
} else if ((A & 0xFF00) == 0x5100) { } else if ((A & 0xFF00) == 0x5100) {
reg = latche;
Sync(); Sync();
} else if (A == 0x4020) { } else if (A == 0x4020) {
X6502_IRQEnd(FCEU_IQEXT); X6502_IRQEnd(FCEU_IQEXT);

View File

@@ -2,6 +2,7 @@
* *
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2007 CaH4e3 * Copyright (C) 2007 CaH4e3
* Copyright (C) 2019 Libretro Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -21,43 +22,99 @@
* *
*/ */
/* added 2019-5-23
* - Mapper 56 - UNL KS202
* FDS Conversion: Super Mario Bros. 3 (Pirate, Alt)
* similar to M142 but use WRAM instead? $D000 additional IRQ trigger
* - fix IRQ counter, noticeable in status bars of both SMB2J(KS7032) and SMB3J(KS202)
*/
#include "mapinc.h" #include "mapinc.h"
static uint8 reg[8], cmd, IRQa = 0, isirqused = 0; static uint8 reg[8], creg[8], mirr, cmd, IRQa = 0;
static int32 IRQCount; static int32 IRQCount, IRQLatch;
static uint8 KS7032;
static uint8 *WRAM = NULL;
static uint32 WRAMSIZE;
static SFORMAT StateRegs[] = static SFORMAT StateRegsKS7032[] =
{ {
{ &cmd, 1, "CMD" }, { &cmd, 1, "CMD" },
{ reg, 8, "REGS" }, { reg, 8, "REGS" },
{ &IRQa, 1, "IRQA" }, { &IRQa, 1, "IRQA" },
{ &IRQCount, 4, "IRQC" }, { &IRQCount, 4 | FCEUSTATE_RLSB, "IRQC" },
{ 0 }
};
static SFORMAT StateRegsKS202[] =
{
{ creg, 8, "CREG" },
{ &mirr, 1, "MIRR" },
{ 0 } { 0 }
}; };
static void Sync(void) { static void Sync(void) {
setprg8(0x6000, reg[4]); setprg8(0x8000, reg[0]);
setprg8(0x8000, reg[1]); setprg8(0xA000, reg[1]);
setprg8(0xA000, reg[2]); setprg8(0xC000, reg[2]);
setprg8(0xC000, reg[3]);
setprg8(0xE000, ~0); setprg8(0xE000, ~0);
setchr8(0); setchr8(0);
if (KS7032)
setprg8(0x6000, reg[3]);
else {
setprg8r(0x10, 0x6000, 0);
setchr1(0x0000, creg[0]);
setchr1(0x0400, creg[1]);
setchr1(0x0800, creg[2]);
setchr1(0x0C00, creg[3]);
setchr1(0x1000, creg[4]);
setchr1(0x1400, creg[5]);
setchr1(0x1800, creg[6]);
setchr1(0x1C00, creg[7]);
setmirror(mirr);
}
} }
static DECLFW(UNLKS7032Write) { static DECLFW(UNLKS7032Write) {
/* FCEU_printf("bs %04x %02x\n",A,V); */ /* FCEU_printf("bs %04x %02x\n",A,V); */
switch (A & 0xF000) { switch (A & 0xF000) {
/* case 0x8FFF: reg[4]=V; Sync(); break; */ /* case 0x8FFF: reg[4]=V; Sync(); break; */
case 0x8000: X6502_IRQEnd(FCEU_IQEXT); IRQCount = (IRQCount & 0x000F) | (V & 0x0F); isirqused = 1; break; case 0x8000: IRQLatch = (IRQLatch & 0xFFF0) | (V & 0x0F); break;
case 0x9000: X6502_IRQEnd(FCEU_IQEXT); IRQCount = (IRQCount & 0x00F0) | ((V & 0x0F) << 4); isirqused = 1; break; case 0x9000: IRQLatch = (IRQLatch & 0xFF0F) | ((V & 0x0F) << 4); break;
case 0xA000: X6502_IRQEnd(FCEU_IQEXT); IRQCount = (IRQCount & 0x0F00) | ((V & 0x0F) << 8); isirqused = 1; break; case 0xA000: IRQLatch = (IRQLatch & 0xF0FF) | ((V & 0x0F) << 8); break;
case 0xB000: X6502_IRQEnd(FCEU_IQEXT); IRQCount = (IRQCount & 0xF000) | (V << 12); isirqused = 1; break; case 0xB000: IRQLatch = (IRQLatch & 0x0FFF) | (V << 12); break;
case 0xC000: if (isirqused) { case 0xC000:
X6502_IRQEnd(FCEU_IQEXT); IRQa = 1; IRQa = (V & 0xF);
} if (IRQa)
break; IRQCount = IRQLatch;
X6502_IRQEnd(FCEU_IQEXT); break;
case 0xD000: X6502_IRQEnd(FCEU_IQEXT); break;
case 0xE000: cmd = V & 7; break; case 0xE000: cmd = V & 7; break;
case 0xF000: reg[cmd] = V; Sync(); break; case 0xF000: {
uint8 bank = (cmd - 1);
if (bank < 3)
reg[bank] = (reg[bank] & 0x10) | (V & 0x0F);
else if (bank < 4)
reg[bank] = V;
Sync();
switch (A & 0xFC00) {
case 0xF000:
A &= 3;
if (A < 3)
reg[bank] = (reg[bank] & 0x0F) | (V & 0x10);
Sync();
break;
case 0xF800:
mirr = (V & 1);
Sync();
break;
case 0xFC00:
creg[A & 7] = V;
Sync();
break;
}
}
break;
} }
} }
@@ -65,8 +122,7 @@ static void FP_FASTAPASS(1) UNLSMB2JIRQHook(int a) {
if (IRQa) { if (IRQa) {
IRQCount += a; IRQCount += a;
if (IRQCount >= 0xFFFF) { if (IRQCount >= 0xFFFF) {
IRQa = 0; IRQCount = IRQLatch;
IRQCount = 0;
X6502_IRQBegin(FCEU_IQEXT); X6502_IRQBegin(FCEU_IQEXT);
} }
} }
@@ -77,6 +133,10 @@ static void UNLKS7032Power(void) {
SetReadHandler(0x6000, 0x7FFF, CartBR); SetReadHandler(0x6000, 0x7FFF, CartBR);
SetReadHandler(0x8000, 0xFFFF, CartBR); SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x4020, 0xFFFF, UNLKS7032Write); SetWriteHandler(0x4020, 0xFFFF, UNLKS7032Write);
if (!KS7032) {
SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
} }
static void StateRestore(int version) { static void StateRestore(int version) {
@@ -84,8 +144,27 @@ static void StateRestore(int version) {
} }
void UNLKS7032_Init(CartInfo *info) { void UNLKS7032_Init(CartInfo *info) {
KS7032 = 1;
info->Power = UNLKS7032Power; info->Power = UNLKS7032Power;
MapIRQHook = UNLSMB2JIRQHook; MapIRQHook = UNLSMB2JIRQHook;
GameStateRestore = StateRestore; GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0); AddExState(&StateRegsKS7032, ~0, 0, 0);
}
void UNLKS202_Init(CartInfo *info) {
KS7032 = 0;
info->Power = UNLKS7032Power;
MapIRQHook = UNLSMB2JIRQHook;
GameStateRestore = StateRestore;
AddExState(&StateRegsKS7032, ~0, 0, 0);
AddExState(&StateRegsKS202, ~0, 0, 0);
WRAMSIZE = 8192;
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
if (info->battery) {
info->SaveGame[0] = WRAM;
info->SaveGameLen[0] = WRAMSIZE;
}
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
} }

View File

@@ -22,12 +22,12 @@
#include "mmc3.h" #include "mmc3.h"
static void SA9602BPW(uint32 A, uint8 V) { static void SA9602BPW(uint32 A, uint8 V) {
setprg8r(EXPREGS[1], A, V & 0x3F); setprg8(A, (EXPREGS[1] & 0xC0) | (V & 0x3F));
if (MMC3_cmd & 0x40) if (MMC3_cmd & 0x40)
setprg8r(0, 0x8000, ~(1)); setprg8(0x8000, 62);
else else
setprg8r(0, 0xc000, ~(1)); setprg8(0xc000, 62);
setprg8r(0, 0xe000, ~(0)); setprg8(0xe000, 63);
} }
static DECLFW(SA9602BWrite) { static DECLFW(SA9602BWrite) {
@@ -35,7 +35,7 @@ static DECLFW(SA9602BWrite) {
case 0x8000: EXPREGS[0] = V; break; case 0x8000: EXPREGS[0] = V; break;
case 0x8001: case 0x8001:
if ((EXPREGS[0] & 7) < 6) { if ((EXPREGS[0] & 7) < 6) {
EXPREGS[1] = V >> 6; EXPREGS[1] = V;
FixMMC3PRG(MMC3_cmd); FixMMC3PRG(MMC3_cmd);
} }
break; break;

View File

@@ -34,7 +34,7 @@ static SFORMAT StateRegs[] =
static void Sync(void) { static void Sync(void) {
setprg8(0x6000, reg); setprg8(0x6000, reg);
setprg32r(1, 0x8000, 0); setprg32(0x8000, 4);
setchr8(0); setchr8(0);
setmirror(mirr); setmirror(mirr);
} }

View File

@@ -195,6 +195,41 @@ void Mapper61_Init(CartInfo *info) {
Latch_Init(info, M61Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0); Latch_Init(info, M61Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0);
} }
/*------------------ Map 063 ---------------------------*/
/* added 2019-5-23
* Mapper 63 NTDEC-Multicart
* http://wiki.nesdev.com/w/index.php/INES_Mapper_063
* - Powerful 250-in-1
* - Hello Kitty 255-in-1 */
static uint16 openBus;
static DECLFR(M63Read) {
if (A < 0xC000)
if (openBus)
return X.DB;
return CartBR(A);
}
static void M63Sync(void) {
uint16 mode = latche & 2;
uint16 prg_bank = (latche & 0x3F8) >> 1;
uint16 prg16 = (latche & 4) >> 1;
openBus = ((latche & 0x300) == 0x300);
setprg8(0x8000, (prg_bank | (mode ? 0 : prg16 | 0)));
setprg8(0xA000, (prg_bank | (mode ? 1 : prg16 | 1)));
setprg8(0xC000, (prg_bank | (mode ? 2 : prg16 | 0)));
setprg8(0xE000, ((latche & 0x800) ? ((latche & 0x7C) | ((latche & 6) ? 3 : 1)) :
(prg_bank | (mode ? 3 : (prg16 | 1)))));
setchr8(0);
setmirror((latche & 1) ^ 1);
}
void Mapper63_Init(CartInfo *info) {
Latch_Init(info, M63Sync, M63Read, 0x0000, 0x8000, 0xFFFF, 0);
}
/*------------------ Map 092 ---------------------------*/ /*------------------ Map 092 ---------------------------*/
/* Another two-in-one mapper, two Jaleco carts uses similar /* Another two-in-one mapper, two Jaleco carts uses similar
* hardware, but with different wiring. * hardware, but with different wiring.
@@ -506,3 +541,36 @@ static void BMCG146Sync(void) {
void BMCG146_Init(CartInfo *info) { void BMCG146_Init(CartInfo *info) {
Latch_Init(info, BMCG146Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0); Latch_Init(info, BMCG146Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0);
} }
/*-------------- BMC-TJ-03 ------------------------*/
/* NES 2.0 mapper 341 is used for a simple 4-in-1 multicart */
static void BMCTJ03Sync(void) {
uint8 mirr = ((latche >> 1) & 1) ^ 1;
uint8 bank = (latche >> 8) & 7;
setprg32(0x8000, bank);
setchr8(bank);
if (bank == 3) mirr ^= 1; /* Twin Bee has incorrect mirroring */
setmirror(mirr);
}
void BMCTJ03_Init(CartInfo *info) {
Latch_Init(info, BMCTJ03Sync, NULL, 0x0000, 0x8000, 0xFFFF, 0);
}
/*-------------- BMC-SA005-A ------------------------*/
/* NES 2.0 mapper 338 is used for a 16-in-1 and a 200/300/600/1000-in-1 multicart.
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_338 */
static void BMCSA005ASync(void) {
setprg16(0x8000, latche & 0x0F);
setprg16(0xC000, latche & 0x0F);
setchr8(latche & 0x0F);
setmirror((latche >> 3) & 1);
}
void BMCSA005A_Init(CartInfo *info) {
Latch_Init(info, BMCSA005ASync, NULL, 0x0000, 0x8000, 0xFFFF, 0);
}

90
src/boards/ax40g.c Normal file
View File

@@ -0,0 +1,90 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 527 is used for a bootleg version of
* Taito's 不動明王伝 (Fudō Myōō Den).
* Its UNIF board name is UNL-AX-40G. The original INES Mapper 207 is
* replaced with a VRC2 clone (A0/A1, i.e. VRC2b) while retaining
* Mapper 207's extended mirroring.
*/
#include "mapinc.h"
static uint8 preg[2], creg[8], NT[2];
static SFORMAT StateRegs[] =
{
{ preg, 2, "PREG" },
{ creg, 8, "CREG" },
{ NT, 2, "NMT" },
{ 0 }
};
static void Sync(void) {
uint8 i;
setprg8(0x8000, preg[0]);
setprg8(0xA000, preg[1]);
setprg8(0xC000, 0x1E);
setprg8(0xE000, 0x1F);
for (i = 0; i < 8; i++)
setchr1(i << 10, creg[i]);
setmirrorw(NT[0], NT[0], NT[1], NT[1]);
}
static DECLFW(UNLAX40GWrite8) {
A &= 0xF003;
preg[0] = V & 0x1F;
Sync();
}
static DECLFW(UNLAX40GWriteA) {
A &= 0xF003;
preg[1] = V & 0x1F;
Sync();
}
static DECLFW(UNLAX40GWriteB) {
uint16 i, shift;
A &= 0xF003;
i = ((A >> 1) & 1) | ((A - 0xB000) >> 11);
shift = ((A & 1) << 2);
creg[i] = (creg[i] & (0xF0 >> shift)) | ((V & 0xF) << shift);
if (i < 2)
NT[i] = (creg[i] & 0x80) >> 7;
Sync();
}
static void UNLAX40GPower(void) {
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0x8FFF, UNLAX40GWrite8);
SetWriteHandler(0xA000, 0xAFFF, UNLAX40GWriteA);
SetWriteHandler(0xB000, 0xEFFF, UNLAX40GWriteB);
}
static void StateRestore(int version) {
Sync();
}
void UNLAX40G_Init(CartInfo *info) {
info->Power = UNLAX40GPower;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

119
src/boards/bj56.c Normal file
View File

@@ -0,0 +1,119 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 526 is used for a bootleg version of Namco's 三国志: 中原の覇者 (Sangokushi: Chūgen no Hasha).
* Its UNIF board name is UNL-BJ-56.
* Mirroring seems to be hard-wired (to vertical).
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_526
*/
#include "mapinc.h"
static uint8 preg[4], creg[8];
static uint32 IRQCount;
static uint8 *WRAM = NULL;
static uint32 WRAMSIZE;
static SFORMAT StateRegs[] =
{
{ preg, 4, "PREG" },
{ creg, 8, "CREG" },
{ &IRQCount, 4, "IRQC" },
{ 0 }
};
static void Sync(void) {
uint8 i;
setprg8r(0x10, 0x6000, 0);
setprg8(0x8000, preg[0]);
setprg8(0xA000, preg[1]);
setprg8(0xC000, preg[2]);
setprg8(0xE000, preg[3]);
for (i = 0; i < 8; i++)
setchr1((i << 10), creg[i]);
setmirror(MI_V);
}
static DECLFW(UNLBJ56Write) {
/* FCEU_printf("Wr: A:%04x V:%02x\n", A, V); */
A &= 0xF00F;
if (A <= 0x8007) {
creg[A & 0x07] = V;
Sync();
} else if (A <= 0x800B) {
preg[A & 0x03] = V;
Sync();
} else {
switch (A & 0x0F) {
case 0x0D:
case 0x0F:
/* One of these two acknowledges a pending IRQ, and the other
* resets to IRQ counter to zero. Because they are always written
* to one after the other, it's not clear which one does which. */
X6502_IRQEnd(FCEU_IQEXT);
IRQCount = 0;
break;
}
}
}
static void FP_FASTAPASS(1) UNLBJ56IRQHook(int a) {
IRQCount += a;
if (IRQCount & 4096)
X6502_IRQBegin(FCEU_IQEXT);
}
static void UNLBJ56Close(void) {
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;
}
static void UNLBJ56Power(void) {
preg[0] = ~3;
preg[1] = ~2;
preg[2] = ~1;
preg[3] = ~0;
Sync();
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x8000, 0x800F, UNLBJ56Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void StateRestore(int version) {
Sync();
}
void UNLBJ56_Init(CartInfo *info) {
info->Power = UNLBJ56Power;
info->Close = UNLBJ56Close;
MapIRQHook = UNLBJ56IRQHook;
GameStateRestore = StateRestore;
WRAMSIZE = 8192;
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
if (info->battery) {
info->SaveGame[0] = WRAM;
info->SaveGameLen[0] = WRAMSIZE;
}
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@@ -3,6 +3,7 @@
* Copyright notice for this file: * Copyright notice for this file:
* Copyright (C) 2005 CaH4e3 * Copyright (C) 2005 CaH4e3
* Copyright (C) 2009 qeed * Copyright (C) 2009 qeed
* Copyright (C) 2019 Libretro Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * 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" #include "mapinc.h"
static uint8 reorder_banks = 0;
static uint8 isresetbased = 0; static uint8 isresetbased = 0;
static uint8 latche[2], reset; static uint8 latche[2], reset;
static uint8 banks[4] = { 0, 0, 1, 2 };
static SFORMAT StateRegs[] = static SFORMAT StateRegs[] =
{ {
{ &reset, 1, "RST" }, { &reset, 1, "RST" },
@@ -34,11 +43,17 @@ static SFORMAT StateRegs[] =
}; };
static void Sync(void) { static void Sync(void) {
uint8 bank; uint8 bank = 0;
uint8 base = ((latche[0] & 0x80) >> 7) | ((latche[1] & 1) << 1);
if (isresetbased) if (isresetbased)
bank = (latche[0] & 0x1f) | (reset << 5) | ((latche[1] & 1) << 6); bank = (latche[0] & 0x1f) | (reset << 5) | ((latche[1] & 1) << 6);
else else {
bank = (latche[0] & 0x1f) | ((latche[0] & 0x80) >> 2) | ((latche[1] & 1) << 6); if (reorder_banks) /* for 1536 KB prg roms */
base = banks[base];
bank = (base << 5) | (latche[0] & 0x1f);
}
if (!(latche[0] & 0x20)) if (!(latche[0] & 0x20))
setprg32(0x8000, bank >> 1); setprg32(0x8000, bank >> 1);
else { else {
@@ -65,19 +80,29 @@ static void StateRestore(int version) {
Sync(); Sync();
} }
static void M226Reset(void) {
latche[0] = latche[1] = reset = 0;
Sync();
}
void Mapper226_Init(CartInfo *info) { void Mapper226_Init(CartInfo *info) {
isresetbased = 0; isresetbased = 0;
/* 1536KiB PRG roms have different bank order */
reorder_banks = ((info->prgRom * 16) == 1536) ? 1 : 0;
info->Power = M226Power; info->Power = M226Power;
info->Reset = M226Reset;
AddExState(&StateRegs, ~0, 0, 0); AddExState(&StateRegs, ~0, 0, 0);
GameStateRestore = StateRestore; GameStateRestore = StateRestore;
} }
static void M233Reset(void) { static void M233Reset(void) {
latche[0] = latche[1] = 0;
reset ^= 1; reset ^= 1;
Sync(); Sync();
} }
void Mapper233_Init(CartInfo *info) { void Mapper233_Init(CartInfo *info) {
reorder_banks = 0;
isresetbased = 1; isresetbased = 1;
info->Power = M226Power; info->Power = M226Power;
info->Reset = M233Reset; info->Reset = M233Reset;

110
src/boards/bmc60311c.c Normal file
View File

@@ -0,0 +1,110 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*/
/* added 2019-5-23
* UNIF: BMC-60311C:
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_289
*/
#include "mapinc.h"
static uint8 inner_bank, outer_bank, mode;
static SFORMAT StateRegs[] =
{
{ &inner_bank, 1, "INB0" },
{ &outer_bank, 1, "OUTB" },
{ &mode, 1, "MODE" },
{ 0 }
};
static void Sync(void) {
uint8 bbank = (mode & 4) ? 0 : (inner_bank & 7);
uint8 bank = outer_bank | bbank;
uint8 preg[2];
/* 0: NROM-128: Same inner/outer 16 KiB bank at CPU $8000-$BFFF
* and $C000-$FFFF
* 1: NROM-256: 32 kiB bank at CPU $8000-$FFFF (Selected inner/outer bank SHR 1)
* 2: UNROM: Inner/outer bank at CPU $8000-BFFF,
* fixed inner bank 7 within outer bank at $C000-$FFFF
* 3: Unknown
*
* The combined inner/outer bank is simply the inner bank, selected by the
* latch at $8000-$FFFF (or 0 if the latch is disabled) ORed with the
* outer bank selected by $6001, without any bit shifting.
*/
preg[0] = bank;
switch (mode & 3) {
case 0x00:
case 0x01:
preg[1] = bank | ((mode & 1) ? 1 : 0);
break;
case 0x02:
preg[1] = outer_bank | 7;
case 0x03:
break;
}
setchr8(0);
setprg16(0x8000, preg[0]);
setprg16(0xC000, preg[1]);
setmirror(((mode & 8) >> 3) ^ 1);
}
static DECLFW(Write0) {
mode = V;
Sync();
}
static DECLFW(Write1) {
outer_bank = V;
Sync();
}
static DECLFW(Write8) {
inner_bank = V;
Sync();
}
static void BMC60311CPower(void) {
inner_bank = outer_bank = mode = 0;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x6000, Write0);
SetWriteHandler(0x6001, 0x6001, Write1);
SetWriteHandler(0x8000, 0xFFFF, Write8);
}
static void BMC60311CReset(void) {
inner_bank = outer_bank = mode = 0;
Sync();
}
static void BMC60311CRestore(int version) {
Sync();
}
void BMC60311C_Init(CartInfo *info) {
info->Power = BMC60311CPower;
info->Reset = BMC60311CReset;
GameStateRestore = BMC60311CRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

77
src/boards/bmc80013b.c Normal file
View File

@@ -0,0 +1,77 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*/
/* NES 2.0 Mapper 274 is used for the 90-in-1 Hwang Shinwei multicart.
* Its UNIF board name is BMC-80013-B.
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_274 */
#include "mapinc.h"
static uint8 regs[2], mode;
static SFORMAT StateRegs[] =
{
{ &regs[0], 1, "REG0" },
{ &regs[1], 1, "REG1" },
{ &mode, 1, "MODE" },
{ 0 }
};
static void Sync(void) {
if (mode & 0x02)
setprg16(0x8000, (regs[0] & 0x0F) | (regs[1] & 0x70));
else
setprg16(0x8000, (regs[0] & 0x0F) | 0x80);
setprg16(0xC000, regs[1]);
setmirror(((regs[0] >> 4) & 1) ^ 1);
}
static DECLFW(BMC80013BWrite) {
uint8 reg = (A >> 13) & 0x03;
if (!reg)
regs[0] = V & 0x1F;
else {
regs[1] = V & 0x7F;
mode = reg;
}
Sync();
}
static void BMC80013BPower(void) {
Sync();
setchr8(0);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, BMC80013BWrite);
}
static void BMC80013BReset(void) {
regs[0] = regs[1] = mode = 0;
Sync();
}
static void BMC80013BRestore(int version) {
Sync();
}
void BMC80013B_Init(CartInfo *info) {
info->Power = BMC80013BPower;
info->Reset = BMC80013BReset;
GameStateRestore = BMC80013BRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@@ -0,0 +1,80 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*
*/
/* NES 2.0 Mapper 320 is used for the Super HiK 6-in-1 A-030 multicart.
* Basically UxROM with an address-latch-based outer bank register.
* UNIF board name is BMC-830425C-4391T. Mirroring is hard-wired.
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_320
*/
#include "mapinc.h"
static uint8 bank_size;
static uint8 inner_bank;
static uint8 outer_bank;
static SFORMAT StateRegs[] =
{
{ &inner_bank, 1, "INNB" },
{ &outer_bank, 1, "OUTB" },
{ &bank_size, 1, "SIZE" },
{ 0 }
};
static void Sync(void) {
setprg16(0x8000, (outer_bank << 3) | (inner_bank & bank_size));
setprg16(0xC000, (outer_bank << 3) | bank_size);
setchr8(0);
}
static DECLFW(M320Write) {
/* 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 = (A & 0x0F);
bank_size = (A & 0x10) ? 0x07 : 0x0F;
}
inner_bank = (V & 0x0F);
Sync();
}
static void M320Power(void) {
bank_size = 0x0F;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M320Write);
}
static void M320Reset(void) {
inner_bank = outer_bank = 0;
bank_size = 0x0F;
Sync();
}
static void StateRestore(int version) {
Sync();
}
void BMC830425C4391T_Init(CartInfo *info) {
info->Power = M320Power;
info->Reset = M320Reset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

74
src/boards/bmcctc09.c Normal file
View File

@@ -0,0 +1,74 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*
*/
/* NES 2.0 mapper 335 is used for a 10-in-1 multicart.
* Its UNIF board name is BMC-CTC-09.
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_335 */
#include "mapinc.h"
#define PRG 0
#define CHR 1
static uint8 regs[2];
static SFORMAT StateRegs[] =
{
{ regs, 2, "REGS" },
{ 0 }
};
static void Sync(void) {
if (regs[PRG] & 0x10) {
setprg16(0x8000, ((regs[PRG] & 0x07) << 1) | ((regs[PRG] >> 3) & 1));
setprg16(0xC000, ((regs[PRG] & 0x07) << 1) | ((regs[PRG] >> 3) & 1));
} else
setprg32(0x8000, regs[PRG] & 0x07);
setchr8(regs[CHR] & 0x0F);
setmirror(((regs[PRG] >> 5) & 1) ^ 1);
}
static DECLFW(WritePRG) {
regs[PRG] = V;
Sync();
}
static DECLFW(WriteCHR) {
regs[CHR] = V;
Sync();
}
static void BMCCTC09Power(void) {
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xBFFF, WriteCHR);
SetWriteHandler(0xC000, 0xFFFF, WritePRG);
}
static void StateRestore(int version) {
Sync();
}
void BMCCTC09_Init(CartInfo *info) {
info->Power = BMCCTC09Power;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

95
src/boards/bmcgamecard.c Normal file
View File

@@ -0,0 +1,95 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 337 - BMC-CTC-12IN1
* 12-in-1 Game Card multicart
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_337
* NES 2.0 Mapper 350 - BMC-891227
* Super 15-in-1 Game Card
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_350
*/
#include "mapinc.h"
static uint8 latche, m350;
static SFORMAT StateRegs[] =
{
{ &latche, 1, "LATC" },
{ &m350, 1, "M350" },
{ 0 }
};
static void Sync(void) {
uint8 mirroring = m350 ? ((latche >> 7) & 1) : ((latche >> 5) & 1);
uint8 mode = m350 ? ((latche >> 5) & 0x03) : ((latche >> 6) & 0x03);
uint8 base = m350 ? ((latche & 0x40) ? (latche & 0x20) : 0) : 0;
setchr8(0);
setprg8(0x6000, 1);
setprg16r(0, 0x8000, base | (latche & 0x1F));
setprg16r(0, 0xC000, base | ((latche & 0x1F) | ((mode & 2) ? 0x07 : (mode & 1))));
setmirror(mirroring ^ 1);
}
static DECLFW(BMCCTC12IN1Write8) {
latche = (latche & 7) | (V & ~7);
Sync();
}
static DECLFW(BMCCTC12IN1WriteC) {
latche = (latche & ~7) | (V & 7);
Sync();
}
static void BMCCTC12IN1Power(void) {
Sync();
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xBFFF, BMCCTC12IN1Write8);
SetWriteHandler(0xC000, 0xFFFF, BMCCTC12IN1WriteC);
}
static void BMCCTC12IN1Reset(void) {
latche = 0;
Sync();
}
static void StateRestore(int version) {
Sync();
}
/* Mapper 337 - BMC-CTC-12IN1 */
void BMCCTC12IN1_Init(CartInfo *info) {
m350 = 0;
info->Power = BMCCTC12IN1Power;
info->Reset = BMCCTC12IN1Reset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}
/* Mapper 350 - BMC-891227 */
void BMC891227_Init(CartInfo *info) {
m350 = 1;
info->Power = BMCCTC12IN1Power;
info->Reset = BMCCTC12IN1Reset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

70
src/boards/bmck3006.c Normal file
View File

@@ -0,0 +1,70 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*
*/
/* NES 2.0 mapper 339 is used for a 21-in-1 multicart.
* Its UNIF board name is BMC-K-3006.
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_339
*/
#include "mapinc.h"
#include "mmc3.h"
static void BMCK3006CW(uint32 A, uint8 V) {
setchr1(A, (V & 0x7F) | (EXPREGS[0] & 0x18) << 4);
}
static void BMCK3006PW(uint32 A, uint8 V) {
if (EXPREGS[0] & 0x20) { /* MMC3 mode */
setprg8(A, (V & 0x0F) | (EXPREGS[0] & 0x18) << 1);
} else {
if ((EXPREGS[0] & 0x07) == 0x06) { /* NROM-256 */
setprg32(0x8000, (EXPREGS[0] >> 1) & 0x0F);
} else { /* NROM-128 */
setprg16(0x8000, EXPREGS[0] & 0x1F);
setprg16(0xC000, EXPREGS[0] & 0x1F);
}
}
}
static DECLFW(BMCK3006Write) {
EXPREGS[0] = A & 0x3F;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void BMCK3006Reset(void) {
EXPREGS[0] = 0;
MMC3RegReset();
}
static void BMCK3006Power(void) {
EXPREGS[0] = 0;
GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, BMCK3006Write);
}
void BMCK3006_Init(CartInfo *info) {
GenMMC3_Init(info, 512, 512, 8, 0);
pwrap = BMCK3006PW;
cwrap = BMCK3006CW;
info->Power = BMCK3006Power;
info->Reset = BMCK3006Reset;
AddExState(EXPREGS, 1, 0, "EXPR");
}

93
src/boards/bmck3033.c Normal file
View File

@@ -0,0 +1,93 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 322
* BMC-K-3033
* 35-in-1 (K-3033)
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_322
*/
#include "mapinc.h"
#include "mmc3.h"
static void BMCK3033CW(uint32 A, uint8 V) {
if (EXPREGS[2]) {
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 {
/* FCEU_printf("NROM: A:%04x V:%02x R1:%02x\n", A, V, EXPREGS[1]); */
setchr1(A, (V & 0x7F));
}
}
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); */
setprg8(A, (EXPREGS[1] << 5) | (V & 0x1F));
} else {
/* FCEU_printf("MMC3-128 A:%04x V:%02x chip:%02x\n", A, V, EXPREGS[1]); */
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]); */
setprg32(0x8000, base | EXPREGS[0] >> 1);
} else {
/* FCEU_printf("NROM-128 base:%02x chip:%02x\n", EXPREGS[0], EXPREGS[1]); */
setprg16(0x8000, base | EXPREGS[0]);
setprg16(0xC000, base | EXPREGS[0]);
}
}
}
static DECLFW(BMCK3033Write) {
EXPREGS[0] = (A & 0x07);
EXPREGS[1] = ((A & 0x18) >> 3) | ((A & 0x40) >> 4);
EXPREGS[2] = (A & 0x20);
EXPREGS[3] = (A & 0x80);
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void BMCK3033Power(void) {
GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, BMCK3033Write);
}
static void BMCK3033Reset(void) {
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
MMC3RegReset();
}
void BMCK3033_Init(CartInfo *info) {
GenMMC3_Init(info, 256, 256, 1, 0);
pwrap = BMCK3033PW;
cwrap = BMCK3033CW;
info->Power = BMCK3033Power;
info->Reset = BMCK3033Reset;
AddExState(EXPREGS, 4, 0, "EXPR");
}

79
src/boards/bmck3036.c Normal file
View File

@@ -0,0 +1,79 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*
*/
/* NES 2.0 mapper 340 is used for a 35-in-1 multicart.
* Its UNIF board name is BMC-K-3036.
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_340
* TODO: Some games are not working...
*/
#include "mapinc.h"
static uint8 regs[2], mirr, mode;
static SFORMAT StateRegs[] =
{
{ regs, 2, "REGS" },
{ &mode, 1, "MODE" },
{ &mirr, 1, "MIRR" },
{ 0 }
};
static void Sync(void) {
if (mode) { /* NROM-128 */
setprg16(0x8000, regs[0]);
setprg16(0xC000, regs[0]);
} else { /* UNROM */
setprg16(0x8000, regs[0] | regs[1]);
setprg16(0xC000, regs[0] | 0x07);
}
setchr8(0);
setmirror(mirr);
}
static DECLFW(M340Write) {
regs[0] = A & 0x1F;
regs[1] = V & 0x07;
mode = A & 0x20;
mirr = ((A & 0x25) == 0x25) ? 0 : 1;
Sync();
}
static void BMCK3036Power(void) {
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M340Write);
}
static void BMCK3036Reset(void) {
regs[0] = regs[1] = mode = mirr = 0;
Sync();
}
static void StateRestore(int version) {
Sync();
}
void BMCK3036_Init(CartInfo *info) {
info->Power = BMCK3036Power;
info->Reset = BMCK3036Reset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

74
src/boards/bmcl6in1.c Normal file
View File

@@ -0,0 +1,74 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 345
* BMC-L6IN1
* New Star 6-in-1 Game Cartridge
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_345
*/
#include "mapinc.h"
#include "mmc3.h"
static void BMCL6IN1CW(uint32 A, uint8 V) {
setchr8(V);
}
static void BMCL6IN1PW(uint32 A, uint8 V) {
if (EXPREGS[0] & 0x0C)
setprg8(A, (V & 0x0F) | (EXPREGS[0] & 0xC0) >> 2);
else
setprg32(0x8000, ((EXPREGS[0] & 0xC0) >> 4) | (EXPREGS[0] & 0x03));
}
static void BMCL6IN1MW(uint8 V) {
if (EXPREGS[0] & 0x20)
setmirror(MI_0 + ((EXPREGS[0] & 0x10) >> 1));
else {
A000B = V;
setmirror((V & 1) ^ 1);
}
}
static DECLFW(BMCL6IN1Write) {
EXPREGS[0] = V;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void BMCL6IN1Reset(void) {
EXPREGS[0] = 0;
MMC3RegReset();
}
static void BMCL6IN1Power(void) {
GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, BMCL6IN1Write);
}
void BMCL6IN1_Init(CartInfo *info) {
GenMMC3_Init(info, 512, 0, 1, 0);
pwrap = BMCL6IN1PW;
cwrap = BMCL6IN1CW;
mwrap = BMCL6IN1MW;
info->Power = BMCL6IN1Power;
info->Reset = BMCL6IN1Reset;
AddExState(EXPREGS, 1, 0, "EXPR");
}

View File

@@ -42,7 +42,7 @@ static void COOLBOYCW(uint32 A, uint8 V) {
} }
} }
/* Highest bit goes from MMC3 registers when EXPREGS[3]&0x80==0 or from EXPREGS[0]&0x08 otherwise */ /* Highest bit goes from MMC3 registers when EXPREGS[3]&0x80==0 or from EXPREGS[0]&0x08 otherwise */
setchr1(A, setchr1(A,
(V & 0x80 & mask) | ((((EXPREGS[0] & 0x08) << 4) & ~mask)) /* 7th bit */ (V & 0x80 & mask) | ((((EXPREGS[0] & 0x08) << 4) & ~mask)) /* 7th bit */
| ((EXPREGS[2] & 0x0F) << 3) /* 6-3 bits */ | ((EXPREGS[2] & 0x0F) << 3) /* 6-3 bits */
| ((A >> 10) & 7) /* 2-0 bits */ | ((A >> 10) & 7) /* 2-0 bits */
@@ -107,7 +107,7 @@ static DECLFW(COOLBOYWrite) {
CartBW(A,V); CartBW(A,V);
/* Deny any further writes when 7th bit is 1 AND 4th is 0 */ /* Deny any further writes when 7th bit is 1 AND 4th is 0 */
if ((EXPREGS[3] & 0x90) != 0x80) { if ((EXPREGS[3] & 0x90) != 0x80) {
EXPREGS[A & 3] = V; EXPREGS[A & 3] = V;
FixMMC3PRG(MMC3_cmd); FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd); FixMMC3CHR(MMC3_cmd);
@@ -150,3 +150,27 @@ void COOLBOY_Init(CartInfo *info) {
info->Reset = COOLBOYReset; info->Reset = COOLBOYReset;
AddExState(EXPREGS, 4, 0, "EXPR"); AddExState(EXPREGS, 4, 0, "EXPR");
} }
/*------------------ MINDKIDS ---------------------------*/
/* A COOLBOY variant that works identically but puts the outer bank registers
* in the $5xxx range instead of the $6xxx range.
* The UNIF board name is MINDKIDS (submapper 1).
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_268
*/
static void MINDKIDSPower(void) {
GenMMC3Power();
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
SetWriteHandler(0x5000, 0x5fff, COOLBOYWrite);
}
void MINDKIDS_Init(CartInfo *info) {
GenMMC3_Init(info, 2048, 256, 8, info->battery);
pwrap = COOLBOYPW;
cwrap = COOLBOYCW;
info->Power = MINDKIDSPower;
info->Reset = COOLBOYReset;
AddExState(EXPREGS, 4, 0, "EXPR");
}

View File

@@ -94,7 +94,7 @@ static DECLFW(NROMWrite) {
static void NROMPower(void) { static void NROMPower(void) {
setprg8r(0x10, 0x6000, 0); /* Famili BASIC (v3.0) need it (uses only 4KB), FP-BASIC uses 8KB */ setprg8r(0x10, 0x6000, 0); /* Famili BASIC (v3.0) need it (uses only 4KB), FP-BASIC uses 8KB */
setprg16(0x8000, 0); setprg16(0x8000, 0);
setprg16(0xC000, ~0); setprg16(0xC000, 1);
setchr8(0); setchr8(0);
SetReadHandler(0x6000, 0x7FFF, CartBR); SetReadHandler(0x6000, 0x7FFF, CartBR);
@@ -153,24 +153,29 @@ static void CNROMSync(void) {
} }
void CNROM_Init(CartInfo *info) { void CNROM_Init(CartInfo *info) {
unsigned _no_busc, _busc;
_busc = 1; /* by default, CNROM is set to emulate bus conflicts to all games */
_no_busc = 0;
if (GameInfo->cspecial == 1)
_no_busc = 1;
/* TODO: move these to extended database when implemented. */ /* TODO: move these to extended database when implemented. */
int _busc, x; switch (info->CRC32) {
uint64 partialmd5 = 0; case 0xf283cf58: /* Colorful Dragon (Asia) (PAL) (Unl).nes */
_busc = 1; case 0x2915faf0: /* Incantation (Asia) (Unl).nes */
for (x = 0; x < 8; x++) case 0xebd0644d: /* Dao Shuai (Asia) (Unl).nes */
partialmd5 |= (uint64)info->MD5[15 - x] << (x * 8); case 0x8f154a0d: /* Pu Ke Jing Ling (China) (Unl).nes */
if (partialmd5 == 0x117181328eb1ad23LL) /* 75 Bingo (Sachen-English) [U].unf */ case 0xd04a40e6: /* Bingo 75 (Asia) (Unl).nes */
_busc = 0; case 0xe41b440f: /* Sidewinder (Joy Van) */
else case 0xb0c871c5: /* Wei Lai Xiao Zi (Joy Van) */
switch (info->CRC32) { case 0xb3be2f71: /* Yanshan Chess (Unl) */
case 0xf283cf58: /* Colorful Dragon (Asia) (PAL) (Unl).nes */ _no_busc = 1;
case 0x2915faf0: /* Incantation (Asia) (Unl).nes */ break;
case 0xebd0644d: /* Dao Shuai (Asia) (Unl).nes */
case 0x8f154a0d: /* Pu Ke Jing Ling (China) (Unl).nes */
case 0xd04a40e6: /* Bingo 75 (Asia) (Unl).nes */
_busc = 0;
break;
} }
if (_no_busc == 1) _busc = 0;
Latch_Init(info, CNROMSync, 0, 0x8000, 0xFFFF, 1, _busc); Latch_Init(info, CNROMSync, 0, 0x8000, 0xFFFF, 1, _busc);
} }
@@ -225,6 +230,22 @@ void CPROM_Init(CartInfo *info) {
Latch_Init(info, CPROMSync, 0, 0x8000, 0xFFFF, 0, 0); Latch_Init(info, CPROMSync, 0, 0x8000, 0xFFFF, 0, 0);
} }
/*------------------ Map 29 ---------------------------*/
/* added 2019-5-23
* Mapper 28, used by homebrew game Glider
* https://wiki.nesdev.com/w/index.php/INES_Mapper_029 */
static void M29Sync(void) {
setprg16(0x8000, (latche >> 2) & 7);
setprg16(0xc000, ~0);
setchr8r(0, latche & 3);
setprg8r(0x10, 0x6000, 0);
}
void Mapper29_Init(CartInfo *info) {
Latch_Init(info, M29Sync, 0x0000, 0x6000, 0xFFFF, 1, 0);
}
/*------------------ Map 38 ---------------------------*/ /*------------------ Map 38 ---------------------------*/
static void M38Sync(void) { static void M38Sync(void) {
@@ -476,22 +497,32 @@ void Mapper241_Init(CartInfo *info) {
* 16 bankswitching mode and normal mirroring... But there is no any * 16 bankswitching mode and normal mirroring... But there is no any
* correlations between modes and they can be used in one mapper code. * correlations between modes and they can be used in one mapper code.
*/ */
static int A65ASsubmapper;
static void BMCA65ASSync(void) { static void BMCA65ASSync(void) {
if (latche & 0x40) if (latche & 0x40)
setprg32(0x8000, (latche >> 1) & 0x0F); setprg32(0x8000, (latche >> 1) & 0x0F);
else { else {
setprg16(0x8000, ((latche & 0x30) >> 1) | (latche & 7)); if (A65ASsubmapper == 1) {
setprg16(0xC000, ((latche & 0x30) >> 1) | 7); setprg16(0x8000, ((latche & 0x38) >> 0) | (latche & 7));
setprg16(0xC000, ((latche & 0x38) >> 0) | 7);
} else {
setprg16(0x8000, ((latche & 0x30) >> 1) | (latche & 7));
setprg16(0xC000, ((latche & 0x30) >> 1) | 7);
}
} }
setchr8(0); setchr8(0);
if (latche & 0x80) if (latche & 0x80)
setmirror(MI_0 + (((latche >> 5) & 1))); setmirror(MI_0 + (((latche >> 5) & 1)));
else else {
setmirror(((latche >> 3) & 1) ^ 1); if (A65ASsubmapper == 1) /* added as workaround since games for this cart uses vertical mirroring */
setmirror(MI_V);
else
setmirror(((latche >> 3) & 1) ^ 1);
}
} }
void BMCA65AS_Init(CartInfo *info) { void BMCA65AS_Init(CartInfo *info) {
A65ASsubmapper = info->submapper; /* not a real submapper */
Latch_Init(info, BMCA65ASSync, 0, 0x8000, 0xFFFF, 0, 0); Latch_Init(info, BMCA65ASSync, 0, 0x8000, 0xFFFF, 0, 0);
} }
@@ -508,3 +539,17 @@ static void BMC11160Sync(void) {
void BMC11160_Init(CartInfo *info) { void BMC11160_Init(CartInfo *info) {
Latch_Init(info, BMC11160Sync, 0, 0x8000, 0xFFFF, 0, 0); Latch_Init(info, BMC11160Sync, 0, 0x8000, 0xFFFF, 0, 0);
} }
/*------------------ BMC-K-3046 ---------------------------*/
/* NES 2.0 mapper 336 is used for an 11-in-1 multicart
* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_336 */
static void BMCK3046Sync(void) {
setprg16(0x8000, latche);
setprg16(0xC000, latche | 0x07);
setchr8(0);
}
void BMCK3046_Init(CartInfo *info) {
Latch_Init(info, BMCK3046Sync, 0, 0x8000, 0xFFFF, 0, 0);
}

View File

@@ -18,36 +18,40 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
/* Updated 6-27-19 */
#include "mapinc.h" #include "mapinc.h"
static uint16 addrlatch; static uint8 datalatch, addrlatch, lock, hw_mode;
static uint8 datalatch, hw_mode;
static SFORMAT StateRegs[] = static SFORMAT StateRegs[] =
{ {
{ &addrlatch, 2, "ADRL" }, { &addrlatch, 1, "ADRL" },
{ &datalatch, 1, "DATL" }, { &datalatch, 1, "DATL" },
{ &hw_mode, 1, "HWMO" }, { &hw_mode, 1, "HWMO" },
{ &lock, 1, "LOCK" },
{ 0 } { 0 }
}; };
static void Sync(void) { static void Sync(void) {
uint8 prg = (addrlatch & 7); uint8 prg = (addrlatch & 0x3F);
setchr8(datalatch); setchr8(datalatch);
if(addrlatch & 0x80) { if (addrlatch & 0x80) {
setprg16(0x8000,prg); setprg16(0x8000,prg);
setprg16(0xC000,prg); setprg16(0xC000,prg);
} else { } else {
setprg32(0x8000,prg >> 1); setprg32(0x8000,prg >> 1);
} }
setmirror(MI_V); setmirror(((datalatch >> 7) & 1) ^ 1);
} }
static DECLFW(EH8813AWrite) { static DECLFW(EH8813AWrite) {
if((addrlatch & 0x100) == 0) { if (lock == 0) {
addrlatch = A & 0x1FF; addrlatch = A & 0xFF;
datalatch = V & 0xF; datalatch = V & 0xFC;
lock = (A & 0x100) >> 8;
} }
datalatch = (datalatch & ~0x03) | (V & 0x03);
Sync(); Sync();
} }
@@ -56,16 +60,16 @@ static DECLFR(EH8813ARead) {
A= (A & 0xFFF0) + hw_mode; A= (A & 0xFFF0) + hw_mode;
return CartBR(A); return CartBR(A);
} }
static void EH8813APower(void) { static void EH8813APower(void) {
addrlatch = datalatch = hw_mode = 0; addrlatch = datalatch = hw_mode = lock = 0;
Sync(); Sync();
SetReadHandler(0x8000, 0xFFFF, EH8813ARead); SetReadHandler(0x8000, 0xFFFF, EH8813ARead);
SetWriteHandler(0x8000, 0xFFFF, EH8813AWrite); SetWriteHandler(0x8000, 0xFFFF, EH8813AWrite);
} }
static void EH8813AReset(void) { static void EH8813AReset(void) {
addrlatch = datalatch = 0; addrlatch = datalatch = lock = 0;
hw_mode = (hw_mode + 1) & 0xF; hw_mode = (hw_mode + 1) & 0xF;
FCEU_printf("Hardware Switch is %01X\n", hw_mode); FCEU_printf("Hardware Switch is %01X\n", hw_mode);
Sync(); Sync();

View File

@@ -49,22 +49,23 @@
#include "emu2413.h" #include "emu2413.h"
static const unsigned char default_inst[15][8] = { static const unsigned char default_inst[15][8] = {
/* VRC7 instruments, January 17, 2004 update -Xodnizel */ /* 2019-03-19 VRC7 instrument patchset dumped by Nuke.YKT */
{ 0x03, 0x21, 0x04, 0x06, 0x8D, 0xF2, 0x42, 0x17 }, /* https://wiki.nesdev.com/w/index.php/VRC7_audio */
{ 0x13, 0x41, 0x05, 0x0E, 0x99, 0x96, 0x63, 0x12 }, { 0x03, 0x21, 0x05, 0x06, 0xE8, 0x81, 0x42, 0x27 },
{ 0x31, 0x11, 0x10, 0x0A, 0xF0, 0x9C, 0x32, 0x02 }, { 0x13, 0x41, 0x14, 0x0D, 0xD8, 0xF6, 0x23, 0x12 },
{ 0x21, 0x61, 0x1D, 0x07, 0x9F, 0x64, 0x20, 0x27 }, { 0x11, 0x11, 0x08, 0x08, 0xFA, 0xB2, 0x20, 0x12 },
{ 0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28 }, { 0x31, 0x61, 0x0C, 0x07, 0xA8, 0x64, 0x61, 0x27 },
{ 0x02, 0x01, 0x06, 0x00, 0xF0, 0xF2, 0x03, 0x95 }, { 0x32, 0x21, 0x1E, 0x06, 0xE1, 0x76, 0x01, 0x28 },
{ 0x21, 0x61, 0x1C, 0x07, 0x82, 0x81, 0x16, 0x07 }, { 0x02, 0x01, 0x06, 0x00, 0xA3, 0xE2, 0xF4, 0xF4 },
{ 0x23, 0x21, 0x1A, 0x17, 0xEF, 0x82, 0x25, 0x15 }, { 0x21, 0x61, 0x1D, 0x07, 0x82, 0x81, 0x11, 0x07 },
{ 0x25, 0x11, 0x1F, 0x00, 0x86, 0x41, 0x20, 0x11 }, { 0x23, 0x21, 0x22, 0x17, 0xA2, 0x72, 0x01, 0x17 },
{ 0x85, 0x01, 0x1F, 0x0F, 0xE4, 0xA2, 0x11, 0x12 }, { 0x35, 0x11, 0x25, 0x00, 0x40, 0x73, 0x72, 0x01 },
{ 0x07, 0xC1, 0x2B, 0x45, 0xB4, 0xF1, 0x24, 0xF4 }, { 0xB5, 0x01, 0x0F, 0x0F, 0xA8, 0xA5, 0x51, 0x02 },
{ 0x61, 0x23, 0x11, 0x06, 0x96, 0x96, 0x13, 0x16 }, { 0x17, 0xC1, 0x24, 0x07, 0xF8, 0xF8, 0x22, 0x12 },
{ 0x01, 0x02, 0xD3, 0x05, 0x82, 0xA2, 0x31, 0x51 }, { 0x71, 0x23, 0x11, 0x06, 0x65, 0x74, 0x18, 0x16 },
{ 0x61, 0x22, 0x0D, 0x02, 0xC3, 0x7F, 0x24, 0x05 }, { 0x01, 0x02, 0xD3, 0x05, 0xC9, 0x95, 0x03, 0x02 },
{ 0x21, 0x62, 0x0E, 0x00, 0xA1, 0xA0, 0x44, 0x17 }, { 0x61, 0x63, 0x0C, 0x00, 0x94, 0xC0, 0x33, 0xF6 },
{ 0x21, 0x72, 0x0D, 0x00, 0xC1, 0xD5, 0x56, 0x06 }
}; };
/* Size of Sintable ( 8 -- 18 can be used. 9 recommended.)*/ /* Size of Sintable ( 8 -- 18 can be used. 9 recommended.)*/

70
src/boards/faridunrom.c Normal file
View File

@@ -0,0 +1,70 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 324
* FARID_UNROM_8-IN-1
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_324
*/
#include "mapinc.h"
static uint8 latch;
static SFORMAT StateRegs[] =
{
{ &latch, 1, "LATC" },
{ 0 }
};
static void Sync(void) {
setchr8(0);
setprg16(0x8000, ((latch & 0x70) >> 1) | (latch & 0x07));
setprg16(0xC000, ((latch & 0x70) >> 1) | 0x07 );
}
static DECLFW(FARIDUNROMWrite) {
V &= CartBR(A);
if ((V & 0x80) && !(latch & 0x80) && !(latch & 0x08))
latch = (latch & 0x87) | (V & 0x78);
latch = (latch & 0x78) | (V & 0x87);
Sync();
}
static void FARIDUNROMPower(void) {
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, FARIDUNROMWrite);
}
static void FARIDUNROMReset(void) {
latch &= ~0x78;
Sync();
}
static void StateRestore(int version) {
Sync();
}
void FARIDUNROM_Init(CartInfo *info) {
info->Power = FARIDUNROMPower;
info->Reset = FARIDUNROMReset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@@ -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);
}

69
src/boards/gn26.c Normal file
View File

@@ -0,0 +1,69 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 344
* BMC-GN-26
* Kuai Da Jin Ka Zhong Ji Tiao Zhan 3-in-1 (3-in-1,6-in-1,Unl)
*/
#include "mapinc.h"
#include "mmc3.h"
static void BMCGN26CW(uint32 A, uint8 V) {
uint32 base = (EXPREGS[0] & 0x03) << 7;
setchr1(A, base | (V & 0xFF));
}
static void BMCGN26PW(uint32 A, uint8 V) {
/* 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)
setprg32(0x8000, (base << 2) | (V >> 2));
} else
setprg8(A, (base << 4) | (V & 0x0F));
}
static DECLFW(BMCGN26Write) {
EXPREGS[0] = A & 0x0F;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void BMCGN26Reset(void) {
EXPREGS[0] = 0;
MMC3RegReset();
}
static void BMCGN26Power(void) {
GenMMC3Power();
SetWriteHandler(0x6800, 0x68FF, BMCGN26Write);
}
void BMCGN26_Init(CartInfo *info) {
GenMMC3_Init(info, 128, 256, 1, 0);
pwrap = BMCGN26PW;
cwrap = BMCGN26CW;
info->Power = BMCGN26Power;
info->Reset = BMCGN26Reset;
AddExState(EXPREGS, 1, 0, "EXPR");
}

View File

@@ -29,7 +29,7 @@ static SFORMAT StateRegs[] =
}; };
static void Sync(void) { static void Sync(void) {
setprg8r(1, 0x6000, 0); setprg8(0x6000, 32);
setprg32(0x8000, reg); setprg32(0x8000, reg);
setchr8(0); setchr8(0);
} }
@@ -40,7 +40,7 @@ static DECLFW(BMCGS2004Write) {
} }
static void BMCGS2004Power(void) { static void BMCGS2004Power(void) {
reg = ~0; reg = 0x07;
Sync(); Sync();
SetReadHandler(0x6000, 0x7FFF, CartBR); SetReadHandler(0x6000, 0x7FFF, CartBR);
SetReadHandler(0x8000, 0xFFFF, CartBR); SetReadHandler(0x8000, 0xFFFF, CartBR);
@@ -48,7 +48,7 @@ static void BMCGS2004Power(void) {
} }
static void BMCGS2004Reset(void) { static void BMCGS2004Reset(void) {
reg = ~0; reg = 0x07;
} }
static void StateRestore(int version) { static void StateRestore(int version) {

View File

@@ -29,8 +29,8 @@ static SFORMAT StateRegs[] =
}; };
static void Sync(void) { static void Sync(void) {
setprg8r(0, 0x6000, ~0); setprg8(0x6000, 31);
setprg32r((reg & 8) >> 3, 0x8000, reg); setprg32(0x8000, reg);
setchr8(0); setchr8(0);
} }
@@ -40,7 +40,7 @@ static DECLFW(BMCGS2013Write) {
} }
static void BMCGS2013Power(void) { static void BMCGS2013Power(void) {
reg = ~0; reg = 0;
Sync(); Sync();
SetReadHandler(0x6000, 0x7FFF, CartBR); SetReadHandler(0x6000, 0x7FFF, CartBR);
SetReadHandler(0x8000, 0xFFFF, CartBR); SetReadHandler(0x8000, 0xFFFF, CartBR);
@@ -48,7 +48,7 @@ static void BMCGS2013Power(void) {
} }
static void BMCGS2013Reset(void) { static void BMCGS2013Reset(void) {
reg = ~0; reg = 0;
} }
static void StateRestore(int version) { static void StateRestore(int version) {

171
src/boards/hp10xx_hp20xx.c Normal file
View File

@@ -0,0 +1,171 @@
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2017 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
*/
#include "mapinc.h"
#include "mmc3.h"
#include "../ines.h"
/* added on 2019-5-23 - NES 2.0 Mapper 260
* HP10xx/HP20xx - a simplified version of FK23C mapper with pretty strict and better
* organized banking behaviour. It seems that some 176 mapper assigned game may be
* actually this kind of board instead but in common they aren't compatible at all,
* the games on the regular FK23C boards couldn't run on this mapper and vice versa...
*/
static uint8 unromchr, lock;
static uint32 dipswitch;
static void BMCHPxxCW(uint32 A, uint8 V) {
if (EXPREGS[0] & 4) { /* custom banking */
switch(EXPREGS[0] & 3) {
case 0:
case 1:
setchr8(EXPREGS[2] & 0x3F);
/* FCEU_printf("\tCHR8 %02X\n",EXPREGS[2]&0x3F); */
break;
case 2:
setchr8((EXPREGS[2] & 0x3E) | (unromchr & 1));
/* FCEU_printf("\tCHR8 %02X\n",(EXPREGS[2]&0x3E)|(unromchr&1)); */
break;
case 3:
setchr8((EXPREGS[2] & 0x3C) | (unromchr & 3));
/* FCEU_printf("\tCHR8 %02X\n",(EXPREGS[2]&0x3C)|(unromchr&3)); */
break;
}
} else { /* mmc3 banking */
int base, mask;
if(EXPREGS[0] & 1) { /* 128K mode */
base = EXPREGS[2] & 0x30;
mask = 0x7F;
} else { /* 256K mode */
base = EXPREGS[2] & 0x20;
mask = 0xFF;
}
/* FCEU_printf("\tCHR1 %04x:%02X\n",A,(V&mask)|(base<<3)); */
setchr1(A, (V & mask) | (base << 3));
}
}
/* PRG wrapper */
static void BMCHPxxPW(uint32 A, uint8 V) {
if(EXPREGS[0] & 4) { /* custom banking */
if((EXPREGS[0] & 0xF) == 4) { /* 16K mode */
/* FCEU_printf("\tPRG16 %02X\n",EXPREGS[1]&0x1F); */
setprg16(0x8000, EXPREGS[1] & 0x1F);
setprg16(0xC000, EXPREGS[1] & 0x1F);
} else { /* 32K modes */
/* FCEU_printf("\tPRG32 %02X\n",(EXPREGS[1]&0x1F)>>1); */
setprg32(0x8000, (EXPREGS[1] & 0x1F) >> 1);
}
} else { /* mmc3 banking */
uint8 base, mask;
if(EXPREGS[0] & 2) { /* 128K mode */
base = EXPREGS[1] & 0x18;
mask = 0x0F;
} else { /* 256K mode */
base = EXPREGS[1] & 0x10;
mask = 0x1F;
}
/* FCEU_printf("\tPRG8 %02X\n",(V&mask)|(base<<1)); */
setprg8(A, (V & mask) | (base << 1));
setprg8r(0x10, 0x6000, A001B & 3);
}
}
/* MIRROR wrapper */
static void BMCHPxxMW(uint8 V) {
if(EXPREGS[0] & 4) { /* custom banking */
/* FCEU_printf("CUSTOM MIRR: %d\n",(unromchr>>2)&1); */
setmirror(((unromchr >> 2) & 1) ^ 1);
} else { /* mmc3 banking */
/* FCEU_printf("MMC3 MIRR: %d\n",(V&1)^1); */
A000B = V;
setmirror((A000B & 1) ^ 1);
}
}
/* PRG handler ($8000-$FFFF) */
static DECLFW(BMCHPxxHiWrite) {
/* FCEU_printf("HI WRITE %04X:%02X\n",A,V); */
if(EXPREGS[0] & 4) { /* custom banking */
/* FCEU_printf("CUSTOM\n"); */
unromchr = V;
FixMMC3CHR(MMC3_cmd);
} else { /* mmc3 banking */
/* FCEU_printf("MMC3\n"); */
if(A<0xC000) {
MMC3_CMDWrite(A, V);
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
} else {
MMC3_IRQWrite(A, V);
}
}
}
/* EXP handler ($5000-$5FFF) */
static DECLFW(BMCHPxxWrite) {
if (!lock) {
/* FCEU_printf("LO WRITE %04X:%02X\n",A,V); */
EXPREGS[A & 3] = V;
lock = V & 0x80;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
}
static DECLFR(BMCHPxxRead) {
return dipswitch;
}
static void BMCHPxxReset(void) {
dipswitch++;
dipswitch &= 0xF;
lock = 0;
/* FCEU_printf("BMCHPxx dipswitch set to %d\n",dipswitch); */
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
MMC3RegReset();
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
}
static void BMCHPxxPower(void) {
GenMMC3Power();
dipswitch = lock = 0;
EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
SetReadHandler(0x5000, 0x5fff, BMCHPxxRead);
SetWriteHandler(0x5000, 0x5fff, BMCHPxxWrite);
SetWriteHandler(0x8000, 0xffff, BMCHPxxHiWrite);
}
void BMCHPxx_Init(CartInfo *info) {
GenMMC3_Init(info, 256, 256, 8, 0);
cwrap = BMCHPxxCW;
pwrap = BMCHPxxPW;
mwrap = BMCHPxxMW;
info->Power = BMCHPxxPower;
info->Reset = BMCHPxxReset;
AddExState(EXPREGS, 8, 0, "EXPR");
AddExState(&unromchr, 1, 0, "UCHR");
AddExState(&dipswitch, 1, 0, "DPSW");
AddExState(&lock, 1, 0, "LOCK");
}

87
src/boards/lh51.c Normal file
View File

@@ -0,0 +1,87 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
* NES 2.0 Mapper 309 is used for Whirlwind Manu's ROM cartridge conversion
* of game 愛戦士ニコル (Ai Senshi Nicol, cartridge code LH51).
* Its UNIF board name is UNL-LH51.
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_309
*/
#include "mapinc.h"
static uint8 reg, mirr;
static uint8 *WRAM = NULL;
static uint32 WRAMSIZE;
static SFORMAT StateRegs[] =
{
{ &reg, 1, "REG" },
{ &mirr, 1, "MIRR" },
{ 0 }
};
static void Sync(void) {
setchr8(0);
setprg8r(0x10, 0x6000, 0);
setprg8(0x8000, reg & 0x0F);
setprg8(0xA000, 13);
setprg8(0xC000, 14);
setprg8(0xE000, 15);
setmirror(((mirr >> 3) & 1) ^ 1);
}
static DECLFW(LH51Write) {
switch (A & 0xF000) {
case 0x8000: reg = V; Sync(); break;
case 0xF000: mirr = V; Sync(); break;
}
}
static void LH51Power(void) {
Sync();
SetReadHandler(0x6000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetWriteHandler(0x8000, 0xFFFF, LH51Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void LH51Close(void) {
if (WRAM)
FCEU_gfree(WRAM);
WRAM = NULL;
}
static void StateRestore(int version) {
Sync();
}
void LH51_Init(CartInfo *info) {
info->Power = LH51Power;
info->Close = LH51Close;
GameStateRestore = StateRestore;
WRAMSIZE = 8192;
WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE);
SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1);
AddExState(WRAM, WRAMSIZE, 0, "WRAM");
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@@ -31,7 +31,7 @@ static void MALEEPower(void) {
SetReadHandler(0x6000, 0x67FF, CartBR); SetReadHandler(0x6000, 0x67FF, CartBR);
SetReadHandler(0x7000, 0x77FF, CartBR); SetReadHandler(0x7000, 0x77FF, CartBR);
SetWriteHandler(0x7000, 0x77FF, CartBW); SetWriteHandler(0x7000, 0x77FF, CartBW);
setprg2r(1, 0x6000, 0); setprg2(0x6000, 16);
setprg32(0x8000, 0); setprg32(0x8000, 0);
setchr8(0); setchr8(0);
} }

View File

@@ -36,13 +36,17 @@ static uint8 *WRAM = NULL;
static uint8 *CHRRAM = NULL; static uint8 *CHRRAM = NULL;
static int is155, is171; static int is155, is171;
static uint8 MMC1WRAMEnabled(void) {
return !(DRegs[3] & 0x10);
}
static DECLFW(MBWRAM) { static DECLFW(MBWRAM) {
if (!(DRegs[3] & 0x10) || is155) if (MMC1WRAMEnabled() || is155)
Page[A >> 11][A] = V; /* WRAM is enabled. */ Page[A >> 11][A] = V; /* WRAM is enabled. */
} }
static DECLFR(MAWRAM) { static DECLFR(MAWRAM) {
if ((DRegs[3] & 0x10) && !is155) if (!MMC1WRAMEnabled() && !is155)
return X.DB; /* WRAM is disabled */ return X.DB; /* WRAM is disabled */
return(Page[A >> 11][A]); return(Page[A >> 11][A]);
} }
@@ -201,12 +205,12 @@ static int DetectMMC1WRAMSize(uint32 crc32) {
static uint32 NWCIRQCount; static uint32 NWCIRQCount;
static uint8 NWCRec; static uint8 NWCRec;
#define NWCDIP 0xE static int32 nwcdip = 0x4;
static void NWCIRQHook(int a) { static void NWCIRQHook(int a) {
if (!(NWCRec & 0x10)) { if (!(NWCRec & 0x10)) {
NWCIRQCount += a; NWCIRQCount += a;
if ((NWCIRQCount | (NWCDIP << 25)) >= 0x3e000000) { if (NWCIRQCount >= (0x20000000 | (nwcdip << 25))) {
NWCIRQCount = 0; NWCIRQCount = 0;
X6502_IRQBegin(FCEU_IQEXT); X6502_IRQBegin(FCEU_IQEXT);
} }
@@ -236,6 +240,11 @@ static void NWCPRGHook(uint32 A, uint8 V) {
static void NWCPower(void) { static void NWCPower(void) {
GenMMC1Power(); GenMMC1Power();
setchr8r(0, 0); setchr8r(0, 0);
nwcdip = (int32)GameInfo->cspecial;
}
static void NWCReset(void) {
nwcdip = (int32)GameInfo->cspecial;
} }
void Mapper105_Init(CartInfo *info) { void Mapper105_Init(CartInfo *info) {
@@ -244,6 +253,7 @@ void Mapper105_Init(CartInfo *info) {
MMC1PRGHook16 = NWCPRGHook; MMC1PRGHook16 = NWCPRGHook;
MapIRQHook = NWCIRQHook; MapIRQHook = NWCIRQHook;
info->Power = NWCPower; info->Power = NWCPower;
info->Reset = NWCReset;
} }
static void GenMMC1Power(void) { static void GenMMC1Power(void) {
@@ -389,4 +399,47 @@ void SOROM_Init(CartInfo *info) {
GenMMC1Init(info, 256, 0, 16, info->battery); GenMMC1Init(info, 256, 0, 16, info->battery);
} }
/* ----------------------- FARID_SLROM_8-IN-1 -----------------------*/
/* NES 2.0 Mapper 323 - UNIF FARID_SLROM_8-IN-1 */
static uint8 reg, lock;
static void FARIDSLROM8IN1PRGHook(uint32 A, uint8 V) {
setprg16(A, (V & 0x07) | (reg << 3));
}
static void FARIDSLROM8IN1CHRHook(uint32 A, uint8 V) {
setchr4(A, (V & 0x1F) | (reg << 5));
}
static DECLFW(FARIDSLROM8IN1Write) {
if (MMC1WRAMEnabled() && !lock) {
lock = (V & 0x08) >> 3;
reg = (V & 0xF0) >> 4;
MMC1MIRROR();
MMC1CHR();
MMC1PRG();
}
}
static void FARIDSLROM8IN1Power(void) {
reg = lock = 0;
GenMMC1Power();
SetWriteHandler(0x6000, 0x7FFF, FARIDSLROM8IN1Write);
}
static void FARIDSLROM8IN1Reset(void) {
reg = lock = 0;
MMC1CMReset();
}
void FARIDSLROM8IN1_Init(CartInfo *info) {
GenMMC1Init(info, 1024, 256, 8, 0);
MMC1CHRHook4 = FARIDSLROM8IN1CHRHook;
MMC1PRGHook16 = FARIDSLROM8IN1PRGHook;
info->Power = FARIDSLROM8IN1Power;
info->Reset = FARIDSLROM8IN1Reset;
AddExState(&lock, 1, 0, "LOCK");
AddExState(&reg, 1, 0, "REG6");
}

View File

@@ -236,8 +236,9 @@ static void GENPWRAP(uint32 A, uint8 V) {
/* [NJ102] Mo Dao Jie (C) has 1024Mb MMC3 BOARD, maybe something other will be broken /* [NJ102] Mo Dao Jie (C) has 1024Mb MMC3 BOARD, maybe something other will be broken
* also HengGe BBC-2x boards enables this mode as default board mode at boot up * also HengGe BBC-2x boards enables this mode as default board mode at boot up
*/ */
setprg8(A, (V & 0x7F) | ((kt_extra & 4) << 4)); setprg8(A, (V & 0x7F)/* | ((kt_extra & 4) << 4)*/);
/* KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support */ /* KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support */
/* KT-008 boards should be assigned to mapper 224 */
} }
static void GENMWRAP(uint8 V) { static void GENMWRAP(uint8 V) {
@@ -265,7 +266,7 @@ void GenMMC3Power(void) {
SetReadHandler(0x8000, 0xFFFF, CartBR); SetReadHandler(0x8000, 0xFFFF, CartBR);
/* KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support */ /* KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support */
SetWriteHandler(0x5000,0x5FFF, KT008HackWrite); /* SetWriteHandler(0x5000,0x5FFF, KT008HackWrite); */ /* KT-008 boards should be assigned to mapper 224 */
A001B = A000B = 0; A001B = A000B = 0;
setmirror(1); setmirror(1);
@@ -321,6 +322,7 @@ void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery) {
} }
/* KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support */ /* KT-008 boards hack 2-in-1, TODO assign to new ines mapper, most dump of KT-boards on the net are mapper 4, so need database or goodnes fix support */
/* KT-008 boards should be assigned to mapper 224 */
AddExState(&kt_extra, 1, 0, "KTEX"); AddExState(&kt_extra, 1, 0, "KTEX");
AddExState(MMC3_StateRegs, ~0, 0, 0); AddExState(MMC3_StateRegs, ~0, 0, 0);
@@ -597,6 +599,12 @@ void Mapper47_Init(CartInfo *info) {
} }
/* ---------------------------- Mapper 49 ------------------------------- */ /* ---------------------------- Mapper 49 ------------------------------- */
/* -------------------- BMC-STREETFIGTER-GAME4IN1 ----------------------- */
/* added 6-24-19:
* BMC-STREETFIGTER-GAME4IN1 - Sic. $6000 set to $41 rather than $00 on power-up.
*/
static uint8 isUNIF = 0;
static void M49PW(uint32 A, uint8 V) { static void M49PW(uint32 A, uint8 V) {
if (EXPREGS[0] & 1) { if (EXPREGS[0] & 1) {
@@ -623,11 +631,12 @@ static DECLFW(M49Write) {
} }
static void M49Reset(void) { static void M49Reset(void) {
EXPREGS[0] = 0; EXPREGS[0] = isUNIF ? 0x41 : 0;
MMC3RegReset(); MMC3RegReset();
} }
static void M49Power(void) { static void M49Power(void) {
EXPREGS[0] = isUNIF ? 0x41 : 0;
M49Reset(); M49Reset();
GenMMC3Power(); GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, M49Write); SetWriteHandler(0x6000, 0x7FFF, M49Write);
@@ -635,6 +644,7 @@ static void M49Power(void) {
} }
void Mapper49_Init(CartInfo *info) { void Mapper49_Init(CartInfo *info) {
isUNIF = 0;
GenMMC3_Init(info, 512, 256, 0, 0); GenMMC3_Init(info, 512, 256, 0, 0);
cwrap = M49CW; cwrap = M49CW;
pwrap = M49PW; pwrap = M49PW;
@@ -643,6 +653,16 @@ void Mapper49_Init(CartInfo *info) {
AddExState(EXPREGS, 1, 0, "EXPR"); AddExState(EXPREGS, 1, 0, "EXPR");
} }
void BMCSFGAME4IN1_Init(CartInfo *info) {
isUNIF = 1;
GenMMC3_Init(info, 512, 512, 0, 0);
cwrap = M49CW;
pwrap = M49PW;
info->Reset = M49Reset;
info->Power = M49Power;
AddExState(EXPREGS, 1, 0, "EXPR");
}
/* ---------------------------- Mapper 52 ------------------------------- */ /* ---------------------------- Mapper 52 ------------------------------- */
static void M52PW(uint32 A, uint8 V) { static void M52PW(uint32 A, uint8 V) {
uint32 mask = 0x1F ^ ((EXPREGS[0] & 8) << 1); uint32 mask = 0x1F ^ ((EXPREGS[0] & 8) << 1);
@@ -720,18 +740,24 @@ void Mapper74_Init(CartInfo *info) {
/* ---------------------------- Mapper 114 ------------------------------ */ /* ---------------------------- Mapper 114 ------------------------------ */
static uint8 cmdin; static uint8 cmdin, type_Boogerman = 0;
uint8 boogerman_perm[8] = { 0, 2, 5, 3, 6, 1, 7, 4 };
uint8 m114_perm[8] = { 0, 3, 1, 5, 6, 7, 2, 4 }; uint8 m114_perm[8] = { 0, 3, 1, 5, 6, 7, 2, 4 };
static void M114PWRAP(uint32 A, uint8 V) { static void M114PWRAP(uint32 A, uint8 V) {
if (EXPREGS[0] & 0x80) { if (EXPREGS[0] & 0x80) {
/* FCEU_printf("8000-C000:%02X\n",EXPREGS[0]&0xF); */ if (EXPREGS[0] & 0x20)
setprg16(0x8000, EXPREGS[0] & 0xF); setprg32(0x8000, (EXPREGS[0] & 0x0F) >> 1);
setprg16(0xC000, EXPREGS[0] & 0xF); else {
} else { setprg16(0x8000, (EXPREGS[0] & 0x0F));
/* FCEU_printf("%04X:%02X\n",A,V&0x3F); */ setprg16(0xC000, (EXPREGS[0] & 0x0F));
setprg8(A, V & 0x3F); }
} } else
setprg8(A, V);
}
static void M114CWRAP(uint32 A, uint8 V) {
setchr1(A, (uint32)V | ((EXPREGS[1] & 1) << 8));
} }
static DECLFW(M114Write) { static DECLFW(M114Write) {
@@ -746,28 +772,52 @@ static DECLFW(M114Write) {
} }
} }
static DECLFW(BoogermanWrite) {
switch (A & 0xE001) {
case 0x8001: if (!cmdin) break; MMC3_CMDWrite(0x8001, V); cmdin = 0; break;
case 0xA000: MMC3_CMDWrite(0x8000, (V & 0xC0) | (boogerman_perm[V & 7])); cmdin = 1; break;
case 0xA001: IRQReload = 1; break;
case 0xC000: MMC3_CMDWrite(0xA000, V); break;
case 0xC001: IRQLatch = V; break;
case 0xE000: X6502_IRQEnd(FCEU_IQEXT); IRQa = 0; break;
case 0xE001: IRQa = 1; break;
}
}
static DECLFW(M114ExWrite) { static DECLFW(M114ExWrite) {
if (A <= 0x7FFF) { if (A <= 0x7FFF) {
EXPREGS[0] = V; if (A & 1)
EXPREGS[1] = V;
else
EXPREGS[0] = V;
FixMMC3PRG(MMC3_cmd); FixMMC3PRG(MMC3_cmd);
} }
} }
static void M114Power(void) { static void M114Power(void) {
EXPREGS[0] = EXPREGS[1] = 0;
GenMMC3Power(); GenMMC3Power();
SetWriteHandler(0x6000, 0x7FFF, M114ExWrite);
SetWriteHandler(0x8000, 0xFFFF, M114Write); SetWriteHandler(0x8000, 0xFFFF, M114Write);
SetWriteHandler(0x5000, 0x7FFF, M114ExWrite); if (type_Boogerman)
SetWriteHandler(0x8000, 0xFFFF, BoogermanWrite);
} }
static void M114Reset(void) { static void M114Reset(void) {
EXPREGS[0] = 0; EXPREGS[0] = EXPREGS[1] = 0;
MMC3RegReset(); MMC3RegReset();
} }
void Mapper114_Init(CartInfo *info) { void Mapper114_Init(CartInfo *info) {
isRevB = 0; isRevB = 0;
type_Boogerman = 0;
if (info->CRC32 == 0x80eb1839 || /* Boogerman (Sugar Softec) (Unl) [!] - submapper 1 */
info->CRC32 == 0x071e4ee8) /* 114 test-rom https://forums.nesdev.com/viewtopic.php?f=3&t=17391 */
type_Boogerman = 1;
GenMMC3_Init(info, 256, 256, 0, 0); GenMMC3_Init(info, 256, 256, 0, 0);
pwrap = M114PWRAP; pwrap = M114PWRAP;
cwrap = M114CWRAP;
info->Power = M114Power; info->Power = M114Power;
info->Reset = M114Reset; info->Reset = M114Reset;
AddExState(EXPREGS, 1, 0, "EXPR"); AddExState(EXPREGS, 1, 0, "EXPR");
@@ -855,13 +905,19 @@ void Mapper119_Init(CartInfo *info) {
} }
/* ---------------------------- Mapper 134 ------------------------------ */ /* ---------------------------- 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) { static void M134PW(uint32 A, uint8 V) {
setprg8(A, (V & 0x1F) | ((EXPREGS[0] & 2) << 4)); uint8 mask = (EXPREGS[0] & 0x04) ? 0x0F : 0x1F;
setprg8(A, (V & mask) | ((EXPREGS[0] & 3) << 4));
} }
static void M134CW(uint32 A, uint8 V) { static void M134CW(uint32 A, uint8 V) {
setchr1(A, (V & 0xFF) | ((EXPREGS[0] & 0x20) << 3)); uint8 mask = (EXPREGS[0] & 0x04) ? 0x7F : 0xFF;
setchr1(A, (V & mask) | ((EXPREGS[0] & 0x30) << 3));
} }
static DECLFW(M134Write) { static DECLFW(M134Write) {
@@ -871,13 +927,14 @@ static DECLFW(M134Write) {
} }
static void M134Power(void) { static void M134Power(void) {
EXPREGS[0] = 0; EXPREGS[0] = 0x01;
GenMMC3Power(); GenMMC3Power();
SetWriteHandler(0x6001, 0x6001, M134Write); SetWriteHandler(0x6001, 0x6001, M134Write);
SetWriteHandler(0x6801, 0x6801, M134Write);
} }
static void M134Reset(void) { static void M134Reset(void) {
EXPREGS[0] = 0; EXPREGS[0] = 0x01;
MMC3RegReset(); MMC3RegReset();
} }
@@ -1137,19 +1194,73 @@ void Mapper198_Init(CartInfo *info) {
} }
/* ---------------------------- Mapper 205 ------------------------------ */ /* ---------------------------- Mapper 205 ------------------------------ */
/* GN-45 BOARD */ /* UNIF boardname BMC-JC-016-2
https://wiki.nesdev.com/w/index.php/INES_Mapper_205 */
static void M205PW(uint32 A, uint8 V) { static void M205PW(uint32 A, uint8 V) {
uint8 bank = V & ((EXPREGS[0] & 0x02) ? 0x0F : 0x1F);
setprg8(A, EXPREGS[0] << 4 | bank);
}
static void M205CW(uint32 A, uint8 V) {
uint8 bank = V & ((EXPREGS[0] & 0x02) ? 0x7F : 0xFF);
setchr1(A, (EXPREGS[0] << 7) | bank);
}
static DECLFW(M205Write0) {
if (EXPREGS[1] == 0) {
EXPREGS[0] = V & 0x03;
EXPREGS[1] = A & 0x80;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
} else
CartBW(A, V);
}
static DECLFW(M205Write1) {
if (EXPREGS[1] == 0) {
EXPREGS[0] = V & 0xF0;
FixMMC3PRG(MMC3_cmd);
FixMMC3CHR(MMC3_cmd);
} else
CartBW(A, V);
}
static void M205Reset(void) {
EXPREGS[0] = EXPREGS[1] = 0;
MMC3RegReset();
}
static void M205Power(void) {
EXPREGS[0] = EXPREGS[1] = 0;
GenMMC3Power();
SetWriteHandler(0x6000, 0x6fff, M205Write0);
SetWriteHandler(0x7000, 0x7fff, M205Write1); /* OK-411 boards, the same logic, but data latched, 2-in-1 frankenstein */
}
void Mapper205_Init(CartInfo *info) {
GenMMC3_Init(info, 256, 128, 8, 0);
pwrap = M205PW;
cwrap = M205CW;
info->Power = M205Power;
info->Reset = M205Reset;
AddExState(EXPREGS, 1, 0, "EXPR");
}
/* --------------------------- GN-45 BOARD ------------------------------ */
/* Mapper 361 and 366, previously assigned as Mapper 205 */
static void GN45PW(uint32 A, uint8 V) {
/* GN-30A - \ED\E0\F7\E0\EB\FC\ED\E0\FF \EC\E0\F1\EA\E0 \E4\EE\EB\E6\ED\E0 \E1\FB\F2\FC 1F + \E0\EF\EF\E0\F0\E0\F2\ED\FB\E9 \EF\E5\F0\E5\EA\EB\FE\F7\E0\F2\E5\EB\FC \ED\E0 \F8\E8\ED\E5 \E0\E4\F0\E5\F1\E0 */ /* GN-30A - \ED\E0\F7\E0\EB\FC\ED\E0\FF \EC\E0\F1\EA\E0 \E4\EE\EB\E6\ED\E0 \E1\FB\F2\FC 1F + \E0\EF\EF\E0\F0\E0\F2\ED\FB\E9 \EF\E5\F0\E5\EA\EB\FE\F7\E0\F2\E5\EB\FC \ED\E0 \F8\E8\ED\E5 \E0\E4\F0\E5\F1\E0 */
setprg8(A, (V & 0x0f) | EXPREGS[0]); setprg8(A, (V & 0x0f) | EXPREGS[0]);
} }
static void M205CW(uint32 A, uint8 V) { static void GN45CW(uint32 A, uint8 V) {
/* GN-30A - \ED\E0\F7\E0\EB\FC\ED\E0\FF \EC\E0\F1\EA\E0 \E4\EE\EB\E6\ED\E0 \E1\FB\F2\FC FF */ /* GN-30A - \ED\E0\F7\E0\EB\FC\ED\E0\FF \EC\E0\F1\EA\E0 \E4\EE\EB\E6\ED\E0 \E1\FB\F2\FC FF */
setchr1(A, (V & 0x7F) | (EXPREGS[0] << 3)); setchr1(A, (V & 0x7F) | (EXPREGS[0] << 3));
} }
static DECLFW(M205Write0) { static DECLFW(GN45Write0) {
if (EXPREGS[2] == 0) { if (EXPREGS[2] == 0) {
EXPREGS[0] = A & 0x30; EXPREGS[0] = A & 0x30;
EXPREGS[2] = A & 0x80; EXPREGS[2] = A & 0x80;
@@ -1159,7 +1270,7 @@ static DECLFW(M205Write0) {
CartBW(A, V); CartBW(A, V);
} }
static DECLFW(M205Write1) { static DECLFW(GN45Write1) {
if (EXPREGS[2] == 0) { if (EXPREGS[2] == 0) {
EXPREGS[0] = V & 0x30; EXPREGS[0] = V & 0x30;
FixMMC3PRG(MMC3_cmd); FixMMC3PRG(MMC3_cmd);
@@ -1168,23 +1279,23 @@ static DECLFW(M205Write1) {
CartBW(A, V); CartBW(A, V);
} }
static void M205Reset(void) { static void GN45Reset(void) {
EXPREGS[0] = EXPREGS[2] = 0; EXPREGS[0] = EXPREGS[2] = 0;
MMC3RegReset(); MMC3RegReset();
} }
static void M205Power(void) { static void GN45Power(void) {
GenMMC3Power(); GenMMC3Power();
SetWriteHandler(0x6000, 0x6fff, M205Write0); SetWriteHandler(0x6000, 0x6fff, GN45Write0);
SetWriteHandler(0x7000, 0x7fff, M205Write1); /* OK-411 boards, the same logic, but data latched, 2-in-1 frankenstein */ SetWriteHandler(0x7000, 0x7fff, GN45Write1); /* OK-411 boards, the same logic, but data latched, 2-in-1 frankenstein */
} }
void Mapper205_Init(CartInfo *info) { void GN45_Init(CartInfo *info) {
GenMMC3_Init(info, 128, 128, 8, 0); GenMMC3_Init(info, 128, 128, 8, 0);
pwrap = M205PW; pwrap = GN45PW;
cwrap = M205CW; cwrap = GN45CW;
info->Power = M205Power; info->Power = GN45Power;
info->Reset = M205Reset; info->Reset = GN45Reset;
AddExState(EXPREGS, 1, 0, "EXPR"); AddExState(EXPREGS, 1, 0, "EXPR");
} }

View File

@@ -0,0 +1,75 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 343
* BMC-RESETNROM-XIN1
* - Sheng Tian 2-in-1(Unl,ResetBase)[p1] - Kung Fu (Spartan X), Super Mario Bros (alt)
* - Sheng Tian 2-in-1(Unl,ResetBase)[p2] - B-Wings, Twin-bee
*
* BMC-KS106C
* - Kaiser 4-in-1(Unl,KS106C)[p1] - B-Wings, Kung Fu, 1942, SMB1 (wrong mirroring)
*/
#include "mapinc.h"
static uint8 gameblock, limit;
static SFORMAT StateRegs[] =
{
{ &gameblock, 1, "GAME" },
{ 0 }
};
static void Sync(void) {
setchr8(gameblock);
setprg32(0x8000, gameblock);
}
static void BMCRESETNROMXIN1Power(void) {
gameblock = 0;
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
}
static void BMCRESETNROMXIN1Reset(void) {
gameblock++;
gameblock &= limit;
Sync();
}
static void StateRestore(int version) {
Sync();
}
void BMCRESETNROMXIN1_Init(CartInfo *info) {
limit = 0x01;
info->Power = BMCRESETNROMXIN1Power;
info->Reset = BMCRESETNROMXIN1Reset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}
void BMCKS106C_Init(CartInfo *info) {
limit = 0x03;
info->Power = BMCRESETNROMXIN1Power;
info->Reset = BMCRESETNROMXIN1Reset;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

57
src/boards/resettxrom.c Normal file
View File

@@ -0,0 +1,57 @@
/* FCEUmm - NES/Famicom Emulator
*
* Copyright notice for this file:
* 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
* 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
*/
/* NES 2.0 Mapper 313 is used for MMC3-based multicarts that switch
* between 128 KiB PRG-ROM/128 KiB CHR-ROM-sized games on each reset and
* thus require no additional registers.
* Its UNIF board name is BMC-RESET-TXROM.
*/
#include "mapinc.h"
#include "mmc3.h"
static void M313CW(uint32 A, uint8 V) {
setchr1(A, (EXPREGS[0] << 7) | (V & 0x7F));
}
static void M313PW(uint32 A, uint8 V) {
setprg8(A, (EXPREGS[0] << 4) | (V & 0x0F));
}
static void M313Reset(void) {
EXPREGS[0]++;
EXPREGS[0] &= 0x03;
MMC3RegReset();
}
static void M313Power(void) {
EXPREGS[0] = 0;
GenMMC3Power();
}
/* NES 2.0 313, UNIF BMC-RESET-TXROM */
void BMCRESETTXROM_Init(CartInfo *info) {
GenMMC3_Init(info, 128, 128, 0, 0);
cwrap = M313CW;
pwrap = M313PW;
info->Power = M313Power;
info->Reset = M313Reset;
AddExState(EXPREGS, 1, 0, "EXPR");
}

74
src/boards/super40in1.c Normal file
View File

@@ -0,0 +1,74 @@
/* FCEUmm - NES/Famicom Emulator
*
* 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
* 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
*/
/* added 2019-5-23
* BMC-WS Used for Super 40-in-1 multicart
* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_332 */
#include "mapinc.h"
static uint8 preg, creg;
static SFORMAT StateRegs[] =
{
{ &preg, 1, "PREG" },
{ &creg, 1, "CREG" },
{ 0 }
};
static void Sync(void) {
if (preg & 8) {
setprg16(0x8000, preg & 7);
setprg16(0xc000, preg & 7);
}
else
setprg32(0x8000, (preg & 6) >> 1);
setchr8(creg);
setmirror(((preg >> 4) & 1) ^ 1);
}
static DECLFW(BMCWSWrite) {
if (preg & 0x20)
return;
switch (A & 1) {
case 0: preg = V; Sync(); break;
case 1: creg = V; Sync(); break;
}
}
static void MBMCWSPower(void) {
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x6000, 0x6001, BMCWSWrite);
}
static void BMCWSReset(void) {
}
static void StateRestore(int version) {
Sync();
}
void BMCWS_Init(CartInfo *info) {
info->Reset = BMCWSReset;
info->Power = MBMCWSPower;
GameStateRestore = StateRestore;
AddExState(&StateRegs, ~0, 0, 0);
}

View File

@@ -30,23 +30,12 @@ static SFORMAT StateRegs[] =
static void Sync(void) { static void Sync(void) {
setchr8(0); setchr8(0);
if (PRGptr[1]) setprg8(0x6000, (((cmd0 & 0xF) << 4) | 0xF) + 4);
setprg8r((cmd0 & 0xC) >> 2, 0x6000, ((cmd0 & 0x3) << 4) | 0xF);
else
setprg8(0x6000, (((cmd0 & 0xF) << 4) | 0xF) + 4);
if (cmd0 & 0x10) { 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(0x8000, (((cmd0 & 0xF) << 3) | (cmd1 & 7)) + 2);
setprg16(0xc000, (((cmd0 & 0xF) << 3) | 7) + 2); setprg16(0xc000, (((cmd0 & 0xF) << 3) | 7) + 2);
}
} else } else
if (PRGptr[4]) setprg32(0x8000, 0);
setprg32r(4, 0x8000, 0);
else
setprg32(0x8000, 0);
setmirror(((cmd0 & 0x20) >> 5) ^ 1); setmirror(((cmd0 & 0x20) >> 5) ^ 1);
} }

View File

@@ -217,9 +217,9 @@ void UNROM512_Init(CartInfo *info) {
flash_bank = 0; flash_bank = 0;
flash_save = info->battery; flash_save = info->battery;
if (info->vram_size == 8192) if (info->chrRam == 8192)
chrram_mask = 0; chrram_mask = 0;
else if (info->vram_size == 16384) else if (info->chrRam == 16384)
chrram_mask = 0x20; chrram_mask = 0x20;
else else
chrram_mask = 0x60; chrram_mask = 0x60;
@@ -236,7 +236,7 @@ void UNROM512_Init(CartInfo *info) {
SetupCartMirroring(MI_0, 0, NULL); SetupCartMirroring(MI_0, 0, NULL);
break; break;
case 3: /* hard four screen, last 8k of 32k RAM (flags: 4-screen + vertical) */ 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; break;
} }
bus_conflict = !info->battery; bus_conflict = !info->battery;

View File

@@ -31,7 +31,6 @@ static uint8 prgreg[2], chrreg[8];
static uint16 chrhi[8]; static uint16 chrhi[8];
static uint8 regcmd, irqcmd, mirr, big_bank; static uint8 regcmd, irqcmd, mirr, big_bank;
static uint16 acount = 0; static uint16 acount = 0;
static uint16 weirdo = 0;
static uint8 *WRAM = NULL; static uint8 *WRAM = NULL;
static uint32 WRAMSIZE; static uint32 WRAMSIZE;
@@ -65,15 +64,8 @@ static void Sync(void) {
setchr8(0); setchr8(0);
else { else {
uint8 i; uint8 i;
/* if (!weirdo) */ for (i = 0; i < 8; i++)
for (i = 0; i < 8; i++) setchr1(i << 10, (chrhi[i] | chrreg[i]) >> is22);
setchr1(i << 10, (chrhi[i] | chrreg[i]) >> is22);
/* else {
setchr1(0x0000, 0xFC);
setchr1(0x0400, 0xFD);
setchr1(0x0800, 0xFF);
weirdo--;
} */
} }
switch (mirr & 0x3) { switch (mirr & 0x3) {
case 0: setmirror(MI_V); break; case 0: setmirror(MI_V); break;
@@ -158,14 +150,20 @@ static DECLFW(M23Write) {
VRC24Write(A, V); VRC24Write(A, V);
} }
static void M21Power(void) { static void VRC24PowerCommon(void (*WRITEFUNC)(uint32 A, uint8 V)) {
Sync(); Sync();
setprg8r(0x10, 0x6000, 0); setprg8r(0x10, 0x6000, 0); /* Only two Goemon games are have battery backed RAM, three more shooters
* (Parodius Da!, Gradius 2 and Crisis Force uses 2k or SRAM at 6000-67FF only
*/
SetReadHandler(0x6000, 0x7FFF, CartBR); SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW); SetWriteHandler(0x6000, 0x7FFF, CartBW);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
SetReadHandler(0x8000, 0xFFFF, CartBR); SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M21Write); SetWriteHandler(0x8000, 0xFFFF, WRITEFUNC);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
}
static void M21Power(void) {
VRC24PowerCommon(M21Write);
} }
static void M22Power(void) { static void M22Power(void) {
@@ -176,26 +174,12 @@ static void M22Power(void) {
static void M23Power(void) { static void M23Power(void) {
big_bank = 0x20; big_bank = 0x20;
Sync(); VRC24PowerCommon(M23Write);
setprg8r(0x10, 0x6000, 0); /* Only two Goemon games are have battery backed RAM, three more shooters
* (Parodius Da!, Gradius 2 and Crisis Force uses 2k or SRAM at 6000-67FF only
*/
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M23Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
} }
static void M25Power(void) { static void M25Power(void) {
big_bank = 0x20; big_bank = 0x20;
Sync(); VRC24PowerCommon(M22Write);
setprg8r(0x10, 0x6000, 0);
SetReadHandler(0x6000, 0x7FFF, CartBR);
SetWriteHandler(0x6000, 0x7FFF, CartBW);
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x8000, 0xFFFF, M22Write);
FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM);
} }
void FP_FASTAPASS(1) VRC24IRQHook(int a) { void FP_FASTAPASS(1) VRC24IRQHook(int a) {
@@ -279,3 +263,99 @@ void UNLT230_Init(CartInfo *info) {
info->Power = M23Power; info->Power = M23Power;
VRC24_Init(info); VRC24_Init(info);
} }
/* -------------------- UNL-TH2131-1 -------------------- */
/* https://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_308
* NES 2.0 Mapper 308 is used for a bootleg version of the Sunsoft game Batman
* similar to Mapper 23 Submapper 3) with custom IRQ functionality.
* UNIF board name is UNL-TH2131-1.
*/
static DECLFW(TH2131Write) {
switch (A & 0xF003) {
case 0xF000: X6502_IRQEnd(FCEU_IQEXT); IRQa = 0; IRQCount = 0; break;
case 0xF001: IRQa = 1; break;
case 0xF003: IRQLatch = (V & 0xF0) >> 4; break;
}
}
void FP_FASTAPASS(1) TH2131IRQHook(int a) {
int count;
if (!IRQa)
return;
for (count = 0; count < a; count++) {
IRQCount++;
if ((IRQCount & 0x0FFF) == 2048)
IRQLatch--;
if (!IRQLatch && (IRQCount & 0x0FFF) < 2048)
X6502_IRQBegin(FCEU_IQEXT);
}
}
static void TH2131Power(void) {
VRC24PowerCommon(VRC24Write);
SetWriteHandler(0xF000, 0xFFFF, TH2131Write);
}
void UNLTH21311_Init(CartInfo *info) {
info->Power = TH2131Power;
VRC24_Init(info);
MapIRQHook = TH2131IRQHook;
}
/* -------------------- UNL-KS7021A -------------------- */
/* http://wiki.nesdev.com/w/index.php/NES_2.0_Mapper_525
* NES 2.0 Mapper 525 is used for a bootleg version of versions of Contra and 月風魔伝 (Getsu Fūma Den).
* Its similar to Mapper 23 Submapper 3) with non-nibblized CHR-ROM bank registers.
*/
static DECLFW(KS7021AWrite) {
switch (A & 0xB000) {
case 0xB000: chrreg[A & 0x07] = V; Sync(); break;
}
}
static void KS7021APower(void) {
VRC24PowerCommon(VRC24Write);
SetWriteHandler(0xB000, 0xBFFF, KS7021AWrite);
}
void UNLKS7021A_Init(CartInfo *info) {
info->Power = KS7021APower;
VRC24_Init(info);
}
/* -------------------- BTL-900218 -------------------- */
/* http://wiki.nesdev.com/w/index.php/UNIF/900218
* NES 2.0 Mapper 524 describes the PCB used for the pirate port Lord of King or Axe of Fight.
* UNIF board name is BTL-900218.
*/
static DECLFW(BTL900218Write) {
switch (A & 0xF00C) {
case 0xF008: IRQa = 1; break;
case 0xF00C: X6502_IRQEnd(FCEU_IQEXT); IRQa = 0; IRQCount = 0; break;
}
}
void FP_FASTAPASS(1) BTL900218IRQHook(int a) {
if (!IRQa)
return;
IRQCount += a;
if (IRQCount & 1024)
X6502_IRQBegin(FCEU_IQEXT);
}
static void BTL900218Power(void) {
VRC24PowerCommon(VRC24Write);
SetWriteHandler(0xF000, 0xFFFF, BTL900218Write);
}
void BTL900218_Init(CartInfo *info) {
info->Power = BTL900218Power;
VRC24_Init(info);
MapIRQHook = BTL900218IRQHook;
}

View File

@@ -53,6 +53,9 @@ static int PRGram[32];
uint8 *PRGptr[32]; uint8 *PRGptr[32];
uint8 *CHRptr[32]; uint8 *CHRptr[32];
uint32 PRGchip_max;
uint32 CHRchip_max;
uint32 PRGsize[32]; uint32 PRGsize[32];
uint32 CHRsize[32]; uint32 CHRsize[32];
@@ -104,6 +107,8 @@ void ResetCartMapping(void) {
for (x = 0; x < 8; x++) { for (x = 0; x < 8; x++) {
MMC5SPRVPage[x] = MMC5BGVPage[x] = VPageR[x] = nothing - 0x400 * x; MMC5SPRVPage[x] = MMC5BGVPage[x] = VPageR[x] = nothing - 0x400 * x;
} }
PRGchip_max = 0;
CHRchip_max = 0;
} }
void SetupCartPRGMapping(int chip, uint8 *p, uint32 size, int ram) { void SetupCartPRGMapping(int chip, uint8 *p, uint32 size, int ram) {

View File

@@ -10,6 +10,9 @@ typedef struct {
uint32 SaveGameLen[4]; /* How much memory to save/load. */ uint32 SaveGameLen[4]; /* How much memory to save/load. */
/* Set by iNES/UNIF loading code. */ /* 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. int mirror; /* As set in the header or chunk.
* iNES/UNIF specific. Intended * iNES/UNIF specific. Intended
* to help support games like "Karnov" * to help support games like "Karnov"
@@ -17,7 +20,14 @@ typedef struct {
* set to mapper 4. * set to mapper 4.
*/ */
int battery; /* Presence of an actual battery. */ 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]; uint8 MD5[16];
uint32 CRC32; /* Should be set by the iNES/UNIF loading uint32 CRC32; /* Should be set by the iNES/UNIF loading
* code, used by mapper/board code, maybe * code, used by mapper/board code, maybe
@@ -39,6 +49,9 @@ DECLFW(CartBW);
extern uint8 *PRGptr[32]; extern uint8 *PRGptr[32];
extern uint8 *CHRptr[32]; extern uint8 *CHRptr[32];
extern uint32 PRGchip_max;
extern uint32 CHRchip_max;
extern uint32 PRGsize[32]; extern uint32 PRGsize[32];
extern uint32 CHRsize[32]; extern uint32 CHRsize[32];

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2010-2017 The RetroArch team /* Copyright (C) 2010-2018 The RetroArch team
* *
* --------------------------------------------------------------------------------------- * ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (compat_snprintf.c). * The following license statement only applies to this file (compat_snprintf.c).
@@ -23,9 +23,7 @@
/* THIS FILE HAS NOT BEEN VALIDATED ON PLATFORMS BESIDES MSVC */ /* THIS FILE HAS NOT BEEN VALIDATED ON PLATFORMS BESIDES MSVC */
#ifdef _MSC_VER #ifdef _MSC_VER
#include <retro_common.h> #include <stdio.h>
#include <stdio.h> /* added for _vsnprintf_s and _vscprintf on VS2015 and VS2017 */
#include <stdarg.h> #include <stdarg.h>
#if _MSC_VER < 1800 #if _MSC_VER < 1800
@@ -53,14 +51,23 @@ int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list
int count = -1; int count = -1;
if (size != 0) if (size != 0)
{
#if (_MSC_VER <= 1310) #if (_MSC_VER <= 1310)
count = _vsnprintf(outBuf, size, format, ap); count = _vsnprintf(outBuf, size - 1, format, ap);
#else #else
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); count = _vsnprintf_s(outBuf, size, size - 1, format, ap);
#endif #endif
}
if (count == -1) if (count == -1)
count = _vscprintf(format, ap); count = _vscprintf(format, ap);
if (count == size)
{
/* there was no room for a NULL, so truncate the last character */
outBuf[size - 1] = '\0';
}
return count; return count;
} }

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2010-2017 The RetroArch team /* Copyright (C) 2010-2018 The RetroArch team
* *
* --------------------------------------------------------------------------------------- * ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (msvc.h). * The following license statement only applies to this file (msvc.h).
@@ -39,8 +39,8 @@ extern "C" {
int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...); int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...);
#endif #endif
/* Pre-MSVC 2010 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */ /* Pre-MSVC 2008 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */
#if _MSC_VER < 1600 #if _MSC_VER < 1500
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#ifndef vsnprintf #ifndef vsnprintf
@@ -56,6 +56,8 @@ extern "C" {
#undef UNICODE /* Do not bother with UNICODE at this time. */ #undef UNICODE /* Do not bother with UNICODE at this time. */
#include <direct.h> #include <direct.h>
#include <stddef.h> #include <stddef.h>
#define _USE_MATH_DEFINES
#include <math.h> #include <math.h>
/* Python headers defines ssize_t and sets HAVE_SSIZE_T. /* Python headers defines ssize_t and sets HAVE_SSIZE_T.
@@ -125,4 +127,3 @@ typedef int ssize_t;
#endif #endif
#endif #endif

View File

@@ -67,7 +67,6 @@ extern "C" {
# endif # endif
#endif #endif
/* 7.18.1 Integer types. */ /* 7.18.1 Integer types. */
/* 7.18.1.1 Exact-width integer types. */ /* 7.18.1.1 Exact-width integer types. */
@@ -94,7 +93,6 @@ extern "C" {
typedef signed __int64 int64_t; typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
/* 7.18.1.2 Minimum-width integer types. */ /* 7.18.1.2 Minimum-width integer types. */
typedef int8_t int_least8_t; typedef int8_t int_least8_t;
typedef int16_t int_least16_t; typedef int16_t int_least16_t;
@@ -255,4 +253,3 @@ typedef uint64_t uintmax_t;
#endif #endif
#endif #endif

View File

@@ -202,6 +202,8 @@ extern "C" {
#define RETRO_DEVICE_ID_JOYPAD_L3 14 #define RETRO_DEVICE_ID_JOYPAD_L3 14
#define RETRO_DEVICE_ID_JOYPAD_R3 15 #define RETRO_DEVICE_ID_JOYPAD_R3 15
#define RETRO_DEVICE_ID_JOYPAD_MASK 256
/* Index / Id values for ANALOG device. */ /* Index / Id values for ANALOG device. */
#define RETRO_DEVICE_INDEX_ANALOG_LEFT 0 #define RETRO_DEVICE_INDEX_ANALOG_LEFT 0
#define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1 #define RETRO_DEVICE_INDEX_ANALOG_RIGHT 1
@@ -248,6 +250,7 @@ extern "C" {
#define RETRO_DEVICE_ID_POINTER_X 0 #define RETRO_DEVICE_ID_POINTER_X 0
#define RETRO_DEVICE_ID_POINTER_Y 1 #define RETRO_DEVICE_ID_POINTER_Y 1
#define RETRO_DEVICE_ID_POINTER_PRESSED 2 #define RETRO_DEVICE_ID_POINTER_PRESSED 2
#define RETRO_DEVICE_ID_POINTER_COUNT 3
/* Returned from retro_get_region(). */ /* Returned from retro_get_region(). */
#define RETRO_REGION_NTSC 0 #define RETRO_REGION_NTSC 0
@@ -274,6 +277,7 @@ enum retro_language
RETRO_LANGUAGE_VIETNAMESE = 15, RETRO_LANGUAGE_VIETNAMESE = 15,
RETRO_LANGUAGE_ARABIC = 16, RETRO_LANGUAGE_ARABIC = 16,
RETRO_LANGUAGE_GREEK = 17, RETRO_LANGUAGE_GREEK = 17,
RETRO_LANGUAGE_TURKISH = 18,
RETRO_LANGUAGE_LAST, RETRO_LANGUAGE_LAST,
/* Ensure sizeof(enum) == sizeof(int) */ /* Ensure sizeof(enum) == sizeof(int) */
@@ -485,11 +489,13 @@ enum retro_mod
/* Environment commands. */ /* Environment commands. */
#define RETRO_ENVIRONMENT_SET_ROTATION 1 /* const unsigned * -- #define RETRO_ENVIRONMENT_SET_ROTATION 1 /* const unsigned * --
* Sets screen rotation of graphics. * Sets screen rotation of graphics.
* Is only implemented if rotation can be accelerated by hardware.
* Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180, * Valid values are 0, 1, 2, 3, which rotates screen by 0, 90, 180,
* 270 degrees counter-clockwise respectively. * 270 degrees counter-clockwise respectively.
*/ */
#define RETRO_ENVIRONMENT_GET_OVERSCAN 2 /* bool * -- #define RETRO_ENVIRONMENT_GET_OVERSCAN 2 /* bool * --
* NOTE: As of 2019 this callback is considered deprecated in favor of
* using core options to manage overscan in a more nuanced, core-specific way.
*
* Boolean value whether or not the implementation should use overscan, * Boolean value whether or not the implementation should use overscan,
* or crop away overscan. * or crop away overscan.
*/ */
@@ -608,7 +614,7 @@ enum retro_mod
* Afterward it may be called again for the core to communicate * Afterward it may be called again for the core to communicate
* updated options to the frontend, but the number of core * updated options to the frontend, but the number of core
* options must not change from the number in the initial call. * options must not change from the number in the initial call.
* *
* 'data' points to an array of retro_variable structs * 'data' points to an array of retro_variable structs
* terminated by a { NULL, NULL } element. * terminated by a { NULL, NULL } element.
* retro_variable::key should be namespaced to not collide * retro_variable::key should be namespaced to not collide
@@ -875,12 +881,12 @@ enum retro_mod
* types already defined in the libretro API. * types already defined in the libretro API.
* *
* The core must pass an array of const struct retro_controller_info which * The core must pass an array of const struct retro_controller_info which
* is terminated with a blanked out struct. Each element of the * is terminated with a blanked out struct. Each element of the
* retro_controller_info struct corresponds to the ascending port index * retro_controller_info struct corresponds to the ascending port index
* that is passed to retro_set_controller_port_device() when that function * that is passed to retro_set_controller_port_device() when that function
* is called to indicate to the core that the frontend has changed the * is called to indicate to the core that the frontend has changed the
* active device subclass. SEE ALSO: retro_set_controller_port_device() * active device subclass. SEE ALSO: retro_set_controller_port_device()
* *
* The ascending input port indexes provided by the core in the struct * The ascending input port indexes provided by the core in the struct
* are generally presented by frontends as ascending User # or Player #, * are generally presented by frontends as ascending User # or Player #,
* such as Player 1, Player 2, Player 3, etc. Which device subclasses are * such as Player 1, Player 2, Player 3, etc. Which device subclasses are
@@ -892,7 +898,7 @@ enum retro_mod
* User or Player, beginning with the generic Libretro device that the * User or Player, beginning with the generic Libretro device that the
* subclasses are derived from. The second inner element of each entry is the * subclasses are derived from. The second inner element of each entry is the
* total number of subclasses that are listed in the retro_controller_description. * total number of subclasses that are listed in the retro_controller_description.
* *
* NOTE: Even if special device types are set in the libretro core, * NOTE: Even if special device types are set in the libretro core,
* libretro should only poll input based on the base input device types. * libretro should only poll input based on the base input device types.
*/ */
@@ -1079,10 +1085,173 @@ enum retro_mod
* fastforwarding mode. * fastforwarding mode.
*/ */
#define RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE (50 | RETRO_ENVIRONMENT_EXPERIMENTAL)
/* float * --
* Float value that lets us know what target refresh rate
* is curently in use by the frontend.
*
* The core can use the returned value to set an ideal
* refresh rate/framerate.
*/
#define RETRO_ENVIRONMENT_GET_INPUT_BITMASKS (51 | RETRO_ENVIRONMENT_EXPERIMENTAL)
/* bool * --
* Boolean value that indicates whether or not the frontend supports
* input bitmasks being returned by retro_input_state_t. The advantage
* of this is that retro_input_state_t has to be only called once to
* grab all button states instead of multiple times.
*
* If it returns true, you can pass RETRO_DEVICE_ID_JOYPAD_MASK as 'id'
* to retro_input_state_t (make sure 'device' is set to RETRO_DEVICE_JOYPAD).
* It will return a bitmask of all the digital buttons.
*/
#define RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION 52
/* unsigned * --
* Unsigned value is the API version number of the core options
* interface supported by the frontend. If callback return false,
* API version is assumed to be 0.
*
* In legacy code, core options are set by passing an array of
* retro_variable structs to RETRO_ENVIRONMENT_SET_VARIABLES.
* This may be still be done regardless of the core options
* interface version.
*
* If version is 1 however, core options may instead be set by
* passing an array of retro_core_option_definition structs to
* RETRO_ENVIRONMENT_SET_CORE_OPTIONS, or a 2D array of
* retro_core_option_definition structs to RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL.
* This allows the core to additionally set option sublabel information
* and/or provide localisation support.
*/
#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS 53
/* const struct retro_core_option_definition ** --
* Allows an implementation to signal the environment
* which variables it might want to check for later using
* GET_VARIABLE.
* This allows the frontend to present these variables to
* a user dynamically.
* This should only be called if RETRO_ENVIRONMENT_GET_ENHANCED_CORE_OPTIONS
* returns an API version of 1.
* This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES.
* This should be called the first time as early as
* possible (ideally in retro_set_environment).
* Afterwards it may be called again for the core to communicate
* updated options to the frontend, but the number of core
* options must not change from the number in the initial call.
*
* 'data' points to an array of retro_core_option_definition structs
* terminated by a { NULL, NULL, NULL, {{0}}, NULL } element.
* retro_core_option_definition::key should be namespaced to not collide
* with other implementations' keys. e.g. A core called
* 'foo' should use keys named as 'foo_option'.
* retro_core_option_definition::desc should contain a human readable
* description of the key.
* retro_core_option_definition::info should contain any additional human
* readable information text that a typical user may need to
* understand the functionality of the option.
* retro_core_option_definition::values is an array of retro_core_option_value
* structs terminated by a { NULL, NULL } element.
* > retro_core_option_definition::values[index].value is an expected option
* value.
* > retro_core_option_definition::values[index].label is a human readable
* label used when displaying the value on screen. If NULL,
* the value itself is used.
* retro_core_option_definition::default_value is the default core option
* setting. It must match one of the expected option values in the
* retro_core_option_definition::values array. If it does not, or the
* default value is NULL, the first entry in the
* retro_core_option_definition::values array is treated as the default.
*
* The number of possible options should be very limited,
* and must be less than RETRO_NUM_CORE_OPTION_VALUES_MAX.
* i.e. it should be feasible to cycle through options
* without a keyboard.
*
* First entry should be treated as a default.
*
* Example entry:
* {
* "foo_option",
* "Speed hack coprocessor X",
* "Provides increased performance at the expense of reduced accuracy",
* {
* { "false", NULL },
* { "true", NULL },
* { "unstable", "Turbo (Unstable)" },
* { NULL, NULL },
* },
* "false"
* }
*
* Only strings are operated on. The possible values will
* generally be displayed and stored as-is by the frontend.
*/
#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL 54
/* const struct retro_core_options_intl * --
* Allows an implementation to signal the environment
* which variables it might want to check for later using
* GET_VARIABLE.
* This allows the frontend to present these variables to
* a user dynamically.
* This should only be called if RETRO_ENVIRONMENT_GET_ENHANCED_CORE_OPTIONS
* returns an API version of 1.
* This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES.
* This should be called the first time as early as
* possible (ideally in retro_set_environment).
* Afterwards it may be called again for the core to communicate
* updated options to the frontend, but the number of core
* options must not change from the number in the initial call.
*
* This is fundamentally the same as RETRO_ENVIRONMENT_SET_CORE_OPTIONS,
* with the addition of localisation support. The description of the
* RETRO_ENVIRONMENT_SET_CORE_OPTIONS callback should be consulted
* for further details.
*
* 'data' points to a retro_core_options_intl struct.
*
* retro_core_options_intl::us is a pointer to an array of
* retro_core_option_definition structs defining the US English
* core options implementation. It must point to a valid array.
*
* retro_core_options_intl::local is a pointer to an array of
* retro_core_option_definition structs defining core options for
* the current frontend language. It may be NULL (in which case
* retro_core_options_intl::us is used by the frontend). Any items
* missing from this array will be read from retro_core_options_intl::us
* instead.
*
* NOTE: Default core option values are always taken from the
* retro_core_options_intl::us array. Any default values in
* retro_core_options_intl::local array will be ignored.
*/
#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY 55
/* struct retro_core_option_display * --
*
* Allows an implementation to signal the environment to show
* or hide a variable when displaying core options. This is
* considered a *suggestion*. The frontend is free to ignore
* this callback, and its implementation not considered mandatory.
*
* 'data' points to a retro_core_option_display struct
*
* retro_core_option_display::key is a variable identifier
* which has already been set by SET_VARIABLES/SET_CORE_OPTIONS.
*
* retro_core_option_display::visible is a boolean, specifying
* whether variable should be displayed
*
* Note that all core option variables will be set visible by
* default when calling SET_VARIABLES/SET_CORE_OPTIONS.
*/
/* VFS functionality */ /* VFS functionality */
/* File paths: /* File paths:
* File paths passed as parameters when using this api shall be well formed unix-style, * File paths passed as parameters when using this API shall be well formed UNIX-style,
* using "/" (unquoted forward slash) as directory separator regardless of the platform's native separator. * using "/" (unquoted forward slash) as directory separator regardless of the platform's native separator.
* Paths shall also include at least one forward slash ("game.bin" is an invalid path, use "./game.bin" instead). * Paths shall also include at least one forward slash ("game.bin" is an invalid path, use "./game.bin" instead).
* Other than the directory separator, cores shall not make assumptions about path format: * Other than the directory separator, cores shall not make assumptions about path format:
@@ -1100,6 +1269,10 @@ enum retro_mod
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
struct retro_vfs_file_handle; struct retro_vfs_file_handle;
/* Opaque directory handle
* Introduced in VFS API v3 */
struct retro_vfs_dir_handle;
/* File open flags /* File open flags
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
#define RETRO_VFS_FILE_ACCESS_READ (1 << 0) /* Read only mode */ #define RETRO_VFS_FILE_ACCESS_READ (1 << 0) /* Read only mode */
@@ -1119,6 +1292,12 @@ struct retro_vfs_file_handle;
#define RETRO_VFS_SEEK_POSITION_CURRENT 1 #define RETRO_VFS_SEEK_POSITION_CURRENT 1
#define RETRO_VFS_SEEK_POSITION_END 2 #define RETRO_VFS_SEEK_POSITION_END 2
/* stat() result flags
* Introduced in VFS API v3 */
#define RETRO_VFS_STAT_IS_VALID (1 << 0)
#define RETRO_VFS_STAT_IS_DIRECTORY (1 << 1)
#define RETRO_VFS_STAT_IS_CHARACTER_SPECIAL (1 << 2)
/* Get path from opaque handle. Returns the exact same path passed to file_open when getting the handle /* Get path from opaque handle. Returns the exact same path passed to file_open when getting the handle
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
typedef const char *(RETRO_CALLCONV *retro_vfs_get_path_t)(struct retro_vfs_file_handle *stream); typedef const char *(RETRO_CALLCONV *retro_vfs_get_path_t)(struct retro_vfs_file_handle *stream);
@@ -1128,7 +1307,7 @@ typedef const char *(RETRO_CALLCONV *retro_vfs_get_path_t)(struct retro_vfs_file
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
typedef struct retro_vfs_file_handle *(RETRO_CALLCONV *retro_vfs_open_t)(const char *path, unsigned mode, unsigned hints); typedef struct retro_vfs_file_handle *(RETRO_CALLCONV *retro_vfs_open_t)(const char *path, unsigned mode, unsigned hints);
/* Close the file and release its resources. Must be called if open_file returns non-NULL. Returns 0 on succes, -1 on failure. /* Close the file and release its resources. Must be called if open_file returns non-NULL. Returns 0 on success, -1 on failure.
* Whether the call succeeds ot not, the handle passed as parameter becomes invalid and should no longer be used. * Whether the call succeeds ot not, the handle passed as parameter becomes invalid and should no longer be used.
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
typedef int (RETRO_CALLCONV *retro_vfs_close_t)(struct retro_vfs_file_handle *stream); typedef int (RETRO_CALLCONV *retro_vfs_close_t)(struct retro_vfs_file_handle *stream);
@@ -1141,7 +1320,7 @@ typedef int64_t (RETRO_CALLCONV *retro_vfs_size_t)(struct retro_vfs_file_handle
* Introduced in VFS API v2 */ * Introduced in VFS API v2 */
typedef int64_t (RETRO_CALLCONV *retro_vfs_truncate_t)(struct retro_vfs_file_handle *stream, int64_t length); typedef int64_t (RETRO_CALLCONV *retro_vfs_truncate_t)(struct retro_vfs_file_handle *stream, int64_t length);
/* Get the current read / write position for the file. Returns - 1 for error. /* Get the current read / write position for the file. Returns -1 for error.
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
typedef int64_t (RETRO_CALLCONV *retro_vfs_tell_t)(struct retro_vfs_file_handle *stream); typedef int64_t (RETRO_CALLCONV *retro_vfs_tell_t)(struct retro_vfs_file_handle *stream);
@@ -1169,6 +1348,39 @@ typedef int (RETRO_CALLCONV *retro_vfs_remove_t)(const char *path);
* Introduced in VFS API v1 */ * Introduced in VFS API v1 */
typedef int (RETRO_CALLCONV *retro_vfs_rename_t)(const char *old_path, const char *new_path); typedef int (RETRO_CALLCONV *retro_vfs_rename_t)(const char *old_path, const char *new_path);
/* Stat the specified file. Retruns a bitmask of RETRO_VFS_STAT_* flags, none are set if path was not valid.
* Additionally stores file size in given variable, unless NULL is given.
* Introduced in VFS API v3 */
typedef int (RETRO_CALLCONV *retro_vfs_stat_t)(const char *path, int32_t *size);
/* Create the specified directory. Returns 0 on success, -1 on unknown failure, -2 if already exists.
* Introduced in VFS API v3 */
typedef int (RETRO_CALLCONV *retro_vfs_mkdir_t)(const char *dir);
/* Open the specified directory for listing. Returns the opaque dir handle, or NULL for error.
* Support for the include_hidden argument may vary depending on the platform.
* Introduced in VFS API v3 */
typedef struct retro_vfs_dir_handle *(RETRO_CALLCONV *retro_vfs_opendir_t)(const char *dir, bool include_hidden);
/* Read the directory entry at the current position, and move the read pointer to the next position.
* Returns true on success, false if already on the last entry.
* Introduced in VFS API v3 */
typedef bool (RETRO_CALLCONV *retro_vfs_readdir_t)(struct retro_vfs_dir_handle *dirstream);
/* Get the name of the last entry read. Returns a string on success, or NULL for error.
* The returned string pointer is valid until the next call to readdir or closedir.
* Introduced in VFS API v3 */
typedef const char *(RETRO_CALLCONV *retro_vfs_dirent_get_name_t)(struct retro_vfs_dir_handle *dirstream);
/* Check if the last entry read was a directory. Returns true if it was, false otherwise (or on error).
* Introduced in VFS API v3 */
typedef bool (RETRO_CALLCONV *retro_vfs_dirent_is_dir_t)(struct retro_vfs_dir_handle *dirstream);
/* Close the directory and release its resources. Must be called if opendir returns non-NULL. Returns 0 on success, -1 on failure.
* Whether the call succeeds ot not, the handle passed as parameter becomes invalid and should no longer be used.
* Introduced in VFS API v3 */
typedef int (RETRO_CALLCONV *retro_vfs_closedir_t)(struct retro_vfs_dir_handle *dirstream);
struct retro_vfs_interface struct retro_vfs_interface
{ {
/* VFS API v1 */ /* VFS API v1 */
@@ -1185,6 +1397,14 @@ struct retro_vfs_interface
retro_vfs_rename_t rename; retro_vfs_rename_t rename;
/* VFS API v2 */ /* VFS API v2 */
retro_vfs_truncate_t truncate; retro_vfs_truncate_t truncate;
/* VFS API v3 */
retro_vfs_stat_t stat;
retro_vfs_mkdir_t mkdir;
retro_vfs_opendir_t opendir;
retro_vfs_readdir_t readdir;
retro_vfs_dirent_get_name_t dirent_get_name;
retro_vfs_dirent_is_dir_t dirent_is_dir;
retro_vfs_closedir_t closedir;
}; };
struct retro_vfs_interface_info struct retro_vfs_interface_info
@@ -1207,6 +1427,7 @@ enum retro_hw_render_interface_type
RETRO_HW_RENDER_INTERFACE_D3D10 = 2, RETRO_HW_RENDER_INTERFACE_D3D10 = 2,
RETRO_HW_RENDER_INTERFACE_D3D11 = 3, RETRO_HW_RENDER_INTERFACE_D3D11 = 3,
RETRO_HW_RENDER_INTERFACE_D3D12 = 4, RETRO_HW_RENDER_INTERFACE_D3D12 = 4,
RETRO_HW_RENDER_INTERFACE_GSKIT_PS2 = 5,
RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX RETRO_HW_RENDER_INTERFACE_DUMMY = INT_MAX
}; };
@@ -2272,6 +2493,64 @@ struct retro_variable
const char *value; const char *value;
}; };
struct retro_core_option_display
{
/* Variable to configure in RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY */
const char *key;
/* Specifies whether variable should be displayed
* when presenting core options to the user */
bool visible;
};
/* Maximum number of values permitted for a core option
* NOTE: This may be increased on a core-by-core basis
* if required (doing so has no effect on the frontend) */
#define RETRO_NUM_CORE_OPTION_VALUES_MAX 128
struct retro_core_option_value
{
/* Expected option value */
const char *value;
/* Human-readable value label. If NULL, value itself
* will be displayed by the frontend */
const char *label;
};
struct retro_core_option_definition
{
/* Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE. */
const char *key;
/* Human-readable core option description (used as menu label) */
const char *desc;
/* Human-readable core option information (used as menu sublabel) */
const char *info;
/* Array of retro_core_option_value structs, terminated by NULL */
struct retro_core_option_value values[RETRO_NUM_CORE_OPTION_VALUES_MAX];
/* Default core option value. Must match one of the values
* in the retro_core_option_value array, otherwise will be
* ignored */
const char *default_value;
};
struct retro_core_options_intl
{
/* Pointer to an array of retro_core_option_definition structs
* - US English implementation
* - Must point to a valid array */
struct retro_core_option_definition *us;
/* Pointer to an array of retro_core_option_definition structs
* - Implementation for current frontend language
* - May be NULL */
struct retro_core_option_definition *local;
};
struct retro_game_info struct retro_game_info
{ {
const char *path; /* Path to game, UTF-8 encoded. const char *path; /* Path to game, UTF-8 encoded.

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2010-2017 The RetroArch team /* Copyright (C) 2010-2018 The RetroArch team
* *
* --------------------------------------------------------------------------------------- * ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (retro_common.h). * The following license statement only applies to this file (retro_common.h).
@@ -34,4 +34,3 @@ in a public API, you may need this.
#include <compat/msvc.h> #include <compat/msvc.h>
#endif #endif

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2010-2017 The RetroArch team /* Copyright (C) 2010-2018 The RetroArch team
* *
* --------------------------------------------------------------------------------------- * ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (retro_common_api.h). * The following license statement only applies to this file (retro_common_api.h).
@@ -113,6 +113,5 @@ Of course, another school of thought is that you should do as little damage as p
in as few places as possible... in as few places as possible...
*/ */
/* _LIBRETRO_COMMON_RETRO_COMMON_API_H */ /* _LIBRETRO_COMMON_RETRO_COMMON_API_H */
#endif #endif

View File

@@ -0,0 +1,39 @@
/* Copyright (C) 2010-2018 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (retro_inline.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __LIBRETRO_SDK_INLINE_H
#define __LIBRETRO_SDK_INLINE_H
#ifndef INLINE
#if defined(_WIN32) || defined(__INTEL_COMPILER)
#define INLINE __inline
#elif defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L
#define INLINE inline
#elif defined(__GNUC__)
#define INLINE __inline__
#else
#define INLINE
#endif
#endif
#endif

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2010-2017 The RetroArch team /* Copyright (C) 2010-2018 The RetroArch team
* *
* --------------------------------------------------------------------------------------- * ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (memory_stream.h). * The following license statement only applies to this file (memory_stream.h).

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 2010-2017 The RetroArch team /* Copyright (C) 2010-2018 The RetroArch team
* *
* --------------------------------------------------------------------------------------- * ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (memory_stream.c). * The following license statement only applies to this file (memory_stream.c).

View File

@@ -29,6 +29,8 @@
#endif #endif
#include "libretro-common/include/streams/memory_stream.h" #include "libretro-common/include/streams/memory_stream.h"
#include "libretro_dipswitch.h"
#include "libretro_core_options.h"
#define MAX_PLAYERS 4 /* max supported players */ #define MAX_PLAYERS 4 /* max supported players */
#define MAX_PORTS 2 /* max controller ports, #define MAX_PORTS 2 /* max controller ports,
@@ -63,7 +65,7 @@ static retro_video_refresh_t video_cb = NULL;
static retro_input_poll_t poll_cb = NULL; static retro_input_poll_t poll_cb = NULL;
static retro_input_state_t input_cb = NULL; static retro_input_state_t input_cb = NULL;
static retro_audio_sample_batch_t audio_batch_cb = NULL; static retro_audio_sample_batch_t audio_batch_cb = NULL;
static retro_environment_t environ_cb = NULL; retro_environment_t environ_cb = NULL;
#ifdef PSP #ifdef PSP
static bool use_overscan; static bool use_overscan;
#else #else
@@ -77,7 +79,9 @@ static bool enable_4player = false;
static unsigned turbo_enabler[MAX_PLAYERS] = {0}; static unsigned turbo_enabler[MAX_PLAYERS] = {0};
static unsigned turbo_delay = 0; static unsigned turbo_delay = 0;
static unsigned input_type[MAX_PLAYERS + 1] = {0}; /* 4-players + famicom expansion */ static unsigned input_type[MAX_PLAYERS + 1] = {0}; /* 4-players + famicom expansion */
static unsigned lightgun_enabled = 1; /* 0=mouse 1=lightgun(default) */ enum RetroZapperInputModes{RetroLightgun, RetroMouse, RetroPointer};
static enum RetroZapperInputModes zappermode = RetroLightgun;
static unsigned show_advance_sound_options;
/* emulator-specific variables */ /* emulator-specific variables */
@@ -133,6 +137,7 @@ extern uint8 *XBuf;
extern CartInfo iNESCart; extern CartInfo iNESCart;
extern CartInfo UNIFCart; extern CartInfo UNIFCart;
extern int show_crosshair; extern int show_crosshair;
extern int option_ramstate;
/* emulator-specific callback functions */ /* emulator-specific callback functions */
@@ -561,6 +566,8 @@ struct st_palettes palettes[] = {
} }
}; };
static bool libretro_supports_bitmasks = false;
unsigned retro_api_version(void) unsigned retro_api_version(void)
{ {
return RETRO_API_VERSION; return RETRO_API_VERSION;
@@ -687,7 +694,7 @@ static unsigned fc_to_libretro(int d)
void retro_set_controller_port_device(unsigned port, unsigned device) void retro_set_controller_port_device(unsigned port, unsigned device)
{ {
if ((port < 5) && (input_type[port] != device)) if (port < 5)
{ {
if (port < 2) /* player 1-2 */ if (port < 2) /* player 1-2 */
{ {
@@ -737,39 +744,29 @@ void retro_set_controller_port_device(unsigned port, unsigned device)
} }
} }
static void set_variables(void)
{
unsigned i = 0, index = 0;
/* Initialize main core option struct */
for (i = 0; i < MAX_CORE_OPTIONS; i++)
option_defs_us[i] = option_defs_empty;
/* Write common core options to main struct */
while (option_defs_common[index].key) {
option_defs_us[index] = option_defs_common[index];
index++;
}
/* Append dipswitch settings to core options if available */
index += set_dipswitch_variables(index, option_defs_us);
option_defs_us[index] = option_defs_empty;
libretro_set_core_options(environ_cb);
}
void retro_set_environment(retro_environment_t cb) void retro_set_environment(retro_environment_t cb)
{ {
static const struct retro_variable vars[] = {
{ "fceumm_region", "Region Override; Auto|NTSC|PAL|Dendy" },
{ "fceumm_aspect", "Preferred aspect ratio; 8:7 PAR|4:3" },
{ "fceumm_palette", "Color Palette; default|asqrealc|nintendo-vc|rgb|yuv-v3|unsaturated-final|sony-cxa2025as-us|pal|bmf-final2|bmf-final3|smooth-fbx|composite-direct-fbx|pvm-style-d93-fbx|ntsc-hardware-fbx|nes-classic-fbx-fs|nescap|wavebeam|raw|custom" },
{ "fceumm_up_down_allowed", "Allow Opposing Directions; disabled|enabled" },
#ifdef PSP
{ "fceumm_overscan", "Crop Overscan; enabled|disabled" },
#else
{ "fceumm_overscan_h", "Crop Overscan (Horizontal); disabled|enabled" },
{ "fceumm_overscan_v", "Crop Overscan (Vertical); enabled|disabled" },
#endif
{ "fceumm_nospritelimit", "No Sprite Limit; disabled|enabled" },
{ "fceumm_sndvolume", "Sound Volume; 150|160|170|180|190|200|210|220|230|240|250|0|10|20|30|40|50|60|70|80|90|100|110|120|130|140" },
{ "fceumm_sndquality", "Sound Quality; Low|High|Very High" },
{ "fceumm_swapduty", "Swap Duty Cycles; disabled|enabled" },
#ifdef DEBUG
{ "fceumm_apu_1", "Enable Sound Channel 1 (Square 1); enabled|disabled" },
{ "fceumm_apu_2", "Enable Sound Channel 2 (Square 2); enabled|disabled" },
{ "fceumm_apu_3", "Enable Sound Channel 3 (Triangle); enabled|disabled" },
{ "fceumm_apu_4", "Enable Sound Channel 4 (Noise); enabled|disabled" },
{ "fceumm_apu_5", "Enable Sound Channel 5 (PCM); enabled|disabled" },
#endif
{ "fceumm_turbo_enable", "Turbo Enable; None|Player 1|Player 2|Both" },
{ "fceumm_turbo_delay", "Turbo Delay (in frames); 3|5|10|15|30|60|1|2" },
{ "fceumm_zapper_mode", "Zapper Mode; lightgun|mouse" },
{ "fceumm_show_crosshair", "Show Crosshair; enabled|disabled" },
{ "fceumm_overclocking", "Overclocking; disabled|2x-Postrender|2x-VBlank" },
{ "fceumm_ramstate", "RAM power up state (Restart); fill $ff|fill $00|random" },
{ NULL, NULL },
};
static const struct retro_controller_description pads1[] = { static const struct retro_controller_description pads1[] = {
{ "Auto", RETRO_DEVICE_AUTO }, { "Auto", RETRO_DEVICE_AUTO },
{ "Gamepad", RETRO_DEVICE_GAMEPAD }, { "Gamepad", RETRO_DEVICE_GAMEPAD },
@@ -816,8 +813,7 @@ void retro_set_environment(retro_environment_t cb)
}; };
environ_cb = cb; environ_cb = cb;
cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars); environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
} }
void retro_get_system_info(struct retro_system_info *info) void retro_get_system_info(struct retro_system_info *info)
@@ -876,19 +872,8 @@ void retro_init(void)
log_cb.log(RETRO_LOG_INFO, "Frontend supports RGB565 - will use that instead of XRGB1555.\n"); log_cb.log(RETRO_LOG_INFO, "Frontend supports RGB565 - will use that instead of XRGB1555.\n");
#endif #endif
/* initialize some of the default variables */ if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL))
#ifdef GEKKO libretro_supports_bitmasks = true;
sndsamplerate = 32000;
#else
sndsamplerate = 48000;
#endif
sndquality = 0;
sndvolume = 150;
swapDuty = 0;
/* Wii: initialize this or else last variable is passed through
* when loading another rom causing save state size change. */
serialize_size = 0;
} }
static void retro_set_custom_palette(void) static void retro_set_custom_palette(void)
@@ -1002,7 +987,8 @@ void retro_deinit (void)
#if defined(RENDER_GSKIT_PS2) #if defined(RENDER_GSKIT_PS2)
ps2 = NULL; ps2 = NULL;
#endif #endif
libretro_supports_bitmasks = false;
DPSW_Cleanup();
} }
void retro_reset(void) void retro_reset(void)
@@ -1016,16 +1002,6 @@ typedef struct
unsigned nes; unsigned nes;
} keymap; } keymap;
static const keymap bindmap[] = {
{ RETRO_DEVICE_ID_JOYPAD_A, JOY_A },
{ RETRO_DEVICE_ID_JOYPAD_B, JOY_B },
{ RETRO_DEVICE_ID_JOYPAD_SELECT, JOY_SELECT },
{ RETRO_DEVICE_ID_JOYPAD_START, JOY_START },
{ RETRO_DEVICE_ID_JOYPAD_UP, JOY_UP },
{ RETRO_DEVICE_ID_JOYPAD_DOWN, JOY_DOWN },
{ RETRO_DEVICE_ID_JOYPAD_LEFT, JOY_LEFT },
{ RETRO_DEVICE_ID_JOYPAD_RIGHT, JOY_RIGHT },
};
static const keymap turbomap[] = { static const keymap turbomap[] = {
{ RETRO_DEVICE_ID_JOYPAD_X, JOY_A }, { RETRO_DEVICE_ID_JOYPAD_X, JOY_A },
@@ -1049,6 +1025,18 @@ static void check_variables(bool startup)
char key[256]; char key[256];
int i, enable_apu; int i, enable_apu;
var.key = "fceumm_ramstate";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{
if (!strcmp(var.value, "random"))
option_ramstate = 2;
else if (!strcmp(var.value, "fill $00"))
option_ramstate = 1;
else
option_ramstate = 0;
}
var.key = "fceumm_palette"; var.key = "fceumm_palette";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
@@ -1161,8 +1149,9 @@ static void check_variables(bool startup)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{ {
if (!strcmp(var.value, "mouse")) lightgun_enabled = 0; if (!strcmp(var.value, "mouse")) zappermode = RetroMouse;
else lightgun_enabled = 1; /*default setting*/ else if (!strcmp(var.value, "touchscreen")) zappermode = RetroPointer;
else zappermode = RetroLightgun; /*default setting*/
} }
var.key = "fceumm_show_crosshair"; var.key = "fceumm_show_crosshair";
@@ -1216,8 +1205,6 @@ static void check_variables(bool startup)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{ {
unsigned i;
turbo_enabler[0] = 0; turbo_enabler[0] = 0;
turbo_enabler[1] = 0; turbo_enabler[1] = 0;
@@ -1292,7 +1279,8 @@ static void check_variables(bool startup)
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
{ {
sndvolume = atoi(var.value); int val = (int)(atof(var.value) * 25.6);
sndvolume = val;
FCEUD_SoundToggle(); FCEUD_SoundToggle();
} }
@@ -1333,6 +1321,7 @@ static void check_variables(bool startup)
set_apu_channels(0xff); set_apu_channels(0xff);
#endif #endif
update_dipswitch();
} }
static int mzx = 0, mzy = 0; static int mzx = 0, mzy = 0;
@@ -1353,7 +1342,7 @@ void get_mouse_input(unsigned port, uint32_t *zapdata)
max_height = 240; max_height = 240;
zapdata[2] = 0; /* reset click state */ zapdata[2] = 0; /* reset click state */
if (!lightgun_enabled) /* mouse device */ if (zappermode == RetroMouse) /* mouse device */
{ {
min_width = (adjx ? 8 : 0) + 1; min_width = (adjx ? 8 : 0) + 1;
min_height = (adjy ? 8 : 0) + 1; min_height = (adjy ? 8 : 0) + 1;
@@ -1379,6 +1368,27 @@ void get_mouse_input(unsigned port, uint32_t *zapdata)
if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT)) if (input_cb(port, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT))
zapdata[2] |= 0x2; zapdata[2] |= 0x2;
} }
else if (zappermode == RetroPointer) {
int offset_x = (adjx ? 0X8FF : 0);
int offset_y = (adjy ? 0X999 : 0);
int _x = input_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_X);
int _y = input_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_Y);
if (_x == 0 && _y == 0)
{
zapdata[0] = 0;
zapdata[1] = 0;
}
else
{
zapdata[0] = (_x + (0x7FFF + offset_x)) * max_width / ((0x7FFF + offset_x) * 2);
zapdata[1] = (_y + (0x7FFF + offset_y)) * max_height / ((0x7FFF + offset_y) * 2);
}
if (input_cb(port, RETRO_DEVICE_POINTER, 0, RETRO_DEVICE_ID_POINTER_PRESSED))
zapdata[2] |= 0x1;
}
else /* lightgun device */ else /* lightgun device */
{ {
int offset_x = (adjx ? 0X8FF : 0); int offset_x = (adjx ? 0X8FF : 0);
@@ -1440,9 +1450,45 @@ static void FCEUD_UpdateInput(void)
if (player_enabled) if (player_enabled)
{ {
for (i = 0; i < MAX_BUTTONS; i++) int16_t ret;
input_buf |= input_cb(player, RETRO_DEVICE_JOYPAD, 0,
bindmap[i].retro) ? bindmap[i].nes : 0; if (libretro_supports_bitmasks)
{
ret = input_cb(player, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_MASK);
if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_A))
input_buf |= JOY_A;
if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_B))
input_buf |= JOY_B;
if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_SELECT))
input_buf |= JOY_SELECT;
if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_START))
input_buf |= JOY_START;
if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_UP))
input_buf |= JOY_UP;
if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_DOWN))
input_buf |= JOY_DOWN;
if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_LEFT))
input_buf |= JOY_LEFT;
if (ret & (1 << RETRO_DEVICE_ID_JOYPAD_RIGHT))
input_buf |= JOY_RIGHT;
}
else
{
static const keymap bindmap[] = {
{ RETRO_DEVICE_ID_JOYPAD_A, JOY_A },
{ RETRO_DEVICE_ID_JOYPAD_B, JOY_B },
{ RETRO_DEVICE_ID_JOYPAD_SELECT, JOY_SELECT },
{ RETRO_DEVICE_ID_JOYPAD_START, JOY_START },
{ RETRO_DEVICE_ID_JOYPAD_UP, JOY_UP },
{ RETRO_DEVICE_ID_JOYPAD_DOWN, JOY_DOWN },
{ RETRO_DEVICE_ID_JOYPAD_LEFT, JOY_LEFT },
{ RETRO_DEVICE_ID_JOYPAD_RIGHT, JOY_RIGHT },
};
for (i = 0; i < MAX_BUTTONS; i++)
input_buf |= input_cb(player, RETRO_DEVICE_JOYPAD, 0,
bindmap[i].retro) ? bindmap[i].nes : 0;
}
/* Turbo A and Turbo B buttons are /* Turbo A and Turbo B buttons are
* mapped to Joypad X and Joypad Y * mapped to Joypad X and Joypad Y
@@ -1587,7 +1633,7 @@ static void retro_run_blit(uint8_t *gfx)
} }
if (ps2->interface_version != RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION) { if (ps2->interface_version != RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION) {
printf("HW render interface mismatch, expected %u, got %u!\n", printf("HW render interface mismatch, expected %u, got %u!\n",
RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION, ps2->interface_version); RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION, ps2->interface_version);
return; return;
} }
@@ -1597,9 +1643,9 @@ static void retro_run_blit(uint8_t *gfx)
ps2->coreTexture->PSM = GS_PSM_T8; ps2->coreTexture->PSM = GS_PSM_T8;
ps2->coreTexture->ClutPSM = GS_PSM_CT16; ps2->coreTexture->ClutPSM = GS_PSM_CT16;
ps2->coreTexture->Filter = GS_FILTER_LINEAR; ps2->coreTexture->Filter = GS_FILTER_LINEAR;
ps2->padding = (struct retro_hw_ps2_insets){ overscan_v ? 8.0f : 0.0f, ps2->padding = (struct retro_hw_ps2_insets){ overscan_v ? 8.0f : 0.0f,
overscan_h ? 8.0f : 0.0f, overscan_h ? 8.0f : 0.0f,
overscan_v ? 8.0f : 0.0f, overscan_v ? 8.0f : 0.0f,
overscan_h ? 8.0f : 0.0f}; overscan_h ? 8.0f : 0.0f};
} }
@@ -1985,7 +2031,6 @@ static char slash = '/';
#endif #endif
extern uint32_t iNESGameCRC32; extern uint32_t iNESGameCRC32;
extern int option_ramstate;
bool retro_load_game(const struct retro_game_info *game) bool retro_load_game(const struct retro_game_info *game)
{ {
@@ -2048,24 +2093,23 @@ bool retro_load_game(const struct retro_game_info *game)
struct retro_memory_descriptor descs[64]; struct retro_memory_descriptor descs[64];
struct retro_memory_map mmaps; struct retro_memory_map mmaps;
struct retro_variable var = {0};
if (!game) if (!game)
return false; return false;
var.value = 0; /* initialize some of the default variables */
var.key = "fceumm_ramstate"; #ifdef GEKKO
sndsamplerate = 32000;
#else
sndsamplerate = 48000;
#endif
sndquality = 0;
sndvolume = 150;
swapDuty = 0;
/* set this variable before calling PowerNES() */ /* Wii: initialize this or else last variable is passed through
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) * when loading another rom causing save state size change. */
{ serialize_size = 0;
if (!strcmp(var.value, "random"))
option_ramstate = 2;
else if (!strcmp(var.value, "fill $00"))
option_ramstate = 1;
else
option_ramstate = 0;
}
PowerNES(); PowerNES();
check_system_specs(); check_system_specs();
@@ -2103,7 +2147,7 @@ bool retro_load_game(const struct retro_game_info *game)
for (i = 0; i < MAX_PORTS; i++) { for (i = 0; i < MAX_PORTS; i++) {
FCEUI_SetInput(i, SI_GAMEPAD, &JSReturn, 0); FCEUI_SetInput(i, SI_GAMEPAD, &JSReturn, 0);
input_type[i] == RETRO_DEVICE_JOYPAD; input_type[i] = RETRO_DEVICE_JOYPAD;
} }
external_palette_exist = ipalette; external_palette_exist = ipalette;
@@ -2113,9 +2157,10 @@ bool retro_load_game(const struct retro_game_info *game)
is_PAL = retro_get_region(); /* Save current loaded region info */ is_PAL = retro_get_region(); /* Save current loaded region info */
retro_set_custom_palette(); retro_set_custom_palette();
FCEUD_SoundToggle(); FCEUD_SoundToggle();
set_variables();
check_variables(true); check_variables(true);
PowerNES();
FCEUI_DisableFourScore(1); FCEUI_DisableFourScore(1);

View File

@@ -0,0 +1,563 @@
#ifndef LIBRETRO_CORE_OPTIONS_H__
#define LIBRETRO_CORE_OPTIONS_H__
#include <stdlib.h>
#include <string.h>
#include <libretro.h>
#include <retro_inline.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
********************************
* Core Option Definitions
********************************
*/
/* RETRO_LANGUAGE_ENGLISH */
/* Default language:
* - All other languages must include the same keys and values
* - Will be used as a fallback in the event that frontend language
* is not available
* - Will be used as a fallback for any missing entries in
* frontend language definition */
#define MAX_CORE_OPTIONS 32
struct retro_core_option_definition option_defs_common[] = {
{
"fceumm_region",
"Region Override",
"Force core to use NTSC, PAL or Dendy region timings.",
{
{ "Auto", NULL },
{ "NTSC", NULL },
{ "PAL", NULL },
{ "Dendy", NULL },
{ NULL, NULL},
},
"Auto",
},
{
"fceumm_aspect",
"Preferred aspect ratio",
"Choose preferred aspect ratio.",
{
{ "8:7 PAR", NULL },
{ "4:3", NULL },
{ NULL, NULL},
},
"8:7 PAR",
},
{
"fceumm_palette",
"Color Palette",
"Choose from pre-generated palettes, a custom 64x3 palette from file or raw format (needs to use a nes-decoder shader).",
{
{ "default", NULL },
{ "asqrealc", NULL },
{ "nintendo-vc", NULL },
{ "rgb", NULL },
{ "yuv-v3", NULL },
{ "unsaturated-final", NULL },
{ "sony-cxa2025as-us", NULL },
{ "pal", NULL },
{ "bmf-final2", NULL },
{ "bmf-final3", NULL },
{ "smooth-fbx", NULL },
{ "composite-direct-fbx", NULL },
{ "pvm-style-d93-fbx", NULL },
{ "ntsc-hardware-fbx", NULL },
{ "nes-classic-fbx-fs", NULL },
{ "nescap", NULL },
{ "wavebeam", NULL },
{ "raw", NULL },
{ "custom", NULL },
{ NULL, NULL},
},
"default",
},
{
"fceumm_up_down_allowed",
"Allow Opposing Directions",
"Allows simultaneous UP+DOWN or LEFT+RIGHT button combinations which can create different effects in some games.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL},
},
"disabled",
},
#ifdef PSP
{
"fceumm_overscan",
"Crop Overscan",
"Removes 8 pixel overscan from all sides",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL},
},
"enabled",
},
#else
{
"fceumm_overscan_h",
"Crop Overscan (Horizontal)",
"Removes 8 pixel from left and right side of the screen to simulate overscan seen on standard CRT television.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL},
},
"disabled",
},
{
"fceumm_overscan_v",
"Crop Overscan (Vertical)",
"Removes 8 pixel from the top and bottom of the screen to simulate overscan seen on standard CRT television.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL},
},
"enabled",
},
#endif
{
"fceumm_nospritelimit",
"No Sprite Limit",
"Removes the 8-per-scanline hardware limit. This reduces sprite flickering but can cause some games to glitch since some use this for effects.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL},
},
"disabled",
},
{
"fceumm_sndvolume",
"Sound Volume",
"Change master volume level",
{
{ "0", NULL },
{ "1", NULL },
{ "2", NULL },
{ "3", NULL },
{ "4", NULL },
{ "5", NULL },
{ "6", NULL },
{ "7", NULL },
{ "8", NULL },
{ "9", NULL },
{ "10", NULL },
{ NULL, NULL},
},
"7",
},
{
"fceumm_sndquality",
"Sound Quality",
"Enable higher quality sounds in exchange for more processing power required",
{
{ "Low", NULL },
{ "High", NULL },
{ "Very High", NULL },
{ NULL, NULL},
},
"Low",
},
{
"fceumm_swapduty",
"Swap Duty Cycles",
"Simulates the sound from famiclones has the pulse wave channels duty cycle bits reversed.",
{
{ "disabled", NULL },
{ "enabled", NULL },
{ NULL, NULL},
},
"disabled",
},
{
"fceumm_turbo_enable",
"Turbo Enable",
"Enables or disables turbo buttons.",
{
{ "None", NULL },
{ "Player 1", NULL },
{ "Player 2", NULL },
{ "Both", NULL },
{ NULL, NULL},
},
"None",
},
{
"fceumm_turbo_delay",
"Turbo Delay (in frames)",
"Repeat rate of turbo buttons in frames.",
{
{ "1", NULL },
{ "2", NULL },
{ "3", NULL },
{ "5", NULL },
{ "10", NULL },
{ "15", NULL },
{ "30", NULL },
{ "60", NULL },
{ NULL, NULL},
},
"3",
},
{
"fceumm_zapper_mode",
"Zapper Mode",
"Selects device to use for zapper games.",
{
{ "lightgun", NULL },
{ "touchscreen", NULL },
{ "mouse", NULL },
{ NULL, NULL},
},
"lightgun",
},
{
"fceumm_show_crosshair",
"Show Crosshair",
"Shows or hides on-screen crosshairs when using a zapper.",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL},
},
"enabled",
},
{
"fceumm_overclocking",
"Overclocking",
"Enables or disables overclocking which can reduce slowdowns in some games. Postrender method is more compatible with every game with Vblank more effective for games like Contra Force.",
{
{ "disabled", NULL },
{ "2x-Postrender", NULL },
{ "2x-VBlank", NULL },
{ NULL, NULL},
},
"disabled",
},
{
"fceumm_ramstate",
"RAM power up state (Restart)",
"Choose RAM startup during power up. Some games rely on initial ram values for random generator as an example.",
{
{ "fill $ff", NULL },
{ "fill $00", NULL },
{ "random", NULL },
{ NULL, NULL},
},
"fill $ff",
},
#ifdef DEBUG
{
"fceumm_apu_1",
"Channel 1 (Square 1)",
"Enables or disables pulse wave generator audio output 1.",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL},
},
"enabled",
},
{
"fceumm_apu_2",
"Channel 2 (Square 2)",
"Enables or disables pulse wave generator audio output 2.",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL},
},
"enabled",
},
{
"fceumm_apu_3",
"Channel 3 (Triangle)",
"Enables or disables triangle wave generator audio output.",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL},
},
"enabled",
},
{
"fceumm_apu_4",
"Channel 4 (Noise)",
"Enables or disables noise generator audio output.",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL},
},
"enabled",
},
{
"fceumm_apu_5",
"Channel 5 (PCM)",
"Enables or disables delta modulation channel audio output.",
{
{ "enabled", NULL },
{ "disabled", NULL },
{ NULL, NULL},
},
"enabled",
},
#endif
{ NULL, NULL, NULL, { {0} }, NULL },
};
struct retro_core_option_definition option_defs_empty = {
NULL, NULL, NULL, { {0} }, NULL
};
struct retro_core_option_definition option_defs_us[MAX_CORE_OPTIONS];
/* RETRO_LANGUAGE_JAPANESE */
/* RETRO_LANGUAGE_FRENCH */
/* RETRO_LANGUAGE_SPANISH */
/* RETRO_LANGUAGE_GERMAN */
/* RETRO_LANGUAGE_ITALIAN */
/* RETRO_LANGUAGE_DUTCH */
/* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
/* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
/* RETRO_LANGUAGE_RUSSIAN */
/* RETRO_LANGUAGE_KOREAN */
/* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
/* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
/* RETRO_LANGUAGE_ESPERANTO */
/* RETRO_LANGUAGE_POLISH */
/* RETRO_LANGUAGE_VIETNAMESE */
/* RETRO_LANGUAGE_ARABIC */
/* RETRO_LANGUAGE_GREEK */
/* RETRO_LANGUAGE_TURKISH */
/*
********************************
* Language Mapping
********************************
*/
struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = {
option_defs_us, /* RETRO_LANGUAGE_ENGLISH */
NULL, /* RETRO_LANGUAGE_JAPANESE */
NULL, /* RETRO_LANGUAGE_FRENCH */
NULL, /* RETRO_LANGUAGE_SPANISH */
NULL, /* RETRO_LANGUAGE_GERMAN */
NULL, /* RETRO_LANGUAGE_ITALIAN */
NULL, /* RETRO_LANGUAGE_DUTCH */
NULL, /* RETRO_LANGUAGE_PORTUGUESE_BRAZIL */
NULL, /* RETRO_LANGUAGE_PORTUGUESE_PORTUGAL */
NULL, /* RETRO_LANGUAGE_RUSSIAN */
NULL, /* RETRO_LANGUAGE_KOREAN */
NULL, /* RETRO_LANGUAGE_CHINESE_TRADITIONAL */
NULL, /* RETRO_LANGUAGE_CHINESE_SIMPLIFIED */
NULL, /* RETRO_LANGUAGE_ESPERANTO */
NULL, /* RETRO_LANGUAGE_POLISH */
NULL, /* RETRO_LANGUAGE_VIETNAMESE */
NULL, /* RETRO_LANGUAGE_ARABIC */
NULL, /* RETRO_LANGUAGE_GREEK */
NULL, /* RETRO_LANGUAGE_TURKISH */
};
/*
********************************
* Functions
********************************
*/
/* Handles configuration/setting of core options.
* Should only be called inside retro_set_environment().
* > We place the function body in the header to avoid the
* necessity of adding more .c files (i.e. want this to
* be as painless as possible for core devs)
*/
static INLINE void libretro_set_core_options(retro_environment_t environ_cb)
{
unsigned version = 0;
if (!environ_cb)
return;
if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version == 1))
{
struct retro_core_options_intl core_options_intl;
unsigned language = 0;
core_options_intl.us = option_defs_us;
core_options_intl.local = NULL;
if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) &&
(language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH))
core_options_intl.local = option_defs_intl[language];
environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl);
}
else
{
size_t i;
size_t option_index = 0;
size_t num_options = 0;
struct retro_variable *variables = NULL;
char **values_buf = NULL;
/* Determine number of options
* > Note: We are going to skip a number of irrelevant
* core options when building the retro_variable array,
* but we'll allocate space for all of them. The difference
* in resource usage is negligible, and this allows us to
* keep the code 'cleaner' */
while (true)
{
if (option_defs_us[num_options].key)
num_options++;
else
break;
}
/* Allocate arrays */
variables = (struct retro_variable *)calloc(num_options + 1, sizeof(struct retro_variable));
values_buf = (char **)calloc(num_options, sizeof(char *));
if (!variables || !values_buf)
goto error;
/* Copy parameters from option_defs_us array */
for (i = 0; i < num_options; i++)
{
const char *key = option_defs_us[i].key;
const char *desc = option_defs_us[i].desc;
const char *default_value = option_defs_us[i].default_value;
struct retro_core_option_value *values = option_defs_us[i].values;
size_t buf_len = 3;
size_t default_index = 0;
values_buf[i] = NULL;
/* Skip options that are irrelevant when using the
* old style core options interface */
if ((strcmp(key, "fceumm_advance_sound_options") == 0))
continue;
if (desc)
{
size_t num_values = 0;
/* Determine number of values */
while (true)
{
if (values[num_values].value)
{
/* Check if this is the default value */
if (default_value)
if (strcmp(values[num_values].value, default_value) == 0)
default_index = num_values;
buf_len += strlen(values[num_values].value);
num_values++;
}
else
break;
}
/* Build values string */
if (num_values > 1)
{
size_t j;
buf_len += num_values - 1;
buf_len += strlen(desc);
values_buf[i] = (char *)calloc(buf_len, sizeof(char));
if (!values_buf[i])
goto error;
strcpy(values_buf[i], desc);
strcat(values_buf[i], "; ");
/* Default value goes first */
strcat(values_buf[i], values[default_index].value);
/* Add remaining values */
for (j = 0; j < num_values; j++)
{
if (j != default_index)
{
strcat(values_buf[i], "|");
strcat(values_buf[i], values[j].value);
}
}
}
}
variables[option_index].key = key;
variables[option_index].value = values_buf[i];
option_index++;
}
/* Set variables */
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables);
error:
/* Clean up */
if (values_buf)
{
for (i = 0; i < num_options; i++)
{
if (values_buf[i])
{
free(values_buf[i]);
values_buf[i] = NULL;
}
}
free(values_buf);
values_buf = NULL;
}
if (variables)
{
free(variables);
variables = NULL;
}
}
}
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
#ifndef __VSUNI_DIPSWITCH__
#define __VSUNI_DIPSWITCH__
#include <libretro.h>
size_t set_dipswitch_variables(unsigned current_index, struct retro_core_option_definition *vars);
void update_dipswitch(void);
void DPSW_Cleanup(void);
extern retro_environment_t environ_cb;
#endif /* __VSUNI_DIPSWITCH__ */

View File

@@ -25,6 +25,7 @@ typedef struct {
uint8 MD5[16]; uint8 MD5[16];
int soundrate; /* For Ogg Vorbis expansion sound wacky support. 0 for default. */ int soundrate; /* For Ogg Vorbis expansion sound wacky support. 0 for default. */
int soundchan; /* Number of sound channels. */ int soundchan; /* Number of sound channels. */
int gameid; /* Currently used for VS game id for per-game dipswitch */
} FCEUGI; } FCEUGI;
#endif #endif

View File

@@ -49,7 +49,7 @@
{0x52ab2d17, 1, 8}, /* Toukyou Pachi-Slot Adventure (Japan) (Rev 0) */ {0x52ab2d17, 1, 8}, /* Toukyou Pachi-Slot Adventure (Japan) (Rev 0) */
{0x934db14a, 1, -1},/* All-Pro Basketball */ {0x934db14a, 1, -1},/* All-Pro Basketball */
{0xf74dfc91, 1, -1},/* Win, Lose, or Draw */ {0xf74dfc91, 1, -1},/* Win, Lose, or Draw */
{0xe6a477b2, 2, 0}, /* 3-D WorldRunner (USA) */ {0xe6a477b2, 2, 1}, /* 3-D WorldRunner (USA) */
{0x9ea1dc76, 2, 0}, /* Rainbow Islands */ {0x9ea1dc76, 2, 0}, /* Rainbow Islands */
{0x6d65cac6, 2, 0}, /* Terra Cresta */ {0x6d65cac6, 2, 0}, /* Terra Cresta */
{0xe1b260da, 2, 1}, /* Argos no Senshi */ {0xe1b260da, 2, 1}, /* Argos no Senshi */
@@ -79,7 +79,7 @@
{0xbc065fc3, 3, 1}, /* Pipe Dream */ {0xbc065fc3, 3, 1}, /* Pipe Dream */
{0xc9ee15a7, 3, -1}, /* 3 is probably best. 41 WILL NOT WORK. */ {0xc9ee15a7, 3, -1}, /* 3 is probably best. 41 WILL NOT WORK. */
{0x97b6cb19, 4, -1},/* Aladdin (SuperGame) (Mapper 4) [!] */ {0x97b6cb19, 4, -1},/* Aladdin (SuperGame) (Mapper 4) [!] */
{0xd97c31b0, 4, 1}, /* Rasaaru Ishii no Childs Quest (J) */ {0xd97c31b0, 206, 1}, /* Rasaaru Ishii no Childs Quest (J) */
{0x404b2e8b, 4, 2}, /* Rad Racer 2 */ {0x404b2e8b, 4, 2}, /* Rad Racer 2 */
{0x15141401, 4, 8}, /* Asmik Kun Land */ {0x15141401, 4, 8}, /* Asmik Kun Land */
{0x4cccd878, 4, 8}, /* Cat Ninden Teyandee */ {0x4cccd878, 4, 8}, /* Cat Ninden Teyandee */
@@ -116,24 +116,36 @@
{0x5555fca3, 32, 8}, {0x5555fca3, 32, 8},
{0x283ad224, 32, 8}, /* Ai Sensei no Oshiete */ {0x283ad224, 32, 8}, /* Ai Sensei no Oshiete */
{0x243a8735, 32, 0x10|4}, /* Major League */ {0x243a8735, 32, 0x10|4}, /* Major League */
{0xbc7b1d0f, 33, -1}, /* Bakushou!! Jinsei Gekijou 2 (J) [!] */ {0x8a7d0abe, 33, 8}, /* Akira (J) [!] */
{0x376138d8, 33, 8}, /* Akira (J) [a1] */
{0xadf606f6, 33, 8}, /* Bakushou!! Jinsei Gekijou (J) [!] */
{0xbc7b1d0f, 33, 8}, /* Bakushou!! Jinsei Gekijou 2 (J) [!] */
{0x7a497ae3, 33, 8}, /* Don Doko Don (J) [!] */
{0xbaca10a9, 33, 8}, /* Golf Ko Open (J) [!] */
{0xf80bdc50, 33, 8}, /* Insector X (J) [!] */
{0x2a6559a1, 33, 8}, /* Operation Wolf (J) [!] */
{0xaeb7fce9, 33, 8}, /* Power Blazer (J) [!] */
{0xd920f9df, 33, 8}, /* Takeshi no Sengoku Fuuunji (J) [!] */
{0x3cd4b420, 33, 8}, /* Takeshi no Sengoku Fuuunji (Japan) (Beta) */
{0x4c7c1af3, 34, 1}, /* Caesar's Palace */ {0x4c7c1af3, 34, 1}, /* Caesar's Palace */
{0x932ff06e, 34, 1}, /* Classic Concentration */ {0x932ff06e, 34, 1}, /* Classic Concentration */
{0xf46ef39a, 37, -1}, /* Super Mario Bros. + Tetris + Nintendo World Cup (E) [!] */ {0xf46ef39a, 37, -1}, /* Super Mario Bros. + Tetris + Nintendo World Cup (E) [!] */
{0x7ccb12a3, 43, -1}, /* SMB2j */ {0x7ccb12a3, 43, -1}, /* SMB2j */
{0x6c71feae, 45, -1}, /* Kunio 8-in-1 */ {0x6c71feae, 45, -1}, /* Kunio 8-in-1 */
{0xe2c94bc2, 48, -1}, /* Super Bros 8 (Unl) [!] */
{0xaebd6549, 48, 8}, /* Bakushou!! Jinsei Gekijou 3 */
{0x6cdc0cd9, 48, 8}, /* Bubble Bobble 2 */
{0x99c395f9, 48, 8}, /* Captain Saver */
{0xa7b0536c, 48, 8}, /* Don Doko Don 2 */
{0x40c0ad47, 48, 8}, /* Flintstones 2 */ {0x40c0ad47, 48, 8}, /* Flintstones 2 */
{0x1500e835, 48, 8}, /* Jetsons (J) */ {0xaebd6549, 48, 8}, /* Bakushou!! Jinsei Gekijou 3 (J) [!] */
{0x6cdc0cd9, 48, 8}, /* Bubble Bobble 2 (J) */
{0x99c395f9, 48, 8}, /* Captain Saver (J) */
{0xa7b0536c, 48, 8}, /* Don Doko Don 2 (J) [!] */
{0xb17c828a, 48, 8}, /* Don Doko Don 2 (J) [a1] */
{0x10e24006, 48, 8}, /* Flintstones, The - The Rescue of Dino & Hoppy (J) */
{0x1500e835, 48, 8}, /* Jetsons, The - Cogswell's Caper! (J) */
{0xe2c94bc2, 48, 8}, /* Super Bros 8 (Unl) [!] */
{0xa912b064, 51|0x800, 8}, /* 11-in-1 Ball Games(has CHR ROM when it shouldn't) */ {0xa912b064, 51|0x800, 8}, /* 11-in-1 Ball Games(has CHR ROM when it shouldn't) */
{0x39ab0fc7, 64, 8}, /* Hard Drivin' (USA) (Proto) (Unl) */ {0x39ab0fc7, 64, 8}, /* Hard Drivin' (USA) (Proto) (Unl) */
{0xb19a55dd, 64, 8}, /* Road Runner */ {0xb19a55dd, 64, 8}, /* Road Runner */
{0xf92be3ec, 64, -1}, /* Rolling Thunder */ {0xf92be3ec, 64, -1}, /* Rolling Thunder */
{0xd114f544, 66, 1}, /* AV Super Real Pachinko (Japan) (Unl) */ {0xd114f544, 66, 0}, /* AV Super Real Pachinko (Japan) (Unl) */
{0xe84274c5, 66, 1}, /* Mississippi Satsujin Jiken (J) [h2] */ {0xe84274c5, 66, 1}, /* Mississippi Satsujin Jiken (J) [h2] */
{0xbde3ae9b, 66, 1}, /* Doraemon */ {0xbde3ae9b, 66, 1}, /* Doraemon */
{0x9552e8df, 66, 1}, /* Dragon Ball */ {0x9552e8df, 66, 1}, /* Dragon Ball */
@@ -142,7 +154,7 @@
{0xdd8ed0f7, 70, 1}, /* Kamen Rider Club */ {0xdd8ed0f7, 70, 1}, /* Kamen Rider Club */
{0xbba58be5, 70, -1}, /* Family Trainer - Manhattan Police */ {0xbba58be5, 70, -1}, /* Family Trainer - Manhattan Police */
{0x370ceb65, 70, -1}, /* Family Trainer - Meiro Dai Sakusen */ {0x370ceb65, 70, -1}, /* Family Trainer - Meiro Dai Sakusen */
{0x86be4746, 71, -1}, /* Dooly Bravo Land (Korea) (Unl) */ {0x86be4746, 2, -1}, /* Dooly Bravo Land (Korea) (Unl) */
{0xe62e3382, 71, -1}, /* Mig-29 Soviet Fighter */ {0xe62e3382, 71, -1}, /* Mig-29 Soviet Fighter */
{0xac7b0742, 71, -1}, /* Golden KTV (Ch) [!], not actually 71, but UNROM without BUS conflict */ {0xac7b0742, 71, -1}, /* Golden KTV (Ch) [!], not actually 71, but UNROM without BUS conflict */
{0x054bd3e9, 74, -1}, /* Di 4 Ci - Ji Qi Ren Dai Zhan (As) */ {0x054bd3e9, 74, -1}, /* Di 4 Ci - Ji Qi Ren Dai Zhan (As) */
@@ -159,7 +171,8 @@
{0xd2699893, 88, 0}, /* Dragon Spirit */ {0xd2699893, 88, 0}, /* Dragon Spirit */
{0xbb7c5f7a, 89, 8}, /* Mito Koumon or something similar */ {0xbb7c5f7a, 89, 8}, /* Mito Koumon or something similar */
{0x10119e6b, 93, 8}, /* Fantasy Zone (Japan) */ {0x10119e6b, 93, 8}, /* Fantasy Zone (Japan) */
{0x0da5e32e, 101, -1}, /* Uruusey Yatsura */ {0x2b750bf9, 101, 1}, /* Urusei Yatsura - Lum no Wedding Bell (Japan) (Beta) */
{0x0da5e32e, 101, 1}, /* Urusei Yatsura - Lum no Wedding Bell (Japan) */
{0x6096f84e, 104, 1}, /* Pegasus 5-in-1 (Golden Five) (Unl) */ {0x6096f84e, 104, 1}, /* Pegasus 5-in-1 (Golden Five) (Unl) */
{0x3d3ff543, 113, 0}, /* Kazama Jun to Asama Yuuko no AV Dragon Mahjong (Japan) (Unl) */ {0x3d3ff543, 113, 0}, /* Kazama Jun to Asama Yuuko no AV Dragon Mahjong (Japan) (Unl) */
{0x68379fdb, 113, 1}, /* Pipemania (Australia) (HES) (Unl) */ {0x68379fdb, 113, 1}, /* Pipemania (Australia) (HES) (Unl) */
@@ -167,7 +180,6 @@
{0x0d98db53, 114, -1}, /* Pocahontas */ {0x0d98db53, 114, -1}, /* Pocahontas */
{0x4e7729ff, 114, -1}, /* Super Donkey Kong */ {0x4e7729ff, 114, -1}, /* Super Donkey Kong */
{0xc5e5c5b2, 115, -1}, /* Bao Qing Tian (As).nes */ {0xc5e5c5b2, 115, -1}, /* Bao Qing Tian (As).nes */
{0xa1dc16c0, 116, -1}, /* Street Heroes (Sachen) [b1] */
{0xe40dfb7e, 116, -1}, /* Somari (P conf.) */ {0xe40dfb7e, 116, -1}, /* Somari (P conf.) */
{0xc9371ebb, 116, -1}, /* Somari (W conf.) */ {0xc9371ebb, 116, -1}, /* Somari (W conf.) */
{0x78b657ac, 118, -1}, /* Armadillo */ {0x78b657ac, 118, -1}, /* Armadillo */
@@ -296,7 +308,7 @@
{0x2447e03b, 210, 1}, /* Top Striker */ {0x2447e03b, 210, 1}, /* Top Striker */
{0x1dc0f740, 210, 1}, /* Wagyan Land 2 */ {0x1dc0f740, 210, 1}, /* Wagyan Land 2 */
{0xd323b806, 210, 1}, /* Wagyan Land 3 */ {0xd323b806, 210, 1}, /* Wagyan Land 3 */
{0xbd523011, 210, 0}, /* Dream Master */ {0xbd523011, 210, 0}, /* Namco Prism Zone - Dream Master (Japan) */
{0x5daae69a, 211, -1}, /* Aladdin - Return of Jaffar, The (Unl) [!] */ {0x5daae69a, 211, -1}, /* Aladdin - Return of Jaffar, The (Unl) [!] */
{0x1ec1dfeb, 217, -1}, /* 255-in-1 (Cut version) [p1] */ {0x1ec1dfeb, 217, -1}, /* 255-in-1 (Cut version) [p1] */
{0x046d70cc, 217, -1}, /* 500-in-1 (Anim Splash, Alt Mapper)[p1][!] */ {0x046d70cc, 217, -1}, /* 500-in-1 (Anim Splash, Alt Mapper)[p1][!] */
@@ -305,18 +317,63 @@
{0x62ef6c79, 232, 8}, /* Quattro Sports -Aladdin */ {0x62ef6c79, 232, 8}, /* Quattro Sports -Aladdin */
{0x2705eaeb, 234, -1}, /* Maxi 15 */ {0x2705eaeb, 234, -1}, /* Maxi 15 */
{0x6f12afc5, 235, -1}, /* Golden Game 150-in-1 */ {0x6f12afc5, 235, -1}, /* Golden Game 150-in-1 */
{0xfb2b6b10, 241, -1}, /* Fan Kong Jing Ying (Ch) */
{0xb5e83c9a, 241, -1}, /* Xing Ji Zheng Ba (Ch) */
{0x2537b3e6, 241, -1}, /* Dance Xtreme - Prima (Unl) */ {0x2537b3e6, 241, -1}, /* Dance Xtreme - Prima (Unl) */
{0x11611e89, 241, -1}, /* Darkseed (Unl) [p1] */ {0x11611e89, 241, -1}, /* Darkseed (Unl) [p1] */
{0x81a37827, 241, -1}, /* Darkseed (Unl) [p1][b1] */ {0x81a37827, 241, -1}, /* Darkseed (Unl) [p1][b1] */
{0xc2730c30, 241, -1}, /* Deadly Towers (U) [!] */ {0xfb2b6b10, 241, -1}, /* Fan Kong Jing Ying (Ch) */
{0xa21e675c, 241, -1}, /* Mashou (J) [!] */ {0xb5e83c9a, 241, -1}, /* Xing Ji Zheng Ba (Ch) */
{0x368c19a8, 241, -1}, /* LIKO Study Cartridge 3-in-1 (Unl) [!] */ {0x368c19a8, 241, -1}, /* LIKO Study Cartridge 3-in-1 (Unl) [!] */
{0x54d98b79, 241, -1}, /* Titanic 1912 (Unl) */ {0x54d98b79, 241, -1}, /* Titanic 1912 (Unl) */
{0xc2730c30, 34, 0}, /* Deadly Towers (U) [!] */
{0xa21e675c, 34, 0}, /* Mashou (J) [!] */
{0x6bea1235, 245, -1}, /* MMC3 cart, but with nobanking applied to CHR-RAM, so let it be there */ {0x6bea1235, 245, -1}, /* MMC3 cart, but with nobanking applied to CHR-RAM, so let it be there */
{0x345ee51a, 245, -1}, /* DQ4c */ {0x345ee51a, 245, -1}, /* DQ4c */
{0x57514c6c, 245, -1}, /* Yong Zhe Dou E Long - Dragon Quest VI (Ch) */ {0x57514c6c, 245, -1}, /* Yong Zhe Dou E Long - Dragon Quest VI (Ch) */
{0xdb9d71b7, 114, -1}, /* Super Donkey Kong (Unl) [o1] */
{0x61fc4d20, 224, 0}, /* Pokemon HeartGold (KT-008 PCB)(Ch)[!] */
{0x4d735cb1, 224, 0}, /* Pokemon Platinum (KT-008 PCB)(Ch)[!] */
{0x4f427110, 224, 0}, /* Pokemon Platinum Alt title 1 (KT-008 PCB)(Ch)[!] */
{0xe001de16, 224, 0}, /* Pokemon Platinum Alt title 2 (KT-008 PCB)(Ch)[!] */
{0xbdbe3c96, 238, 1}, /* Contra Fighter (Unl) */
{0xcfe02ada, 1, -1}, /* Darkman (E) [!] */
{0xcb53c523, 11, 1}, /* King Neptune's Adventure (Color Dreams) [!] */
{0x6e149729, 189, -1}, /* Master Fighter II (Unl) [a1] */
{0x60bfeb0c, 90, -1}, /* Mortal Kombat 2 (Unl) [!] */
{0x247cc73d, 150, -1}, /* Poker II (Sachen) [!] */
{0xe41b440f, 3, 0}, /* Sidewinder (Joy Van) */
{0x1f1326d4, 121, 0}, /* Super Sonic 5 (1997) (Unl) [!] */
{0xb0c871c5, 3, 1}, /* Wei Lai Xiao Zi (Joy Van) */
{0xb3be2f71, 3, 0}, /* Yanshan Chess (Unl) */
{0x8dedea07, 3, 1}, /* Shui Guo Li (Ch) [a1] */
{0x1a71fd06, 1, 1}, /* Kujaku Ou (J) [T+Eng1.1_Snark] */
{0x99748230, 215, 0}, /* EarthWorm Jim 2 (SuperGame) */
{0x37876ac7, 215, 0}, /* Golden Card 6-in-1 (Unl) [!] */
{0x1a3320a3, 215, 0}, /* Mortal Kombat 3 (SuperGame) */
{0x80eb1839, 114, 0}, /* Boogerman (Sugar Softec) (Unl) [!] */
{0x071e4ee8, 114, 0}, /* m114,submapper 1 test rom */
{0xfe3e03a1, 197, -1}, /* Mortal Kombat III Special (YY-030) (Ch) [!] */
{0x9151d311, 197, -1}, /* Mortal Kombat III 28 Peoples (NT-328) (Ch) [!] */
{0x272709b9, 237, -1}, /* Teletubbies Y2K (420-in-1) */
{0x2e27e0af, 227, -1}, /* Bio Hazard (No-Bug) (Unl).nes */
{0x0e7e9309, 189, -1}, /* Street Fighter II - The World Warrior (Unl) [a1].nes */
{0xa3ac0095, 189, -1}, /* Street Fighter II - The World Warrior (Unl) [a2].nes */
{0xeced5899, 121, -1}, /* Ultimate Mortal Kombat 4 (Unl) [!].nes */
/* ines mappers that uses iNes 2.0 numbers */
{0xf6bd8e31, 281, 0}, /* 1997 Super HIK 4-in-1 (JY-052) [p1][!] */
{0x5aa23a15, 361, 0}, /* 4-in-1 (OK-411)[p1][!] */
{0xf6b9d088, 366, 0}, /* 4-in-1 (K-3131GS, GN-45) [p1][!] */
{0x503566b2, 366, 0}, /* 4-in-1 (K-3131SS, GN-45) [p1][!] */
/* ines mappers that uses unif boards */
{0x0073dbd8, 260, -1}, /* 2-in-1 - Mortal Kombat V Turbo 30 + Super Aladdin (Unl) [p1][!] */
{0x4dc6107d, 260, -1}, /* 2-in-1 - Boogerman + Flintstones, The (Unl) [p1][!] */
{0xb72b2cf4, 260, -1}, /* 2-in-1 - Aladdin + Lion King, The (Unl) [p1][!] */
{0xa1dc16c0, 262, -1}, /* Street Heroes (Asia) (Ja) (Unl */
{0x1df10182, 263, -1}, /* Boogerman II (Rex-Soft) [!].nes */
{0xf956fcea, 521, -1}, /* Korean Igo (Korea) (Unl) */
{0x00000000, -1, -1} {0x00000000, -1, -1}

View File

@@ -57,7 +57,9 @@ uint32 VROM_size = 0;
static int CHRRAMSize = -1; static int CHRRAMSize = -1;
static int iNES_Init(int num); static int iNES_Init(int num);
static int iNES2 = 0;
static int MapperNo = 0; static int MapperNo = 0;
static int subMapper = 0;
static DECLFR(TrainerRead) { static DECLFR(TrainerRead) {
return(trainerpoo[A & 0x1FF]); return(trainerpoo[A & 0x1FF]);
@@ -237,7 +239,6 @@ void CheckBad(uint64 md5partial) {
} }
} }
struct CHINF { struct CHINF {
uint32 crc32; uint32 crc32;
int32 mapper; int32 mapper;
@@ -295,6 +296,8 @@ static void CheckHInfo(void) {
}; };
int32 tofix = 0, x; int32 tofix = 0, x;
uint64 partialmd5 = 0; uint64 partialmd5 = 0;
int32 current_mapper = 0;
int32 cur_mirr = 0;
for (x = 0; x < 8; x++) for (x = 0; x < 8; x++)
partialmd5 |= (uint64)iNESCart.MD5[15 - x] << (x * 8); partialmd5 |= (uint64)iNESCart.MD5[15 - x] << (x * 8);
@@ -310,12 +313,14 @@ static void CheckHInfo(void) {
VROM = NULL; VROM = NULL;
tofix |= 8; tofix |= 8;
} }
if (MapperNo != (moo[x].mapper & 0xFF)) { if (MapperNo != (moo[x].mapper & 0xFFF)) {
tofix |= 1; tofix |= 1;
MapperNo = moo[x].mapper & 0xFF; current_mapper = MapperNo;
MapperNo = moo[x].mapper & 0xFFF;
} }
} }
if (moo[x].mirror >= 0) { if (moo[x].mirror >= 0) {
cur_mirr = Mirroring;
if (moo[x].mirror == 8) { if (moo[x].mirror == 8) {
if (Mirroring == 2) { /* Anything but hard-wired(four screen). */ if (Mirroring == 2) { /* Anything but hard-wired(four screen). */
tofix |= 2; tofix |= 2;
@@ -361,19 +366,19 @@ static void CheckHInfo(void) {
if (tofix) { if (tofix) {
char gigastr[768]; char gigastr[768];
strcpy(gigastr, "The iNES header contains incorrect information. For now, the information will be corrected in RAM. "); strcpy(gigastr, "The iNES header contains incorrect information. For now, the information will be corrected in RAM. ");
if (tofix & 1) if (tofix & 1)
sprintf(gigastr + strlen(gigastr), "The mapper number should be set to %d. ", MapperNo); sprintf(gigastr + strlen(gigastr), "Current mapper # is %d. The mapper number should be set to %d. ", current_mapper, MapperNo);
if (tofix & 2) { if (tofix & 2) {
uint8 *mstr[3] = { (uint8_t*)"Horizontal", (uint8_t*)"Vertical", (uint8_t*)"Four-screen" }; uint8 *mstr[3] = { (uint8_t*)"Horizontal", (uint8_t*)"Vertical", (uint8_t*)"Four-screen" };
sprintf(gigastr + strlen(gigastr), "Mirroring should be set to \"%s\". ", mstr[Mirroring & 3]); sprintf(gigastr + strlen(gigastr), "Current mirroring is %s. Mirroring should be set to \"%s\". ", mstr[cur_mirr & 3], mstr[Mirroring & 3]);
} }
if (tofix & 4) if (tofix & 4)
strcat(gigastr, "The battery-backed bit should be set. "); strcat(gigastr, "The battery-backed bit should be set. ");
if (tofix & 8) if (tofix & 8)
strcat(gigastr, "This game should not have any CHR ROM. "); strcat(gigastr, "This game should not have any CHR ROM. ");
strcat(gigastr, "\n"); strcat(gigastr, "\n");
FCEU_printf("%s", gigastr); FCEU_printf("%s\n", gigastr);
} }
} }
@@ -417,10 +422,10 @@ static BMAPPINGLocal bmap[] = {
{(uint8_t*)"Konami VRC2/VRC4 D", 25, Mapper25_Init}, {(uint8_t*)"Konami VRC2/VRC4 D", 25, Mapper25_Init},
{(uint8_t*)"Konami VRC6 Rev. B", 26, Mapper26_Init}, {(uint8_t*)"Konami VRC6 Rev. B", 26, Mapper26_Init},
{(uint8_t*)"CC-21 MI HUN CHE", 27, UNLCC21_Init}, /* Former dupe for VRC2/VRC4 mapper, redefined with crc to mihunche boards */ {(uint8_t*)"CC-21 MI HUN CHE", 27, UNLCC21_Init}, /* Former dupe for VRC2/VRC4 mapper, redefined with crc to mihunche boards */
/* {(uint8_t*)"", 28, Mapper28_Init}, */ /* Custom Multidiscrete mapper for PDs */ {(uint8_t*)"Action 53", 28, Mapper28_Init},
/* {(uint8_t*)"", 29, Mapper29_Init}, */ {(uint8_t*)"", 29, Mapper29_Init},
{(uint8_t*)"UNROM 512", 30, UNROM512_Init}, {(uint8_t*)"UNROM 512", 30, UNROM512_Init},
/* {(uint8_t*)"", 31, Mapper31_Init}, */ {(uint8_t*)"infineteNesLives-NSF", 31, Mapper31_Init},
{(uint8_t*)"IREM G-101", 32, Mapper32_Init}, {(uint8_t*)"IREM G-101", 32, Mapper32_Init},
{(uint8_t*)"TC0190FMC/TC0350FMR", 33, Mapper33_Init}, {(uint8_t*)"TC0190FMC/TC0350FMR", 33, Mapper33_Init},
{(uint8_t*)"IREM I-IM/BNROM", 34, Mapper34_Init}, {(uint8_t*)"IREM I-IM/BNROM", 34, Mapper34_Init},
@@ -445,14 +450,14 @@ static BMAPPINGLocal bmap[] = {
{(uint8_t*)"SUPERVISION 16-in-1", 53, Supervision16_Init}, {(uint8_t*)"SUPERVISION 16-in-1", 53, Supervision16_Init},
/* {(uint8_t*)"", 54, Mapper54_Init}, */ /* {(uint8_t*)"", 54, Mapper54_Init}, */
/* {(uint8_t*)"", 55, Mapper55_Init}, */ /* {(uint8_t*)"", 55, Mapper55_Init}, */
/* {(uint8_t*)"", 56, Mapper56_Init}, */ {(uint8_t*)"UNLKS202", 56, UNLKS202_Init},
{(uint8_t*)"SIMBPLE BMC PIRATE A", 57, Mapper57_Init}, {(uint8_t*)"SIMBPLE BMC PIRATE A", 57, Mapper57_Init},
{(uint8_t*)"SIMBPLE BMC PIRATE B", 58, BMCGK192_Init}, {(uint8_t*)"SIMBPLE BMC PIRATE B", 58, BMCGK192_Init},
{(uint8_t*)"", 59, Mapper59_Init}, /* Check this out */ {(uint8_t*)"", 59, Mapper59_Init}, /* Check this out */
{(uint8_t*)"SIMBPLE BMC PIRATE C", 60, BMCD1038_Init}, {(uint8_t*)"SIMBPLE BMC PIRATE C", 60, BMCD1038_Init},
{(uint8_t*)"20-in-1 KAISER Rev. A",61, Mapper61_Init}, {(uint8_t*)"20-in-1 KAISER Rev. A",61, Mapper61_Init},
{(uint8_t*)"700-in-1", 62, Mapper62_Init}, {(uint8_t*)"700-in-1", 62, Mapper62_Init},
/* {(uint8_t*)"", 63, Mapper63_Init}, */ {(uint8_t*)"", 63, Mapper63_Init},
{(uint8_t*)"TENGEN RAMBO1", 64, Mapper64_Init}, {(uint8_t*)"TENGEN RAMBO1", 64, Mapper64_Init},
{(uint8_t*)"IREM-H3001", 65, Mapper65_Init}, {(uint8_t*)"IREM-H3001", 65, Mapper65_Init},
{(uint8_t*)"MHROM", 66, MHROM_Init}, {(uint8_t*)"MHROM", 66, MHROM_Init},
@@ -515,7 +520,7 @@ static BMAPPINGLocal bmap[] = {
{(uint8_t*)"MMC3 PIRATE H2288", 123, UNLH2288_Init}, {(uint8_t*)"MMC3 PIRATE H2288", 123, UNLH2288_Init},
/* {(uint8_t*)"", 124, Mapper124_Init}, */ /* {(uint8_t*)"", 124, Mapper124_Init}, */
{(uint8_t*)"FDS LH32", 125, LH32_Init}, {(uint8_t*)"FDS LH32", 125, LH32_Init},
/* {(uint8_t*)"", 126, Mapper126_Init}, */ {(uint8_t*)"PowerJoy 84-in-1 PJ-008", 126, Mapper126_Init},
/* {(uint8_t*)"", 127, Mapper127_Init}, */ /* {(uint8_t*)"", 127, Mapper127_Init}, */
/* {(uint8_t*)"", 128, Mapper128_Init}, */ /* {(uint8_t*)"", 128, Mapper128_Init}, */
/* {(uint8_t*)"", 129, Mapper129_Init}, */ /* {(uint8_t*)"", 129, Mapper129_Init}, */
@@ -571,7 +576,7 @@ static BMAPPINGLocal bmap[] = {
/* {(uint8_t*)"", 179, Mapper179_Init}, */ /* {(uint8_t*)"", 179, Mapper179_Init}, */
{(uint8_t*)"", 180, Mapper180_Init}, {(uint8_t*)"", 180, Mapper180_Init},
{(uint8_t*)"", 181, Mapper181_Init}, {(uint8_t*)"", 181, Mapper181_Init},
/* {(uint8_t*)"", 182, Mapper182_Init}, */ /* Deprecated, dupe */ /* {(uint8_t*)"", 182, Mapper182_Init}, */ /* Deprecated, dupe of Mapper 114 */
{(uint8_t*)"", 183, Mapper183_Init}, {(uint8_t*)"", 183, Mapper183_Init},
{(uint8_t*)"", 184, Mapper184_Init}, {(uint8_t*)"", 184, Mapper184_Init},
{(uint8_t*)"", 185, Mapper185_Init}, {(uint8_t*)"", 185, Mapper185_Init},
@@ -594,7 +599,7 @@ static BMAPPINGLocal bmap[] = {
{(uint8_t*)"", 202, Mapper202_Init}, {(uint8_t*)"", 202, Mapper202_Init},
{(uint8_t*)"", 203, Mapper203_Init}, {(uint8_t*)"", 203, Mapper203_Init},
{(uint8_t*)"", 204, Mapper204_Init}, {(uint8_t*)"", 204, Mapper204_Init},
{(uint8_t*)"", 205, Mapper205_Init}, {(uint8_t*)"BMC 15-in-1/3-in-1", 205, Mapper205_Init},
{(uint8_t*)"NAMCOT 108 Rev. C", 206, Mapper206_Init}, /* Deprecated, Used to be "DEIROM" whatever it means, but actually simple version of MMC3 */ {(uint8_t*)"NAMCOT 108 Rev. C", 206, Mapper206_Init}, /* Deprecated, Used to be "DEIROM" whatever it means, but actually simple version of MMC3 */
{(uint8_t*)"TAITO X1-005 Rev. B", 207, Mapper207_Init}, {(uint8_t*)"TAITO X1-005 Rev. B", 207, Mapper207_Init},
{(uint8_t*)"", 208, Mapper208_Init}, {(uint8_t*)"", 208, Mapper208_Init},
@@ -604,7 +609,7 @@ static BMAPPINGLocal bmap[] = {
{(uint8_t*)"", 212, Mapper212_Init}, {(uint8_t*)"", 212, Mapper212_Init},
{(uint8_t*)"", 213, Mapper213_Init}, {(uint8_t*)"", 213, Mapper213_Init},
{(uint8_t*)"", 214, Mapper214_Init}, {(uint8_t*)"", 214, Mapper214_Init},
{(uint8_t*)"", 215, UNL8237_Init}, {(uint8_t*)"UNL-8237", 215, UNL8237_Init},
{(uint8_t*)"", 216, Mapper216_Init}, {(uint8_t*)"", 216, Mapper216_Init},
{(uint8_t*)"", 217, Mapper217_Init}, /* Redefined to a new Discrete BMC mapper */ {(uint8_t*)"", 217, Mapper217_Init}, /* Redefined to a new Discrete BMC mapper */
/* {(uint8_t*)"", 218, Mapper218_Init}, */ /* {(uint8_t*)"", 218, Mapper218_Init}, */
@@ -613,7 +618,7 @@ static BMAPPINGLocal bmap[] = {
{(uint8_t*)"UNLN625092", 221, UNLN625092_Init}, {(uint8_t*)"UNLN625092", 221, UNLN625092_Init},
{(uint8_t*)"", 222, Mapper222_Init}, {(uint8_t*)"", 222, Mapper222_Init},
/* {(uint8_t*)"", 223, Mapper223_Init}, */ /* {(uint8_t*)"", 223, Mapper223_Init}, */
/* {(uint8_t*)"", 224, Mapper224_Init}, */ {(uint8_t*)"KT-008", 224, Mapper224_Init},
{(uint8_t*)"", 225, Mapper225_Init}, {(uint8_t*)"", 225, Mapper225_Init},
{(uint8_t*)"BMC 22+20-in-1", 226, Mapper226_Init}, {(uint8_t*)"BMC 22+20-in-1", 226, Mapper226_Init},
{(uint8_t*)"", 227, Mapper227_Init}, {(uint8_t*)"", 227, Mapper227_Init},
@@ -626,7 +631,7 @@ static BMAPPINGLocal bmap[] = {
{(uint8_t*)"BMC MAXI", 234, Mapper234_Init}, {(uint8_t*)"BMC MAXI", 234, Mapper234_Init},
{(uint8_t*)"", 235, Mapper235_Init}, {(uint8_t*)"", 235, Mapper235_Init},
/* {(uint8_t*)"", 236, Mapper236_Init}, */ /* {(uint8_t*)"", 236, Mapper236_Init}, */
/* {(uint8_t*)"", 237, Mapper237_Init}, */ {(uint8_t*)"Teletubbies / Y2K", 237, Mapper237_Init},
{(uint8_t*)"UNL6035052", 238, UNL6035052_Init}, {(uint8_t*)"UNL6035052", 238, UNL6035052_Init},
/* {(uint8_t*)"", 239, Mapper239_Init}, */ /* {(uint8_t*)"", 239, Mapper239_Init}, */
{(uint8_t*)"", 240, Mapper240_Init}, {(uint8_t*)"", 240, Mapper240_Init},
@@ -644,20 +649,115 @@ static BMAPPINGLocal bmap[] = {
{(uint8_t*)"SAN GUO ZHI PIRATE", 252, Mapper252_Init}, {(uint8_t*)"SAN GUO ZHI PIRATE", 252, Mapper252_Init},
{(uint8_t*)"DRAGON BALL PIRATE", 253, Mapper253_Init}, {(uint8_t*)"DRAGON BALL PIRATE", 253, Mapper253_Init},
{(uint8_t*)"", 254, Mapper254_Init}, {(uint8_t*)"", 254, Mapper254_Init},
/* {(uint8_t*)"", 255, Mapper255_Init}, */ /* No good dumps for this mapper */ {(uint8_t*)"", 255, Mapper255_Init}, /* Duplicate of M225? */
{(uint8_t*)"", 0, NULL}
/* -------------- ----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},
/* 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) { int iNESLoad(const char *name, FCEUFILE *fp) {
struct md5_context md5; struct md5_context md5;
char* mappername; char* mappername = NULL;
uint32 mappertest; uint32 filesize = fp->fp->size;
uint32 mappertest = 0;
uint32 prgRom = 0;
uint32 chrRom = 0;
if (FCEU_fread(&head, 1, 16, fp) != 16) if (FCEU_fread(&head, 1, 16, fp) != 16)
return 0; return 0;
filesize -= 16; /* remove header size from total size */
if (memcmp(&head, "NES\x1a", 4)) { 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; return 0;
} }
@@ -678,20 +778,54 @@ int iNESLoad(const char *name, FCEUFILE *fp) {
memset((char*)(&head) + 0xA, 0, 0x6); memset((char*)(&head) + 0xA, 0, 0x6);
} }
MapperNo = (head.ROM_type >> 4); Mirroring = 0;
MapperNo |= (head.ROM_type2 & 0xF0); ROM_size = 0;
if (head.ROM_type & 8) { VROM_size = 0;
Mirroring = 2; iNES2 = 0;
} else MapperNo = 0;
Mirroring = (head.ROM_type & 1); subMapper = 0;
if (!head.ROM_size) MapperNo = (head.ROM_type >> 4) | (head.ROM_type2 & 0xF0);
ROM_size = 256; Mirroring = (head.ROM_type & 8) ? 2 : (head.ROM_type & 1);
else prgRom = head.ROM_size;
ROM_size = uppow2(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) if ((ROM = (uint8*)FCEU_malloc(ROM_size << 14)) == NULL)
return 0; return 0;
@@ -706,63 +840,32 @@ int iNESLoad(const char *name, FCEUFILE *fp) {
memset(VROM, 0xFF, VROM_size << 13); memset(VROM, 0xFF, VROM_size << 13);
} }
if (head.ROM_type & 4) { /* Trainer */
trainerpoo = (uint8*)FCEU_gmalloc(512);
FCEU_fread(trainerpoo, 512, 1, fp);
}
ResetCartMapping(); ResetCartMapping();
ResetExState(0, 0); ResetExState(0, 0);
SetupCartPRGMapping(0, ROM, ROM_size << 14, 0); SetupCartPRGMapping(0, ROM, ROM_size << 14, 0);
if (head.ROM_size) FCEU_fread(ROM, 0x4000, prgRom, fp);
FCEU_fread(ROM, 0x4000, head.ROM_size, fp);
else
FCEU_fread(ROM, 0x4000, ROM_size, fp);
if (VROM_size) if (VROM_size)
FCEU_fread(VROM, 0x2000, VROM_size, fp); FCEU_fread(VROM, 0x2000, chrRom, fp);
md5_starts(&md5); md5_starts(&md5);
if (head.ROM_size) { md5_update(&md5, ROM, prgRom << 14);
md5_update(&md5, ROM, head.ROM_size << 14); iNESGameCRC32 = CalcCRC32(0, ROM, prgRom << 14);
iNESGameCRC32 = CalcCRC32(0, ROM, head.ROM_size << 14);
} else {
md5_update(&md5, ROM, ROM_size << 14);
iNESGameCRC32 = CalcCRC32(0, ROM, ROM_size << 14);
}
if (VROM_size) { if (VROM_size) {
iNESGameCRC32 = CalcCRC32(iNESGameCRC32, VROM, VROM_size << 13); iNESGameCRC32 = CalcCRC32(iNESGameCRC32, VROM, chrRom << 13);
md5_update(&md5, VROM, VROM_size << 13); md5_update(&md5, VROM, chrRom << 13);
} }
md5_finish(&md5, iNESCart.MD5); md5_finish(&md5, iNESCart.MD5);
memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5)); memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5));
iNESCart.CRC32 = iNESGameCRC32; iNESCart.CRC32 = iNESGameCRC32;
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(" ROM CRC32: 0x%08lx\n", iNESGameCRC32);
FCEU_printf(" ROM MD5: 0x%s\n", md5_asciistr(iNESCart.MD5));
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;
}
}
FCEU_printf(" Mapper #: %d\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");
SetInput(); SetInput();
CheckHInfo(); CheckHInfo();
{ {
int x; int x;
uint64 partialmd5 = 0; uint64 partialmd5 = 0;
@@ -787,30 +890,92 @@ int iNESLoad(const char *name, FCEUFILE *fp) {
else else
SetupCartMirroring(Mirroring & 1, (Mirroring & 4) >> 2, 0); 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.battery = (head.ROM_type & 2) ? 1 : 0;
iNESCart.mirror = Mirroring; iNESCart.mirror = Mirroring;
if (!iNES_Init(MapperNo)) mappername = "Not Listed";
FCEU_PrintError("iNES mapper #%d is not supported at all.", MapperNo);
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", prgRom);
FCEU_printf(" CHR ROM: %3d x 8KiB\n", chrRom);
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(" 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; GameInterface = iNESGI;
FCEU_printf("\n");
if (strstr(name, "(E)") || strstr(name, "(e)") if (iNES2) {
|| strstr(name, "(Europe)") || strstr(name, "(PAL)") switch (iNESCart.region & 0x03) {
|| strstr(name, "(F)") || strstr(name, "(f)") /* 0: RP2C02 ("NTSC NES")
|| strstr(name, "(G)") || strstr(name, "(g)") * 1: RP2C07 ("Licensed PAL NES")
|| strstr(name, "(I)") || strstr(name, "(i)") * 2: Multiple-region
|| strstr(name, "(S)") || strstr(name, "(s)") * 3: UMC 6527P ("Dendy")
|| strstr(name, "(France)") || strstr(name, "(Germany)") */
|| strstr(name, "(Italy)") || strstr(name, "(Spain)") case 0: case 2: FCEUI_SetVidSystem(0); break;
|| strstr(name, "(Sweden)") || strstr(name, "(Sw)") case 1: FCEUI_SetVidSystem(1); break;
|| strstr(name, "(Australia)") || strstr(name, "(A)") case 3: dendy = 1; FCEUI_SetVidSystem(0); break;
|| strstr(name, "(a)")) { }
FCEUI_SetVidSystem(1); } 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; return 1;
} }
@@ -827,21 +992,32 @@ static int iNES_Init(int num) {
if (num == tmp->number) { if (num == tmp->number) {
UNIFchrrama = 0; /* need here for compatibility with UNIF mapper code */ UNIFchrrama = 0; /* need here for compatibility with UNIF mapper code */
if (!VROM_size) { if (!VROM_size) {
switch (num) { /* FIXME, mapper or game data base with the board parameters and ROM/RAM sizes */ if (iNESCart.iNES2) {
case 13: CHRRAMSize = 16 * 1024; break; CHRRAMSize = iNESCart.chrRam + iNESCart.chrRam_battery;
case 6: } else {
case 30: switch (num) { /* FIXME, mapper or game data base with the board parameters and ROM/RAM sizes */
case 45: case 13: CHRRAMSize = 16 * 1024; break;
case 96: CHRRAMSize = 32 * 1024; break; case 6:
case 176: CHRRAMSize = 128 * 1024; break; case 28:
default: CHRRAMSize = 8 * 1024; break; 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");
} }
if (head.ROM_type & 8) if (head.ROM_type & 8)
AddExState(ExtraNTARAM, 2048, 0, "EXNR"); AddExState(ExtraNTARAM, 2048, 0, "EXNR");

View File

@@ -28,7 +28,14 @@ typedef struct {
uint8 VROM_size; uint8 VROM_size;
uint8 ROM_type; uint8 ROM_type;
uint8 ROM_type2; 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; } iNES_HEADER;
extern uint8 *ROM; extern uint8 *ROM;
@@ -63,7 +70,9 @@ void Mapper23_Init(CartInfo *);
void Mapper24_Init(CartInfo *); void Mapper24_Init(CartInfo *);
void Mapper25_Init(CartInfo *); void Mapper25_Init(CartInfo *);
void Mapper26_Init(CartInfo *); void Mapper26_Init(CartInfo *);
void UNROM512_Init(CartInfo *); /* Mapper #30 */ void Mapper28_Init(CartInfo *);
void Mapper29_Init(CartInfo *);
void Mapper31_Init(CartInfo *);
void Mapper32_Init(CartInfo *); void Mapper32_Init(CartInfo *);
void Mapper33_Init(CartInfo *); void Mapper33_Init(CartInfo *);
void Mapper34_Init(CartInfo *); void Mapper34_Init(CartInfo *);
@@ -87,6 +96,7 @@ void Mapper57_Init(CartInfo *);
void Mapper59_Init(CartInfo *); void Mapper59_Init(CartInfo *);
void Mapper61_Init(CartInfo *); void Mapper61_Init(CartInfo *);
void Mapper62_Init(CartInfo *); void Mapper62_Init(CartInfo *);
void Mapper63_Init(CartInfo *);
void Mapper64_Init(CartInfo *); void Mapper64_Init(CartInfo *);
void Mapper65_Init(CartInfo *); void Mapper65_Init(CartInfo *);
void Mapper67_Init(CartInfo *); void Mapper67_Init(CartInfo *);
@@ -136,6 +146,7 @@ void Mapper119_Init(CartInfo *);
void Mapper120_Init(CartInfo *); void Mapper120_Init(CartInfo *);
void Mapper121_Init(CartInfo *); void Mapper121_Init(CartInfo *);
void Mapper125_Init(CartInfo *); void Mapper125_Init(CartInfo *);
void Mapper126_Init(CartInfo *);
void Mapper134_Init(CartInfo *); void Mapper134_Init(CartInfo *);
void Mapper140_Init(CartInfo *); void Mapper140_Init(CartInfo *);
void Mapper144_Init(CartInfo *); void Mapper144_Init(CartInfo *);
@@ -198,6 +209,7 @@ void Mapper216_Init(CartInfo *);
void Mapper217_Init(CartInfo *); void Mapper217_Init(CartInfo *);
void Mapper220_Init(CartInfo *); void Mapper220_Init(CartInfo *);
void Mapper222_Init(CartInfo *); void Mapper222_Init(CartInfo *);
void Mapper224_Init(CartInfo *);
void Mapper225_Init(CartInfo *); void Mapper225_Init(CartInfo *);
void Mapper226_Init(CartInfo *); void Mapper226_Init(CartInfo *);
void Mapper227_Init(CartInfo *); void Mapper227_Init(CartInfo *);
@@ -222,5 +234,9 @@ void Mapper250_Init(CartInfo *);
void Mapper252_Init(CartInfo *); void Mapper252_Init(CartInfo *);
void Mapper253_Init(CartInfo *); void Mapper253_Init(CartInfo *);
void Mapper254_Init(CartInfo *); void Mapper254_Init(CartInfo *);
void Mapper255_Init(CartInfo *);
void GN45_Init(CartInfo *info); /* m361, m366 */
void Mapper281_Init(CartInfo *);
#endif #endif

View File

@@ -1233,7 +1233,8 @@ SFORMAT FCEUSND_STATEINFO[] = {
* issues loading states with this. Increasing it only helps a few games. * issues loading states with this. Increasing it only helps a few games.
* Disabling this state variable for Wii/WiiU/GC for now. */ * Disabling this state variable for Wii/WiiU/GC for now. */
/* TODO: fix this for better runahead feature for big-endian */ /* TODO: fix this for better runahead feature for big-endian */
#ifndef GEKKO /* UPDATE: Try to ignore this for all big-endian for now */
#ifndef MSB_FIRST
/* wave buffer is used for filtering, only need first 17 values from it */ /* wave buffer is used for filtering, only need first 17 values from it */
{ &Wave, 32 * sizeof(int32), "WAVE"}, { &Wave, 32 * sizeof(int32), "WAVE"},
#endif #endif

View File

@@ -47,6 +47,7 @@ typedef struct {
typedef struct { typedef struct {
char *name; char *name;
int ines_mapper;
void (*init)(CartInfo *); void (*init)(CartInfo *);
int flags; int flags;
} BMAPPING; } BMAPPING;
@@ -60,6 +61,8 @@ CartInfo UNIFCart;
static int vramo; static int vramo;
static int mirrortodo; static int mirrortodo;
static int submapper;
static int cspecial;
static uint8 *boardname; static uint8 *boardname;
static uint8 *sboardname; static uint8 *sboardname;
@@ -72,6 +75,15 @@ static UNIF_HEADER uchead;
static uint8 *malloced[32]; static uint8 *malloced[32];
static uint32 mallocedsizes[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) { static int FixRomSize(uint32 size, uint32 minimum) {
uint32 x = 1; uint32 x = 1;
@@ -96,24 +108,39 @@ static void FreeUNIF(void) {
free(malloced[x]); malloced[x] = 0; free(malloced[x]); malloced[x] = 0;
} }
} }
if (ROM) {
free(ROM); ROM = 0;
}
if (VROM) {
free(VROM); VROM = 0;
}
} }
static void ResetUNIF(void) { static void ResetUNIF(void) {
int x; int x;
for (x = 0; x < 32; x++) for (x = 0; x < 32; x++)
malloced[x] = 0; malloced[x] = 0;
for (x = 0; x < 16; x++)
prg_idx[x] = chr_idx[x] = 0;
vramo = 0; vramo = 0;
boardname = 0; boardname = 0;
mirrortodo = 0; mirrortodo = 0;
memset(&UNIFCart, 0, sizeof(UNIFCart)); memset(&UNIFCart, 0, sizeof(UNIFCart));
UNIFchrrama = 0; 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]; static uint8 exntar[2048];
static void MooMirroring(void) { static void MooMirroring(void) {
if (mirrortodo < 0x4) if (mirrortodo < 0x4)
SetupCartMirroring(mirrortodo, 1, 0); /* 06-22-19 Allow override when using vertical/horizontal mirroring. */
SetupCartMirroring(mirrortodo, (mirrortodo >> 1) & 1, 0);
else if (mirrortodo == 0x4) { else if (mirrortodo == 0x4) {
SetupCartMirroring(4, 1, exntar); SetupCartMirroring(4, 1, exntar);
AddExState(exntar, 2048, 0, "EXNR"); AddExState(exntar, 2048, 0, "EXNR");
@@ -259,7 +286,7 @@ static int LoadPRG(FCEUFILE *fp) {
FCEU_printf(" PRG ROM %d size: %d\n", z, (int)uchead.info); FCEU_printf(" PRG ROM %d size: %d\n", z, (int)uchead.info);
if (malloced[z]) if (malloced[z])
free(malloced[z]); free(malloced[z]);
t = FixRomSize(uchead.info, 2048); t = uchead.info;
if (!(malloced[z] = (uint8*)FCEU_malloc(t))) if (!(malloced[z] = (uint8*)FCEU_malloc(t)))
return(0); return(0);
mallocedsizes[z] = t; mallocedsizes[z] = t;
@@ -267,10 +294,12 @@ static int LoadPRG(FCEUFILE *fp) {
if (FCEU_fread(malloced[z], 1, uchead.info, fp) != uchead.info) { if (FCEU_fread(malloced[z], 1, uchead.info, fp) != uchead.info) {
FCEU_printf("Read Error!\n"); FCEU_printf("Read Error!\n");
return(0); return(0);
} /* else }
FCEU_printf("\n"); */
UNIF_PRGROMSize += t;
prg_idx[prg_chip_count] = z;
prg_chip_count++;
SetupCartPRGMapping(z, malloced[z], t, 0);
return(1); return(1);
} }
@@ -294,7 +323,7 @@ static int LoadCHR(FCEUFILE *fp) {
FCEU_printf(" CHR ROM %d size: %d\n", z, (int)uchead.info); FCEU_printf(" CHR ROM %d size: %d\n", z, (int)uchead.info);
if (malloced[16 + z]) if (malloced[16 + z])
free(malloced[16 + z]); free(malloced[16 + z]);
t = FixRomSize(uchead.info, 8192); t = uchead.info;
if (!(malloced[16 + z] = (uint8*)FCEU_malloc(t))) if (!(malloced[16 + z] = (uint8*)FCEU_malloc(t)))
return(0); return(0);
mallocedsizes[16 + z] = t; mallocedsizes[16 + z] = t;
@@ -302,13 +331,75 @@ static int LoadCHR(FCEUFILE *fp) {
if (FCEU_fread(malloced[16 + z], 1, uchead.info, fp) != uchead.info) { if (FCEU_fread(malloced[16 + z], 1, uchead.info, fp) != uchead.info) {
FCEU_printf("Read Error!\n"); FCEU_printf("Read Error!\n");
return(0); return(0);
} /* else }
FCEU_printf("\n"); */
UNIF_CHRROMSize += t;
chr_idx[chr_chip_count] = z;
chr_chip_count++;
SetupCartCHRMapping(z, malloced[16 + z], t, 0);
return(1); return(1);
} }
#define NO_BUSC 1
struct _unif_db {
uint64 partialMD5;
char *boardname;
int submapper;
int mirroring;
int special; /* TODO: for bus conflicts, set 1 for no bus_conflict */
};
static struct _unif_db unif_db[] = {
{ 0x8ebad077d08e6c78ULL, "A65AS", 1, -1 }, /* 3-in-1 (N080) [p1][U][!], not a real submapper */
{ 0x117181328eb1ad23ULL, "CNROM", 0, MI_H, NO_BUSC }, /* 75 Bingo (Sachen-English) [U] */
{ 0x616851e56946893bULL, "RESETNROM-XIN1", 0, MI_V }, /* Sheng Tian 2-in-1(Unl,ResetBase)[p1].unf */
{ 0x4cd729b5ae23a3cfULL, "RESETNROM-XIN1", 0, MI_H }, /* Sheng Tian 2-in-1(Unl,ResetBase)[p2].unf */
{ 0, NULL, -1, -1, -1 } /* end of the line */
};
static void CheckHashInfo(void) {
unsigned x = 0;
uint64 partialMD5 = 0;
for (x = 0; x < 8; x++)
partialMD5 |= (uint64)UNIFCart.MD5[15 - x] << (x * 8);
x = 0;
do {
if (partialMD5 == unif_db[x].partialMD5) {
FCEU_printf("\n");
FCEU_PrintError(" The UNIF header contains incorrect information.\n");
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 = (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);
submapper = unif_db[x].submapper;
}
if (unif_db[x].mirroring >= 0 && unif_db[x].mirroring != mirrortodo) {
static char *stuffo[6] = { "Horizontal", "Vertical", "$2000", "$2400", "\"Four-screen\"", "Controlled by Mapper Hardware" };
FCEU_PrintError(" Mirroring should be set to %s\n", stuffo[unif_db[x].mirroring]);
mirrortodo = unif_db[x].mirroring;
}
if (unif_db[x].special >= 0 && unif_db[x].special != cspecial) {
if (!(strcmp((char*)sboardname, "CNROM"))) {
FCEU_PrintError(" Special flags applied, No bus conflict.\n");
cspecial = unif_db[x].special;
}
}
/* todo special case aka, dipswitches, busc-like in fk23c/a, etc */
FCEU_printf("\n");
}
x++;
} while (unif_db[x].partialMD5 > 0);
}
#define NO_INES -1
#define BMCFLAG_FORCE4 0x01 #define BMCFLAG_FORCE4 0x01
#define BMCFLAG_16KCHRR 0x02 #define BMCFLAG_16KCHRR 0x02
#define BMCFLAG_32KCHRR 0x04 #define BMCFLAG_32KCHRR 0x04
@@ -316,160 +407,202 @@ static int LoadCHR(FCEUFILE *fp) {
#define BMCFLAG_256KCHRR 0x10 #define BMCFLAG_256KCHRR 0x10
static BMAPPING bmap[] = { static BMAPPING bmap[] = {
{ "11160", BMC11160_Init, 0 }, { "11160", 299, BMC11160_Init, 0 },
{ "12-IN-1", BMC12IN1_Init, 0 }, { "12-IN-1", 331, BMC12IN1_Init, 0 },
{ "13in1JY110", BMC13in1JY110_Init, 0 }, { "13in1JY110", 295, BMC13in1JY110_Init, 0 },
{ "190in1", BMC190in1_Init, 0 }, { "190in1", 300, BMC190in1_Init, 0 },
{ "22211", UNL22211_Init, 0 }, { "22211", 132, UNL22211_Init, 0 },
{ "3D-BLOCK", UNL3DBlock_Init, 0 }, { "3D-BLOCK", 355, UNL3DBlock_Init, 0 },
{ "411120-C", BMC411120C_Init, 0 }, { "411120-C", 287, BMC411120C_Init, 0 },
{ "42in1ResetSwitch", Mapper226_Init, 0 }, { "42in1ResetSwitch", 233, Mapper233_Init, 0 },
{ "43272", UNL43272_Init, 0 }, { "43272", 227, UNL43272_Init, 0 },
{ "603-5052", UNL6035052_Init, 0 }, { "603-5052", 238, UNL6035052_Init, 0 },
{ "64in1NoRepeat", BMC64in1nr_Init, 0 }, { "64in1NoRepeat", 314, BMC64in1nr_Init, 0 },
{ "70in1", BMC70in1_Init, 0 }, { "70in1", 236, BMC70in1_Init, 0 },
{ "70in1B", BMC70in1B_Init, 0 }, { "70in1B", 236, BMC70in1B_Init, 0 },
{ "810544-C-A1", BMC810544CA1_Init, 0 }, { "810544-C-A1", 261, BMC810544CA1_Init, 0 },
{ "8157", UNL8157_Init, 0 }, { "8157", 301, UNL8157_Init, 0 },
{ "8237", UNL8237_Init, 0 }, { "8237", 215, UNL8237_Init, 0 },
{ "8237A", UNL8237A_Init, 0 }, { "8237A", 215, UNL8237A_Init, 0 },
{ "830118C", BMC830118C_Init, 0 }, { "830118C", 348, BMC830118C_Init, 0 },
{ "A65AS", BMCA65AS_Init, 0 }, { "A65AS", 285, BMCA65AS_Init, 0 },
{ "AC08", AC08_Init, 0 }, { "AC08", NO_INES, AC08_Init, 0 }, /* Mapper 42.. but not.. Used for Green Beret */
{ "ANROM", ANROM_Init, 0 }, { "ANROM", 7, ANROM_Init, 0 },
{ "AX5705", UNLAX5705_Init, 0 }, { "AX5705", 530, UNLAX5705_Init, 0 },
{ "BB", UNLBB_Init, 0 }, { "BB", 108, UNLBB_Init, 0 },
{ "BS-5", BMCBS5_Init, 0 }, { "BS-5", 286, BMCBS5_Init, 0 },
{ "CC-21", UNLCC21_Init, 0 }, { "CC-21", 27, UNLCC21_Init, 0 },
{ "CITYFIGHT", UNLCITYFIGHT_Init, 0 }, { "CITYFIGHT", 266, UNLCITYFIGHT_Init, 0 },
{ "10-24-C-A1", BMC1024CA1_Init, 0 }, { "10-24-C-A1", 327, BMC1024CA1_Init, 0 },
{ "CNROM", CNROM_Init, 0 }, { "CNROM", 3, CNROM_Init, 0 },
{ "CPROM", CPROM_Init, BMCFLAG_16KCHRR }, { "CPROM", 13, CPROM_Init, BMCFLAG_16KCHRR },
{ "D1038", BMCD1038_Init, 0 }, { "D1038", 59, BMCD1038_Init, 0 },
{ "DANCE", UNLOneBus_Init, 0 }, /* redundant */ { "DANCE", 256, UNLOneBus_Init, 0 }, /* redundant */
{ "DANCE2000", UNLD2000_Init, 0 }, { "DANCE2000", 518, UNLD2000_Init, 0 },
{ "DREAMTECH01", DreamTech01_Init, 0 }, { "DREAMTECH01", 521, DreamTech01_Init, 0 },
{ "EDU2000", UNLEDU2000_Init, 0 }, { "EDU2000", 329, UNLEDU2000_Init, 0 },
{ "EKROM", EKROM_Init, 0 }, { "EKROM", 5, EKROM_Init, 0 },
{ "ELROM", ELROM_Init, 0 }, { "ELROM", 5, ELROM_Init, 0 },
{ "ETROM", ETROM_Init, 0 }, { "ETROM", 5, ETROM_Init, 0 },
{ "EWROM", EWROM_Init, 0 }, { "EWROM", 5, EWROM_Init, 0 },
{ "FK23C", BMCFK23C_Init, BMCFLAG_256KCHRR }, { "FK23C", 176, BMCFK23C_Init, BMCFLAG_256KCHRR },
{ "FK23CA", BMCFK23CA_Init, BMCFLAG_256KCHRR }, { "FK23CA", 176, BMCFK23CA_Init, BMCFLAG_256KCHRR },
{ "FS304", UNLFS304_Init, 0 }, { "FS304", 162, UNLFS304_Init, 0 },
{ "G-146", BMCG146_Init, 0 }, { "G-146", 349, BMCG146_Init, 0 },
{ "GK-192", BMCGK192_Init, 0 }, { "GK-192", NO_INES, BMCGK192_Init, 0 }, /* mapper 58? */
{ "GS-2004", BMCGS2004_Init, 0 }, { "GS-2004", 283, BMCGS2004_Init, 0 },
{ "GS-2013", BMCGS2013_Init, 0 }, { "GS-2013", 283, BMCGS2013_Init, 0 },
{ "Ghostbusters63in1", BMCGhostbusters63in1_Init, 0 }, { "Ghostbusters63in1", 226, Mapper226_Init, 0 },
{ "H2288", UNLH2288_Init, 0 }, { "H2288", 123, UNLH2288_Init, 0 },
{ "HKROM", HKROM_Init, 0 }, { "HKROM", 4, HKROM_Init, 0 },
{ "KOF97", UNLKOF97_Init, 0 }, { "KOF97", 263, UNLKOF97_Init, 0 },
{ "KONAMI-QTAI", Mapper190_Init, 0 }, { "KONAMI-QTAI", NO_INES, Mapper190_Init, 0 },
{ "KS7012", UNLKS7012_Init, 0 }, { "KS7012", 346, UNLKS7012_Init, 0 },
{ "KS7013B", UNLKS7013B_Init, 0 }, { "KS7013B", 312, UNLKS7013B_Init, 0 },
{ "KS7016", UNLKS7016_Init, 0 }, { "KS7016", 306, UNLKS7016_Init, 0 },
{ "KS7017", UNLKS7017_Init, 0 }, { "KS7017", 303, UNLKS7017_Init, 0 },
{ "KS7030", UNLKS7030_Init, 0 }, { "KS7030", 347, UNLKS7030_Init, 0 },
{ "KS7031", UNLKS7031_Init, 0 }, { "KS7031", 305, UNLKS7031_Init, 0 },
{ "KS7032", UNLKS7032_Init, 0 }, { "KS7032", 142, UNLKS7032_Init, 0 },
{ "KS7037", UNLKS7037_Init, 0 }, { "KS7037", 307, UNLKS7037_Init, 0 },
{ "KS7057", UNLKS7057_Init, 0 }, { "KS7057", 302, UNLKS7057_Init, 0 },
{ "LE05", LE05_Init, 0 }, { "LE05", NO_INES, LE05_Init, 0 },
{ "LH10", LH10_Init, 0 }, { "LH10", 522, LH10_Init, 0 },
{ "LH32", LH32_Init, 0 }, { "LH32", 125, LH32_Init, 0 },
{ "LH53", LH53_Init, 0 }, { "LH53", 535, LH53_Init, 0 },
{ "MALISB", UNLMaliSB_Init, 0 }, { "MALISB", 325, UNLMaliSB_Init, 0 },
{ "MARIO1-MALEE2", MALEE_Init, 0 }, { "MARIO1-MALEE2", 42, MALEE_Init, 0 },
{ "MHROM", MHROM_Init, 0 }, { "MHROM", 66, MHROM_Init, 0 },
{ "N625092", UNLN625092_Init, 0 }, { "N625092", 221, UNLN625092_Init, 0 },
{ "NROM", NROM_Init, 0 }, { "NROM", 0, NROM_Init, 0 },
{ "NROM-128", NROM_Init, 0 }, { "NROM-128", 0, NROM_Init, 0 },
{ "NROM-256", NROM_Init, 0 }, { "NROM-256", 0, NROM_Init, 0 },
{ "NTBROM", Mapper68_Init, 0 }, { "NTBROM", 68, Mapper68_Init, 0 },
{ "NTD-03", BMCNTD03_Init, 0 }, { "NTD-03", 290, BMCNTD03_Init, 0 },
{ "NovelDiamond9999999in1", Novel_Init, 0 }, { "NovelDiamond9999999in1", 201, Novel_Init, 0 },
{ "OneBus", UNLOneBus_Init, 0 }, { "OneBus", 256, UNLOneBus_Init, 0 },
{ "PEC-586", UNLPEC586Init, 0 }, { "PEC-586", NO_INES, UNLPEC586Init, 0 },
{ "RROM", NROM_Init, 0 }, { "RROM", 0, NROM_Init, 0 },
{ "RROM-128", NROM_Init, 0 }, { "RROM-128", 0, NROM_Init, 0 },
{ "SA-002", TCU02_Init, 0 }, { "SA-002", 136, TCU02_Init, 0 },
{ "SA-0036", SA0036_Init, 0 }, { "SA-0036", 149, SA0036_Init, 0 },
{ "SA-0037", SA0037_Init, 0 }, { "SA-0037", 148, SA0037_Init, 0 },
{ "SA-009", SA009_Init, 0 }, { "SA-009", 160, SA009_Init, 0 },
{ "SA-016-1M", SA0161M_Init, 0 }, { "SA-016-1M", 146, SA0161M_Init, 0 },
{ "SA-72007", SA72007_Init, 0 }, { "SA-72007", 145, SA72007_Init, 0 },
{ "SA-72008", SA72008_Init, 0 }, { "SA-72008", 133, SA72008_Init, 0 },
{ "SA-9602B", SA9602B_Init, BMCFLAG_32KCHRR }, { "SA-9602B", 513, SA9602B_Init, BMCFLAG_32KCHRR },
{ "SA-NROM", TCA01_Init, 0 }, { "SA-NROM", 143, TCA01_Init, 0 },
{ "SAROM", SAROM_Init, 0 }, { "SAROM", 1, SAROM_Init, 0 },
{ "SBROM", SBROM_Init, 0 }, { "SBROM", 1, SBROM_Init, 0 },
{ "SC-127", UNLSC127_Init, 0 }, { "SC-127", 35, UNLSC127_Init, 0 },
{ "SCROM", SCROM_Init, 0 }, { "SCROM", 1, SCROM_Init, 0 },
{ "SEROM", SEROM_Init, 0 }, { "SEROM", 1, SEROM_Init, 0 },
{ "SGROM", SGROM_Init, 0 }, { "SGROM", 1, SGROM_Init, 0 },
{ "SHERO", UNLSHeroes_Init, 0 }, { "SHERO", 262, UNLSHeroes_Init, 0 },
{ "SKROM", SKROM_Init, 0 }, { "SKROM", 1, SKROM_Init, 0 },
{ "SL12", UNLSL12_Init, 0 }, { "SL12", 116, UNLSL12_Init, 0 },
{ "SL1632", UNLSL1632_Init, 0 }, { "SL1632", 14, UNLSL1632_Init, 0 },
{ "SL1ROM", SL1ROM_Init, 0 }, { "SL1ROM", 1, SL1ROM_Init, 0 },
{ "SLROM", SLROM_Init, 0 }, { "SLROM", 1, SLROM_Init, 0 },
{ "SMB2J", UNLSMB2J_Init, 0 }, { "SMB2J", 304, UNLSMB2J_Init, 0 },
{ "SNROM", SNROM_Init, 0 }, { "SNROM", 1, SNROM_Init, 0 },
{ "SOROM", SOROM_Init, 0 }, { "SOROM", 1, SOROM_Init, 0 },
{ "SSS-NROM-256", SSSNROM_Init, 0 }, { "SSS-NROM-256", NO_INES, SSSNROM_Init, 0 },
{ "SUNSOFT_UNROM", SUNSOFT_UNROM_Init, 0 }, /* fix me, real pcb name, real pcb type */ { "SUNSOFT_UNROM", 93, SUNSOFT_UNROM_Init, 0 }, /* fix me, real pcb name, real pcb type */
{ "Sachen-74LS374N", S74LS374N_Init, 0 }, { "Sachen-74LS374N", 150, S74LS374N_Init, 0 },
{ "Sachen-74LS374NA", S74LS374NA_Init, 0 }, /* seems to be custom mapper */ { "Sachen-74LS374NA", 243, S74LS374NA_Init, 0 }, /* seems to be custom mapper */
{ "Sachen-8259A", S8259A_Init, 0 }, { "Sachen-8259A", 141, S8259A_Init, 0 },
{ "Sachen-8259B", S8259B_Init, 0 }, { "Sachen-8259B", 138, S8259B_Init, 0 },
{ "Sachen-8259C", S8259C_Init, 0 }, { "Sachen-8259C", 139, S8259C_Init, 0 },
{ "Sachen-8259D", S8259D_Init, 0 }, { "Sachen-8259D", 137, S8259D_Init, 0 },
{ "Super24in1SC03", Super24_Init, 0 }, { "Super24in1SC03", 176, Super24_Init, 0 },
{ "SuperHIK8in1", Mapper45_Init, 0 }, { "Super24in1SC03", 176, Super24_Init, 0 },
{ "Supervision16in1", Supervision16_Init, 0 }, { "SuperHIK8in1", 45, Mapper45_Init, 0 },
{ "T-227-1", BMCT2271_Init, 0 }, { "Supervision16in1", 53, Supervision16_Init, 0 },
{ "T-230", UNLT230_Init, 0 }, { "T-227-1", NO_INES, BMCT2271_Init, 0 },
{ "T-262", BMCT262_Init, 0 }, { "T-230", 529, UNLT230_Init, 0 },
{ "TBROM", TBROM_Init, 0 }, { "T-262", 265, BMCT262_Init, 0 },
{ "TC-U01-1.5M", TCU01_Init, 0 }, { "TBROM", 4, TBROM_Init, 0 },
{ "TEK90", Mapper90_Init, 0 }, { "TC-U01-1.5M", 147, TCU01_Init, 0 },
{ "TEROM", TEROM_Init, 0 }, { "TEK90", 90, Mapper90_Init, 0 },
{ "TF1201", UNLTF1201_Init, 0 }, { "TEROM", 4, TEROM_Init, 0 },
{ "TFROM", TFROM_Init, 0 }, { "TF1201", 298, UNLTF1201_Init, 0 },
{ "TGROM", TGROM_Init, 0 }, { "TFROM", 4, TFROM_Init, 0 },
{ "TKROM", TKROM_Init, 0 }, { "TGROM", 4, TGROM_Init, 0 },
{ "TKSROM", TKSROM_Init, 0 }, { "TKROM", 4, TKROM_Init, 0 },
{ "TLROM", TLROM_Init, 0 }, { "TKSROM", 118, TKSROM_Init, 0 },
{ "TLSROM", TLSROM_Init, 0 }, { "TLROM", 4, TLROM_Init, 0 },
{ "TQROM", TQROM_Init, 0 }, { "TLSROM", 118, TLSROM_Init, 0 },
{ "TR1ROM", TFROM_Init, BMCFLAG_FORCE4 }, { "TQROM", 119, TQROM_Init, 0 },
{ "TSROM", TSROM_Init, 0 }, { "TR1ROM", 4, TFROM_Init, BMCFLAG_FORCE4 },
{ "TVROM", TLROM_Init, BMCFLAG_FORCE4 }, { "TSROM", 4, TSROM_Init, 0 },
{ "Transformer", Transformer_Init, 0 }, { "TVROM", 4, TLROM_Init, BMCFLAG_FORCE4 },
{ "UNROM", UNROM_Init, 0 }, { "Transformer", NO_INES, Transformer_Init, 0 },
{ "UNROM-512-8", UNROM512_Init, 0 }, { "UNROM", 2, UNROM_Init, 0 },
{ "UNROM-512-16", UNROM512_Init, BMCFLAG_16KCHRR }, { "UNROM-512-8", 30, UNROM512_Init, 0 },
{ "UNROM-512-32", UNROM512_Init, BMCFLAG_32KCHRR }, { "UNROM-512-16", 30, UNROM512_Init, BMCFLAG_16KCHRR },
{ "UOROM", UNROM_Init, 0 }, { "UNROM-512-32", 30, UNROM512_Init, BMCFLAG_32KCHRR },
{ "VRC7", UNLVRC7_Init, 0 }, { "UOROM", 2, UNROM_Init, 0 },
{ "YOKO", UNLYOKO_Init, 0 }, { "VRC7", 85, UNLVRC7_Init, 0 },
{ "COOLBOY", COOLBOY_Init, BMCFLAG_256KCHRR }, { "YOKO", 264, UNLYOKO_Init, 0 },
{ "158B", UNL158B_Init, 0 }, { "COOLBOY", 268, COOLBOY_Init, BMCFLAG_256KCHRR },
{ "DRAGONFIGHTER", UNLBMW8544_Init, 0 }, { "158B", 258, UNL158B_Init, 0 },
{ "EH8813A", UNLEH8813A_Init, 0 }, { "DRAGONFIGHTER", 292, UNLBMW8544_Init, 0 },
{ "HP898F", BMCHP898F_Init, 0 }, { "EH8813A", 519, UNLEH8813A_Init, 0 },
{ "F-15", BMCF15_Init, 0 }, { "HP898F", 319, BMCHP898F_Init, 0 },
{ "RT-01", UNLRT01_Init, 0 }, { "F-15", 259, BMCF15_Init, 0 },
{ "81-01-31-C", BMC810131C_Init, 0 }, { "RT-01", 328, UNLRT01_Init, 0 },
{ "8-IN-1", BMC8IN1_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 #ifdef COPYFAMI
{ "COPYFAMI_MMC3", MapperCopyFamiMMC3_Init, 0 }, { "COPYFAMI_MMC3", NO_INES, MapperCopyFamiMMC3_Init, 0 },
{ "COPYFAMI", MapperCopyFami_Init, 0 }, { "COPYFAMI", NO_INES, MapperCopyFami_Init, 0 },
#endif #endif
{ NULL, NULL, 0 } { NULL, NO_INES, NULL, 0 }
}; };
static BFMAPPING bfunc[] = { static BFMAPPING bfunc[] = {
@@ -521,7 +654,7 @@ static int InitializeBoard(void) {
while (bmap[x].name) { while (bmap[x].name) {
if (!strcmp((char*)sboardname, (char*)bmap[x].name)) { if (!strcmp((char*)sboardname, (char*)bmap[x].name)) {
if (!malloced[16]) { if (VROM_size == 0) {
if (bmap[x].flags & BMCFLAG_16KCHRR) if (bmap[x].flags & BMCFLAG_16KCHRR)
CHRRAMSize = 16; CHRRAMSize = 16;
else if (bmap[x].flags & BMCFLAG_32KCHRR) else if (bmap[x].flags & BMCFLAG_32KCHRR)
@@ -542,12 +675,19 @@ static int InitializeBoard(void) {
if (bmap[x].flags & BMCFLAG_FORCE4) if (bmap[x].flags & BMCFLAG_FORCE4)
mirrortodo = 4; mirrortodo = 4;
MooMirroring(); MooMirroring();
PRGchip_max = prg_chip_count - 1;
if (chr_chip_count)
CHRchip_max = chr_chip_count - 1;
UNIFCart.submapper = submapper;
GameInfo->cspecial = cspecial;
bmap[x].init(&UNIFCart); bmap[x].init(&UNIFCart);
return(1); return(1);
} }
x++; x++;
} }
FCEU_PrintError("Board type not supported."); FCEU_PrintError("Board type not supported, '%s'.", boardname);
return(0); return(0);
} }
@@ -571,6 +711,10 @@ static void UNIFGI(int h) {
} }
int UNIFLoad(const char *name, FCEUFILE *fp) { 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_fseek(fp, 0, SEEK_SET);
FCEU_fread(&unhead, 1, 4, fp); FCEU_fread(&unhead, 1, 4, fp);
if (memcmp(&unhead, "UNIF", 4)) if (memcmp(&unhead, "UNIF", 4))
@@ -586,21 +730,54 @@ int UNIFLoad(const char *name, FCEUFILE *fp) {
goto aborto; goto aborto;
if (!LoadUNIFChunks(fp)) if (!LoadUNIFChunks(fp))
goto aborto; 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++) ROM_size = FixRomSize(UNIF_PRGROMSize, 2048);
if (malloced[x]) { if (UNIF_CHRROMSize)
md5_update(&md5, malloced[x], mallocedsizes[x]); VROM_size = FixRomSize(UNIF_CHRROMSize, 8192);
}
md5_finish(&md5, UNIFCart.MD5); ROM = (uint8*)malloc(ROM_size);
FCEU_printf(" ROM MD5: 0x%s\n", md5_asciistr(UNIFCart.MD5)); if (VROM_size)
memcpy(GameInfo->MD5, UNIFCart.MD5, sizeof(UNIFCart.MD5)); 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()) if (!InitializeBoard())
goto aborto; goto aborto;

View File

@@ -157,6 +157,40 @@ void BMCF15_Init(CartInfo *info);
void UNLRT01_Init(CartInfo *info); void UNLRT01_Init(CartInfo *info);
void BMC810131C_Init(CartInfo *info); void BMC810131C_Init(CartInfo *info);
void BMC8IN1_Init(CartInfo *info); void BMC8IN1_Init(CartInfo *info);
void BMC80013B_Init(CartInfo *info);
void BMC60311C_Init(CartInfo *info); /* m289 */
void BMCWS_Init(CartInfo *info); /* m332 */
void UNLKS202_Init(CartInfo *info); /* m056 */
void BMCHPxx_Init(CartInfo *info); /* m260 */
void BMCRESETNROMXIN1_Init(CartInfo *info);
void BMCKS106C_Init(CartInfo *info);
void UNLTH21311_Init(CartInfo *info); /* m308 */
void LH51_Init(CartInfo *info); /* m309 */
void BMCRESETTXROM_Init(CartInfo *info); /* m313 */
void FARIDSLROM8IN1_Init(CartInfo *info); /* m323 */
void BMC830425C4391T_Init(CartInfo *info); /* m320 */
void BMCTJ03_Init(CartInfo *info); /* m341 */
void BMCCTC09_Init(CartInfo *info); /* m335 */
void BMCK3046_Init(CartInfo *info); /* m336 */
void BMCSA005A_Init(CartInfo *info); /* m338 */
void BMCK3006_Init(CartInfo *info); /* m339 */
void BMCK3036_Init(CartInfo *info); /* m340 */
void MINDKIDS_Init(CartInfo *info); /* m268 */
void UNLKS7021A_Init(CartInfo *info); /* m525 */
void BTL900218_Init(CartInfo *info); /* m524 */
void UNLAX40G_Init(CartInfo *info); /* m527 */
void BMCK3088_Init(CartInfo *info); /* m287 */
void BMCSFGAME4IN1_Init(CartInfo *info); /* m049 */
void UNLBJ56_Init(CartInfo *info); /* m526 */
void BMCL6IN1_Init(CartInfo *info); /* m345 */
void BMCCTC12IN1_Init(CartInfo *info); /* m337 */
void BMC891227_Init(CartInfo *info); /* m350 */
void FARIDUNROM_Init(CartInfo *info); /* m324 */
void BMCK3033_Init(CartInfo *info); /* mm22 */
void BMC830134C_Init(CartInfo *info); /* m315 */
void BMCGN26_Init(CartInfo *info); /* m344 */
#ifdef COPYFAMI #ifdef COPYFAMI
void MapperCopyFamiMMC3_Init(CartInfo *info); void MapperCopyFamiMMC3_Init(CartInfo *info);

View File

@@ -34,6 +34,7 @@
typedef struct { typedef struct {
char *name; char *name;
int gameid;
uint64 md5partial; uint64 md5partial;
int mapper; int mapper;
int mirroring; int mirroring;
@@ -245,48 +246,45 @@ RC2C05-04:
VSUNIENTRY VSUniGames[] = VSUNIENTRY VSUniGames[] =
{ {
{ "Baseball", 0x691d4200ea42be45LL, 99, 2, RP2C04_0001, 0 }, { "Baseball", VS_BASEBALL, 0x691d4200ea42be45LL, 99, 2, RP2C04_0001, 0 },
{ "Battle City", 0x8540949d74c4d0ebLL, 99, 2, RP2C04_0001, 0 }, { "Battle City", VS_BATTLECITY, 0x8540949d74c4d0ebLL, 99, 2, RP2C04_0001, 0 },
{ "Battle City(Bootleg)", 0x8093cbe7137ac031LL, 99, 2, RP2C04_0001, 0 }, { "Battle City(Bootleg)", VS_BATTLECITY, 0x8093cbe7137ac031LL, 99, 2, RP2C04_0001, 0 },
{ "Clu Clu Land", VS_CLUCLULAND, 0x1b8123218f62b1eeLL, 99, 2, RP2C04_0004, IOPTION_SWAPDIRAB },
{ "Clu Clu Land", 0x1b8123218f62b1eeLL, 99, 2, RP2C04_0004, IOPTION_SWAPDIRAB }, { "Dr Mario", VS_DRMARIO, 0xe1af09c477dc0081LL, 1, 0, RP2C04_0003, IOPTION_SWAPDIRAB },
{ "Dr Mario", 0xe1af09c477dc0081LL, 1, 0, RP2C04_0003, IOPTION_SWAPDIRAB }, { "Duck Hunt", VS_DUCKHUNT, 0x47735d1e5f1205bbLL, 99, 2, RCP2C03B, IOPTION_GUN },
{ "Duck Hunt", 0x47735d1e5f1205bbLL, 99, 2, RCP2C03B, IOPTION_GUN }, { "Excitebike", VS_EXITEBIKE, 0x3dcd1401bcafde77LL, 99, 2, RP2C04_0003, 0 },
{ "Excitebike", 0x3dcd1401bcafde77LL, 99, 2, RP2C04_0003, 0 }, { "Excitebike (J)", VS_EXITEBIKE, 0x7ea51c9d007375f0LL, 99, 2, RP2C04_0004, 0 },
{ "Excitebike (J)", 0x7ea51c9d007375f0LL, 99, 2, RP2C04_0004, 0 }, { "Freedom Force", VS_FREEDOMFORCE, 0xed96436bd1b5e688LL, 4, 0, RP2C04_0001, IOPTION_GUN }, /* Wrong color in game select screen? */
{ "Freedom Force", 0xed96436bd1b5e688LL, 4, 0, RP2C04_0001, IOPTION_GUN }, /* Wrong color in game select screen? */ { "Stroke and Match Golf", VS_STROKEANDMATCHGOLF, 0x612325606e82bc66LL, 99, 2, RP2C04_0002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x01 },
{ "Stroke and Match Golf", 0x612325606e82bc66LL, 99, 2, RP2C04_0002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x01 }, { "Goonies", VS_GOONIES, 0xb4032d694e1d2733LL, 151, 1, RP2C04_0003, 0 },
{ "Gradius", VS_GRADIUS, 0x50687ae63bdad976LL, 151, 1, RP2C04_0001, IOPTION_SWAPDIRAB },
{ "Goonies", 0xb4032d694e1d2733LL, 151, 1, RP2C04_0003, 0 }, { "Gumshoe", VS_GUMSHOE, 0x87161f8ee37758d3LL, 99, 2, RC2C05_03, IOPTION_GUN },
{ "Gradius", 0x50687ae63bdad976LL, 151, 1, RP2C04_0001, IOPTION_SWAPDIRAB }, { "Gumshoe", VS_GUMSHOE, 0xb8500780bf69ce29LL, 99, 2, RC2C05_03, IOPTION_GUN },
{ "Gumshoe", 0x87161f8ee37758d3LL, 99, 2, RC2C05_03, IOPTION_GUN }, { "Gumshoe", VS_GUMSHOE, 0xa6bf132ba11d0a8cLL, 99, 2, RC2C05_03, IOPTION_GUN }, /* Gumshoe (VS).nes added: 2017-9-5*/
{ "Gumshoe", 0xb8500780bf69ce29LL, 99, 2, RC2C05_03, IOPTION_GUN }, { "Hogan's Alley", VS_HOGANSALLEY, 0xd78b7f0bb621fb45LL, 99, 2, RP2C04_0001, IOPTION_GUN },
{ "Gumshoe", 0xa6bf132ba11d0a8cLL, 99, 2, RC2C05_03, IOPTION_GUN }, /* Gumshoe (VS).nes added: 2017-9-5*/ { "Ice Climber", VS_ICECLIMBER, 0xd21e999513435e2aLL, 99, 2, RP2C04_0004, IOPTION_SWAPDIRAB },
{ "Hogan's Alley", 0xd78b7f0bb621fb45LL, 99, 2, RP2C04_0001, IOPTION_GUN }, { "Ladies Golf", VS_LADIESGOLF, 0x781b24be57ef6785LL, 99, 2, RP2C04_0002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 },
{ "Ice Climber", 0xd21e999513435e2aLL, 99, 2, RP2C04_0004, IOPTION_SWAPDIRAB }, { "Mach Rider", VS_MACHRIDER, 0x015672618af06441LL, 99, 2, RP2C04_0002, 0 },
{ "Ladies Golf", 0x781b24be57ef6785LL, 99, 2, RP2C04_0002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 }, { "Mach Rider (J)", VS_MACHRIDER, 0xa625afb399811a8aLL, 99, 2, RP2C04_0001, 0 },
{ "Mighty Bomb Jack", VS_MIGHTYBOMBJACK, 0xe6a89f4873fac37bLL, 0, 2, RC2C05_02, 0 },
{ "Mach Rider", 0x015672618af06441LL, 99, 2, RP2C04_0002, 0 }, { "Ninja Jajamaru Kun", VS_JAJAMARU, 0xb26a2c31474099c0LL, 99, 2, RC2C05_01, IOPTION_SWAPDIRAB },
{ "Mach Rider (J)", 0xa625afb399811a8aLL, 99, 2, RP2C04_0001, 0 }, { "Pinball", VS_PINBALL, 0xc5f49d3de7f2e9b8LL, 99, 2, RP2C04_0001, IOPTION_PREDIP, 0x01 },
{ "Mighty Bomb Jack", 0xe6a89f4873fac37bLL, 0, 2, RC2C05_02, 0 }, { "Pinball (J)", VS_PINBALL, 0x66ab1a3828cc901cLL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x1 },
{ "Ninja Jajamaru Kun", 0xb26a2c31474099c0LL, 99, 2, RC2C05_01, IOPTION_SWAPDIRAB }, { "Platoon", VS_PLATOON, 0x160f237351c19f1fLL, 68, 1, RP2C04_0001, 0 },
{ "Pinball", 0xc5f49d3de7f2e9b8LL, 99, 2, RP2C04_0001, IOPTION_PREDIP, 0x01 }, { "RBI Baseball", VS_RBIBASEBALL, 0x6a02d345812938afLL, 4, 1, RP2C04_0001, IOPTION_SWAPDIRAB },
{ "Pinball (J)", 0x66ab1a3828cc901cLL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x1 }, { "Soccer", VS_SOCCER, 0xd4e7a9058780eda3LL, 99, 2, RP2C04_0003, IOPTION_SWAPDIRAB },
{ "Platoon", 0x160f237351c19f1fLL, 68, 1, RP2C04_0001, 0 }, { "Star Luster", VS_STARLUSTER, 0x8360e134b316d94cLL, 99, 2, RCP2C03B, 0 },
{ "RBI Baseball", 0x6a02d345812938afLL, 4, 1, RP2C04_0001, IOPTION_SWAPDIRAB }, { "Stroke and Match Golf (J)", VS_STROKEANDMATCHGOLF, 0x869bb83e02509747LL, 99, 2, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 },
{ "Soccer", 0xd4e7a9058780eda3LL, 99, 2, RP2C04_0003, IOPTION_SWAPDIRAB }, { "Super Sky Kid", VS_SUPERSKYKID, 0x78d04c1dd4ec0101LL, 4, 1, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x20 },
{ "Star Luster", 0x8360e134b316d94cLL, 99, 2, RCP2C03B, 0 }, { "Super Xevious", VS_SUPERXEVIOUS, 0x2d396247cf58f9faLL, 206, 0, RP2C04_0001, 0 },
{ "Stroke and Match Golf (J)", 0x869bb83e02509747LL, 99, 2, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 }, { "Tetris", VS_TETRIS, 0x531a5e8eea4ce157LL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x20 },
{ "Super Sky Kid", 0x78d04c1dd4ec0101LL, 4, 1, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x20 }, { "Top Gun", VS_TOPGUN, 0xf1dea36e6a7b531dLL, 2, 0, RC2C05_04, 0 },
{ "VS Castlevania", VS_CASTLEVANIA, 0x92fd6909c81305b9LL, 2, 1, RP2C04_0002, 0 },
{ "Super Xevious", 0x2d396247cf58f9faLL, 206, 0, RP2C04_0001, 0 }, { "VS Slalom", VS_SLALOM, 0x4889b5a50a623215LL, 0, 1, RP2C04_0002, 0 },
{ "Tetris", 0x531a5e8eea4ce157LL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x20 }, { "VS Super Mario Bros", VS_SMB, 0x39d8cfa788e20b6cLL, 99, 2, RP2C04_0004, 0 },
{ "Top Gun", 0xf1dea36e6a7b531dLL, 2, 0, RC2C05_04, 0 }, { "VS Super Mario Bros [a1]", VS_SMB, 0xfc182e5aefbce14dLL, 99, 2, RP2C04_0004, 0 },
{ "VS Castlevania", 0x92fd6909c81305b9LL, 2, 1, RP2C04_0002, 0 }, { "VS TKO Boxing", VS_TKOBOXING, 0x6e1ee06171d8ce3aLL, 206, 1, RP2C04_0003, IOPTION_PREDIP, 0x00 },
{ "VS Slalom", 0x4889b5a50a623215LL, 0, 1, RP2C04_0002, 0 }, { "VS TKO Boxing [a1]", VS_TKOBOXING, 0xa1c694ce147bc1edLL, 206, 1, RP2C04_0003, IOPTION_PREDIP, 0x00 },
{ "VS Super Mario Bros", 0x39d8cfa788e20b6cLL, 99, 2, RP2C04_0004, 0 },
{ "VS Super Mario Bros [a1]", 0xfc182e5aefbce14dLL, 99, 2, RP2C04_0004, 0 },
{ "VS TKO Boxing", 0x6e1ee06171d8ce3aLL, 4, 1, RP2C04_0003, IOPTION_PREDIP, 0x00 },
{ 0 } { 0 }
}; };
@@ -302,18 +300,19 @@ void FCEU_VSUniCheck(uint64 md5partial, int *MapperNo, uint8 *Mirroring) {
GameInfo->type = GIT_VSUNI; GameInfo->type = GIT_VSUNI;
GameInfo->cspecial = SIS_VSUNISYSTEM; GameInfo->cspecial = SIS_VSUNISYSTEM;
GameInfo->inputfc = SIFC_NONE; GameInfo->inputfc = SIFC_NONE;
GameInfo->gameid = vs->gameid;
curppu = vs->ppu; curppu = vs->ppu;
curmd5 = md5partial; curmd5 = md5partial;
FCEU_printf(" System: VS-UniSystem\n");
FCEU_printf(" Name: %s\n", vs->name);
secptr = 0; secptr = 0;
{ if (vs->gameid == VS_TKOBOXING)
static int64 tko = 0x6e1ee06171d8ce3aULL, rbi = 0x6a02d345812938afULL; secptr = secdata[0];
if (md5partial == tko) if (vs->gameid == VS_RBIBASEBALL)
secptr = secdata[0]; secptr = secdata[1];
if (md5partial == rbi)
secptr = secdata[1];
}
vsdip = 0x0; vsdip = 0x0;
if (vs->ioption & IOPTION_PREDIP) { if (vs->ioption & IOPTION_PREDIP) {

View File

@@ -9,4 +9,37 @@ void FCEU_VSUniToggleDIP(int); /* For movies and netplay */
void FCEU_VSUniCoin(void); void FCEU_VSUniCoin(void);
void FCEU_VSUniSwap(uint8 *j0, uint8 *j1); void FCEU_VSUniSwap(uint8 *j0, uint8 *j1);
enum {
VS_BASEBALL = 1,
VS_BATTLECITY,
VS_CASTLEVANIA,
VS_CLUCLULAND,
VS_DRMARIO,
VS_DUCKHUNT,
VS_EXITEBIKE,
VS_FREEDOMFORCE,
VS_GOONIES,
VS_GRADIUS,
VS_GUMSHOE,
VS_HOGANSALLEY,
VS_ICECLIMBER,
VS_JAJAMARU,
VS_LADIESGOLF,
VS_MACHRIDER,
VS_MIGHTYBOMBJACK,
VS_PINBALL,
VS_PLATOON,
VS_RBIBASEBALL,
VS_SLALOM,
VS_SMB,
VS_SOCCER,
VS_STARLUSTER,
VS_STROKEANDMATCHGOLF,
VS_SUPERSKYKID,
VS_SUPERXEVIOUS,
VS_TETRIS,
VS_TKOBOXING,
VS_TOPGUN
};
#endif #endif