From a81cd5fcb5967a808c941ac952a92958c67dff37 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 6 May 2020 05:13:47 +0800 Subject: [PATCH 001/295] Fix build when compiling without NTSC filter support - broke on last commit - fixed 3ds build --- src/drivers/libretro/libretro.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 52d2c93..73d1eff 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -970,7 +970,11 @@ void retro_get_system_av_info(struct retro_system_av_info *info) #endif info->geometry.base_width = width; info->geometry.base_height = height; +#ifdef HAVE_NTSC_FILTER info->geometry.max_width = (use_ntsc ? NTSC_WIDTH : NES_WIDTH); +#else + info->geometry.max_width = NES_WIDTH; +#endif info->geometry.max_height = NES_HEIGHT; info->geometry.aspect_ratio = (float)(use_par ? NES_8_7_PAR : NES_4_3); info->timing.sample_rate = (float)sndsamplerate; From 542b8e64cbaae9114ed04c93f899025a2622457b Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 6 May 2020 05:45:24 +0800 Subject: [PATCH 002/295] Use proper geometry when switching ntsc filter on or off - Width changes previously was not respected when using ntsc filter. With full use of overscan, nes width is 602 px when ntsc filter is used and 256 px on normal --- src/drivers/libretro/libretro.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 73d1eff..ab6e46f 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -968,13 +968,14 @@ void retro_get_system_av_info(struct retro_system_av_info *info) unsigned width = NES_WIDTH - (overscan_h ? 16 : 0); unsigned height = NES_HEIGHT - (overscan_v ? 16 : 0); #endif - info->geometry.base_width = width; - info->geometry.base_height = height; #ifdef HAVE_NTSC_FILTER + info->geometry.base_width = (use_ntsc ? NES_NTSC_OUT_WIDTH(width) : width); info->geometry.max_width = (use_ntsc ? NTSC_WIDTH : NES_WIDTH); #else + info->geometry.base_width = width; info->geometry.max_width = NES_WIDTH; #endif + info->geometry.base_height = height; info->geometry.max_height = NES_HEIGHT; info->geometry.aspect_ratio = (float)(use_par ? NES_8_7_PAR : NES_4_3); info->timing.sample_rate = (float)sndsamplerate; From 6b9899848c6cd6f4c91ad735087871c9c553b7b9 Mon Sep 17 00:00:00 2001 From: Autechre Date: Wed, 6 May 2020 01:05:16 +0200 Subject: [PATCH 003/295] Update Makefile.libretro --- Makefile.libretro | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index 42f51bc..b23ced1 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -726,7 +726,7 @@ ifneq (,$(findstring msvc,$(platform))) COREDEFINES += -DINLINE=_inline endif -CFLAGS += -DWANT_GRIFFIN -Werror=implicit-function-declaration +CFLAGS += -DWANT_GRIFFIN OBJECTS := $(SOURCES_C:.c=.o) OBJECTS += $(RETROARCH_OBJECTS) @@ -743,7 +743,7 @@ else ifneq (,$(findstring msvc,$(platform))) WARNING_DEFINES = LIBM := else -WARNING_DEFINES = -Wno-write-strings +WARNING_DEFINES = -Wno-write-strings -Werror=implicit-function-declaration endif CFLAGS += $(fpic) $(WARNING_DEFINES) $(DEFINES) $(ENDIANNESS_DEFINES) From d023887b85e645659ef6a0632dbe5a2015b29232 Mon Sep 17 00:00:00 2001 From: negativeExponent <54053706+negativeExponent@users.noreply.github.com> Date: Wed, 6 May 2020 14:21:33 +0800 Subject: [PATCH 004/295] Update Makefile.libretro --- Makefile.libretro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.libretro b/Makefile.libretro index b23ced1..b71d0a4 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -743,7 +743,7 @@ else ifneq (,$(findstring msvc,$(platform))) WARNING_DEFINES = LIBM := else -WARNING_DEFINES = -Wno-write-strings -Werror=implicit-function-declaration +WARNING_DEFINES = -Wno-write-strings endif CFLAGS += $(fpic) $(WARNING_DEFINES) $(DEFINES) $(ENDIANNESS_DEFINES) From 83457362e70f92d6c89974afc5aac80f59bbfe38 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 12 May 2020 09:44:31 +0800 Subject: [PATCH 005/295] ines-correct.h: Fix MMC1 overrides MMC1 overrides are treated as ines 2.0, so its needs at least default values for prgRam and chrRam columns. Fixes FF1 pink screen due to unmapped chrram. --- src/ines-correct.h | 61 +++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/ines-correct.h b/src/ines-correct.h index ea9f9f3..7410d1a 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -5,21 +5,22 @@ don't have battery-backed RAM is not that big of a problem, so I'll treat this differently by only listing games that should have battery-backed RAM. */ - { 0xb17574f3, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* AD&D Heroes of the Lance */ - { 0x5de61639, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* AD&D Hillsfar */ - { 0x2545214c, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* DW */ - { 0x3b3f88f0, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* DW */ - { 0x8c5a784e, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* DW 2 */ - { 0x506e259d, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* DW 4*/ - { 0xa86a5318, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dw 3 */ - { 0x45f03d2e, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Faria */ - { 0xb8b88130, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Final Fantasy (FFE Hack) */ - { 0xcebd2a31, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Final Fantasy */ - { 0xd29db3c7, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Final Fantasy 2 */ - { 0x466efdc2, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Final Fantasy J */ - { 0xeaf7ed72, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Legend of Zelda */ - { 0x3fe272fb, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Legend of Zelda */ - { 0xba322865, 1, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Zelda 2 */ + /* CRC32, mapperNum, SubMapper, Mirroring, hasBattery, prgRam, chrRam, region, extra flags */ + { 0xb17574f3, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* AD&D Heroes of the Lance */ + { 0x5de61639, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* AD&D Hillsfar */ + { 0x2545214c, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* DW */ + { 0x3b3f88f0, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* DW */ + { 0x8c5a784e, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* DW 2 */ + { 0x506e259d, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* DW 4*/ + { 0xa86a5318, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Dw 3 */ + { 0x45f03d2e, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Faria */ + { 0xb8b88130, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy (FFE Hack) */ + { 0xcebd2a31, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy */ + { 0xd29db3c7, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy 2 */ + { 0x466efdc2, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy J */ + { 0xeaf7ed72, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Legend of Zelda */ + { 0x3fe272fb, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Legend of Zelda */ + { 0xba322865, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Zelda 2 */ { 0x25952141, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* AD&D Pool of Radiance */ { 0x1335cb05, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Crystalis */ { 0x57e220d0, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Final Fantasy 3 */ @@ -58,31 +59,31 @@ { 0x5b837e8d, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Alien Syndrome (Japan).nes */ { 0x37ba3261, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Back to the Future Part II & III (USA).nes */ { 0x5b6ca654, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Barbie (USA).nes */ - { 0x61a852ea, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Battle Stadium - Senbatsu Pro Yakyuu (Japan).nes */ + { 0x61a852ea, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Battle Stadium - Senbatsu Pro Yakyuu (Japan).nes */ { 0xf6fa4453, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bigfoot (U) [b4].nes */ - { 0x391aa1b8, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bloody Warriors - Shan-Go no Gyakushuu (Japan).nes */ + { 0x391aa1b8, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Bloody Warriors - Shan-Go no Gyakushuu (Japan).nes */ { 0xa5e8d2cd, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* BreakThru (USA).nes */ - { 0x3f56a392, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain ED (Japan).nes */ - { 0x078ced30, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Choujin - Ultra Baseball (Japan).nes */ - { 0xfe364be5, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Deep Dungeon IV - Kuro no Youjutsushi (Japan).nes */ + { 0x3f56a392, 1, DEFAULT, DFAULT8, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Captain ED (Japan).nes */ + { 0x078ced30, 1, DEFAULT, DFAULT8, 1, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* Choujin - Ultra Baseball (Japan).nes */ + { 0xfe364be5, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Deep Dungeon IV - Kuro no Youjutsushi (Japan).nes */ { 0x57c12280, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Demon Sword (U) [b1].nes */ { 0xd09b74dc, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Great Tank (Japan).nes */ - { 0xe8baa782, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Gunhed - Aratanaru Tatakai (Japan).nes */ - { 0x970bd9c2, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Hanjuku Eiyuu (J) [b1].nes */ - { 0xcd7a2fd7, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Hanjuku Hero (Japan).nes */ - { 0x63469396, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Hokuto no Ken 4 - Shichisei Haken Den - Hokuto Shinken no Kanata e (Japan).nes */ - { 0xe94d5181, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Future Wars - Mirai Senshi Lios (Japan).nes */ - { 0x7156cb4d, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Muppet Adventure - Chaos at the Carnival (USA).nes */ - { 0x70f67ab7, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Musashi no Bouken (Japan).nes */ + { 0xe8baa782, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Gunhed - Aratanaru Tatakai (Japan).nes */ + { 0x970bd9c2, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hanjuku Eiyuu (J) [b1].nes */ + { 0xcd7a2fd7, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hanjuku Hero (Japan).nes */ + { 0x63469396, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hokuto no Ken 4 - Shichisei Haken Den - Hokuto Shinken no Kanata e (Japan).nes */ + { 0xe94d5181, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Future Wars - Mirai Senshi Lios (Japan).nes */ + { 0x7156cb4d, 1, DEFAULT, DFAULT8, 0, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Muppet Adventure - Chaos at the Carnival (USA).nes */ + { 0x70f67ab7, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Musashi no Bouken (Japan).nes */ { 0x958e4bae, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Orb-3D (USA).nes */ - { 0x291bcd7d, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pachio-kun 2 (Japan).nes */ - { 0xa9a4ea4c, 1, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Satomi Hakkenden (J) [b2].nes */ + { 0x291bcd7d, 1, DEFAULT, DFAULT8, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Pachio-kun 2 (Japan).nes */ + { 0xa9a4ea4c, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Satomi Hakkenden (J) [b2].nes */ { 0xcc3544b0, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Triathron, The (Japan).nes */ { 0x52ab2d17, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Toukyou Pachi-Slot Adventure (Japan).nes */ { 0x934db14a, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* All-Pro Basketball (USA).nes */ { 0xf74dfc91, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Win, Lose or Draw (USA).nes */ { 0xcfe02ada, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Darkman (Europe).nes */ - { 0x1a71fd06, 1, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kujaku Ou.nes */ + { 0x1a71fd06, 1, DEFAULT, MI_H, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Kujaku Ou.nes */ /* MMC1 games with more than 8K wram */ { 0x2225c20f, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* Genghis Khan */ From ed784833dd3539ec30479e62537e482c9670181a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 17 May 2020 23:09:23 +0200 Subject: [PATCH 006/295] Buildfix --- src/input/zapper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/input/zapper.c b/src/input/zapper.c index 7729e5b..a0a7dd2 100644 --- a/src/input/zapper.c +++ b/src/input/zapper.c @@ -163,10 +163,12 @@ static uint32 InefficientSqrt(uint32 z) { } #endif -void FCEU_ZapperSetTolerance(int t) { +void FCEU_ZapperSetTolerance(int t) +{ #ifdef ROUNDED_TARGET + uint32_t y; tolerance = t <= MAX_TOLERANCE ? t : MAX_TOLERANCE; - for (uint32 y = 0 ; y <= tolerance ; y++) + for (y = 0; y <= tolerance; y++) targetExpansion[y] = InefficientSqrt(tolerance*tolerance-y*y); #else tolerance = t; From 9604a33f7a4b90c8c4236d36b509c1ba98089cc0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 17 May 2020 23:30:06 +0200 Subject: [PATCH 007/295] MSVC2010 buildfix --- Makefile.libretro | 2 +- src/input/zapper.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index b71d0a4..6f17bc9 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -84,7 +84,7 @@ else ifeq ($(platform), osx) fpic := -fPIC SHARED := -dynamiclib ifeq ($(arch),ppc) - ENDIANNESS_DEFINES += -DMSB_FIRST + ENDIANNESS_DEFINES += -DMSB_FIRST -DHAVE_NO_LANGEXTRA endif OSXVER = `sw_vers -productVersion | cut -d. -f 2` OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"` diff --git a/src/input/zapper.c b/src/input/zapper.c index a0a7dd2..776f51a 100644 --- a/src/input/zapper.c +++ b/src/input/zapper.c @@ -58,10 +58,11 @@ static void FP_FASTAPASS(3) ZapperFrapper(int w, uint8 * bg, uint8 * spr, uint32 if (scanline >= (zy - tolerance) && scanline <= (zy + tolerance)) { #ifdef ROUNDED_TARGET + int spread; int dy = scanline - zy; if (dy < 0) dy = -dy; - int spread = targetExpansion[dy]; + spread = targetExpansion[dy]; #else int spread = tolerance; #endif From c68bfd4c7f42f587837c462fd32ae53564f14129 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Tue, 19 May 2020 21:03:22 +0200 Subject: [PATCH 008/295] Adapt ps2 port to latest SDK Status --- Makefile.libretro | 7 +- ps2/SMS_Utils.s | 202 ------------------ ps2/inttypes.h | 8 - ps2/stdint.h | 33 --- .../include/libretro_gskit_ps2.h | 6 +- src/drivers/libretro/libretro.c | 7 - 6 files changed, 4 insertions(+), 259 deletions(-) delete mode 100644 ps2/SMS_Utils.s delete mode 100644 ps2/inttypes.h delete mode 100644 ps2/stdint.h diff --git a/Makefile.libretro b/Makefile.libretro index 6f17bc9..509515e 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -174,15 +174,12 @@ else ifeq ($(platform), ps2) AR = ee-ar$(EXE_EXT) FCEU_DEFINES := -DPATH_MAX=1024 -DINLINE=inline -DPSS_STYLE=1 -DFCEU_VERSION_NUMERIC=9813 -DHAVE_ASPRINTF ENDIANNESS_DEFINES := -DLSB_FIRST -DLOCAL_LE=1 - PLATFORM_DEFINES := -DPS2 -G0 -DFRONTEND_SUPPORTS_ABGR1555 -DRENDER_GSKIT_PS2 - PLATFORM_DEFINES += -Dmemcpy=mips_memcpy -Dmemset=mips_memset - PLATFORM_DEFINES += -I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include -Ips2/ -I$(PS2DEV)/gsKit/include + PLATFORM_DEFINES := -DPS2 -D_EE -G0 -DFRONTEND_SUPPORTS_ABGR1555 -DRENDER_GSKIT_PS2 + PLATFORM_DEFINES += -I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include -I$(PS2DEV)/gsKit/include STATIC_LINKING=1 EXTERNAL_ZLIB=1 - RETROARCH_OBJECTS += ps2/SMS_Utils.o HAVE_NTSC = 0 - # PSP else ifeq ($(platform), psp1) TARGET := $(TARGET_NAME)_libretro_$(platform).a diff --git a/ps2/SMS_Utils.s b/ps2/SMS_Utils.s deleted file mode 100644 index e437356..0000000 --- a/ps2/SMS_Utils.s +++ /dev/null @@ -1,202 +0,0 @@ -/* -# ___ _ _ ___ -# | | | | | -# ___| | | ___| PS2DEV Open Source Project. -#---------------------------------------------------------- -# MUL64 is pulled from some binary library (I don't remember which one). -# mips_memcpy routine is pulled from 'sde' library from MIPS. -# -*/ -.set noat -.set noreorder -.set nomacro - -.globl MUL64 -.globl mips_memcpy -.globl mips_memset - -.text - -MUL64: - pmultuw $v0, $a0, $a1 - dsra32 $a2, $a0, 0 - dsra32 $v1, $a1, 0 - mult $v1, $a0, $v1 - mult1 $a2, $a2, $a1 - addu $v1, $v1, $a2 - dsll32 $v1, $v1, 0 - jr $ra - daddu $v0, $v0, $v1 - -mips_memcpy: - addu $v0, $a0, $zero - beqz $a2, 1f - sltiu $t2, $a2, 12 - bnez $t2, 2f - xor $v1, $a1, $a0 - andi $v1, $v1, 7 - negu $a3, $a0 - beqz $v1, 3f - andi $a3, $a3, 7 - beqz $a3, 4f - subu $a2, $a2, $a3 - ldr $v1, 0($a1) - ldl $v1, 7($a1) - addu $a1, $a1, $a3 - sdr $v1, 0($a0) - addu $a0, $a0, $a3 -4: - andi $v1, $a2, 31 - subu $a3, $a2, $v1 - beqz $a3, 5f - addu $a2, $v1, $zero - addu $a3, $a3, $a1 -6: - ldr $v1, 0($a1) - ldl $v1, 7($a1) - ldr $t0, 8($a1) - ldl $t0, 15($a1) - ldr $t1, 16($a1) - ldl $t1, 23($a1) - ldr $t2, 24($a1) - ldl $t2, 31($a1) - sd $v1, 0($a0) - sd $t0, 8($a0) - sd $t1, 16($a0) - addiu $a1, $a1, 32 - addiu $a0, $a0, 32 - bne $a1, $a3, 6b - sd $t2, -8($a0) -5: - andi $v1, $a2, 7 - subu $a3, $a2, $v1 - beqz $a3, 2f - addu $a2, $v1, $zero - addu $a3, $a3, $a1 -7: - ldr $v1, 0($a1) - ldl $v1, 7($a1) - addiu $a1, $a1, 8 - addiu $a0, $a0, 8 - nop - bne $a1, $a3, 7b - sd $v1, -8($a0) - beq $zero, $zero, 2f - nop -3: - beqz $a3, 8f - subu $a2, $a2, $a3 - ldr $v1, 0($a1) - addu $a1, $a1, $a3 - sdr $v1, 0($a0) - addu $a0, $a0, $a3 -8: - andi $v1, $a2, 31 - subu $a3, $a2, $v1 - beqz $a3, 9f - addu $a2, $v1, $zero - addu $a3, $a3, $a1 -10: - ld $v1, 0($a1) - ld $t0, 8($a1) - ld $t1, 16($a1) - ld $t2, 24($a1) - sd $v1, 0($a0) - sd $t0, 8($a0) - sd $t1, 16($a0) - addiu $a1, $a1, 32 - addiu $a0, $a0, 32 - bne $a1, $a3, 10b - sd $t2, -8($a0) -9: - andi $v1, $a2, 7 - subu $a3, $a2, $v1 - beqz $a3, 2f - addu $a2, $v1, $zero - addu $a3, $a3, $a1 -11: - ld $v1, 0($a1) - addiu $a1, $a1, 8 - addiu $a0, $a0, 8 - nop - nop - bne $a1, $a3, 11b - sd $v1, -8($a0) -2: - beqz $a2, 1f - addu $a3, $a2, $a1 -12: - lbu $v1, 0($a1) - addiu $a1, $a1, 1 - addiu $a0, $a0, 1 - nop - nop - bne $a1, $a3, 12b - sb $v1, -1($a0) -1: - jr $ra - nop - -mips_memset: - beqz $a2, 1f - sltiu $at, $a2, 16 - bnez $at, 2f - andi $a1, $a1, 0xFF - dsll $at, $a1, 0x8 - or $a1, $a1, $at - dsll $at, $a1, 0x10 - or $a1, $a1, $at - dsll32 $at, $a1, 0x0 - or $a1, $a1, $at - andi $v1, $a0, 0x7 - beqz $v1, 3f - li $a3, 8 - subu $a3, $a3, $v1 - subu $a2, $a2, $a3 - sdr $a1, 0($a0) - addu $a0, $a0, $a3 -3: - andi $v1, $a2, 0x1f - subu $a3, $a2, $v1 - beqz $a3, 4f - move $a2, $v1 - addu $a3, $a3, $a0 -5: - sd $a1, 0($a0) - sd $a1, 8($a0) - sd $a1, 16($a0) - addiu $a0, $a0, 32 - sd $a1, -8($a0) - bne $a0, $a3, 5b -4: - andi $v1, $a2, 0x7 - subu $a3, $a2, $v1 - beqz $a3, 2f - move $a2, $v1 - addu $a3, $a3, $a0 -6: - addiu $a0, $a0, 8 - beq $a0, $a3, 2f - sd $a1, -8($a0) - addiu $a0, $a0, 8 - beq $a0, $a3, 2f - sd $a1, -8($a0) - addiu $a0, $a0, 8 - bne $a0, $a3, 6b - sd $a1, -8($a0) -2: - beqz $a2, 1f - addu $a3, $a2, $a0 -7: - addiu $a0, $a0, 1 - beq $a0, $a3, 1f - sb $a1, -1($a0) - addiu $a0, $a0, 1 - beq $a0, $a3, 1f - sb $a1, -1($a0) - addiu $a0, $a0, 1 - bne $a0, $a3, 7b - sb $a1, -1($a0) -1: - jr $ra - nop diff --git a/ps2/inttypes.h b/ps2/inttypes.h deleted file mode 100644 index 3049fbd..0000000 --- a/ps2/inttypes.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef INTTYPES_H -#define INTTYPES_H - -#define PRId64 "ld" -#define PRIu64 "lu" -#define PRIuPTR "lu" - -#endif //INTTYPES_H diff --git a/ps2/stdint.h b/ps2/stdint.h deleted file mode 100644 index ae9a75b..0000000 --- a/ps2/stdint.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef STDINT_H -#define STDINT_H - -typedef unsigned long uintptr_t; -typedef signed long intptr_t; - -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef signed long int64_t; -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long uint64_t; - -typedef unsigned long uint_least32_t; -typedef unsigned short uint_least16_t; - -#define STDIN_FILENO 0 /* standard input file descriptor */ -#define STDOUT_FILENO 1 /* standard output file descriptor */ -#define STDERR_FILENO 2 /* standard error file descriptor */ - -#define INT8_C(val) val##c -#define INT16_C(val) val##h -#define INT32_C(val) val##i -#define INT64_C(val) val##l - -#define UINT8_C(val) val##uc -#define UINT16_C(val) val##uh -#define UINT32_C(val) val##ui -#define UINT64_C(val) val##ul - -#endif //STDINT_H diff --git a/src/drivers/libretro/libretro-common/include/libretro_gskit_ps2.h b/src/drivers/libretro/libretro-common/include/libretro_gskit_ps2.h index f7b61dc..033bb1f 100644 --- a/src/drivers/libretro/libretro-common/include/libretro_gskit_ps2.h +++ b/src/drivers/libretro/libretro-common/include/libretro_gskit_ps2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro_d3d.h) @@ -33,7 +33,7 @@ #include -#define RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION 1 +#define RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION 2 struct retro_hw_ps2_insets { @@ -57,8 +57,6 @@ struct retro_hw_render_interface_gskit_ps2 * in this interface. */ GSTEXTURE *coreTexture; - bool clearTexture; - bool updatedPalette; struct retro_hw_ps2_insets padding; }; typedef struct retro_hw_render_interface_gskit_ps2 RETRO_HW_RENDER_INTEFACE_GSKIT_PS2; diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 127b95f..1a7e286 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1063,12 +1063,6 @@ static void retro_set_custom_palette(void) } FCEUI_SetPaletteArray( base_palette ); } - -#if defined(RENDER_GSKIT_PS2) - if (ps2) { - ps2->updatedPalette = true; - } -#endif } /* Set variables for NTSC(1) / PAL(2) / Dendy(3) @@ -1840,7 +1834,6 @@ static void retro_run_blit(uint8_t *gfx) overscan_h ? 8.0f : 0.0f}; } - ps2->updatedPalette = true; ps2->coreTexture->Clut = (u32*)retro_palette; ps2->coreTexture->Mem = (u32*)gfx; From 86c29c0a5c314c9df78de0d6587fcf8224ada4d0 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Tue, 19 May 2020 22:14:04 +0200 Subject: [PATCH 009/295] Add CICD for ps2-platform --- .github/workflows/compilation.yml | 33 +++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/compilation.yml diff --git a/.github/workflows/compilation.yml b/.github/workflows/compilation.yml new file mode 100644 index 0000000..02f4cef --- /dev/null +++ b/.github/workflows/compilation.yml @@ -0,0 +1,33 @@ +name: CI + +on: + push: + pull_request: + repository_dispatch: + types: [run_build] + +jobs: + build-ps2: + runs-on: ubuntu-latest + container: ps2dev/ps2dev:latest + steps: + - uses: actions/checkout@v2 + + - name: Install dependencies + run: | + apk add build-base git bash + + - name: Compile project + run: | + make -f Makefile.libretro platform=ps2 clean all + + - name: Get short SHA + id: slug + run: echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)" + + - name: Upload artifacts + if: ${{ success() }} + uses: actions/upload-artifact@v2 + with: + name: fceumm_libretro_ps2-${{ steps.slug.outputs.sha8 }} + path: fceumm_libretro_ps2.a From 48b80d3230f12158d46d3dd97b37d90f27506343 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Thu, 4 Jun 2020 13:26:02 +0800 Subject: [PATCH 010/295] Fix input not working on big-endian systems (regression fix) Fix https://github.com/libretro/libretro-fceumm/issues/372 --- src/drivers/libretro/libretro.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 1a7e286..d63b05f 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -123,7 +123,7 @@ typedef struct { uint32_t type[MAX_PLAYERS + 1]; /* 4-players + famicom expansion */ /* input data */ - uint8_t JSReturn[MAX_PLAYERS]; /* 1-4 player data */ + uint32_t JSReturn; /* player input data, 1 byte per player (1-4) */ uint32_t MouseData[MAX_PORTS][3]; /* nes mouse data */ uint32_t FamicomData; /* Famicom expansion port data */ } NES_INPUT_T; @@ -751,7 +751,7 @@ static void update_nes_controllers(unsigned port, unsigned device) case RETRO_DEVICE_GAMEPAD: default: nes_input.type[port] = RETRO_DEVICE_GAMEPAD; - FCEUI_SetInput(port, SI_GAMEPAD, (uint32_t*)nes_input.JSReturn, 0); + FCEUI_SetInput(port, SI_GAMEPAD, &nes_input.JSReturn, 0); FCEU_printf(" Player %u: Gamepad\n", port + 1); break; } @@ -774,7 +774,7 @@ static void update_nes_controllers(unsigned port, unsigned device) FCEU_printf(" Famicom Expansion: Oeka Kids Tablet\n"); break; case RETRO_DEVICE_FC_4PLAYERS: - FCEUI_SetInputFC(SIFC_4PLAYER, (uint32_t*)nes_input.JSReturn, 0); + FCEUI_SetInputFC(SIFC_4PLAYER, &nes_input.JSReturn, 0); FCEU_printf(" Famicom Expansion: Famicom 4-Player Adapter\n"); break; case RETRO_DEVICE_NONE: @@ -1636,6 +1636,9 @@ static void FCEUD_UpdateInput(void) poll_cb(); + /* Reset input states */ + nes_input.JSReturn = 0; + /* nes gamepad */ for (player = 0; player < MAX_PLAYERS; player++) { @@ -1715,7 +1718,7 @@ static void FCEUD_UpdateInput(void) input_buf &= ~((JOY_LEFT ) | (JOY_RIGHT)); } - nes_input.JSReturn[player] = input_buf; + nes_input.JSReturn |= (input_buf & 0xff) << (player << 3); } /* other inputs*/ @@ -2372,7 +2375,7 @@ bool retro_load_game(const struct retro_game_info *game) } for (i = 0; i < MAX_PORTS; i++) { - FCEUI_SetInput(i, SI_GAMEPAD, (uint32_t*)nes_input.JSReturn, 0); + FCEUI_SetInput(i, SI_GAMEPAD, &nes_input.JSReturn, 0); nes_input.type[i] = RETRO_DEVICE_JOYPAD; } @@ -2408,7 +2411,7 @@ bool retro_load_game(const struct retro_game_info *game) if (famicom_4p_db_list[i].crc == iNESCart.CRC32) { GameInfo->inputfc = SIFC_4PLAYER; - FCEUI_SetInputFC(SIFC_4PLAYER, (uint32_t*)nes_input.JSReturn, 0); + FCEUI_SetInputFC(SIFC_4PLAYER, &nes_input.JSReturn, 0); nes_input.enable_4player = true; break; } From aeaae261364959dd87349d4f63047f53baa36855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Sun, 12 Jul 2020 21:04:09 +0700 Subject: [PATCH 011/295] Add Micro Mages to fourscore_db_list --- src/drivers/libretro/libretro.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index d63b05f..ff11195 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -2059,6 +2059,10 @@ static const struct cartridge_db fourscore_db_list[] = "M.U.L.E. (USA)", 0x0939852f }, + { + "Micro Mages", + 0x4e6b9078 + }, { "Monster Truck Rally (USA)", 0x2f698c4d From a20dc87b435cb173cc6e979a0dd9a33f34c173ca Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sat, 25 Jul 2020 14:17:26 +0800 Subject: [PATCH 012/295] Fix SIGSEGV error when using Famicom expansion devices (port 5) --- src/drivers/libretro/libretro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index ff11195..154824b 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -125,7 +125,7 @@ typedef struct { /* input data */ uint32_t JSReturn; /* player input data, 1 byte per player (1-4) */ uint32_t MouseData[MAX_PORTS][3]; /* nes mouse data */ - uint32_t FamicomData; /* Famicom expansion port data */ + uint32_t FamicomData[3]; /* Famicom expansion port data */ } NES_INPUT_T; static NES_INPUT_T nes_input = { 0 }; From 3e50be9cb925ca18ddd553edc16d93c2b29de669 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 31 Aug 2020 10:37:59 +0800 Subject: [PATCH 013/295] Cheat: Add raw format and multiline cheat support - Add handling raw cheat formats Fix https://github.com/libretro/libretro-fceumm/issues/378 - Add multiline cheat support --- src/drivers/libretro/libretro.c | 46 +++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 154824b..2bef7bb 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1966,25 +1966,45 @@ void retro_cheat_reset(void) void retro_cheat_set(unsigned index, bool enabled, const char *code) { char name[256]; + char temp[256]; + char *codepart; uint16 a; uint8 v; int c; int type = 1; + int ret = 0; + + if (code == NULL) + return; + sprintf(name, "N/A"); + strcpy(temp, code); + codepart = strtok(temp, "+,;._ "); - if (FCEUI_DecodeGG(code, &a, &v, &c)) - goto input_cheat; - - /* Not a Game Genie code. */ - - if (FCEUI_DecodePAR(code, &a, &v, &c, &type)) - goto input_cheat; - - /* Not a Pro Action Replay code. */ - - return; -input_cheat: - FCEUI_AddCheat(name, a, v, c, type); + while (codepart) + { + if ((strlen(codepart) == 7) && (codepart[4]==':')) + { + /* raw code format */ + c = -1; + codepart[4] = '\0'; + a = strtoul(codepart, NULL, 16); + v = strtoul(codepart + 5, NULL, 16); + FCEUI_AddCheat(name, a, v, c, type); + log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (Raw)\n", codepart); + } + else if (FCEUI_DecodeGG(codepart, &a, &v, &c)) + { + FCEUI_AddCheat(name, a, v, c, type); + log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (GG)\n", codepart); + } + else if (FCEUI_DecodePAR(codepart, &a, &v, &c, &type)) + { + FCEUI_AddCheat(name, a, v, c, type); + log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (PAR)\n", codepart); + } + codepart = strtok(NULL,"+,;._ "); + } } typedef struct cartridge_db From 0b362afcc03cbcca5b34eddcdb26445d29dcb87e Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 31 Aug 2020 12:49:42 +0800 Subject: [PATCH 014/295] Cheats: Fix pro action replay cheat format Two issues are causiong PAR cheats to not work. 1. GG decoder should only accept specific characters. When it fails, assume PAR code. 2. The corrent code that makes PAR decoding work was not set. Both fixed on this PR with some added notes. --- src/cheat.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/cheat.c b/src/cheat.c index f92e8d4..2602bf5 100644 --- a/src/cheat.c +++ b/src/cheat.c @@ -332,27 +332,33 @@ int FCEUI_DecodeGG(const char *str, uint16 *a, uint8 *v, int *c) { if (s != 6 && s != 8) return(0); t = GGtobin(*str++); + if (!t) return (0); V |= (t & 0x07); V |= (t & 0x08) << 4; t = GGtobin(*str++); + if (!t) return (0); V |= (t & 0x07) << 4; A |= (t & 0x08) << 4; t = GGtobin(*str++); + if (!t) return (0); A |= (t & 0x07) << 4; /* if(t&0x08) return(0); */ /* 8-character code?! */ t = GGtobin(*str++); + if (!t) return (0); A |= (t & 0x07) << 12; A |= (t & 0x08); t = GGtobin(*str++); + if (!t) return (0); A |= (t & 0x07); A |= (t & 0x08) << 8; if (s == 6) { t = GGtobin(*str++); + if (!t) return (0); A |= (t & 0x07) << 8; V |= (t & 0x08); @@ -362,14 +368,17 @@ int FCEUI_DecodeGG(const char *str, uint16 *a, uint8 *v, int *c) { return(1); } else { t = GGtobin(*str++); + if (!t) return (0); A |= (t & 0x07) << 8; C |= (t & 0x08); t = GGtobin(*str++); + if (!t) return (0); C |= (t & 0x07); C |= (t & 0x08) << 4; t = GGtobin(*str++); + if (!t) return (0); C |= (t & 0x07) << 4; V |= (t & 0x08); *a = A; @@ -388,13 +397,21 @@ int FCEUI_DecodePAR(const char *str, uint16 *a, uint8 *v, int *c, int *type) { *c = -1; - if (1) { + /* 2020-08-31 - negativeExponent + * Why is the top code set as default on non-debug runtime when + * bottom code is what works for PAR? + */ + /* if (1) { *a = (boo[3] << 8) | (boo[2] + 0x7F); *v = 0; } else { *v = boo[3]; *a = boo[2] | (boo[1] << 8); - } + } */ + + *v = boo[3]; + *a = boo[2] | (boo[1] << 8); + /* Zero-page addressing modes don't go through the normal read/write handlers in FCEU, so we must do the old hacky method of RAM cheats. */ From 0ca1e69a9d87a91e9aa376564d25793d9ed0be04 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 31 Aug 2020 13:09:40 +0800 Subject: [PATCH 015/295] Cheat: Add raw codes support in xxxx?yy:zz format --- src/drivers/libretro/libretro.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 2bef7bb..11137e3 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1985,11 +1985,22 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) { if ((strlen(codepart) == 7) && (codepart[4]==':')) { - /* raw code format */ - c = -1; + /* raw code in xxxx:xx format */ codepart[4] = '\0'; a = strtoul(codepart, NULL, 16); v = strtoul(codepart + 5, NULL, 16); + c = -1; + FCEUI_AddCheat(name, a, v, c, type); + log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (Raw)\n", codepart); + } + else if ((strlen(codepart) == 10) && (codepart[4] == '?') && (codepart[7] == ':')) + { + /* raw code in xxxx?xx:xx */ + codepart[4] = '\0'; + codepart[7] = '\0'; + a = strtoul(codepart, NULL, 16); + v = strtoul(codepart + 8, NULL, 16); + c = strtoul(codepart + 5, NULL, 16); FCEUI_AddCheat(name, a, v, c, type); log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (Raw)\n", codepart); } From 771822a2e0d93b51d57f9f45ec21f3cdea5471dd Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 31 Aug 2020 13:38:58 +0800 Subject: [PATCH 016/295] Fix logs --- src/drivers/libretro/libretro.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 11137e3..153e746 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1986,23 +1986,23 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) if ((strlen(codepart) == 7) && (codepart[4]==':')) { /* raw code in xxxx:xx format */ + log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (Raw)\n", codepart); codepart[4] = '\0'; a = strtoul(codepart, NULL, 16); v = strtoul(codepart + 5, NULL, 16); c = -1; FCEUI_AddCheat(name, a, v, c, type); - log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (Raw)\n", codepart); } else if ((strlen(codepart) == 10) && (codepart[4] == '?') && (codepart[7] == ':')) { /* raw code in xxxx?xx:xx */ + log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (Raw)\n", codepart); codepart[4] = '\0'; codepart[7] = '\0'; a = strtoul(codepart, NULL, 16); v = strtoul(codepart + 8, NULL, 16); c = strtoul(codepart + 5, NULL, 16); FCEUI_AddCheat(name, a, v, c, type); - log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (Raw)\n", codepart); } else if (FCEUI_DecodeGG(codepart, &a, &v, &c)) { From 11ebeed2acffb8c618bb6e6b56765d199e4815c9 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 1 Sep 2020 23:00:14 +0800 Subject: [PATCH 017/295] Cheats: Fix RAW cheats that use zero-page address --- src/drivers/libretro/libretro.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 153e746..25209c3 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1991,6 +1991,9 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) a = strtoul(codepart, NULL, 16); v = strtoul(codepart + 5, NULL, 16); c = -1; + /* Zero-page addressing modes don't go through the normal read/write handlers in FCEU, so + * we must do the old hacky method of RAM cheats. */ + if (a < 0x0100) type = 0; FCEUI_AddCheat(name, a, v, c, type); } else if ((strlen(codepart) == 10) && (codepart[4] == '?') && (codepart[7] == ':')) @@ -2002,6 +2005,9 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) a = strtoul(codepart, NULL, 16); v = strtoul(codepart + 8, NULL, 16); c = strtoul(codepart + 5, NULL, 16); + /* Zero-page addressing modes don't go through the normal read/write handlers in FCEU, so + * we must do the old hacky method of RAM cheats. */ + if (a < 0x0100) type = 0; FCEUI_AddCheat(name, a, v, c, type); } else if (FCEUI_DecodeGG(codepart, &a, &v, &c)) From f4ef50722287f4fa43fc339b28041deb4d6125fa Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 9 Sep 2020 11:33:36 +0800 Subject: [PATCH 018/295] Cheats: Add check for valid game genie code format - Partially reverts changes in https://github.com/libretro/libretro-fceumm/commit/0b362afcc03cbcca5b34eddcdb26445d29dcb87e - Checks the codestring if its a valid game genie code before attempting to decode it. If code fails, then assume it to be a pro action replay cheat. Issue: Cheats where failing because a value of 0 in the decoder does not mean an error. Fix https://github.com/libretro/libretro-fceumm/issues/384 --- src/cheat.c | 9 --------- src/drivers/libretro/libretro.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/cheat.c b/src/cheat.c index 2602bf5..cdf0aaf 100644 --- a/src/cheat.c +++ b/src/cheat.c @@ -332,33 +332,27 @@ int FCEUI_DecodeGG(const char *str, uint16 *a, uint8 *v, int *c) { if (s != 6 && s != 8) return(0); t = GGtobin(*str++); - if (!t) return (0); V |= (t & 0x07); V |= (t & 0x08) << 4; t = GGtobin(*str++); - if (!t) return (0); V |= (t & 0x07) << 4; A |= (t & 0x08) << 4; t = GGtobin(*str++); - if (!t) return (0); A |= (t & 0x07) << 4; /* if(t&0x08) return(0); */ /* 8-character code?! */ t = GGtobin(*str++); - if (!t) return (0); A |= (t & 0x07) << 12; A |= (t & 0x08); t = GGtobin(*str++); - if (!t) return (0); A |= (t & 0x07); A |= (t & 0x08) << 8; if (s == 6) { t = GGtobin(*str++); - if (!t) return (0); A |= (t & 0x07) << 8; V |= (t & 0x08); @@ -368,17 +362,14 @@ int FCEUI_DecodeGG(const char *str, uint16 *a, uint8 *v, int *c) { return(1); } else { t = GGtobin(*str++); - if (!t) return (0); A |= (t & 0x07) << 8; C |= (t & 0x08); t = GGtobin(*str++); - if (!t) return (0); C |= (t & 0x07); C |= (t & 0x08) << 4; t = GGtobin(*str++); - if (!t) return (0); C |= (t & 0x07) << 4; V |= (t & 0x08); *a = A; diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 25209c3..02dc738 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1958,6 +1958,31 @@ bool retro_unserialize(const void * data, size_t size) return true; } +static int checkGG(char c) +{ + static const char lets[16] = { 'A', 'P', 'Z', 'L', 'G', 'I', 'T', 'Y', 'E', 'O', 'X', 'U', 'K', 'S', 'V', 'N' }; + int x; + + for (x = 0; x < 16; x++) + if (lets[x] == toupper(c)) + return 1; + return 0; +} + +static int GGisvalid(const char *code) +{ + size_t len = strlen(code); + int i; + + if (len != 6 && len != 8) + return 0; + + for (i = 0; i < len; i++) + if (!checkGG(code[i])) + return 0; + return 1; +} + void retro_cheat_reset(void) { FCEU_ResetCheats(); @@ -2010,7 +2035,7 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) if (a < 0x0100) type = 0; FCEUI_AddCheat(name, a, v, c, type); } - else if (FCEUI_DecodeGG(codepart, &a, &v, &c)) + else if (GGisvalid(codepart) && FCEUI_DecodeGG(codepart, &a, &v, &c)) { FCEUI_AddCheat(name, a, v, c, type); log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (GG)\n", codepart); @@ -2020,6 +2045,8 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) FCEUI_AddCheat(name, a, v, c, type); log_cb.log(RETRO_LOG_DEBUG, "Cheat code added: '%s' (PAR)\n", codepart); } + else + log_cb.log(RETRO_LOG_DEBUG, "Invalid or unknown code: '%s'\n", codepart); codepart = strtok(NULL,"+,;._ "); } } From e566538c9972307d702cbb9e8c9dbdb9131c791b Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 9 Sep 2020 11:51:04 +0800 Subject: [PATCH 019/295] Fix warning --- src/drivers/libretro/libretro.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 02dc738..5aa8526 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include From 47f84dea99b36b9365331ca577e6aee83ed17f7f Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Fri, 2 Oct 2020 19:17:55 +0800 Subject: [PATCH 020/295] ntsc: Remove magic numbers and cleanup --- src/drivers/libretro/libretro.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 5aa8526..55088fe 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -633,7 +633,7 @@ struct st_palettes palettes[] = { #define NTSC_RGB 3 #define NTSC_MONOCHROME 4 -#define NTSC_WIDTH 602 +#define NES_NTSC_WIDTH (((NES_NTSC_OUT_WIDTH(256) + 3) >> 2) << 2) static unsigned use_ntsc = 0; static unsigned burst_phase; @@ -652,7 +652,7 @@ static void NTSCFilter_Init(void) { memset(&nes_ntsc, 0, sizeof(nes_ntsc)); memset(&ntsc_setup, 0, sizeof(ntsc_setup)); - ntsc_video_out = (uint16_t *)malloc(NTSC_WIDTH * NES_HEIGHT * sizeof(uint16_t)); + ntsc_video_out = (uint16_t *)malloc(NES_NTSC_WIDTH * NES_HEIGHT * sizeof(uint16_t)); } static void NTSCFilter_Setup(void) @@ -973,7 +973,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info) #endif #ifdef HAVE_NTSC_FILTER info->geometry.base_width = (use_ntsc ? NES_NTSC_OUT_WIDTH(width) : width); - info->geometry.max_width = (use_ntsc ? NTSC_WIDTH : NES_WIDTH); + info->geometry.max_width = (use_ntsc ? NES_NTSC_WIDTH : NES_WIDTH); #else info->geometry.base_width = width; info->geometry.max_width = NES_WIDTH; @@ -1846,34 +1846,33 @@ static void retro_run_blit(uint8_t *gfx) #ifdef HAVE_NTSC_FILTER if (use_ntsc) { - int h_offset, v_offset; - burst_phase ^= 1; if (ntsc_setup.merge_fields) burst_phase = 0; nes_ntsc_blit(&nes_ntsc, (NES_NTSC_IN_T const*)gfx, (NES_NTSC_IN_T *)XDBuf, NES_WIDTH, burst_phase, NES_WIDTH, NES_HEIGHT, - ntsc_video_out, NTSC_WIDTH * sizeof(uint16)); + ntsc_video_out, NES_NTSC_WIDTH * sizeof(uint16)); - h_offset = overscan_h ? NES_NTSC_OUT_WIDTH(8) : 0; - v_offset = overscan_v ? 8 : 0; - width = overscan_h ? 560 : 602; - height = overscan_v ? 224 : 240; + width = NES_WIDTH - (overscan_h ? 16 : 0); + width = NES_NTSC_OUT_WIDTH(width); + height = NES_HEIGHT - (overscan_v ? 16 : 0); pitch = width * sizeof(uint16_t); { - const uint16_t *in = ntsc_video_out + h_offset + NTSC_WIDTH * v_offset; - uint16_t *out = fceu_video_out; - int y; + int32_t h_offset = overscan_h ? NES_NTSC_OUT_WIDTH(8) : 0; + int32_t v_offset = overscan_v ? 8 : 0; + const uint16_t *in = ntsc_video_out + h_offset + NES_NTSC_WIDTH * v_offset; + uint16_t *out = fceu_video_out; for (y = 0; y < height; y++) { - memcpy(out, in, width * sizeof(uint16_t)); - in += NTSC_WIDTH; + memcpy(out, in, pitch); + in += NES_NTSC_WIDTH; out += width; } } + video_cb(fceu_video_out, width, height, pitch); } else #endif /* HAVE_NTSC_FILTER */ @@ -1897,8 +1896,8 @@ static void retro_run_blit(uint8_t *gfx) for (x = 0; x < width; x++, gfx++) fceu_video_out[y * width + x] = retro_palette[*gfx]; } + video_cb(fceu_video_out, width, height, pitch); } - video_cb(fceu_video_out, width, height, pitch); #endif } @@ -2406,7 +2405,7 @@ bool retro_load_game(const struct retro_game_info *game) fceu_video_out = (uint16_t*)linearMemAlign(256 * 240 * sizeof(uint16_t), 128); #elif !defined(PSP) #ifdef HAVE_NTSC_FILTER -#define FB_WIDTH NTSC_WIDTH +#define FB_WIDTH NES_NTSC_WIDTH #define FB_HEIGHT NES_HEIGHT #else /* !HAVE_NTSC_FILTER */ #define FB_WIDTH NES_WIDTH From 6e1d87384677480098e4c054cca5b41692b46c01 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Fri, 2 Oct 2020 19:24:00 +0800 Subject: [PATCH 021/295] Rename overscan-related variables - Rename overscan options to something more readable - Fixes PSP overscan option logic where some places where the option is reversed --- src/drivers/libretro/libretro.c | 68 ++++++++++++++++----------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 55088fe..a88a9cf 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -69,10 +69,10 @@ static retro_input_state_t input_cb = NULL; static retro_audio_sample_batch_t audio_batch_cb = NULL; retro_environment_t environ_cb = NULL; #ifdef PSP -static bool use_overscan; +static bool crop_overscan; #else -static bool overscan_h; -static bool overscan_v; +static bool crop_overscan_h; +static bool crop_overscan_v; #endif static bool use_raw_palette; @@ -965,11 +965,11 @@ void retro_get_system_info(struct retro_system_info *info) void retro_get_system_av_info(struct retro_system_av_info *info) { #ifdef PSP - unsigned width = NES_WIDTH - (use_overscan ? 16 : 0); - unsigned height = NES_HEIGHT - (use_overscan ? 16 : 0); + unsigned width = NES_WIDTH - (crop_overscan ? 16 : 0); + unsigned height = NES_HEIGHT - (crop_overscan ? 16 : 0); #else - unsigned width = NES_WIDTH - (overscan_h ? 16 : 0); - unsigned height = NES_HEIGHT - (overscan_v ? 16 : 0); + unsigned width = NES_WIDTH - (crop_overscan_h ? 16 : 0); + unsigned height = NES_HEIGHT - (crop_overscan_v ? 16 : 0); #endif #ifdef HAVE_NTSC_FILTER info->geometry.base_width = (use_ntsc ? NES_NTSC_OUT_WIDTH(width) : width); @@ -1325,10 +1325,10 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - bool newval = (!strcmp(var.value, "disabled")); - if (newval != use_overscan) + bool newval = (!strcmp(var.value, "enabled")); + if (newval != crop_overscan) { - use_overscan = newval; + crop_overscan = newval; audio_video_updated = 1; } } @@ -1339,9 +1339,9 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { bool newval = (!strcmp(var.value, "enabled")); - if (newval != overscan_h) + if (newval != crop_overscan_h) { - overscan_h = newval; + crop_overscan_h = newval; audio_video_updated = 1; } } @@ -1351,9 +1351,9 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { bool newval = (!strcmp(var.value, "enabled")); - if (newval != overscan_v) + if (newval != crop_overscan_v) { - overscan_v = newval; + crop_overscan_v = newval; audio_video_updated = 1; } } @@ -1544,10 +1544,10 @@ void get_mouse_input(unsigned port, uint32_t *zapdata) int min_width, min_height, max_width, max_height; #ifdef PSP - adjx = adjy = use_overscan ? 1 : 0; + adjx = adjy = crop_overscan ? 1 : 0; #else - adjx = overscan_h ? 1 : 0; - adjy = overscan_v ? 1 : 0; + adjx = crop_overscan_h ? 1 : 0; + adjy = crop_overscan_v ? 1 : 0; #endif max_width = 256; max_height = 240; @@ -1780,7 +1780,7 @@ static void retro_run_blit(uint8_t *gfx) unsigned pitch = 512; #ifdef PSP - if (!use_overscan) + if (crop_overscan) { width -= 16; height -= 16; @@ -1796,10 +1796,10 @@ static void retro_run_blit(uint8_t *gfx) * so we use GU_PSM_4444 ( 2 Bytes per pixel ) instead * with half the values for pitch / width / x offset */ - if (use_overscan) - sceGuCopyImage(GU_PSM_4444, 0, 0, 128, 240, 128, XBuf, 0, 0, 128, texture_vram_p); - else + if (crop_overscan) sceGuCopyImage(GU_PSM_4444, 4, 4, 120, 224, 128, XBuf, 0, 0, 128, texture_vram_p); + else + sceGuCopyImage(GU_PSM_4444, 0, 0, 128, 240, 128, XBuf, 0, 0, 128, texture_vram_p); sceGuTexSync(); sceGuTexImage(0, 256, 256, 256, texture_vram_p); @@ -1832,10 +1832,10 @@ static void retro_run_blit(uint8_t *gfx) ps2->coreTexture->PSM = GS_PSM_T8; ps2->coreTexture->ClutPSM = GS_PSM_CT16; ps2->coreTexture->Filter = GS_FILTER_LINEAR; - ps2->padding = (struct retro_hw_ps2_insets){ overscan_v ? 8.0f : 0.0f, - overscan_h ? 8.0f : 0.0f, - overscan_v ? 8.0f : 0.0f, - overscan_h ? 8.0f : 0.0f}; + ps2->padding = (struct retro_hw_ps2_insets){ crop_overscan_v ? 8.0f : 0.0f, + crop_overscan_h ? 8.0f : 0.0f, + crop_overscan_v ? 8.0f : 0.0f, + crop_overscan_h ? 8.0f : 0.0f}; } ps2->coreTexture->Clut = (u32*)retro_palette; @@ -1854,14 +1854,14 @@ static void retro_run_blit(uint8_t *gfx) NES_WIDTH, burst_phase, NES_WIDTH, NES_HEIGHT, ntsc_video_out, NES_NTSC_WIDTH * sizeof(uint16)); - width = NES_WIDTH - (overscan_h ? 16 : 0); + width = NES_WIDTH - (crop_overscan_h ? 16 : 0); width = NES_NTSC_OUT_WIDTH(width); - height = NES_HEIGHT - (overscan_v ? 16 : 0); + height = NES_HEIGHT - (crop_overscan_v ? 16 : 0); pitch = width * sizeof(uint16_t); { - int32_t h_offset = overscan_h ? NES_NTSC_OUT_WIDTH(8) : 0; - int32_t v_offset = overscan_v ? 8 : 0; + int32_t h_offset = crop_overscan_h ? NES_NTSC_OUT_WIDTH(8) : 0; + int32_t v_offset = crop_overscan_v ? 8 : 0; const uint16_t *in = ntsc_video_out + h_offset + NES_NTSC_WIDTH * v_offset; uint16_t *out = fceu_video_out; @@ -1877,11 +1877,11 @@ static void retro_run_blit(uint8_t *gfx) else #endif /* HAVE_NTSC_FILTER */ { - incr += (overscan_h ? 16 : 0); - width -= (overscan_h ? 16 : 0); - height -= (overscan_v ? 16 : 0); - pitch -= (overscan_h ? 32 : 0); - gfx += (overscan_v ? ((overscan_h ? 8 : 0) + 256 * 8) : (overscan_h ? 8 : 0)); + incr += (crop_overscan_h ? 16 : 0); + width -= (crop_overscan_h ? 16 : 0); + height -= (crop_overscan_v ? 16 : 0); + pitch -= (crop_overscan_h ? 32 : 0); + gfx += (crop_overscan_v ? ((crop_overscan_h ? 8 : 0) + 256 * 8) : (crop_overscan_h ? 8 : 0)); if (use_raw_palette) { From 085efc98a7b5200e51f44240110a6ce4c89b2ba4 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 5 Oct 2020 10:38:44 +0800 Subject: [PATCH 022/295] input: Fix warnings [-Wincompatible-pointer-types] --- src/drivers/libretro/libretro.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index a88a9cf..3f41833 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -763,15 +763,15 @@ static void update_nes_controllers(unsigned port, unsigned device) switch (device) { case RETRO_DEVICE_FC_ARKANOID: - FCEUI_SetInputFC(SIFC_ARKANOID, &nes_input.FamicomData, 0); + FCEUI_SetInputFC(SIFC_ARKANOID, nes_input.FamicomData, 0); FCEU_printf(" Famicom Expansion: Arkanoid\n"); break; case RETRO_DEVICE_FC_SHADOW: - FCEUI_SetInputFC(SIFC_SHADOW, &nes_input.FamicomData, 1); + FCEUI_SetInputFC(SIFC_SHADOW, nes_input.FamicomData, 1); FCEU_printf(" Famicom Expansion: (Bandai) Hyper Shot\n"); break; case RETRO_DEVICE_FC_OEKAKIDS: - FCEUI_SetInputFC(SIFC_OEKAKIDS, &nes_input.FamicomData, 1); + FCEUI_SetInputFC(SIFC_OEKAKIDS, nes_input.FamicomData, 1); FCEU_printf(" Famicom Expansion: Oeka Kids Tablet\n"); break; case RETRO_DEVICE_FC_4PLAYERS: @@ -1740,7 +1740,7 @@ static void FCEUD_UpdateInput(void) case RETRO_DEVICE_FC_ARKANOID: case RETRO_DEVICE_FC_OEKAKIDS: case RETRO_DEVICE_FC_SHADOW: - get_mouse_input(0, &nes_input.FamicomData); + get_mouse_input(0, nes_input.FamicomData); break; } From 0a40774e8628e64457aa57f48736f335f8652dbe Mon Sep 17 00:00:00 2001 From: Autechre Date: Tue, 6 Oct 2020 18:58:56 +0200 Subject: [PATCH 023/295] Create .gitlab-ci.yml --- .gitlab-ci.yml | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..b24ca82 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,65 @@ +.core-defs: + variables: + JNI_PATH: . + CORENAME: fceumm + +include: + - template: Jobs/Code-Quality.gitlab-ci.yml + - project: 'libretro-infrastructure/ci-templates' + file: '/libnx-static.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/linux-x64.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/windows-x64-mingw.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/android-jni.yml' + +stages: + - build-prepare + - build-shared + - build-static + - test + +#Desktop +libretro-build-linux-x64: + extends: + - .core-defs + - .libretro-linux-x64-make-default + variables: + MAKEFILE: Makefile.libretro + +libretro-build-windows-x64: + extends: + - .core-defs + - .libretro-windows-x64-mingw-make-default + variables: + MAKEFILE: Makefile.libretro + +# Android +android-armeabi-v7a: + extends: + - .core-defs + - .libretro-android-jni-armeabi-v7a + +android-arm64-v8a: + extends: + - .core-defs + - .libretro-android-jni-arm64-v8a + +android-x86_64: + extends: + - .core-defs + - .libretro-android-jni-x86_64 + +android-x86: + extends: + - .core-defs + - .libretro-android-jni-x86 + +# Static +libretro-build-libnx-aarch64: + extends: + - .core-defs + - .libretro-libnx-static-retroarch-master + variables: + MAKEFILE: Makefile.libretro From da770d9ac8ba7a0ac2da4824a4abeea53d453984 Mon Sep 17 00:00:00 2001 From: Autechre Date: Tue, 6 Oct 2020 20:33:47 +0200 Subject: [PATCH 024/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b24ca82..90273dc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -40,6 +40,11 @@ android-armeabi-v7a: extends: - .core-defs - .libretro-android-jni-armeabi-v7a + +android-armeabi: + extends: + - .core-defs + - .libretro-android-jni-armeabi android-arm64-v8a: extends: @@ -55,6 +60,16 @@ android-x86: extends: - .core-defs - .libretro-android-jni-x86 + +android-mips: + extends: + - .core-defs + - .libretro-android-jni-mips + +android-mips64: + extends: + - .core-defs + - .libretro-android-jni-mips64 # Static libretro-build-libnx-aarch64: From 5218acf52cf0b0a711703bc3eee8f06c0d62cb70 Mon Sep 17 00:00:00 2001 From: Autechre Date: Tue, 6 Oct 2020 20:37:48 +0200 Subject: [PATCH 025/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 90273dc..b24ca82 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -40,11 +40,6 @@ android-armeabi-v7a: extends: - .core-defs - .libretro-android-jni-armeabi-v7a - -android-armeabi: - extends: - - .core-defs - - .libretro-android-jni-armeabi android-arm64-v8a: extends: @@ -60,16 +55,6 @@ android-x86: extends: - .core-defs - .libretro-android-jni-x86 - -android-mips: - extends: - - .core-defs - - .libretro-android-jni-mips - -android-mips64: - extends: - - .core-defs - - .libretro-android-jni-mips64 # Static libretro-build-libnx-aarch64: From 451a040d26475bba57a364e743ca2858dd13cf78 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 7 Oct 2020 00:07:12 +0200 Subject: [PATCH 026/295] (gitlab) Add vita --- .gitlab-ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b24ca82..ced340e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,6 +7,8 @@ include: - template: Jobs/Code-Quality.gitlab-ci.yml - project: 'libretro-infrastructure/ci-templates' file: '/libnx-static.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/vita-static.yml' - project: 'libretro-infrastructure/ci-templates' file: '/linux-x64.yml' - project: 'libretro-infrastructure/ci-templates' @@ -63,3 +65,10 @@ libretro-build-libnx-aarch64: - .libretro-libnx-static-retroarch-master variables: MAKEFILE: Makefile.libretro + +libretro-build-vita: + extends: + - .core-defs + - .libretro-vita-static-retroarch-master + variables: + MAKEFILE: Makefile.libretro From e03f7adc85012062dc92152a64aa5801d52bb6dd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 7 Oct 2020 00:09:44 +0200 Subject: [PATCH 027/295] Fix warnings --- src/fds_apu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/fds_apu.c b/src/fds_apu.c index 8d67d36..8115c03 100644 --- a/src/fds_apu.c +++ b/src/fds_apu.c @@ -19,11 +19,12 @@ */ /* Begin FDS sound */ - +#include #include "fceu-types.h" #include "x6502.h" #include "fceu.h" #include "sound.h" +#include "state.h" #define FDSClock (1789772.7272727272727272 / 2) @@ -295,4 +296,4 @@ DECLFW(FDSSoundWrite) { void FDSSoundPower(void) { FDSSoundReset(); FDSSoundStateAdd(); -} \ No newline at end of file +} From 5657cb9a1cc24ce9509a09118824a784a492cbb9 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sun, 11 Oct 2020 20:25:44 +0800 Subject: [PATCH 028/295] Add mapper 554 --- src/boards/554.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ines.c | 1 + src/ines.h | 1 + 3 files changed, 79 insertions(+) create mode 100644 src/boards/554.c diff --git a/src/boards/554.c b/src/boards/554.c new file mode 100644 index 0000000..bbb4796 --- /dev/null +++ b/src/boards/554.c @@ -0,0 +1,77 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 negativeExponent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Mapper 554 - Kaiser KS-7010 + * used for one of several cartridge conversions of the FDS version of + * 悪魔城 Dracula, the Japanese version of Castlevania + */ + +#include "mapinc.h" + +static uint8 reg; + +static SFORMAT StateRegs[] = +{ + { ®, 1, "REG" }, + { 0 } +}; + +static void Sync(void) { + setprg8(0x6000, reg); + setprg8(0x8000, 10); + setprg8(0xA000, 11); + setprg8(0xC000, 6); + setprg8(0xE000, 7); + setchr8(reg); +} + +static DECLFR(M554Read) { + if ((A >= 0xCAB6) && (A < 0xCAD7)) + { + reg = (A >> 2) & 0x0F; + Sync(); + } + else if ((A == 0xEBE2) || (A == 0xEE32)) + { + reg = (A >> 2) & 0x0F; + Sync(); + } + else if (A == 0xFFFC) + { + reg = (A >> 2) & 0x0F; + Sync(); + } + return CartBR(A); +} + +static void M554Power(void) { + Sync(); + SetReadHandler(0x6000, 0xFFFF, M554Read); +} + +static void StateRestore(int version) { + Sync(); +} + +void Mapper554_Init(CartInfo *info) { + info->Power = M554Power; + GameStateRestore = StateRestore; + AddExState(&StateRegs, ~0, 0, 0); +} diff --git a/src/ines.c b/src/ines.c index 6d811a0..b974723 100644 --- a/src/ines.c +++ b/src/ines.c @@ -706,6 +706,7 @@ INES_BOARD_BEGIN() INES_BOARD( "82112C", 540, Mapper540_Init ) INES_BOARD( "LittleCom 160-in-1", 541, Mapper541_Init ) INES_BOARD( "5-in-1 (CH-501)", 543, Mapper543_Init ) + INES_BOARD( "KS-7010", 554, Mapper554_Init ) INES_BOARD( "", 550, Mapper550_Init ) /* UNIF to NES 2.0 BOARDS */ diff --git a/src/ines.h b/src/ines.h index 24e0abb..347eeeb 100644 --- a/src/ines.h +++ b/src/ines.h @@ -274,5 +274,6 @@ void Mapper540_Init(CartInfo *); void Mapper541_Init(CartInfo *); void Mapper543_Init(CartInfo *); void Mapper550_Init(CartInfo *); +void Mapper554_Init(CartInfo *); #endif From 8073cfba7e2d21bc69290d86e0ad01b31162103f Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sun, 11 Oct 2020 22:47:48 +0800 Subject: [PATCH 029/295] Add mapper 411 --- src/boards/411.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ines.c | 1 + src/ines.h | 1 + 3 files changed, 87 insertions(+) create mode 100644 src/boards/411.c diff --git a/src/boards/411.c b/src/boards/411.c new file mode 100644 index 0000000..eafa3cc --- /dev/null +++ b/src/boards/411.c @@ -0,0 +1,85 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 negativeExponent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +/* Mapper 411 - A88S-1 + * 1997 Super 7-in-1 (JY-201) + * 1997 Super 6-in-1 (JY-202) + * 1997 Super 7-in-1 (JY-203) + * 1997 龍珠武鬥會 7-in-1 (JY-204) + * 1997 Super 7-in-1 (JY-205) + * 1997 Super 7-in-1 (JY-206) + */ + +#include "mapinc.h" +#include "mmc3.h" + +static void M411CW(uint32 A, uint8 V) { + uint32 mask = (EXPREGS[1] & 2) ? 0xFF : 0x7F; + V &= mask; + setchr1(A, V | ((EXPREGS[1] << 5) & 0x80) | ((EXPREGS[0] << 4) & 0x100)); +} + +static void M411PW(uint32 A, uint8 V) { + /* NROM Mode */ + if (EXPREGS[0] & 0x40) + { + uint32 bank = (EXPREGS[0] & 1) | ((EXPREGS[0] >> 2) & 2) | (EXPREGS[0] & 4) | (EXPREGS[1] & 8) | ((EXPREGS[1] >> 2) & 0x10); + + /* NROM-256 */ + if (EXPREGS[0] & 0x02) { + setprg32(0x8000, bank >> 1); + + /* NROM-128 */ + } else { + setprg16(0x8000, bank); + setprg16(0xC000, bank); + } + } + + /* MMC3 Mode */ + else + { + uint32 mask = (EXPREGS[1] & 2) ? 0x1F : 0x0F; + V &= mask; + setprg8(A, V | ((EXPREGS[1] << 1) & 0x10) | ((EXPREGS[1] >> 1) & 0x20)); + } +} + +static DECLFW(M411Write5000) { + EXPREGS[A & 1] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); +} + +static void M411Power(void) { + EXPREGS[0] = 0x80; + EXPREGS[1] = 0x82; + GenMMC3Power(); + SetWriteHandler(0x5000, 0x5FFF, M411Write5000); +} + +void Mapper411_Init(CartInfo *info) { + GenMMC3_Init(info, 256, 256, 0, 0); + pwrap = M411PW; + cwrap = M411CW; + info->Power = M411Power; + AddExState(EXPREGS, 2, 0, "EXPR"); +} diff --git a/src/ines.c b/src/ines.c index 6d811a0..8897dab 100644 --- a/src/ines.c +++ b/src/ines.c @@ -698,6 +698,7 @@ INES_BOARD_BEGIN() INES_BOARD( "830928C", 382, Mapper382_Init ) INES_BOARD( "Caltron 9-in-1", 389, Mapper389_Init ) INES_BOARD( "Realtec 8031", 390, Mapper390_Init ) + INES_BOARD( "A88S-1", 411, Mapper411_Init ) INES_BOARD( "Brilliant Com Cocoma Pack", 516, Mapper516_Init ) INES_BOARD( "Sachen 3014", 533, Mapper533_Init ) INES_BOARD( "NJ064", 534, Mapper534_Init ) diff --git a/src/ines.h b/src/ines.h index 24e0abb..3f40b06 100644 --- a/src/ines.h +++ b/src/ines.h @@ -265,6 +265,7 @@ void Mapper381_Init(CartInfo *); void Mapper382_Init(CartInfo *); void Mapper389_Init(CartInfo *); void Mapper390_Init(CartInfo *); +void Mapper411_Init(CartInfo *); void Mapper516_Init(CartInfo *); void Mapper533_Init(CartInfo *); void Mapper534_Init(CartInfo *); From 658370fa9030896a436ef5c6b2b0fd471a69aace Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 12 Oct 2020 11:12:07 +0800 Subject: [PATCH 030/295] m176: Always enable wram for ines-headered roms --- src/boards/fk23c.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index acb781a..f4c46ac 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -521,6 +521,9 @@ void BMCFK23C_Init(CartInfo *info) { * size when battery is set */ if (info->battery) WRAMSIZE = 32 * 1024; + else + /* Always enable WRAM for ines-headered roms, lets see who complains */ + WRAMSIZE = 8 * 1024; } GenBMCFK23C_Init(info); From 7b1cb3e22449134112e371413d7171440456721c Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 13 Oct 2020 04:27:33 +0800 Subject: [PATCH 031/295] Enable default 8K wram to unif fk32ca --- src/boards/fk23c.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index f4c46ac..dece010 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -517,8 +517,7 @@ void BMCFK23C_Init(CartInfo *info) { CHRRAMSIZE = 8 * 1024; } - /* Only waixing boards has battery backed wram, so only declare - * size when battery is set */ + /* Waixing boards has 32K battery backed wram */ if (info->battery) WRAMSIZE = 32 * 1024; else @@ -537,6 +536,8 @@ void BMCFK23CA_Init(CartInfo *info) if (!UNIFchrrama) CHRRAMSIZE = 8 * 1024; + WRAMSIZE = 8 * 1024; + GenBMCFK23C_Init(info); is_bmcfk23ca = 1; } From b42551e23280550934337d9ee2090865d9e5bfae Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 16 Oct 2020 00:56:39 +0200 Subject: [PATCH 032/295] Add ps2 target --- .gitlab-ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ced340e..c581253 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,8 @@ include: file: '/libnx-static.yml' - project: 'libretro-infrastructure/ci-templates' file: '/vita-static.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/ps2-static.yml' - project: 'libretro-infrastructure/ci-templates' file: '/linux-x64.yml' - project: 'libretro-infrastructure/ci-templates' @@ -72,3 +74,10 @@ libretro-build-vita: - .libretro-vita-static-retroarch-master variables: MAKEFILE: Makefile.libretro + +libretro-build-ps2: + extends: + - .core-defs + - .libretro-ps2-static-retroarch-master + variables: + MAKEFILE: Makefile.libretro From abe6e3d232b51b65a08df5a4c18109fcca0f495c Mon Sep 17 00:00:00 2001 From: Autechre Date: Sun, 18 Oct 2020 19:20:16 +0200 Subject: [PATCH 033/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c581253..014629e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,6 +9,8 @@ include: file: '/libnx-static.yml' - project: 'libretro-infrastructure/ci-templates' file: '/vita-static.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/psp-static.yml' - project: 'libretro-infrastructure/ci-templates' file: '/ps2-static.yml' - project: 'libretro-infrastructure/ci-templates' @@ -75,6 +77,13 @@ libretro-build-vita: variables: MAKEFILE: Makefile.libretro +libretro-build-psp: + extends: + - .core-defs + - .libretro-psp-static-retroarch-master + variables: + MAKEFILE: Makefile.libretro + libretro-build-ps2: extends: - .core-defs From 412e40698de037075842cb34bdaf09878e52c971 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 19 Oct 2020 08:18:23 +0800 Subject: [PATCH 034/295] Fix overrides incorrectly setting flags --- src/ines.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ines.c b/src/ines.c index 8ca2d3e..8b8c621 100644 --- a/src/ines.c +++ b/src/ines.c @@ -328,13 +328,15 @@ static void CheckHInfo(void) { case 1: case 5: case 176: - tofix |= 32; - iNESCart.iNES2 = 1; if (moo[x].prgram >= 0) { + tofix |= 32; + iNESCart.iNES2 = 1; iNESCart.PRGRamSize = (moo[x].prgram & 0x0F) ? (64 << ((moo[x].prgram >> 0) & 0xF)) : 0; iNESCart.PRGRamSaveSize = (moo[x].prgram & 0xF0) ? (64 << ((moo[x].prgram >> 4) & 0xF)) : 0; } if (moo[x].chrram >= 0) { + tofix |= 32; + iNESCart.iNES2 = 1; iNESCart.CHRRamSize = (moo[x].chrram & 0x0F) ? (64 << ((moo[x].chrram >> 0) & 0xF)) : 0; iNESCart.CHRRamSaveSize = (moo[x].chrram & 0xF0) ? (64 << ((moo[x].chrram >> 4) & 0xF)) : 0; } From 023d2a397b2ee41035a240712a396fe253a3db0c Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 19 Oct 2020 09:17:45 +0800 Subject: [PATCH 035/295] m176: Updates - Fix incorrect chr-bank mask (let's see which games complain again) - Enables the 7-stage dipswitch support through reset switch. E.g switches multicart type on supported carts. like 10-in-1 to 20-in-1 etc. --- src/boards/fk23c.c | 97 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index dece010..8aed560 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -32,6 +32,76 @@ * Subtype 2, 8192 or more KiB PRG-ROM, no CHR-ROM: Like Subtype 0, but MMC3 registers $46 and $47 swapped. */ +/* +Mode Register ($5xx0) +7654 3210 +---- ---- +PCTm PMMM +|||| |||| +|||| |+++- Select PRG Banking Mode (ignored in Extended MMC3 Mode) +|||| | 0: MMC3 PRG Mode, 512 KiB Outer PRG Bank Size +|||| | 1: MMC3 PRG Mode, 256 KiB Outer PRG Bank Size +|||| | 2: MMC3 PRG Mode, 128 KiB Outer PRG Bank Size +|||| | 3: NROM-128 PRG Mode, 16 KiB PRG at $8000-$BFFF mirrored at $C000-$FFFF +|||| | 4: NROM-256 PRG Mode, 32 KiB PRG at $8000-$FFFF +|||| | 5-7: Never used +|||| +---- PRG Base A21 +|||+------ Select Outer CHR Bank Size +||| 0: In MMC3 CHR Mode: 256 KiB +||| In CNROM CHR Mode: 32 KiB +||| 1: In MMC3 CHR Mode: 128 KiB +||| In CNROM CHR Mode: 16 KiB +||+------- Select CHR Memory Type +|| 0: CHR-ROM +|| 1: CHR-RAM +|+-------- CHR Mode +| 0: MMC3 CHR Mode +| 1: NROM/CNROM CHR Mode ++--------- PRG Base A22 + +Power-on value: $00 + +PRG Base Register ($5xx1) +Mask: $5xx3, x determined by solder pad setting + +7654 3210 +---- ---- +.PPP PPPP + ||| |||| + +++-++++- PRG Base A20..A14 + +Power-on value: $00 +CHR Base Register ($5xx2) +Mask: $5xx3, x determined by solder pad setting + +7654 3210 +---- ---- +ccdC CCCC +|||| |||| +++++-++++- CHR Base A20..A13 +||+------- PRG Base A25 +++-------- PRG Base A24..A23 + +Power-on value: $00 +Writing to the CHR Base Register also resets the CNROM latch. + +Extended Mode Register ($5xx3) +Mask: $5xx3, x determined by solder pad setting + +7654 3210 +---- ---- +.C.. .CE. + | || + | |+- Extended MMC3 Mode + | | 0: disable + | | 1: enable + +----+-- Select NROM/CNROM CHR Mode + 0: NROM + 1: CNROM + +Power-on value: $02 (Submapper 1), $00 (otherwise) +*/ + /* 2020-3-14 - Refactoring based on latest sources */ /* TODO: Add database for ines 1.0 headers */ @@ -55,7 +125,11 @@ static uint8 irq_reload = 0; static uint8 cnrom_chr = 0; static uint8 dipswitch = 0; static uint8 subType = 0; -static uint8 is_bmcfk23ca = 0; + +/* enable dipswitch settings for fk23/fk23ca, + * switchable on reset. Can enable different multicart-modes + * depending on address */ +static uint8 dipsw_enable = 0; static SFORMAT StateRegs[] = { { fk23_regs, 4, "EXPR" }, @@ -138,12 +212,12 @@ static void SyncCHR(void) { uint16 cbase = INVERT_CHR ? 0x1000 : 0; uint8 mask = CHR_OUTER_BANK_SIZE ? 0x7F : 0xFF; - uint16 outer = (fk23_regs[2] << 3) & ~mask; + uint16 outer = (fk23_regs[2] << 3); - cwrap(cbase ^ 0x0000, ((mmc3_regs[0] & 0xFE) & mask) | outer); - cwrap(cbase ^ 0x0400, ((mmc3_regs[0] | 0x01) & mask) | outer); - cwrap(cbase ^ 0x0800, ((mmc3_regs[1] & 0xFE) & mask) | outer); - cwrap(cbase ^ 0x0C00, ((mmc3_regs[1] | 0x01) & mask) | outer); + cwrap(cbase ^ 0x0000, ((mmc3_regs[0] & mask) & 0xFE) | outer); + cwrap(cbase ^ 0x0400, ((mmc3_regs[0] & mask) | 0x01) | outer); + cwrap(cbase ^ 0x0800, ((mmc3_regs[1] & mask) & 0xFE) | outer); + cwrap(cbase ^ 0x0C00, ((mmc3_regs[1] & mask) | 0x01) | outer); cwrap(cbase ^ 0x1000, (mmc3_regs[2] & mask) | outer); cwrap(cbase ^ 0x1400, (mmc3_regs[3] & mask) | outer); @@ -383,10 +457,10 @@ static void IRQHook(void) static void Reset(void) { /* this little hack makes sure that we try all the dip switch settings eventually, if we reset enough */ - /*if (is_bmcfk23ca) { + if (dipsw_enable) { dipswitch = (dipswitch + 1) & 7; - printf("BMCFK23C dipswitch set to $%04x\n",0x5000|0x10 << dipswitch); - }*/ + FCEU_printf("BMCFK23C dipswitch set to $%04x\n",0x5000|0x10 << dipswitch); + } fk23_regs[0] = fk23_regs[1] = fk23_regs[2] = fk23_regs[3] = 0; mmc3_regs[0] = 0; @@ -463,7 +537,7 @@ static void StateRestore(int version) void GenBMCFK23C_Init(CartInfo *info) { - is_bmcfk23ca = 0; + dipsw_enable = 0; info->Power = Power; info->Reset = Reset; @@ -526,6 +600,7 @@ void BMCFK23C_Init(CartInfo *info) { } GenBMCFK23C_Init(info); + dipsw_enable = 1; } /* UNIF Boards, declares so we can for chr mixed mode size and wram if any */ @@ -539,7 +614,7 @@ void BMCFK23CA_Init(CartInfo *info) WRAMSIZE = 8 * 1024; GenBMCFK23C_Init(info); - is_bmcfk23ca = 1; + dipsw_enable = 1; } /* BMC-Super24in1SC03 */ From 7d232046a1452e88f3e2a8817a5044613581451f Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 19 Oct 2020 09:31:16 +0800 Subject: [PATCH 036/295] Remove unused functions --- src/driver.h | 9 --------- src/drivers/libretro/libretro.c | 17 ----------------- src/ppu.c | 2 +- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/driver.h b/src/driver.h index b3f029b..9ce4796 100644 --- a/src/driver.h +++ b/src/driver.h @@ -35,7 +35,6 @@ void FCEU_printf(char *format, ...); /* Video interface */ void FCEUD_SetPalette(uint8 index, uint8 r, uint8 g, uint8 b); -void FCEUD_GetPalette(uint8 i, uint8 *r, uint8 *g, uint8 *b); /* Displays an error. Can block or not. */ void FCEUD_PrintError(char *s); @@ -51,14 +50,6 @@ int FCEUI_NetplayStart(int nlocal, int divisor); /* Call when network play needs to stop. */ void FCEUI_NetplayStop(void); -/* Note: YOU MUST NOT CALL ANY FCEUI_* FUNCTIONS WHILE IN FCEUD_SendData() or - FCEUD_RecvData(). -*/ - -/* Return 0 on failure, 1 on success. */ -int FCEUD_SendData(void *data, uint32 len); -int FCEUD_RecvData(void *data, uint32 len); - /* Display text received over the network. */ void FCEUD_NetplayText(uint8 *text); diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 3f41833..56b2bb2 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -202,11 +202,6 @@ const char * GetKeyboard(void) return ""; } -int FCEUD_SendData(void *data, uint32 len) -{ - return 1; -} - #define BUILD_PIXEL_RGB565(R,G,B) (((int) ((R)&0x1f) << RED_SHIFT) | ((int) ((G)&0x3f) << GREEN_SHIFT) | ((int) ((B)&0x1f) << BLUE_SHIFT)) #if defined (PSP) @@ -266,15 +261,6 @@ void FCEUD_SetPalette(uint8_t index, uint8_t r, uint8_t g, uint8_t b) #endif } -void FCEUD_GetPalette(unsigned char i, unsigned char *r, unsigned char *g, unsigned char *b) -{ -} - -bool FCEUD_ShouldDrawInputAids (void) -{ - return 1; -} - static struct retro_log_callback log_cb; static void default_logger(enum retro_log_level level, const char *fmt, ...) {} @@ -304,9 +290,6 @@ void FCEUD_SoundToggle (void) FCEUI_SetSoundVolume(sndvolume); } -void FCEUD_VideoChanged (void) -{ } - FILE *FCEUD_UTF8fopen(const char *n, const char *m) { if (n) diff --git a/src/ppu.c b/src/ppu.c index e9aec63..0d8ee53 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -1241,7 +1241,7 @@ int FCEUPPU_Loop(int skip) { for (scanline = 0; scanline < totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ deempcnt[deemp]++; - if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1); + /* if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1); */ DoLine(); if (scanline < normal_scanlines || scanline == totalscanlines) overclocked = 0; From 8b3c191f68f0ed668a368b40ce1ba0968f6a61dd Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 19 Oct 2020 09:32:37 +0800 Subject: [PATCH 037/295] Remove NETWORK branch This was part of netplay.c that do not exist anymore. Its empty and not relevant to current codebase. --- src/driver.h | 22 ---------------------- src/input.c | 3 --- 2 files changed, 25 deletions(-) diff --git a/src/driver.h b/src/driver.h index 9ce4796..196c733 100644 --- a/src/driver.h +++ b/src/driver.h @@ -41,28 +41,6 @@ void FCEUD_PrintError(char *s); void FCEUD_Message(char *s); void FCEUD_DispMessage(char *m); -#ifdef NETWORK -/* Network interface */ - -/* Call only when a game is loaded. */ -int FCEUI_NetplayStart(int nlocal, int divisor); - -/* Call when network play needs to stop. */ -void FCEUI_NetplayStop(void); - -/* Display text received over the network. */ -void FCEUD_NetplayText(uint8 *text); - -/* Encode and send text over the network. */ -void FCEUI_NetplayText(uint8 *text); - -/* Called when a fatal error occurred and network play can't continue. This function - should call FCEUI_NetplayStop() after it has deinitialized the network on the driver - side. -*/ -void FCEUD_NetworkClose(void); -#endif - int FCEUI_BeginWaveRecord(char *fn); int FCEUI_EndWaveRecord(void); diff --git a/src/input.c b/src/input.c index ff01bd5..318d68a 100644 --- a/src/input.c +++ b/src/input.c @@ -195,9 +195,6 @@ static void FP_FASTAPASS(3) UpdateGP(int w, void *data, int arg) { joy[1] = *(uint32*)ptr >> 8; joy[3] = *(uint32*)ptr >> 24; } -#ifdef NETWORK - if (FCEUnetplay) NetplayUpdate(joy); -#endif FCEUMOV_AddJoy(joy); } From 2c97c53c8b50326eec4d1a06c6aa52d7d85ef973 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 20 Oct 2020 21:12:32 +0800 Subject: [PATCH 038/295] m176: Fix address mask causing incorrect register writes --- src/boards/fk23c.c | 139 ++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 85 deletions(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index 8aed560..b022389 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -156,7 +156,7 @@ static SFORMAT StateRegs[] = { #define CHR_CNROM_MODE (fk23_regs[0] & 0x40) #define CHR_OUTER_BANK_SIZE (fk23_regs[0] & 0x10) -static void cwrap(uint16 A, uint16 V) +static void cwrap(uint32 A, uint32 V) { int bank = 0; @@ -178,10 +178,10 @@ static void SyncCHR(void) { if (CHR_CNROM_MODE) { - uint8 mask = (fk23_regs[3] & 0x46) ? (CHR_OUTER_BANK_SIZE ? 0x01 : 0x03) : 0; - uint16 bank = (fk23_regs[2] | (cnrom_chr & mask)) << 3; + uint32 mask = (fk23_regs[3] & 0x46) ? (CHR_OUTER_BANK_SIZE ? 0x01 : 0x03) : 0; + uint32 bank = (fk23_regs[2] | (cnrom_chr & mask)) << 3; - cwrap(0x0000, bank); + cwrap(0x0000, bank + 0); cwrap(0x0400, bank + 1); cwrap(0x0800, bank + 2); cwrap(0x0C00, bank + 3); @@ -193,11 +193,12 @@ static void SyncCHR(void) } else { + uint32 cbase = (INVERT_CHR ? 0x1000 : 0); + uint32 outer = (fk23_regs[2] << 3); + uint32 cmask = (CHR_OUTER_BANK_SIZE ? 0x7F : 0xFF); + if (MMC3_EXTENDED) { - uint16 cbase = INVERT_CHR ? 0x1000 : 0; - uint16 outer = fk23_regs[2] << 3; - cwrap(cbase ^ 0x0000, mmc3_regs[0] | outer); cwrap(cbase ^ 0x0400, mmc3_regs[10] | outer); cwrap(cbase ^ 0x0800, mmc3_regs[1] | outer); @@ -210,34 +211,30 @@ static void SyncCHR(void) } else { - uint16 cbase = INVERT_CHR ? 0x1000 : 0; - uint8 mask = CHR_OUTER_BANK_SIZE ? 0x7F : 0xFF; - uint16 outer = (fk23_regs[2] << 3); + cwrap(cbase ^ 0x0000, ((mmc3_regs[0] & cmask) & 0xFE) | outer); + cwrap(cbase ^ 0x0400, ((mmc3_regs[0] & cmask) | 0x01) | outer); + cwrap(cbase ^ 0x0800, ((mmc3_regs[1] & cmask) & 0xFE) | outer); + cwrap(cbase ^ 0x0C00, ((mmc3_regs[1] & cmask) | 0x01) | outer); - cwrap(cbase ^ 0x0000, ((mmc3_regs[0] & mask) & 0xFE) | outer); - cwrap(cbase ^ 0x0400, ((mmc3_regs[0] & mask) | 0x01) | outer); - cwrap(cbase ^ 0x0800, ((mmc3_regs[1] & mask) & 0xFE) | outer); - cwrap(cbase ^ 0x0C00, ((mmc3_regs[1] & mask) | 0x01) | outer); - - cwrap(cbase ^ 0x1000, (mmc3_regs[2] & mask) | outer); - cwrap(cbase ^ 0x1400, (mmc3_regs[3] & mask) | outer); - cwrap(cbase ^ 0x1800, (mmc3_regs[4] & mask) | outer); - cwrap(cbase ^ 0x1c00, (mmc3_regs[5] & mask) | outer); + cwrap(cbase ^ 0x1000, (mmc3_regs[2] & cmask) | outer); + cwrap(cbase ^ 0x1400, (mmc3_regs[3] & cmask) | outer); + cwrap(cbase ^ 0x1800, (mmc3_regs[4] & cmask) | outer); + cwrap(cbase ^ 0x1c00, (mmc3_regs[5] & cmask) | outer); } } } static void SyncPRG(void) { - uint8 prg_mode = fk23_regs[0] & 7; - uint16 prg_base = (fk23_regs[1] & 0x07F) | ((fk23_regs[0] << 4) & 0x080) | + uint32 prg_mode = (fk23_regs[0] & 7); + uint32 prg_base = (fk23_regs[1] & 0x07F) | ((fk23_regs[0] << 4) & 0x080) | ((fk23_regs[0] << 1) & 0x100) | ((fk23_regs[2] << 3) & 0x600) | ((fk23_regs[2] << 6) & 0x800); switch (prg_mode) { case 4: - setprg32(0x8000, prg_base >> 1); + setprg32(0x8000, (prg_base >> 1)); break; case 3: setprg16(0x8000, prg_base); @@ -246,29 +243,29 @@ static void SyncPRG(void) case 0: case 1: case 2: + { + uint32 cbase = (INVERT_PRG ? 0x4000 : 0); + uint32 mask = (0x3F >> prg_mode); + + prg_base <<= 1; + if (MMC3_EXTENDED) { - uint16 cbase = INVERT_PRG ? 0x4000 : 0; - uint16 outer = prg_base << 1; - - setprg8(0x8000 ^ cbase, mmc3_regs[6] | outer); - setprg8(0xA000, mmc3_regs[7] | outer); - setprg8(0xC000 ^ cbase, mmc3_regs[8] | outer); - setprg8(0xE000, mmc3_regs[9] | outer); + setprg8(0x8000 ^ cbase, mmc3_regs[6] | prg_base); + setprg8(0xA000, mmc3_regs[7] | prg_base); + setprg8(0xC000 ^ cbase, mmc3_regs[8] | prg_base); + setprg8(0xE000, mmc3_regs[9] | prg_base); } else { - uint16 cbase = INVERT_PRG ? 0x4000 : 0; - uint8 mask = 0x3F >> prg_mode; - uint16 outer = (prg_base << 1) & ~mask; - - setprg8(0x8000 ^ cbase, (mmc3_regs[6] & mask) | outer); - setprg8(0xA000, (mmc3_regs[7] & mask) | outer); - setprg8(0xC000 ^ cbase, (0xFE & mask) | outer); - setprg8(0xE000, (0xFF & mask) | outer); + setprg8(0x8000 ^ cbase, (mmc3_regs[6] & mask) | (prg_base & ~mask)); + setprg8(0xA000, (mmc3_regs[7] & mask) | (prg_base & ~mask)); + setprg8(0xC000 ^ cbase, (0xFE & mask) | (prg_base & ~mask)); + setprg8(0xE000, (0xFF & mask) | (prg_base & ~mask)); } break; } + } } static void SyncWRAM(void) @@ -306,54 +303,24 @@ static void Sync(void) SyncMIR(); } -static DECLFW(WriteLo) +static DECLFW(Write5000) { if (((WRAM_EXTENDED == 0) || FK23_ENABLED) && (A & (0x10 << dipswitch))) { - switch (A & 3) - { - case 0: - if (fk23_regs[0] != V) - { - fk23_regs[0] = V; - SyncPRG(); - SyncCHR(); - } - break; - case 1: - if (fk23_regs[1] != V) - { - fk23_regs[1] = V; - SyncPRG(); - } - break; - case 2: + fk23_regs[A & 3] = V; + if ((A & 3) == 2) cnrom_chr = 0; - if (fk23_regs[2] != V) - { - fk23_regs[2] = V; - SyncPRG(); - SyncCHR(); - } - break; - case 3: - if (fk23_regs[3] != V) - { - fk23_regs[3] = V; - SyncPRG(); - SyncCHR(); - } - break; - } + SyncPRG(); + SyncCHR(); } else /* FK23C Registers disabled, $5000-$5FFF maps to the second 4 KiB of the 8 KiB WRAM bank 2 */ CartBW(A, V); } -static DECLFW(WriteHi) +static DECLFW(Write8000) { - switch (A & 0xE000) + switch (A & 0xF000) { case 0x8000: case 0x9000: @@ -361,19 +328,19 @@ static DECLFW(WriteHi) case 0xD000: case 0xE000: case 0xF000: - if (CHR_CNROM_MODE) - { - cnrom_chr = V & 0x03; + if (!CHR_CNROM_MODE) + break; + cnrom_chr = V & 0x03; + if ((fk23_regs[0] & 0x07) == 0x03) + cnrom_chr = 0; - if ((fk23_regs[0] & 0x07) == 0x03) - cnrom_chr = 0; - - SyncCHR(); - } + SyncCHR(); + break; + default: break; } - switch (A & 0xE001) + switch (A & 0xF001) { case 0x8000: { @@ -438,6 +405,8 @@ static DECLFW(WriteHi) case 0xE001: irq_enabled = 1; break; + default: + break; } } @@ -508,8 +477,8 @@ static void Power(void) Sync(); SetReadHandler(0x8000, 0xFFFF, CartBR); - SetWriteHandler(0x5000, 0x5fff, WriteLo); - SetWriteHandler(0x8000, 0xFFFF, WriteHi); + SetWriteHandler(0x5000, 0x5fff, Write5000); + SetWriteHandler(0x8000, 0xFFFF, Write8000); if (WRAMSIZE) { From 99c0d8351fe0ff81e430263991481b03364b8cca Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 21 Oct 2020 20:35:05 +0800 Subject: [PATCH 039/295] Fix warnings [-Wmissing-field-initializers] --- src/drivers/libretro/libretro_dipswitch.c | 2 +- src/input.c | 2 +- src/sound.c | 2 +- src/unif.c | 6 +-- src/vsuni.c | 60 +++++++++++------------ 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/drivers/libretro/libretro_dipswitch.c b/src/drivers/libretro/libretro_dipswitch.c index 1126fa9..e31116c 100644 --- a/src/drivers/libretro/libretro_dipswitch.c +++ b/src/drivers/libretro/libretro_dipswitch.c @@ -1258,7 +1258,7 @@ static struct retro_core_option_definition dipswitch_nwc[] = { { "8", "7:30" }, { "9", "7:49" }, { "10", "8:08" }, - { "11" "8:27" }, + { "11", "8:27" }, { "12", "8:45" }, { "13", "9:04" }, { "14", "9:23" }, diff --git a/src/input.c b/src/input.c index 318d68a..03defa6 100644 --- a/src/input.c +++ b/src/input.c @@ -68,7 +68,7 @@ static int JPAttribFC = 0; static int JPTypeFC = 0; static void *InputDataPtrFC; -static INPUTC DummyJPort = { 0, 0, 0, 0, 0 }; +static INPUTC DummyJPort = { 0, 0, 0, 0, 0, 0 }; static INPUTC *JPorts[2] = { &DummyJPort, &DummyJPort }; static INPUTCFC *FCExp = 0; diff --git a/src/sound.c b/src/sound.c index 7ba8d84..40973c2 100644 --- a/src/sound.c +++ b/src/sound.c @@ -38,7 +38,7 @@ int32 Wave[2048 + 512]; int32 WaveHi[40000]; int32 WaveFinal[2048 + 512]; -EXPSOUND GameExpSound = { 0, 0, 0 }; +EXPSOUND GameExpSound = { 0, 0, 0, 0, 0, 0 }; static uint8 TriCount = 0; static uint8 TriMode = 0; diff --git a/src/unif.c b/src/unif.c index ff5a477..736dcb3 100644 --- a/src/unif.c +++ b/src/unif.c @@ -359,9 +359,9 @@ struct _unif_db { }; static struct _unif_db unif_db[] = { - { 0x8ebad077d08e6c78ULL, "A65AS", 1, -1 }, /* 3-in-1 (N080) [p1][U][!], not a real submapper */ - { 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 */ + { 0x8ebad077d08e6c78ULL, "A65AS", 1, -1, -1 }, /* 3-in-1 (N080) [p1][U][!], not a real submapper */ + { 0x616851e56946893bULL, "RESETNROM-XIN1", 0, MI_V, -1 }, /* Sheng Tian 2-in-1(Unl,ResetBase)[p1].unf */ + { 0x4cd729b5ae23a3cfULL, "RESETNROM-XIN1", 0, MI_H, -1 }, /* Sheng Tian 2-in-1(Unl,ResetBase)[p2].unf */ { 0, NULL, -1, -1, -1 } /* end of the line */ }; diff --git a/src/vsuni.c b/src/vsuni.c index 2771043..2afb379 100644 --- a/src/vsuni.c +++ b/src/vsuni.c @@ -246,43 +246,43 @@ RC2C05-04: VSUNIENTRY VSUniGames[] = { - { "Baseball", VS_BASEBALL, 0x691d4200ea42be45LL, 99, 2, RP2C04_0001, 0 }, - { "Battle City", VS_BATTLECITY, 0x8540949d74c4d0ebLL, 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 }, - { "Dr Mario", VS_DRMARIO, 0xe1af09c477dc0081LL, 1, 0, RP2C04_0003, IOPTION_SWAPDIRAB }, - { "Duck Hunt", VS_DUCKHUNT, 0x47735d1e5f1205bbLL, 99, 2, RCP2C03B, IOPTION_GUN }, - { "Excitebike", VS_EXITEBIKE, 0x3dcd1401bcafde77LL, 99, 2, RP2C04_0003, 0 }, - { "Excitebike (J)", VS_EXITEBIKE, 0x7ea51c9d007375f0LL, 99, 2, RP2C04_0004, 0 }, - { "Freedom Force", VS_FREEDOMFORCE, 0xed96436bd1b5e688LL, 4, 0, RP2C04_0001, IOPTION_GUN }, /* Wrong color in game select screen? */ + { "Baseball", VS_BASEBALL, 0x691d4200ea42be45LL, 99, 2, RP2C04_0001, 0, 0 }, + { "Battle City", VS_BATTLECITY, 0x8540949d74c4d0ebLL, 99, 2, RP2C04_0001, 0, 0 }, + { "Battle City(Bootleg)", VS_BATTLECITY, 0x8093cbe7137ac031LL, 99, 2, RP2C04_0001, 0, 0 }, + { "Clu Clu Land", VS_CLUCLULAND, 0x1b8123218f62b1eeLL, 99, 2, RP2C04_0004, IOPTION_SWAPDIRAB, 0 }, + { "Dr Mario", VS_DRMARIO, 0xe1af09c477dc0081LL, 1, 0, RP2C04_0003, IOPTION_SWAPDIRAB, 0 }, + { "Duck Hunt", VS_DUCKHUNT, 0x47735d1e5f1205bbLL, 99, 2, RCP2C03B, IOPTION_GUN, 0 }, + { "Excitebike", VS_EXITEBIKE, 0x3dcd1401bcafde77LL, 99, 2, RP2C04_0003, 0, 0 }, + { "Excitebike (J)", VS_EXITEBIKE, 0x7ea51c9d007375f0LL, 99, 2, RP2C04_0004, 0, 0 }, + { "Freedom Force", VS_FREEDOMFORCE, 0xed96436bd1b5e688LL, 4, 0, RP2C04_0001, IOPTION_GUN, 0 }, /* Wrong color in game select screen? */ { "Stroke and Match Golf", VS_STROKEANDMATCHGOLF, 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 }, - { "Gumshoe", VS_GUMSHOE, 0x87161f8ee37758d3LL, 99, 2, RC2C05_03, IOPTION_GUN }, - { "Gumshoe", VS_GUMSHOE, 0xb8500780bf69ce29LL, 99, 2, RC2C05_03, IOPTION_GUN }, - { "Gumshoe", VS_GUMSHOE, 0xa6bf132ba11d0a8cLL, 99, 2, RC2C05_03, IOPTION_GUN }, /* Gumshoe (VS).nes added: 2017-9-5*/ - { "Hogan's Alley", VS_HOGANSALLEY, 0xd78b7f0bb621fb45LL, 99, 2, RP2C04_0001, IOPTION_GUN }, - { "Ice Climber", VS_ICECLIMBER, 0xd21e999513435e2aLL, 99, 2, RP2C04_0004, IOPTION_SWAPDIRAB }, + { "Goonies", VS_GOONIES, 0xb4032d694e1d2733LL, 151, 1, RP2C04_0003, 0, 0 }, + { "Gradius", VS_GRADIUS, 0x50687ae63bdad976LL, 151, 1, RP2C04_0001, IOPTION_SWAPDIRAB, 0 }, + { "Gumshoe", VS_GUMSHOE, 0x87161f8ee37758d3LL, 99, 2, RC2C05_03, IOPTION_GUN, 0 }, + { "Gumshoe", VS_GUMSHOE, 0xb8500780bf69ce29LL, 99, 2, RC2C05_03, IOPTION_GUN, 0 }, + { "Gumshoe", VS_GUMSHOE, 0xa6bf132ba11d0a8cLL, 99, 2, RC2C05_03, IOPTION_GUN, 0 }, /* Gumshoe (VS).nes added: 2017-9-5*/ + { "Hogan's Alley", VS_HOGANSALLEY, 0xd78b7f0bb621fb45LL, 99, 2, RP2C04_0001, IOPTION_GUN, 0 }, + { "Ice Climber", VS_ICECLIMBER, 0xd21e999513435e2aLL, 99, 2, RP2C04_0004, IOPTION_SWAPDIRAB, 0 }, { "Ladies Golf", VS_LADIESGOLF, 0x781b24be57ef6785LL, 99, 2, RP2C04_0002, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 }, - { "Mach Rider", VS_MACHRIDER, 0x015672618af06441LL, 99, 2, RP2C04_0002, 0 }, - { "Mach Rider (J)", VS_MACHRIDER, 0xa625afb399811a8aLL, 99, 2, RP2C04_0001, 0 }, - { "Mighty Bomb Jack", VS_MIGHTYBOMBJACK, 0xe6a89f4873fac37bLL, 0, 2, RC2C05_02, 0 }, - { "Ninja Jajamaru Kun", VS_JAJAMARU, 0xb26a2c31474099c0LL, 99, 2, RC2C05_01, IOPTION_SWAPDIRAB }, + { "Mach Rider", VS_MACHRIDER, 0x015672618af06441LL, 99, 2, RP2C04_0002, 0, 0 }, + { "Mach Rider (J)", VS_MACHRIDER, 0xa625afb399811a8aLL, 99, 2, RP2C04_0001, 0, 0 }, + { "Mighty Bomb Jack", VS_MIGHTYBOMBJACK, 0xe6a89f4873fac37bLL, 0, 2, RC2C05_02, 0, 0 }, + { "Ninja Jajamaru Kun", VS_JAJAMARU, 0xb26a2c31474099c0LL, 99, 2, RC2C05_01, IOPTION_SWAPDIRAB, 0 }, { "Pinball", VS_PINBALL, 0xc5f49d3de7f2e9b8LL, 99, 2, RP2C04_0001, IOPTION_PREDIP, 0x01 }, { "Pinball (J)", VS_PINBALL, 0x66ab1a3828cc901cLL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x1 }, - { "Platoon", VS_PLATOON, 0x160f237351c19f1fLL, 68, 1, RP2C04_0001, 0 }, - { "RBI Baseball", VS_RBIBASEBALL, 0x6a02d345812938afLL, 4, 1, RP2C04_0001, IOPTION_SWAPDIRAB }, - { "Soccer", VS_SOCCER, 0xd4e7a9058780eda3LL, 99, 2, RP2C04_0003, IOPTION_SWAPDIRAB }, - { "Star Luster", VS_STARLUSTER, 0x8360e134b316d94cLL, 99, 2, RCP2C03B, 0 }, + { "Platoon", VS_PLATOON, 0x160f237351c19f1fLL, 68, 1, RP2C04_0001, 0, 0 }, + { "RBI Baseball", VS_RBIBASEBALL, 0x6a02d345812938afLL, 4, 1, RP2C04_0001, IOPTION_SWAPDIRAB, 0 }, + { "Soccer", VS_SOCCER, 0xd4e7a9058780eda3LL, 99, 2, RP2C04_0003, IOPTION_SWAPDIRAB, 0 }, + { "Star Luster", VS_STARLUSTER, 0x8360e134b316d94cLL, 99, 2, RCP2C03B, 0, 0 }, { "Stroke and Match Golf (J)", VS_STROKEANDMATCHGOLF, 0x869bb83e02509747LL, 99, 2, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x1 }, { "Super Sky Kid", VS_SUPERSKYKID, 0x78d04c1dd4ec0101LL, 4, 1, RCP2C03B, IOPTION_SWAPDIRAB | IOPTION_PREDIP, 0x20 }, - { "Super Xevious", VS_SUPERXEVIOUS, 0x2d396247cf58f9faLL, 206, 0, RP2C04_0001, 0 }, + { "Super Xevious", VS_SUPERXEVIOUS, 0x2d396247cf58f9faLL, 206, 0, RP2C04_0001, 0, 0 }, { "Tetris", VS_TETRIS, 0x531a5e8eea4ce157LL, 99, 2, RCP2C03B, IOPTION_PREDIP, 0x20 }, - { "Top Gun", VS_TOPGUN, 0xf1dea36e6a7b531dLL, 2, 0, RC2C05_04, 0 }, - { "VS Castlevania", VS_CASTLEVANIA, 0x92fd6909c81305b9LL, 2, 1, RP2C04_0002, 0 }, - { "VS Slalom", VS_SLALOM, 0x4889b5a50a623215LL, 0, 1, RP2C04_0002, 0 }, - { "VS Super Mario Bros", VS_SMB, 0x39d8cfa788e20b6cLL, 99, 2, RP2C04_0004, 0 }, - { "VS Super Mario Bros [a1]", VS_SMB, 0xfc182e5aefbce14dLL, 99, 2, RP2C04_0004, 0 }, + { "Top Gun", VS_TOPGUN, 0xf1dea36e6a7b531dLL, 2, 0, RC2C05_04, 0, 0 }, + { "VS Castlevania", VS_CASTLEVANIA, 0x92fd6909c81305b9LL, 2, 1, RP2C04_0002, 0, 0 }, + { "VS Slalom", VS_SLALOM, 0x4889b5a50a623215LL, 0, 1, RP2C04_0002, 0, 0 }, + { "VS Super Mario Bros", VS_SMB, 0x39d8cfa788e20b6cLL, 99, 2, RP2C04_0004, 0, 0 }, + { "VS Super Mario Bros [a1]", VS_SMB, 0xfc182e5aefbce14dLL, 99, 2, RP2C04_0004, 0, 0 }, { "VS TKO Boxing", VS_TKOBOXING, 0x6e1ee06171d8ce3aLL, 206, 1, RP2C04_0003, IOPTION_PREDIP, 0x00 }, { "VS TKO Boxing [a1]", VS_TKOBOXING, 0xa1c694ce147bc1edLL, 206, 1, RP2C04_0003, IOPTION_PREDIP, 0x00 }, { 0 } From e0cb4d2814ae0ef1cb9e1ae126a193e23d05431d Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 21 Oct 2020 20:55:08 +0800 Subject: [PATCH 040/295] Fix warnings [-Wimplicit-fallthrough=] --- src/boards/116.c | 6 +++--- src/boards/bmc13in1jy110.c | 2 ++ src/boards/yoko.c | 2 +- src/fds.c | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/boards/116.c b/src/boards/116.c index 88f5f00..cb7d40f 100644 --- a/src/boards/116.c +++ b/src/boards/116.c @@ -250,10 +250,10 @@ static DECLFW(UNLSL12Write) { mmc1_regs[n] = mmc1_buffer; mmc1_buffer = mmc1_shift = 0; switch (n) { - case 0: SyncMIR(); - case 2: SyncCHR(); + case 0: SyncMIR(); break; + case 2: SyncCHR(); break; case 3: - case 1: SyncPRG(); + case 1: SyncPRG(); break; } } } diff --git a/src/boards/bmc13in1jy110.c b/src/boards/bmc13in1jy110.c index c7bd349..0f70257 100644 --- a/src/boards/bmc13in1jy110.c +++ b/src/boards/bmc13in1jy110.c @@ -41,11 +41,13 @@ static void Sync(void) { case 1: setprg16(0x8000, ((8 + (bank_value & 7)) >> 1) + prgb[1]); setprg16(0xC000, (bank_value & 7) >> 1); + break; case 4: setprg32(0x8000, 8 + (bank_value & 7)); break; case 5: setprg16(0x8000, ((8 + (bank_value & 7)) >> 1) + prgb[1]); setprg16(0xC000, ((8 + (bank_value & 7)) >> 1) + prgb[3]); + break; case 2: setprg8(0x8000, prgb[0] >> 2); setprg8(0xa000, prgb[1]); diff --git a/src/boards/yoko.c b/src/boards/yoko.c index e91974a..f27ab6f 100644 --- a/src/boards/yoko.c +++ b/src/boards/yoko.c @@ -117,7 +117,7 @@ static DECLFW(UNLYOKOWrite) { static DECLFW(M83Write) { switch (A) { - case 0x8000: is2kbank = 1; + case 0x8000: is2kbank = 1; M83Sync(); break; case 0xB000: /* Dragon Ball Z Party [p1] BMC */ case 0xB0FF: /* Dragon Ball Z Party [p1] BMC */ case 0xB1FF: bank = V; mode |= 0x40; M83Sync(); break; /* Dragon Ball Z Party [p1] BMC */ diff --git a/src/fds.c b/src/fds.c index 3501915..302fdae 100644 --- a/src/fds.c +++ b/src/fds.c @@ -346,6 +346,7 @@ static DECLFW(FDSWrite) { X6502_IRQEnd(FCEU_IQEXT); X6502_IRQEnd(FCEU_IQEXT2); } + break; case 0x4024: #ifndef USE_DINK if ((InDisk != 255) && !(FDSRegs[5] & 0x4) && (FDSRegs[3] & 0x1)) { From c2594418a98f4a9f1fcd9eb0c0e545cd620a3086 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 21 Oct 2020 21:03:36 +0800 Subject: [PATCH 041/295] m176: Fix battery save size, silence parenthesis warning --- src/boards/235.c | 2 +- src/boards/fk23c.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/boards/235.c b/src/boards/235.c index e065a88..b823666 100644 --- a/src/boards/235.c +++ b/src/boards/235.c @@ -40,7 +40,7 @@ static SFORMAT StateRegs[] = static void Sync(void) { if (type && unrom) { - setprg16(0x8000, 0x80 | reg & 7); + setprg16(0x8000, 0x80 | (reg & 7)); setprg16(0xC000, 0x80 | 7); setchr8(0); setmirror(MI_V); diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index b022389..3ed31ed 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -531,7 +531,10 @@ void GenBMCFK23C_Init(CartInfo *info) if (info->battery) { info->SaveGame[0] = WRAM; - info->SaveGameLen[0] = info->PRGRamSaveSize ? info->PRGRamSaveSize : WRAMSIZE; + if (info->iNES2 && info->PRGRamSaveSize) + info->SaveGameLen[0] = info->PRGRamSaveSize + else + info->SaveGameLen[0] = WRAMSIZE; } } From fc99e34a2c1fd6b76910587793254ee9434ebd28 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 21 Oct 2020 21:07:13 +0800 Subject: [PATCH 042/295] Typo --- src/boards/fk23c.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index 3ed31ed..9f39bee 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -532,7 +532,7 @@ void GenBMCFK23C_Init(CartInfo *info) { info->SaveGame[0] = WRAM; if (info->iNES2 && info->PRGRamSaveSize) - info->SaveGameLen[0] = info->PRGRamSaveSize + info->SaveGameLen[0] = info->PRGRamSaveSize; else info->SaveGameLen[0] = WRAMSIZE; } From 5538bbedd9455380bf04c56223775c6bc6f414d1 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Thu, 22 Oct 2020 05:32:16 +0800 Subject: [PATCH 043/295] Update mapper 059/060 Excerpt from nesdev: NESten's Mapper DLL v1.0 contained an incorrect implementation of T3H53 as iNES mapper 059 and UNIF mapper BMC-T3H53. The UNIF implementation was improved in NESten's Mapper DLL v1.2 while the iNES implementation was not, causing confusion about what kind of cartridge the unimproved mapper 59 was supposed to be. As Nintendulator's mapper DLL is based on NESten's mapper DLL, this was carried over to Nintendulator. Presumably as a result of this confusion, FCEUX and others put the correct implementation of T3H53 at INES Mapper 060, displacing the "Reset-based NROM-128 4-in-1" in the process. With that said above, im following nesdev's notes and change the following: - Reassign Mapper 60 as Mapper 59. - Add BMC-T3H53, a UNIF cart using the same UNIF-board D1038 which is assigned as iNES Mapper 59 - Add the Reset-Based NRON-128 mapper, Mapper 60 --- src/boards/60.c | 56 ++++++++++++++++++++++++++++++++++++++++++ src/boards/addrlatch.c | 5 ++-- src/ines.c | 5 ++-- src/ines.h | 1 + src/unif.c | 1 + 5 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 src/boards/60.c diff --git a/src/boards/60.c b/src/boards/60.c new file mode 100644 index 0000000..01e4ccf --- /dev/null +++ b/src/boards/60.c @@ -0,0 +1,56 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 negativeExponent + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "mapinc.h" + +static uint8 game = 0; + +static void Sync(void) +{ + setchr8(game); + setprg16(0x8000, game); + setprg16(0xC000, game); +} + +static void M60Reset(void) +{ + game = (game + 1) & 3; + Sync(); +} + +static void M60Power(void) +{ + game = 0; + Sync(); + SetReadHandler(0x8000, 0xFFFF, CartBR); + SetWriteHandler(0x8000, 0xFFFF, CartBW); +} + +static void StateRestore(int version) { + Sync(); +} + +void Mapper60_Init(CartInfo *info) +{ + info->Power = M60Power; + info->Reset = M60Reset; + GameStateRestore = StateRestore; + AddExState(&game, 1, 0, "GAME"); +} \ No newline at end of file diff --git a/src/boards/addrlatch.c b/src/boards/addrlatch.c index b2e193a..415d574 100644 --- a/src/boards/addrlatch.c +++ b/src/boards/addrlatch.c @@ -166,7 +166,8 @@ void BMCGK192_Init(CartInfo *info) { /*------------------ Map 059 ---------------------------*/ /* One more forgotten mapper */ -static void M59Sync(void) { +/* Formerly, an incorrect implementation of BMC-T3H53 */ +/*static void M59Sync(void) { setprg32(0x8000, (latche >> 4) & 7); setchr8(latche & 0x7); setmirror((latche >> 3) & 1); @@ -181,7 +182,7 @@ static DECLFR(M59Read) { void Mapper59_Init(CartInfo *info) { Latch_Init(info, M59Sync, M59Read, 0x0000, 0x8000, 0xFFFF, 0); -} +}*/ /*------------------ Map 061 ---------------------------*/ static void M61Sync(void) { diff --git a/src/ines.c b/src/ines.c index 8b8c621..ab839b7 100644 --- a/src/ines.c +++ b/src/ines.c @@ -479,8 +479,9 @@ INES_BOARD_BEGIN() INES_BOARD( "UNLKS202", 56, UNLKS202_Init ) INES_BOARD( "SIMBPLE BMC PIRATE A", 57, Mapper57_Init ) INES_BOARD( "SIMBPLE BMC PIRATE B", 58, BMCGK192_Init ) - INES_BOARD( "", 59, Mapper59_Init ) /* Check this out */ - INES_BOARD( "SIMBPLE BMC PIRATE C", 60, BMCD1038_Init ) +/* INES_BOARD( "", 59, Mapper59_Init ) */ /* Check this out, update 2020-10-21 - formerly an incorrect implementation of T3H53 */ + INES_BOARD( "BMC T3H53/D1038", 59, BMCD1038_Init ) + INES_BOARD( "Reset-based NROM-128 ", 60, Mapper60_Init ) INES_BOARD( "20-in-1 KAISER Rev. A", 61, Mapper61_Init ) INES_BOARD( "700-in-1", 62, Mapper62_Init ) INES_BOARD( "", 63, Mapper63_Init ) diff --git a/src/ines.h b/src/ines.h index 3ad9898..bc119f2 100644 --- a/src/ines.h +++ b/src/ines.h @@ -94,6 +94,7 @@ void Mapper51_Init(CartInfo *); void Mapper52_Init(CartInfo *); void Mapper57_Init(CartInfo *); void Mapper59_Init(CartInfo *); +void Mapper60_Init(CartInfo *); void Mapper61_Init(CartInfo *); void Mapper62_Init(CartInfo *); void Mapper63_Init(CartInfo *); diff --git a/src/unif.c b/src/unif.c index 736dcb3..cc81a11 100644 --- a/src/unif.c +++ b/src/unif.c @@ -446,6 +446,7 @@ static BMAPPING bmap[] = { { "CNROM", 3, CNROM_Init, 0 }, { "CPROM", 13, CPROM_Init, BMCFLAG_16KCHRR }, { "D1038", 59, BMCD1038_Init, 0 }, + { "T3H53", 59, BMCD1038_Init, 0 }, { "DANCE", 256, UNLOneBus_Init, 0 }, { "DANCE2000", 518, UNLD2000_Init, 0 }, { "DREAMTECH01", 521, DreamTech01_Init, 0 }, From 75165981fb8e0f09160368ef53b041d3c1c890eb Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Thu, 22 Oct 2020 19:59:23 +0800 Subject: [PATCH 044/295] Change c++ to c comments --- src/ppu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ppu.c b/src/ppu.c index 0d8ee53..45ccc7f 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -719,7 +719,7 @@ static void DoLine(void) GameHBIRQHook(); X6502_Run(85 - 16 - 10); } else { - X6502_Run(6); // Tried 65, caused problems with Slalom(maybe others) + X6502_Run(6); /* Tried 65, caused problems with Slalom(maybe others) */ Fixit2(); X6502_Run(85 - 6 - 16); From c5422046519ce269009075b5b59b5d3640e48de6 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Fri, 23 Oct 2020 09:51:17 +0800 Subject: [PATCH 045/295] UNIF: Fix incorrect ines-mapper log and cleanup --- src/unif.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/unif.c b/src/unif.c index cc81a11..7ee60ae 100644 --- a/src/unif.c +++ b/src/unif.c @@ -692,7 +692,7 @@ static int InitializeBoard(void) { mirrortodo = 4; MooMirroring(); - UNIFCart.submapper = bmap[x].ines_mapper; + UNIFCart.mapper = bmap[x].ines_mapper; UNIFCart.submapper = submapper; GameInfo->cspecial = cspecial; @@ -701,7 +701,8 @@ static int InitializeBoard(void) { } x++; } - FCEU_PrintError("Board type not supported, '%s'.", boardname); + FCEU_printf("\n"); + FCEU_PrintError(" Board type not supported, '%s'.\n", boardname); return(0); } @@ -798,17 +799,17 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { if (UNIF_CHRROMSize) SetupCartCHRMapping(0, VROM, UNIF_CHRROMSize, 0); + FCEU_printf(" PRG-ROM CRC32: 0x%08X\n", UNIFCart.PRGCRC32); + FCEU_printf(" PRG+CHR CRC32: 0x%08X\n", UNIFCart.CRC32); + FCEU_printf(" PRG+CHR MD5 : 0x%s\n", md5_asciistr(UNIFCart.MD5)); + if (!InitializeBoard()) goto aborto; - FCEU_printf(" PRG-ROM CRC32: 0x%08X\n", UNIFCart.PRGCRC32); - FCEU_printf(" PRG+CHR CRC32: 0x%08X\n", UNIFCart.CRC32); - FCEU_printf(" PRG+CHR MD5 : 0x%s\n", md5_asciistr(UNIFCart.MD5)); - if (UNIFCart.mapper) - FCEU_printf(" [Unif] Mapper: %d\n", UNIFCart.mapper); - FCEU_printf(" [Unif] SubMapper: %d\n", UNIFCart.submapper); - FCEU_printf(" [Unif] PRG ROM: %u KiB\n", UNIFCart.PRGRomSize / 1024); - FCEU_printf(" [Unif] CHR ROM: %u KiB\n", UNIFCart.CHRRomSize / 1024); + FCEU_printf(" [UNIF] PRG ROM: %u KiB\n", UNIFCart.PRGRomSize / 1024); + FCEU_printf(" [UNIF] CHR ROM: %u KiB\n", UNIFCart.CHRRomSize / 1024); + FCEU_printf(" [UNIF] iNES Mapper: %d\n", UNIFCart.mapper); + FCEU_printf(" [UNIF] SubMapper: %d\n", UNIFCart.submapper); GameInterface = UNIFGI; From 71daae412ee467d2151dde403e89c60fbba19056 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Fri, 23 Oct 2020 10:17:38 +0800 Subject: [PATCH 046/295] UNIF: Ensure that used memory are freed on errors - removes "goto" jumps - frees ROM and VROM if necessary --- src/unif.c | 102 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/src/unif.c b/src/unif.c index 7ee60ae..88d2595 100644 --- a/src/unif.c +++ b/src/unif.c @@ -138,6 +138,11 @@ static void ResetUNIF(void) { VROM_size = 0; } +static void Cleanup(void) { + FreeUNIF(); + ResetUNIF(); +} + static uint8 exntar[2048]; static void MooMirroring(void) { @@ -727,8 +732,8 @@ static void UNIFGI(int h) { int UNIFLoad(const char *name, FCEUFILE *fp) { struct md5_context md5; - uint32 x = 0; - uint64 PRGptr = 0, CHRptr = 0; + uint64 prg_size_bytes = 0, chr_size_bytes = 0; + int x = 0; FCEU_fseek(fp, 0, SEEK_SET); FCEU_fread(&unhead, 1, 4, fp); @@ -739,12 +744,18 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { ResetExState(0, 0); ResetUNIF(); - if (!FCEU_read32le(&unhead.info, fp)) - goto aborto; - if (FCEU_fseek(fp, 0x20, SEEK_SET) < 0) - goto aborto; - if (!LoadUNIFChunks(fp)) - goto aborto; + if (!FCEU_read32le(&unhead.info, fp)) { + Cleanup(); + return 0; + } + if (FCEU_fseek(fp, 0x20, SEEK_SET) < 0) { + Cleanup(); + return 0; + } + if (!LoadUNIFChunks(fp)) { + Cleanup(); + return 0; + } ROM_size = (UNIF_PRGROMSize / 0x1000) + ((UNIF_PRGROMSize % 0x1000) ? 1 : 0); ROM_size = (ROM_size >> 2) + ((ROM_size & 3) ? 1: 0); @@ -753,48 +764,63 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { VROM_size = (VROM_size >> 3) + ((VROM_size & 7) ? 1: 0); } - UNIFCart.PRGRomSize = UNIF_PRGROMSize; - UNIFCart.CHRRomSize = UNIF_CHRROMSize; - UNIF_PRGROMSize = FixRomSize(UNIF_PRGROMSize, 2048); if (UNIF_CHRROMSize) UNIF_CHRROMSize = FixRomSize(UNIF_CHRROMSize, 8192); - ROM = (uint8*)malloc(UNIF_PRGROMSize); - if (UNIF_CHRROMSize) - VROM = (uint8*)malloc(UNIF_CHRROMSize); + /* Note: Use rounded size for memory allocations and board mapping */ + + if (!(ROM = (uint8*)malloc(UNIF_PRGROMSize))) { + Cleanup(); + return 0; + } + if (UNIF_CHRROMSize) { + if (!(VROM = (uint8*)malloc(UNIF_CHRROMSize))) { + Cleanup(); + return 0; + } + } + + /* combine multiple prg/chr blocks into single blocks and free memory used. */ for (x = 0; x < 16; x++) { - unsigned p = prg_idx[x]; - unsigned c = 16 + chr_idx[x]; + int p = prg_idx[x]; + int c = 16 + chr_idx[x]; if (malloced[p]) { - memcpy(ROM + PRGptr, malloced[p], mallocedsizes[p]); - PRGptr += mallocedsizes[p]; + memcpy(ROM + prg_size_bytes, malloced[p], mallocedsizes[p]); + prg_size_bytes += mallocedsizes[p]; free(malloced[p]); malloced[p] = 0; } if (malloced[c]) { - memcpy(VROM + CHRptr, malloced[c], mallocedsizes[c]); - CHRptr += mallocedsizes[c]; + memcpy(VROM + chr_size_bytes, malloced[c], mallocedsizes[c]); + chr_size_bytes += mallocedsizes[c]; free(malloced[c]); malloced[c] = 0; } } - UNIFCart.PRGCRC32 = CalcCRC32(0, ROM, PRGptr); - UNIFCart.CHRCRC32 = CalcCRC32(0, VROM, CHRptr); - UNIFCart.CRC32 = CalcCRC32(UNIFCart.PRGCRC32, VROM, CHRptr); + /* Note: Use raw size in bytes for checksums */ + + UNIFCart.PRGRomSize = prg_size_bytes; + UNIFCart.CHRRomSize = chr_size_bytes; + + UNIFCart.PRGCRC32 = CalcCRC32(0, ROM, prg_size_bytes); + UNIFCart.CHRCRC32 = CalcCRC32(0, VROM, chr_size_bytes); + UNIFCart.CRC32 = CalcCRC32(UNIFCart.PRGCRC32, VROM, chr_size_bytes); md5_starts(&md5); - md5_update(&md5, ROM, PRGptr); - if (UNIF_CHRROMSize) - md5_update(&md5, VROM, CHRptr); + md5_update(&md5, ROM, prg_size_bytes); + if (chr_size_bytes) + md5_update(&md5, VROM, chr_size_bytes); md5_finish(&md5, UNIFCart.MD5); memcpy(GameInfo->MD5, UNIFCart.MD5, sizeof(UNIFCart.MD5)); CheckHashInfo(); + /* Note: Use rounded size for board mappings */ + SetupCartPRGMapping(0, ROM, UNIF_PRGROMSize, 0); if (UNIF_CHRROMSize) SetupCartCHRMapping(0, VROM, UNIF_CHRROMSize, 0); @@ -803,8 +829,10 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { FCEU_printf(" PRG+CHR CRC32: 0x%08X\n", UNIFCart.CRC32); FCEU_printf(" PRG+CHR MD5 : 0x%s\n", md5_asciistr(UNIFCart.MD5)); - if (!InitializeBoard()) - goto aborto; + if (!InitializeBoard()) { + Cleanup(); + return 0; + } FCEU_printf(" [UNIF] PRG ROM: %u KiB\n", UNIFCart.PRGRomSize / 1024); FCEU_printf(" [UNIF] CHR ROM: %u KiB\n", UNIFCart.CHRRomSize / 1024); @@ -814,12 +842,6 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { GameInterface = UNIFGI; return 1; - - aborto: - - FreeUNIF(); - ResetUNIF(); - return 0; } int CopyFamiLoad() { @@ -827,15 +849,11 @@ int CopyFamiLoad() { ResetExState(0, 0); sboardname = (uint8_t*)"COPYFAMI"; - if (!InitializeBoard()) - goto aborto; + if (!InitializeBoard()) { + Cleanup(); + return 0; + } GameInterface = UNIFGI; return 1; - - aborto: - - FreeUNIF(); - ResetUNIF(); - return 0; } From 565f60c0f2fa9777167b2d040cab155bab6954cf Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sun, 25 Oct 2020 08:31:41 +0800 Subject: [PATCH 047/295] Fix some warnings --- src/boards/269.c | 2 +- src/boards/KS7030.c | 2 +- src/cheat.c | 2 +- src/drivers/libretro/libretro.c | 7 ++----- src/general.c | 10 +++++----- src/input/zapper.c | 4 ++-- src/state.c | 6 +++--- 7 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/boards/269.c b/src/boards/269.c index 0acef24..358ccce 100644 --- a/src/boards/269.c +++ b/src/boards/269.c @@ -80,7 +80,7 @@ static uint8 unscrambleCHR(uint8 data) { } void Mapper269_Init(CartInfo *info) { - int i; + uint8 i; GenMMC3_Init(info, 512, 0, 8, 0); cwrap = M269CW; pwrap = M269PW; diff --git a/src/boards/KS7030.c b/src/boards/KS7030.c index c6de258..fb61a7e 100644 --- a/src/boards/KS7030.c +++ b/src/boards/KS7030.c @@ -26,7 +26,7 @@ */ /* 2020-3-6 - update mirroring (negativeExponent) -/* PRG-ROM Bank Select #1/Mirroring Select ($8000-$8FFF, write) + * PRG-ROM Bank Select #1/Mirroring Select ($8000-$8FFF, write) * A~FEDC BA98 7654 3210 * ------------------- * 1000 .... .... MBBB diff --git a/src/cheat.c b/src/cheat.c index cdf0aaf..0e82364 100644 --- a/src/cheat.c +++ b/src/cheat.c @@ -570,7 +570,7 @@ void FCEUI_CheatSearchBegin(void) { } -static int INLINE CAbs(int x) { +static INLINE int CAbs(int x) { if (x < 0) return(0 - x); return x; diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 56b2bb2..90e1790 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1123,7 +1123,6 @@ static void set_apu_channels(int chan) static void check_variables(bool startup) { struct retro_variable var = {0}; - bool palette_updated = false; char key[256]; int i, enable_apu; @@ -1886,9 +1885,8 @@ static void retro_run_blit(uint8_t *gfx) void retro_run(void) { - unsigned i; uint8_t *gfx; - int32_t ssize = 0; + int32_t i, ssize = 0; bool updated = false; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) @@ -1955,7 +1953,7 @@ static int checkGG(char c) static int GGisvalid(const char *code) { size_t len = strlen(code); - int i; + uint32 i; if (len != 6 && len != 8) return 0; @@ -1980,7 +1978,6 @@ void retro_cheat_set(unsigned index, bool enabled, const char *code) uint8 v; int c; int type = 1; - int ret = 0; if (code == NULL) return; diff --git a/src/general.c b/src/general.c index 70321ab..33af07f 100644 --- a/src/general.c +++ b/src/general.c @@ -69,22 +69,22 @@ void FCEUI_SetDirOverride(int which, char *n) char *FCEU_MakeFName(int type, int id1, char *cd1) { - char tmp[2048] = {0}; + char tmp[4096 + 512] = {0}; /* +512 for no reason :D */ char *ret = 0; switch (type) { case FCEUMKF_GGROM: - sprintf(tmp, "%s"PSS "gg.rom", BaseDirectory); + sprintf(tmp, "%s%c%s", BaseDirectory, PS, "gg.rom"); break; case FCEUMKF_FDSROM: - sprintf(tmp, "%s"PSS "disksys.rom", BaseDirectory); + sprintf(tmp, "%s%c%s", BaseDirectory, PS, "disksys.rom"); break; case FCEUMKF_PALETTE: - sprintf(tmp, "%s"PSS "nes.pal", BaseDirectory); + sprintf(tmp, "%s%c%s", BaseDirectory, PS, "nes.pal"); break; case FCEUMKF_FDS: - sprintf(tmp, "%s"PSS "%s.sav", SaveDirectory, FileBase); + sprintf(tmp, "%s%c%s%s", SaveDirectory, PS, FileBase, ".sav"); break; default: break; diff --git a/src/input/zapper.c b/src/input/zapper.c index 776f51a..40a182a 100644 --- a/src/input/zapper.c +++ b/src/input/zapper.c @@ -28,7 +28,7 @@ #define MAX_TOLERANCE 20 static uint32 targetExpansion[MAX_TOLERANCE+1]; #endif -static int tolerance; +static uint32 tolerance; typedef struct { uint32 mzx, mzy, mzb; @@ -167,7 +167,7 @@ static uint32 InefficientSqrt(uint32 z) { void FCEU_ZapperSetTolerance(int t) { #ifdef ROUNDED_TARGET - uint32_t y; + uint32 y; tolerance = t <= MAX_TOLERANCE ? t : MAX_TOLERANCE; for (y = 0; y <= tolerance; y++) targetExpansion[y] = InefficientSqrt(tolerance*tolerance-y*y); diff --git a/src/state.c b/src/state.c index baeab1c..1c14a8d 100644 --- a/src/state.c +++ b/src/state.c @@ -85,7 +85,7 @@ static int SubWrite(memstream_t *mem, SFORMAT *sf) while(sf->v) { - if(sf->s == ~0) /* Link to another struct. */ + if(sf->s == (~(uint32)0)) /* Link to another struct. */ { uint32 tmp; @@ -140,7 +140,7 @@ static SFORMAT *CheckS(SFORMAT *sf, uint32 tsize, char *desc) { while (sf->v) { - if (sf->s == ~0) + if (sf->s == (~(uint32)0)) { /* Link to another SFORMAT structure. */ SFORMAT *tmp; if ((tmp = CheckS((SFORMAT*)sf->v, tsize, desc))) @@ -162,7 +162,7 @@ static SFORMAT *CheckS(SFORMAT *sf, uint32 tsize, char *desc) static int ReadStateChunk(memstream_t *mem, SFORMAT *sf, int size) { SFORMAT *tmp; - int temp; + uint64 temp; temp = memstream_pos(mem); while(memstream_pos(mem) < (temp + size)) From 6eccb4401f86a138d0c597860dce936c2a428283 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sun, 25 Oct 2020 12:01:27 +0800 Subject: [PATCH 048/295] Update libretro-common --- .../libretro-common/compat/compat_snprintf.c | 30 ++- .../libretro-common/compat/compat_strl.c | 2 +- .../libretro-common/encodings/encoding_utf.c | 146 ++++++------ .../libretro-common/include/boolean.h | 2 +- .../libretro-common/include/compat/msvc.h | 21 +- .../libretro-common/include/compat/strl.h | 2 +- .../libretro-common/include/encodings/crc32.h | 2 +- .../libretro-common/include/encodings/utf.h | 4 +- .../libretro-common/include/encodings/win32.h | 2 +- .../libretro-common/include/libretro.h | 219 +++++++++++++++++- .../libretro-common/include/retro_common.h | 2 +- .../include/retro_common_api.h | 2 +- .../libretro-common/include/retro_inline.h | 2 +- .../include/streams/memory_stream.h | 2 +- .../include/string/stdstring.h | 95 ++++++-- .../libretro-common/streams/memory_stream.c | 64 +++-- .../libretro-common/string/stdstring.c | 57 ++++- 17 files changed, 467 insertions(+), 187 deletions(-) diff --git a/src/drivers/libretro/libretro-common/compat/compat_snprintf.c b/src/drivers/libretro/libretro-common/compat/compat_snprintf.c index b69ad04..d7320cc 100644 --- a/src/drivers/libretro/libretro-common/compat/compat_snprintf.c +++ b/src/drivers/libretro/libretro-common/compat/compat_snprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_snprintf.c). @@ -33,12 +33,12 @@ #if _MSC_VER < 1300 #define _vscprintf c89_vscprintf_retro__ -static int c89_vscprintf_retro__(const char *format, va_list pargs) +static int c89_vscprintf_retro__(const char *fmt, va_list pargs) { int retval; va_list argcopy; va_copy(argcopy, pargs); - retval = vsnprintf(NULL, 0, format, argcopy); + retval = vsnprintf(NULL, 0, fmt, argcopy); va_end(argcopy); return retval; } @@ -46,38 +46,36 @@ static int c89_vscprintf_retro__(const char *format, va_list pargs) /* http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 */ -int c99_vsnprintf_retro__(char *outBuf, size_t size, const char *format, va_list ap) +int c99_vsnprintf_retro__(char *s, size_t len, const char *fmt, va_list ap) { int count = -1; - if (size != 0) + if (len != 0) { #if (_MSC_VER <= 1310) - count = _vsnprintf(outBuf, size - 1, format, ap); + count = _vsnprintf(s, len - 1, fmt, ap); #else - count = _vsnprintf_s(outBuf, size, size - 1, format, ap); + count = _vsnprintf_s(s, len, len - 1, fmt, ap); #endif } if (count == -1) - count = _vscprintf(format, ap); + count = _vscprintf(fmt, ap); - if (count == size) - { - /* there was no room for a NULL, so truncate the last character */ - outBuf[size - 1] = '\0'; - } + /* there was no room for a NULL, so truncate the last character */ + if (count == len && len) + s[len - 1] = '\0'; return count; } -int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...) +int c99_snprintf_retro__(char *s, size_t len, const char *fmt, ...) { int count; va_list ap; - va_start(ap, format); - count = c99_vsnprintf_retro__(outBuf, size, format, ap); + va_start(ap, fmt); + count = c99_vsnprintf_retro__(s, len, fmt, ap); va_end(ap); return count; diff --git a/src/drivers/libretro/libretro-common/compat/compat_strl.c b/src/drivers/libretro/libretro-common/compat/compat_strl.c index 94cb39b..3172310 100644 --- a/src/drivers/libretro/libretro-common/compat/compat_strl.c +++ b/src/drivers/libretro/libretro-common/compat/compat_strl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (compat_strl.c). diff --git a/src/drivers/libretro/libretro-common/encodings/encoding_utf.c b/src/drivers/libretro/libretro-common/encodings/encoding_utf.c index b6ad2f9..2760824 100644 --- a/src/drivers/libretro/libretro-common/encodings/encoding_utf.c +++ b/src/drivers/libretro/libretro-common/encodings/encoding_utf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (encoding_utf.c). @@ -37,6 +37,8 @@ #include #endif +#define UTF8_WALKBYTE(string) (*((*(string))++)) + static unsigned leading_ones(uint8_t c) { unsigned ones = 0; @@ -89,13 +91,14 @@ size_t utf8_conv_utf32(uint32_t *out, size_t out_chars, bool utf16_conv_utf8(uint8_t *out, size_t *out_chars, const uint16_t *in, size_t in_size) { - static uint8_t kUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - size_t out_pos = 0; - size_t in_pos = 0; + size_t out_pos = 0; + size_t in_pos = 0; + static const + uint8_t utf8_limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; for (;;) { - unsigned numAdds; + unsigned num_adds; uint32_t value; if (in_pos == in_size) @@ -124,21 +127,21 @@ bool utf16_conv_utf8(uint8_t *out, size_t *out_chars, value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000; } - for (numAdds = 1; numAdds < 5; numAdds++) - if (value < (((uint32_t)1) << (numAdds * 5 + 6))) + for (num_adds = 1; num_adds < 5; num_adds++) + if (value < (((uint32_t)1) << (num_adds * 5 + 6))) break; if (out) - out[out_pos] = (char)(kUtf8Limits[numAdds - 1] - + (value >> (6 * numAdds))); + out[out_pos] = (char)(utf8_limits[num_adds - 1] + + (value >> (6 * num_adds))); out_pos++; do { - numAdds--; + num_adds--; if (out) out[out_pos] = (char)(0x80 - + ((value >> (6 * numAdds)) & 0x3F)); + + ((value >> (6 * num_adds)) & 0x3F)); out_pos++; - }while (numAdds != 0); + }while (num_adds != 0); } *out_chars = out_pos; @@ -166,13 +169,15 @@ size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars) while (*sb && chars-- > 0) { sb++; - while ((*sb & 0xC0) == 0x80) sb++; + while ((*sb & 0xC0) == 0x80) + sb++; } if ((size_t)(sb - sb_org) > d_len-1 /* NUL */) { sb = sb_org + d_len-1; - while ((*sb & 0xC0) == 0x80) sb--; + while ((*sb & 0xC0) == 0x80) + sb--; } memcpy(d, sb_org, sb-sb_org); @@ -184,14 +189,18 @@ size_t utf8cpy(char *d, size_t d_len, const char *s, size_t chars) const char *utf8skip(const char *str, size_t chars) { const uint8_t *strb = (const uint8_t*)str; + if (!chars) return str; + do { strb++; - while ((*strb & 0xC0)==0x80) strb++; + while ((*strb & 0xC0)==0x80) + strb++; chars--; - } while(chars); + }while (chars); + return (const char*)strb; } @@ -211,24 +220,22 @@ size_t utf8len(const char *string) return ret; } -#define utf8_walkbyte(string) (*((*(string))++)) - /* Does not validate the input, returns garbage if it's not UTF-8. */ uint32_t utf8_walk(const char **string) { - uint8_t first = utf8_walkbyte(string); + uint8_t first = UTF8_WALKBYTE(string); uint32_t ret = 0; if (first < 128) return first; - ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F); + ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F); if (first >= 0xE0) { - ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F); + ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F); if (first >= 0xF0) { - ret = (ret << 6) | (utf8_walkbyte(string) & 0x3F); + ret = (ret << 6) | (UTF8_WALKBYTE(string) & 0x3F); return ret | (first & 7) << 18; } return ret | (first & 15) << 12; @@ -277,9 +284,7 @@ bool utf16_to_char_string(const uint16_t *in, char *s, size_t len) static char *mb_to_mb_string_alloc(const char *str, enum CodePage cp_in, enum CodePage cp_out) { - char *path_buf = NULL; wchar_t *path_buf_wide = NULL; - int path_buf_len = 0; int path_buf_wide_len = MultiByteToWideChar(cp_in, 0, str, -1, NULL, 0); /* Windows 95 will return 0 from these functions with @@ -292,54 +297,51 @@ static char *mb_to_mb_string_alloc(const char *str, * MultiByteToWideChar also supports CP_UTF7 and CP_UTF8. */ - if (path_buf_wide_len) - { - path_buf_wide = (wchar_t*) - calloc(path_buf_wide_len + sizeof(wchar_t), sizeof(wchar_t)); - - if (path_buf_wide) - { - MultiByteToWideChar(cp_in, 0, - str, -1, path_buf_wide, path_buf_wide_len); - - if (*path_buf_wide) - { - path_buf_len = WideCharToMultiByte(cp_out, 0, - path_buf_wide, -1, NULL, 0, NULL, NULL); - - if (path_buf_len) - { - path_buf = (char*) - calloc(path_buf_len + sizeof(char), sizeof(char)); - - if (path_buf) - { - WideCharToMultiByte(cp_out, 0, - path_buf_wide, -1, path_buf, - path_buf_len, NULL, NULL); - - free(path_buf_wide); - - if (*path_buf) - return path_buf; - - free(path_buf); - return NULL; - } - } - else - { - free(path_buf_wide); - return strdup(str); - } - } - } - } - else + if (!path_buf_wide_len) return strdup(str); + path_buf_wide = (wchar_t*) + calloc(path_buf_wide_len + sizeof(wchar_t), sizeof(wchar_t)); + if (path_buf_wide) + { + MultiByteToWideChar(cp_in, 0, + str, -1, path_buf_wide, path_buf_wide_len); + + if (*path_buf_wide) + { + int path_buf_len = WideCharToMultiByte(cp_out, 0, + path_buf_wide, -1, NULL, 0, NULL, NULL); + + if (path_buf_len) + { + char *path_buf = (char*) + calloc(path_buf_len + sizeof(char), sizeof(char)); + + if (path_buf) + { + WideCharToMultiByte(cp_out, 0, + path_buf_wide, -1, path_buf, + path_buf_len, NULL, NULL); + + free(path_buf_wide); + + if (*path_buf) + return path_buf; + + free(path_buf); + return NULL; + } + } + else + { + free(path_buf_wide); + return strdup(str); + } + } + free(path_buf_wide); + } return NULL; } @@ -379,13 +381,13 @@ char* local_to_utf8_string_alloc(const char *str) wchar_t* utf8_to_utf16_string_alloc(const char *str) { #ifdef _WIN32 - int len = 0; - int out_len = 0; + int len = 0; + int out_len = 0; #else - size_t len = 0; + size_t len = 0; size_t out_len = 0; #endif - wchar_t *buf = NULL; + wchar_t *buf = NULL; if (!str || !*str) return NULL; diff --git a/src/drivers/libretro/libretro-common/include/boolean.h b/src/drivers/libretro/libretro-common/include/boolean.h index f06ac5a..9d0d7c1 100644 --- a/src/drivers/libretro/libretro-common/include/boolean.h +++ b/src/drivers/libretro/libretro-common/include/boolean.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (boolean.h). diff --git a/src/drivers/libretro/libretro-common/include/compat/msvc.h b/src/drivers/libretro/libretro-common/include/compat/msvc.h index 1c24263..a4c93a5 100644 --- a/src/drivers/libretro/libretro-common/include/compat/msvc.h +++ b/src/drivers/libretro/libretro-common/include/compat/msvc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (msvc.h). @@ -29,22 +29,17 @@ extern "C" { #endif -/* Pre-MSVC 2015 compilers don't implement snprintf in a cross-platform manner. */ +/* Pre-MSVC 2015 compilers don't implement snprintf, vsnprintf in a cross-platform manner. */ #if _MSC_VER < 1900 - #include - #include - #ifndef snprintf - #define snprintf c99_snprintf_retro__ - #endif - - int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...); -#endif - -/* Pre-MSVC 2008 compilers don't implement vsnprintf in a cross-platform manner? Not sure about this one. */ -#if _MSC_VER < 1500 #include #include #include + + #ifndef snprintf + #define snprintf c99_snprintf_retro__ + #endif + int c99_snprintf_retro__(char *outBuf, size_t size, const char *format, ...); + #ifndef vsnprintf #define vsnprintf c99_vsnprintf_retro__ #endif diff --git a/src/drivers/libretro/libretro-common/include/compat/strl.h b/src/drivers/libretro/libretro-common/include/compat/strl.h index c70f119..5e7a892 100644 --- a/src/drivers/libretro/libretro-common/include/compat/strl.h +++ b/src/drivers/libretro/libretro-common/include/compat/strl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (strl.h). diff --git a/src/drivers/libretro/libretro-common/include/encodings/crc32.h b/src/drivers/libretro/libretro-common/include/encodings/crc32.h index 25e9262..5236c91 100644 --- a/src/drivers/libretro/libretro-common/include/encodings/crc32.h +++ b/src/drivers/libretro/libretro-common/include/encodings/crc32.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (crc32.h). diff --git a/src/drivers/libretro/libretro-common/include/encodings/utf.h b/src/drivers/libretro/libretro-common/include/encodings/utf.h index b513f28..bea4e14 100644 --- a/src/drivers/libretro/libretro-common/include/encodings/utf.h +++ b/src/drivers/libretro/libretro-common/include/encodings/utf.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (utf.h). @@ -35,7 +35,7 @@ RETRO_BEGIN_DECLS enum CodePage { CODEPAGE_LOCAL = 0, /* CP_ACP */ - CODEPAGE_UTF8 = 65001 /* CP_UTF8 */ + CODEPAGE_UTF8 = 65001 /* CP_UTF8 */ }; size_t utf8_conv_utf32(uint32_t *out, size_t out_chars, diff --git a/src/drivers/libretro/libretro-common/include/encodings/win32.h b/src/drivers/libretro/libretro-common/include/encodings/win32.h index d4221bd..8104af0 100644 --- a/src/drivers/libretro/libretro-common/include/encodings/win32.h +++ b/src/drivers/libretro/libretro-common/include/encodings/win32.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (utf.h). diff --git a/src/drivers/libretro/libretro-common/include/libretro.h b/src/drivers/libretro/libretro-common/include/libretro.h index 4ddb6e8..59bd513 100644 --- a/src/drivers/libretro/libretro-common/include/libretro.h +++ b/src/drivers/libretro/libretro-common/include/libretro.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this libretro API header (libretro.h). @@ -278,6 +278,10 @@ enum retro_language RETRO_LANGUAGE_ARABIC = 16, RETRO_LANGUAGE_GREEK = 17, RETRO_LANGUAGE_TURKISH = 18, + RETRO_LANGUAGE_SLOVAK = 19, + RETRO_LANGUAGE_PERSIAN = 20, + RETRO_LANGUAGE_HEBREW = 21, + RETRO_LANGUAGE_ASTURIAN = 22, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ @@ -1087,10 +1091,10 @@ enum retro_mod #define RETRO_ENVIRONMENT_GET_TARGET_REFRESH_RATE (50 | RETRO_ENVIRONMENT_EXPERIMENTAL) /* float * -- - * Float value that lets us know what target refresh rate + * 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 + * The core can use the returned value to set an ideal * refresh rate/framerate. */ @@ -1098,7 +1102,7 @@ enum retro_mod /* 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 + * 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' @@ -1287,6 +1291,89 @@ enum retro_mod * based systems). */ +#define RETRO_ENVIRONMENT_GET_MESSAGE_INTERFACE_VERSION 59 + /* unsigned * -- + * Unsigned value is the API version number of the message + * interface supported by the frontend. If callback returns + * false, API version is assumed to be 0. + * + * In legacy code, messages may be displayed in an + * implementation-specific manner by passing a struct + * of type retro_message to RETRO_ENVIRONMENT_SET_MESSAGE. + * This may be still be done regardless of the message + * interface version. + * + * If version is >= 1 however, messages may instead be + * displayed by passing a struct of type retro_message_ext + * to RETRO_ENVIRONMENT_SET_MESSAGE_EXT. This allows the + * core to specify message logging level, priority and + * destination (OSD, logging interface or both). + */ + +#define RETRO_ENVIRONMENT_SET_MESSAGE_EXT 60 + /* const struct retro_message_ext * -- + * Sets a message to be displayed in an implementation-specific + * manner for a certain amount of 'frames'. Additionally allows + * the core to specify message logging level, priority and + * destination (OSD, logging interface or both). + * Should not be used for trivial messages, which should simply be + * logged via RETRO_ENVIRONMENT_GET_LOG_INTERFACE (or as a + * fallback, stderr). + */ + +#define RETRO_ENVIRONMENT_GET_INPUT_MAX_USERS 61 + /* unsigned * -- + * Unsigned value is the number of active input devices + * provided by the frontend. This may change between + * frames, but will remain constant for the duration + * of each frame. + * If callback returns true, a core need not poll any + * input device with an index greater than or equal to + * the number of active devices. + * If callback returns false, the number of active input + * devices is unknown. In this case, all input devices + * should be considered active. + */ + +#define RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK 62 + /* const struct retro_audio_buffer_status_callback * -- + * Lets the core know the occupancy level of the frontend + * audio buffer. Can be used by a core to attempt frame + * skipping in order to avoid buffer under-runs. + * A core may pass NULL to disable buffer status reporting + * in the frontend. + */ + +#define RETRO_ENVIRONMENT_SET_MINIMUM_AUDIO_LATENCY 63 + /* const unsigned * -- + * Sets minimum frontend audio latency in milliseconds. + * Resultant audio latency may be larger than set value, + * or smaller if a hardware limit is encountered. A frontend + * is expected to honour requests up to 512 ms. + * + * - If value is less than current frontend + * audio latency, callback has no effect + * - If value is zero, default frontend audio + * latency is set + * + * May be used by a core to increase audio latency and + * therefore decrease the probability of buffer under-runs + * (crackling) when performing 'intensive' operations. + * A core utilising RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK + * to implement audio-buffer-based frame skipping may achieve + * optimal results by setting the audio latency to a 'high' + * (typically 6x or 8x) integer multiple of the expected + * frame time. + * + * WARNING: This can only be called from within retro_run(). + * Calling this can require a full reinitialization of audio + * drivers in the frontend, so it is important to call it very + * sparingly, and usually only with the users explicit consent. + * An eventual driver reinitialize will happen so that audio + * callbacks happening after this call within the same retro_run() + * call will target the newly initialized driver. + */ + /* VFS functionality */ /* File paths: @@ -2176,6 +2263,30 @@ struct retro_frame_time_callback retro_usec_t reference; }; +/* Notifies a libretro core of the current occupancy + * level of the frontend audio buffer. + * + * - active: 'true' if audio buffer is currently + * in use. Will be 'false' if audio is + * disabled in the frontend + * + * - occupancy: Given as a value in the range [0,100], + * corresponding to the occupancy percentage + * of the audio buffer + * + * - underrun_likely: 'true' if the frontend expects an + * audio buffer underrun during the + * next frame (indicates that a core + * should attempt frame skipping) + * + * It will be called right before retro_run() every frame. */ +typedef void (RETRO_CALLCONV *retro_audio_buffer_status_callback_t)( + bool active, unsigned occupancy, bool underrun_likely); +struct retro_audio_buffer_status_callback +{ + retro_audio_buffer_status_callback_t callback; +}; + /* Pass this to retro_video_refresh_t if rendering to hardware. * Passing NULL to retro_video_refresh_t is still a frame dupe as normal. * */ @@ -2506,6 +2617,104 @@ struct retro_message unsigned frames; /* Duration in frames of message. */ }; +enum retro_message_target +{ + RETRO_MESSAGE_TARGET_ALL = 0, + RETRO_MESSAGE_TARGET_OSD, + RETRO_MESSAGE_TARGET_LOG +}; + +enum retro_message_type +{ + RETRO_MESSAGE_TYPE_NOTIFICATION = 0, + RETRO_MESSAGE_TYPE_NOTIFICATION_ALT, + RETRO_MESSAGE_TYPE_STATUS, + RETRO_MESSAGE_TYPE_PROGRESS +}; + +struct retro_message_ext +{ + /* Message string to be displayed/logged */ + const char *msg; + /* Duration (in ms) of message when targeting the OSD */ + unsigned duration; + /* Message priority when targeting the OSD + * > When multiple concurrent messages are sent to + * the frontend and the frontend does not have the + * capacity to display them all, messages with the + * *highest* priority value should be shown + * > There is no upper limit to a message priority + * value (within the bounds of the unsigned data type) + * > In the reference frontend (RetroArch), the same + * priority values are used for frontend-generated + * notifications, which are typically assigned values + * between 0 and 3 depending upon importance */ + unsigned priority; + /* Message logging level (info, warn, error, etc.) */ + enum retro_log_level level; + /* Message destination: OSD, logging interface or both */ + enum retro_message_target target; + /* Message 'type' when targeting the OSD + * > RETRO_MESSAGE_TYPE_NOTIFICATION: Specifies that a + * message should be handled in identical fashion to + * a standard frontend-generated notification + * > RETRO_MESSAGE_TYPE_NOTIFICATION_ALT: Specifies that + * message is a notification that requires user attention + * or action, but that it should be displayed in a manner + * that differs from standard frontend-generated notifications. + * This would typically correspond to messages that should be + * displayed immediately (independently from any internal + * frontend message queue), and/or which should be visually + * distinguishable from frontend-generated notifications. + * For example, a core may wish to inform the user of + * information related to a disk-change event. It is + * expected that the frontend itself may provide a + * notification in this case; if the core sends a + * message of type RETRO_MESSAGE_TYPE_NOTIFICATION, an + * uncomfortable 'double-notification' may occur. A message + * of RETRO_MESSAGE_TYPE_NOTIFICATION_ALT should therefore + * be presented such that visual conflict with regular + * notifications does not occur + * > RETRO_MESSAGE_TYPE_STATUS: Indicates that message + * is not a standard notification. This typically + * corresponds to 'status' indicators, such as a core's + * internal FPS, which are intended to be displayed + * either permanently while a core is running, or in + * a manner that does not suggest user attention or action + * is required. 'Status' type messages should therefore be + * displayed in a different on-screen location and in a manner + * easily distinguishable from both standard frontend-generated + * notifications and messages of type RETRO_MESSAGE_TYPE_NOTIFICATION_ALT + * > RETRO_MESSAGE_TYPE_PROGRESS: Indicates that message reports + * the progress of an internal core task. For example, in cases + * where a core itself handles the loading of content from a file, + * this may correspond to the percentage of the file that has been + * read. Alternatively, an audio/video playback core may use a + * message of type RETRO_MESSAGE_TYPE_PROGRESS to display the current + * playback position as a percentage of the runtime. 'Progress' type + * messages should therefore be displayed as a literal progress bar, + * where: + * - 'retro_message_ext.msg' is the progress bar title/label + * - 'retro_message_ext.progress' determines the length of + * the progress bar + * NOTE: Message type is a *hint*, and may be ignored + * by the frontend. If a frontend lacks support for + * displaying messages via alternate means than standard + * frontend-generated notifications, it will treat *all* + * messages as having the type RETRO_MESSAGE_TYPE_NOTIFICATION */ + enum retro_message_type type; + /* Task progress when targeting the OSD and message is + * of type RETRO_MESSAGE_TYPE_PROGRESS + * > -1: Unmetered/indeterminate + * > 0-100: Current progress percentage + * NOTE: Since message type is a hint, a frontend may ignore + * progress values. Where relevant, a core should therefore + * include progress percentage within the message string, + * such that the message intent remains clear when displayed + * as a standard frontend-generated notification */ + int8_t progress; +}; + /* Describes how the libretro implementation maps a libretro input bind * to its internal input system through a human readable string. * This string can be used to better let a user configure input. */ @@ -2526,7 +2735,7 @@ struct retro_input_descriptor struct retro_system_info { /* All pointers are owned by libretro implementation, and pointers must - * remain valid until retro_deinit() is called. */ + * remain valid until it is unloaded. */ const char *library_name; /* Descriptive name of library. Should not * contain any version numbers, etc. */ diff --git a/src/drivers/libretro/libretro-common/include/retro_common.h b/src/drivers/libretro/libretro-common/include/retro_common.h index 9a1fd5f..a715a28 100644 --- a/src/drivers/libretro/libretro-common/include/retro_common.h +++ b/src/drivers/libretro/libretro-common/include/retro_common.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_common.h). diff --git a/src/drivers/libretro/libretro-common/include/retro_common_api.h b/src/drivers/libretro/libretro-common/include/retro_common_api.h index d784842..0f68b7d 100644 --- a/src/drivers/libretro/libretro-common/include/retro_common_api.h +++ b/src/drivers/libretro/libretro-common/include/retro_common_api.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_common_api.h). diff --git a/src/drivers/libretro/libretro-common/include/retro_inline.h b/src/drivers/libretro/libretro-common/include/retro_inline.h index e4a21f6..b27d6dd 100644 --- a/src/drivers/libretro/libretro-common/include/retro_inline.h +++ b/src/drivers/libretro/libretro-common/include/retro_inline.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (retro_inline.h). diff --git a/src/drivers/libretro/libretro-common/include/streams/memory_stream.h b/src/drivers/libretro/libretro-common/include/streams/memory_stream.h index f9e641b..2c6f3fc 100644 --- a/src/drivers/libretro/libretro-common/include/streams/memory_stream.h +++ b/src/drivers/libretro/libretro-common/include/streams/memory_stream.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (memory_stream.h). diff --git a/src/drivers/libretro/libretro-common/include/string/stdstring.h b/src/drivers/libretro/libretro-common/include/string/stdstring.h index d57256a..5d8c31b 100644 --- a/src/drivers/libretro/libretro-common/include/string/stdstring.h +++ b/src/drivers/libretro/libretro-common/include/string/stdstring.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2019 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (stdstring.h). @@ -35,6 +35,33 @@ RETRO_BEGIN_DECLS +#define STRLEN_CONST(x) ((sizeof((x))-1)) + +#define strcpy_literal(a, b) strcpy(a, b) + +#define string_is_not_equal(a, b) !string_is_equal((a), (b)) + +#define string_is_not_equal_fast(a, b, size) (memcmp(a, b, size) != 0) +#define string_is_equal_fast(a, b, size) (memcmp(a, b, size) == 0) + +#define TOLOWER(c) (c | (lr_char_props[c] & 0x20)) +#define TOUPPER(c) (c & ~(lr_char_props[c] & 0x20)) + +/* C standard says \f \v are space, but this one disagrees */ +#define ISSPACE(c) (lr_char_props[c] & 0x80) + +#define ISDIGIT(c) (lr_char_props[c] & 0x40) +#define ISALPHA(c) (lr_char_props[c] & 0x20) +#define ISLOWER(c) (lr_char_props[c] & 0x04) +#define ISUPPER(c) (lr_char_props[c] & 0x02) +#define ISALNUM(c) (lr_char_props[c] & 0x60) +#define ISUALPHA(c) (lr_char_props[c] & 0x28) +#define ISUALNUM(c) (lr_char_props[c] & 0x68) +#define IS_XDIGIT(c) (lr_char_props[c] & 0x01) + +/* Deprecated alias, all callers should use string_is_equal_case_insensitive instead */ +#define string_is_equal_noncase string_is_equal_case_insensitive + static INLINE bool string_is_empty(const char *data) { return !data || (*data == '\0'); @@ -45,12 +72,44 @@ static INLINE bool string_is_equal(const char *a, const char *b) return (a && b) ? !strcmp(a, b) : false; } -#define STRLEN_CONST(x) ((sizeof((x))-1)) +static INLINE bool string_starts_with_size(const char *str, const char *prefix, + size_t size) +{ + return (str && prefix) ? !strncmp(prefix, str, size) : false; +} -#define string_is_not_equal(a, b) !string_is_equal((a), (b)) +static INLINE bool string_starts_with(const char *str, const char *prefix) +{ + return (str && prefix) ? !strncmp(prefix, str, strlen(prefix)) : false; +} + +static INLINE bool string_ends_with_size(const char *str, const char *suffix, + size_t str_len, size_t suffix_len) +{ + return (str_len < suffix_len) ? false : + !memcmp(suffix, str + (str_len - suffix_len), suffix_len); +} + +static INLINE bool string_ends_with(const char *str, const char *suffix) +{ + if (!str || !suffix) + return false; + return string_ends_with_size(str, suffix, strlen(str), strlen(suffix)); +} + +/* Returns the length of 'str' (c.f. strlen()), but only + * checks the first 'size' characters + * - If 'str' is NULL, returns 0 + * - If 'str' is not NULL and no '\0' character is found + * in the first 'size' characters, returns 'size' */ +static INLINE size_t strlen_size(const char *str, size_t size) +{ + size_t i = 0; + if (str) + while (i < size && str[i]) i++; + return i; +} -#define string_is_not_equal_fast(a, b, size) (memcmp(a, b, size) != 0) -#define string_is_equal_fast(a, b, size) (memcmp(a, b, size) == 0) static INLINE bool string_is_equal_case_insensitive(const char *a, const char *b) @@ -71,24 +130,6 @@ static INLINE bool string_is_equal_case_insensitive(const char *a, return (result == 0); } -static INLINE bool string_is_equal_noncase(const char *a, const char *b) -{ - int result = 0; - const unsigned char *p1 = (const unsigned char*)a; - const unsigned char *p2 = (const unsigned char*)b; - - if (!a || !b) - return false; - if (p1 == p2) - return false; - - while ((result = tolower (*p1) - tolower (*p2++)) == 0) - if (*p1++ == '\0') - break; - - return (result == 0); -} - char *string_to_upper(char *s); char *string_to_lower(char *s); @@ -121,7 +162,7 @@ char *word_wrap(char *buffer, const char *string, * char *str = "1,2,3,4,5,6,7,,,10,"; * char **str_ptr = &str; * char *token = NULL; - * while((token = string_tokenize(str_ptr, ","))) + * while ((token = string_tokenize(str_ptr, ","))) * { * printf("%s\n", token); * free(token); @@ -146,6 +187,12 @@ unsigned string_to_unsigned(const char *str); * Returns 0 if string is invalid */ unsigned string_hex_to_unsigned(const char *str); +char *string_init(const char *src); + +void string_set(char **string, const char *src); + +extern const unsigned char lr_char_props[256]; + RETRO_END_DECLS #endif diff --git a/src/drivers/libretro/libretro-common/streams/memory_stream.c b/src/drivers/libretro/libretro-common/streams/memory_stream.c index 829ef03..2aa1c80 100644 --- a/src/drivers/libretro/libretro-common/streams/memory_stream.c +++ b/src/drivers/libretro/libretro-common/streams/memory_stream.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (memory_stream.c). @@ -26,29 +26,24 @@ #include +/* TODO/FIXME - static globals */ static uint8_t* g_buffer = NULL; static uint64_t g_size = 0; static uint64_t last_file_size = 0; struct memstream { - uint8_t *buf; uint64_t size; uint64_t ptr; uint64_t max_ptr; + uint8_t *buf; unsigned writing; }; -static void memstream_update_pos(memstream_t *stream) -{ - if (stream && stream->ptr > stream->max_ptr) - stream->max_ptr = stream->ptr; -} - void memstream_set_buffer(uint8_t *buffer, uint64_t size) { g_buffer = buffer; - g_size = size; + g_size = size; } uint64_t memstream_get_last_size(void) @@ -56,30 +51,26 @@ uint64_t memstream_get_last_size(void) return last_file_size; } -static void memstream_init(memstream_t *stream, - uint8_t *buffer, uint64_t max_size, unsigned writing) -{ - if (!stream) - return; - - stream->buf = buffer; - stream->size = max_size; - stream->ptr = 0; - stream->max_ptr = 0; - stream->writing = writing; -} - memstream_t *memstream_open(unsigned writing) { memstream_t *stream; if (!g_buffer || !g_size) return NULL; - stream = (memstream_t*)calloc(1, sizeof(*stream)); - memstream_init(stream, g_buffer, g_size, writing); + stream = (memstream_t*)malloc(sizeof(*stream)); + + if (!stream) + return NULL; + + stream->buf = g_buffer; + stream->size = g_size; + stream->ptr = 0; + stream->max_ptr = 0; + stream->writing = writing; + + g_buffer = NULL; + g_size = 0; - g_buffer = NULL; - g_size = 0; return stream; } @@ -104,17 +95,19 @@ uint64_t memstream_read(memstream_t *stream, void *data, uint64_t bytes) if (!stream) return 0; - avail = stream->size - stream->ptr; + avail = stream->size - stream->ptr; if (bytes > avail) - bytes = avail; + bytes = avail; memcpy(data, stream->buf + stream->ptr, (size_t)bytes); - stream->ptr += bytes; - memstream_update_pos(stream); + stream->ptr += bytes; + if (stream->ptr > stream->max_ptr) + stream->max_ptr = stream->ptr; return bytes; } -uint64_t memstream_write(memstream_t *stream, const void *data, uint64_t bytes) +uint64_t memstream_write(memstream_t *stream, + const void *data, uint64_t bytes) { uint64_t avail = 0; @@ -127,7 +120,8 @@ uint64_t memstream_write(memstream_t *stream, const void *data, uint64_t bytes) memcpy(stream->buf + stream->ptr, data, (size_t)bytes); stream->ptr += bytes; - memstream_update_pos(stream); + if (stream->ptr > stream->max_ptr) + stream->max_ptr = stream->ptr; return bytes; } @@ -181,7 +175,8 @@ int memstream_getc(memstream_t *stream) return EOF; ret = stream->buf[stream->ptr++]; - memstream_update_pos(stream); + if (stream->ptr > stream->max_ptr) + stream->max_ptr = stream->ptr; return ret; } @@ -191,5 +186,6 @@ void memstream_putc(memstream_t *stream, int c) if (stream->ptr < stream->size) stream->buf[stream->ptr++] = c; - memstream_update_pos(stream); + if (stream->ptr > stream->max_ptr) + stream->max_ptr = stream->ptr; } diff --git a/src/drivers/libretro/libretro-common/string/stdstring.c b/src/drivers/libretro/libretro-common/string/stdstring.c index e2afef1..67ee7fc 100644 --- a/src/drivers/libretro/libretro-common/string/stdstring.c +++ b/src/drivers/libretro/libretro-common/string/stdstring.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2010-2018 The RetroArch team +/* Copyright (C) 2010-2020 The RetroArch team * * --------------------------------------------------------------------------------------- * The following license statement only applies to this file (stdstring.c). @@ -22,10 +22,43 @@ #include #include +#include #include #include +const uint8_t lr_char_props[256] = { + /*x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x80,0x00,0x00, /* 0x */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 1x */ + 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 2x !"#$%&'()*+,-./ */ + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00, /* 3x 0123456789:;<=>? */ + 0x00,0x23,0x23,0x23,0x23,0x23,0x23,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, /* 4x @ABCDEFGHIJKLMNO */ + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00,0x08, /* 5x PQRSTUVWXYZ[\]^_ */ + 0x00,0x25,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24, /* 6x `abcdefghijklmno */ + 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00, /* 7x pqrstuvwxyz{|}~ */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8x */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 9x */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Ax */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Bx */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Cx */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Dx */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Ex */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Fx */ +}; + +char *string_init(const char *src) +{ + return src ? strdup(src) : NULL; +} + +void string_set(char **string, const char *src) +{ + free(*string); + *string = string_init(src); +} + + char *string_to_upper(char *s) { char *cs = (char *)s; @@ -107,18 +140,18 @@ char *string_replace_substring(const char *in, /* Remove leading whitespaces */ char *string_trim_whitespace_left(char *const s) { - if(s && *s) + if (s && *s) { size_t len = strlen(s); char *current = s; - while(*current && isspace((unsigned char)*current)) + while (*current && ISSPACE((unsigned char)*current)) { ++current; --len; } - if(s != current) + if (s != current) memmove(s, current, len + 1); } @@ -128,18 +161,18 @@ char *string_trim_whitespace_left(char *const s) /* Remove trailing whitespaces */ char *string_trim_whitespace_right(char *const s) { - if(s && *s) + if (s && *s) { size_t len = strlen(s); char *current = s + len - 1; - while(current != s && isspace((unsigned char)*current)) + while (current != s && ISSPACE((unsigned char)*current)) { --current; --len; } - current[isspace((unsigned char)*current) ? 0 : 1] = '\0'; + current[ISSPACE((unsigned char)*current) ? 0 : 1] = '\0'; } return s; @@ -190,7 +223,7 @@ char *word_wrap(char* buffer, const char *string, int line_width, bool unicode, buffer[i] = string[i]; char_len--; i++; - } while(char_len); + } while (char_len); /* check for newlines embedded in the original input * and reset the index */ @@ -248,7 +281,7 @@ char *word_wrap(char* buffer, const char *string, int line_width, bool unicode, * char *str = "1,2,3,4,5,6,7,,,10,"; * char **str_ptr = &str; * char *token = NULL; - * while((token = string_tokenize(str_ptr, ","))) + * while ((token = string_tokenize(str_ptr, ","))) * { * printf("%s\n", token); * free(token); @@ -328,7 +361,7 @@ void string_replace_all_chars(char *str, char find, char replace) if (string_is_empty(str)) return; - while((str_ptr = strchr(str_ptr, find)) != NULL) + while ((str_ptr = strchr(str_ptr, find))) *str_ptr++ = replace; } @@ -343,7 +376,7 @@ unsigned string_to_unsigned(const char *str) for (ptr = str; *ptr != '\0'; ptr++) { - if (!isdigit(*ptr)) + if (!ISDIGIT((unsigned char)*ptr)) return 0; } @@ -376,7 +409,7 @@ unsigned string_hex_to_unsigned(const char *str) /* Check for valid characters */ for (ptr = hex_str; *ptr != '\0'; ptr++) { - if (!isxdigit(*ptr)) + if (!isxdigit((unsigned char)*ptr)) return 0; } From 2ae14b75de84c27736aec633d12c0d31f0d78e6b Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sun, 25 Oct 2020 13:58:06 +0800 Subject: [PATCH 049/295] APU: Move duty cycle swapping during apu writes --- src/sound.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sound.c b/src/sound.c index 40973c2..a3f331b 100644 --- a/src/sound.c +++ b/src/sound.c @@ -195,6 +195,8 @@ static DECLFW(Write_PSG) { DoSQ1(); EnvUnits[0].Mode = (V & 0x30) >> 4; EnvUnits[0].Speed = (V & 0xF); + if (swapDuty) + V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1); break; case 0x1: DoSQ1(); @@ -214,6 +216,8 @@ static DECLFW(Write_PSG) { DoSQ2(); EnvUnits[1].Mode = (V & 0x30) >> 4; EnvUnits[1].Speed = (V & 0xF); + if (swapDuty) + V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1); break; case 0x5: DoSQ2(); @@ -561,8 +565,6 @@ static INLINE void RDoSQ(int x) { amp <<= 24; dutyCycle = (PSG[(x << 2)] & 0xC0) >> 6; - if (swapDuty) - dutyCycle = ((dutyCycle & 2) >> 1) | ((dutyCycle & 1) << 1); rthresh = RectDuties[dutyCycle]; currdc = RectDutyCount[x]; D = &WaveHi[ChannelBC[x]]; @@ -640,8 +642,6 @@ static void RDoSQLQ(void) { if (!inie[x]) amp[x] = 0; /* Correct? Buzzing in MM2, others otherwise... */ dutyCycle = (PSG[(x << 2)] & 0xC0) >> 6; - if (swapDuty) - dutyCycle = ((dutyCycle & 2) >> 1) | ((dutyCycle & 1) << 1); rthresh[x] = RectDuties[dutyCycle]; for (y = 0; y < 8; y++) { From 4e2c5468e4f4ac72ef318ee2756db4eb9cc2037f Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sun, 25 Oct 2020 19:13:45 +0800 Subject: [PATCH 050/295] Overclock: Remove this for region change These variables, normal_scanlines and totalscanlines will get updated if FCUI_SetVidSystem(), so no need to set it here. --- src/drivers/libretro/libretro.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 90e1790..b29fdec 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1053,7 +1053,7 @@ static void retro_set_custom_palette(void) * Dendy has PAL framerate and resolution, but ~NTSC timings, * and has 50 dummy scanlines to force 50 fps. */ -void FCEUD_RegionOverride(unsigned region) +static void FCEUD_RegionOverride(unsigned region) { unsigned pal = 0; unsigned d = 0; @@ -1078,8 +1078,6 @@ void FCEUD_RegionOverride(unsigned region) } dendy = d; - normal_scanlines = dendy ? 290 : 240; - totalscanlines = normal_scanlines + (overclock_enabled ? extrascanlines : 0); FCEUI_SetVidSystem(pal); ResetPalette(); } From 9f465177922f95c561e1204a793b045d9d8bf702 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 26 Oct 2020 06:51:20 +0800 Subject: [PATCH 051/295] Fix some warnings reported from LGTM --- src/boards/269.c | 2 +- src/input/shadow.c | 2 +- src/input/zapper.c | 2 +- src/sound.c | 10 ++++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/boards/269.c b/src/boards/269.c index 358ccce..b62f50f 100644 --- a/src/boards/269.c +++ b/src/boards/269.c @@ -80,7 +80,7 @@ static uint8 unscrambleCHR(uint8 data) { } void Mapper269_Init(CartInfo *info) { - uint8 i; + uint32 i; GenMMC3_Init(info, 512, 0, 8, 0); cwrap = M269CW; pwrap = M269PW; diff --git a/src/input/shadow.c b/src/input/shadow.c index 8f9d767..e8b0aa9 100644 --- a/src/input/shadow.c +++ b/src/input/shadow.c @@ -66,7 +66,7 @@ static void FP_FASTAPASS(3) ZapperFrapper(uint8 * bg, uint8 * spr, uint32 linets sum = palo[a1].r + palo[a1].g + palo[a1].b; if (sum >= 100 * 3) { - ZD.zaphit = ((uint64)linets + (xs + 16) * (PAL ? 15 : 16)) / 48 + timestampbase; + ZD.zaphit = ((uint64)linets + (uint64)(xs + 16) * (PAL ? 15 : 16)) / 48 + timestampbase; goto endo; } } diff --git a/src/input/zapper.c b/src/input/zapper.c index 40a182a..3d891f4 100644 --- a/src/input/zapper.c +++ b/src/input/zapper.c @@ -82,7 +82,7 @@ static void FP_FASTAPASS(3) ZapperFrapper(int w, uint8 * bg, uint8 * spr, uint32 sum = palo[a1].r + palo[a1].g + palo[a1].b; if (sum >= 100 * 3) { - ZD[w].zaphit = ((uint64)linets + (xs + 16) * (PAL ? 15 : 16)) / 48 + timestampbase; + ZD[w].zaphit = ((uint64)linets + (uint64)(xs + 16) * (PAL ? 15 : 16)) / 48 + timestampbase; goto endo; } } diff --git a/src/sound.c b/src/sound.c index a3f331b..2fd2ca2 100644 --- a/src/sound.c +++ b/src/sound.c @@ -1254,7 +1254,7 @@ void FCEUSND_LoadState(int version) { /* minimal validation */ for (i = 0; i < 5; i++) { - int BC_max = 15; + uint32 BC_max = 15; if (FSettings.soundq == 2) { @@ -1264,7 +1264,7 @@ void FCEUSND_LoadState(int version) { { BC_max = 485; } - if (ChannelBC[i] < 0 || ChannelBC[i] > BC_max) + if (/* ChannelBC[i] < 0 || */ ChannelBC[i] > BC_max) { ChannelBC[i] = 0; } @@ -1283,14 +1283,16 @@ void FCEUSND_LoadState(int version) { RectDutyCount[i] = 7; } } - if (sound_timestamp < 0) + + /* Comparison is always false because access to array >= 0. */ + /* if (sound_timestamp < 0) { sound_timestamp = 0; } if (soundtsoffs < 0) { soundtsoffs = 0; - } + } */ if (soundtsoffs + sound_timestamp >= soundtsinc) { soundtsoffs = 0; From 1258eb759fbfe9a53ec2262da0c6626a3e003045 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Tue, 27 Oct 2020 04:00:53 +0100 Subject: [PATCH 052/295] Don't set pixel_format in retro_init libretro.h says "This function should be called inside retro_load_game() or retro_get_system_av_info().", let's do as it says. --- src/drivers/libretro/libretro.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 56b2bb2..7e5b6fb 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -981,18 +981,11 @@ static void check_system_specs(void) void retro_init(void) { bool achievements = true; - enum retro_pixel_format rgb565; log_cb.log=default_logger; environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log_cb); environ_cb(RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS, &achievements); -#ifdef FRONTEND_SUPPORTS_RGB565 - rgb565 = RETRO_PIXEL_FORMAT_RGB565; - if(environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565)) - log_cb.log(RETRO_LOG_INFO, "Frontend supports RGB565 - will use that instead of XRGB1555.\n"); -#endif - if (environ_cb(RETRO_ENVIRONMENT_GET_INPUT_BITMASKS, NULL)) libretro_supports_bitmasks = true; } @@ -2309,6 +2302,7 @@ bool retro_load_game(const struct retro_game_info *game) char* sav_dir=NULL; size_t fourscore_len = sizeof(fourscore_db_list) / sizeof(fourscore_db_list[0]); size_t famicom_4p_len = sizeof(famicom_4p_db_list) / sizeof(famicom_4p_db_list[0]); + enum retro_pixel_format rgb565; struct retro_input_descriptor desc[] = { { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" }, @@ -2367,6 +2361,12 @@ bool retro_load_game(const struct retro_game_info *game) if (!game) return false; +#ifdef FRONTEND_SUPPORTS_RGB565 + rgb565 = RETRO_PIXEL_FORMAT_RGB565; + if(environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565)) + log_cb.log(RETRO_LOG_INFO, "Frontend supports RGB565 - will use that instead of XRGB1555.\n"); +#endif + /* initialize some of the default variables */ #ifdef GEKKO sndsamplerate = 32000; From 344c12301fc661e1fdb752788a589497e7fc334e Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 26 Oct 2020 09:22:11 +0800 Subject: [PATCH 053/295] Add mapper 370 and 395, update mapper 221 Add support for mapper 395 Add support for mapper 370 Update mapper 221 for 2MB bank support --- src/boards/370.c | 96 ++++++++++++++++++++++++++++++++++++++++++++ src/boards/395.c | 67 +++++++++++++++++++++++++++++++ src/boards/n625092.c | 20 ++++----- src/ines.c | 2 + src/ines.h | 2 + 5 files changed, 177 insertions(+), 10 deletions(-) create mode 100644 src/boards/370.c create mode 100644 src/boards/395.c diff --git a/src/boards/370.c b/src/boards/370.c new file mode 100644 index 0000000..25f5887 --- /dev/null +++ b/src/boards/370.c @@ -0,0 +1,96 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 negativeExponent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Mapper 370 - F600 + * Golden Mario Party II - Around the World (6-in-1 multicart) + */ + +#include "mapinc.h" +#include "mmc3.h" + +static uint8 PPUCHRBus; +static uint8 mirr[8]; + +static void FP_FASTAPASS(1) M370PPU(uint32 A) { + if ((EXPREGS[0] & 7) == 1) { + A &= 0x1FFF; + A >>= 10; + PPUCHRBus = A; + setmirror(MI_0 + mirr[A]); + } +} + +static void M370CW(uint32 A, uint8 V) { + uint8 mask = (EXPREGS[0] & 4) ? 0x7F : 0xFF; + /* FIXME: Mario VII, mask is reversed? */ + if ((EXPREGS[0] & 7) == 6 && V & 0x80) + mask = 0xFF; + mirr[A >> 10] = V >> 7; + setchr1(A, (V & mask) | ((EXPREGS[0] & 7) << 7)); + if (((EXPREGS[0] & 7) == 1) && (PPUCHRBus == (A >> 10))) + setmirror(MI_0 + (V >> 7)); +} + +static void M370PW(uint32 A, uint8 V) { + uint8 mask = EXPREGS[0] & 0x20 ? 0x0F : 0x1F; + setprg8(A, (V & mask) | ((EXPREGS[0] & 0x38) << 1)); +} + +static void M370MW(uint8 V) { + A000B = V; + if ((EXPREGS[0] & 7) != 1) + setmirror((V & 1) ^ 1); +} + +static DECLFR(M370Read) {; + return (EXPREGS[1] << 7); +} + +static DECLFW(M370Write) { + EXPREGS[0] = (A & 0xFF); + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); +} + +static void M370Reset(void) { + EXPREGS[0] = 0; + EXPREGS[1] ^= 1; + FCEU_printf("solderpad=%02x\n", EXPREGS[1]); + MMC3RegReset(); +} + +static void M370Power(void) { + EXPREGS[0] = 0; + EXPREGS[1] = 1; /* start off with the 6-in-1 menu */ + GenMMC3Power(); + SetReadHandler(0x5000, 0x5FFF, M370Read); + SetWriteHandler(0x5000, 0x5FFF, M370Write); +} + +void Mapper370_Init(CartInfo *info) { + GenMMC3_Init(info, 256, 256, 8, 0); + cwrap = M370CW; + pwrap = M370PW; + mwrap = M370MW; + PPU_hook = M370PPU; + info->Power = M370Power; + info->Reset = M370Reset; + AddExState(EXPREGS, 2, 0, "EXPR"); +} diff --git a/src/boards/395.c b/src/boards/395.c new file mode 100644 index 0000000..6508850 --- /dev/null +++ b/src/boards/395.c @@ -0,0 +1,67 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 negativeExponent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Mapper 395 - Realtec 8210 + * Super Card 12-in-1 (SPC002) + * Super Card 13-in-1 (SPC003) + * Super Card 14-in-1 (King006) + * Super Card 14-in-1 (King007) + */ + +#include "mapinc.h" +#include "mmc3.h" + +static void M395CW(uint32 A, uint8 V) { + uint8 mask = EXPREGS[1] & 0x40 ? 0x7F : 0xFF; + setchr1(A, (V & mask) | ((EXPREGS[1] & 0x10) << 3) | ((EXPREGS[0] & 0x30) << 4) | ((EXPREGS[1] & 0x20) << 5)); +} + +static void M395PW(uint32 A, uint8 V) { + uint8 mask = EXPREGS[1] & 8 ? 0x0F : 0x1F; + setprg8(A, (V & mask) | ((EXPREGS[0] & 0x30) << 1) | ((EXPREGS[0] & 8) << 4) | ((EXPREGS[1] & 1) << 4)); +} + +static DECLFW(M395Write) { + if (!(EXPREGS[1] & 0x80)) { + EXPREGS[(A >> 4) & 1] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } +} + +static void M395Reset(void) { + EXPREGS[0] = EXPREGS[1] = 0; + MMC3RegReset(); +} + +static void M395Power(void) { + EXPREGS[0] = EXPREGS[1] = 0; + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, M395Write); +} + +void Mapper395_Init(CartInfo *info) { + GenMMC3_Init(info, 256, 256, 0, 0); + cwrap = M395CW; + pwrap = M395PW; + info->Power = M395Power; + info->Reset = M395Reset; + AddExState(EXPREGS, 2, 0, "EXPR"); +} diff --git a/src/boards/n625092.c b/src/boards/n625092.c index 1f134c0..800d986 100644 --- a/src/boards/n625092.c +++ b/src/boards/n625092.c @@ -18,18 +18,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * 700in1 and 400in1 carts - * + * 1000-in-1 */ - #include "mapinc.h" static uint16 cmd, bank; static SFORMAT StateRegs[] = { - { &cmd, 2, "CMD" }, - { &bank, 2, "BANK" }, + { &cmd, 2 | FCEUSTATE_RLSB, "CMD" }, + { &bank, 2 | FCEUSTATE_RLSB, "BANK" }, { 0 } }; @@ -38,15 +37,15 @@ static void Sync(void) { setchr8(0); if (cmd & 2) { if (cmd & 0x100) { - setprg16(0x8000, ((cmd & 0xfc) >> 2) | bank); - setprg16(0xC000, ((cmd & 0xfc) >> 2) | 7); + setprg16(0x8000, ((cmd & 0x200) >> 3) | ((cmd & 0xfc) >> 2) | bank); + setprg16(0xC000, ((cmd & 0x200) >> 3) | ((cmd & 0xfc) >> 2) | 7); } else { - setprg16(0x8000, ((cmd & 0xfc) >> 2) | (bank & 6)); - setprg16(0xC000, ((cmd & 0xfc) >> 2) | ((bank & 6) | 1)); + setprg16(0x8000, ((cmd & 0x200) >> 3) | ((cmd & 0xfc) >> 2) | (bank & 6)); + setprg16(0xC000, ((cmd & 0x200) >> 3) | ((cmd & 0xfc) >> 2) | ((bank & 6) | 1)); } } else { - setprg16(0x8000, ((cmd & 0xfc) >> 2) | bank); - setprg16(0xC000, ((cmd & 0xfc) >> 2) | bank); + setprg16(0x8000, ((cmd & 0x200) >> 3) | ((cmd & 0xfc) >> 2) | bank); + setprg16(0xC000, ((cmd & 0x200) >> 3) | ((cmd & 0xfc) >> 2) | bank); } } @@ -81,6 +80,7 @@ static void UNLN625092Reset(void) { bank = 0; ass++; FCEU_printf("%04x\n", ass); + Sync(); } static void StateRestore(int version) { diff --git a/src/ines.c b/src/ines.c index ab839b7..93c3761 100644 --- a/src/ines.c +++ b/src/ines.c @@ -694,6 +694,7 @@ INES_BOARD_BEGIN() INES_BOARD( "Bitcorp 31-in-1", 360, Mapper360_Init ) INES_BOARD( "OK-411", 361, GN45_Init ) /* OK-411 is emulated together with GN-45 */ INES_BOARD( "GN-45", 366, GN45_Init ) + INES_BOARD( "Golden Mario Party II - Around the World 6-in-1", 370, Mapper370_Init ) INES_BOARD( "MMC3 PIRATE SFC-12", 372, Mapper372_Init ) INES_BOARD( "95/96 Super HiK 4-in-1", 374, Mapper374_Init ) INES_BOARD( "42 to 80,000 (970630C)", 380, Mapper380_Init ) @@ -701,6 +702,7 @@ INES_BOARD_BEGIN() INES_BOARD( "830928C", 382, Mapper382_Init ) INES_BOARD( "Caltron 9-in-1", 389, Mapper389_Init ) INES_BOARD( "Realtec 8031", 390, Mapper390_Init ) + INES_BOARD( "Realtec 8210", 395, Mapper395_Init ) INES_BOARD( "A88S-1", 411, Mapper411_Init ) INES_BOARD( "Brilliant Com Cocoma Pack", 516, Mapper516_Init ) INES_BOARD( "Sachen 3014", 533, Mapper533_Init ) diff --git a/src/ines.h b/src/ines.h index bc119f2..43085e4 100644 --- a/src/ines.h +++ b/src/ines.h @@ -259,6 +259,7 @@ void Mapper357_Init(CartInfo *); void Mapper359_Init(CartInfo *); void Mapper360_Init(CartInfo *); void Mapper369_Init(CartInfo *); +void Mapper370_Init(CartInfo *); void Mapper372_Init(CartInfo *); void Mapper374_Init(CartInfo *); void Mapper380_Init(CartInfo *); @@ -266,6 +267,7 @@ void Mapper381_Init(CartInfo *); void Mapper382_Init(CartInfo *); void Mapper389_Init(CartInfo *); void Mapper390_Init(CartInfo *); +void Mapper395_Init(CartInfo *); void Mapper411_Init(CartInfo *); void Mapper516_Init(CartInfo *); void Mapper533_Init(CartInfo *); From 66dc404582ee99d1ca1a1cf5866256f17dbcd13a Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 27 Oct 2020 10:03:59 +0800 Subject: [PATCH 054/295] Fix #398 --- src/boards/AbG1l.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/boards/AbG1l.c b/src/boards/AbG1l.c index 7305336..7fde82b 100644 --- a/src/boards/AbG1l.c +++ b/src/boards/AbG1l.c @@ -44,14 +44,25 @@ static void SyncAbG1l(void) { setprg16(0xC000, (regs[1] & 0xE0) >> 5); } - setchr8(regs[1]); - setmirror((regs[1] & 0x8) ? 0 : 1); + /* FIXME: 2020-10-26 */ + switch (regs[2] & 0xC0) { + case 0xC0: /* Pipe Dream */ + setchr8((regs[0] & 0x03) | (regs[1] & ~0x03)); + break; + case 0x40: /* Goonies */ + setchr8((regs[0] & 0x01) | (regs[1] & 0x07)); + break; + default: + setchr8(regs[1]); + break; + } + setmirror((regs[1] & 0x8) ? 0 : 1); } static DECLFW(AbG1lWriteHi) { regs[0] = V; - setchr8(((regs[2] & 0xC0) >> 7) << 2 | (regs[0] & 0x03)); + /* setchr8(((regs[2] & 0xC0) >> 7) << 2 | (regs[0] & 0x03)); */ Sync(); } From ed01e34323490f0f8987e3db9a0d0291dc8cf063 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 21 Oct 2020 05:41:51 +0800 Subject: [PATCH 055/295] Add unif multicarts - Add unif board BS400R - Add unif board BS4040R --- src/boards/bs4xxxr.c | 156 +++++++++++++++++++++++++++++++++++++++++++ src/unif.c | 3 + src/unif.h | 3 + 3 files changed, 162 insertions(+) create mode 100644 src/boards/bs4xxxr.c diff --git a/src/boards/bs4xxxr.c b/src/boards/bs4xxxr.c new file mode 100644 index 0000000..f10ef08 --- /dev/null +++ b/src/boards/bs4xxxr.c @@ -0,0 +1,156 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 + * + * 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 + */ + +/* originally submitted by dragon2snow + * Known carts: + * UNIF BMC-BS-400R : 700000-in-1 (BS-400R)(Unl), PRG 1024K CHR 1024K CRC 0x5DBDFAA0 + * UNIF BMC-BS-4040R : Double Dragon 310000-in-1 (4040R) PRG 512 CHR 512 CRC 0x3A642F31 + * + * FIXME: Future Kids notes + * Either something is wrong or missing because chr banks for the game is $E8 - EB + * but game uses $EC-EF here. These are chr banks for the next game and does not masked properly + * by mapper code. + * ~ c@2020 + */ + +#include "mapinc.h" +#include "mmc3.h" + +static uint8 pointer; +static uint8 offset; + +static int getPRGBankBS4XXXR(int bank) +{ + if (((~bank) & 1) && (pointer & 0x40)) bank ^= 2; + return ((bank & 2) ? 0xFE | (bank & 1) : DRegBuf[6 | (bank & 1)]); +} + +static void BS4XXXRPW(uint32 A, uint8 V) +{ + if ((EXPREGS[3] >> 4) & 1) { + uint8 prgAND = ((EXPREGS[0] >> 1) & 1) ? 0x0F : 0x0F; + uint8 prgOR = (EXPREGS[0] & 7) << 4; + uint8 bank0 = getPRGBankBS4XXXR(0); + uint8 bank1 = getPRGBankBS4XXXR(1); + /* 16K Mode */ + if (!((EXPREGS[3] >>1 )& 0x1)) { + setprg8(0x8000, (bank0 & prgAND) | prgOR); + setprg8(0xA000, (bank1 & prgAND) | prgOR); + setprg8(0xC000, (bank0 & prgAND) | prgOR); + setprg8(0xE000, (bank1 & prgAND) | prgOR); + } + /* 32K Mode */ + else { + setprg8(0x8000, (bank0 & prgAND) | prgOR); + setprg8(0xA000, (bank1 & prgAND) | prgOR); + setprg8(0xC000, ((bank0 | 2) & prgAND) | prgOR); + setprg8(0xE000, ((bank1 | 2) & prgAND) | prgOR); + } + } + /* Mmc3 Mode */ + else { + uint8 prgAND = ((EXPREGS[0] >> offset) & 1) ? 0x0F : 0x1F; /* 4040R 6,400R 1 */ + uint8 prgOR = (EXPREGS[0] & 7) << 4; + setprg8(A, (V & prgAND) | prgOR); + } +} + +static void BS4XXXRCW(uint32 A, uint8 V) { + if ((EXPREGS[3] >> 4) & 1) { + uint8 chrAND = ((EXPREGS[0] >> 1) & 1) ? 0x0F : 0x0F; + uint8 chrOR = ((EXPREGS[0] >> 3) & 7) << 4; + /* FIXME: Ugly hack for Future Kids */ + if (EXPREGS[4]) { + chrAND = 0x03; + chrOR |= 8; + } + setchr8((EXPREGS[2] & chrAND) | chrOR); + } else { + uint8 chrAND = ((EXPREGS[0] >> 1) & 1) ? 0xFF : 0xFF; + uint16 chrOR = ((EXPREGS[0] >> 3) & 7) << 7; + setchr1(A, (V & chrAND) | chrOR); + } +} + +static DECLFW(BS4XXXRHiWrite) { + /* FCEU_printf("Wr8B: A:%04x V:%02x\n", A, V); */ + if (A == 0x8000) + pointer = MMC3_cmd ^ V; + MMC3_CMDWrite(A, V); +} + +static DECLFW(BS4XXXRLoWrite) { + /* FCEU_printf("WrLo: A:%04x V:%02x\n", A, V); */ + if (A & 0x800) { + /* Future Kids hack */ + if (!EXPREGS[4]) { + if ((((A & 3) == 2) && (V == 0xE8))) + EXPREGS[4] = 1; + } + if (!(EXPREGS[3] & 0x80)) { + EXPREGS[A & 0x03] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } + else if (EXPREGS[3] & 0x10) { + EXPREGS[A & 0x03] = V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } + } +} + +static void BS4XXXRReset(void) { + EXPREGS[4] = 0; + EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; + MMC3RegReset(); +} + +static void BS4XXXRPower(void) { + EXPREGS[4] = 0; + EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; + GenMMC3Power(); + SetReadHandler(0x6000, 0x7FFF, CartBR); + SetWriteHandler(0x6000, 0x7FFF, BS4XXXRLoWrite); + SetWriteHandler(0x8000, 0xBFFF, BS4XXXRHiWrite); +} + +void BS4XXXR_Init(CartInfo *info) { + GenMMC3_Init(info, 512, 256, 8, 0); + cwrap = BS4XXXRCW; + pwrap = BS4XXXRPW; + + info->Power = BS4XXXRPower; + info->Reset = BS4XXXRReset; + + AddExState(EXPREGS, 4, 0, "EXPR"); + AddExState(&pointer, 1, 0, "PNTR"); + AddExState(&offset, 1, 0, "OFFS"); +} + +void BS400R_Init(CartInfo *info) { + offset = 1; + BS4XXXR_Init(info); +} + +void BS4040R_Init(CartInfo *info) { + offset = 6; + BS4XXXR_Init(info); +} diff --git a/src/unif.c b/src/unif.c index 88d2595..fd7a642 100644 --- a/src/unif.c +++ b/src/unif.c @@ -616,6 +616,9 @@ static BMAPPING bmap[] = { { "82112C", 540, Mapper540_Init, 0 }, { "N49C-300", 369, Mapper369_Init, 0 }, + { "BS-400R", NO_INES, BS400R_Init, 0 }, + { "BS-4040R", NO_INES, BS4040R_Init, 0 }, + #ifdef COPYFAMI { "COPYFAMI_MMC3", NO_INES, MapperCopyFamiMMC3_Init, 0 }, { "COPYFAMI", NO_INES, MapperCopyFami_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 07caff8..3b2cbe3 100644 --- a/src/unif.h +++ b/src/unif.h @@ -196,6 +196,9 @@ void AbG1l_Init(CartInfo *info); void KG256_Init(CartInfo *info); void WAIXINGFS005_Init(CartInfo *info); +void BS4040R_Init(CartInfo *info); +void BS400R_Init(CartInfo *info); + #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); void MapperCopyFami_Init(CartInfo *info); From 066899eaff345aa582f8d00bafcf15ec3b46904e Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Sat, 7 Nov 2020 13:06:56 -0800 Subject: [PATCH 056/295] Remove extraneous semicolons at top-level These are unnecessary and not strictly allowed in ISO C. --- src/boards/txcchip.c | 2 +- src/sound.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/boards/txcchip.c b/src/boards/txcchip.c index a361cc8..294cd39 100644 --- a/src/boards/txcchip.c +++ b/src/boards/txcchip.c @@ -65,7 +65,7 @@ typedef struct { static TXC txc; -static void Dummyfunc(void) { }; +static void Dummyfunc(void) { } static void (*WSync)(void) = Dummyfunc; static SFORMAT StateRegs[] = diff --git a/src/sound.c b/src/sound.c index 2fd2ca2..a483d16 100644 --- a/src/sound.c +++ b/src/sound.c @@ -145,7 +145,7 @@ static char DMCHaveDMA = 0; static uint8 DMCDMABuf = 0; static char DMCHaveSample = 0; -static void Dummyfunc(void) { }; +static void Dummyfunc(void) { } static void (*DoNoise)(void) = Dummyfunc; static void (*DoTriangle)(void) = Dummyfunc; static void (*DoPCM)(void) = Dummyfunc; From d8132fa88d520f4f249acaa718c4f62d5b5374ea Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Thu, 12 Nov 2020 02:44:58 +0800 Subject: [PATCH 057/295] Update bs4xxxr --- src/boards/bs4xxxr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boards/bs4xxxr.c b/src/boards/bs4xxxr.c index f10ef08..a844007 100644 --- a/src/boards/bs4xxxr.c +++ b/src/boards/bs4xxxr.c @@ -115,6 +115,7 @@ static DECLFW(BS4XXXRLoWrite) { FixMMC3CHR(MMC3_cmd); } } + CartBW(A, V); } static void BS4XXXRReset(void) { @@ -127,7 +128,6 @@ static void BS4XXXRPower(void) { EXPREGS[4] = 0; EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; GenMMC3Power(); - SetReadHandler(0x6000, 0x7FFF, CartBR); SetWriteHandler(0x6000, 0x7FFF, BS4XXXRLoWrite); SetWriteHandler(0x8000, 0xBFFF, BS4XXXRHiWrite); } From 14b689cde6dad0a2bff9a9668139b3796112e71f Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 16 Nov 2020 18:13:51 +0800 Subject: [PATCH 058/295] Add mapper 293 --- src/boards/293.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++ src/ines-correct.h | 3 ++ src/ines.c | 2 ++ src/ines.h | 1 + 4 files changed, 92 insertions(+) create mode 100644 src/boards/293.c diff --git a/src/boards/293.c b/src/boards/293.c new file mode 100644 index 0000000..7496388 --- /dev/null +++ b/src/boards/293.c @@ -0,0 +1,86 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 negativeExponent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * NewStar 12-in-1 and 76-in-1 + */ + +#include "mapinc.h" + +static uint8 regs[2]; +static SFORMAT StateRegs[] = +{ + { regs, 2, "REGS" }, + { 0 } +}; + +static void Sync(void) { + uint8 mode = ((regs[0] >> 2) & 2) | ((regs[1] >> 6) & 1); + uint8 bank = ((regs[1] << 5) & 0x20) | ((regs[1] >> 1) & 0x18); + uint8 block = (regs[0] & 7); + switch (mode) { + case 0: /* UNROM */ + setprg16(0x8000, bank | block); + setprg16(0xC000, bank | 7); + break; + case 1: + setprg16(0x8000, bank | block & 0xFE); + setprg16(0xC000, bank | 7); + break; + case 2: /* NROM-128 */ + setprg16(0x8000, bank | block); + setprg16(0xC000, bank | block); + break; + case 3: /* NROM-256 */ + setprg32(0x8000, (bank | block) >> 1); + break; + } + setchr8(0); + setmirror(((regs[1] >> 7) & 1) ^ 1); +} + +static DECLFW(M293Write1) { + if (A < 0xA000) regs[0] = V; + regs[1] = V; + Sync(); +} + +static DECLFW(M293Write2) { + if (A < 0xA000) regs[1] = V; + regs[0] = V; + Sync(); +} + +static void M293Power(void) { + regs[0] = regs[1] = 0; + Sync(); + SetReadHandler(0x8000, 0xFFFF, CartBR); + SetWriteHandler(0x8000, 0xBFFF, M293Write1); + SetWriteHandler(0xC000, 0xDFFF, M293Write2); +} + +static void StateRestore(int version) { + Sync(); +} + +/* BMC 12-in-1/76-in-1 (NewStar) (Unl) */ +void Mapper293_Init(CartInfo *info) { + info->Power = M293Power; + GameStateRestore = StateRestore; + AddExState(&StateRegs, ~0, 0, 0); +} diff --git a/src/ines-correct.h b/src/ines-correct.h index 7410d1a..870b2b8 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -657,7 +657,10 @@ /* ines mappers that uses iNes 2.0 numbers */ + /* CRC32, mapperNum, SubMapper, Mirroring, hasBattery, prgRam, chrRam, region, extra flags */ { 0xf6bd8e31, 281, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 1997 Super HIK 4-in-1 (JY-052) [p1][!].nes */ + /* dumps are assigned 281, but its 293 on nesdev */ + { 0x06256C80, 293, DEFAULT, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Super 12-in-1 NewStar (UNL) */ { 0x5aa23a15, 361, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (OK-411)[p1][!].nes */ { 0xf6b9d088, 366, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (K-3131GS, GN-45) [p1][!].nes */ { 0x503566b2, 366, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (K-3131SS, GN-45) [p1][!].nes */ diff --git a/src/ines.c b/src/ines.c index 93c3761..b81fafc 100644 --- a/src/ines.c +++ b/src/ines.c @@ -328,6 +328,7 @@ static void CheckHInfo(void) { case 1: case 5: case 176: + case 293: if (moo[x].prgram >= 0) { tofix |= 32; iNESCart.iNES2 = 1; @@ -702,6 +703,7 @@ INES_BOARD_BEGIN() INES_BOARD( "830928C", 382, Mapper382_Init ) INES_BOARD( "Caltron 9-in-1", 389, Mapper389_Init ) INES_BOARD( "Realtec 8031", 390, Mapper390_Init ) + INES_BOARD( "NewStar 12-in-1/7-in-1", 293, Mapper293_Init ) INES_BOARD( "Realtec 8210", 395, Mapper395_Init ) INES_BOARD( "A88S-1", 411, Mapper411_Init ) INES_BOARD( "Brilliant Com Cocoma Pack", 516, Mapper516_Init ) diff --git a/src/ines.h b/src/ines.h index 43085e4..4b2e6e5 100644 --- a/src/ines.h +++ b/src/ines.h @@ -252,6 +252,7 @@ void J2282_Init(CartInfo *); void Mapper267_Init(CartInfo *); void Mapper269_Init(CartInfo *); void Mapper288_Init(CartInfo *); +void Mapper293_Init(CartInfo *); void Mapper297_Init(CartInfo *); void Mapper353_Init(CartInfo *); void Mapper356_Init(CartInfo *); From 0cc55ba1f16a160188e5c5869fae36ce7ccb37e6 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 17 Nov 2020 00:18:31 +0800 Subject: [PATCH 059/295] m293: Fix alignment and update --- src/boards/293.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/boards/293.c b/src/boards/293.c index 7496388..f70d504 100644 --- a/src/boards/293.c +++ b/src/boards/293.c @@ -34,44 +34,49 @@ static void Sync(void) { uint8 bank = ((regs[1] << 5) & 0x20) | ((regs[1] >> 1) & 0x18); uint8 block = (regs[0] & 7); switch (mode) { - case 0: /* UNROM */ - setprg16(0x8000, bank | block); - setprg16(0xC000, bank | 7); + case 0: /* UNROM */ + setprg16(0x8000, bank | block); + setprg16(0xC000, bank | 7); break; case 1: setprg16(0x8000, bank | block & 0xFE); setprg16(0xC000, bank | 7); break; - case 2: /* NROM-128 */ + case 2: /* NROM-128 */ setprg16(0x8000, bank | block); - setprg16(0xC000, bank | block); + setprg16(0xC000, bank | block); break; - case 3: /* NROM-256 */ + case 3: /* NROM-256 */ setprg32(0x8000, (bank | block) >> 1); - break; - } - setchr8(0); - setmirror(((regs[1] >> 7) & 1) ^ 1); + break; + } + setchr8(0); + setmirror(((regs[1] >> 7) & 1) ^ 1); } static DECLFW(M293Write1) { - if (A < 0xA000) regs[0] = V; + regs[0] = V; regs[1] = V; - Sync(); + Sync(); } static DECLFW(M293Write2) { - if (A < 0xA000) regs[1] = V; + regs[1] = V; + Sync(); +} + +static DECLFW(M293Write3) { regs[0] = V; - Sync(); + Sync(); } static void M293Power(void) { regs[0] = regs[1] = 0; Sync(); SetReadHandler(0x8000, 0xFFFF, CartBR); - SetWriteHandler(0x8000, 0xBFFF, M293Write1); - SetWriteHandler(0xC000, 0xDFFF, M293Write2); + SetWriteHandler(0x8000, 0x9FFF, M293Write1); + SetWriteHandler(0xA000, 0xBFFF, M293Write2); + SetWriteHandler(0xC000, 0xDFFF, M293Write3); } static void StateRestore(int version) { From faa58abe0f384712b305ed05ca93420d5d73e482 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 17 Nov 2020 03:29:24 +0800 Subject: [PATCH 060/295] Add mapper 401 --- src/boards/401.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++ src/ines-correct.h | 1 + src/ines.c | 1 + src/ines.h | 1 + 4 files changed, 99 insertions(+) create mode 100644 src/boards/401.c diff --git a/src/boards/401.c b/src/boards/401.c new file mode 100644 index 0000000..98c459b --- /dev/null +++ b/src/boards/401.c @@ -0,0 +1,96 @@ +/* FCEUmm - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 negativeExponent + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * NES 2.0 - Mapper 401 (reference from NewRisingSun) + * Super 19-in-1 (VIP19) (crc 0x2F497313) + * + */ + +#include "mapinc.h" +#include "mmc3.h" + +static uint8 dipswitch = 0; + +static void M401CW(uint32 A, uint8 V) { + uint32 mask = (0xFF >> (~EXPREGS[2] &0xF)); + uint32 bank = (EXPREGS[0] | ((EXPREGS[2] << 4) &0xF00)); + setchr1(A, (V & mask) | bank); +} + +static void M401PW(uint32 A, uint8 V) { + if ((dipswitch & 1) && (EXPREGS[1] &0x80)) { + /* openbus */ + } else { + uint32 mask = (~EXPREGS[3] & 0x1F); + uint32 bank = (EXPREGS[1] & 0x1F) | (EXPREGS[2] & 0x80) | + ((dipswitch & 2) ? (EXPREGS[2] & 0x20) : ((EXPREGS[1] >> 1) & 0x20)) | + ((dipswitch & 4) ? (EXPREGS[2] & 0x40) : ((EXPREGS[1] << 1) & 0x40)); + setprg8(A, (V & mask) | bank); + } +} + +static DECLFR(M401Read) { + if ((dipswitch & 1) && (EXPREGS[1] & 0x80)) + return X.DB; + return CartBR(A); +} + +static DECLFW(M401Write) { + /* FCEU_printf("Wr A:%04x V:%02x index:%d\n", A, V, EXPREGS[4]); */ + if (!(EXPREGS[3] & 0x40)) { + EXPREGS[EXPREGS[4]] = V; + EXPREGS[4] = (EXPREGS[4] + 1) & 3; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } + CartBW(A, V); +} + +static void M401Reset(void) { + dipswitch = (dipswitch + 1) & 7; + FCEU_printf("dipswitch = %d\n", dipswitch); + EXPREGS[0] = 0x00; + EXPREGS[1] = 0x00; + EXPREGS[2] = 0x0F; + EXPREGS[3] = 0x00; + EXPREGS[4] = 0x00; + MMC3RegReset(); +} + +static void M401Power(void) { + dipswitch = 7; + EXPREGS[0] = 0x00; + EXPREGS[1] = 0x00; + EXPREGS[2] = 0x0F; + EXPREGS[3] = 0x00; + EXPREGS[4] = 0x00; + GenMMC3Power(); + SetReadHandler(0x8000, 0xFFFF, M401Read); + SetWriteHandler(0x6000, 0x7FFF, M401Write); +} + +void Mapper401_Init(CartInfo *info) { + GenMMC3_Init(info, 256, 256, 8, 0); + cwrap = M401CW; + pwrap = M401PW; + info->Power = M401Power; + info->Reset = M401Reset; + AddExState(EXPREGS, 5, 0, "EXPR"); + AddExState(dipswitch, 1, 0, "DPSW"); +} diff --git a/src/ines-correct.h b/src/ines-correct.h index 870b2b8..4c4185d 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -667,6 +667,7 @@ { 0xdb2d2d88, 369, DEFAULT, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* Super Mario Bros. Party.nes */ { 0x87f83ea2, 380, DEFAULT, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* 42 to 80,000 */ { 0xc4b94bd5, 389, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Caltron - 9 in 1 (USA) (Proto) (Unl).nes */ + { 0x2F497313, 401, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 19-in-1 (VIP19) */ /* ines mappers that uses unif boards */ diff --git a/src/ines.c b/src/ines.c index b81fafc..892aea6 100644 --- a/src/ines.c +++ b/src/ines.c @@ -705,6 +705,7 @@ INES_BOARD_BEGIN() INES_BOARD( "Realtec 8031", 390, Mapper390_Init ) INES_BOARD( "NewStar 12-in-1/7-in-1", 293, Mapper293_Init ) INES_BOARD( "Realtec 8210", 395, Mapper395_Init ) + INES_BOARD( "BMC Super 19-in-1 (VIP19)", 401, Mapper401_Init ) INES_BOARD( "A88S-1", 411, Mapper411_Init ) INES_BOARD( "Brilliant Com Cocoma Pack", 516, Mapper516_Init ) INES_BOARD( "Sachen 3014", 533, Mapper533_Init ) diff --git a/src/ines.h b/src/ines.h index 4b2e6e5..b1ce41c 100644 --- a/src/ines.h +++ b/src/ines.h @@ -269,6 +269,7 @@ void Mapper382_Init(CartInfo *); void Mapper389_Init(CartInfo *); void Mapper390_Init(CartInfo *); void Mapper395_Init(CartInfo *); +void Mapper401_Init(CartInfo *); void Mapper411_Init(CartInfo *); void Mapper516_Init(CartInfo *); void Mapper533_Init(CartInfo *); From d98245e49cde64b4d5193527da9f595864725777 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 17 Nov 2020 06:40:10 +0800 Subject: [PATCH 061/295] Misc update --- src/boards/401.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/boards/401.c b/src/boards/401.c index 98c459b..067849b 100644 --- a/src/boards/401.c +++ b/src/boards/401.c @@ -28,13 +28,13 @@ static uint8 dipswitch = 0; static void M401CW(uint32 A, uint8 V) { - uint32 mask = (0xFF >> (~EXPREGS[2] &0xF)); - uint32 bank = (EXPREGS[0] | ((EXPREGS[2] << 4) &0xF00)); + uint32 mask = (0xFF >> (~EXPREGS[2] & 0xF)); + uint32 bank = (EXPREGS[0] | ((EXPREGS[2] << 4) & 0xF00)); setchr1(A, (V & mask) | bank); } static void M401PW(uint32 A, uint8 V) { - if ((dipswitch & 1) && (EXPREGS[1] &0x80)) { + if ((dipswitch & 1) && (EXPREGS[1] & 0x80)) { /* openbus */ } else { uint32 mask = (~EXPREGS[3] & 0x1F); From 565391c2133ed795ffb8a595db70b33b13f195b9 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 17 Nov 2020 06:46:41 +0800 Subject: [PATCH 062/295] Directly apply NES 2.0 overrides when available --- src/ines.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/ines.c b/src/ines.c index 892aea6..e946c91 100644 --- a/src/ines.c +++ b/src/ines.c @@ -323,28 +323,21 @@ static void CheckHInfo(void) { iNESCart.region = moo[x].region; } } - switch (moo[x].mapper) { - /* TODO: Eventually, all items from overrides should be considered as ines 2.0 compatible */ - case 1: - case 5: - case 176: - case 293: - if (moo[x].prgram >= 0) { - tofix |= 32; - iNESCart.iNES2 = 1; - iNESCart.PRGRamSize = (moo[x].prgram & 0x0F) ? (64 << ((moo[x].prgram >> 0) & 0xF)) : 0; - iNESCart.PRGRamSaveSize = (moo[x].prgram & 0xF0) ? (64 << ((moo[x].prgram >> 4) & 0xF)) : 0; - } - if (moo[x].chrram >= 0) { - tofix |= 32; - iNESCart.iNES2 = 1; - iNESCart.CHRRamSize = (moo[x].chrram & 0x0F) ? (64 << ((moo[x].chrram >> 0) & 0xF)) : 0; - iNESCart.CHRRamSaveSize = (moo[x].chrram & 0xF0) ? (64 << ((moo[x].chrram >> 4) & 0xF)) : 0; - } - break; - default: - break; + + if (moo[x].prgram >= 0) { + tofix |= 32; + iNESCart.iNES2 = 1; + iNESCart.PRGRamSize = (moo[x].prgram & 0x0F) ? (64 << ((moo[x].prgram >> 0) & 0xF)) : 0; + iNESCart.PRGRamSaveSize = (moo[x].prgram & 0xF0) ? (64 << ((moo[x].prgram >> 4) & 0xF)) : 0; } + + if (moo[x].chrram >= 0) { + tofix |= 32; + iNESCart.iNES2 = 1; + iNESCart.CHRRamSize = (moo[x].chrram & 0x0F) ? (64 << ((moo[x].chrram >> 0) & 0xF)) : 0; + iNESCart.CHRRamSaveSize = (moo[x].chrram & 0xF0) ? (64 << ((moo[x].chrram >> 4) & 0xF)) : 0; + } + break; } x++; From 8deefc3beffb9395438850ec3d9a262229201def Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 17 Nov 2020 06:47:45 +0800 Subject: [PATCH 063/295] Fix warning --- src/boards/401.c | 2 +- src/ines.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/boards/401.c b/src/boards/401.c index 067849b..75cb508 100644 --- a/src/boards/401.c +++ b/src/boards/401.c @@ -92,5 +92,5 @@ void Mapper401_Init(CartInfo *info) { info->Power = M401Power; info->Reset = M401Reset; AddExState(EXPREGS, 5, 0, "EXPR"); - AddExState(dipswitch, 1, 0, "DPSW"); + AddExState(&dipswitch, 1, 0, "DPSW"); } diff --git a/src/ines.c b/src/ines.c index e946c91..9c23c7e 100644 --- a/src/ines.c +++ b/src/ines.c @@ -386,7 +386,6 @@ static void CheckHInfo(void) { } } strcat(gigastr, "\n"); - FCEU_printf("\n", gigastr); FCEU_printf("%s\n", gigastr); } From 70952034f89aec52e9b29d441842e730c73dc1e2 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 27 Nov 2020 10:41:45 +0000 Subject: [PATCH 064/295] Add OpenDingux target to .gitlab-ci.yml --- .gitlab-ci.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 014629e..7ddc8f1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,6 +17,8 @@ include: file: '/linux-x64.yml' - project: 'libretro-infrastructure/ci-templates' file: '/windows-x64-mingw.yml' + - project: 'libretro-infrastructure/ci-templates' + file: '/dingux-i386.yml' - project: 'libretro-infrastructure/ci-templates' file: '/android-jni.yml' @@ -40,7 +42,14 @@ libretro-build-windows-x64: - .libretro-windows-x64-mingw-make-default variables: MAKEFILE: Makefile.libretro - + +libretro-build-dingux-i386: + extends: + - .core-defs + - .libretro-dingux-i386-make-default + variables: + MAKEFILE: Makefile.libretro + # Android android-armeabi-v7a: extends: From f4cf5dbfc92486884d71072d43c3708690ca9c75 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 6 Dec 2020 19:40:54 +0100 Subject: [PATCH 065/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 177 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 122 insertions(+), 55 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7ddc8f1..7cda1fc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,101 +1,168 @@ +# DESCRIPTION: GitLab CI/CD for libRetro (NOT FOR GitLab-proper) + +############################################################################## +################################# BOILERPLATE ################################ +############################################################################## + +# Core definitions .core-defs: variables: JNI_PATH: . CORENAME: fceumm + MAKEFILE: Makefile.libretro +# Inclusion templates, required for the build to work include: - - template: Jobs/Code-Quality.gitlab-ci.yml - - project: 'libretro-infrastructure/ci-templates' - file: '/libnx-static.yml' - - project: 'libretro-infrastructure/ci-templates' - file: '/vita-static.yml' - - project: 'libretro-infrastructure/ci-templates' - file: '/psp-static.yml' - - project: 'libretro-infrastructure/ci-templates' - file: '/ps2-static.yml' - - project: 'libretro-infrastructure/ci-templates' - file: '/linux-x64.yml' + ################################## DESKTOPS ################################ + # Windows 64-bit - project: 'libretro-infrastructure/ci-templates' file: '/windows-x64-mingw.yml' + + # Linux 64-bit - project: 'libretro-infrastructure/ci-templates' - file: '/dingux-i386.yml' + file: '/linux-x64.yml' + + # MacOS 64-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/osx-x64.yml' + + ################################## CELLULAR ################################ + # Android - project: 'libretro-infrastructure/ci-templates' file: '/android-jni.yml' + ################################## CONSOLES ################################ + # PlayStation Portable + - project: 'libretro-infrastructure/ci-templates' + file: '/psp-static.yml' + + # PlayStation Vita + - project: 'libretro-infrastructure/ci-templates' + file: '/vita-static.yml' + + # PlayStation2 + - project: 'libretro-infrastructure/ci-templates' + file: '/ps2-static.yml' + + # Nintendo 3DS + - project: 'libretro-infrastructure/ci-templates' + file: '/ctr-static.yml' + + # Nintendo GameCube + - project: 'libretro-infrastructure/ci-templates' + file: '/ngc-static.yml' + + # Nintendo Wii + - project: 'libretro-infrastructure/ci-templates' + file: '/wii-static.yml' + + # Nintendo Switch + - project: 'libretro-infrastructure/ci-templates' + file: '/libnx-static.yml' + + # OpenDingux + - project: 'libretro-infrastructure/ci-templates' + file: '/dingux-mips32.yml' + +# Stages for building stages: - build-prepare - build-shared - build-static - - test - -#Desktop -libretro-build-linux-x64: - extends: - - .core-defs - - .libretro-linux-x64-make-default - variables: - MAKEFILE: Makefile.libretro +############################################################################## +#################################### STAGES ################################## +############################################################################## +# +################################### DESKTOPS ################################# +# Windows 64-bit libretro-build-windows-x64: extends: - - .core-defs - .libretro-windows-x64-mingw-make-default - variables: - MAKEFILE: Makefile.libretro - -libretro-build-dingux-i386: - extends: - .core-defs - - .libretro-dingux-i386-make-default - variables: - MAKEFILE: Makefile.libretro -# Android +# Linux 64-bit +libretro-build-linux-x64: + extends: + - .libretro-linux-x64-make-default + - .core-defs + +# MacOS 64-bit +libretro-build-osx-x64: + extends: + - .libretro-osx-x64-make-default + - .core-defs + +################################### CELLULAR ################################# +# Android ARMv7a android-armeabi-v7a: extends: - - .core-defs - .libretro-android-jni-armeabi-v7a + - .core-defs +# Android ARMv8a android-arm64-v8a: extends: - - .core-defs - .libretro-android-jni-arm64-v8a + - .core-defs +# Android 64-bit x86 android-x86_64: extends: - - .core-defs - .libretro-android-jni-x86_64 + - .core-defs +# Android 32-bit x86 android-x86: extends: - - .core-defs - .libretro-android-jni-x86 - -# Static -libretro-build-libnx-aarch64: - extends: - .core-defs - - .libretro-libnx-static-retroarch-master - variables: - MAKEFILE: Makefile.libretro - -libretro-build-vita: - extends: - - .core-defs - - .libretro-vita-static-retroarch-master - variables: - MAKEFILE: Makefile.libretro +################################### CONSOLES ################################# +# PlayStation Portable libretro-build-psp: extends: - - .core-defs - .libretro-psp-static-retroarch-master - variables: - MAKEFILE: Makefile.libretro + - .core-defs +# PlayStation Vita +libretro-build-vita: + extends: + - .libretro-vita-static-retroarch-master + - .core-defs + +# PlayStation2 libretro-build-ps2: extends: - - .core-defs - .libretro-ps2-static-retroarch-master - variables: - MAKEFILE: Makefile.libretro + - .core-defs + +# Nintendo 3DS +libretro-build-ctr: + extends: + - .libretro-ctr-static-retroarch-master + - .core-defs + +# Nintendo GameCube +libretro-build-ngc: + extends: + - .libretro-ngc-static-retroarch-master + - .core-defs + +# Nintendo Wii +libretro-build-wii: + extends: + - .libretro-wii-static-retroarch-master + - .core-defs + +# Nintendo Switch +libretro-build-libnx-aarch64: + extends: + - .libretro-libnx-static-retroarch-master + - .core-defs + +# OpenDingux +libretro-build-dingux-mips32: + extends: + - .libretro-dingux-mips32-make-default + - .core-defs From 1a0eec1b17d66aeb973a8b6d456f9046ed3008e2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 20 Dec 2020 03:46:42 +0100 Subject: [PATCH 066/295] Update --- Makefile.libretro | 22 +------------------ .../libretro-common/include/libretro.h | 2 +- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index 509515e..3ecbbd3 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -147,26 +147,6 @@ else ifeq ($(platform), qnx) AR = qcc -Vgcc_ntoarmv7le PLATFORM_DEFINES := -D__BLACKBERRY_QNX__ -marm -mcpu=cortex-a9 -mfpu=neon -mfloat-abi=softfp -# PS3 -else ifeq ($(platform), ps3) - TARGET := $(TARGET_NAME)_libretro_$(platform).a - CC = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-gcc.exe - AR = $(CELL_SDK)/host-win32/ppu/bin/ppu-lv2-ar.exe - PLATFORM_DEFINES := -D__CELLOS_LV2 - ENDIANNESS_DEFINES += -DMSB_FIRST - STATIC_LINKING=1 - EXTERNAL_ZLIB=1 - -# sncps3 -else ifeq ($(platform), sncps3) - TARGET := $(TARGET_NAME)_libretro_ps3.a - CC = $(CELL_SDK)/host-win32/sn/bin/ps3ppusnc.exe - AR = $(CELL_SDK)/host-win32/sn/bin/ps3snarl.exe - PLATFORM_DEFINES := -D__CELLOS_LV2 - ENDIANNESS_DEFINES += -DMSB_FIRST - STATIC_LINKING=1 - EXTERNAL_ZLIB=1 - # PS2 else ifeq ($(platform), ps2) TARGET := $(TARGET_NAME)_libretro_$(platform).a @@ -247,7 +227,7 @@ else ifeq ($(platform), psl1ght) TARGET := $(TARGET_NAME)_libretro_$(platform).a CC = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT) AR = $(PS3DEV)/ppu/bin/ppu-ar$(EXE_EXT) - PLATFORM_DEFINES := -D__CELLOS_LV2 + PLATFORM_DEFINES := -D__PSL1GHT__ ENDIANNESS_DEFINES += -DMSB_FIRST STATIC_LINKING=1 EXTERNAL_ZLIB=1 diff --git a/src/drivers/libretro/libretro-common/include/libretro.h b/src/drivers/libretro/libretro-common/include/libretro.h index 59bd513..d843114 100644 --- a/src/drivers/libretro/libretro-common/include/libretro.h +++ b/src/drivers/libretro/libretro-common/include/libretro.h @@ -69,7 +69,7 @@ extern "C" { # endif # endif # else -# if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__CELLOS_LV2__) +# if defined(__GNUC__) && __GNUC__ >= 4 # define RETRO_API RETRO_CALLCONV __attribute__((__visibility__("default"))) # else # define RETRO_API RETRO_CALLCONV From 2e408ab958551014c615ec0d64445fbe20626778 Mon Sep 17 00:00:00 2001 From: Autechre Date: Mon, 28 Dec 2020 23:22:20 +0100 Subject: [PATCH 067/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7cda1fc..422a21e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -56,6 +56,10 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/wii-static.yml' + # Nintendo WiiU + - project: 'libretro-infrastructure/ci-templates' + file: '/wiiu-static.yml' + # Nintendo Switch - project: 'libretro-infrastructure/ci-templates' file: '/libnx-static.yml' @@ -155,6 +159,12 @@ libretro-build-wii: - .libretro-wii-static-retroarch-master - .core-defs +# Nintendo WiiU +libretro-build-wiiu: + extends: + - .libretro-wiiu-static-retroarch-master + - .core-defs + # Nintendo Switch libretro-build-libnx-aarch64: extends: From 5fc31e82be9ab565c33571b1155a9ce3c222eb63 Mon Sep 17 00:00:00 2001 From: Dwedit Date: Wed, 30 Dec 2020 15:33:27 -0500 Subject: [PATCH 068/295] Fixed a bug that caused extended save state information to be truncated early. --- src/fceu-types.h | 2 +- src/ines.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/fceu-types.h b/src/fceu-types.h index dda3a8e..cc8f7c5 100644 --- a/src/fceu-types.h +++ b/src/fceu-types.h @@ -39,7 +39,7 @@ typedef uint32_t uint32; typedef unsigned long long uint64; typedef long long int64; #define GINLINE inline -#elif MSVC +#elif MSVC | _MSC_VER typedef __int64 int64; typedef unsigned __int64 uint64; #define GINLINE /* Can't declare a function INLINE diff --git a/src/ines.c b/src/ines.c index 9bb3ef7..715d808 100644 --- a/src/ines.c +++ b/src/ines.c @@ -844,7 +844,12 @@ static int iNES_Init(int num) { AddExState(VROM, CHRRAMSize, 0, "CHRR"); } if (head.ROM_type & 8) - AddExState(ExtraNTARAM, 2048, 0, "EXNR"); + { + if (ExtraNTARAM != NULL) + { + AddExState(ExtraNTARAM, 2048, 0, "EXNR"); + } + } tmp->init(&iNESCart); return 1; } From d87f7e5b341d284fbe2ad623b0766dc357d7574a Mon Sep 17 00:00:00 2001 From: Dwedit Date: Wed, 30 Dec 2020 15:50:22 -0500 Subject: [PATCH 069/295] Prevent adding NULL terminator to save state extra list --- src/state.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/state.c b/src/state.c index 35f7d6a..9c452ae 100644 --- a/src/state.c +++ b/src/state.c @@ -324,6 +324,8 @@ void ResetExState(void (*PreSave)(void), void (*PostSave)(void)) void AddExState(void *v, uint32 s, int type, char *desc) { + /* prevent adding a terminator to the list if a NULL pointer was provided */ + if (v == NULL) return; memset(SFMDATA[SFEXINDEX].desc, 0, sizeof(SFMDATA[SFEXINDEX].desc)); if (desc) strncpy(SFMDATA[SFEXINDEX].desc, desc, sizeof(SFMDATA[SFEXINDEX].desc)); From d3543238b79568ec8f00bde724bd4f1cee208522 Mon Sep 17 00:00:00 2001 From: Autechre Date: Sat, 2 Jan 2021 00:11:04 +0100 Subject: [PATCH 070/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 422a21e..3264c16 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,6 +17,10 @@ include: # Windows 64-bit - project: 'libretro-infrastructure/ci-templates' file: '/windows-x64-mingw.yml' + + # Windows 32-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/windows-i686-mingw.yml' # Linux 64-bit - project: 'libretro-infrastructure/ci-templates' @@ -84,6 +88,12 @@ libretro-build-windows-x64: extends: - .libretro-windows-x64-mingw-make-default - .core-defs + +# Windows 32-bit +libretro-build-windows-i686: + extends: + - .libretro-windows-i686-mingw-make-default + - .core-defs # Linux 64-bit libretro-build-linux-x64: From 7649a24ca28bb22e732594402680877657c09246 Mon Sep 17 00:00:00 2001 From: Autechre Date: Thu, 7 Jan 2021 22:50:28 +0100 Subject: [PATCH 071/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3264c16..0f99378 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,6 +26,10 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/linux-x64.yml' + # Linux 32-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/linux-i686.yml' + # MacOS 64-bit - project: 'libretro-infrastructure/ci-templates' file: '/osx-x64.yml' @@ -35,6 +39,10 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/android-jni.yml' + # iOS 9 + - project: 'libretro-infrastructure/ci-templates' + file: '/ios9.yml' + ################################## CONSOLES ################################ # PlayStation Portable - project: 'libretro-infrastructure/ci-templates' @@ -72,6 +80,11 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/dingux-mips32.yml' + #################################### MISC ################################## + # Emscripten + - project: 'libretro-infrastructure/ci-templates' + file: '/emscripten-static.yml' + # Stages for building stages: - build-prepare @@ -101,6 +114,12 @@ libretro-build-linux-x64: - .libretro-linux-x64-make-default - .core-defs +# Linux 32-bit +libretro-build-linux-i686: + extends: + - .libretro-linux-i686-make-default + - .core-defs + # MacOS 64-bit libretro-build-osx-x64: extends: @@ -132,6 +151,12 @@ android-x86: - .libretro-android-jni-x86 - .core-defs +# iOS 9 +libretro-build-ios-9: + extends: + - .libretro-ios9-make-default + - .core-defs + ################################### CONSOLES ################################# # PlayStation Portable libretro-build-psp: @@ -186,3 +211,10 @@ libretro-build-dingux-mips32: extends: - .libretro-dingux-mips32-make-default - .core-defs + +#################################### MISC ################################## +# Emscripten +libretro-build-emscripten: + extends: + - .libretro-emscripten-static-retroarch-master + - .core-defs From 6501adf6ed2781b31374cc88a08e632199c7617c Mon Sep 17 00:00:00 2001 From: liberodark Date: Wed, 13 Jan 2021 16:33:56 +0100 Subject: [PATCH 072/295] Add RPI3 + RPI4 and fix aarch64 --- Makefile.libretro | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index 3ecbbd3..2ec6b79 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -221,6 +221,23 @@ else ifeq ($(platform), rpi2) CFLAGS += -DARM CFLAGS += -marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard -funsafe-math-optimizations CFLAGS += -fomit-frame-pointer -fstrict-aliasing -ffast-math + +# Raspberry Pi 3 +else ifeq ($(platform), rpi3) + TARGET := $(TARGET_NAME)_libretro.so + fpic := -fPIC + SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined + CFLAGS += -DARM + CFLAGS += -marm -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -funsafe-math-optimizations + CFLAGS += -fomit-frame-pointer -fstrict-aliasing -ffast-math + +# Raspberry Pi 4 (64-bit) +else ifeq ($(platform), rpi4) + TARGET := $(TARGET_NAME)_libretro.so + fpic := -fPIC + SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined + CFLAGS += -mcpu=cortex-a72 -mtune=cortex-a72 -funsafe-math-optimizations + CFLAGS += -fomit-frame-pointer -fstrict-aliasing -ffast-math # Lightweight PS3 Homebrew SDK else ifeq ($(platform), psl1ght) @@ -357,8 +374,8 @@ else ifeq ($(platform), classic_armv8_a35) ARCH = arm BUILTIN_GPU = neon USE_DYNAREC = 1 - CFLAGS += -march=armv8-a - LDFLAGS += -static-libgcc -static-libstdc++ + LDFLAGS += -lrt + LDFLAGS += -marm -mcpu=cortex-a35 -mfpu=neon-fp-armv8 -mfloat-abi=hard -Ofast -flto -fuse-linker-plugin ####################################### # ARM From 8b55ffc5339b5c042c74915bf195996e9580d953 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Sun, 12 Apr 2020 17:43:09 +0200 Subject: [PATCH 073/295] make it to compile --- Makefile.libretro | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index 2ec6b79..d653c60 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -150,8 +150,8 @@ else ifeq ($(platform), qnx) # PS2 else ifeq ($(platform), ps2) TARGET := $(TARGET_NAME)_libretro_$(platform).a - CC = ee-gcc$(EXE_EXT) - AR = ee-ar$(EXE_EXT) + CC = mips64r5900el-ps2-elf-gcc$(EXE_EXT) + AR = mips64r5900el-ps2-elf-ar$(EXE_EXT) FCEU_DEFINES := -DPATH_MAX=1024 -DINLINE=inline -DPSS_STYLE=1 -DFCEU_VERSION_NUMERIC=9813 -DHAVE_ASPRINTF ENDIANNESS_DEFINES := -DLSB_FIRST -DLOCAL_LE=1 PLATFORM_DEFINES := -DPS2 -D_EE -G0 -DFRONTEND_SUPPORTS_ABGR1555 -DRENDER_GSKIT_PS2 @@ -790,10 +790,10 @@ endif %.o: %.c $(CC) -c $(OBJOUT)$@ $< $(CFLAGS) $(INCFLAGS) -ifeq ($(platform), ps2) -%.o: %.s - ee-as -G0 $< -o $@ -endif +# ifeq ($(platform), ps2) +# %.o: %.s +# mips64r5900el-ps2-elf-as -G0 $< -o $@ +# endif clean-objs: rm -f $(OBJECTS) From c85ab0580054abe211029e95e4272a2233b510b8 Mon Sep 17 00:00:00 2001 From: Francisco Javier Trujillo Mata Date: Mon, 21 Dec 2020 21:58:23 +0100 Subject: [PATCH 074/295] Fix wrong aligment in the buffer --- Makefile.libretro | 5 ----- src/drivers/libretro/libretro.c | 8 ++++++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index d653c60..db37a02 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -790,11 +790,6 @@ endif %.o: %.c $(CC) -c $(OBJOUT)$@ $< $(CFLAGS) $(INCFLAGS) -# ifeq ($(platform), ps2) -# %.o: %.s -# mips64r5900el-ps2-elf-as -G0 $< -o $@ -# endif - clean-objs: rm -f $(OBJECTS) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 43536b6..3bac67f 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -28,6 +28,10 @@ #include "../../vsuni.h" #include "../../video.h" +#ifdef PSP +#include "pspgu.h" +#endif + #if defined(RENDER_GSKIT_PS2) #include "libretro-common/include/libretro_gskit_ps2.h" #endif @@ -159,8 +163,8 @@ static unsigned opt_showAdvSoundOptions = 0; static unsigned opt_showAdvSystemOptions = 0; int FCEUnetplay; -#ifdef PSP -#include "pspgu.h" + +#if defined(PSP) || defined(PS2) static __attribute__((aligned(16))) uint16_t retro_palette[256]; #else static uint16_t retro_palette[256]; From d14e4155f920254cf9bf94315aadf7b6c1d83660 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 15 Jan 2021 19:17:25 +0100 Subject: [PATCH 075/295] Add Apple ARM64 rules --- .gitlab-ci.yml | 11 +++++++++++ Makefile.libretro | 15 +++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0f99378..d1f3f80 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,6 +34,11 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/osx-x64.yml' + # MacOS ARM 64-bit + - project: 'libretro-infrastructure/ci-templates' + ref: 'macosx-arm64' + file: '/osx-arm64.yml' + ################################## CELLULAR ################################ # Android - project: 'libretro-infrastructure/ci-templates' @@ -126,6 +131,12 @@ libretro-build-osx-x64: - .libretro-osx-x64-make-default - .core-defs +# MacOS ARM 64-bit +libretro-build-osx-arm64: + extends: + - .libretro-osx-arm64-make-default + - .core-defs + ################################### CELLULAR ################################# # Android ARMv7a android-armeabi-v7a: diff --git a/Makefile.libretro b/Makefile.libretro index db37a02..9d9d6f7 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -41,10 +41,15 @@ ifeq ($(shell uname -a),) system_platform = win else ifneq ($(findstring Darwin,$(shell uname -a)),) system_platform = osx - arch = intel - ifeq ($(shell uname -p),powerpc) - arch = ppc +ifeq ($(shell uname -p),powerpc) + arch = ppc +else + ifeq ($(shell uname -p),arm) + arch = arm + else + arch = intel endif +endif else ifneq ($(findstring MINGW,$(shell uname -a)),) system_platform = win endif @@ -86,9 +91,11 @@ else ifeq ($(platform), osx) ifeq ($(arch),ppc) ENDIANNESS_DEFINES += -DMSB_FIRST -DHAVE_NO_LANGEXTRA endif + ifneq ($(arch),arm) + fpic += -mmacosx-version-min=10.1 + endif OSXVER = `sw_vers -productVersion | cut -d. -f 2` OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"` - fpic += -mmacosx-version-min=10.1 ifndef ($(NOUNIVERSAL)) CFLAGS += $(ARCHFLAGS) LDFLAGS += $(ARCHFLAGS) From ce8ae5d34ce3460850adcf2a79a6424e9669c3a8 Mon Sep 17 00:00:00 2001 From: Autechre Date: Fri, 15 Jan 2021 19:18:22 +0100 Subject: [PATCH 076/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d1f3f80..0be1470 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,7 +36,6 @@ include: # MacOS ARM 64-bit - project: 'libretro-infrastructure/ci-templates' - ref: 'macosx-arm64' file: '/osx-arm64.yml' ################################## CELLULAR ################################ From 0401c3983d6b7e86e0c3a9a2adc561f6f853b6a4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 15 Jan 2021 22:50:28 +0100 Subject: [PATCH 077/295] Cleanup --- Makefile.libretro | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index 9d9d6f7..508d236 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -25,10 +25,6 @@ ifeq ($(platform),) platform = win else ifneq ($(findstring Darwin,$(shell uname -s)),) platform = osx - arch = intel - ifeq ($(shell uname -p),powerpc) - arch = ppc - endif else ifneq ($(findstring win,$(shell uname -s)),) platform = win endif From 4bcd398acf49847f742fa4e10465b5127f787989 Mon Sep 17 00:00:00 2001 From: Autechre Date: Fri, 15 Jan 2021 22:56:23 +0100 Subject: [PATCH 078/295] Update Makefile.libretro --- Makefile.libretro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile.libretro b/Makefile.libretro index 508d236..50f4768 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -87,7 +87,10 @@ else ifeq ($(platform), osx) ifeq ($(arch),ppc) ENDIANNESS_DEFINES += -DMSB_FIRST -DHAVE_NO_LANGEXTRA endif - ifneq ($(arch),arm) + ifeq ($(arch),arm) + TARGET_RULE = -target $(LIBRETRO_APPLE_PLATFORM) -isysroot $(LIBRETRO_APPLE_ISYSROOT) + CFLAGS += $(TARGET_RULE) + else fpic += -mmacosx-version-min=10.1 endif OSXVER = `sw_vers -productVersion | cut -d. -f 2` From b5f6221abcad1e8611f28a2c7bf5eaabcf82acbf Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 20 Jan 2021 07:59:45 +0100 Subject: [PATCH 079/295] Fix MSVC 2003 build --- src/ntsc/nes_ntsc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ntsc/nes_ntsc.c b/src/ntsc/nes_ntsc.c index df57cb0..3d5d88d 100644 --- a/src/ntsc/nes_ntsc.c +++ b/src/ntsc/nes_ntsc.c @@ -243,7 +243,7 @@ void nes_ntsc_blit( nes_ntsc_t const* ntsc, NES_NTSC_IN_T const* input, NES_NTSC NES_NTSC_IN_T const* line_inD = inputD; NES_NTSC_BEGIN_ROW( ntsc, burst_phase, nes_ntsc_black, nes_ntsc_black, NES_NTSC_ADJ_IN( *line_in, *line_inD ) ); - nes_ntsc_out_t* restrict line_out = (nes_ntsc_out_t*) rgb_out; + nes_ntsc_out_t* line_out = (nes_ntsc_out_t*) rgb_out; int n; ++line_in; From 1ef25ff1c6cb75018471afd03ccb4eaac3aab9b0 Mon Sep 17 00:00:00 2001 From: Autechre Date: Tue, 26 Jan 2021 19:34:59 +0100 Subject: [PATCH 080/295] Update Makefile.libretro --- Makefile.libretro | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index 50f4768..c511e58 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -41,7 +41,7 @@ ifeq ($(shell uname -p),powerpc) arch = ppc else ifeq ($(shell uname -p),arm) - arch = arm + arch = arm64 else arch = intel endif @@ -87,12 +87,13 @@ else ifeq ($(platform), osx) ifeq ($(arch),ppc) ENDIANNESS_DEFINES += -DMSB_FIRST -DHAVE_NO_LANGEXTRA endif - ifeq ($(arch),arm) - TARGET_RULE = -target $(LIBRETRO_APPLE_PLATFORM) -isysroot $(LIBRETRO_APPLE_ISYSROOT) + ifeq ($(arch),arm64) + TARGET_RULE = -arch arm64 CFLAGS += $(TARGET_RULE) else fpic += -mmacosx-version-min=10.1 endif + OSXVER = `sw_vers -productVersion | cut -d. -f 2` OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"` ifndef ($(NOUNIVERSAL)) From c17439b4f4a1a900b40a0c402aa52767fc04e5fb Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 28 Jan 2021 04:49:28 +0100 Subject: [PATCH 081/295] (OSX) Add cross compile rules for arm64 --- Makefile.libretro | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index c511e58..48f2826 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -87,15 +87,17 @@ else ifeq ($(platform), osx) ifeq ($(arch),ppc) ENDIANNESS_DEFINES += -DMSB_FIRST -DHAVE_NO_LANGEXTRA endif - ifeq ($(arch),arm64) - TARGET_RULE = -arch arm64 + ifeq ($(CROSS_COMPILE),1) + TARGET_RULE = -target $(LIBRETRO_APPLE_PLATFORM) -isysroot $(LIBRETRO_APPLE_ISYSROOT) CFLAGS += $(TARGET_RULE) - else - fpic += -mmacosx-version-min=10.1 - endif + LDFLAGS += $(TARGET_RULE) + endif OSXVER = `sw_vers -productVersion | cut -d. -f 2` OSX_LT_MAVERICKS = `(( $(OSXVER) <= 9)) && echo "YES"` + ifeq ($(OSX_LT_MAVERICKS),YES) + fpic += -mmacosx-version-min=10.1 + endif ifndef ($(NOUNIVERSAL)) CFLAGS += $(ARCHFLAGS) LDFLAGS += $(ARCHFLAGS) From 82ce944aa356eb9f03cd789f0af748e93899931f Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Sun, 31 Jan 2021 15:51:09 +0100 Subject: [PATCH 082/295] Combine the very similar mappers 126/422/534/BS400/BS4040 into one common source code file. Rewrite for accuracy and compatibility with all known game dumps. Replace FUTURE KIDS hack with correct CNROM masking. --- src/boards/126-422-534.c | 136 ++++++++++++++++++++++++++++++++++ src/boards/126.c | 105 -------------------------- src/boards/534.c | 89 ---------------------- src/boards/bs4xxxr.c | 156 --------------------------------------- src/ines.c | 1 + src/ines.h | 1 + src/unif.c | 4 +- src/unif.h | 3 +- 8 files changed, 141 insertions(+), 354 deletions(-) create mode 100644 src/boards/126-422-534.c delete mode 100644 src/boards/126.c delete mode 100644 src/boards/534.c delete mode 100644 src/boards/bs4xxxr.c diff --git a/src/boards/126-422-534.c b/src/boards/126-422-534.c new file mode 100644 index 0000000..e8d6610 --- /dev/null +++ b/src/boards/126-422-534.c @@ -0,0 +1,136 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2020 NewRisingSun + * + * 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 422: "Normal" version of the mapper. Represents UNIF boards BS-400R and BS-4040R. + Mapper 126: Power Joy version of the mapper, connecting CHR A18 and A19 in reverse order. + Mapper 534: Waixing version of the mapper, inverting the reload value of the MMC3 scanline counter. +*/ + +#include "mapinc.h" +#include "mmc3.h" + +static uint8 reverseCHR_A18_A19; +static uint8 invertC000; +static uint8 dipSwitch; + +static void wrapPRG(uint32 A, uint8 V) { + int prgAND = EXPREGS[0] &0x40? 0x0F: 0x1F; // 128 KiB or 256 KiB inner PRG bank selection + int prgOR =(EXPREGS[0] <<4 &0x70 | EXPREGS[0] <<3 &0x180) &~prgAND; // outer PRG bank + switch(EXPREGS[3] &3) { + case 0: // MMC3 PRG mode + break; + case 1: + case 2: // NROM-128 mode: MMC3 register 6 applies throughout $8000-$FFFF, MMC3 A13 replaced with CPU A13. + V =DRegBuf[6] &~1 | A >>13 &1; + setprg8(A ^0x4000, V &prgAND | prgOR); // wrapPRG is only called with A containing the switchable banks, so we need to manually switch the normally fixed banks in this mode as well. + break; + case 3: // NROM-256 mode: MMC3 register 6 applies throughout $8000-$FFFF, MMC3 A13-14 replaced with CPU A13-14. + V =DRegBuf[6] &~3 | A >>13 &3; + setprg8(A ^0x4000, (V ^2) &prgAND | prgOR); // wrapPRG is only called with A containing the switchable banks, so we need to manually switch the normally fixed banks in this mode as well. + break; + } + setprg8(A, V &prgAND | prgOR); +} + +static void wrapCHR(uint32 A, uint8 V) { + int chrAND = EXPREGS[0] &0x80? 0x7F: 0xFF; // 128 KiB or 256 KiB innter CHR bank selection + int chrOR; // outer CHR bank + if (reverseCHR_A18_A19) // Mapper 126 swaps CHR A18 and A19 + chrOR =(EXPREGS[0] <<4 &0x080 | EXPREGS[0] <<3 &0x100 | EXPREGS[0] <<5 &0x200) &~chrAND; + else + chrOR =EXPREGS[0] <<4 &0x380 &~chrAND; + + if (EXPREGS[3] &0x10) // CNROM mode: 8 KiB inner CHR bank comes from outer bank register #2 + setchr8(EXPREGS[2] &(chrAND >>3) | chrOR >>3); + else // MMC3 CHR mode + setchr1(A, (V & chrAND) | chrOR); +} + +static DECLFW(writeWRAM) { + if (~EXPREGS[3] &0x80) { + // Lock bit clear: Update any outer bank register + EXPREGS[A &3] =V; + FixMMC3PRG(MMC3_cmd); + FixMMC3CHR(MMC3_cmd); + } else + if ((A &3) ==2) { + // Lock bit set: Only update the bottom one or two bits of the CNROM bank + int latchMask =EXPREGS[2] &0x10? 1: 3; // 16 or 32 KiB inner CHR bank selection + EXPREGS[2] &=~latchMask; + EXPREGS[2] |= V &latchMask; + FixMMC3CHR(MMC3_cmd); + } + CartBW(A, V); +} + +static DECLFR(readDIP) { + uint8 result =CartBR(A); + if (EXPREGS[1] &1) result =result &~3 | dipSwitch &3; // Replace bottom two bits with solder pad or DIP switch setting if so selected + return result; +} + +static DECLFW(writeIRQ) { + MMC3_IRQWrite(A, V ^0xFF); +} + +static void reset(void) { + dipSwitch++; // Soft-resetting cycles through solder pad or DIP switch settings + EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; + MMC3RegReset(); +} + +static void power(void) { + dipSwitch =0; + EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; + GenMMC3Power(); + SetWriteHandler(0x6000, 0x7FFF, writeWRAM); + SetReadHandler(0x8000, 0xFFFF, readDIP); + if (invertC000) SetWriteHandler(0xC000, 0xDFFF, writeIRQ); // Mapper 534 inverts the MMC3 scanline counter reload value +} + +static void init(CartInfo *info) { + GenMMC3_Init(info, 512, 256, 8, info->battery); + cwrap = wrapCHR; + pwrap = wrapPRG; + + info->Power = power; + info->Reset = reset; + + AddExState(EXPREGS, 4, 0, "EXPR"); + AddExState(&dipSwitch, 1, 0, "DPSW"); +} + +void Mapper126_Init(CartInfo *info) { + reverseCHR_A18_A19 = 1; + invertC000 = 0; + init(info); +} + +void Mapper422_Init(CartInfo *info) { + reverseCHR_A18_A19 = 0; + invertC000 = 0; + init(info); +} + +void Mapper534_Init(CartInfo *info) { + reverseCHR_A18_A19 = 0; + invertC000 = 1; + init(info); +} diff --git a/src/boards/126.c b/src/boards/126.c deleted file mode 100644 index 0a93910..0000000 --- a/src/boards/126.c +++ /dev/null @@ -1,105 +0,0 @@ -/* 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"); -} diff --git a/src/boards/534.c b/src/boards/534.c deleted file mode 100644 index 8c8bb9d..0000000 --- a/src/boards/534.c +++ /dev/null @@ -1,89 +0,0 @@ -/* FCEUmm - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2020 negativeExponent - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* NES 2.0 Mapper 534 - 2-in-1 数独/五子棋 (Sudoku/Gomoku, NJ064) */ - -#include "mapinc.h" -#include "mmc3.h" - -static uint32 GetPRGBank(uint32 bank) -{ - if (~bank & 1 && (MMC3_cmd & 0x40)) bank ^= 2; - return (bank & 2) ? (0xFE | (bank & 1)) : DRegBuf[6 | (bank & 1)]; -} - -void SyncPRG_GNROM(int A14, int AND, int OR) { - setprg8(0x8000, ((GetPRGBank(0) & ~A14) & AND) | OR); - setprg8(0xA000, ((GetPRGBank(1) & ~A14) & AND) | OR); - setprg8(0xC000, ((GetPRGBank(0) | A14) & AND) | OR); - setprg8(0xE000, ((GetPRGBank(1) | A14) & AND) | OR); -} - -static void M534PW(uint32 A, uint8 V) { - if (EXPREGS[0] & 0x40) - SyncPRG_GNROM(EXPREGS[3] & 0x02, 0x0F, ((EXPREGS[0] & 3) << 4)); - else - setprg8(A, (V & 0x1F) | ((EXPREGS[0] & 0x2) << 4)); -} - -static void M534CW(uint32 A, uint8 V) { - setchr1(A, (V & 0xFF) | ((EXPREGS[2] & 0x0F) << 3) | ((EXPREGS[0] & 0x18) << 4)); -} - -static DECLFW(M534IRQWrite) { - MMC3_IRQWrite(0xC000 | (A & 1), V ^ 0xFF); -} - -static DECLFW(M534WriteLo) { - if ((A & 0x800) && (!(EXPREGS[3] & 0x80) || (A & 3) == 2)) { - EXPREGS[A & 3] = V; - FixMMC3CHR(MMC3_cmd); - FixMMC3PRG(MMC3_cmd); - } -} - -static void M534Power(void) { - EXPREGS[0] = 0x00; - EXPREGS[1] = 0x00; - EXPREGS[2] = 0x00; - EXPREGS[3] = 0x00; - GenMMC3Power(); - SetWriteHandler(0x6000, 0x6FFF, M534WriteLo); - SetWriteHandler(0xC000, 0xDFFF, M534IRQWrite); -} - -static void M534Reset(void) { - EXPREGS[0] = 0x00; - EXPREGS[1] = 0x00; - EXPREGS[2] = 0x00; - EXPREGS[3] = 0x00; - EXPREGS[4] = (EXPREGS[4] + 1) & 7; - FCEU_printf("dipswitch = %d\n", EXPREGS[4]); - MMC3RegReset(); -} - -void Mapper534_Init(CartInfo *info) { - GenMMC3_Init(info, 512, 512, 0, 0); - pwrap = M534PW; - cwrap = M534CW; - info->Power = M534Power; - info->Reset = M534Reset; - AddExState(EXPREGS, 5, 0, "EXPR"); -} diff --git a/src/boards/bs4xxxr.c b/src/boards/bs4xxxr.c deleted file mode 100644 index a844007..0000000 --- a/src/boards/bs4xxxr.c +++ /dev/null @@ -1,156 +0,0 @@ -/* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2020 - * - * 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 - */ - -/* originally submitted by dragon2snow - * Known carts: - * UNIF BMC-BS-400R : 700000-in-1 (BS-400R)(Unl), PRG 1024K CHR 1024K CRC 0x5DBDFAA0 - * UNIF BMC-BS-4040R : Double Dragon 310000-in-1 (4040R) PRG 512 CHR 512 CRC 0x3A642F31 - * - * FIXME: Future Kids notes - * Either something is wrong or missing because chr banks for the game is $E8 - EB - * but game uses $EC-EF here. These are chr banks for the next game and does not masked properly - * by mapper code. - * ~ c@2020 - */ - -#include "mapinc.h" -#include "mmc3.h" - -static uint8 pointer; -static uint8 offset; - -static int getPRGBankBS4XXXR(int bank) -{ - if (((~bank) & 1) && (pointer & 0x40)) bank ^= 2; - return ((bank & 2) ? 0xFE | (bank & 1) : DRegBuf[6 | (bank & 1)]); -} - -static void BS4XXXRPW(uint32 A, uint8 V) -{ - if ((EXPREGS[3] >> 4) & 1) { - uint8 prgAND = ((EXPREGS[0] >> 1) & 1) ? 0x0F : 0x0F; - uint8 prgOR = (EXPREGS[0] & 7) << 4; - uint8 bank0 = getPRGBankBS4XXXR(0); - uint8 bank1 = getPRGBankBS4XXXR(1); - /* 16K Mode */ - if (!((EXPREGS[3] >>1 )& 0x1)) { - setprg8(0x8000, (bank0 & prgAND) | prgOR); - setprg8(0xA000, (bank1 & prgAND) | prgOR); - setprg8(0xC000, (bank0 & prgAND) | prgOR); - setprg8(0xE000, (bank1 & prgAND) | prgOR); - } - /* 32K Mode */ - else { - setprg8(0x8000, (bank0 & prgAND) | prgOR); - setprg8(0xA000, (bank1 & prgAND) | prgOR); - setprg8(0xC000, ((bank0 | 2) & prgAND) | prgOR); - setprg8(0xE000, ((bank1 | 2) & prgAND) | prgOR); - } - } - /* Mmc3 Mode */ - else { - uint8 prgAND = ((EXPREGS[0] >> offset) & 1) ? 0x0F : 0x1F; /* 4040R 6,400R 1 */ - uint8 prgOR = (EXPREGS[0] & 7) << 4; - setprg8(A, (V & prgAND) | prgOR); - } -} - -static void BS4XXXRCW(uint32 A, uint8 V) { - if ((EXPREGS[3] >> 4) & 1) { - uint8 chrAND = ((EXPREGS[0] >> 1) & 1) ? 0x0F : 0x0F; - uint8 chrOR = ((EXPREGS[0] >> 3) & 7) << 4; - /* FIXME: Ugly hack for Future Kids */ - if (EXPREGS[4]) { - chrAND = 0x03; - chrOR |= 8; - } - setchr8((EXPREGS[2] & chrAND) | chrOR); - } else { - uint8 chrAND = ((EXPREGS[0] >> 1) & 1) ? 0xFF : 0xFF; - uint16 chrOR = ((EXPREGS[0] >> 3) & 7) << 7; - setchr1(A, (V & chrAND) | chrOR); - } -} - -static DECLFW(BS4XXXRHiWrite) { - /* FCEU_printf("Wr8B: A:%04x V:%02x\n", A, V); */ - if (A == 0x8000) - pointer = MMC3_cmd ^ V; - MMC3_CMDWrite(A, V); -} - -static DECLFW(BS4XXXRLoWrite) { - /* FCEU_printf("WrLo: A:%04x V:%02x\n", A, V); */ - if (A & 0x800) { - /* Future Kids hack */ - if (!EXPREGS[4]) { - if ((((A & 3) == 2) && (V == 0xE8))) - EXPREGS[4] = 1; - } - if (!(EXPREGS[3] & 0x80)) { - EXPREGS[A & 0x03] = V; - FixMMC3PRG(MMC3_cmd); - FixMMC3CHR(MMC3_cmd); - } - else if (EXPREGS[3] & 0x10) { - EXPREGS[A & 0x03] = V; - FixMMC3PRG(MMC3_cmd); - FixMMC3CHR(MMC3_cmd); - } - } - CartBW(A, V); -} - -static void BS4XXXRReset(void) { - EXPREGS[4] = 0; - EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; - MMC3RegReset(); -} - -static void BS4XXXRPower(void) { - EXPREGS[4] = 0; - EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; - GenMMC3Power(); - SetWriteHandler(0x6000, 0x7FFF, BS4XXXRLoWrite); - SetWriteHandler(0x8000, 0xBFFF, BS4XXXRHiWrite); -} - -void BS4XXXR_Init(CartInfo *info) { - GenMMC3_Init(info, 512, 256, 8, 0); - cwrap = BS4XXXRCW; - pwrap = BS4XXXRPW; - - info->Power = BS4XXXRPower; - info->Reset = BS4XXXRReset; - - AddExState(EXPREGS, 4, 0, "EXPR"); - AddExState(&pointer, 1, 0, "PNTR"); - AddExState(&offset, 1, 0, "OFFS"); -} - -void BS400R_Init(CartInfo *info) { - offset = 1; - BS4XXXR_Init(info); -} - -void BS4040R_Init(CartInfo *info) { - offset = 6; - BS4XXXR_Init(info); -} diff --git a/src/ines.c b/src/ines.c index 69dabaf..231b846 100644 --- a/src/ines.c +++ b/src/ines.c @@ -699,6 +699,7 @@ INES_BOARD_BEGIN() INES_BOARD( "Realtec 8210", 395, Mapper395_Init ) INES_BOARD( "BMC Super 19-in-1 (VIP19)", 401, Mapper401_Init ) INES_BOARD( "A88S-1", 411, Mapper411_Init ) + INES_BOARD( "BS-400R/BS-4040", 422, Mapper422_Init ) INES_BOARD( "Brilliant Com Cocoma Pack", 516, Mapper516_Init ) INES_BOARD( "Sachen 3014", 533, Mapper533_Init ) INES_BOARD( "NJ064", 534, Mapper534_Init ) diff --git a/src/ines.h b/src/ines.h index b1ce41c..99e4756 100644 --- a/src/ines.h +++ b/src/ines.h @@ -271,6 +271,7 @@ void Mapper390_Init(CartInfo *); void Mapper395_Init(CartInfo *); void Mapper401_Init(CartInfo *); void Mapper411_Init(CartInfo *); +void Mapper422_Init(CartInfo *); void Mapper516_Init(CartInfo *); void Mapper533_Init(CartInfo *); void Mapper534_Init(CartInfo *); diff --git a/src/unif.c b/src/unif.c index fd7a642..2d1bfe4 100644 --- a/src/unif.c +++ b/src/unif.c @@ -616,8 +616,8 @@ static BMAPPING bmap[] = { { "82112C", 540, Mapper540_Init, 0 }, { "N49C-300", 369, Mapper369_Init, 0 }, - { "BS-400R", NO_INES, BS400R_Init, 0 }, - { "BS-4040R", NO_INES, BS4040R_Init, 0 }, + { "BS-400R", 422, Mapper422_Init, 0 }, + { "BS-4040R", 422, Mapper422_Init, 0 }, #ifdef COPYFAMI { "COPYFAMI_MMC3", NO_INES, MapperCopyFamiMMC3_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 3b2cbe3..0dbd4ab 100644 --- a/src/unif.h +++ b/src/unif.h @@ -196,8 +196,7 @@ void AbG1l_Init(CartInfo *info); void KG256_Init(CartInfo *info); void WAIXINGFS005_Init(CartInfo *info); -void BS4040R_Init(CartInfo *info); -void BS400R_Init(CartInfo *info); +void Mapper422_Init(CartInfo *info); #ifdef COPYFAMI void MapperCopyFamiMMC3_Init(CartInfo *info); From f282bbdc2910e290a864f88de2f2a30d5c585b6c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 9 Feb 2021 00:33:37 +0100 Subject: [PATCH 083/295] (MSVC 2005/2010) Add core --- .gitlab-ci.yml | 30 ++++++++++++++++++++++++++++ Makefile.common | 2 -- Makefile.libretro | 51 ++++++++++++++++++++++++++++------------------- 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0be1470..0664811 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,6 +22,18 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/windows-i686-mingw.yml' + # Windows msvc10 64-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/windows-x64-msvc10-msys2.yml' + + # Windows msvc10 32-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/windows-i686-msvc10-msys2.yml' + + # Windows msvc05 32-bit + - project: 'libretro-infrastructure/ci-templates' + file: '/windows-i686-msvc05-msys2.yml' + # Linux 64-bit - project: 'libretro-infrastructure/ci-templates' file: '/linux-x64.yml' @@ -112,6 +124,24 @@ libretro-build-windows-i686: - .libretro-windows-i686-mingw-make-default - .core-defs +# Windows msvc10 64-bit +libretro-build-windows-msvc10-x64: + extends: + - .libretro-windows-x64-msvc10-msys2-make-default + - .core-defs + +# Windows msvc10 32-bit +libretro-build-windows-msvc10-i686: + extends: + - .libretro-windows-i686-msvc10-msys2-make-default + - .core-defs + +# Windows msvc05 32-bit +libretro-build-windows-msvc05-i686: + extends: + - .libretro-windows-i686-msvc05-msys2-make-default + - .core-defs + # Linux 64-bit libretro-build-linux-x64: extends: diff --git a/Makefile.common b/Makefile.common index fe710f6..8c75113 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1,6 +1,4 @@ -ifeq ($(LIBRETRO_COMM_DIR),) LIBRETRO_COMM_DIR := $(CORE_DIR)/drivers/libretro/libretro-common -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 diff --git a/Makefile.libretro b/Makefile.libretro index 48f2826..b8be704 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -524,18 +524,19 @@ else ifeq ($(platform), windows_msvc2010_x64) PATH := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/bin/amd64"):$(PATH) PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../IDE") -INCLUDE := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/include") LIB := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/lib/amd64") -BIN := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/bin") +INCLUDE := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/include") -WindowsSdkDir := $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*')lib/x64 -WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*')lib/x64 -WindowsSdkDirInc := $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*')Include -WindowsSdkDirInc ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*')Include +WindowsSdkDir := $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*') +WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*') -INCFLAGS_PLATFORM = -I"$(WindowsSdkDirInc)" -export INCLUDE := $(INCLUDE) -export LIB := $(LIB);$(WindowsSdkDir) +WindowsSDKIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include") +WindowsSDKGlIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\gl") +WindowsSDKLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib\x64") + +INCFLAGS_PLATFORM = -I"$(WindowsSDKIncludeDir)" +export INCLUDE := $(INCLUDE);$(WindowsSDKIncludeDir);$(WindowsSDKGlIncludeDir) +export LIB := $(LIB);$(WindowsSDKLibDir) TARGET := $(TARGET_NAME)_libretro.dll PSS_STYLE :=2 LDFLAGS += -DLL @@ -547,18 +548,19 @@ else ifeq ($(platform), windows_msvc2010_x86) PATH := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/bin"):$(PATH) PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../IDE") -INCLUDE := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/include") LIB := $(shell IFS=$$'\n'; cygpath -w "$(VS100COMNTOOLS)../../VC/lib") -BIN := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/bin") +INCLUDE := $(shell IFS=$$'\n'; cygpath "$(VS100COMNTOOLS)../../VC/include") -WindowsSdkDir := $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*')lib -WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*')lib -WindowsSdkDirInc := $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*')Include -WindowsSdkDirInc ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*')Include +WindowsSdkDir := $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.1A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*') +WindowsSdkDir ?= $(shell reg query "HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A" -v "InstallationFolder" | grep -o '[A-Z]:\\.*') -INCFLAGS_PLATFORM = -I"$(WindowsSdkDirInc)" -export INCLUDE := $(INCLUDE) -export LIB := $(LIB);$(WindowsSdkDir) +WindowsSDKIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include") +WindowsSDKGlIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\gl") +WindowsSDKLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib") + +INCFLAGS_PLATFORM = -I"$(WindowsSDKIncludeDir)" +export INCLUDE := $(INCLUDE);$(WindowsSDKIncludeDir);$(WindowsSDKGlIncludeDir) +export LIB := $(LIB);$(WindowsSDKLibDir) TARGET := $(TARGET_NAME)_libretro.dll PSS_STYLE :=2 LDFLAGS += -DLL @@ -627,10 +629,17 @@ INCLUDE := $(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../../VC/include") LIB := $(shell IFS=$$'\n'; cygpath -w "$(VS80COMNTOOLS)../../VC/lib") BIN := $(shell IFS=$$'\n'; cygpath "$(VS80COMNTOOLS)../../VC/bin") -WindowsSdkDir := $(INETSDK) +WindowsSdkDir := $(shell reg query "HKLM\SOFTWARE\Microsoft\MicrosoftSDK\InstalledSDKs\8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3" -v "Install Dir" | grep -o '[A-Z]:\\.*') -export INCLUDE := $(INCLUDE);$(INETSDK)/Include -export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib +WindowsSDKIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include") +WindowsSDKAtlIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\atl") +WindowsSDKCrtIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\crt") +WindowsSDKGlIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\gl") +WindowsSDKMfcIncludeDir := $(shell cygpath -w "$(WindowsSdkDir)\Include\mfc") +WindowsSDKLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib") + +export INCLUDE := $(INCLUDE);$(WindowsSDKIncludeDir);$(WindowsSDKAtlIncludeDir);$(WindowsSDKCrtIncludeDir);$(WindowsSDKGlIncludeDir);$(WindowsSDKMfcIncludeDir);libretro-common/include/compat/msvc +export LIB := $(LIB);$(WindowsSDKLibDir) TARGET := $(TARGET_NAME)_libretro.dll PSS_STYLE :=2 LDFLAGS += -DLL From 91ccd3b9e0247db66b07c68532805b8a1a94f8f0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 14 Feb 2021 17:46:31 +0100 Subject: [PATCH 084/295] (MSVC) Embed MSVCR runtime --- Makefile.libretro | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index b8be704..fda55d5 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -675,36 +675,23 @@ endif ifeq ($(DEBUG), 1) ifneq (,$(findstring msvc,$(platform))) - ifeq ($(STATIC_LINKING),1) - CFLAGS += -MTd - CXXFLAGS += -MTd - else - CFLAGS += -MDd - CXXFLAGS += -MDd - endif - - CFLAGS += -Od -Zi -DDEBUG -D_DEBUG - CXXFLAGS += -Od -Zi -DDEBUG -D_DEBUG + CFLAGS += -MTd + CXXFLAGS += -MTd + CFLAGS += -Od -Zi -D_DEBUG + CXXFLAGS += -Od -Zi -D_DEBUG else - CFLAGS += -O0 -g -DDEBUG - CXXFLAGS += -O0 -g -DDEBUG + CFLAGS += -O0 -g + CXXFLAGS += -O0 -g endif + CFLAGS += -DDEBUG + CXXFLAGS += -DDEBUG else ifneq (,$(findstring msvc,$(platform))) - ifeq ($(STATIC_LINKING),1) - CFLAGS += -MT - CXXFLAGS += -MT - else - CFLAGS += -MD - CXXFLAGS += -MD - endif - - CFLAGS += -O2 -DNDEBUG - CXXFLAGS += -O2 -DNDEBUG - else - CFLAGS += -O2 -DNDEBUG - CXXFLAGS += -O2 -DNDEBUG + CFLAGS += -MT + CXXFLAGS += -MT endif + CFLAGS += -O2 -DNDEBUG + CXXFLAGS += -O2 -DNDEBUG endif ifneq ($(SANITIZER),) From 8fa62114d86fa55eaafc0330b4fd285f7f55d3e8 Mon Sep 17 00:00:00 2001 From: negativeExponent <54053706+negativeExponent@users.noreply.github.com> Date: Mon, 1 Mar 2021 06:33:17 +0800 Subject: [PATCH 085/295] Apply region overrides when loading new rom (Fix#430) --- src/drivers/libretro/libretro.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 3bac67f..94ec2c2 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -2376,6 +2376,7 @@ bool retro_load_game(const struct retro_game_info *game) sndvolume = 150; swapDuty = 0; dendy = 0; + opt_region = 0; /* Wii: initialize this or else last variable is passed through * when loading another rom causing save state size change. */ From 4194145d3a62a61fa236d182fa14a5d0672d23d7 Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 7 Mar 2021 16:34:55 -1000 Subject: [PATCH 086/295] Support iOS and tvOS in gitlab ci --- .gitlab-ci.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0664811..2e111a8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -55,9 +55,9 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/android-jni.yml' - # iOS 9 + # iOS - project: 'libretro-infrastructure/ci-templates' - file: '/ios9.yml' + file: '/ios-arm64.yml' ################################## CONSOLES ################################ # PlayStation Portable @@ -96,6 +96,10 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/dingux-mips32.yml' + # tvOS (AppleTV) + - project: 'libretro-infrastructure/ci-templates' + file: '/tvos-arm64.yml' + #################################### MISC ################################## # Emscripten - project: 'libretro-infrastructure/ci-templates' @@ -191,10 +195,10 @@ android-x86: - .libretro-android-jni-x86 - .core-defs -# iOS 9 -libretro-build-ios-9: +# iOS +libretro-build-ios-arm64: extends: - - .libretro-ios9-make-default + - .libretro-ios-arm64-make-default - .core-defs ################################### CONSOLES ################################# From 8b7e8d463441018247eba735b2e596f679ff83dd Mon Sep 17 00:00:00 2001 From: Yoshi Sugawara Date: Sun, 7 Mar 2021 17:06:36 -1000 Subject: [PATCH 087/295] add back ios9 target --- .gitlab-ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2e111a8..3967fdb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -59,6 +59,10 @@ include: - project: 'libretro-infrastructure/ci-templates' file: '/ios-arm64.yml' + # iOS (armv7) + - project: 'libretro-infrastructure/ci-templates' + file: '/ios9.yml' + ################################## CONSOLES ################################ # PlayStation Portable - project: 'libretro-infrastructure/ci-templates' @@ -201,6 +205,12 @@ libretro-build-ios-arm64: - .libretro-ios-arm64-make-default - .core-defs +# iOS (armv7) +libretro-build-ios9: + extends: + - .libretro-ios9-make-default + - .core-defs + ################################### CONSOLES ################################# # PlayStation Portable libretro-build-psp: From eb87c5e09f06e394d5160350d3cfc20673d7f863 Mon Sep 17 00:00:00 2001 From: Autechre Date: Mon, 8 Mar 2021 04:26:34 +0100 Subject: [PATCH 088/295] Update .gitlab-ci.yml --- .gitlab-ci.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3967fdb..031eee5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -205,11 +205,17 @@ libretro-build-ios-arm64: - .libretro-ios-arm64-make-default - .core-defs -# iOS (armv7) +# iOS (armv7) [iOS 9 and up] libretro-build-ios9: extends: - .libretro-ios9-make-default - .core-defs + +# tvOS +libretro-build-tvos-arm64: + extends: + - .libretro-tvos-arm64-make-default + - .core-defs ################################### CONSOLES ################################# # PlayStation Portable From 66760e1a17342070ab876ec028aee273e9cb8236 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 25 Mar 2021 21:18:05 +0100 Subject: [PATCH 089/295] Add od-beta --- .gitlab-ci.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 031eee5..6771abe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -272,6 +272,12 @@ libretro-build-dingux-mips32: - .libretro-dingux-mips32-make-default - .core-defs +# OpenDingux Beta +libretro-build-dingux-odbeta-mips32: + extends: + - .libretro-dingux-odbeta-mips32-make-default + - .core-defs + #################################### MISC ################################## # Emscripten libretro-build-emscripten: From f4a5c2a420ef60eaf5662f7b50599dba4c1c6c53 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 7 Apr 2021 18:45:37 +0200 Subject: [PATCH 090/295] Mapper 332: Add CNROM mode, support larger multicarts --- src/boards/super40in1.c | 49 ++++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/src/boards/super40in1.c b/src/boards/super40in1.c index ef5a5e1..3de6804 100644 --- a/src/boards/super40in1.c +++ b/src/boards/super40in1.c @@ -23,43 +23,72 @@ #include "mapinc.h" -static uint8 preg, creg; +static uint8 preg, creg, latch, dipSwitch; static SFORMAT StateRegs[] = { { &preg, 1, "PREG" }, { &creg, 1, "CREG" }, + { &latch, 1, "LATC" }, + { &dipSwitch, 1, "DPSW" }, { 0 } }; static void Sync(void) { + int prg = (preg & 7) | ((preg >> 3) & 0x08); // There is a high bit 3 of the PRG register that applies both to PRG and CHR if (preg & 8) { - setprg16(0x8000, preg & 7); - setprg16(0xc000, preg & 7); + setprg16(0x8000, prg); + setprg16(0xc000, prg); } else - setprg32(0x8000, (preg & 6) >> 1); - setchr8(creg); + setprg32(0x8000, prg >> 1); + + int chr = (creg & 7) | ((preg >> 3) & 0x08); // There is a high bit 3 of the PRG register that applies both to PRG and CHR + int mask = (creg & 0x10)? 0: (creg & 0x20)? 1: 3; // There is an CNROM mode that takes either two or four inner CHR banks from a CNROM-like latch register at $8000-$FFFF. + setchr8((chr &~mask) | (latch &mask)); // This "inner CHR bank" substitutes the respective bit(s) of the creg register. + setmirror(((preg >> 4) & 1) ^ 1); } +static DECLFR(BMCWSRead) { + if ((creg >> 6) & (dipSwitch &3)) + return X.DB; + else + return CartBR(A); +} + static DECLFW(BMCWSWrite) { if (preg & 0x20) return; switch (A & 1) { - case 0: preg = V; Sync(); break; - case 1: creg = V; Sync(); break; + case 0: preg = V; Sync(); break; + case 1: creg = V; Sync(); break; } } -static void MBMCWSPower(void) { +static DECLFW(LatchWrite) { + latch =V; Sync(); - SetReadHandler(0x8000, 0xFFFF, CartBR); - SetWriteHandler(0x6000, 0x6001, BMCWSWrite); +} + +static void MBMCWSPower(void) { + dipSwitch =0; + Sync(); + SetReadHandler(0x8000, 0xFFFF, BMCWSRead); + SetWriteHandler(0x6000, 0x7FFF, BMCWSWrite); + SetWriteHandler(0x8000, 0xFFFF, LatchWrite); } static void BMCWSReset(void) { + dipSwitch++; // Soft-resetting cycles through solder pad or DIP switch settings + if (dipSwitch == 3) dipSwitch = 0; // Only 00b, 01b and 10b settings are valid + + // Always reset to menu + preg =0; + creg =0; + latch =0; + Sync(); } static void StateRestore(int version) { From c06e25ed30a81410c241ba4302ab8ede037edcd8 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Thu, 8 Apr 2021 17:06:17 +0200 Subject: [PATCH 091/295] Rewrite and unify J.Y. ASIC emulation. Add multicart mappers. --- src/boards/90.c | 505 ------------------------------------- src/boards/bmc13in1jy110.c | 99 -------- src/boards/jyasic.c | 483 +++++++++++++++++++++++++++++++++++ src/boards/sc-127.c | 123 --------- src/ines.c | 13 +- src/ines.h | 9 + src/unif.c | 4 +- src/unif.h | 2 - 8 files changed, 504 insertions(+), 734 deletions(-) delete mode 100644 src/boards/90.c delete mode 100644 src/boards/bmc13in1jy110.c create mode 100644 src/boards/jyasic.c delete mode 100644 src/boards/sc-127.c diff --git a/src/boards/90.c b/src/boards/90.c deleted file mode 100644 index ff2b0b4..0000000 --- a/src/boards/90.c +++ /dev/null @@ -1,505 +0,0 @@ -/* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel - * Copyright (C) 2005 CaH4e3 - * 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 - */ - -#include "mapinc.h" -/* #define DEBUG90 */ - -/* 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 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 is211; -static int is281; - -static uint8 IRQMode; /* from $c001 */ -static uint8 IRQPre; /* from $c004 */ -static uint8 IRQPreSize; /* from $c007 */ -static uint8 IRQCount; /* from $c005 */ -static uint8 IRQXOR; /* Loaded from $C006 */ -static uint8 IRQa; /* $c002, $c003, and $c000 */ - -static uint8 mul[2]; -static uint8 regie; - -static uint8 tkcom[4]; -static uint8 prgb[4]; -static uint8 chrlow[8]; -static uint8 chrhigh[8]; - -static uint8 chr[2]; - -static uint16 names[4]; -static uint8 tekker; - -static SFORMAT Tek_StateRegs[] = { - { &IRQMode, 1, "IRQM" }, - { &IRQPre, 1, "IRQP" }, - { &IRQPreSize, 1, "IRQR" }, - { &IRQCount, 1, "IRQC" }, - { &IRQXOR, 1, "IRQX" }, - { &IRQa, 1, "IRQA" }, - { mul, 2, "MUL" }, - { ®ie, 1, "REGI" }, - { tkcom, 4, "TKCO" }, - { prgb, 4, "PRGB" }, - { chr, 2, "CLTC" }, - { chrlow, 4, "CHRL" }, - { chrhigh, 8, "CHRH" }, - { &names[0], 2 | FCEUSTATE_RLSB, "NMS0" }, - { &names[1], 2 | FCEUSTATE_RLSB, "NMS1" }, - { &names[2], 2 | FCEUSTATE_RLSB, "NMS2" }, - { &names[3], 2 | FCEUSTATE_RLSB, "NMS3" }, - { &tekker, 1, "TEKR" }, - { 0 } -}; - -static void mira(void) { - if (((tkcom[0] & 0x20) && is209) || is211 || ((tkcom[1] & 0x08) && is281)) { - int x; - if (tkcom[0] & 0x40) { /* Name tables are ROM-only */ - for (x = 0; x < 4; x++) - setntamem(CHRptr[0] + (((names[x]) & CHRmask1[0]) << 10), 0, x); - } else { /* Name tables can be RAM or ROM. */ - for (x = 0; x < 4; x++) { - if ((tkcom[1] & 0x80) == (names[x] & 0x80)) /* RAM selected. */ - setntamem(NTARAM + ((names[x] & 0x1) << 10), 1, x); - else - setntamem(CHRptr[0] + (((names[x]) & CHRmask1[0]) << 10), 0, x); - } - } - } else { - switch (tkcom[1] & 3) { - case 0: setmirror(MI_V); break; - case 1: setmirror(MI_H); break; - case 2: setmirror(MI_0); break; - case 3: setmirror(MI_1); break; - } - } -} - -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) { - uint8 prgshift = 0, prgmask = 0x3F, outb_sel = 0x06, last_bank = 0x3F; - uint8 prgmode = tkcom[0] & 0x03; - 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) - setprg8(0x6000, (((prgb[3] << 2) + 3) & 0x3F) | bankmode); - setprg32(0x8000, (last_bank & prgmask) | bankmode); - break; - case 0x01: - if (tkcom[0] & 0x80) - setprg8(0x6000, (((prgb[3] << 1) + 1) & 0x3F) | bankmode); - setprg16(0x8000, (prgb[1] & prgmask) | bankmode); - setprg16(0xC000, (last_bank & prgmask) | bankmode); - break; - case 0x02: - case 0x03: - if (tkcom[0] & 0x80) - setprg8(0x6000, (invertprg(prgb[3], invert) & 0x3F) | bankmode); - setprg8(0x8000, (invertprg(prgb[0], invert) & prgmask) | bankmode); - setprg8(0xa000, (invertprg(prgb[1], invert) & prgmask) | bankmode); - setprg8(0xc000, (invertprg(prgb[2], invert) & prgmask) | bankmode); - setprg8(0xe000, (invertprg(last_bank, invert) & prgmask) | bankmode); - break; - } -} - -static void tekvrom(void) { - int x, bank = 0, mask = 0xFFFF; - if (!(tkcom[3] & 0x20) || is281) { - if (is281) - bank = tkcom[3] & 1; - else - bank = (tkcom[3] & 1) | ((tkcom[3] & 0x18) >> 2); - switch (tkcom[0] & 0x18) { - case 0x00: bank <<= 5; mask = 0x1F; break; - case 0x08: bank <<= 6; mask = 0x3F; break; - case 0x10: bank <<= 7; mask = 0x7F; break; - case 0x18: bank <<= 8; mask = 0xFF; break; - } - } - switch (tkcom[0] & 0x18) { - case 0x00: /* 8KB */ - setchr8(((chrlow[0] | (chrhigh[0] << 8)) & mask) | bank); - break; - case 0x08: /* 4KB */ -#if 0 - for(x=0;x<8;x+=4) - setchr4(x<<10,((chrlow[x]|(chrhigh[x]<<8))&mask)|bank); -#endif - setchr4(0x0000, ((chrlow[chr[0]] | (chrhigh[chr[0]] << 8)) & mask) | bank); - setchr4(0x1000, ((chrlow[chr[1]] | (chrhigh[chr[1]] << 8)) & mask) | bank); - break; - case 0x10: /* 2KB */ - for (x = 0; x < 8; x += 2) - setchr2(x << 10, ((chrlow[x] | (chrhigh[x] << 8)) & mask) | bank); - break; - case 0x18: /* 1KB */ - for (x = 0; x < 8; x++) - setchr1(x << 10, ((chrlow[x] | (chrhigh[x] << 8)) & mask) | bank); - break; - } -} - -static DECLFW(M90TekWrite) { - switch (A & 0x5C03) { - case 0x5800: mul[0] = V; break; - case 0x5801: mul[1] = V; break; - case 0x5803: regie = V; break; - } -} - -static DECLFR(M90TekRead) { - switch (A & 0x5C03) { - case 0x5800: return(mul[0] * mul[1]); - case 0x5801: return((mul[0] * mul[1]) >> 8); - case 0x5803: return(regie); - default: return tekker; - } - return(0xff); -} - -static DECLFW(M90PRGWrite) { -/* FCEU_printf("bs %04x %02x\n",A,V); */ - prgb[A & 3] = V; - tekprom(); -} - -static DECLFW(M90CHRlowWrite) { -/* FCEU_printf("bs %04x %02x\n",A,V); */ - chrlow[A & 7] = V; - tekvrom(); -} - -static DECLFW(M90CHRhiWrite) { -/* FCEU_printf("bs %04x %02x\n",A,V); */ - chrhigh[A & 7] = V; - tekvrom(); -} - -static DECLFW(M90NTWrite) { -/* FCEU_printf("bs %04x %02x\n",A,V); */ - if (A & 4) { - names[A & 3] &= 0x00FF; - names[A & 3] |= V << 8; - } else { - names[A & 3] &= 0xFF00; - names[A & 3] |= V; - } - mira(); -} - -static DECLFW(M90IRQWrite) { -/* FCEU_printf("bs %04x %02x\n",A,V); */ - switch (A & 7) { - case 00: -/* FCEU_printf("%s IRQ (C000)\n",V&1?"Enable":"Disable"); */ - IRQa = V & 1; - if (!(V & 1)) - X6502_IRQEnd(FCEU_IQEXT); - break; - case 02: -/* FCEU_printf("Disable IRQ (C002) scanline=%d\n", scanline); */ - IRQa = 0; X6502_IRQEnd(FCEU_IQEXT); - break; - case 03: -/* FCEU_printf("Enable IRQ (C003) scanline=%d\n", scanline); */ - IRQa = 1; - break; - case 01: - IRQMode = V; -#if 0 - FCEU_printf("IRQ Count method: "); - switch (IRQMode&3) - { - case 00: FCEU_printf("M2 cycles\n");break; - case 01: FCEU_printf("PPU A12 toggles\n");break; - case 02: FCEU_printf("PPU reads\n");break; - case 03: FCEU_printf("Writes to CPU space\n");break; - } - FCEU_printf("Counter prescaler size: %s\n",(IRQMode&4)?"3 bits":"8 bits"); - FCEU_printf("Counter prescaler size adjust: %s\n",(IRQMode&8)?"Used C007":"Normal Operation"); - if((IRQMode>>6)==2) FCEU_printf("Counter Down\n"); - else if((IRQMode>>6)==1) FCEU_printf("Counter Up\n"); - else FCEU_printf("Counter Stopped\n"); -#endif - break; - case 04: -/* FCEU_printf("Pre Counter Loaded and Xored wiht C006: %d\n",V^IRQXOR); */ - IRQPre = V ^ IRQXOR; - break; - case 05: -/* FCEU_printf("Main Counter Loaded and Xored wiht C006: %d\n",V^IRQXOR); */ - IRQCount = V ^ IRQXOR; - break; - case 06: -/* FCEU_printf("Xor Value: %d\n",V); */ - IRQXOR = V; - break; - case 07: -#if 0 - if(!(IRQMode&8)) FCEU_printf("C001 is clear, no effect applied\n"); - else if(V==0xFF) FCEU_printf("Prescaler is changed for 12bits\n"); - else FCEU_printf("Counter Stopped\n"); -#endif - IRQPreSize = V; - break; - } -} - -static DECLFW(M90ModeWrite) { -/* FCEU_printf("bs %04x %02x\n",A,V); */ - tkcom[A & 3] = V; - tekprom(); - tekvrom(); - mira(); - -#ifdef DEBUG90 - switch (A & 3) { - case 00: - FCEU_printf("Main Control Register:\n"); - FCEU_printf(" PGR Banking mode: %d\n", V & 7); - FCEU_printf(" CHR Banking mode: %d\n", (V >> 3) & 3); - FCEU_printf(" 6000-7FFF addresses mapping: %s\n", (V & 0x80) ? "Yes" : "No"); - FCEU_printf(" Nametable control: %s\n", (V & 0x20) ? "Enabled" : "Disabled"); - if (V & 0x20) - FCEU_printf(" Nametable can be: %s\n", (V & 0x40) ? "ROM Only" : "RAM or ROM"); - break; - case 01: - FCEU_printf("Mirroring mode: "); - switch (V & 3) { - case 0: FCEU_printf("Vertical\n"); break; - case 1: FCEU_printf("Horizontal\n"); break; - case 2: FCEU_printf("Nametable 0 only\n"); break; - case 3: FCEU_printf("Nametable 1 only\n"); break; - } - FCEU_printf("Mirroring flag: %s\n", (V & 0x80) ? "On" : "Off"); - break; - case 02: - if ((((tkcom[0]) >> 5) & 3) == 1) - FCEU_printf("Nametable ROM/RAM select mode: %d\n", V >> 7); - break; - case 03: - FCEU_printf("CHR Banking mode: %s\n", (V & 0x20) ? "Entire CHR ROM" : "256Kb Switching mode"); - if (!(V & 0x20)) FCEU_printf("256K CHR bank number: %02x\n", (V & 1) | ((V & 0x18) >> 2)); - FCEU_printf("512K PRG bank number: %d\n", (V & 6) >> 1); - FCEU_printf("CHR Bank mirroring: %s\n", (V & 0x80) ? "Swapped" : "Normal operate"); - } -#endif -} - -static DECLFW(M90DummyWrite) { -/* FCEU_printf("bs %04x %02x\n",A,V); */ -} - -static void CCL(void) { - if ((IRQMode >> 6) == 1) { /* Count Up */ - IRQCount++; - if ((IRQCount == 0) && IRQa) { - X6502_IRQBegin(FCEU_IQEXT); - } - } else if ((IRQMode >> 6) == 2) { /* Count down */ - IRQCount--; - if ((IRQCount == 0xFF) && IRQa) { - X6502_IRQBegin(FCEU_IQEXT); - } - } -} - -static void ClockCounter(void) { - uint8 premask; - - if (IRQMode & 0x4) - premask = 0x7; - else - premask = 0xFF; - if ((IRQMode >> 6) == 1) { /* Count up */ - IRQPre++; - if ((IRQPre & premask) == 0) CCL(); - } else if ((IRQMode >> 6) == 2) { /* Count down */ - IRQPre--; - if ((IRQPre & premask) == premask) CCL(); - } -} - -void FP_FASTAPASS(1) CPUWrap(int a) { - int x; - if ((IRQMode & 3) == 0) for (x = 0; x < a; x++) ClockCounter(); -} - -static void SLWrap(void) { - int x; - if ((IRQMode & 3) == 1) for (x = 0; x < 8; x++) ClockCounter(); -} - -static uint32 lastread; -static void FP_FASTAPASS(1) M90PPU(uint32 A) { - if ((IRQMode & 3) == 2) { - if (lastread != A) { - ClockCounter(); - ClockCounter(); - } - lastread = A; - } - - if (is209) { - uint8 l, h; - h = A >> 8; - if (h < 0x20 && ((h & 0x0F) == 0xF)) { - l = A & 0xF0; - if (l == 0xD0) { - chr[(h & 0x10) >> 4] = ((h & 0x10) >> 2); - tekvrom(); - } else if (l == 0xE0) { - chr[(h & 0x10) >> 4] = ((h & 0x10) >> 2) | 2; - tekvrom(); - } - } - } else { - chr[0] = 0; - chr[1] = 4; - } -} - -static void togglie(void) { - tekker += 0x40; - tekker &= 0xC0; - FCEU_printf("tekker=%02x\n", tekker); - memset(tkcom, 0x00, sizeof(tkcom)); - memset(prgb, 0xff, sizeof(prgb)); - tekprom(); - tekvrom(); -} - -static void M90Restore(int version) { - tekprom(); - tekvrom(); - mira(); -} - -static void M90Power(void) { - SetWriteHandler(0x5000, 0x5fff, M90TekWrite); - SetWriteHandler(0x8000, 0x8ff0, M90PRGWrite); - SetWriteHandler(0x9000, 0x9fff, M90CHRlowWrite); - SetWriteHandler(0xA000, 0xAfff, M90CHRhiWrite); - SetWriteHandler(0xB000, 0xBfff, M90NTWrite); - SetWriteHandler(0xC000, 0xCfff, M90IRQWrite); - SetWriteHandler(0xD000, 0xD5ff, M90ModeWrite); - SetWriteHandler(0xE000, 0xFfff, M90DummyWrite); - - SetReadHandler(0x5000, 0x5fff, M90TekRead); - SetReadHandler(0x6000, 0xffff, CartBR); - - mul[0] = mul[1] = regie = 0xFF; - - memset(tkcom, 0x00, sizeof(tkcom)); - memset(prgb, 0xff, sizeof(prgb)); - memset(chrlow, 0xff, sizeof(chrlow)); - memset(chrhigh, 0xff, sizeof(chrhigh)); - memset(names, 0x00, sizeof(names)); - - if (is211) - tekker = 0xC0; - else - tekker = 0x00; - - tekprom(); - tekvrom(); -} - -void Mapper90_Init(CartInfo *info) { - is211 = 0; - is209 = 0; - is281 = 0; - info->Reset = togglie; - info->Power = M90Power; - PPU_hook = M90PPU; - MapIRQHook = CPUWrap; - GameHBIRQHook2 = SLWrap; - GameStateRestore = M90Restore; - AddExState(Tek_StateRegs, ~0, 0, 0); -} - -void Mapper209_Init(CartInfo *info) { - is211 = 0; - is209 = 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 Mapper211_Init(CartInfo *info) { - 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->Power = M90Power; - PPU_hook = M90PPU; - MapIRQHook = CPUWrap; - GameHBIRQHook2 = SLWrap; - GameStateRestore = M90Restore; - AddExState(Tek_StateRegs, ~0, 0, 0); -} diff --git a/src/boards/bmc13in1jy110.c b/src/boards/bmc13in1jy110.c deleted file mode 100644 index 0f70257..0000000 --- a/src/boards/bmc13in1jy110.c +++ /dev/null @@ -1,99 +0,0 @@ -/* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2005 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 - * - * BMC 42-in-1 "reset switch" type - */ - -#include "mapinc.h" - -static uint8 bank_mode; -static uint8 bank_value; -static uint8 prgb[4]; -static SFORMAT StateRegs[] = -{ - { &bank_mode, 1, "BNM" }, - { &bank_value, 1, "BMV" }, - { prgb, 4, "PRGB" }, - { 0 } -}; - -static void Sync(void) { -/* FCEU_printf("%02x: %02x %02x\n", bank_mode, bank_value, prgb[0]); */ - switch (bank_mode & 7) { - case 0: - setprg32(0x8000, bank_value & 7); break; - case 1: - setprg16(0x8000, ((8 + (bank_value & 7)) >> 1) + prgb[1]); - setprg16(0xC000, (bank_value & 7) >> 1); - break; - case 4: - setprg32(0x8000, 8 + (bank_value & 7)); break; - case 5: - setprg16(0x8000, ((8 + (bank_value & 7)) >> 1) + prgb[1]); - setprg16(0xC000, ((8 + (bank_value & 7)) >> 1) + prgb[3]); - break; - case 2: - setprg8(0x8000, prgb[0] >> 2); - setprg8(0xa000, prgb[1]); - setprg8(0xc000, prgb[2]); - setprg8(0xe000, ~0); - break; - case 3: - setprg8(0x8000, prgb[0]); - setprg8(0xa000, prgb[1]); - setprg8(0xc000, prgb[2]); - setprg8(0xe000, prgb[3]); - break; - } -} - -static DECLFW(BMC13in1JY110Write) { -/* FCEU_printf("%04x:%04x\n",A,V); */ - switch (A) { - case 0x8000: - case 0x8001: - case 0x8002: - case 0x8003: prgb[A & 3] = V; break; - case 0xD000: bank_mode = V; break; - case 0xD001: setmirror(V & 3); - case 0xD002: break; - case 0xD003: bank_value = V; break; - } - Sync(); -} - -static void BMC13in1JY110Power(void) { - prgb[0] = prgb[1] = prgb[2] = prgb[3] = 0; - bank_mode = 0; - bank_value = 0; - setprg32(0x8000, 0); - setchr8(0); - SetWriteHandler(0x8000, 0xFFFF, BMC13in1JY110Write); - SetReadHandler(0x8000, 0xFFFF, CartBR); -} - -static void StateRestore(int version) { - Sync(); -} - -void BMC13in1JY110_Init(CartInfo *info) { - info->Power = BMC13in1JY110Power; - AddExState(&StateRegs, ~0, 0, 0); - GameStateRestore = StateRestore; -} diff --git a/src/boards/jyasic.c b/src/boards/jyasic.c new file mode 100644 index 0000000..174bcc4 --- /dev/null +++ b/src/boards/jyasic.c @@ -0,0 +1,483 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * Copyright (C) 2005 CaH4e3 + * 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 + */ + +#include "mapinc.h" + +void (*sync)(void); +static uint8 allowExtendedMirroring; + +static uint8 mode[4]; +static uint8* WRAM = NULL; +static uint32 WRAMSIZE; + +static uint8 irqControl; +static uint8 irqEnabled; +static uint8 irqPrescaler; +static uint8 irqCounter; +static uint8 irqXor; +static uint32 lastPPUAddress; + +static uint8 prg[4]; +static uint16 chr[8]; +static uint16 nt[4]; +static uint8 latch[2]; +static uint8 mul[2]; +static uint8 adder; +static uint8 test; +static uint8 dipSwitch; + +static writefunc cpuWriteHandlers[0x10000]; // Actual write handlers for CPU write trapping as a method fo IRQ clocking + +static SFORMAT JYASIC_stateRegs[] = { + { &irqControl, 1, "IRQM" }, + { &irqPrescaler, 1, "IRQP" }, + { &irqCounter, 1, "IRQC" }, + { &irqXor, 1, "IRQX" }, + { &irqEnabled, 1, "IRQA" }, + { mul, 2, "MUL" }, + { &test, 1, "REGI" }, + { mode , 4, "TKCO" }, + { prg, 4, "PRGB" }, + { latch, 2, "CLTC" }, + { chr, 8*2, "CHRB" }, + { &nt[0], 2 | FCEUSTATE_RLSB, "NMS0" }, + { &nt[1], 2 | FCEUSTATE_RLSB, "NMS1" }, + { &nt[2], 2 | FCEUSTATE_RLSB, "NMS2" }, + { &nt[3], 2 | FCEUSTATE_RLSB, "NMS3" }, + { &dipSwitch, 1, "TEKR" }, + { &adder, 1, "ADDE" }, + { 0 } +}; + +static uint8 rev (uint8_t val) { + return ((val <<6) &0x40) | ((val <<4) &0x20) | ((val <<2) &0x10) | (val &0x08) | ((val >>2) &0x04) | ((val >>4) &0x02) | ((val >>6) &0x01); +} + +static void syncPRG (int AND, int OR) { + uint8_t prgLast =mode[0] &0x04? prg[3]: 0xFF; + uint8_t prg6000 =0; + switch (mode[0] &0x03) { + case 0: setprg32(0x8000, prgLast &AND >>2 |OR >>2); + prg6000 =prg[3] <<2 |3; + break; + case 1: setprg16(0x8000, prg[1] &AND >>1 |OR >>1); + setprg16(0xC000, prgLast &AND >>1 |OR >>1); + prg6000 =prg[3] <<1 |1; + break; + case 2: setprg8(0x8000, prg[0] &AND |OR); + setprg8(0xA000, prg[1] &AND |OR); + setprg8(0xC000, prg[2] &AND |OR); + setprg8(0xE000, prgLast &AND |OR); + prg6000 =prg[3]; + break; + case 3: setprg8(0x8000, rev(prg[0]) &AND |OR); + setprg8(0xA000, rev(prg[1]) &AND |OR); + setprg8(0xC000, rev(prg[2]) &AND |OR); + setprg8(0xE000, rev( prgLast) &AND |OR); + prg6000 =rev(prg[3]); + break; + } + if (mode[0] &0x80) // Map ROM + setprg8 (0x6000, prg6000 &AND |OR); + else + if (WRAMSIZE) // Otherwise map WRAM if it exists + setprg8r(0x10, 0x6000, 0); +} + +static void syncCHR (int AND, int OR) { + if (mode[3] &0x80 && (mode[0] &0x18) ==0x08) // MMC4 mode[0] with 4 KiB CHR mode[0] + for (int chrBank =0; chrBank <8; chrBank +=4) setchr4(0x400 *chrBank, chr[latch[chrBank /4]&2 | chrBank] &AND >>2 | OR >>2); + else + switch(mode[0] &0x18) { + case 0x00: // 8 KiB CHR mode[0] + setchr8(chr[0] &AND >>3 | OR >>3); + break; + case 0x08: // 4 KiB CHR mode[0] + for (int chrBank =0; chrBank <8; chrBank +=4) setchr4(0x400 *chrBank, chr[chrBank] &AND >>2 | OR >>2); + break; + case 0x10: + for (int chrBank =0; chrBank <8; chrBank +=2) setchr2(0x400 *chrBank, chr[chrBank] &AND >>1 | OR >>1); + break; + case 0x18: + for (int chrBank =0; chrBank <8; chrBank +=1) setchr1(0x400 *chrBank, chr[chrBank] &AND | OR ); + break; + } + PPUCHRRAM =mode[2] &0x40? 0xFF: 0x00; // Write-protect or write-enable CHR-RAM +} + +static void syncNT (int AND, int OR) { + if (mode[0] &0x20 || mode[1] &0x08) { // ROM nametables or extended mirroring + // First, set normal CIRAM pages using extended registers ... + setmirrorw(nt[0] &1, nt[1] &1, nt[2] &1, nt[3] &1); + + if (mode[0] &0x20) for (int ntBank =0; ntBank <4; ntBank++) { // Then replace with ROM nametables if such are generally enabled + int vromHere =(nt[ntBank] &0x80) ^(mode[2] &0x80) |(mode[0] &0x40); // ROM nametables are used either when globally enabled via D000.6 or per-bank via B00x.7 vs. D002.7 + if (vromHere) setntamem(CHRptr[0] +0x400*((nt[ntBank] &AND | OR) & CHRmask1[0]), 0, ntBank); + } + } else + switch (mode[1] &0x03) { // Regularly mirrored CIRAM + case 0: setmirror(MI_V); break; + case 1: setmirror(MI_H); break; + case 2: setmirror(MI_0); break; + case 3: setmirror(MI_1); break; + } +} + +static void clockIRQ (void) { + uint8_t mask =irqControl &0x04? 0x07: 0xFF; + if (irqEnabled) switch (irqControl &0xC0) { + case 0x40: + irqPrescaler =(irqPrescaler &~mask) | (++irqPrescaler &mask); + if ((irqPrescaler &mask) ==0x00 && (irqControl &0x08? irqCounter: ++irqCounter) ==0x00) X6502_IRQBegin(FCEU_IQEXT); + break; + case 0x80: + irqPrescaler =(irqPrescaler &~mask) | (--irqPrescaler &mask); + if ((irqPrescaler &mask) ==mask && (irqControl &0x08? irqCounter: --irqCounter) ==0xFF) X6502_IRQBegin(FCEU_IQEXT); + break; + } +} + +static DECLFW(trapCPUWrite) { + if ((irqControl &0x03) ==0x03) clockIRQ(); // Clock IRQ counter on CPU writes + cpuWriteHandlers[A](A, V); +} + +static void FP_FASTAPASS(1) trapPPUAddressChange (uint32 A) { + if ((irqControl &0x03) ==0x02 && lastPPUAddress !=A) for (int i =0; i <2; i++) clockIRQ(); // Clock IRQ counter on PPU "reads" + if (mode[3] &0x80 && (mode[0] &0x18) ==0x08 && ((A &0x2FF0) ==0xFD0 || (A &0x2FF0) ==0xFE0)) { // If MMC4 mode[0] is enabled, and CHR mode[0] is 4 KiB, and tile FD or FE is being fetched ... + latch[A >>12 &1] =(A >>10 &4) | (A >>4 &2); // ... switch the left or right pattern table's latch to 0 (FD) or 2 (FE), being used as an offset for the CHR register index. + sync(); + } + lastPPUAddress =A; +} + +static void ppuScanline(void) { + if ((irqControl &0x03) ==0x01) for (int i =0; i <8; i++) clockIRQ(); // Clock IRQ counter on A12 rises (eight per scanline). This should be done in trapPPUAddressChange, but would require more accurate PPU emulation for that. +} + +void FP_FASTAPASS(1) cpuCycle(int a) { + if ((irqControl &0x03) ==0x00) while (a--) clockIRQ(); // Clock IRQ counter on M2 cycles +} + +static DECLFR(readALU_DIP) { + if ((A &0x3FF) ==0 && A !=0x5800) // 5000, 5400, 5C00: read solder pad setting + return dipSwitch | X.DB &0x3F; + else + if (A &0x800) switch (A &3) { // 5800-5FFF: read ALU + case 0: return (mul[0] *mul[1]) &0xFF; + case 1: return (mul[0] *mul[1]) >>8; + case 2: return adder; + case 3: return test; + } else // all others + return X.DB; +} + +static DECLFW(writeALU) { + switch (A &3) { + case 0: mul[0] =V; break; + case 1: mul[1] =V; break; + case 2: adder +=V; break; + case 3: test =V; + adder =0; + break; + } +} + +static DECLFW(writePRG) { + prg[A &3] = V; + sync(); +} + +static DECLFW(writeCHRLow) { + chr[A &7] =chr[A &7] &0xFF00 | V; + sync(); +} + +static DECLFW(writeCHRHigh) { + chr[A &7] =chr[A &7] &0x00FF | V <<8; + sync(); +} + +static DECLFW(writeNT) { + if (~A &4) + nt[A &3] =nt[A &3] &0xFF00 | V; + else + nt[A &3] =nt[A &3] &0x00FF | V <<8; + sync(); +} + +static DECLFW(writeIRQ) { + switch (A &7) { + case 0: irqEnabled =!!(V &1); + if (!irqEnabled) { + irqPrescaler =0; + X6502_IRQEnd(FCEU_IQEXT); + } + break; + case 1: irqControl =V; + break; + case 2: irqEnabled =0; + irqPrescaler =0; + X6502_IRQEnd(FCEU_IQEXT); + break; + case 3: irqEnabled =1; + break; + case 4: irqPrescaler =V ^irqXor; + break; + case 5: irqCounter =V ^irqXor; + break; + case 6: irqXor =V; + break; + } +} + +static DECLFW(writeMode) { + switch (A &3) { + case 0: mode[0] =V; + if (!allowExtendedMirroring) mode[0] &=~0x20; + break; + case 1: mode[1] =V; + if (!allowExtendedMirroring) mode[1] &=~0x08; + break; + case 2: mode[2] =V; + break; + case 3: mode[3] =V; + break; + } + sync(); +} + +static void JYASIC_power(void) { + SetWriteHandler(0x5000, 0x5FFF, writeALU); + SetWriteHandler(0x6000, 0x7fff, CartBW); + SetWriteHandler(0x8000, 0x87FF, writePRG); // 8800-8FFF ignored + SetWriteHandler(0x9000, 0x97FF, writeCHRLow); // 9800-9FFF ignored + SetWriteHandler(0xA000, 0xA7FF, writeCHRHigh); // A800-AFFF ignored + SetWriteHandler(0xB000, 0xB7FF, writeNT); // B800-BFFF ignored + SetWriteHandler(0xC000, 0xCFFF, writeIRQ); + SetWriteHandler(0xD000, 0xD7FF, writeMode); // D800-DFFF ignored + + for (unsigned int i =0; i <0x10000; i++) cpuWriteHandlers[i] =GetWriteHandler(i); + SetWriteHandler(0x0000, 0xFFFF, trapCPUWrite); // Trap all CPU writes for IRQ clocking purposes + + SetReadHandler(0x5000, 0x5FFF, readALU_DIP); + SetReadHandler(0x6000, 0xFFFF, CartBR); + + mul[0] = mul[1] = adder = test = dipSwitch = 0; + mode[0] = mode[1] = mode[2] = mode[3] =0; + irqControl =irqEnabled = irqPrescaler =irqCounter = irqXor = lastPPUAddress = 0; + memset(prg, 0, sizeof(prg)); + memset(chr, 0, sizeof(chr)); + memset(nt, 0, sizeof(nt)); + latch[0] =0; + latch[1] =4; + + sync(); +} + +static void JYASIC_reset (void) { + dipSwitch = (dipSwitch +0x40) &0xC0; +} + +static void JYASIC_restore (int version) { + sync(); +} + +void JYASIC_init (CartInfo *info) { + info->Reset = JYASIC_reset; + info->Power = JYASIC_power; + PPU_hook = trapPPUAddressChange; + MapIRQHook = cpuCycle; + GameHBIRQHook2 = ppuScanline; + AddExState(JYASIC_stateRegs, ~0, 0, 0); + GameStateRestore = JYASIC_restore; + + // WRAM is present only in iNES mapper 35, or in mappers with numbers above 255 that require NES 2.0, which explicitly denotes WRAM size + if (info->iNES2) + WRAMSIZE =info->PRGRamSize + info->PRGRamSaveSize; + else + WRAMSIZE =info->mapper ==35? 8192: 0; + + if (WRAMSIZE) { + WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); + } +} + +static void syncSingleCart (void) { + syncPRG(0x3F, mode[3] <<5 &~0x3F); + if (mode[3] &0x20) { + syncCHR(0x1FF, mode[3] <<6 &0x600); + syncNT (0x1FF, mode[3] <<6 &0x600); + } else { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); + } +} +void Mapper35_Init(CartInfo *info) { // Basically mapper 90/209/211 with WRAM + allowExtendedMirroring =1; + sync =syncSingleCart; + JYASIC_init(info); +} +void Mapper90_Init(CartInfo *info) { // Single cart, extended mirroring and ROM nametables disabled + allowExtendedMirroring =0; + sync =syncSingleCart; + JYASIC_init(info); +} +void Mapper209_Init(CartInfo *info) { // Single cart, extended mirroring and ROM nametables enabled + allowExtendedMirroring =1; + sync =syncSingleCart; + JYASIC_init(info); +} +void Mapper211_Init(CartInfo *info) { // Duplicate of mapper 209 + allowExtendedMirroring =1; + sync =syncSingleCart; + JYASIC_init(info); +} + +static void sync281 (void) { + syncPRG(0x1F, mode[3] <<5); + syncCHR(0xFF, mode[3] <<8); + syncNT (0xFF, mode[3] <<8); +} +void Mapper281_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =1; + sync =sync281; + JYASIC_init(info); +} + +static void sync282 (void) { + syncPRG(0x1F, mode[3] <<4 &~0x1F); + if (mode[3] &0x20) { + syncCHR(0x1FF, mode[3] <<6 &0x600); + syncNT (0x1FF, mode[3] <<6 &0x600); + } else { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); + } +} +void Mapper282_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =1; + sync =sync282; + JYASIC_init(info); +} + +void sync295 (void) { + syncPRG(0x0F, mode[3] <<4); + syncCHR(0x7F, mode[3] <<7); + syncNT (0x7F, mode[3] <<7); +} +void Mapper295_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =1; + sync =sync295; + JYASIC_init(info); +} + +void sync358 (void) { + syncPRG(0x1F, mode[3] <<4 &~0x1F); + if (mode[3] &0x20) { + syncCHR(0x1FF, mode[3] <<7 &0x600); + syncNT (0x1FF, mode[3] <<7 &0x600); + } else { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + } +} +void Mapper358_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =1; + sync =sync358; + JYASIC_init(info); +} + +void sync386 (void) { + syncPRG(0x1F, mode[3] <<4 &0x20 | mode[3] <<3 &0x40); + if (mode[3] &0x20) { + syncCHR(0x1FF, mode[3] <<7 &0x600); + syncNT (0x1FF, mode[3] <<7 &0x600); + } else { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + } +} +void Mapper386_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =1; + sync =sync386; + JYASIC_init(info); +} + +void sync387 (void) { + syncPRG(0x0F, mode[3] <<3 &0x10 | mode[3] <<2 &0x20); + if (mode[3] &0x20) { + syncCHR(0x1FF, mode[3] <<7 &0x600); + syncNT (0x1FF, mode[3] <<7 &0x600); + } else { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + } +} +void Mapper387_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =1; + sync =sync387; + JYASIC_init(info); +} + +void sync388 (void) { + syncPRG(0x1F, mode[3] <<3 &0x60); + if (mode[3] &0x20) { + syncCHR(0x1FF, mode[3] <<8 &0x200); + syncNT (0x1FF, mode[3] <<8 &0x200); + } else { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<8 &0x200); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<8 &0x200); + } +} +void Mapper388_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =0; + sync =sync388; + JYASIC_init(info); +} + +void sync397 (void) { + syncPRG(0x1F, mode[3] <<4 &~0x1F); + syncCHR(0x7F, mode[3] <<7); + syncNT (0x7F, mode[3] <<7); +} +void Mapper397_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =1; + sync =sync397; + JYASIC_init(info); +} + +void sync421 (void) { + if (mode[3] &0x04) + syncPRG(0x3F, mode[3] <<4 &~0x3F); + else + syncPRG(0x1F, mode[3] <<4 &~0x1F); + syncCHR(0x1FF, mode[3] <<8 &0x300); + syncNT (0x1FF, mode[3] <<8 &0x300); +} +void Mapper421_Init(CartInfo *info) { // Multicart + allowExtendedMirroring =1; + sync =sync421; + JYASIC_init(info); +} diff --git a/src/boards/sc-127.c b/src/boards/sc-127.c deleted file mode 100644 index 127fcb8..0000000 --- a/src/boards/sc-127.c +++ /dev/null @@ -1,123 +0,0 @@ -/* FCE Ultra - NES/Famicom Emulator - * - * Copyright notice for this file: - * Copyright (C) 2009 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 - * - * Wario Land II (Kirby hack) - */ - -#include "mapinc.h" - -static uint8 reg[8], chr[8]; -static uint8 *WRAM = NULL; -static uint32 WRAMSIZE; -static uint16 IRQCount, IRQa; - -static SFORMAT StateRegs[] = -{ - { reg, 8, "REGS" }, - { chr, 8, "CHRS" }, - { &IRQCount, 2, "IRQc" }, - { &IRQa, 2, "IRQa" }, - { 0 } -}; - -static void Sync(void) { - int i; - setprg8r(0x10, 0x6000, 0); - setprg8(0x8000, reg[0]); - setprg8(0xA000, reg[1]); - setprg8(0xC000, reg[2]); - setprg8(0xE000, ~0); - for (i = 0; i < 8; i++) - setchr1(i << 10, chr[i]); - setmirror(reg[3] ^ 1); -} - -static DECLFW(UNLSC127Write) { - switch (A) { - case 0x8000: reg[0] = V; break; - case 0x8001: reg[1] = V; break; - case 0x8002: reg[2] = V; break; - case 0x9000: chr[0] = V; break; - case 0x9001: chr[1] = V; break; - case 0x9002: chr[2] = V; break; - case 0x9003: chr[3] = V; break; - case 0x9004: chr[4] = V; break; - case 0x9005: chr[5] = V; break; - case 0x9006: chr[6] = V; break; - case 0x9007: chr[7] = V; break; - case 0xC002: IRQa = 0; X6502_IRQEnd(FCEU_IQEXT); break; - case 0xC005: IRQCount = V; break; - case 0xC003: IRQa = 1; break; - case 0xD001: reg[3] = V; break; - } - Sync(); -} - -static DECLFR(UNLSC127ProtRead) { - return 0x20; -} - -static void UNLSC127Power(void) { - IRQCount = IRQa = 0; - Sync(); - SetReadHandler(0x5800, 0x5800, UNLSC127ProtRead); - SetReadHandler(0x6000, 0x7fff, CartBR); - SetWriteHandler(0x6000, 0x7fff, CartBW); - SetReadHandler(0x8000, 0xFFFF, CartBR); - SetWriteHandler(0x8000, 0xFFFF, UNLSC127Write); - FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); -} - -static void UNLSC127IRQ(void) { - if (IRQa) { - if(IRQCount > 0) - IRQCount--; - if (!IRQCount) { - X6502_IRQBegin(FCEU_IQEXT); - IRQa = 0; - } - } -} - -static void UNLSC127Reset(void) { - IRQCount = IRQa = 0; -} - -static void UNLSC127Close(void) { - if (WRAM) - FCEU_gfree(WRAM); - WRAM = NULL; -} - -static void StateRestore(int version) { - Sync(); -} - -void UNLSC127_Init(CartInfo *info) { - info->Reset = UNLSC127Reset; - info->Power = UNLSC127Power; - info->Close = UNLSC127Close; - GameHBIRQHook = UNLSC127IRQ; - GameStateRestore = StateRestore; - WRAMSIZE = 8192; - WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); - SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); - AddExState(WRAM, WRAMSIZE, 0, "WRAM"); - AddExState(&StateRegs, ~0, 0, 0); -} diff --git a/src/ines.c b/src/ines.c index 231b846..316fa5d 100644 --- a/src/ines.c +++ b/src/ines.c @@ -448,7 +448,7 @@ INES_BOARD_BEGIN() INES_BOARD( "IREM G-101", 32, Mapper32_Init ) INES_BOARD( "TC0190FMC/TC0350FMR", 33, Mapper33_Init ) INES_BOARD( "IREM I-IM/BNROM", 34, Mapper34_Init ) - INES_BOARD( "Wario Land 2", 35, UNLSC127_Init ) + INES_BOARD( "EL870914C", 35, Mapper35_Init ) INES_BOARD( "TXC Policeman", 36, Mapper36_Init ) INES_BOARD( "PAL-ZZ SMB/TETRIS/NWC", 37, Mapper37_Init ) INES_BOARD( "Bit Corp.", 38, Mapper38_Init ) /* Crime Busters */ @@ -676,7 +676,8 @@ INES_BOARD_BEGIN() INES_BOARD( "8-in-1 JY-119", 267, Mapper267_Init ) INES_BOARD( "Games Xplosion 121-in-1", 269, Mapper269_Init ) - INES_BOARD( "HUMMER/JY-052", 281, Mapper281_Init ) + INES_BOARD( "YY860417C", 281, Mapper281_Init ) + INES_BOARD( "860224C", 282, Mapper282_Init ) INES_BOARD( "GKCX1", 288, Mapper288_Init ) INES_BOARD( "MMC3 BMC PIRATE", 294, Bs5652_Init ) /* nesdev redirects this as mapper 134 */ INES_BOARD( "TXC 01-22110-000", 297, Mapper297_Init ) @@ -735,7 +736,7 @@ INES_BOARD_BEGIN() INES_BOARD( "60311C", 289, BMC60311C_Init ) INES_BOARD( "NTD-03", 290, BMCNTD03_Init ) INES_BOARD( "DRAGONFIGHTER", 292, UNLBMW8544_Init ) - INES_BOARD( "13in1JY110", 295, BMC13in1JY110_Init ) + INES_BOARD( "YY860216C", 295, Mapper295_Init ) INES_BOARD( "TF1201", 298, UNLTF1201_Init ) INES_BOARD( "11160", 299, BMC11160_Init ) INES_BOARD( "190in1", 300, BMC190in1_Init ) @@ -779,9 +780,15 @@ INES_BOARD_BEGIN() INES_BOARD( "G-146", 349, BMCG146_Init ) INES_BOARD( "891227", 350, BMC891227_Init ) INES_BOARD( "3D-BLOCK", 355, UNL3DBlock_Init ) + INES_BOARD( "YY860606C", 358, Mapper358_Init ) INES_BOARD( "N49C-300", 369, Mapper369_Init ) + INES_BOARD( "YY860729C", 386, Mapper386_Init ) + INES_BOARD( "YY850735C", 387, Mapper387_Init ) + INES_BOARD( "YY850835C", 388, Mapper388_Init ) INES_BOARD( "NC7000M", 391, NC7000M_Init ) + INES_BOARD( "YY850439C", 397, Mapper397_Init ) INES_BOARD( "831019C J-2282", 402, J2282_Init ) + INES_BOARD( "SC871115C", 421, Mapper421_Init ) INES_BOARD( "SA-9602B", 513, SA9602B_Init ) INES_BOARD( "DANCE2000", 518, UNLD2000_Init ) INES_BOARD( "EH8813A", 519, UNLEH8813A_Init ) diff --git a/src/ines.h b/src/ines.h index 99e4756..574a0de 100644 --- a/src/ines.h +++ b/src/ines.h @@ -76,6 +76,7 @@ void Mapper31_Init(CartInfo *); void Mapper32_Init(CartInfo *); void Mapper33_Init(CartInfo *); void Mapper34_Init(CartInfo *); +void Mapper35_Init(CartInfo *); void Mapper36_Init(CartInfo *); void Mapper37_Init(CartInfo *); void Mapper38_Init(CartInfo *); @@ -244,6 +245,8 @@ void Mapper255_Init(CartInfo *); void GN45_Init(CartInfo *info); /* m361, m366 */ void Mapper281_Init(CartInfo *); +void Mapper282_Init(CartInfo *); +void Mapper295_Init(CartInfo *); void Bs5652_Init(CartInfo *); void NC7000M_Init(CartInfo *); @@ -257,6 +260,7 @@ void Mapper297_Init(CartInfo *); void Mapper353_Init(CartInfo *); void Mapper356_Init(CartInfo *); void Mapper357_Init(CartInfo *); +void Mapper358_Init(CartInfo *); void Mapper359_Init(CartInfo *); void Mapper360_Init(CartInfo *); void Mapper369_Init(CartInfo *); @@ -266,11 +270,16 @@ void Mapper374_Init(CartInfo *); void Mapper380_Init(CartInfo *); void Mapper381_Init(CartInfo *); void Mapper382_Init(CartInfo *); +void Mapper386_Init(CartInfo *); +void Mapper387_Init(CartInfo *); +void Mapper388_Init(CartInfo *); void Mapper389_Init(CartInfo *); void Mapper390_Init(CartInfo *); void Mapper395_Init(CartInfo *); +void Mapper397_Init(CartInfo *); void Mapper401_Init(CartInfo *); void Mapper411_Init(CartInfo *); +void Mapper421_Init(CartInfo *); void Mapper422_Init(CartInfo *); void Mapper516_Init(CartInfo *); void Mapper533_Init(CartInfo *); diff --git a/src/unif.c b/src/unif.c index 2d1bfe4..14c3f60 100644 --- a/src/unif.c +++ b/src/unif.c @@ -421,7 +421,7 @@ static void CheckHashInfo(void) { static BMAPPING bmap[] = { { "11160", 299, BMC11160_Init, 0 }, { "12-IN-1", 331, BMC12IN1_Init, 0 }, - { "13in1JY110", 295, BMC13in1JY110_Init, 0 }, + { "13in1JY110", 295, Mapper295_Init, 0 }, { "190in1", 300, BMC190in1_Init, 0 }, { "22211", 132, Mapper132_Init, 0 }, { "3D-BLOCK", 355, UNL3DBlock_Init, 0 }, @@ -510,7 +510,7 @@ static BMAPPING bmap[] = { { "SA-NROM", 143, TCA01_Init, 0 }, { "SAROM", 1, SAROM_Init, 0 }, { "SBROM", 1, SBROM_Init, 0 }, - { "SC-127", 35, UNLSC127_Init, 0 }, + { "SC-127", 35, Mapper35_Init, 0 }, { "SCROM", 1, SCROM_Init, 0 }, { "SEROM", 1, SEROM_Init, 0 }, { "SGROM", 1, SGROM_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 0dbd4ab..4f5517e 100644 --- a/src/unif.h +++ b/src/unif.h @@ -25,7 +25,6 @@ void AC08_Init(CartInfo *info); void ANROM_Init(CartInfo *info); void BMC11160_Init(CartInfo *info); void BMC12IN1_Init(CartInfo *info); -void BMC13in1JY110_Init(CartInfo *info); void BMC190in1_Init(CartInfo *info); void BMC411120C_Init(CartInfo *info); void BMC64in1nr_Init(CartInfo *info); @@ -135,7 +134,6 @@ void UNLN625092_Init(CartInfo *info); void UNLMaliSB_Init(CartInfo *info); void UNLOneBus_Init(CartInfo *info); void UNLPEC586Init(CartInfo *info); -void UNLSC127_Init(CartInfo *info); void UNLSHeroes_Init(CartInfo *info); void UNLSL12_Init(CartInfo *info); void UNLSL1632_Init(CartInfo *info); From d14623a9662378e65a70d5f518c9b4f4ec014817 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Thu, 8 Apr 2021 17:27:41 +0200 Subject: [PATCH 092/295] readALU_DIP already returned a value in every case, but LGTM apparently did not get it. --- src/boards/jyasic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/boards/jyasic.c b/src/boards/jyasic.c index 174bcc4..eb88070 100644 --- a/src/boards/jyasic.c +++ b/src/boards/jyasic.c @@ -187,8 +187,9 @@ static DECLFR(readALU_DIP) { case 1: return (mul[0] *mul[1]) >>8; case 2: return adder; case 3: return test; - } else // all others - return X.DB; + } + // all others + return X.DB; } static DECLFW(writeALU) { From 960528aa153ce4a67a35c58de92a622b13e57ef4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 8 Apr 2021 17:46:51 +0200 Subject: [PATCH 093/295] Style nits, C89 build fixes --- src/boards/jyasic.c | 616 +++++++++++++++++++++++++++----------------- 1 file changed, 381 insertions(+), 235 deletions(-) diff --git a/src/boards/jyasic.c b/src/boards/jyasic.c index eb88070..239d084 100644 --- a/src/boards/jyasic.c +++ b/src/boards/jyasic.c @@ -45,7 +45,7 @@ static uint8 adder; static uint8 test; static uint8 dipSwitch; -static writefunc cpuWriteHandlers[0x10000]; // Actual write handlers for CPU write trapping as a method fo IRQ clocking +static writefunc cpuWriteHandlers[0x10000]; /* Actual write handlers for CPU write trapping as a method fo IRQ clocking */ static SFORMAT JYASIC_stateRegs[] = { { &irqControl, 1, "IRQM" }, @@ -96,50 +96,69 @@ static void syncPRG (int AND, int OR) { prg6000 =rev(prg[3]); break; } - if (mode[0] &0x80) // Map ROM + if (mode[0] &0x80) /* Map ROM */ setprg8 (0x6000, prg6000 &AND |OR); else - if (WRAMSIZE) // Otherwise map WRAM if it exists + if (WRAMSIZE) /* Otherwise map WRAM if it exists */ setprg8r(0x10, 0x6000, 0); } -static void syncCHR (int AND, int OR) { - if (mode[3] &0x80 && (mode[0] &0x18) ==0x08) // MMC4 mode[0] with 4 KiB CHR mode[0] - for (int chrBank =0; chrBank <8; chrBank +=4) setchr4(0x400 *chrBank, chr[latch[chrBank /4]&2 | chrBank] &AND >>2 | OR >>2); - else - switch(mode[0] &0x18) { - case 0x00: // 8 KiB CHR mode[0] - setchr8(chr[0] &AND >>3 | OR >>3); - break; - case 0x08: // 4 KiB CHR mode[0] - for (int chrBank =0; chrBank <8; chrBank +=4) setchr4(0x400 *chrBank, chr[chrBank] &AND >>2 | OR >>2); - break; - case 0x10: - for (int chrBank =0; chrBank <8; chrBank +=2) setchr2(0x400 *chrBank, chr[chrBank] &AND >>1 | OR >>1); - break; - case 0x18: - for (int chrBank =0; chrBank <8; chrBank +=1) setchr1(0x400 *chrBank, chr[chrBank] &AND | OR ); - break; - } - PPUCHRRAM =mode[2] &0x40? 0xFF: 0x00; // Write-protect or write-enable CHR-RAM +static void syncCHR (int AND, int OR) +{ + if (mode[3] &0x80 && (mode[0] &0x18) ==0x08) /* MMC4 mode[0] with 4 KiB CHR mode[0] */ + for (int chrBank =0; chrBank <8; chrBank +=4) setchr4(0x400 *chrBank, chr[latch[chrBank /4]&2 | chrBank] &AND >>2 | OR >>2); + else + switch(mode[0] &0x18) { + case 0x00: /* 8 KiB CHR mode[0] */ + setchr8(chr[0] &AND >>3 | OR >>3); + break; + case 0x08: /* 4 KiB CHR mode[0] */ + for (int chrBank =0; chrBank <8; chrBank +=4) setchr4(0x400 *chrBank, chr[chrBank] &AND >>2 | OR >>2); + break; + case 0x10: + for (int chrBank =0; chrBank <8; chrBank +=2) setchr2(0x400 *chrBank, chr[chrBank] &AND >>1 | OR >>1); + break; + case 0x18: + for (int chrBank =0; chrBank <8; chrBank +=1) setchr1(0x400 *chrBank, chr[chrBank] &AND | OR ); + break; + } + PPUCHRRAM =mode[2] &0x40? 0xFF: 0x00; /* Write-protect or write-enable CHR-RAM */ } -static void syncNT (int AND, int OR) { - if (mode[0] &0x20 || mode[1] &0x08) { // ROM nametables or extended mirroring - // First, set normal CIRAM pages using extended registers ... - setmirrorw(nt[0] &1, nt[1] &1, nt[2] &1, nt[3] &1); - - if (mode[0] &0x20) for (int ntBank =0; ntBank <4; ntBank++) { // Then replace with ROM nametables if such are generally enabled - int vromHere =(nt[ntBank] &0x80) ^(mode[2] &0x80) |(mode[0] &0x40); // ROM nametables are used either when globally enabled via D000.6 or per-bank via B00x.7 vs. D002.7 - if (vromHere) setntamem(CHRptr[0] +0x400*((nt[ntBank] &AND | OR) & CHRmask1[0]), 0, ntBank); - } - } else - switch (mode[1] &0x03) { // Regularly mirrored CIRAM - case 0: setmirror(MI_V); break; - case 1: setmirror(MI_H); break; - case 2: setmirror(MI_0); break; - case 3: setmirror(MI_1); break; - } +static void syncNT (int AND, int OR) +{ + if (mode[0] &0x20 || mode[1] &0x08) + { + /* ROM nametables or extended mirroring */ + /* First, set normal CIRAM pages using extended registers ... */ + setmirrorw(nt[0] &1, nt[1] &1, nt[2] &1, nt[3] &1); + + if (mode[0] &0x20) for (int ntBank =0; ntBank <4; ntBank++) + { + /* Then replace with ROM nametables if such are generally enabled */ + int vromHere =(nt[ntBank] &0x80) ^(mode[2] &0x80) |(mode[0] &0x40); + /* ROM nametables are used either when globally enabled via D000.6 or per-bank via B00x.7 vs. D002.7 */ + if (vromHere) + setntamem(CHRptr[0] +0x400*((nt[ntBank] &AND | OR) & CHRmask1[0]), 0, ntBank); + } + } + else + switch (mode[1] &0x03) + { + /* Regularly mirrored CIRAM */ + case 0: + setmirror(MI_V); + break; + case 1: + setmirror(MI_H); + break; + case 2: + setmirror(MI_0); + break; + case 3: + setmirror(MI_1); + break; + } } static void clockIRQ (void) { @@ -156,51 +175,87 @@ static void clockIRQ (void) { } } -static DECLFW(trapCPUWrite) { - if ((irqControl &0x03) ==0x03) clockIRQ(); // Clock IRQ counter on CPU writes +static DECLFW(trapCPUWrite) +{ + if ((irqControl &0x03) ==0x03) + clockIRQ(); /* Clock IRQ counter on CPU writes */ cpuWriteHandlers[A](A, V); } -static void FP_FASTAPASS(1) trapPPUAddressChange (uint32 A) { - if ((irqControl &0x03) ==0x02 && lastPPUAddress !=A) for (int i =0; i <2; i++) clockIRQ(); // Clock IRQ counter on PPU "reads" - if (mode[3] &0x80 && (mode[0] &0x18) ==0x08 && ((A &0x2FF0) ==0xFD0 || (A &0x2FF0) ==0xFE0)) { // If MMC4 mode[0] is enabled, and CHR mode[0] is 4 KiB, and tile FD or FE is being fetched ... - latch[A >>12 &1] =(A >>10 &4) | (A >>4 &2); // ... switch the left or right pattern table's latch to 0 (FD) or 2 (FE), being used as an offset for the CHR register index. - sync(); - } - lastPPUAddress =A; +static void FP_FASTAPASS(1) trapPPUAddressChange (uint32 A) +{ + if ((irqControl &0x03) ==0x02 && lastPPUAddress !=A) + { + int i; + for (i =0; i <2; i++) + clockIRQ(); /* Clock IRQ counter on PPU "reads" */ + } + if (mode[3] &0x80 && (mode[0] &0x18) ==0x08 && ((A &0x2FF0) ==0xFD0 || (A &0x2FF0) ==0xFE0)) + { + /* If MMC4 mode[0] is enabled, and CHR mode[0] is 4 KiB, and tile FD or FE is being fetched ... */ + latch[A >>12 &1] =(A >>10 &4) | (A >>4 &2); /* ... switch the left or right pattern table's latch to 0 (FD) or 2 (FE), being used as an offset for the CHR register index. */ + sync(); + } + lastPPUAddress =A; } -static void ppuScanline(void) { - if ((irqControl &0x03) ==0x01) for (int i =0; i <8; i++) clockIRQ(); // Clock IRQ counter on A12 rises (eight per scanline). This should be done in trapPPUAddressChange, but would require more accurate PPU emulation for that. +static void ppuScanline(void) +{ + if ((irqControl &0x03) ==0x01) + { + int i; + for (i =0; i <8; i++) + clockIRQ(); /* Clock IRQ counter on A12 rises (eight per scanline). This should be done in trapPPUAddressChange, but would require more accurate PPU emulation for that. */ + } } -void FP_FASTAPASS(1) cpuCycle(int a) { - if ((irqControl &0x03) ==0x00) while (a--) clockIRQ(); // Clock IRQ counter on M2 cycles +void FP_FASTAPASS(1) cpuCycle(int a) +{ + if ((irqControl &0x03) ==0x00) + while (a--) + clockIRQ(); /* Clock IRQ counter on M2 cycles */ } -static DECLFR(readALU_DIP) { - if ((A &0x3FF) ==0 && A !=0x5800) // 5000, 5400, 5C00: read solder pad setting - return dipSwitch | X.DB &0x3F; - else - if (A &0x800) switch (A &3) { // 5800-5FFF: read ALU - case 0: return (mul[0] *mul[1]) &0xFF; - case 1: return (mul[0] *mul[1]) >>8; - case 2: return adder; - case 3: return test; - } - // all others - return X.DB; +static DECLFR(readALU_DIP) +{ + if ((A &0x3FF) ==0 && A !=0x5800) /* 5000, 5400, 5C00: read solder pad setting */ + return dipSwitch | X.DB &0x3F; + + if (A &0x800) + switch (A &3) + { + /* 5800-5FFF: read ALU */ + case 0: + return (mul[0] *mul[1]) &0xFF; + case 1: + return (mul[0] *mul[1]) >>8; + case 2: + return adder; + case 3: + return test; + } + /* all others */ + return X.DB; } -static DECLFW(writeALU) { - switch (A &3) { - case 0: mul[0] =V; break; - case 1: mul[1] =V; break; - case 2: adder +=V; break; - case 3: test =V; - adder =0; - break; - } +static DECLFW(writeALU) +{ + switch (A &3) + { + case 0: + mul[0] =V; + break; + case 1: + mul[1] =V; + break; + case 2: + adder +=V; + break; + case 3: + test = V; + adder = 0; + break; + } } static DECLFW(writePRG) { @@ -226,258 +281,349 @@ static DECLFW(writeNT) { sync(); } -static DECLFW(writeIRQ) { - switch (A &7) { - case 0: irqEnabled =!!(V &1); - if (!irqEnabled) { - irqPrescaler =0; - X6502_IRQEnd(FCEU_IQEXT); - } - break; - case 1: irqControl =V; - break; - case 2: irqEnabled =0; - irqPrescaler =0; - X6502_IRQEnd(FCEU_IQEXT); - break; - case 3: irqEnabled =1; - break; - case 4: irqPrescaler =V ^irqXor; - break; - case 5: irqCounter =V ^irqXor; - break; - case 6: irqXor =V; - break; - } +static DECLFW(writeIRQ) +{ + switch (A &7) + { + case 0: + irqEnabled =!!(V &1); + if (!irqEnabled) + { + irqPrescaler =0; + X6502_IRQEnd(FCEU_IQEXT); + } + break; + case 1: + irqControl =V; + break; + case 2: + irqEnabled =0; + irqPrescaler =0; + X6502_IRQEnd(FCEU_IQEXT); + break; + case 3: + irqEnabled =1; + break; + case 4: + irqPrescaler =V ^irqXor; + break; + case 5: + irqCounter =V ^irqXor; + break; + case 6: + irqXor =V; + break; + } } -static DECLFW(writeMode) { - switch (A &3) { - case 0: mode[0] =V; - if (!allowExtendedMirroring) mode[0] &=~0x20; - break; - case 1: mode[1] =V; - if (!allowExtendedMirroring) mode[1] &=~0x08; - break; - case 2: mode[2] =V; - break; - case 3: mode[3] =V; - break; - } +static DECLFW(writeMode) +{ + switch (A &3) + { + case 0: + mode[0] =V; + if (!allowExtendedMirroring) + mode[0] &=~0x20; + break; + case 1: + mode[1] =V; + if (!allowExtendedMirroring) + mode[1] &=~0x08; + break; + case 2: + mode[2] =V; + break; + case 3: + mode[3] =V; + break; + } sync(); } -static void JYASIC_power(void) { - SetWriteHandler(0x5000, 0x5FFF, writeALU); - SetWriteHandler(0x6000, 0x7fff, CartBW); - SetWriteHandler(0x8000, 0x87FF, writePRG); // 8800-8FFF ignored - SetWriteHandler(0x9000, 0x97FF, writeCHRLow); // 9800-9FFF ignored - SetWriteHandler(0xA000, 0xA7FF, writeCHRHigh); // A800-AFFF ignored - SetWriteHandler(0xB000, 0xB7FF, writeNT); // B800-BFFF ignored - SetWriteHandler(0xC000, 0xCFFF, writeIRQ); - SetWriteHandler(0xD000, 0xD7FF, writeMode); // D800-DFFF ignored - - for (unsigned int i =0; i <0x10000; i++) cpuWriteHandlers[i] =GetWriteHandler(i); - SetWriteHandler(0x0000, 0xFFFF, trapCPUWrite); // Trap all CPU writes for IRQ clocking purposes +static void JYASIC_power(void) +{ + unsigned int i; - SetReadHandler(0x5000, 0x5FFF, readALU_DIP); - SetReadHandler(0x6000, 0xFFFF, CartBR); + SetWriteHandler(0x5000, 0x5FFF, writeALU); + SetWriteHandler(0x6000, 0x7fff, CartBW); + SetWriteHandler(0x8000, 0x87FF, writePRG); /* 8800-8FFF ignored */ + SetWriteHandler(0x9000, 0x97FF, writeCHRLow); /* 9800-9FFF ignored */ + SetWriteHandler(0xA000, 0xA7FF, writeCHRHigh); /* A800-AFFF ignored */ + SetWriteHandler(0xB000, 0xB7FF, writeNT); /* B800-BFFF ignored */ + SetWriteHandler(0xC000, 0xCFFF, writeIRQ); + SetWriteHandler(0xD000, 0xD7FF, writeMode); /* D800-DFFF ignored */ - mul[0] = mul[1] = adder = test = dipSwitch = 0; - mode[0] = mode[1] = mode[2] = mode[3] =0; - irqControl =irqEnabled = irqPrescaler =irqCounter = irqXor = lastPPUAddress = 0; - memset(prg, 0, sizeof(prg)); - memset(chr, 0, sizeof(chr)); - memset(nt, 0, sizeof(nt)); - latch[0] =0; - latch[1] =4; - - sync(); + for (i =0; i <0x10000; i++) cpuWriteHandlers[i] =GetWriteHandler(i); + SetWriteHandler(0x0000, 0xFFFF, trapCPUWrite); /* Trap all CPU writes for IRQ clocking purposes */ + + SetReadHandler(0x5000, 0x5FFF, readALU_DIP); + SetReadHandler(0x6000, 0xFFFF, CartBR); + + mul[0] = mul[1] = adder = test = dipSwitch = 0; + mode[0] = mode[1] = mode[2] = mode[3] = 0; + irqControl =irqEnabled = irqPrescaler =irqCounter = irqXor = lastPPUAddress = 0; + memset(prg, 0, sizeof(prg)); + memset(chr, 0, sizeof(chr)); + memset(nt, 0, sizeof(nt)); + latch[0] =0; + latch[1] =4; + + sync(); } -static void JYASIC_reset (void) { +static void JYASIC_reset (void) +{ dipSwitch = (dipSwitch +0x40) &0xC0; } -static void JYASIC_restore (int version) { +static void JYASIC_restore (int version) +{ sync(); } -void JYASIC_init (CartInfo *info) { - info->Reset = JYASIC_reset; - info->Power = JYASIC_power; - PPU_hook = trapPPUAddressChange; - MapIRQHook = cpuCycle; - GameHBIRQHook2 = ppuScanline; - AddExState(JYASIC_stateRegs, ~0, 0, 0); - GameStateRestore = JYASIC_restore; +void JYASIC_init (CartInfo *info) +{ + info->Reset = JYASIC_reset; + info->Power = JYASIC_power; + PPU_hook = trapPPUAddressChange; + MapIRQHook = cpuCycle; + GameHBIRQHook2 = ppuScanline; + AddExState(JYASIC_stateRegs, ~0, 0, 0); + GameStateRestore = JYASIC_restore; - // WRAM is present only in iNES mapper 35, or in mappers with numbers above 255 that require NES 2.0, which explicitly denotes WRAM size - if (info->iNES2) - WRAMSIZE =info->PRGRamSize + info->PRGRamSaveSize; - else - WRAMSIZE =info->mapper ==35? 8192: 0; + /* WRAM is present only in iNES mapper 35, or in mappers with numbers above 255 that require NES 2.0, which explicitly denotes WRAM size */ + if (info->iNES2) + WRAMSIZE =info->PRGRamSize + info->PRGRamSaveSize; + else + WRAMSIZE =info->mapper ==35? 8192: 0; - if (WRAMSIZE) { - WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); - SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); - FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); - } + if (WRAMSIZE) + { + WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); + } } -static void syncSingleCart (void) { - syncPRG(0x3F, mode[3] <<5 &~0x3F); - if (mode[3] &0x20) { - syncCHR(0x1FF, mode[3] <<6 &0x600); - syncNT (0x1FF, mode[3] <<6 &0x600); - } else { - syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); - syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); - } +static void syncSingleCart (void) +{ + syncPRG(0x3F, mode[3] <<5 &~0x3F); + if (mode[3] &0x20) + { + syncCHR(0x1FF, mode[3] <<6 &0x600); + syncNT (0x1FF, mode[3] <<6 &0x600); + } + else + { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); + } } -void Mapper35_Init(CartInfo *info) { // Basically mapper 90/209/211 with WRAM +void Mapper35_Init(CartInfo *info) +{ + /* Basically mapper 90/209/211 with WRAM */ allowExtendedMirroring =1; sync =syncSingleCart; JYASIC_init(info); } -void Mapper90_Init(CartInfo *info) { // Single cart, extended mirroring and ROM nametables disabled +void Mapper90_Init(CartInfo *info) +{ + /* Single cart, extended mirroring and ROM nametables disabled */ allowExtendedMirroring =0; sync =syncSingleCart; JYASIC_init(info); } -void Mapper209_Init(CartInfo *info) { // Single cart, extended mirroring and ROM nametables enabled - allowExtendedMirroring =1; - sync =syncSingleCart; - JYASIC_init(info); -} -void Mapper211_Init(CartInfo *info) { // Duplicate of mapper 209 + +void Mapper209_Init(CartInfo *info) +{ + /* Single cart, extended mirroring and ROM nametables enabled */ allowExtendedMirroring =1; sync =syncSingleCart; JYASIC_init(info); } -static void sync281 (void) { - syncPRG(0x1F, mode[3] <<5); - syncCHR(0xFF, mode[3] <<8); - syncNT (0xFF, mode[3] <<8); +void Mapper211_Init(CartInfo *info) +{ + /* Duplicate of mapper 209 */ + allowExtendedMirroring =1; + sync =syncSingleCart; + JYASIC_init(info); } -void Mapper281_Init(CartInfo *info) { // Multicart + +static void sync281 (void) +{ + syncPRG(0x1F, mode[3] <<5); + syncCHR(0xFF, mode[3] <<8); + syncNT (0xFF, mode[3] <<8); +} + +void Mapper281_Init(CartInfo *info) +{ + /* Multicart */ allowExtendedMirroring =1; sync =sync281; JYASIC_init(info); } -static void sync282 (void) { +static void sync282 (void) +{ syncPRG(0x1F, mode[3] <<4 &~0x1F); - if (mode[3] &0x20) { + if (mode[3] &0x20) + { syncCHR(0x1FF, mode[3] <<6 &0x600); syncNT (0x1FF, mode[3] <<6 &0x600); - } else { + } + else + { syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<6 &0x600); } } -void Mapper282_Init(CartInfo *info) { // Multicart + +void Mapper282_Init(CartInfo *info) +{ + /* Multicart */ allowExtendedMirroring =1; sync =sync282; JYASIC_init(info); } -void sync295 (void) { - syncPRG(0x0F, mode[3] <<4); - syncCHR(0x7F, mode[3] <<7); - syncNT (0x7F, mode[3] <<7); +void sync295 (void) +{ + syncPRG(0x0F, mode[3] <<4); + syncCHR(0x7F, mode[3] <<7); + syncNT (0x7F, mode[3] <<7); } -void Mapper295_Init(CartInfo *info) { // Multicart + +void Mapper295_Init(CartInfo *info) +{ + /* Multicart */ allowExtendedMirroring =1; sync =sync295; JYASIC_init(info); } -void sync358 (void) { - syncPRG(0x1F, mode[3] <<4 &~0x1F); - if (mode[3] &0x20) { - syncCHR(0x1FF, mode[3] <<7 &0x600); - syncNT (0x1FF, mode[3] <<7 &0x600); - } else { - syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); - syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); - } +void sync358 (void) +{ + syncPRG(0x1F, mode[3] <<4 &~0x1F); + if (mode[3] &0x20) + { + syncCHR(0x1FF, mode[3] <<7 &0x600); + syncNT (0x1FF, mode[3] <<7 &0x600); + } + else + { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + } } -void Mapper358_Init(CartInfo *info) { // Multicart + +void Mapper358_Init(CartInfo *info) +{ + /* Multicart */ allowExtendedMirroring =1; sync =sync358; JYASIC_init(info); } -void sync386 (void) { - syncPRG(0x1F, mode[3] <<4 &0x20 | mode[3] <<3 &0x40); - if (mode[3] &0x20) { - syncCHR(0x1FF, mode[3] <<7 &0x600); - syncNT (0x1FF, mode[3] <<7 &0x600); - } else { - syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); - syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); - } +void sync386 (void) +{ + syncPRG(0x1F, mode[3] <<4 &0x20 | mode[3] <<3 &0x40); + if (mode[3] &0x20) + { + syncCHR(0x1FF, mode[3] <<7 &0x600); + syncNT (0x1FF, mode[3] <<7 &0x600); + } + else + { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); + } } -void Mapper386_Init(CartInfo *info) { // Multicart + +void Mapper386_Init(CartInfo *info) +{ + /* Multicart */ allowExtendedMirroring =1; sync =sync386; JYASIC_init(info); } -void sync387 (void) { +void sync387(void) +{ syncPRG(0x0F, mode[3] <<3 &0x10 | mode[3] <<2 &0x20); - if (mode[3] &0x20) { - syncCHR(0x1FF, mode[3] <<7 &0x600); - syncNT (0x1FF, mode[3] <<7 &0x600); - } else { + if (mode[3] &0x20) + { + syncCHR(0x1FF, mode[3] <<7 &0x600); + syncNT (0x1FF, mode[3] <<7 &0x600); + } + else + { syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<7 &0x600); } } -void Mapper387_Init(CartInfo *info) { // Multicart - allowExtendedMirroring =1; - sync =sync387; - JYASIC_init(info); + +void Mapper387_Init(CartInfo *info) +{ + /* Multicart */ + allowExtendedMirroring =1; + sync =sync387; + JYASIC_init(info); } -void sync388 (void) { - syncPRG(0x1F, mode[3] <<3 &0x60); - if (mode[3] &0x20) { - syncCHR(0x1FF, mode[3] <<8 &0x200); - syncNT (0x1FF, mode[3] <<8 &0x200); - } else { - syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<8 &0x200); - syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<8 &0x200); - } +void sync388 (void) +{ + syncPRG(0x1F, mode[3] <<3 &0x60); + + if (mode[3] &0x20) + { + syncCHR(0x1FF, mode[3] <<8 &0x200); + syncNT (0x1FF, mode[3] <<8 &0x200); + } + else + { + syncCHR(0x0FF, mode[3] <<8 &0x100 | mode[3] <<8 &0x200); + syncNT (0x0FF, mode[3] <<8 &0x100 | mode[3] <<8 &0x200); + } } -void Mapper388_Init(CartInfo *info) { // Multicart + +void Mapper388_Init(CartInfo *info) +{ + /* Multicart */ allowExtendedMirroring =0; sync =sync388; JYASIC_init(info); } -void sync397 (void) { +void sync397 (void) +{ syncPRG(0x1F, mode[3] <<4 &~0x1F); syncCHR(0x7F, mode[3] <<7); syncNT (0x7F, mode[3] <<7); } -void Mapper397_Init(CartInfo *info) { // Multicart - allowExtendedMirroring =1; - sync =sync397; - JYASIC_init(info); + +void Mapper397_Init(CartInfo *info) +{ + /* Multicart */ + allowExtendedMirroring =1; + sync =sync397; + JYASIC_init(info); } -void sync421 (void) { - if (mode[3] &0x04) - syncPRG(0x3F, mode[3] <<4 &~0x3F); - else - syncPRG(0x1F, mode[3] <<4 &~0x1F); - syncCHR(0x1FF, mode[3] <<8 &0x300); - syncNT (0x1FF, mode[3] <<8 &0x300); +void sync421 (void) +{ + if (mode[3] &0x04) + syncPRG(0x3F, mode[3] <<4 &~0x3F); + else + syncPRG(0x1F, mode[3] <<4 &~0x1F); + syncCHR(0x1FF, mode[3] <<8 &0x300); + syncNT (0x1FF, mode[3] <<8 &0x300); } -void Mapper421_Init(CartInfo *info) { // Multicart + +void Mapper421_Init(CartInfo *info) +{ + /* Multicart */ allowExtendedMirroring =1; sync =sync421; JYASIC_init(info); From cb9ea8f94ebf6c662152f6c1ea110612d3530da8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 8 Apr 2021 17:50:56 +0200 Subject: [PATCH 094/295] More C89 build fixes - for loop initial declarations --- src/boards/jyasic.c | 139 +++++++++++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 53 deletions(-) diff --git a/src/boards/jyasic.c b/src/boards/jyasic.c index 239d084..353b54c 100644 --- a/src/boards/jyasic.c +++ b/src/boards/jyasic.c @@ -68,61 +68,81 @@ static SFORMAT JYASIC_stateRegs[] = { { 0 } }; -static uint8 rev (uint8_t val) { +static uint8 rev (uint8_t val) +{ return ((val <<6) &0x40) | ((val <<4) &0x20) | ((val <<2) &0x10) | (val &0x08) | ((val >>2) &0x04) | ((val >>4) &0x02) | ((val >>6) &0x01); } -static void syncPRG (int AND, int OR) { +static void syncPRG (int AND, int OR) +{ uint8_t prgLast =mode[0] &0x04? prg[3]: 0xFF; uint8_t prg6000 =0; - switch (mode[0] &0x03) { - case 0: setprg32(0x8000, prgLast &AND >>2 |OR >>2); - prg6000 =prg[3] <<2 |3; - break; - case 1: setprg16(0x8000, prg[1] &AND >>1 |OR >>1); - setprg16(0xC000, prgLast &AND >>1 |OR >>1); - prg6000 =prg[3] <<1 |1; - break; - case 2: setprg8(0x8000, prg[0] &AND |OR); - setprg8(0xA000, prg[1] &AND |OR); - setprg8(0xC000, prg[2] &AND |OR); - setprg8(0xE000, prgLast &AND |OR); - prg6000 =prg[3]; - break; - case 3: setprg8(0x8000, rev(prg[0]) &AND |OR); - setprg8(0xA000, rev(prg[1]) &AND |OR); - setprg8(0xC000, rev(prg[2]) &AND |OR); - setprg8(0xE000, rev( prgLast) &AND |OR); - prg6000 =rev(prg[3]); - break; - } + switch (mode[0] &0x03) + { + case 0: + setprg32(0x8000, prgLast &AND >>2 |OR >>2); + prg6000 =prg[3] <<2 |3; + break; + case 1: + setprg16(0x8000, prg[1] &AND >>1 |OR >>1); + setprg16(0xC000, prgLast &AND >>1 |OR >>1); + prg6000 =prg[3] <<1 |1; + break; + case 2: + setprg8(0x8000, prg[0] &AND |OR); + setprg8(0xA000, prg[1] &AND |OR); + setprg8(0xC000, prg[2] &AND |OR); + setprg8(0xE000, prgLast &AND |OR); + prg6000 =prg[3]; + break; + case 3: + setprg8(0x8000, rev(prg[0]) &AND |OR); + setprg8(0xA000, rev(prg[1]) &AND |OR); + setprg8(0xC000, rev(prg[2]) &AND |OR); + setprg8(0xE000, rev( prgLast) &AND |OR); + prg6000 =rev(prg[3]); + break; + } if (mode[0] &0x80) /* Map ROM */ setprg8 (0x6000, prg6000 &AND |OR); else - if (WRAMSIZE) /* Otherwise map WRAM if it exists */ - setprg8r(0x10, 0x6000, 0); + if (WRAMSIZE) /* Otherwise map WRAM if it exists */ + setprg8r(0x10, 0x6000, 0); } static void syncCHR (int AND, int OR) { - if (mode[3] &0x80 && (mode[0] &0x18) ==0x08) /* MMC4 mode[0] with 4 KiB CHR mode[0] */ - for (int chrBank =0; chrBank <8; chrBank +=4) setchr4(0x400 *chrBank, chr[latch[chrBank /4]&2 | chrBank] &AND >>2 | OR >>2); + /* MMC4 mode[0] with 4 KiB CHR mode[0] */ + if (mode[3] &0x80 && (mode[0] &0x18) ==0x08) + { + int chrBank; + for (chrBank =0; chrBank <8; chrBank +=4) + setchr4(0x400 *chrBank, chr[latch[chrBank /4]&2 | chrBank] &AND >>2 | OR >>2); + } else - switch(mode[0] &0x18) { + { + int chrBank; + switch(mode[0] &0x18) + { case 0x00: /* 8 KiB CHR mode[0] */ setchr8(chr[0] &AND >>3 | OR >>3); break; case 0x08: /* 4 KiB CHR mode[0] */ - for (int chrBank =0; chrBank <8; chrBank +=4) setchr4(0x400 *chrBank, chr[chrBank] &AND >>2 | OR >>2); + for (chrBank =0; chrBank <8; chrBank +=4) + setchr4(0x400 *chrBank, chr[chrBank] &AND >>2 | OR >>2); break; case 0x10: - for (int chrBank =0; chrBank <8; chrBank +=2) setchr2(0x400 *chrBank, chr[chrBank] &AND >>1 | OR >>1); + for (chrBank =0; chrBank <8; chrBank +=2) + setchr2(0x400 *chrBank, chr[chrBank] &AND >>1 | OR >>1); break; case 0x18: - for (int chrBank =0; chrBank <8; chrBank +=1) setchr1(0x400 *chrBank, chr[chrBank] &AND | OR ); + for (chrBank =0; chrBank <8; chrBank +=1) + setchr1(0x400 *chrBank, chr[chrBank] &AND | OR ); break; } - PPUCHRRAM =mode[2] &0x40? 0xFF: 0x00; /* Write-protect or write-enable CHR-RAM */ + } + + PPUCHRRAM = (mode[2] & 0x40) ? 0xFF: 0x00; /* Write-protect or write-enable CHR-RAM */ } static void syncNT (int AND, int OR) @@ -133,13 +153,17 @@ static void syncNT (int AND, int OR) /* First, set normal CIRAM pages using extended registers ... */ setmirrorw(nt[0] &1, nt[1] &1, nt[2] &1, nt[3] &1); - if (mode[0] &0x20) for (int ntBank =0; ntBank <4; ntBank++) + if (mode[0] &0x20) { - /* Then replace with ROM nametables if such are generally enabled */ - int vromHere =(nt[ntBank] &0x80) ^(mode[2] &0x80) |(mode[0] &0x40); - /* ROM nametables are used either when globally enabled via D000.6 or per-bank via B00x.7 vs. D002.7 */ - if (vromHere) - setntamem(CHRptr[0] +0x400*((nt[ntBank] &AND | OR) & CHRmask1[0]), 0, ntBank); + int ntBank; + for (ntBank =0; ntBank <4; ntBank++) + { + /* Then replace with ROM nametables if such are generally enabled */ + int vromHere =(nt[ntBank] &0x80) ^(mode[2] &0x80) |(mode[0] &0x40); + /* ROM nametables are used either when globally enabled via D000.6 or per-bank via B00x.7 vs. D002.7 */ + if (vromHere) + setntamem(CHRptr[0] +0x400*((nt[ntBank] &AND | OR) & CHRmask1[0]), 0, ntBank); + } } } else @@ -161,18 +185,23 @@ static void syncNT (int AND, int OR) } } -static void clockIRQ (void) { +static void clockIRQ (void) +{ uint8_t mask =irqControl &0x04? 0x07: 0xFF; - if (irqEnabled) switch (irqControl &0xC0) { - case 0x40: - irqPrescaler =(irqPrescaler &~mask) | (++irqPrescaler &mask); - if ((irqPrescaler &mask) ==0x00 && (irqControl &0x08? irqCounter: ++irqCounter) ==0x00) X6502_IRQBegin(FCEU_IQEXT); - break; - case 0x80: - irqPrescaler =(irqPrescaler &~mask) | (--irqPrescaler &mask); - if ((irqPrescaler &mask) ==mask && (irqControl &0x08? irqCounter: --irqCounter) ==0xFF) X6502_IRQBegin(FCEU_IQEXT); - break; - } + if (irqEnabled) + switch (irqControl &0xC0) + { + case 0x40: + irqPrescaler =(irqPrescaler &~mask) | (++irqPrescaler &mask); + if ((irqPrescaler &mask) ==0x00 && (irqControl &0x08? irqCounter: ++irqCounter) ==0x00) + X6502_IRQBegin(FCEU_IQEXT); + break; + case 0x80: + irqPrescaler =(irqPrescaler &~mask) | (--irqPrescaler &mask); + if ((irqPrescaler &mask) ==mask && (irqControl &0x08? irqCounter: --irqCounter) ==0xFF) + X6502_IRQBegin(FCEU_IQEXT); + break; + } } static DECLFW(trapCPUWrite) @@ -258,22 +287,26 @@ static DECLFW(writeALU) } } -static DECLFW(writePRG) { +static DECLFW(writePRG) +{ prg[A &3] = V; sync(); } -static DECLFW(writeCHRLow) { +static DECLFW(writeCHRLow) +{ chr[A &7] =chr[A &7] &0xFF00 | V; sync(); } -static DECLFW(writeCHRHigh) { +static DECLFW(writeCHRHigh) +{ chr[A &7] =chr[A &7] &0x00FF | V <<8; sync(); } -static DECLFW(writeNT) { +static DECLFW(writeNT) +{ if (~A &4) nt[A &3] =nt[A &3] &0xFF00 | V; else From 336cac1a4408cd045bcdf845fb77de59bd7cda91 Mon Sep 17 00:00:00 2001 From: crystalct Date: Fri, 9 Apr 2021 13:57:06 +0200 Subject: [PATCH 095/295] Update PSL1GHT platform (#437) * Add PSL1GHT platform * Update PS1GHT platform --- Makefile.libretro | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index fda55d5..22df238 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -249,14 +249,21 @@ else ifeq ($(platform), rpi4) CFLAGS += -fomit-frame-pointer -fstrict-aliasing -ffast-math # Lightweight PS3 Homebrew SDK -else ifeq ($(platform), psl1ght) - TARGET := $(TARGET_NAME)_libretro_$(platform).a - CC = $(PS3DEV)/ppu/bin/ppu-gcc$(EXE_EXT) - AR = $(PS3DEV)/ppu/bin/ppu-ar$(EXE_EXT) - PLATFORM_DEFINES := -D__PSL1GHT__ - ENDIANNESS_DEFINES += -DMSB_FIRST - STATIC_LINKING=1 - EXTERNAL_ZLIB=1 +else ifneq (,$(filter $(platform), ps3 psl1ght)) + ENDIANNESS_DEFINES = -DWORDS_BIGENDIAN + EXTERNAL_ZLIB = 1 + STATIC_LINKING = 1 + + ifneq ($(platdef),) + PLATFORM_DEFINES += -D$(platdef) + else + PLATFORM_DEFINES += -D__PSL1GHT__ + endif + + TARGET := $(TARGET_NAME)_libretro_$(platform).a + CC = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)gcc$(EXE_EXT) + CXX = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)g++$(EXE_EXT) + AR = $(PS3DEV)/ppu/bin/ppu-$(COMMONLV)ar$(EXE_EXT) # Xbox 360 else ifeq ($(platform), xenon) From 491975cf97631218b19ceabb5d156bbdf4edf974 Mon Sep 17 00:00:00 2001 From: negativeExponent <54053706+negativeExponent@users.noreply.github.com> Date: Fri, 9 Apr 2021 20:28:15 +0800 Subject: [PATCH 096/295] C89 fixes --- src/boards/super40in1.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/boards/super40in1.c b/src/boards/super40in1.c index 3de6804..7d954be 100644 --- a/src/boards/super40in1.c +++ b/src/boards/super40in1.c @@ -35,17 +35,18 @@ static SFORMAT StateRegs[] = }; static void Sync(void) { - int prg = (preg & 7) | ((preg >> 3) & 0x08); // There is a high bit 3 of the PRG register that applies both to PRG and CHR + int prg = (preg & 7) | ((preg >> 3) & 0x08); /* There is a high bit 3 of the PRG register that applies both to PRG and CHR */ + int chr = (creg & 7) | ((preg >> 3) & 0x08); /* There is a high bit 3 of the PRG register that applies both to PRG and CHR */ + int mask = (creg & 0x10)? 0: (creg & 0x20)? 1: 3; /* There is an CNROM mode that takes either two or four inner CHR banks from a CNROM-like latch register at $8000-$FFFF. */ + if (preg & 8) { setprg16(0x8000, prg); setprg16(0xc000, prg); } else setprg32(0x8000, prg >> 1); - - int chr = (creg & 7) | ((preg >> 3) & 0x08); // There is a high bit 3 of the PRG register that applies both to PRG and CHR - int mask = (creg & 0x10)? 0: (creg & 0x20)? 1: 3; // There is an CNROM mode that takes either two or four inner CHR banks from a CNROM-like latch register at $8000-$FFFF. - setchr8((chr &~mask) | (latch &mask)); // This "inner CHR bank" substitutes the respective bit(s) of the creg register. + + setchr8((chr &~mask) | (latch &mask)); /* This "inner CHR bank" substitutes the respective bit(s) of the creg register. */ setmirror(((preg >> 4) & 1) ^ 1); } @@ -53,8 +54,7 @@ static void Sync(void) { static DECLFR(BMCWSRead) { if ((creg >> 6) & (dipSwitch &3)) return X.DB; - else - return CartBR(A); + return CartBR(A); } static DECLFW(BMCWSWrite) { @@ -81,10 +81,11 @@ static void MBMCWSPower(void) { } static void BMCWSReset(void) { - dipSwitch++; // Soft-resetting cycles through solder pad or DIP switch settings - if (dipSwitch == 3) dipSwitch = 0; // Only 00b, 01b and 10b settings are valid + dipSwitch++; /* Soft-resetting cycles through solder pad or DIP switch settings */ + if (dipSwitch == 3) + dipSwitch = 0; /* Only 00b, 01b and 10b settings are valid */ - // Always reset to menu + /* Always reset to menu */ preg =0; creg =0; latch =0; From 50b90240808f731de8881a7cee6bfea01a61a9bc Mon Sep 17 00:00:00 2001 From: negativeExponent <54053706+negativeExponent@users.noreply.github.com> Date: Sat, 10 Apr 2021 02:21:29 +0800 Subject: [PATCH 097/295] more C89 fixes --- src/boards/126-422-534.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/boards/126-422-534.c b/src/boards/126-422-534.c index e8d6610..1b81963 100644 --- a/src/boards/126-422-534.c +++ b/src/boards/126-422-534.c @@ -31,48 +31,48 @@ static uint8 invertC000; static uint8 dipSwitch; static void wrapPRG(uint32 A, uint8 V) { - int prgAND = EXPREGS[0] &0x40? 0x0F: 0x1F; // 128 KiB or 256 KiB inner PRG bank selection - int prgOR =(EXPREGS[0] <<4 &0x70 | EXPREGS[0] <<3 &0x180) &~prgAND; // outer PRG bank + int prgAND = EXPREGS[0] &0x40? 0x0F: 0x1F; /* 128 KiB or 256 KiB inner PRG bank selection */ + int prgOR =(EXPREGS[0] <<4 &0x70 | EXPREGS[0] <<3 &0x180) &~prgAND; /* outer PRG bank */ switch(EXPREGS[3] &3) { - case 0: // MMC3 PRG mode + case 0: /* MMC3 PRG mode */ break; case 1: - case 2: // NROM-128 mode: MMC3 register 6 applies throughout $8000-$FFFF, MMC3 A13 replaced with CPU A13. + case 2: /* NROM-128 mode: MMC3 register 6 applies throughout $8000-$FFFF, MMC3 A13 replaced with CPU A13. */ V =DRegBuf[6] &~1 | A >>13 &1; - setprg8(A ^0x4000, V &prgAND | prgOR); // wrapPRG is only called with A containing the switchable banks, so we need to manually switch the normally fixed banks in this mode as well. + setprg8(A ^0x4000, V &prgAND | prgOR); /* wrapPRG is only called with A containing the switchable banks, so we need to manually switch the normally fixed banks in this mode as well. */ break; - case 3: // NROM-256 mode: MMC3 register 6 applies throughout $8000-$FFFF, MMC3 A13-14 replaced with CPU A13-14. + case 3: /* NROM-256 mode: MMC3 register 6 applies throughout $8000-$FFFF, MMC3 A13-14 replaced with CPU A13-14. */ V =DRegBuf[6] &~3 | A >>13 &3; - setprg8(A ^0x4000, (V ^2) &prgAND | prgOR); // wrapPRG is only called with A containing the switchable banks, so we need to manually switch the normally fixed banks in this mode as well. + setprg8(A ^0x4000, (V ^2) &prgAND | prgOR); /* wrapPRG is only called with A containing the switchable banks, so we need to manually switch the normally fixed banks in this mode as well. */ break; } setprg8(A, V &prgAND | prgOR); } static void wrapCHR(uint32 A, uint8 V) { - int chrAND = EXPREGS[0] &0x80? 0x7F: 0xFF; // 128 KiB or 256 KiB innter CHR bank selection - int chrOR; // outer CHR bank - if (reverseCHR_A18_A19) // Mapper 126 swaps CHR A18 and A19 + int chrAND = EXPREGS[0] &0x80? 0x7F: 0xFF; /* 128 KiB or 256 KiB innter CHR bank selection */ + int chrOR; /* outer CHR bank */ + if (reverseCHR_A18_A19) /* Mapper 126 swaps CHR A18 and A19 */ chrOR =(EXPREGS[0] <<4 &0x080 | EXPREGS[0] <<3 &0x100 | EXPREGS[0] <<5 &0x200) &~chrAND; else chrOR =EXPREGS[0] <<4 &0x380 &~chrAND; - if (EXPREGS[3] &0x10) // CNROM mode: 8 KiB inner CHR bank comes from outer bank register #2 + if (EXPREGS[3] &0x10) /* CNROM mode: 8 KiB inner CHR bank comes from outer bank register #2 */ setchr8(EXPREGS[2] &(chrAND >>3) | chrOR >>3); - else // MMC3 CHR mode + else /* MMC3 CHR mode */ setchr1(A, (V & chrAND) | chrOR); } static DECLFW(writeWRAM) { if (~EXPREGS[3] &0x80) { - // Lock bit clear: Update any outer bank register + /* Lock bit clear: Update any outer bank register */ EXPREGS[A &3] =V; FixMMC3PRG(MMC3_cmd); FixMMC3CHR(MMC3_cmd); } else if ((A &3) ==2) { - // Lock bit set: Only update the bottom one or two bits of the CNROM bank - int latchMask =EXPREGS[2] &0x10? 1: 3; // 16 or 32 KiB inner CHR bank selection + /* Lock bit set: Only update the bottom one or two bits of the CNROM bank */ + int latchMask =EXPREGS[2] &0x10? 1: 3; /* 16 or 32 KiB inner CHR bank selection */ EXPREGS[2] &=~latchMask; EXPREGS[2] |= V &latchMask; FixMMC3CHR(MMC3_cmd); @@ -82,7 +82,7 @@ static DECLFW(writeWRAM) { static DECLFR(readDIP) { uint8 result =CartBR(A); - if (EXPREGS[1] &1) result =result &~3 | dipSwitch &3; // Replace bottom two bits with solder pad or DIP switch setting if so selected + if (EXPREGS[1] &1) result =result &~3 | dipSwitch &3; /* Replace bottom two bits with solder pad or DIP switch setting if so selected */ return result; } @@ -91,7 +91,7 @@ static DECLFW(writeIRQ) { } static void reset(void) { - dipSwitch++; // Soft-resetting cycles through solder pad or DIP switch settings + dipSwitch++; /* Soft-resetting cycles through solder pad or DIP switch settings */ EXPREGS[0] = EXPREGS[1] = EXPREGS[2] = EXPREGS[3] = 0; MMC3RegReset(); } @@ -102,7 +102,7 @@ static void power(void) { GenMMC3Power(); SetWriteHandler(0x6000, 0x7FFF, writeWRAM); SetReadHandler(0x8000, 0xFFFF, readDIP); - if (invertC000) SetWriteHandler(0xC000, 0xDFFF, writeIRQ); // Mapper 534 inverts the MMC3 scanline counter reload value + if (invertC000) SetWriteHandler(0xC000, 0xDFFF, writeIRQ); /* Mapper 534 inverts the MMC3 scanline counter reload value */ } static void init(CartInfo *info) { From 61c2d95dacf409ce5153d47cde14e293074816eb Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sat, 10 Apr 2021 15:20:50 +0800 Subject: [PATCH 098/295] Add support for Konami Hyper Shot This is just a quick hook-up of the konami hyper shot controller. -The Konami Hyper Shot is used (and required for gameplay) in the following games: * Hyper Olympic (J) Konami (1985) * Hyper Sports (J) Konami (1985) Fix #439 --- src/drivers/libretro/libretro.c | 39 +++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 94ec2c2..792f89c 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -49,6 +49,7 @@ #define RETRO_DEVICE_FC_OEKAKIDS RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_MOUSE, 3) #define RETRO_DEVICE_FC_SHADOW RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_MOUSE, 4) #define RETRO_DEVICE_FC_4PLAYERS RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 2) +#define RETRO_DEVICE_FC_HYPERSHOT RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 3) #define RETRO_DEVICE_FC_AUTO RETRO_DEVICE_JOYPAD #define NES_WIDTH 256 @@ -765,6 +766,10 @@ static void update_nes_controllers(unsigned port, unsigned device) FCEUI_SetInputFC(SIFC_4PLAYER, &nes_input.JSReturn, 0); FCEU_printf(" Famicom Expansion: Famicom 4-Player Adapter\n"); break; + case RETRO_DEVICE_FC_HYPERSHOT: + FCEUI_SetInputFC(SIFC_HYPERSHOT, nes_input.FamicomData, 0); + FCEU_printf(" Famicom Expansion: Konami Hyper Shot\n"); + break; case RETRO_DEVICE_NONE: default: FCEUI_SetInputFC(SIFC_NONE, &Dummy, 0); @@ -807,6 +812,8 @@ static unsigned fc_to_libretro(int d) return RETRO_DEVICE_FC_OEKAKIDS; case SIFC_4PLAYER: return RETRO_DEVICE_FC_4PLAYERS; + case SIFC_HYPERSHOT: + return RETRO_DEVICE_FC_HYPERSHOT; } return (RETRO_DEVICE_NONE); @@ -918,6 +925,7 @@ void retro_set_environment(retro_environment_t cb) { "Auto", RETRO_DEVICE_FC_AUTO }, { "Arkanoid", RETRO_DEVICE_FC_ARKANOID }, { "(Bandai) Hyper Shot", RETRO_DEVICE_FC_SHADOW }, + { "(Konami) Hyper Shot", RETRO_DEVICE_FC_HYPERSHOT }, { "Oeka Kids Tablet", RETRO_DEVICE_FC_OEKAKIDS }, { "4-Player Adapter", RETRO_DEVICE_FC_4PLAYERS }, { 0, 0 }, @@ -1719,6 +1727,37 @@ static void FCEUD_UpdateInput(void) case RETRO_DEVICE_FC_SHADOW: get_mouse_input(0, nes_input.FamicomData); break; + case RETRO_DEVICE_FC_HYPERSHOT: + { + static int toggle; + int i; + + nes_input.FamicomData[0] = 0; + toggle ^= 1; + for (i = 0; i < 2; i++) + { + + if (input_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B)) + nes_input.FamicomData[0] |= 0x02 << (i * 2); + else if (input_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y)) + { + if (toggle) + nes_input.FamicomData[0] |= 0x02 << (i * 2); + else + nes_input.FamicomData[0] &= ~(0x02 << (i * 2)); + } + if (input_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A)) + nes_input.FamicomData[0] |= 0x04 << (i * 2); + else if (input_cb(i, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X)) + { + if (toggle) + nes_input.FamicomData[0] |= 0x04 << (i * 2); + else + nes_input.FamicomData[0] &= ~(0x04 << (i * 2)); + } + } + break; + } } if (input_cb(0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R2)) From 18dd7585db94828f4ab5452a904f14ca9edb71da Mon Sep 17 00:00:00 2001 From: crystalct Date: Sat, 10 Apr 2021 12:08:06 +0200 Subject: [PATCH 099/295] Wrong Big Endian define for PSL1GHT system --- Makefile.libretro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.libretro b/Makefile.libretro index 22df238..86563b0 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -250,7 +250,7 @@ else ifeq ($(platform), rpi4) # Lightweight PS3 Homebrew SDK else ifneq (,$(filter $(platform), ps3 psl1ght)) - ENDIANNESS_DEFINES = -DWORDS_BIGENDIAN + ENDIANNESS_DEFINES = -DMSB_FIRST EXTERNAL_ZLIB = 1 STATIC_LINKING = 1 From 0657d2136631e48030e994bfed4632d862bc0370 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Sat, 10 Apr 2021 14:38:49 +0200 Subject: [PATCH 100/295] MINDKIDS accessible as NES 2.0 m268.1; mapper 224 is MINDKIDS; remove KT-008 remnants from mmc3.c --- src/boards/224.c | 50 -------------------------------------------- src/boards/coolboy.c | 9 ++++++++ src/boards/mmc3.c | 21 +------------------ src/ines-correct.h | 38 ++++++++++++++++++++++++++++++--- src/ines.c | 5 ++--- src/ines.h | 1 + 6 files changed, 48 insertions(+), 76 deletions(-) delete mode 100644 src/boards/224.c diff --git a/src/boards/224.c b/src/boards/224.c deleted file mode 100644 index 7c885b7..0000000 --- a/src/boards/224.c +++ /dev/null @@ -1,50 +0,0 @@ -/* 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"); -} diff --git a/src/boards/coolboy.c b/src/boards/coolboy.c index 5482550..357cd2a 100644 --- a/src/boards/coolboy.c +++ b/src/boards/coolboy.c @@ -174,3 +174,12 @@ void MINDKIDS_Init(CartInfo *info) { info->Reset = COOLBOYReset; AddExState(EXPREGS, 4, 0, "EXPR"); } + +void Mapper268_Init(CartInfo *info) { + /* Technically, the distinction between COOLBOY ($6000-$7FFF) and MINDKIDS ($5000-$5FFF) is based on a solder pad setting. */ + /* In NES 2.0, the submapper field is used to distinguish between the two settings. */ + if (info->submapper == 1) + MINDKIDS_Init(info); + else + COOLBOY_Init(info); +} diff --git a/src/boards/mmc3.c b/src/boards/mmc3.c index 1618bea..0698d85 100644 --- a/src/boards/mmc3.c +++ b/src/boards/mmc3.c @@ -184,17 +184,6 @@ DECLFW(MMC3_IRQWrite) { } } -/* 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 */ -DECLFW(KT008HackWrite) { -/* FCEU_printf("%04x:%04x\n",A,V); */ - switch (A & 3) { - case 0: kt_extra = V; FixMMC3PRG(MMC3_cmd); break; - case 1: break; /* unk */ - case 2: break; /* unk */ - case 3: break; /* unk */ - } -} - static void ClockMMC3Counter(void) { int count = IRQCount; if (!count || IRQReload) { @@ -236,9 +225,7 @@ static void GENPWRAP(uint32 A, uint8 V) { /* [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 */ - 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 should be assigned to mapper 224 */ + setprg8(A, (V & 0x7F)); } static void GENMWRAP(uint8 V) { @@ -265,9 +252,6 @@ void GenMMC3Power(void) { SetWriteHandler(0xC000, 0xFFFF, MMC3_IRQWrite); 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 */ - /* SetWriteHandler(0x5000,0x5FFF, KT008HackWrite); */ /* KT-008 boards should be assigned to mapper 224 */ - A001B = A000B = 0; setmirror(1); if (mmc3opts & 1) { @@ -321,9 +305,6 @@ void GenMMC3_Init(CartInfo *info, int prg, int chr, int wram, int battery) { info->SaveGameLen[0] = WRAMSIZE; } - /* 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(MMC3_StateRegs, ~0, 0, 0); info->Power = GenMMC3Power; diff --git a/src/ines-correct.h b/src/ines-correct.h index 4c4185d..5096d75 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -619,10 +619,42 @@ { 0x345ee51a, 245, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yong Zhe Dou E Long - Dragon Quest VII (Ch).nes */ { 0x57514c6c, 245, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yong Zhe Dou E Long - Dragon Quest VI (Ch).nes */ { 0xdb9d71b7, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Donkey Kong (Unl) [o1].nes */ + + /* KT-008 PCB. These require mapper 224 for having an outer bank register at $5xxx, but are usually found set to mapper 4. */ { 0x61fc4d20, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* (KT-1062) 口袋怪兽꞉ 水晶版.nes */ - { 0x4d735cb1, 224, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pokemon Platinum (KT-008 PCB)(Ch)[!].nes */ - { 0x4f427110, 224, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pokemon Platinum Alt title 1 (KT-008 PCB)(Ch)[!].nes */ - { 0xe001de16, 224, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pokemon Platinum Alt title 2 (KT-008 PCB)(Ch)[!].nes */ + { 0xaa666c19, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys Origin: Hugo.nes */ + { 0xb0d011d3, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys Origin: Yunica.nes */ + { 0x16143319, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys VI: 纳比斯汀的方舟.nes */ + { 0xe05fc21f, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys: 菲尔盖纳之誓约.nes */ + { 0xf8b58b59, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志 - 蜀魏争霸.nes */ + { 0xcb1bab3d, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志꞉ 蜀汉风云.nes */ + { 0xddc122ed, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 亡灵崛起.nes */ + { 0x4d2811c7, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 伏魔英雄传.nes */ + { 0x24750e5d, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 傲视天地.nes */ + { 0xc658b6a8, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 刀剑英雄传.nes */ + { 0xea831217, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 剑侠情缘.nes */ + { 0x92ebad5b, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙 III꞉ 罪恶渊源.nes */ + { 0x48210324, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 勇者的试炼.nes */ + { 0x3439d140, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 天空的新娘.nes */ + { 0x9a0a531a, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 天空篇.nes */ + { 0xb5fdb3cb, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者黑暗世界 - 混沌世界.nes */ + { 0x4f427110, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 珍珠版.nes */ + { 0xa46d6f4c, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 琥珀版.nes */ + { 0xe001de16, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 白金版.nes */ + { 0x5464d7f8, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 翡翠版.nes */ + { 0x4d735cb1, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 钻石版.nes */ + { 0x5d04547c, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 失落的神器.nes */ + { 0xcb524b42, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 征战天下.nes */ + { 0x5f362198, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 战神世界.nes */ + { 0x36de88e7, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 新魔界.nes */ + { 0xf8e9c9cf, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 无双乱舞.nes */ + { 0xa4c39535, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 神魔大陆.nes */ + { 0x76bbe916, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 落日征战.nes */ + { 0x9b518d54, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 云的彼端.nes */ + { 0x91396b3f, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 天之痕.nes */ + { 0xaa621fa0, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 枫之舞.nes */ + { 0x48d1f54a, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 王者归来.nes */ + { 0xbdbe3c96, 238, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Contra Fighter (Unl).nes */ { 0xcb53c523, 11, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* King Neptune's Adventure (USA) (Unl).nes */ { 0x6e149729, 189, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Master Fighter II (Unl) [a1].nes */ diff --git a/src/ines.c b/src/ines.c index 316fa5d..33cbed2 100644 --- a/src/ines.c +++ b/src/ines.c @@ -639,7 +639,7 @@ INES_BOARD_BEGIN() INES_BOARD( "UNLN625092", 221, UNLN625092_Init ) INES_BOARD( "", 222, Mapper222_Init ) /* INES_BOARD( "", 223, Mapper223_Init ) */ - INES_BOARD( "KT-008", 224, Mapper224_Init ) + INES_BOARD( "KT-008", 224, MINDKIDS_Init ) /* The KT-008 board contains the MINDKIDS chipset */ INES_BOARD( "", 225, Mapper225_Init ) INES_BOARD( "BMC 22+20-in-1", 226, Mapper226_Init ) INES_BOARD( "", 227, Mapper227_Init ) @@ -724,8 +724,7 @@ INES_BOARD_BEGIN() INES_BOARD( "YOKO", 264, UNLYOKO_Init ) INES_BOARD( "T-262", 265, BMCT262_Init ) INES_BOARD( "CITYFIGHT", 266, UNLCITYFIGHT_Init ) - INES_BOARD( "COOLBOY", 268, COOLBOY_Init ) -/* INES_BOARD( "MINDKIDS", 268, MINDKIDS_Init ) */ + INES_BOARD( "COOLBOY/MINDKIDS", 268, Mapper268_Init ) /* Submapper distinguishes between COOLBOY and MINDKIDS */ INES_BOARD( "80013-B", 274, BMC80013B_Init ) INES_BOARD( "GS-2004", 283, BMCGS2004_Init ) /* INES_BOARD( "GS-2013", 283, BMCGS2013_Init ) */ diff --git a/src/ines.h b/src/ines.h index 574a0de..cbeaf42 100644 --- a/src/ines.h +++ b/src/ines.h @@ -253,6 +253,7 @@ void NC7000M_Init(CartInfo *); void J2282_Init(CartInfo *); void Mapper267_Init(CartInfo *); +void Mapper268_Init(CartInfo *); void Mapper269_Init(CartInfo *); void Mapper288_Init(CartInfo *); void Mapper293_Init(CartInfo *); From f3bdbd658197c0b8a8fef1411af266191d1a4aae Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Sat, 10 Apr 2021 21:40:01 +0200 Subject: [PATCH 101/295] Forgot one KT-008 hack remnant. --- src/boards/mmc3.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/boards/mmc3.c b/src/boards/mmc3.c index 0698d85..3fbfd22 100644 --- a/src/boards/mmc3.c +++ b/src/boards/mmc3.c @@ -28,7 +28,6 @@ #include "mmc3.h" uint8 MMC3_cmd; -uint8 kt_extra; uint8 *WRAM; uint32 WRAMSIZE; uint8 *CHRRAM; From 86356c24c2b08960d2d00d0f56738f6a260a73d8 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 14 Apr 2021 19:09:02 +0200 Subject: [PATCH 102/295] Make mapper 59 always reset to menu. Add mapper 59 multicarts that had previously been set to 60, colliding with 'Reset-based 4-in-1', to CRC-based correction table. --- src/boards/addrlatch.c | 4 ++++ src/ines-correct.h | 14 ++++++++++++++ src/ines.c | 1 - 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/boards/addrlatch.c b/src/boards/addrlatch.c index 415d574..1cd7a26 100644 --- a/src/boards/addrlatch.c +++ b/src/boards/addrlatch.c @@ -111,6 +111,10 @@ static DECLFR(BMCD1038Read) { static void BMCD1038Reset(void) { dipswitch++; dipswitch &= 3; + + /* Always reset to menu */ + latche = 0; + BMCD1038Sync(); } void BMCD1038_Init(CartInfo *info) { diff --git a/src/ines-correct.h b/src/ines-correct.h index 5096d75..990395b 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -242,6 +242,20 @@ { 0x1500e835, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jetsons, The - Cogswell's Caper (Japan).nes */ { 0xe2c94bc2, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Bros 8 (Unl) [!].nes */ { 0xa912b064, 51, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, 0x800 }, /* 11-in-1 Ball Games [p1][o1].nes (has CHR ROM when it shouldn't) */ + { 0x2e72a5d9, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 11-in-1 (66-in-1, 86-in-1, 63-in-1).nes */ + { 0x39f514fd, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 18 in 1 (118-in-1, 138-in-1, 198-in-1)VTxxxx.nes */ + { 0xd8b1f465, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 26-in-1 (36-in-1, 46-in-1,56-in-1) VT 335.nes */ + { 0xcf82fae9, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 28 in 1 (38-in-1, 48-in-1, 58-in1)VTxxxx.nes */ + { 0xa7a98698, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 28-in-1 (46-in-1, 63-in-1, 118-in-1)VT-5116.nes */ + { 0x21fd7143, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 41-in-1 (5-in-1,71-in-1) VT345.nes */ + { 0x49ec88d6, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 42-in-1 NT-234 Bad Game Road Fighter.nes */ + { 0x60306f19, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 42-in-1 PCB 3840.nes */ + { 0x450cd86e, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 48-in-1 (62-in-1,73-in-1,88-in-1) VTxxx.nes */ + { 0xd774e041, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 50-in-1 (60-in-1,70-in-1,80-in-1) NT-113.nes */ + { 0x3c4e94f6, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 51-in-1 (61-in-1, 71-in-1, 81-in-1) VT5310.nes */ + { 0x0422ed44, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 7-in-1 (32-in-1,66-in-1,119-in-1) VT15004.nes */ + { 0x7efc0d2c, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 7-in-1 (5000-in-1, 999999999-in-1, 10000000-in-1)NC-07N.nes */ + { 0x6d92dff1, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* TN 95-in-1 (6-in-1) [p1].nes */ { 0x39ab0fc7, 64, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Hard Drivin' (USA) (Proto) (Unl).nes */ { 0xb19a55dd, 64, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Road Runner (USA) (Unl).nes */ { 0xf92be3ec, 64, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rolling Thunder (USA) (Unl).nes */ diff --git a/src/ines.c b/src/ines.c index 33cbed2..a4c5eb8 100644 --- a/src/ines.c +++ b/src/ines.c @@ -472,7 +472,6 @@ INES_BOARD_BEGIN() INES_BOARD( "UNLKS202", 56, UNLKS202_Init ) INES_BOARD( "SIMBPLE BMC PIRATE A", 57, Mapper57_Init ) INES_BOARD( "SIMBPLE BMC PIRATE B", 58, BMCGK192_Init ) -/* INES_BOARD( "", 59, Mapper59_Init ) */ /* Check this out, update 2020-10-21 - formerly an incorrect implementation of T3H53 */ INES_BOARD( "BMC T3H53/D1038", 59, BMCD1038_Init ) INES_BOARD( "Reset-based NROM-128 ", 60, Mapper60_Init ) INES_BOARD( "20-in-1 KAISER Rev. A", 61, Mapper61_Init ) From cf476194ce26ead165cd9b7c002cea4d30e245f8 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 14 Apr 2021 19:16:57 +0200 Subject: [PATCH 103/295] Combine UNIF AB-G1L, WELL-NO-DG450 and TF2740 into NES 2.0 Mapper 428. --- src/boards/{AbG1l.c => 428.c} | 94 ++++++----------------------------- src/ines.c | 1 + src/ines.h | 1 + src/unif.c | 4 +- src/unif.h | 2 - 5 files changed, 20 insertions(+), 82 deletions(-) rename src/boards/{AbG1l.c => 428.c} (50%) diff --git a/src/boards/AbG1l.c b/src/boards/428.c similarity index 50% rename from src/boards/AbG1l.c rename to src/boards/428.c index 7fde82b..3c06a39 100644 --- a/src/boards/AbG1l.c +++ b/src/boards/428.c @@ -25,7 +25,6 @@ static uint8 regs[4]; static uint8 hrd_flag; -static void(*Sync)(void); static SFORMAT StateRegs[] = { @@ -34,7 +33,8 @@ static SFORMAT StateRegs[] = { 0 } }; -static void SyncAbG1l(void) { +static void Sync(void) { + int mask = reg[2] >> 6; /* There is an CNROM mode that takes either two or four inner CHR banks from a CNROM-like latch register at $8000-$FFFF. */ if (regs[1] & 0x10) setprg32(0x8000,(regs[1] & 0xC0) >> 6); @@ -44,48 +44,36 @@ static void SyncAbG1l(void) { setprg16(0xC000, (regs[1] & 0xE0) >> 5); } - /* FIXME: 2020-10-26 */ - switch (regs[2] & 0xC0) { - case 0xC0: /* Pipe Dream */ - setchr8((regs[0] & 0x03) | (regs[1] & ~0x03)); - break; - case 0x40: /* Goonies */ - setchr8((regs[0] & 0x01) | (regs[1] & 0x07)); - break; - default: - setchr8(regs[1]); - break; - } - + setchr8((regs[1] & 0x07) & ~mask) | reg[0] & mask); + setmirror((regs[1] & 0x8) ? 0 : 1); } -static DECLFW(AbG1lWriteHi) { +static DECLFW(WriteHi) { regs[0] = V; - /* setchr8(((regs[2] & 0xC0) >> 7) << 2 | (regs[0] & 0x03)); */ Sync(); } -static DECLFW(AbG1lWriteLo) { +static DECLFW(WriteLo) { regs[A & 0x03] = V; Sync(); } -static DECLFR(AbG1lReadLo) { +static DECLFR(ReadLo) { return hrd_flag; } -static void AbG1lPower(void) { - hrd_flag = 0; +static void Power(void) { + hrd_flag = 0; /* Solder pad, selecting different menus */ regs[0] = 0; regs[1] = 0; regs[2] = 0; Sync(); - SetWriteHandler(0x8000, 0xFFFF, AbG1lWriteHi); - SetWriteHandler(0x6001, 0x6002, AbG1lWriteLo); - SetReadHandler(0x6000, 0x7FFF, AbG1lReadLo); + SetWriteHandler(0x8000, 0xFFFF, WriteHi); + SetWriteHandler(0x6001, 0x6002, WriteLo); + SetReadHandler(0x6000, 0x7FFF, ReadLo); SetReadHandler(0x8000, 0xFFFF, CartBR); } @@ -93,7 +81,7 @@ static void StateRestore(int version) { Sync(); } -static void AbG1lReset(void) { +static void Reset(void) { hrd_flag++; hrd_flag &= 3; @@ -104,64 +92,14 @@ static void AbG1lReset(void) { Sync(); } -void AbG1l_Init(CartInfo *info) { - - Sync = SyncAbG1l; - +void Mapper428_Init(CartInfo *info) { hrd_flag = 0; Sync(); - info->Power = AbG1lPower; - info->Reset = AbG1lReset; + info->Power = Power; + info->Reset = Reset; AddExState(&StateRegs, ~0, 0, 0); GameStateRestore = StateRestore; } - -static void SyncWellNoDG450(void) { - - if (regs[1] & 0x10) - setprg32(0x8000, (regs[1]) >> 6); - else - { - setprg16(0x8000, (regs[1]) >> 5); - setprg16(0xC000, (regs[1]) >> 5); - } - - setchr8(regs[1] & 0x0F); - setmirror((regs[1] & 0x8) ? 0 : 1); -} - -static void WellNoDG450Power(void) { - hrd_flag = 0; - - regs[0] = 0; - regs[1] = 0; - regs[2] = 0; - - Sync(); - - SetWriteHandler(0x6001, 0x6002, AbG1lWriteLo); - SetReadHandler(0x6000, 0x7FFF, AbG1lReadLo); - SetReadHandler(0x8000, 0xFFFF, CartBR); -} - -static void WellNoDG450Reset(void) { - hrd_flag++; - hrd_flag &= 3; - - regs[0] = 0; - regs[1] = 0; - regs[2] = 0; - - Sync(); -} - -void WellNoDG450_Init(CartInfo *info) { - Sync = SyncWellNoDG450; - info->Power = WellNoDG450Power; - info->Reset = WellNoDG450Reset; - AddExState(&StateRegs, ~0, 0, 0); - GameStateRestore = StateRestore; -} diff --git a/src/ines.c b/src/ines.c index 33cbed2..372a966 100644 --- a/src/ines.c +++ b/src/ines.c @@ -788,6 +788,7 @@ INES_BOARD_BEGIN() INES_BOARD( "YY850439C", 397, Mapper397_Init ) INES_BOARD( "831019C J-2282", 402, J2282_Init ) INES_BOARD( "SC871115C", 421, Mapper421_Init ) + INES_BOARD( "AB-G1L/WELL-NO-DG450", 428, Mapper422_Init ) INES_BOARD( "SA-9602B", 513, SA9602B_Init ) INES_BOARD( "DANCE2000", 518, UNLD2000_Init ) INES_BOARD( "EH8813A", 519, UNLEH8813A_Init ) diff --git a/src/ines.h b/src/ines.h index cbeaf42..ad0556e 100644 --- a/src/ines.h +++ b/src/ines.h @@ -282,6 +282,7 @@ void Mapper401_Init(CartInfo *); void Mapper411_Init(CartInfo *); void Mapper421_Init(CartInfo *); void Mapper422_Init(CartInfo *); +void Mapper428_Init(CartInfo *); void Mapper516_Init(CartInfo *); void Mapper533_Init(CartInfo *); void Mapper534_Init(CartInfo *); diff --git a/src/unif.c b/src/unif.c index 14c3f60..e7a93aa 100644 --- a/src/unif.c +++ b/src/unif.c @@ -438,7 +438,7 @@ static BMAPPING bmap[] = { { "8237A", 215, UNL8237A_Init, 0 }, { "830118C", 348, BMC830118C_Init, 0 }, { "A65AS", 285, BMCA65AS_Init, 0 }, - { "AB-G1L", NO_INES, AbG1l_Init, 0 }, + { "AB-G1L", 428, Mapper428_Init, 0 }, { "AC08", 42, AC08_Init, 0 }, { "ANROM", 7, ANROM_Init, 0 }, { "AX5705", 530, UNLAX5705_Init, 0 }, @@ -559,7 +559,7 @@ static BMAPPING bmap[] = { { "UNROM-512-32", 30, UNROM512_Init, BMCFLAG_32KCHRR }, { "UOROM", 2, UNROM_Init, 0 }, { "VRC7", 85, UNLVRC7_Init, 0 }, - { "WELL-NO-DG450", NO_INES, WellNoDG450_Init, 0 }, + { "WELL-NO-DG450", 428, Mapper428_Init, 0 }, { "YOKO", 264, UNLYOKO_Init, 0 }, { "COOLBOY", 268, COOLBOY_Init, BMCFLAG_256KCHRR }, { "158B", 258, UNL158B_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index 4f5517e..c53a3e8 100644 --- a/src/unif.h +++ b/src/unif.h @@ -189,8 +189,6 @@ void BMC830134C_Init(CartInfo *info); /* m315 */ void BMCGN26_Init(CartInfo *info); /* m344 */ void BS110_Init(CartInfo *info); -void WellNoDG450_Init(CartInfo *info); -void AbG1l_Init(CartInfo *info); void KG256_Init(CartInfo *info); void WAIXINGFS005_Init(CartInfo *info); From 5fc30e3d20a8b1cab99f611b5b466d6bae79f067 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 14 Apr 2021 19:17:53 +0200 Subject: [PATCH 104/295] Add TF2740 to unif.c --- src/unif.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/unif.c b/src/unif.c index e7a93aa..e69a75a 100644 --- a/src/unif.c +++ b/src/unif.c @@ -560,6 +560,7 @@ static BMAPPING bmap[] = { { "UOROM", 2, UNROM_Init, 0 }, { "VRC7", 85, UNLVRC7_Init, 0 }, { "WELL-NO-DG450", 428, Mapper428_Init, 0 }, + { "TF2740", 428, Mapper428_Init, 0 }, { "YOKO", 264, UNLYOKO_Init, 0 }, { "COOLBOY", 268, COOLBOY_Init, BMCFLAG_256KCHRR }, { "158B", 258, UNL158B_Init, 0 }, From 9cfea5b7d1aba8b8187aeeb7e3767bf0b6bbb332 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 14 Apr 2021 19:29:08 +0200 Subject: [PATCH 105/295] Typos in 428.c --- src/boards/428.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/boards/428.c b/src/boards/428.c index 3c06a39..06f18f7 100644 --- a/src/boards/428.c +++ b/src/boards/428.c @@ -34,7 +34,7 @@ static SFORMAT StateRegs[] = }; static void Sync(void) { - int mask = reg[2] >> 6; /* There is an CNROM mode that takes either two or four inner CHR banks from a CNROM-like latch register at $8000-$FFFF. */ + int mask = regs[2] >> 6; /* There is an CNROM mode that takes either two or four inner CHR banks from a CNROM-like latch register at $8000-$FFFF. */ if (regs[1] & 0x10) setprg32(0x8000,(regs[1] & 0xC0) >> 6); @@ -44,7 +44,7 @@ static void Sync(void) { setprg16(0xC000, (regs[1] & 0xE0) >> 5); } - setchr8((regs[1] & 0x07) & ~mask) | reg[0] & mask); + setchr8(((regs[1] & 0x07) & ~mask) | regs[0] & mask); setmirror((regs[1] & 0x8) ? 0 : 1); } From 89bd38c33be46d43da4f36999ca4465618bae000 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 14 Apr 2021 19:30:47 +0200 Subject: [PATCH 106/295] Typo in ines.c --- src/ines.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ines.c b/src/ines.c index 372a966..ce9e8b3 100644 --- a/src/ines.c +++ b/src/ines.c @@ -788,7 +788,7 @@ INES_BOARD_BEGIN() INES_BOARD( "YY850439C", 397, Mapper397_Init ) INES_BOARD( "831019C J-2282", 402, J2282_Init ) INES_BOARD( "SC871115C", 421, Mapper421_Init ) - INES_BOARD( "AB-G1L/WELL-NO-DG450", 428, Mapper422_Init ) + INES_BOARD( "AB-G1L/WELL-NO-DG450", 428, Mapper428_Init ) INES_BOARD( "SA-9602B", 513, SA9602B_Init ) INES_BOARD( "DANCE2000", 518, UNLD2000_Init ) INES_BOARD( "EH8813A", 519, UNLEH8813A_Init ) From 825cdb8788391b7afc8bb92845314f6c0d73ff12 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 14 Apr 2021 21:03:59 +0200 Subject: [PATCH 107/295] Add lock bit, necessary for NT-234's Road Fighter --- src/boards/addrlatch.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/boards/addrlatch.c b/src/boards/addrlatch.c index 1cd7a26..e46b9ee 100644 --- a/src/boards/addrlatch.c +++ b/src/boards/addrlatch.c @@ -108,6 +108,12 @@ static DECLFR(BMCD1038Read) { return CartBR(A); } +static DECLFW(BMCD1038Write) { + /* Only recognize the latch write if the lock bit has not been set. Needed for NT-234 "Road Fighter" */ + if (~latche & 0x200) + LatchWrite(A, V); +} + static void BMCD1038Reset(void) { dipswitch++; dipswitch &= 3; @@ -117,9 +123,17 @@ static void BMCD1038Reset(void) { BMCD1038Sync(); } +static void BMCD1038Power(void) { + LatchPower(); + + /* Trap latch writes to enforce the "Lock" bit */ + SetWriteHandler(0x8000, 0xFFFF, BMCD1038Write); +} + void BMCD1038_Init(CartInfo *info) { Latch_Init(info, BMCD1038Sync, BMCD1038Read, 0x0000, 0x8000, 0xFFFF, 0); info->Reset = BMCD1038Reset; + info->Power = BMCD1038Power; AddExState(&dipswitch, 1, 0, "DIPSW"); } From d6c854abd8ad70de15fe25170a7d5a532d8f1502 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 20 Apr 2021 16:18:54 +0800 Subject: [PATCH 108/295] Use fopen_utf8 instead of fopen --- Makefile.common | 3 +- src/drivers/libretro/griffin.c | 1 + .../libretro-common/compat/fopen_utf8.c | 63 +++++++++++++++++++ .../include/compat/fopen_utf8.h | 34 ++++++++++ .../libretro-common/include/libretro.h | 4 ++ .../include/string/stdstring.h | 22 +++---- src/file.c | 4 +- 7 files changed, 118 insertions(+), 13 deletions(-) create mode 100644 src/drivers/libretro/libretro-common/compat/fopen_utf8.c create mode 100644 src/drivers/libretro/libretro-common/include/compat/fopen_utf8.h diff --git a/Makefile.common b/Makefile.common index 8c75113..9876d85 100644 --- a/Makefile.common +++ b/Makefile.common @@ -53,7 +53,8 @@ SOURCES_C += $(CORE_DIR)/drivers/libretro/libretro-common/streams/memory_stream. $(CORE_DIR)/drivers/libretro/libretro-common/compat/compat_snprintf.c \ $(CORE_DIR)/drivers/libretro/libretro-common/string/stdstring.c \ $(CORE_DIR)/drivers/libretro/libretro-common/encodings/encoding_utf.c \ - $(CORE_DIR)/drivers/libretro/libretro-common/compat/compat_strl.c + $(CORE_DIR)/drivers/libretro/libretro-common/compat/compat_strl.c \ + $(CORE_DIR)/drivers/libretro/libretro-common/compat/fopen_utf8.c endif ifeq ($(DEBUG),1) diff --git a/src/drivers/libretro/griffin.c b/src/drivers/libretro/griffin.c index 3158363..9a215eb 100644 --- a/src/drivers/libretro/griffin.c +++ b/src/drivers/libretro/griffin.c @@ -7,6 +7,7 @@ #include "drivers/libretro/libretro-common/string/stdstring.c" #include "drivers/libretro/libretro-common/encodings/encoding_utf.c" #include "drivers/libretro/libretro-common/compat/compat_strl.c" +#include "drivers/libretro/libretro-common/compat/fopen_utf8.c" #endif #include "cart.c" diff --git a/src/drivers/libretro/libretro-common/compat/fopen_utf8.c b/src/drivers/libretro/libretro-common/compat/fopen_utf8.c new file mode 100644 index 0000000..85abb59 --- /dev/null +++ b/src/drivers/libretro/libretro-common/compat/fopen_utf8.c @@ -0,0 +1,63 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (fopen_utf8.c). + * --------------------------------------------------------------------------------------- + * + * 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. + */ + +#include +#include +#include +#include + +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) +#ifndef LEGACY_WIN32 +#define LEGACY_WIN32 +#endif +#endif + +#ifdef _WIN32 +#undef fopen + +void *fopen_utf8(const char * filename, const char * mode) +{ +#if defined(LEGACY_WIN32) + FILE *ret = NULL; + char * filename_local = utf8_to_local_string_alloc(filename); + + if (!filename_local) + return NULL; + ret = fopen(filename_local, mode); + if (filename_local) + free(filename_local); + return ret; +#else + wchar_t * filename_w = utf8_to_utf16_string_alloc(filename); + wchar_t * mode_w = utf8_to_utf16_string_alloc(mode); + FILE* ret = NULL; + + if (filename_w && mode_w) + ret = _wfopen(filename_w, mode_w); + if (filename_w) + free(filename_w); + if (mode_w) + free(mode_w); + return ret; +#endif +} +#endif diff --git a/src/drivers/libretro/libretro-common/include/compat/fopen_utf8.h b/src/drivers/libretro/libretro-common/include/compat/fopen_utf8.h new file mode 100644 index 0000000..97d4404 --- /dev/null +++ b/src/drivers/libretro/libretro-common/include/compat/fopen_utf8.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (fopen_utf8.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_COMPAT_FOPEN_UTF8_H +#define __LIBRETRO_SDK_COMPAT_FOPEN_UTF8_H + +#ifdef _WIN32 +/* Defined to error rather than fopen_utf8, to make it clear to everyone reading the code that not worrying about utf16 is fine */ +/* TODO: enable */ +/* #define fopen (use fopen_utf8 instead) */ +void *fopen_utf8(const char * filename, const char * mode); +#else +#define fopen_utf8 fopen +#endif +#endif diff --git a/src/drivers/libretro/libretro-common/include/libretro.h b/src/drivers/libretro/libretro-common/include/libretro.h index d843114..8a5da86 100644 --- a/src/drivers/libretro/libretro-common/include/libretro.h +++ b/src/drivers/libretro/libretro-common/include/libretro.h @@ -282,6 +282,7 @@ enum retro_language RETRO_LANGUAGE_PERSIAN = 20, RETRO_LANGUAGE_HEBREW = 21, RETRO_LANGUAGE_ASTURIAN = 22, + RETRO_LANGUAGE_FINNISH = 23, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ @@ -712,6 +713,9 @@ enum retro_mod * state of rumble motors in controllers. * A strong and weak motor is supported, and they can be * controlled indepedently. + * Should be called from either retro_init() or retro_load_game(). + * Should not be called from retro_set_environment(). + * Returns false if rumble functionality is unavailable. */ #define RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES 24 /* uint64_t * -- diff --git a/src/drivers/libretro/libretro-common/include/string/stdstring.h b/src/drivers/libretro/libretro-common/include/string/stdstring.h index 5d8c31b..82e038b 100644 --- a/src/drivers/libretro/libretro-common/include/string/stdstring.h +++ b/src/drivers/libretro/libretro-common/include/string/stdstring.h @@ -44,20 +44,20 @@ RETRO_BEGIN_DECLS #define string_is_not_equal_fast(a, b, size) (memcmp(a, b, size) != 0) #define string_is_equal_fast(a, b, size) (memcmp(a, b, size) == 0) -#define TOLOWER(c) (c | (lr_char_props[c] & 0x20)) -#define TOUPPER(c) (c & ~(lr_char_props[c] & 0x20)) +#define TOLOWER(c) ((c) | (lr_char_props[(unsigned char)(c)] & 0x20)) +#define TOUPPER(c) ((c) & ~(lr_char_props[(unsigned char)(c)] & 0x20)) /* C standard says \f \v are space, but this one disagrees */ -#define ISSPACE(c) (lr_char_props[c] & 0x80) +#define ISSPACE(c) (lr_char_props[(unsigned char)(c)] & 0x80) -#define ISDIGIT(c) (lr_char_props[c] & 0x40) -#define ISALPHA(c) (lr_char_props[c] & 0x20) -#define ISLOWER(c) (lr_char_props[c] & 0x04) -#define ISUPPER(c) (lr_char_props[c] & 0x02) -#define ISALNUM(c) (lr_char_props[c] & 0x60) -#define ISUALPHA(c) (lr_char_props[c] & 0x28) -#define ISUALNUM(c) (lr_char_props[c] & 0x68) -#define IS_XDIGIT(c) (lr_char_props[c] & 0x01) +#define ISDIGIT(c) (lr_char_props[(unsigned char)(c)] & 0x40) +#define ISALPHA(c) (lr_char_props[(unsigned char)(c)] & 0x20) +#define ISLOWER(c) (lr_char_props[(unsigned char)(c)] & 0x04) +#define ISUPPER(c) (lr_char_props[(unsigned char)(c)] & 0x02) +#define ISALNUM(c) (lr_char_props[(unsigned char)(c)] & 0x60) +#define ISUALPHA(c) (lr_char_props[(unsigned char)(c)] & 0x28) +#define ISUALNUM(c) (lr_char_props[(unsigned char)(c)] & 0x68) +#define IS_XDIGIT(c) (lr_char_props[(unsigned char)(c)] & 0x01) /* Deprecated alias, all callers should use string_is_equal_case_insensitive instead */ #define string_is_equal_noncase string_is_equal_case_insensitive diff --git a/src/file.c b/src/file.c index 2ceb96f..07da9f8 100644 --- a/src/file.c +++ b/src/file.c @@ -34,6 +34,8 @@ #include "driver.h" #include "general.h" +#include "compat/fopen_utf8.h" + #ifndef __GNUC__ #define strcasecmp strcmp #endif @@ -85,7 +87,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, fceufp->fp = MakeMemWrapBuffer(path, 0, buffer, bufsize); else { - void *t = fopen(path, mode); + void *t = fopen_utf8(path, mode); if (!t) { From e14c20b02afca53bfe6dfd051afe6532523eb948 Mon Sep 17 00:00:00 2001 From: tim942 <75698946+tim942@users.noreply.github.com> Date: Wed, 28 Apr 2021 18:15:10 -0500 Subject: [PATCH 109/295] Update Aspect Ratio Updated aspect ratio selection from a boolean to a float with a Pixel Perfect option --- src/drivers/libretro/libretro.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 792f89c..39263fc 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -56,6 +56,7 @@ #define NES_HEIGHT 240 #define NES_8_7_PAR ((width * (8.0 / 7.0)) / height) #define NES_4_3 ((width / (height * (256.0 / 240.0))) * 4.0 / 3.0) +#define NES_PP ((width / (height * (256.0 / 240.0))) * 16.0 / 15.0) #if defined(_3DS) void* linearMemAlign(size_t size, size_t alignment); @@ -81,7 +82,7 @@ static bool crop_overscan_v; #endif static bool use_raw_palette; -static bool use_par; +static int aspect_ratio_par; /* * Flags to keep track of whether turbo @@ -957,6 +958,16 @@ void retro_get_system_info(struct retro_system_info *info) info->block_extract = false; } +static float get_aspect_ratio(unsigned width, unsigned height) +{ + if (aspect_ratio_par == 2) + return NES_4_3; + else if (aspect_ratio_par == 3) + return NES_PP; + else + return NES_8_7_PAR; +} + void retro_get_system_av_info(struct retro_system_av_info *info) { #ifdef PSP @@ -975,7 +986,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info) #endif info->geometry.base_height = height; info->geometry.max_height = NES_HEIGHT; - info->geometry.aspect_ratio = (float)(use_par ? NES_8_7_PAR : NES_4_3); + info->geometry.aspect_ratio = get_aspect_ratio(width, height); info->timing.sample_rate = (float)sndsamplerate; if (FSettings.PAL || dendy) info->timing.fps = 838977920.0/16777215.0; @@ -1347,12 +1358,16 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - bool newval = (!strcmp(var.value, "8:7 PAR")); - if (newval != use_par) - { - use_par = newval; - audio_video_updated = 1; + unsigned oldval = aspect_ratio_par; + if (!strcmp(var.value, "8:7 PAR")) { + aspect_ratio_par = 1; + } else if (!strcmp(var.value, "4:3")) { + aspect_ratio_par = 2; + } else if (!strcmp(var.value, "PP")) { + aspect_ratio_par = 3; } + if (aspect_ratio_par != oldval) + audio_video_updated = 1; } var.key = "fceumm_turbo_enable"; From 39bce271945817b3aef10e33b6356fce64b1277d Mon Sep 17 00:00:00 2001 From: tim942 <75698946+tim942@users.noreply.github.com> Date: Wed, 28 Apr 2021 18:20:30 -0500 Subject: [PATCH 110/295] Update libretro_core_options.h Adding Pixel Perfect option --- src/drivers/libretro/libretro_core_options.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drivers/libretro/libretro_core_options.h b/src/drivers/libretro/libretro_core_options.h index f0b89c4..fe35d72 100644 --- a/src/drivers/libretro/libretro_core_options.h +++ b/src/drivers/libretro/libretro_core_options.h @@ -128,6 +128,7 @@ struct retro_core_option_definition option_defs_common[] = { { { "8:7 PAR", NULL }, { "4:3", NULL }, + { "PP", NULL }, { NULL, NULL}, }, "8:7 PAR", From 3cc9c323066546a095e99855445b1bea1af9fd84 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 26 May 2021 20:19:25 +0200 Subject: [PATCH 111/295] Use submappers and apply latest hardware findings. Use a heuristic to determine whether to change the DIP switch on every reset. --- src/boards/fk23c.c | 480 ++++++++++++++++++++------------------------- 1 file changed, 212 insertions(+), 268 deletions(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index 9f39bee..cda8cf8 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -19,92 +19,32 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* BMC-FK23C (no WRAM, no DIP switch) - * BMC-FK23CA (no WRAM, with DIP switch) - * BMC-Super24in1SC03 (functional duplicate of BMC-FK23C) - * WAIXING-FS005 (alternative name: Bensheng BS-001) (32 KiB battery-backed WRAM, 8 KiB of CHR-RAM, no DIP switch) - * WAIXING-FS006 (optional 8 KiB battery-backed WRAM, optional 8 KiB of CHR-RAM, no DIP switch) +/* Mappers: + 176 - Standard + 523 - Jncota KT-xxx (1 KiB->2 KiB, 2 KiB->4 KiB CHR, hard-wired nametable mirroring) - * Three incompatible subtypes exist that do not correspond to these UNIF board names. No submappers have been proposed, as the subtypes can be easily discerned heuristically by looking at ROM sizes: - - * Subtype 0, ROM size other than specified below: boot with Extended MMC3 mode disabled (boots in first 512 KiB of PRG-ROM regardless of ROM size) - * Subtype 1, 1024 KiB PRG-ROM, 1024 KiB CHR-ROM: boot with Extended MMC3 mode enabled (boots in last 512 KiB of the first 2 MiB of PRG-ROM) - * Subtype 2, 8192 or more KiB PRG-ROM, no CHR-ROM: Like Subtype 0, but MMC3 registers $46 and $47 swapped. - */ - -/* -Mode Register ($5xx0) -7654 3210 ----- ---- -PCTm PMMM -|||| |||| -|||| |+++- Select PRG Banking Mode (ignored in Extended MMC3 Mode) -|||| | 0: MMC3 PRG Mode, 512 KiB Outer PRG Bank Size -|||| | 1: MMC3 PRG Mode, 256 KiB Outer PRG Bank Size -|||| | 2: MMC3 PRG Mode, 128 KiB Outer PRG Bank Size -|||| | 3: NROM-128 PRG Mode, 16 KiB PRG at $8000-$BFFF mirrored at $C000-$FFFF -|||| | 4: NROM-256 PRG Mode, 32 KiB PRG at $8000-$FFFF -|||| | 5-7: Never used -|||| +---- PRG Base A21 -|||+------ Select Outer CHR Bank Size -||| 0: In MMC3 CHR Mode: 256 KiB -||| In CNROM CHR Mode: 32 KiB -||| 1: In MMC3 CHR Mode: 128 KiB -||| In CNROM CHR Mode: 16 KiB -||+------- Select CHR Memory Type -|| 0: CHR-ROM -|| 1: CHR-RAM -|+-------- CHR Mode -| 0: MMC3 CHR Mode -| 1: NROM/CNROM CHR Mode -+--------- PRG Base A22 - -Power-on value: $00 - -PRG Base Register ($5xx1) -Mask: $5xx3, x determined by solder pad setting - -7654 3210 ----- ---- -.PPP PPPP - ||| |||| - +++-++++- PRG Base A20..A14 - -Power-on value: $00 -CHR Base Register ($5xx2) -Mask: $5xx3, x determined by solder pad setting - -7654 3210 ----- ---- -ccdC CCCC -|||| |||| -++++-++++- CHR Base A20..A13 -||+------- PRG Base A25 -++-------- PRG Base A24..A23 - -Power-on value: $00 -Writing to the CHR Base Register also resets the CNROM latch. - -Extended Mode Register ($5xx3) -Mask: $5xx3, x determined by solder pad setting - -7654 3210 ----- ---- -.C.. .CE. - | || - | |+- Extended MMC3 Mode - | | 0: disable - | | 1: enable - +----+-- Select NROM/CNROM CHR Mode - 0: NROM - 1: CNROM - -Power-on value: $02 (Submapper 1), $00 (otherwise) + Submappers: + 0 - Standard + 1 - FK-xxx + 2 - 外星 FS005/FS006 + 3 - JX9003B + 4 - GameStar Smart Genius Deluxe + + Verified on real hardware: + "Legend of Kage" sets CNROM latch 1 and switches between CHR bank 0 and 1 using 5FF2, causing the wrong bank (1 instead of 0) during gameplay. + + Heuristics for NES 1.0: + - 1 MiB PRG+1 MiB CHR => Submapper 1 + - 256 KiB PRG+128 KiB CHR => Submapper 1 + - 128 KiB PRG+64 KiB CHR => Submapper 1 + - A001.5 ever set => Submapper 2 + - 5FF5/5FF6 written-to => Submapper 3 + + Heuristic for detecting whether the DIP switch should be changed on every soft reset: + The first write to the $5xxx range is to $501x => ROM always addresses $501x; changing the DIP switch on reset would break the emulation after reset, so don't do it. + The first write to the $5xxx range is to $5020 or higher => ROM either uses a DIP switch or writes to $5FFx for safety; changing the DIP switch on reset is possible. */ -/* 2020-3-14 - Refactoring based on latest sources */ -/* TODO: Add database for ines 1.0 headers */ - #include "mapinc.h" #include "../ines.h" @@ -113,7 +53,7 @@ static uint8 *CHRRAM = NULL; static uint32 WRAMSIZE = 0; static uint32 CHRRAMSIZE = 0; -static uint8 fk23_regs[4] = { 0 }; +static uint8 fk23_regs[8] = { 0 }; /* JX9003B has eight registers, all others have four */ static uint8 mmc3_regs[12] = { 0 }; static uint8 mmc3_ctrl = 0; static uint8 mmc3_mirr = 0; @@ -122,19 +62,17 @@ static uint8 irq_count = 0; static uint8 irq_latch = 0; static uint8 irq_enabled = 0; static uint8 irq_reload = 0; -static uint8 cnrom_chr = 0; +static uint8 latch = 0; static uint8 dipswitch = 0; -static uint8 subType = 0; - -/* enable dipswitch settings for fk23/fk23ca, - * switchable on reset. Can enable different multicart-modes - * depending on address */ -static uint8 dipsw_enable = 0; +static uint8 subType = 0; /* NES 2.0 Submapper, denoting PCB variants */ +static uint8 jncota523 = 0; /* Jncota board with unusual wiring that turns 1 KiB CHR banks into 2 KiB banks, and has hard-wired nametable mirroring. */ +static uint8 dipsw_enable = 0; /* Change the address mask on every reset? */ +static uint8 after_power = 0; /* Used for detecting whether a DIP switch is used or not (see above) */ static SFORMAT StateRegs[] = { - { fk23_regs, 4, "EXPR" }, + { fk23_regs, 8, "EXPR" }, { mmc3_regs, 12, "M3RG" }, - { &cnrom_chr, 1, "CCHR" }, + { &latch, 1, "LATC" }, { &dipswitch, 1, "DPSW" }, { &mmc3_ctrl, 1, "M3CT" }, { &mmc3_mirr, 1, "M3MR" }, @@ -147,14 +85,17 @@ static SFORMAT StateRegs[] = { { 0 } }; -#define INVERT_PRG (mmc3_ctrl & 0x40) -#define INVERT_CHR (mmc3_ctrl & 0x80) -#define WRAM_ENABLED (mmc3_wram & 0x80) -#define WRAM_EXTENDED (mmc3_wram & 0x20) -#define FK23_ENABLED (mmc3_wram & 0x40) -#define MMC3_EXTENDED (fk23_regs[3] & 0x02) -#define CHR_CNROM_MODE (fk23_regs[0] & 0x40) -#define CHR_OUTER_BANK_SIZE (fk23_regs[0] & 0x10) +#define INVERT_PRG !!(mmc3_ctrl & 0x40) +#define INVERT_CHR !!(mmc3_ctrl & 0x80) +#define WRAM_ENABLED !!(mmc3_wram & 0x80) +#define WRAM_EXTENDED (!!(mmc3_wram & 0x20) && subType == 2) /* Extended A001 register. Only available on FS005 PCB. */ +#define FK23_ENABLED (!!(mmc3_wram & 0x40) || !WRAM_EXTENDED) /* Enable or disable registers in the $5xxx range. Only available on FS005 PCB. */ +#define PRG_MODE ( fk23_regs[0] & 0x07) +#define MMC3_EXTENDED !!( fk23_regs[3] & 0x02) /* Extended MMC3 mode, adding extra registers for switching the normally-fixed PRG banks C and E and for eight independent 1 KiB CHR banks. Only available on FK- and FS005 PCBs. */ +#define CHR_8K_MODE !!( fk23_regs[0] & 0x40) /* MMC3 CHR registers are ignored, apply outer bank only, and CNROM latch if it exists */ +#define CHR_CNROM_MODE (~fk23_regs[0] & 0x20 && subType == 1) /* Only subtype 1 has a CNROM latch, which can be disabled */ +#define CHR_OUTER_BANK_SIZE !!( fk23_regs[0] & 0x10) /* Switch between 256 and 128 KiB CHR, or 32 and 16 KiB CHR in CNROM mode */ +#define CHR_MIXED !!(WRAM_EXTENDED && mmc3_wram &0x04) /* First 8 KiB of CHR address space are RAM, then ROM */ static void cwrap(uint32 A, uint32 V) { @@ -166,20 +107,18 @@ static void cwrap(uint32 A, uint32 V) else if (CHRRAMSIZE && fk23_regs[0] & 0x20) bank = 0x10; - if (WRAM_EXTENDED) { - if ((mmc3_wram & 0x04) && V < 8) bank = 0x10; /* first 8K of chr bank is ram */ - else bank = 0; - } + if (CHR_MIXED && V < 8) bank = 0x10; /* first 8K of chr bank is RAM */ setchr1r(bank, A, V); } static void SyncCHR(void) { - if (CHR_CNROM_MODE) + uint32 outer = fk23_regs[2] | (subType == 3? (fk23_regs[6] << 8): 0); /* Outer 8 KiB CHR bank. Subtype 3 has an MSB register providing more bits. */ + if (CHR_8K_MODE) { - uint32 mask = (fk23_regs[3] & 0x46) ? (CHR_OUTER_BANK_SIZE ? 0x01 : 0x03) : 0; - uint32 bank = (fk23_regs[2] | (cnrom_chr & mask)) << 3; + uint32 mask = (CHR_CNROM_MODE? (CHR_OUTER_BANK_SIZE? 0x01: 0x03): 0x00); + uint32 bank = ((outer & ~mask) | (latch & mask)) << 3; /* Address bits are never OR'd; they either come from the outer bank or from the CNROM latch. */ cwrap(0x0000, bank + 0); cwrap(0x0400, bank + 1); @@ -193,78 +132,95 @@ static void SyncCHR(void) } else { - uint32 cbase = (INVERT_CHR ? 0x1000 : 0); - uint32 outer = (fk23_regs[2] << 3); - uint32 cmask = (CHR_OUTER_BANK_SIZE ? 0x7F : 0xFF); + uint32 cbase = (INVERT_CHR? 0x1000: 0); + uint32 mask = (CHR_OUTER_BANK_SIZE? 0x7F: 0xFF); + outer = (outer << 3) & ~mask; /* From 8 KiB to 1 KiB banks. Address bits are never OR'd; they either come from the outer bank or from the MMC3. */ if (MMC3_EXTENDED) { - cwrap(cbase ^ 0x0000, mmc3_regs[0] | outer); - cwrap(cbase ^ 0x0400, mmc3_regs[10] | outer); - cwrap(cbase ^ 0x0800, mmc3_regs[1] | outer); - cwrap(cbase ^ 0x0c00, mmc3_regs[11] | outer); + cwrap(cbase ^ 0x0000, mmc3_regs[0] &mask | outer); + cwrap(cbase ^ 0x0400, mmc3_regs[10] &mask | outer); + cwrap(cbase ^ 0x0800, mmc3_regs[1] &mask | outer); + cwrap(cbase ^ 0x0c00, mmc3_regs[11] &mask | outer); - cwrap(cbase ^ 0x1000, mmc3_regs[2] | outer); - cwrap(cbase ^ 0x1400, mmc3_regs[3] | outer); - cwrap(cbase ^ 0x1800, mmc3_regs[4] | outer); - cwrap(cbase ^ 0x1c00, mmc3_regs[5] | outer); + cwrap(cbase ^ 0x1000, mmc3_regs[2] &mask | outer); + cwrap(cbase ^ 0x1400, mmc3_regs[3] &mask | outer); + cwrap(cbase ^ 0x1800, mmc3_regs[4] &mask | outer); + cwrap(cbase ^ 0x1c00, mmc3_regs[5] &mask | outer); } else { - cwrap(cbase ^ 0x0000, ((mmc3_regs[0] & cmask) & 0xFE) | outer); - cwrap(cbase ^ 0x0400, ((mmc3_regs[0] & cmask) | 0x01) | outer); - cwrap(cbase ^ 0x0800, ((mmc3_regs[1] & cmask) & 0xFE) | outer); - cwrap(cbase ^ 0x0C00, ((mmc3_regs[1] & cmask) | 0x01) | outer); + cwrap(cbase ^ 0x0000,(mmc3_regs[0] & 0xFE) & mask | outer); + cwrap(cbase ^ 0x0400,(mmc3_regs[0] | 0x01) & mask | outer); + cwrap(cbase ^ 0x0800,(mmc3_regs[1] & 0xFE) & mask | outer); + cwrap(cbase ^ 0x0C00,(mmc3_regs[1] | 0x01) & mask | outer); - cwrap(cbase ^ 0x1000, (mmc3_regs[2] & cmask) | outer); - cwrap(cbase ^ 0x1400, (mmc3_regs[3] & cmask) | outer); - cwrap(cbase ^ 0x1800, (mmc3_regs[4] & cmask) | outer); - cwrap(cbase ^ 0x1c00, (mmc3_regs[5] & cmask) | outer); + cwrap(cbase ^ 0x1000, mmc3_regs[2] & mask | outer); + cwrap(cbase ^ 0x1400, mmc3_regs[3] & mask | outer); + cwrap(cbase ^ 0x1800, mmc3_regs[4] & mask | outer); + cwrap(cbase ^ 0x1c00, mmc3_regs[5] & mask | outer); } } } static void SyncPRG(void) { - uint32 prg_mode = (fk23_regs[0] & 7); - uint32 prg_base = (fk23_regs[1] & 0x07F) | ((fk23_regs[0] << 4) & 0x080) | - ((fk23_regs[0] << 1) & 0x100) | ((fk23_regs[2] << 3) & 0x600) | - ((fk23_regs[2] << 6) & 0x800); - - switch (prg_mode) + uint32 mask = 0x3F >> PRG_MODE; /* For PRG modes 0-2, the mode# decides how many bits of the inner 8 KiB bank are used. This is greatly relevant to map the correct bank that contains the reset vectors. */ + uint32 prg_base = fk23_regs[1] & 0x7F; /* The bits for the first 2 MiB are the same between all the variants. */ + switch (subType) { - case 4: - setprg32(0x8000, (prg_base >> 1)); - break; - case 3: - setprg16(0x8000, prg_base); - setprg16(0xC000, prg_base); - break; - case 0: - case 1: - case 2: - { - uint32 cbase = (INVERT_PRG ? 0x4000 : 0); - uint32 mask = (0x3F >> prg_mode); - - prg_base <<= 1; - - if (MMC3_EXTENDED) - { - setprg8(0x8000 ^ cbase, mmc3_regs[6] | prg_base); - setprg8(0xA000, mmc3_regs[7] | prg_base); - setprg8(0xC000 ^ cbase, mmc3_regs[8] | prg_base); - setprg8(0xE000, mmc3_regs[9] | prg_base); - } - else - { - setprg8(0x8000 ^ cbase, (mmc3_regs[6] & mask) | (prg_base & ~mask)); - setprg8(0xA000, (mmc3_regs[7] & mask) | (prg_base & ~mask)); - setprg8(0xC000 ^ cbase, (0xFE & mask) | (prg_base & ~mask)); - setprg8(0xE000, (0xFF & mask) | (prg_base & ~mask)); - } - break; + case 1: /* FK-xxx */ + if (PRG_MODE == 0) mask = 0xFF; /* Mode 0 allows the MMC3 to address 2 MiB rather than the usual 512 KiB. */ + break; + case 2: /* FS005 */ + prg_base |= fk23_regs[0] << 4 & 0x080 | fk23_regs[0] << 1 & 0x100 | fk23_regs[2] << 3 & 0x600 | fk23_regs[2] << 6 & 0x800; + break; + case 3: /* JX9003B */ + if (PRG_MODE == 0) mask = 0xFF; /* Mode 0 allows the MMC3 to address 2 MiB rather than the usual 512 KiB. */ + prg_base |= fk23_regs[5] << 7; + break; + case 4: /* GameStar Smart Genius Deluxe */ + prg_base |= fk23_regs[2] & 0x80; + break; } + + switch (PRG_MODE) + { + case 0: /* MMC3 with 512 KiB or 2 MiB addressable */ + case 1: /* MMC3 with 256 KiB addressable */ + case 2: /* MMC3 with 128 KiB addressable */ + { + uint32 cbase = (INVERT_PRG ? 0x4000 : 0); + + prg_base =(prg_base << 1) & ~mask; /* from 16 to 8 KiB. Address bits are never OR'd; they either come from the outer bank or from the MMC3. */ + + if (MMC3_EXTENDED) + { + setprg8(0x8000 ^ cbase, mmc3_regs[6] & mask | prg_base); + setprg8(0xA000, mmc3_regs[7] & mask | prg_base); + setprg8(0xC000 ^ cbase, mmc3_regs[8] & mask | prg_base); + setprg8(0xE000, mmc3_regs[9] & mask | prg_base); + } + else + { + setprg8(0x8000 ^ cbase, (mmc3_regs[6] & mask) | prg_base); + setprg8(0xA000, (mmc3_regs[7] & mask) | prg_base); + setprg8(0xC000 ^ cbase, (0xFE & mask) | prg_base); + setprg8(0xE000, (0xFF & mask) | prg_base); + } + break; + } + case 3: /* NROM-128 */ + setprg16(0x8000, prg_base); + setprg16(0xC000, prg_base); + break; + case 4: /* NROM-256 */ + setprg32(0x8000, (prg_base >> 1)); + break; + case 5: /* UNROM */ + setprg16(0x8000, latch & 0x07 | prg_base &~0x07); + setprg16(0xC000, 0x07 | prg_base ); + break; } } @@ -275,7 +231,6 @@ static void SyncWRAM(void) { if (WRAM_EXTENDED) { - /* FIXME:this does not look normal, but it works, $5000-$5fff */ setprg8r(0x10, 0x4000, (mmc3_wram & 0x03) + 1); setprg8r(0x10, 0x6000, mmc3_wram & 0x03); } @@ -286,7 +241,7 @@ static void SyncWRAM(void) static void SyncMIR(void) { - switch (mmc3_mirr & (WRAM_EXTENDED ? 0x03 : 0x01)) + switch (mmc3_mirr & (subType == 2? 0x03 : 0x01)) { case 0: setmirror(MI_V); break; case 1: setmirror(MI_H); break; @@ -305,11 +260,14 @@ static void Sync(void) static DECLFW(Write5000) { - if (((WRAM_EXTENDED == 0) || FK23_ENABLED) && (A & (0x10 << dipswitch))) + if (after_power && A > 0x5010 && A != 0x5FF3) /* Ignore writes from $5000-$500F, in particular to $5008, but not $5FF3 */ + { + after_power = 0; + dipsw_enable = A >= 0x5020; /* The DIP switch change on soft-reset is enabled if the first write after power-on is not to $501x */ + } + if (FK23_ENABLED && (A & (0x10 << dipswitch))) { - fk23_regs[A & 3] = V; - if ((A & 3) == 2) - cnrom_chr = 0; + fk23_regs[A & (subType == 3? 7: 3)] = V; SyncPRG(); SyncCHR(); } @@ -320,93 +278,79 @@ static DECLFW(Write5000) static DECLFW(Write8000) { - switch (A & 0xF000) + latch = V; + if (CHR_8K_MODE && CHR_CNROM_MODE) SyncCHR(); /* CNROM latch updated */ + if (PRG_MODE == 5) SyncPRG(); /* UNROM latch has been updated */ + + switch (A & 0xE001) { - case 0x8000: - case 0x9000: - case 0xC000: - case 0xD000: - case 0xE000: - case 0xF000: - if (!CHR_CNROM_MODE) - break; - cnrom_chr = V & 0x03; - if ((fk23_regs[0] & 0x07) == 0x03) - cnrom_chr = 0; - - SyncCHR(); - break; - default: - break; - } - - switch (A & 0xF001) - { - case 0x8000: - { - uint8 old_ctrl = mmc3_ctrl; - - /* Subtype 2, 8192 or more KiB PRG-ROM, no CHR-ROM: Like Subtype 0, - * but MMC3 registers $46 and $47 swapped. */ - if (subType == 2) + case 0x8000: { - if (V == 0x46) - V = 0x47; - else if (V == 0x47) - V = 0x46; - } - - mmc3_ctrl = V; - - if (INVERT_PRG != (old_ctrl & 0x40)) - SyncPRG(); - - if (INVERT_CHR != (old_ctrl & 0x80)) - SyncCHR(); - - break; - } - case 0x8001: - { - uint8 ctrl_mask = MMC3_EXTENDED ? 0x0F : 0x07; - - if ((mmc3_ctrl & ctrl_mask) < 12) - { - mmc3_regs[mmc3_ctrl & ctrl_mask] = V; - - if (((mmc3_ctrl & ctrl_mask) < 6) || ((mmc3_ctrl & ctrl_mask) >= 10)) - SyncCHR(); - else + if (A & 2) return; /* Confirmed on real hardware: writes to 8002 and 8003, or 9FFE and 9FFF, are ignored. Needed for Dr. Mario on some of the "bouncing ball" multis. */ + uint8 old_ctrl = mmc3_ctrl; + + /* Subtype 2, 8192 or more KiB PRG-ROM, no CHR-ROM: Like Subtype 0, + * but MMC3 registers $46 and $47 swapped. */ + if (subType == 2) + { + if (V == 0x46) + V = 0x47; + else if (V == 0x47) + V = 0x46; + } + + mmc3_ctrl = V; + + if (INVERT_PRG != (old_ctrl & 0x40)) SyncPRG(); + + if (INVERT_CHR != (old_ctrl & 0x80)) + SyncCHR(); + + break; } - break; - } - case 0xA000: - mmc3_mirr = V; - SyncMIR(); - break; - case 0xA001: - /* ignore bits when ram config register is disabled */ - if ((V & 0x20) == 0) - V &= 0xC0; - mmc3_wram = V; - Sync(); - break; - case 0xC000: - irq_latch = V; - break; - case 0xC001: - irq_reload = 1; - break; - case 0xE000: - X6502_IRQEnd(FCEU_IQEXT); - irq_enabled = 0; - break; - case 0xE001: - irq_enabled = 1; - break; - default: - break; + case 0x8001: + { + if (A & 2) return; /* Confirmed on real hardware: writes to 8002 and 8003, or 9FFE and 9FFF, are ignored. Needed for Dr. Mario on some of the "bouncing ball" multis. */ + uint8 ctrl_mask = MMC3_EXTENDED ? 0x0F : 0x07; + + if ((mmc3_ctrl & ctrl_mask) < 12) + { + mmc3_regs[mmc3_ctrl & ctrl_mask] = V; + + if (((mmc3_ctrl & ctrl_mask) < 6) || ((mmc3_ctrl & ctrl_mask) >= 10)) + SyncCHR(); + else + SyncPRG(); + } + break; + } + case 0xA000: + mmc3_mirr = V; + SyncMIR(); + break; + case 0xA001: + /* ignore bits when ram config register is disabled */ + if ((V & 0x20) == 0) + V &= 0xC0; + mmc3_wram = V; + Sync(); + break; + case 0xC000: + irq_latch = V; + break; + case 0xC001: + irq_reload = 1; + break; + case 0xE000: + X6502_IRQEnd(FCEU_IQEXT); + irq_enabled = 0; + break; + case 0xE001: + irq_enabled = 1; + break; + default: + break; } } @@ -447,14 +391,13 @@ static void Reset(void) mmc3_wram = 0x80; mmc3_ctrl = mmc3_mirr = irq_count = irq_latch = irq_enabled = 0; - if (subType == 1) - fk23_regs[1] = 0x20; - Sync(); } static void Power(void) { + dipsw_enable = 0; /* Initially zero. Will be set to 1 according to the described heuristic, causing the DIP switch to be increased on the next soft reset .*/ + after_power = 1; fk23_regs[0] = fk23_regs[1] = fk23_regs[2] = fk23_regs[3] = 0; mmc3_regs[0] = 0; mmc3_regs[1] = 2; @@ -471,13 +414,10 @@ static void Power(void) mmc3_wram = 0x80; mmc3_ctrl = mmc3_mirr = irq_count = irq_latch = irq_enabled = 0; - if (subType == 1) - fk23_regs[1] = 0x20; - Sync(); SetReadHandler(0x8000, 0xFFFF, CartBR); - SetWriteHandler(0x5000, 0x5fff, Write5000); + SetWriteHandler(0x5000, 0x5FFF, Write5000); SetWriteHandler(0x8000, 0xFFFF, Write8000); if (WRAMSIZE) @@ -506,7 +446,6 @@ static void StateRestore(int version) void GenBMCFK23C_Init(CartInfo *info) { - dipsw_enable = 0; info->Power = Power; info->Reset = Reset; @@ -538,11 +477,18 @@ void GenBMCFK23C_Init(CartInfo *info) } } - subType = 0; - if (((ROM_size * 16) == 1024) && ((VROM_size * 8) == 1024)) - subType = 1; - else if (UNIFchrrama && ((ROM_size << 4) >= 8192)) - subType = 2; + if (info->iNES2) + { + subType = info->submapper; + } + else + { + subType = 0; + if (((ROM_size * 16) == 1024) && ((VROM_size * 8) == 1024)) + subType = 1; + else if (UNIFchrrama && ((ROM_size << 4) >= 8192)) + subType = 2; + } } /* generic entry point for mapper 176 / bmcfk23c carts */ @@ -572,7 +518,6 @@ void BMCFK23C_Init(CartInfo *info) { } GenBMCFK23C_Init(info); - dipsw_enable = 1; } /* UNIF Boards, declares so we can for chr mixed mode size and wram if any */ @@ -586,7 +531,6 @@ void BMCFK23CA_Init(CartInfo *info) WRAMSIZE = 8 * 1024; GenBMCFK23C_Init(info); - dipsw_enable = 1; } /* BMC-Super24in1SC03 */ From b02fa46cb131a95a56b8a3940d15b012f68d1dda Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Wed, 26 May 2021 20:36:06 +0200 Subject: [PATCH 112/295] Add support for Jncota variant, mapper 523 --- src/boards/fk23c.c | 49 +++++++++++++++++++++++++++++++++------------- src/ines.c | 1 + src/ines.h | 1 + 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index cda8cf8..2a4e8f2 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -21,7 +21,7 @@ /* Mappers: 176 - Standard - 523 - Jncota KT-xxx (1 KiB->2 KiB, 2 KiB->4 KiB CHR, hard-wired nametable mirroring) + 523 - Jncota KT-xxx, re-release of 封神榜꞉ 伏魔三太子: 1 KiB->2 KiB, 2 KiB->4 KiB CHR, hard-wired nametable mirroring) Submappers: 0 - Standard @@ -101,15 +101,22 @@ static void cwrap(uint32 A, uint32 V) { int bank = 0; - /* some workaround for chr rom / ram access */ - if (!VROM_size) - bank = 0; - else if (CHRRAMSIZE && fk23_regs[0] & 0x20) - bank = 0x10; - - if (CHR_MIXED && V < 8) bank = 0x10; /* first 8K of chr bank is RAM */ - - setchr1r(bank, A, V); + if (jncota523) + { + if (~A &0x0400) setchr2r(bank, A, V); + } + else + { + /* some workaround for chr rom / ram access */ + if (!VROM_size) + bank = 0; + else if (CHRRAMSIZE && fk23_regs[0] & 0x20) + bank = 0x10; + + if (CHR_MIXED && V < 8) bank = 0x10; /* first 8K of chr bank is RAM */ + + setchr1r(bank, A, V); + } } static void SyncCHR(void) @@ -241,12 +248,15 @@ static void SyncWRAM(void) static void SyncMIR(void) { + if (jncota523) /* Jncota board has hard-wired mirroring */ + return; + else switch (mmc3_mirr & (subType == 2? 0x03 : 0x01)) { - case 0: setmirror(MI_V); break; - case 1: setmirror(MI_H); break; - case 2: setmirror(MI_0); break; - case 3: setmirror(MI_1); break; + case 0: setmirror(MI_V); break; + case 1: setmirror(MI_H); break; + case 2: setmirror(MI_0); break; + case 3: setmirror(MI_1); break; } } @@ -517,6 +527,7 @@ void BMCFK23C_Init(CartInfo *info) { WRAMSIZE = 8 * 1024; } + jncota523 = 0; GenBMCFK23C_Init(info); } @@ -530,6 +541,7 @@ void BMCFK23CA_Init(CartInfo *info) WRAMSIZE = 8 * 1024; + jncota523 = 0; GenBMCFK23C_Init(info); } @@ -539,6 +551,7 @@ void Super24_Init(CartInfo *info) { if (!UNIFchrrama) CHRRAMSIZE = 8 * 1024; + jncota523 = 0; GenBMCFK23C_Init(info); } @@ -551,5 +564,13 @@ void WAIXINGFS005_Init(CartInfo *info) WRAMSIZE = 32 * 1024; + jncota523 = 0; + GenBMCFK23C_Init(info); +} + +void Mapper523_Init(CartInfo *info) +{ + jncota523 = 1; + WRAMSIZE = 8 * 1024; GenBMCFK23C_Init(info); } diff --git a/src/ines.c b/src/ines.c index 449cc2d..8f299c1 100644 --- a/src/ines.c +++ b/src/ines.c @@ -793,6 +793,7 @@ INES_BOARD_BEGIN() INES_BOARD( "EH8813A", 519, UNLEH8813A_Init ) INES_BOARD( "DREAMTECH01", 521, DreamTech01_Init ) INES_BOARD( "LH10", 522, LH10_Init ) + INES_BOARD( "Jncota KT-???", 523, Mapper523_Init ) INES_BOARD( "900218", 524, BTL900218_Init ) INES_BOARD( "KS7021A", 525, UNLKS7021A_Init ) INES_BOARD( "BJ-56", 526, UNLBJ56_Init ) diff --git a/src/ines.h b/src/ines.h index ad0556e..94912ea 100644 --- a/src/ines.h +++ b/src/ines.h @@ -284,6 +284,7 @@ void Mapper421_Init(CartInfo *); void Mapper422_Init(CartInfo *); void Mapper428_Init(CartInfo *); void Mapper516_Init(CartInfo *); +void Mapper523_Init(CartInfo *); void Mapper533_Init(CartInfo *); void Mapper534_Init(CartInfo *); void Mapper538_Init(CartInfo *); From ce2d55c3e83710cecad661ff48b7011225f3d435 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Fri, 28 May 2021 21:22:18 +0200 Subject: [PATCH 113/295] Update the database for mapper 176 games. Set the iNES2 flag when the submapper field is used. --- src/boards/fk23c.c | 151 +++-- src/ines-correct.h | 1569 +++++++++++++++++++++++--------------------- src/ines.c | 3 +- src/ines.h | 1 + 4 files changed, 931 insertions(+), 793 deletions(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index 2a4e8f2..7f75d46 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -406,8 +406,6 @@ static void Reset(void) static void Power(void) { - dipsw_enable = 0; /* Initially zero. Will be set to 1 according to the described heuristic, causing the DIP switch to be increased on the next soft reset .*/ - after_power = 1; fk23_regs[0] = fk23_regs[1] = fk23_regs[2] = fk23_regs[3] = 0; mmc3_regs[0] = 0; mmc3_regs[1] = 2; @@ -454,9 +452,9 @@ static void StateRestore(int version) Sync(); } -void GenBMCFK23C_Init(CartInfo *info) +void Init(CartInfo *info) { - + /* Initialization for iNES and UNIF. subType and dipsw_enable must have been set. */ info->Power = Power; info->Reset = Reset; info->Close = Close; @@ -487,90 +485,121 @@ void GenBMCFK23C_Init(CartInfo *info) } } +} + +void Mapper176_Init(CartInfo *info) { /* .NES file */ + dipsw_enable = 0; + jncota523 = 0; if (info->iNES2) { subType = info->submapper; - } - else - { - subType = 0; - if (((ROM_size * 16) == 1024) && ((VROM_size * 8) == 1024)) - subType = 1; - else if (UNIFchrrama && ((ROM_size << 4) >= 8192)) - subType = 2; - } -} - -/* generic entry point for mapper 176 / bmcfk23c carts */ -void BMCFK23C_Init(CartInfo *info) { - /* prepare ROM params before loading... */ - if (info->iNES2) - { - if (!UNIFchrrama) - CHRRAMSIZE = info->CHRRamSize + info->CHRRamSaveSize; + after_power = subType != 2; /* FS005 never has DIP switches, the others may have one, so use the heuristic. */ + CHRRAMSIZE = info->CHRRamSize + info->CHRRamSaveSize; WRAMSIZE = info->PRGRamSize + info->PRGRamSaveSize; } else { - if (!UNIFchrrama) - { - /* Rockman I - VI uses mixed chr rom/ram */ - if ((ROM_size * 16) == 2048 && (VROM_size * 8) == 512) - CHRRAMSIZE = 8 * 1024; - } - - /* Waixing boards has 32K battery backed wram */ + /* Waixing boards have 32K battery backed wram */ if (info->battery) + { + subType = 2; + after_power = 0; WRAMSIZE = 32 * 1024; + } else - /* Always enable WRAM for ines-headered roms, lets see who complains */ + { + /* Always enable WRAM for iNES-headered files */ WRAMSIZE = 8 * 1024; + + /* Distinguishing subType 1 from subType 0 is important for the correct reset vector location. + It is safe to assume subType 1 except for 1024+512 KiB ROMs. */ + subType = (ROM_size ==128 && VROM_size ==256 || /* 2048+2048 */ + ROM_size ==128 && VROM_size ==128 || /* 2048+1024 */ + ROM_size ==128 && VROM_size ==64 || /* 2048+512 */ + ROM_size ==128 && VROM_size ==0 || /* 2048+0 */ + ROM_size ==64 && VROM_size ==64)? /* 1024+512 */ + 0: 1; + + /* Detect heuristically whether the address mask should be changed on every soft reset */ + after_power = 1; + } } - - jncota523 = 0; - GenBMCFK23C_Init(info); + Init(info); } -/* UNIF Boards, declares so we can for chr mixed mode size and wram if any */ - -void BMCFK23CA_Init(CartInfo *info) +void BMCFK23C_Init(CartInfo *info) /* UNIF FK23C */ { - /* can use mixed chr rom/ram */ if (!UNIFchrrama) - CHRRAMSIZE = 8 * 1024; - + { + /* Rockman I-VI uses mixed chr rom/ram */ + if ((ROM_size * 16) == 2048 && (VROM_size * 8) == 512) + CHRRAMSIZE = 8 * 1024; + } WRAMSIZE = 8 * 1024; + /* UNIF FK23C differs from UNIF FK23CA explicitly by the absence of a DIP switch */ + dipsw_enable = 0; + after_power = 0; jncota523 = 0; - GenBMCFK23C_Init(info); + + /* The UNIF MAPR tells us nothing about whether it is subtype 0 or 1 */ + subType = (ROM_size ==128 && VROM_size ==256 || /* 2048+2048 */ + ROM_size ==128 && VROM_size ==128 || /* 2048+1024 */ + ROM_size ==128 && VROM_size ==64 || /* 2048+512 */ + ROM_size ==128 && VROM_size ==0 || /* 2048+0 */ + ROM_size ==64 && VROM_size ==64)? /* 1024+512 */ + 0: 1; + + Init(info); } -/* BMC-Super24in1SC03 */ -void Super24_Init(CartInfo *info) { - /* can use mixed chr rom/ram */ - if (!UNIFchrrama) - CHRRAMSIZE = 8 * 1024; - - jncota523 = 0; - GenBMCFK23C_Init(info); -} - -void WAIXINGFS005_Init(CartInfo *info) +void BMCFK23CA_Init(CartInfo *info) /* UNIF FK23CA */ { - /* can have 8 or 32 KB battery-backed prg ram - * plus 8 KB chr for these boards */ - if (!UNIFchrrama) - CHRRAMSIZE = 8 * 1024; + WRAMSIZE = 8 * 1024; + /* UNIF FK23CA differs from UNIF FK23C explicitly by the presence of a DIP switch */ + dipsw_enable = 1; + after_power = 0; + jncota523 = 0; + + /* The UNIF MAPR tells us nothing about whether it is subtype 0 or 1 */ + subType = (ROM_size ==128 && VROM_size ==256 || /* 2048+2048 */ + ROM_size ==128 && VROM_size ==128 || /* 2048+1024 */ + ROM_size ==128 && VROM_size ==64 || /* 2048+512 */ + ROM_size ==128 && VROM_size ==0 || /* 2048+0 */ + ROM_size ==64 && VROM_size ==64)? /* 1024+512 */ + 0: 1; + + Init(info); +} + +void Super24_Init(CartInfo *info) /* UNIF BMC-Super24in1SC03 */ +{ + CHRRAMSIZE = 8 * 1024; + dipsw_enable = 0; + after_power = 0; + jncota523 = 0; + subType = 0; + Init(info); +} + +void WAIXINGFS005_Init(CartInfo *info) /* UNIF WAIXING-FS005 */ +{ + CHRRAMSIZE = 8 * 1024; WRAMSIZE = 32 * 1024; - + dipsw_enable = 0; + after_power = 0; jncota523 = 0; - GenBMCFK23C_Init(info); + subType = 2; + Init(info); } -void Mapper523_Init(CartInfo *info) +void Mapper523_Init(CartInfo *info) /* Jncota Fengshengban */ { - jncota523 = 1; WRAMSIZE = 8 * 1024; - GenBMCFK23C_Init(info); + dipsw_enable = 0; + after_power = 0; + jncota523 = 1; + subType = 1; + Init(info); } diff --git a/src/ines-correct.h b/src/ines-correct.h index 990395b..159e9a6 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -1,731 +1,838 @@ -#ifndef _FCEU_INES_CORRECT_H -#define _FCEU_INES_CORRECT_H - - /* ROM images that have the battery-backed bit set in the header that really - don't have battery-backed RAM is not that big of a problem, so I'll - treat this differently by only listing games that should have battery-backed RAM. - */ - /* CRC32, mapperNum, SubMapper, Mirroring, hasBattery, prgRam, chrRam, region, extra flags */ - { 0xb17574f3, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* AD&D Heroes of the Lance */ - { 0x5de61639, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* AD&D Hillsfar */ - { 0x2545214c, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* DW */ - { 0x3b3f88f0, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* DW */ - { 0x8c5a784e, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* DW 2 */ - { 0x506e259d, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* DW 4*/ - { 0xa86a5318, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Dw 3 */ - { 0x45f03d2e, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Faria */ - { 0xb8b88130, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy (FFE Hack) */ - { 0xcebd2a31, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy */ - { 0xd29db3c7, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy 2 */ - { 0x466efdc2, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy J */ - { 0xeaf7ed72, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Legend of Zelda */ - { 0x3fe272fb, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Legend of Zelda */ - { 0xba322865, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Zelda 2 */ - { 0x25952141, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* AD&D Pool of Radiance */ - { 0x1335cb05, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Crystalis */ - { 0x57e220d0, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Final Fantasy 3 */ - { 0x889129cb, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Startropics */ - { 0xd054ffb0, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Startropics 2*/ - { 0xb5ff71ab, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Battle Fleet */ - { 0x0c1792da, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '90 */ - { 0x47c2020b, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Hydlide 3*/ - { 0xbc11e61a, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kaijuu Monogatari */ - { 0xace56f39, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mindseeker */ - { 0xe1383deb, 26, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mouryou Senki Madara */ - { 0xde9c9c64, 80, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kyonshiizu 2 */ - { 0x0e1683c5, 80, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mirai Shinwa Jarvas */ - - { 0xaf5d7aa2, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Clu Clu Land (W) [o3].nes */ - { 0xcfb224e6, 222, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ninja (J) (PRG0) [p1][!].nes */ - { 0x82f204ae, 163, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Liang Shan Ying Xiong (NJ023) (Ch) [!].nes */ - { 0xad9c63e2, 70, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Space Shadow (Japan).nes */ - { 0xe1526228, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ki no Bouken - The Quest of Ki (Japan).nes */ - { 0xaf5d7aa2, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Clu Clu Land (W) [o3].nes */ - { 0xcfb224e6, 222, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ninja (J) (PRG0) [p1][!].nes */ - { 0xfcdaca80, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Elevator Action (Japan).nes */ - { 0xc05a365b, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Chou Fuyuu Yousai Exed Exes (Japan).nes */ - { 0xc4c3949a, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mario Bros. (World).nes */ - { 0x32fa246f, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tag Team Pro-Wrestling (Japan).nes */ - { 0x43d30c2f, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ms. Pac-Man (USA) (Tengen) (Unl).nes */ - { 0xb3c30bea, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Xevious (Japan) (En).nes */ - { 0xe492d45a, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Zippy Race (Japan).nes */ - { 0x24598791, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Duck Hunt (World).nes */ - { 0x49aeb3a6, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Excitebike (Japan, USA).nes */ - { 0xb8535ca3, 0, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mahjong (Japan).nes */ - { 0x330de468, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Obake no Q Tarou - Wanwan Panic (Japan).nes */ - { 0xe28f2596, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pac-Land (J) [b2].nes */ - { 0x5112dc21, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wild Gunman (World) (Rev 1).nes */ - { 0xd8ee7669, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Adventures of Rad Gravity, The (USA).nes */ - { 0x5b837e8d, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Alien Syndrome (Japan).nes */ - { 0x37ba3261, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Back to the Future Part II & III (USA).nes */ - { 0x5b6ca654, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Barbie (USA).nes */ - { 0x61a852ea, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Battle Stadium - Senbatsu Pro Yakyuu (Japan).nes */ - { 0xf6fa4453, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bigfoot (U) [b4].nes */ - { 0x391aa1b8, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Bloody Warriors - Shan-Go no Gyakushuu (Japan).nes */ - { 0xa5e8d2cd, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* BreakThru (USA).nes */ - { 0x3f56a392, 1, DEFAULT, DFAULT8, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Captain ED (Japan).nes */ - { 0x078ced30, 1, DEFAULT, DFAULT8, 1, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* Choujin - Ultra Baseball (Japan).nes */ - { 0xfe364be5, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Deep Dungeon IV - Kuro no Youjutsushi (Japan).nes */ - { 0x57c12280, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Demon Sword (U) [b1].nes */ - { 0xd09b74dc, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Great Tank (Japan).nes */ - { 0xe8baa782, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Gunhed - Aratanaru Tatakai (Japan).nes */ - { 0x970bd9c2, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hanjuku Eiyuu (J) [b1].nes */ - { 0xcd7a2fd7, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hanjuku Hero (Japan).nes */ - { 0x63469396, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hokuto no Ken 4 - Shichisei Haken Den - Hokuto Shinken no Kanata e (Japan).nes */ - { 0xe94d5181, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Future Wars - Mirai Senshi Lios (Japan).nes */ - { 0x7156cb4d, 1, DEFAULT, DFAULT8, 0, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Muppet Adventure - Chaos at the Carnival (USA).nes */ - { 0x70f67ab7, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Musashi no Bouken (Japan).nes */ - { 0x958e4bae, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Orb-3D (USA).nes */ - { 0x291bcd7d, 1, DEFAULT, DFAULT8, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Pachio-kun 2 (Japan).nes */ - { 0xa9a4ea4c, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Satomi Hakkenden (J) [b2].nes */ - { 0xcc3544b0, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Triathron, The (Japan).nes */ - { 0x52ab2d17, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Toukyou Pachi-Slot Adventure (Japan).nes */ - { 0x934db14a, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* All-Pro Basketball (USA).nes */ - { 0xf74dfc91, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Win, Lose or Draw (USA).nes */ - { 0xcfe02ada, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Darkman (Europe).nes */ - { 0x1a71fd06, 1, DEFAULT, MI_H, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Kujaku Ou.nes */ - - /* MMC1 games with more than 8K wram */ - { 0x2225c20f, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* Genghis Khan */ - { 0xfb69743a, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) */ - { 0x4642dda6, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* Nobunaga's Ambition */ - { 0x3f7ad415, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG0) */ - { 0x2b11e0b0, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG1) */ - { 0xc6182024, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* Romance of the 3 Kingdoms */ - { 0xabbf7217, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG0) or Sangokushi */ - { 0xccf35c02, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG1) */ - { 0xb8747abf, 1, DEFAULT, DEFAULT, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Best Play Pro Yakyuu Special (J) (PRG0) */ - { 0xc3de7c69, 1, DEFAULT, DEFAULT, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG1) */ - { 0xc9556b36, 1, DEFAULT, DEFAULT, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy 1+2 */ - - { 0xe6a477b2, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3-D WorldRunner (USA).nes */ - { 0x9ea1dc76, 2, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rainbow Islands (USA).nes */ - { 0x6d65cac6, 2, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Terra Cresta (Japan).nes */ - { 0xe1b260da, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Argos no Senshi - Hachamecha Daishingeki (Japan).nes */ - { 0x1d0f4d6b, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Black Bass, The (USA).nes */ - { 0x266ce198, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* City Adventure Touch - Mystery of Triangle (J) [b1].nes */ - { 0x804f898a, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Unit (Japan).nes */ - { 0x55773880, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Adventures of Gilligan's Island, The (USA).nes */ - { 0x6e0eb43e, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Puss 'n Boots - Pero's Great Adventure (USA).nes */ - { 0x2bb6a0f8, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sherlock Holmes - Hakushaku Reijou Yuukai Jiken (Japan).nes */ - { 0x28c11d24, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sukeban Deka 3 (J) [b1].nes */ - { 0x02863604, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sukeban Deka III (Japan).nes */ - { 0x419461d0, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Cars (USA).nes */ - - /* CNROM by default has bus conflicts enabled, these requires no bus conflict to play correctly */ - { 0x2915faf0, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Incantation (Asia) (Ja) (Unl).nes */ - { 0x8f154a0d, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pu Ke Jing Ling (Asia) (Unl).nes */ - { 0xb0c871c5, 3, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wei Lai Xiao Zi (Joy Van).nes */ - { 0xb3be2f71, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yanshan Chess (Unl).nes */ - { 0xd04a40e6, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bingo 75 (Asia) (Ja) (Unl).nes */ - { 0xe41b440f, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sidewinder (Joy Van).nes */ - { 0xebd0644d, 3, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Master Chu & The Drunkard Hu (Joy Van).nes */ - { 0xf283cf58, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Colorful Dragon (Sachen).nes */ - { 0x2deb12b8, 3, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Venice Beach Volleyball (Asia) (Ja) (Super Mega) (Unl).nes */ - - { 0xdbf90772, 3, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Alpha Mission (USA).nes */ - { 0xd858033d, 3, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ASO - Armored Scrum Object (J).nes */ - { 0xd858033d, 3, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ASO - Armored Scrum Object (J).nes */ - { 0x637ba508, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Adan y Eva (Spain) (Gluk Video) (Unl).nes */ - { 0x9bde3267, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Adventures of Dino Riki (USA).nes */ - { 0xd8eff0df, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Gradius (Japan).nes */ - { 0x1d41cc8c, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Gyruss (USA).nes */ - { 0xcf322bb3, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* John Elway's Quarterback (USA).nes */ - { 0xb5d28ea2, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mystery Quest (USA).nes */ - { 0x02cc3973, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ninja Kid (USA).nes */ - { 0xbc065fc3, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pipe Dream (U) [b1].nes */ - { 0xc9ee15a7, 3, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Aladdin III (1995) (Unl) [hM03].nes */ - { 0x8dedea07, 3, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Shui Guo Li (Ch) [a1].nes */ - { 0x684afccd, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Space Hunter (Japan).nes */ - - { 0x97b6cb19, 4, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Aladdin (SuperGame) (Mapper 4) [!].nes */ - { 0xd97c31b0, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lasalle Ishii no Child's Quest (Japan).nes */ - { 0x404b2e8b, 4, DEFAULT, MI_4, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rad Racer II (USA).nes */ - { 0x15141401, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Asmik-kun Land (Japan).nes */ - { 0x4cccd878, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kyatto Ninden Teyandee (J) [b1].nes */ - { 0x59280bec, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jackie Chan (Japan).nes */ - { 0x7474ac92, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kabuki - Quantum Fighter (USA).nes */ - { 0xf2594374, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Matendouji (Japan).nes */ - { 0x5337f73c, 4, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Niji no Silk Road (Japan).nes */ - { 0x9eefb4b4, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pachi-Slot Adventure 2 - Sorotta-kun no Pachi-Slot Tanteidan (Japan).nes */ - { 0xafe03802, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pachio-kun 3 (Japan) (Rev A).nes */ - { 0x21a653c7, 4, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Sky Kid (VS).nes */ - { 0xdb7f07be, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Toki (USA) (Beta).nes */ - - /* MMC5 */ - { 0x671f23a8, 5, DEFAULT, DEFAULT, 0, 0, 0, PAL, NOEXTRA }, /* Castlevania III - Dracula's Curse (E) */ - { 0xcd4e7430, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Castlevania III - Dracula's Curse (KC) */ - { 0xed2465be, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Castlevania III - Dracula's Curse (U) */ - { 0x0afb395e, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Gun Sight */ - { 0xb0480ae9, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Laser Invasion */ - { 0xb4735fac, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Metal Slader Glory */ - { 0xbb7f829a, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Uchuu Keibitai SDF */ - { 0x0ec6c023, 5, DEFAULT, DEFAULT, 1, 0x70, 0, DEFAULT, NOEXTRA }, /* Gemfire */ - { 0x9cbadc25, 5, DEFAULT, DEFAULT, 1, 0x70, 0, DEFAULT, NOEXTRA }, /* Just Breed */ - { 0xbc80fb52, 5, DEFAULT, DEFAULT, 1, 0x70, 0, DEFAULT, NOEXTRA }, /* Royal Blood */ - { 0xd532e98f, 5, DEFAULT, DEFAULT, 1, 0x70, 0, DEFAULT, NOEXTRA }, /* Shin 4 Nin Uchi Mahjong - Yakuman Tengoku */ - { 0x15fe6d0f, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Bandit Kings of Ancient China */ - { 0xfe3488d1, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Daikoukai Jidai */ - { 0x1ced086f, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Ishin no Arashi */ - { 0x6396b988, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* L'Empereur (J) */ - { 0x9c18762b, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* L'Empereur (U) */ - { 0xeee9a682, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Nobunaga no Yabou - Sengoku Gunyuu Den (J) (PRG0) */ - { 0xf9b4240f, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Nobunaga no Yabou - Sengoku Gunyuu Den (J) (PRG1) */ - { 0x8ce478db, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Nobunaga's Ambition 2 */ - { 0x39f2ce4b, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Suikoden - Tenmei no Chikai */ - { 0xaca15643, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Uncharted Waters */ - { 0x6f4e4312, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Aoki Ookami to Shiroki Mejika - Genchou Hishi */ - { 0xf540677b, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Nobunaga no Yabou - Bushou Fuuun Roku */ - { 0xf011e490, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Romance of The Three Kingdoms II */ - { 0x184c2124, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Sangokushi II (J) (PRG0) */ - { 0xee8e6553, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Sangokushi II (J) (PRG1) */ - - { 0xf518dd58, 7, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain Skyhawk (USA).nes */ - { 0x6c4a9735, 7, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* WWF Wrestlemania (Europe).nes */ - { 0x84382231, 9, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Punch-Out!! (Japan) (Gold Edition).nes */ - { 0xbe939fce, 9, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Punch-Out!! (U) [b1].nes */ - { 0x7b837fde, 9, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mike Tyson's Punch-Out!! (PC10) [b1].nes */ - { 0x345d3a1a, 11, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Castle of Deceit (USA) (Unl).nes */ - { 0xb79f2651, 11, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Chiller (USA) (Unl).nes */ - { 0x5e66eaea, 13, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Videomation (USA).nes */ - { 0xcd373baa, 14, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 武士魂 (8 characters).nes */ - { 0xbfc7a2e9, 16, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball 3 - Gokuu Den (Japan) (Rev 1).nes */ - { 0x6e68e31a, 16, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball 3 - Gokuu Den (Japan).nes */ - { 0x33b899c9, 16, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball - Daimaou Fukkatsu (Japan).nes */ - { 0xa262a81f, 16, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rokudenashi Blues (Japan).nes */ - { 0x286fcd20, 21, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ganbare Goemon Gaiden 2 - Tenka no Zaihou (Japan).nes */ - { 0x335e6339, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* kung fu legend (unl)[!].nes */ - { 0x1a8d767b, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* kung fu legend (unl)[!p].nes */ - { 0x0e263d47, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* World Hero (Unl) (TV System Select) [!].nes */ - { 0xe4a291ce, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* World Hero (Unl) [!].nes */ - { 0x51e9cd33, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* World Hero (Unl) [b1].nes */ - { 0x105dd586, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mi Hun Che (Ch)(full copyrights)[!].nes */ - { 0xbc9bb6c1, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Car (Ch)(full copyrights)[!].nes */ - { 0x43753886, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mi Hun Che (Ch)(replaced copyrights)[p1][!].nes */ - { 0x5b3de3d1, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* -- */ - { 0x511e73f8, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mi Hun Che (Ch) [p1][b2].nes */ - { 0x5555fca3, 32, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Sensei no Oshiete - Watashi no Hoshi (J) [b1].nes */ - { 0x283ad224, 32, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Sensei no Oshiete - Watashi no Hoshi (Japan).nes */ - { 0x243a8735, 32, DEFAULT, 0x10|4, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Major League (Japan).nes */ - { 0x8a7d0abe, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Akira (Japan).nes */ - { 0x376138d8, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Akira (J) [a1].nes */ - { 0xadf606f6, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bakushou!! Jinsei Gekijou (Japan).nes */ - { 0xbc7b1d0f, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bakushou!! Jinsei Gekijou 2 (Japan).nes */ - { 0x7a497ae3, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Don Doko Don (Japan).nes */ - { 0xbaca10a9, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Golfkko Open (Japan).nes */ - { 0xf80bdc50, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Insector X (Japan).nes */ - { 0x2a6559a1, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Operation Wolf (Japan).nes */ - { 0xaeb7fce9, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Power Blazer (Japan).nes */ - { 0xd920f9df, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Takeshi no Sengoku Fuuunji (Japan).nes */ - { 0x3cd4b420, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Takeshi no Sengoku Fuuunji (Japan) (Beta).nes */ - { 0x4c7c1af3, 34, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Caesars Palace (U) [b1].nes */ - { 0x932ff06e, 34, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Classic Concentration (U) [b1].nes */ - { 0xf46ef39a, 37, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Super Mario Bros. + Tetris + Nintendo World Cup (Europe) (Rev 1).nes */ - { 0x4686c5dd, 41, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Caltron - 6 in 1 (USA) (Unl).nes */ - { 0x090c0c17, 42, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Senshi Nicol (FDS Conversion) [p1][!].nes */ - { 0x4df84825, 42, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Senshi Nicol (FDS Conversion) [p2][!].nes */ - { 0x579e5bc5, 42, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Senshi Nicol (FDS Conversion) [p3].nes */ - { 0xc744f205, 42, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Senshi Nicol (FDS Conversion) [p3][t1].nes */ - { 0x71699765, 42, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Love Warrior Nicol.nes */ - { 0x6bf3f6a3, 42, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bio Miracle Bokutte Upa (J) (Mario Baby - FDS Conversion).nes */ - { 0x5ba1c5cf, 42, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Green Beret (FDS Conversion) (Unl).nes */ - { 0x50ab1ab2, 42, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? Green Beret (FDS Conversion, LH09) (Unl) [U][!][t1] (160K PRG */ - { 0x7ccb12a3, 43, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? SMB2j */ - { 0x6c71feae, 45, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kunio 8-in-1 [p1].nes */ - { 0x40c0ad47, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Flintstones, The - The Rescue of Dino & Hoppy (Japan).nes */ - { 0xaebd6549, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bakushou!! Jinsei Gekijou 3 (Japan).nes */ - { 0x6cdc0cd9, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bubble Bobble 2 (Japan).nes */ - { 0x99c395f9, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain Saver (Japan).nes */ - { 0xa7b0536c, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Don Doko Don 2 (Japan).nes */ - { 0xb17c828a, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Don Doko Don 2 (J) [a1].nes */ - { 0x40c0ad47, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Flintstones, The - The Rescue of Dino & Hoppy (J).nes */ - { 0x1500e835, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jetsons, The - Cogswell's Caper (Japan).nes */ - { 0xe2c94bc2, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Bros 8 (Unl) [!].nes */ - { 0xa912b064, 51, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, 0x800 }, /* 11-in-1 Ball Games [p1][o1].nes (has CHR ROM when it shouldn't) */ - { 0x2e72a5d9, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 11-in-1 (66-in-1, 86-in-1, 63-in-1).nes */ - { 0x39f514fd, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 18 in 1 (118-in-1, 138-in-1, 198-in-1)VTxxxx.nes */ - { 0xd8b1f465, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 26-in-1 (36-in-1, 46-in-1,56-in-1) VT 335.nes */ - { 0xcf82fae9, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 28 in 1 (38-in-1, 48-in-1, 58-in1)VTxxxx.nes */ - { 0xa7a98698, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 28-in-1 (46-in-1, 63-in-1, 118-in-1)VT-5116.nes */ - { 0x21fd7143, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 41-in-1 (5-in-1,71-in-1) VT345.nes */ - { 0x49ec88d6, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 42-in-1 NT-234 Bad Game Road Fighter.nes */ - { 0x60306f19, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 42-in-1 PCB 3840.nes */ - { 0x450cd86e, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 48-in-1 (62-in-1,73-in-1,88-in-1) VTxxx.nes */ - { 0xd774e041, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 50-in-1 (60-in-1,70-in-1,80-in-1) NT-113.nes */ - { 0x3c4e94f6, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 51-in-1 (61-in-1, 71-in-1, 81-in-1) VT5310.nes */ - { 0x0422ed44, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 7-in-1 (32-in-1,66-in-1,119-in-1) VT15004.nes */ - { 0x7efc0d2c, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 7-in-1 (5000-in-1, 999999999-in-1, 10000000-in-1)NC-07N.nes */ - { 0x6d92dff1, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* TN 95-in-1 (6-in-1) [p1].nes */ - { 0x39ab0fc7, 64, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Hard Drivin' (USA) (Proto) (Unl).nes */ - { 0xb19a55dd, 64, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Road Runner (USA) (Unl).nes */ - { 0xf92be3ec, 64, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rolling Thunder (USA) (Unl).nes */ - { 0xd114f544, 66, DEFAULT, MI_H, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* AV Super Real Pachinko (Japan) (Unl).nes */ - { 0xe84274c5, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mississippi Satsujin Jiken (J) [h2].nes */ - { 0xbde3ae9b, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Doraemon (Japan).nes */ - { 0x9552e8df, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball - Shen Long no Nazo (Japan).nes */ - { 0x811f06d9, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Power (USA).nes */ - { 0xd26efd78, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Mario Bros. + Duck Hunt (USA).nes */ - { 0xdd8ed0f7, 70, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kamen Rider Club (Japan).nes */ - { 0xbba58be5, 70, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Family Trainer 6 - Manhattan Police (Japan).nes */ - { 0x370ceb65, 70, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Family Trainer 5 - Meiro Daisakusen (Japan).nes */ - { 0x86be4746, 2, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dooly Bravo Land (Korea) (Unl).nes */ - { 0xe62e3382, 71, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* MiG 29 - Soviet Fighter (USA) (Unl).nes */ - { 0xac7b0742, 71, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Golden KTV (Ch) [!].nes */ - { 0x054bd3e9, 74, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Di 4 Ci - Ji Qi Ren Dai Zhan (Ch).nes */ - { 0x496ac8f7, 74, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ji Jia Zhan Shi (Ch) [b3].nes */ - { 0xae854cef, 74, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jia A Fung Yun (Ch).nes */ - { 0xba51ac6f, 78, DEFAULT, MI_4, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Holy Diver (Japan).nes */ - { 0x3d1c3137, 78, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Uchuusen Cosmo Carrier (Japan).nes */ - { 0xa4fbb438, 79, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* F-15 City War (AVE) (REV1.x) [b1].nes */ - { 0xd4a76b07, 79, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* F-15 City War (AVE) (REV1.x) [b2].nes */ - { 0x8eab381c, 79, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Deathbots (USA) (Rev 1) (Unl).nes */ - { 0x1eb4a920, 79, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Double Strike - Aerial Attack Force (USA) (v1.1) (Unl).nes */ - { 0x3e1271d5, 79, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tiles of Fate (USA) (Unl).nes */ - { 0xd2699893, 88, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Spirit - Aratanaru Densetsu (Japan).nes */ - { 0xbb7c5f7a, 89, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tenka no Goikenban - Mito Koumon (J) [f1].nes */ - { 0x082778e6, 91, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Fighter III.nes */ - { 0x10119e6b, 93, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Fantasy Zone (Japan) (Sunsoft).nes */ - { 0x2b750bf9, 101, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Urusei Yatsura - Lum no Wedding Bell (Japan) (Beta).nes */ - { 0x0da5e32e, 101, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Urusei Yatsura - Lum no Wedding Bell (Japan).nes */ - { 0x6096f84e, 104, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pegasus 5-in-1 (Golden Five) (Unl).nes */ - { 0x3d3ff543, 113, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kazama Jun to Asama Yuuko no AV Dragon Mahjong (Japan) (Unl).nes */ - { 0x68379fdb, 113, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Pipemania (Australia) (HES) (Unl).nes */ - { 0x6a03d3f3, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lion King, The (Unl) (Mapper 114).nes */ - { 0x0d98db53, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pocahontas (Unl).nes */ - { 0xf5676f0b, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Donkey Kong (Unl) [b1].nes */ - { 0xc5e5c5b2, 115, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bao Qing Tian (Ch).nes */ - { 0xe40dfb7e, 116, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Somari (SOMARI-P) (NT-616) (Unl) [!].nes */ - { 0xc9371ebb, 116, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Somari (SOMARI-W) (Unl) [!].nes */ - { 0x78b657ac, 118, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Armadillo (Japan).nes */ - { 0x90c773c1, 118, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Goal! Two (USA).nes */ - { 0xb9b4d9e0, 118, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* NES Play Action Football (USA).nes */ - { 0x07d92c31, 118, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* RPG Jinsei Game (Japan).nes */ - { 0x37b62d04, 118, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ys III - Wanderers from Ys (Japan).nes */ - { 0x318e5502, 121, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sonic 3D Blast 6 (Unl).nes */ - { 0xddcfb058, 121, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter Zero 2 '97 (Unl) [!].nes */ - { 0xd2674b0a, 132, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Qi Wang - Chinese Chess (Asia) (Ja) (Unl).nes */ - { 0x5aefbc94, 133, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Jovial Race (Asia) (Ja) (PAL) (Unl).nes */ - { 0xB550B627, 136, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Incantation (Dip Bin) (Joy Van).nes */ - { 0xc2df0a00, 140, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bio Senshi Dan - Increaser Tono Tatakai (J) [hM66][b3].nes */ - { 0xe46b1c5d, 140, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mississippi Satsujin Jiken (Japan).nes */ - { 0x3293afea, 140, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mississippi Satsujin Jiken (Japan) (Rev A).nes */ - { 0x6bc65d7e, 140, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Youkai Club (Japan).nes */ - { 0x5caa3e61, 144, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Death Race (USA) (Unl).nes */ - { 0x48239b42, 146, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mahjang Companion (Asia) (Ja) (Hacker) (Unl).nes */ - { 0xb6a727fa, 146, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Papillon Gals (Japan) (Unl).nes */ - { 0xa62b79e1, 146, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sidewinder (HES) [o1].nes */ - { 0xcc868d4e, 149, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Taiwan Mahjong 16 (Sachen) [a1][!].nes */ - { 0x29582ca1, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mei Nu Quan (Honey Peach) (Sachen) [!].nes */ - { 0x40dbf7a2, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Olympic IQ (Asia) (Ja) (PAL) (Unl).nes */ - { 0x73fb55ac, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lightgun Game 2 in 1 - Cosmocop + Cyber Monster (Asia) (Ja) (Unl).nes */ - { 0xddcbda16, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lightgun Game 2 in 1 - Tough Cop + Super Tough Cop (Asia) (Ja) (Unl).nes */ - { 0x47918d84, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Auto-Upturn (Asia) (Ja) (PAL) (Unl).nes */ - { 0x471173e7, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Chinese Checkers (Asia) (Ja) (PAL) (Unl).nes */ - { 0x2394ae1c, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Happy Pairs (Asia) (Ja) (PAL) (Unl).nes */ - { 0xcab40a6c, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Magic Cube (Asia) (Ja) (PAL) (Unl).nes */ - { 0xbe17e27b, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Poker III (Asia) (Ja) (Alt 2) (Unl).nes */ - { 0x34ddf806, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Strategist (Asia) (Ja) (NTSC) (Unl).nes */ - { 0xc06facfc, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Strategist (Asia) (Ja) (PAL) (Unl).nes */ - { 0xa95a915a, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tasac (Asia) (Ja) (Unl).nes */ - { 0x0f141525, 152, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Arkanoid II (Japan).nes */ - { 0xbda8f8e4, 152, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Gegege no Kitarou 2 - Youkai Gundan no Chousen (Japan).nes */ - { 0xb1a94b82, 152, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pocket Zaurus - Juu Ouken no Nazo (Japan).nes */ - { 0x026c5fca, 152, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Saint Seiya - Ougon Densetsu (Japan).nes */ - { 0x3f15d20d, 153, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famicom Jump II - Saikyou no 7 Nin (Japan).nes */ - { 0xd1691028, 154, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Devil Man (Japan).nes */ - { 0xcfd4a281, 155, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Money Game, The (Japan).nes */ - { 0x2f27cdef, 155, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tatakae!! Rahmen Man - Sakuretsu Choujin 102 Gei (J) [b1].nes */ - { 0xc1719664, 155, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tatakae!! Rahmen Man - Sakuretsu Choujin 102 Gei (Japan).nes */ - { 0xccc03440, 156, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Buzz & Waldog (USA) (Proto) (Unl).nes */ - { 0x983d8175, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Battle Rush - Build Up Robot Tournament (Japan).nes */ - { 0x894efdbc, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Crayon Shin-chan - Ora to Poi Poi (Japan).nes */ - { 0x19e81461, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Dragon Ball Z - Gekitou Tenkaichi Budoukai (Japan).nes */ - { 0xbe06853f, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - J.League Super Top Players (Japan).nes */ - { 0x0be0a328, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - SD Gundam - Gundam Wars (Japan).nes */ - { 0x5b457641, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Ultraman Club - Supokon Fight! (Japan).nes */ - { 0xf51a7f46, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Yu Yu Hakusho - Bakutou Ankoku Bujutsukai (Japan).nes */ - { 0xcbf4366f, 158, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Alien Syndrome (USA) (Unl).nes */ - { 0xe170404c, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* SD Gundam Gaiden - Knight Gundam Monogatari (Japan).nes */ - { 0x276ac722, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* SD Gundam Gaiden - Knight Gundam Monogatari (Japan) (Rev 1).nes */ - { 0x0cf42e69, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Magical Taruruuto-kun - Fantastic World!! (Japan).nes */ - { 0xdcb972ce, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Magical Taruruuto-kun - Fantastic World!! (Japan) (Rev 1).nes */ - { 0xb7f28915, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Magical Taruruuto-kun 2 - Mahou Daibouken (Japan).nes */ - { 0x183859d2, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball Z - Kyoushuu! Saiya Jin (Japan).nes */ - { 0x58152b42, 160, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pipe V (Asia) (Ja) (Unl).nes */ - { 0x1c098942, 162, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Xi You Ji Hou Zhuan (Ch).nes */ - { 0x081caaff, 163, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Commandos (Ch).nes */ - - /* Mapper 176 */ - - { 0x761cf0c0, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 15-in-1 (FK008-15in1-210in1).nes */ - { 0xc51fa465, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 15-in-1 (KD-6032 180-in-1).nes */ - { 0x7642f6b6, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 18-in-1 (FK003-160in1).nes */ - { 0xb12ccb95, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 18-in-1 (FK028-180-in-1).nes */ - { 0xe650ec91, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 18-in-1 (FK032-52in1)).nes */ - { 0xa22de99d, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 20-in-1 (KD-6026 210in1).nes */ - { 0xe8bd5ac3, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 28-in-1 (FK-017).nes */ - { 0x4f2ccd03, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (BS-8004) (BS-0210A) (AA) (Unl) [p1].nes */ - { 0x24762ce8, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-022) 178-in-1.nes */ - { 0x8c48bdba, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 4-in-1 (AA) (BS-0306M) (Unl) [p1].nes */ - { 0x37478f0c, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 4-in-1 (BS-8009) (BS-0306M) (Unl) [p1].nes */ - { 0x98c59170, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 4-in-1 (BS-8014) (Unl) [p1].nes */ - { 0x7ca43c89, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (BS-8117) (Unl) [p1].nes */ - { 0xeebee0c8, 176, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 哥伦布传 - 黄金中文版 (re-release).nes */ - { 0x548d72ff, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 哥伦布 冒险记 - 黄金中文版.nes */ - { 0x3c9df646, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 圣斗士.nes */ - { 0x629fbeec, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 125-in-1 [p1][!].nes */ - { 0x9bdf2424, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 12-in-1 Console TV Game Cartridge (Unl) [!].nes */ - { 0x9206b787, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 160-in-1.nes */ - { 0x6343e6a6, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 16 in 1 (KD-1512).nes */ - { 0xdc904f4c, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3in1 (ES-Q800C)(FSS).nes */ - { 0x104d84df, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3-in-1 (ES-Q800C PCB) [p1].nes */ - { 0xcf7c6ae0, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3in1 (ES-Q800C)(TRS).nes */ - { 0x2b882971, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (15-in-1, 188-in-1, 999999-in-1) (YH478) (KY1501) (Unl) [p1].nes */ - { 0x576d9589, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4in1 (BS-0210A)(MMMM).nes */ - { 0x36c27ae8, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4in1 (BS-0306M)(TPST).nes */ - { 0x409601a5, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (BS-8088) [p1][!].nes */ - { 0xc4d1d2f8, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4in1 (ES-Q800C)(TCCC).nes */ - { 0x44f46bbc, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4in1 (ES-Q800C)(TPFS).nes */ - { 0x6ab68f4f, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 Fighter (ES-Q800C1 PCB) [p1].nes */ - { 0xa391549d, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8021) [p1][!].nes */ - { 0x06d13d9e, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8026) [p1][!].nes */ - { 0x2ebd5fd6, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8033) [p1][!].nes */ - { 0x23e4906a, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8043) [p1][!].nes */ - { 0x10155a92, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8045) [p1][!].nes */ - { 0x8baeedc0, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8052) [p1][!].nes */ - { 0x39307391, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8056) [p1][!].nes */ - { 0x72ceab1e, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8078) (Ch) [p1].nes */ - { 0x07d3f6cb, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8079) [p1][!].nes */ - { 0xc6d97331, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23Cxxxx, S-0210A PCB) [p1][!].nes */ - { 0x9367d1f4, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23Cxxxx, S-0210A PCB)[p1][!](Rus).nes */ - { 0x3907578b, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK-8008) [p1][!].nes */ - { 0xf66944ee, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK-8050) [p1][!].nes */ - { 0x8f6cc85a, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (KT-220B) [p1].nes */ - { 0x0163ca53, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (KT-3445AB) [p1].nes */ - { 0xc18a7bcb, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (KT-443B) [p1].nes */ - { 0xbbfbecbc, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1(SB-04,Unl).nes */ - { 0xd7d2123c, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (VT087) [p1][!].nes */ - { 0x8cb6d32c, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (VT089) [p1][!].nes */ - { 0x23994975, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (VT089)[p1][!] (Rus).nes */ - { 0x93196e95, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (VTxxx, 0208 PCB) [p1][!].nes */ - { 0x5f96184b, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (YH-4102) [p1].nes */ - { 0xfa1cb05c, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (YH4237) [p1].nes */ - { 0x1ef30cc8, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (YH-4253) (Unl) [p1] .nes */ - { 0x5d2129ac, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 YH-481 (20-in-1 KY2001, 228-in-1, 999999-in-1)(Unl)[!].nes */ - { 0x17d43af9, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 5-in-1 (K5003) [p1][!].nes */ - { 0xb3277b6c, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 6-in-1 (FK-3004) [p1][!].nes */ - { 0x97b82f53, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Bao Xiao San Guo (Ch) [a4].nes */ - { 0xd5f7aaef, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Double Moon Densetsu (Japan) [CHS](0806)_.nes */ - { 0x027fd794, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Jian Wuzhe - Sword Dancer.nes */ - { 0x09fc02c7, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Kou Dai Jing Ling - Fei Cui (Ch) [a2].nes */ - { 0x416c07a1, 176, DEFAULT, MI_V, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Meng Huan Zhi Xing IV (ES-1006) (Ch).nes */ - { 0xab09c88b, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* New 4-in-1 Game Fighter (KT-8405) (Unl).nes */ - { 0x85dd49b6, 176, DEFAULT, MI_H, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pocket Monsters Red (Ch) (Decrypted) [b1].nes */ - { 0x977d22c3, 176, DEFAULT, MI_H, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Po Fu Chen Zhou (ES-1092) (Ch) (Decrypted).nes */ - { 0xf011afd6, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rockman 4 MI (Hack).nes */ - { 0xb511c04b, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* San Xia Wu Yi - Yu Mao Chuan Qi (Ch) (ES-1071) [a2].nes */ - { 0x1923a8c5, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Shui Hu Shen Shou (ES-1087) (Ch) (Decrypted).nes */ - { 0xc043a8df, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Shu Qi Yu - Shu Xue Xiao Zhuan Yuan (Ch).nes */ - { 0x2cf5db05, 176, DEFAULT, MI_H, 0, DEFAULT, 0, DEFAULT, NOEXTRA }, /* Shu Qi Yu - Zhi Li Xiao Zhuan Yuan (Ch).nes */ - { 0x3df39ce4, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 3-in-1 (KT-4403) [p1].nes */ - { 0xc447b9fe, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 4-in-1 (BRC-4) [p1].nes */ - { 0xb5d25a20, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 4-in-1 (BS-0306M)(Unl).nes */ - { 0xaa05c592, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 6-in-1 (KY-6011)[p1][!].nes */ - { 0x940933dc, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* super game 3-in-1 (yh-363) (unl).nes */ - { 0x0b2cf73f, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 3-in-1 (YH-8013) (Unl).nes */ - { 0xb55103ad, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 3-in-1 (YH-8019) (MK042) (Unl) Fix.nes */ - { 0xd2f5f51d, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (10-in-1, 168-in-1, 999999-in-1) (YH477) (KY1008) (Unl).nes */ - { 0x719cce0a, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (KT-8394) (Unl).nes */ - { 0xa2e2031c, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (KT-8406) (Unl).nes */ - { 0x25d7cb92, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (MK038) (YH-8016) (Unl).nes */ - { 0x18dd93bc, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 New (YH437) (Unl) Fix.nes */ - { 0x4d18054c, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 New (YH437) (Unl).nes */ - { 0x6d580074, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-4118) (Unl).nes */ - { 0xfa5b1d26, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-4122) (Unl).nes */ - { 0xc3166e11, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH4146) (Unl).nes */ - { 0x4d25a3a6, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-415) (Unl) Fix.nes */ - { 0xf019bfef, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-415) (Unl).nes */ - { 0x60ac647f, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH4222) (Unl).nes */ - { 0x63d43f22, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-451) (Unl).nes */ - { 0xa39c9a6b, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-467) (Unl).nes */ - { 0x80f1e11e, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH701) (Unl) Fix.nes */ - { 0x0f05c0e6, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH701) (Unl).nes */ - { 0x8858d3f7, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8011) (Unl) Fix.nes */ - { 0xc5c30efa, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8011) (Unl).nes */ - { 0xcd55a865, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8023) (003) (Unl).nes */ - { 0x18beb276, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8024) (Unl).nes */ - { 0xe3a0b9e5, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8027) (Unl).nes */ - { 0x92b52357, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8028) (009) (Unl).nes */ - { 0xde94b7fd, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8029) (Unl).nes */ - { 0x5a0e3e69, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8033) (Unl).nes */ - { 0x21d4484a, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8042) (Unl).nes */ - { 0xbeeb0b07, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8043) (MK064) (Unl) Fix.nes */ - { 0xe83e5726, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8043) (MK064) (Unl).nes */ - { 0xd56f27ae, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8046) (009) (Unl).nes */ - { 0x0e8766dc, 176, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 4-in-1 (YH-8049) (002) (Unl).nes */ - { 0xd2a4a9c6, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 6-in-1 (YH 602) (Font Hack) Fix.nes */ - { 0x35974f2c, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 6-in-1 (YH 602) (Font Hack).nes */ - { 0x0881169e, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 8-in-1 (YH 801) (Font Hack).nes */ - { 0x31cadef3, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 9-in-1 (YH904) (Font Hack).nes */ - { 0x05e43745, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game 9-in-1 (YH904) (Unl).nes */ - { 0x5d061e04, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game YH 602 (Unl).nes */ - { 0x5b17fb27, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Game YH 801 (Unl).nes */ - { 0xf9863adf, 176, DEFAULT, MI_V, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Xi Chu Ba Wang (C) [ES-1066].nes */ - { 0xf1d803f3, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Xi Chu Ba Wang (ES-1066) (Ch) (Decrypted).nes */ - { 0x94782fbd, 176, DEFAULT, MI_V, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Xiong Ba Tian Xia (Ch).nes */ - { 0xffde0de5, 176, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 梦幻之星4[简体](修正)一战一级.nes */ - { 0x88e0c48c, 176, DEFAULT, MI_H, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Rockman 6-in-1 (rev1).nes */ - { 0xe6d869ed, 176, DEFAULT, MI_H, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* 6-in-1 Rockman (Unl) [U][!] */ - { 0x8caaff73, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Bao Xiao San Guo (Ch) (Wxn).nes */ - { 0x852ce16b, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Chu Han Zheng Ba - The War Between Chu & Han (Ch) (Wxn).nes */ - { 0xe0dd8d77, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Chu Liu Xiang (Ch) (Wxn).nes */ - { 0x2e4f3051, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Chu Liu Xiang (Ch) (Wxn) [f1].nes */ - { 0x351dd533, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Di Guo Feng Bao - Napoleon's War (Ch) (Wxn).nes */ - { 0x5ee2ef97, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Di Guo Shi Dai (Age of Empires) (Ch) (Wxn).nes */ - { 0xd6ea31c0, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Dong Zhou Lie Guo Zhi (Ch) (Wxn).nes */ - { 0xc04d330d, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Duo Bao Xiao Ying Hao - Guang Ming yu An Hei Chuan Shuo (Ch) (Wxn).nes */ - { 0xfd883527, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Feng Yun (Ch) (Wxn).nes */ - { 0xf354d847, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Grandia (Ch) (Wxn).nes */ - { 0x52a5f554, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DEFAULT, NOEXTRA }, /* Ji Du Shan En Chou Ji - Le Comte de Monte-Cristo (Ch) (Wxn).nes */ - { 0x95569a86, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 甲A - China Soccer League for Division A (re-release).nes */ - { 0xda7d586d, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DEFAULT, NOEXTRA }, /* Jue Dai Ying Xiong - Peerless Hero (Ch) (Wxn).nes */ - { 0x2c3d4ef0, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Kou Dai Jing Ling - Fei Cui (Ch) (Wxn).nes */ - { 0x49f22159, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Mei Guo Fu Hao (Ch) (Wxn).nes */ - { 0xb16d4268, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* M&M Heroes (Ch) (Wxn).nes */ - { 0x3532a114, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Mo Shen Fa Shi (Ch) (Wxn).nes */ - { 0x7d9c7206, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Mo Yu Ying Xiong Chuan - Wai Xing Ke Ji (Ch) (Wxn).nes */ - { 0xa2dc64ff, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Po Fu Chen Zhou (Ch) (Wxn).nes */ - { 0x377fdb36, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Pocket Monsters Gold (Ch) (Wxn).nes */ - { 0x8f6ab5ac, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* San Guo Zhong Lie Zhuan (Ch) (Wxn).nes */ - { 0xc768098b, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* San Xia Wu Yi - Yu Mao Chuan Qi (Ch) (Wxn).nes */ - { 0xf29c8186, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Shanghai Tycoon (Ch) (Wxn).nes */ - { 0x8947ab85, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Shao Nian You Xia (Ch) (Wxn).nes */ - { 0x5a88b5b0, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Shu Ma Bao Bei (Digimon Crystal) (Ch) (Wxn).nes */ - { 0x6b4cac80, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Shui Hu Shen Shou (Ch) (Wxn).nes */ - { 0x34ac5ae9, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Shui Hu Zhuan (Ch) (Wxn).nes */ - { 0x38effd3e, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Sui Tang Yan Yi (Ch) (Wxn).nes */ - { 0x7dce29cb, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DEFAULT, NOEXTRA }, /* Super Daisenryaku (Ch) (Wxn).nes */ - { 0x3ff36623, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Xi Chu Ba Wang (Ch) (Wxn).nes */ - { 0x8264ea52, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Xia Ke Qing - Jing He Ci Qin Wang (Ch) (Wxn).nes */ - { 0x99051cb5, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Xiong Ba Tian Xia (Ch) (Wxn).nes */ - { 0xa46353d1, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Yang Jia Jiang - Yang's Troops (Ch) (Wxn).nes */ - { 0x50d5f94b, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Ying Lie Qun Xia Zhuan (Ch) (Wxn).nes */ - { 0xba29435a, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Zhan Guo Qun Xiong Chuan (Ch) (Wxn).nes */ - { 0x33443508, 176, DEFAULT, MI_H, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* Zheng Ba Shi Ji (Ch) (Wxn).nes */ - { 0xeba09ada, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙域天下 [外星科技汉化].nes */ - { 0x095d8678, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Bimonthly pass - alien technology.nes */ - { 0x7696573a, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* ya te lu zhan ji (c) [es-0122].nes */ - { 0x69a3ca5c, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* duo la a meng - chao shi kong li xian (c).nes */ - { 0xee49f509, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Thief Wu You Emon world's treasures - Speaking of alien technology.nes */ - { 0x848f2d69, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Otaku no Seiza - An Adventure in the Otaku Galaxy (Japan) [CHS](0815)_.nes */ - { 0xeabbb630, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Monster Maker - 7 Tsu no Hihou - Part 1 (Ch).nes */ - { 0xf1d40f5b, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Monster Maker - 7 Tsu no Hihou - Part 2 (Ch).nes */ - { 0x5077cac1, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Ba Bao Qi Zhu - Li Jian Ba Quan Zhuan (EverQuest) (ES-1067) (Ch).nes */ - { 0xbf6e95f5, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Dream King - alien technology.nes */ - { 0xbff7c60c, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Ji Dou Sheng Zhan Shi (ES-1117) (Ch).nes */ - { 0x0dbff515, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Silva Saga (J) [T+ChS].nes */ - { 0xb8fcd425, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* 高达骑士物语 - 外星科技汉化.nes */ - { 0x3a1cfe21, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* 上古神殿 - 外星科技汉化.nes */ - { 0xbc4ac7fe, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* 高达骑士物语2 - 光之骑士 - 外星科技汉化.nes */ - { 0x4bcdb970, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Gui Mei Zhan Ji (C).nes */ - { 0xf17e49d5, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Gui Mei Zhan Ji (C).nes */ - { 0x62dde924, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Long Zhu Z3 Ren Zao Ren Lie Zhuan (ES-1130) (Ch) [f1].nes */ - { 0xc35e9aa8, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Dragon Ball Z II - Gekishin Freeza!! (Ch) [a1].nes */ - { 0xf2398802, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Dragon Ball Z II - Gekishin Freeza!! (Ch) [a2].nes */ - { 0xc9d968af, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Hun Dun Shi Jie (C) [ES-1115].nes */ - { 0x7f3dbf1b, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Chaos World (Ch).nes */ - { 0xb616885c, 176, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Chaos World (Ch) [a1].nes */ - { 0x02c41438, 176, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Xing He Zhan Shi (Asia) (Unl).nes */ - { 0xe8eafbc1, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Long Zhi Gu (ES-1137) (Ch) [f1].nes */ - { 0x6c979bac, 176, DEFAULT, MI_H, 0, DEFAULT, 0x0b, DEFAULT, NOEXTRA }, /* 10-in-1 Omake Game (FC Mobile) [b1].nes */ - { 0x622e9e35, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, MULTI, NOEXTRA }, /* 126-in-1 (5-in-1, 16-in-1, 22-in-1, 42-in-1, 56-in-1, 62-in-1) [p1][b1].nes */ - { 0xe6617bf1, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, MULTI, NOEXTRA }, /* 18-in-1 (FK-027 180in1).nes */ - { 0x04398a9f, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 2-in-1 - Sonic 5 + Earth Worm Jim 3 (Unl) [b1].nes */ - { 0x95aca7a7, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, MULTI, NOEXTRA }, /* 20-in-1 (15-in-1, 80-in-1, 160-in-1) [p1][b1].nes */ - { 0x8e994bcd, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, MULTI, NOEXTRA }, /* 3-in-1 - Lion King 5, The (Unl) [b1].nes */ - { 0x05a1f101, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (FK23C8078) (Ch) [p1][b1].nes */ - { 0x4e5f123a, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 Digital Adventure (Unl) [b1].nes */ - { 0x9ad9a8e9, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 6-in-1 (KY-6006) [p1][b1].nes */ - { 0x521af87b, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 6-in-1 (KY-6009) [p1][b1].nes */ - { 0x205cf073, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 8-in-1 Supergame (KY8002) [p1][b1].nes */ - { 0xd408f0bc, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 9-in-1 (KY-9005) [p1][b1].nes */ - { 0x20379331, 176, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat 30 Peoples (DH1043) (Ch).nes */ - - /* Mapper 199 roms are mapper 176 using extended mmc3 mode */ - { 0xed481b7c, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (Ch).nes */ - { 0xd871d3e6, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Dragon Ball Z II - Gekishin Freeza!! (Ch).nes */ - { 0x44c20420, 176, DEFAULT, MI_H, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* San Guo Zhi 2 (Ch).nes */ - - { 0x558c0dc3, 178, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 2-in-1 (Soccer Game & Crazy Dance) (Unl) [!].nes */ - { 0xc68363f6, 180, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Crazy Climber (Japan).nes */ - { 0x0f05ff0a, 181, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Seicross (Japan) (Rev 1).nes */ - { 0x96ce586e, 189, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter II - The World Warrior (Unl) [!].nes */ - { 0x0e76e4c1, 190, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Magic Kid Googoo (Korea) (Unl).nes */ - { 0x555a555e, 191, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sugoro Quest - Dice no Senshitachi (Ch).nes */ - { 0x2cc381f6, 191, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sugoro Quest - Dice no Senshitachi (Ch) [o1].nes */ - { 0xa145fae6, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Young Chivalry (Ch) [b3].nes */ - { 0xa9115bc1, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Young Chivalry (Ch) [!].nes */ - { 0x4c7bbb0e, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Young Chivalry (Ch) [b2].nes */ - { 0x98c1cd4b, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ying Lie Qun Xia Zhuan (Asia) (Unl).nes */ - { 0xee810d55, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* You Ling Xing Dong (Asia) (Unl).nes */ - { 0x442f1a29, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Young Chivalry (Ch) [b1].nes */ - { 0x637134e8, 193, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Fighting Hero (Asia) (Ja) (Unl).nes */ - { 0xa925226c, 194, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dai-2-Ji - Super Robot Taisen (Ch) [b1].nes */ - { 0x33c5df92, 195, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain Tsubasa Vol. II - Super Striker (Ch) [a1].nes */ - { 0x1bc0be6c, 195, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain Tsubasa Vol. II - Super Striker (Ch) [a3].nes */ - { 0xd5224fde, 195, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* God Slayer - Haruka Tenkuu no Sonata (Ch).nes */ - { 0xfdec419f, 196, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter VI 16 Peoples (Unl) [!].nes */ - { 0x700705f4, 198, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ---- */ - { 0x9a2cf02c, 198, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ---- */ - { 0xd8b401a7, 198, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ---- */ - { 0x28192599, 198, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ---- */ - { 0x19b9e732, 198, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tenchi wo Kurau II - Shokatsu Koumei Den (J) (PRG0) [T-Chi][b6].nes */ - { 0xdd431ba7, 198, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tenchi wo kurau 2 (c) */ - { 0x05658ded, 201, 15, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 21-in-1 (CF-043) (2006-V) (Unl) [p1].nes */ - { 0x276237b3, 206, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Karnov (Japan) (Rev 1).nes */ - { 0xa5e6baf9, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Slayer IV - Drasle Family (Japan).nes */ - { 0x4f2f1846, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '89 - Kaimaku Ban!! (Japan).nes */ - { 0x22d6d5bd, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jikuu Yuuden - Debias (Japan).nes */ - { 0x9d21fe96, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lupin Sansei - Pandora no Isan (Japan).nes */ - { 0xae321339, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pro Yakyuu - Family Stadium '88 (Japan).nes */ - { 0x96dfc776, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* R.B.I. Baseball 2 (USA) (Unl).nes */ - { 0xfd63e7ac, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* R.B.I. Baseball 3 (USA) (Unl).nes */ - { 0x2a01f9d1, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wagyan Land (Japan).nes */ - { 0x7678f1d5, 207, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Fudou Myouou Den (Japan).nes */ - { 0x07eb2c12, 208, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* FC25-台湾格斗游戏+快打传说.nes */ - { 0xdd8ced31, 209, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Power Rangers III (Unl) [!].nes */ - { 0x063b1151, 209, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Power Rangers IV (Unl) [!].nes */ - { 0xdd4d9a62, 209, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Shin Samurai Spirits 2 - Haoumaru Jigoku Hen (Ch).nes */ - { 0x0c47946d, 210, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Chibi Maruko-chan - Uki Uki Shopping (Japan).nes */ - { 0xc247cc80, 210, 1, MI_V, 1, 0x50, DEFAULT, DEFAULT, NOEXTRA }, /* Family Circuit '91 (Japan) (En).nes */ - { 0x808606f0, 210, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '91 (Japan).nes */ - { 0x6ec51de5, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '92 (Japan).nes */ - { 0xadffd64f, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '93 (Japan).nes */ - { 0x429103c9, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '94 (Japan).nes */ - { 0x81b7f1a8, 210, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Heisei Tensai Bakabon (Japan).nes */ - { 0x2447e03b, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Top Striker (Japan).nes */ - { 0x1dc0f740, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wagyan Land 2 (Japan).nes */ - { 0xd323b806, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wagyan Land 3 (Japan).nes */ - { 0xbd523011, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Namco Prism Zone - Dream Master (Japan).nes */ - { 0x5daae69a, 211, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Aladdin - Return of Jaffar, The (Unl) [!].nes */ - { 0x1ec1dfeb, 217, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 255-in-1 (Mapper 204) [p1].nes */ - { 0x046d70cc, 217, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? 500-in-1 (Anim Splash, Alt Mapper)[p1][!] */ - { 0x12f86a4d, 217, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 500-in-1.nes */ - { 0xd09f778d, 217, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? 9999999-in-1 (Static Splash, Alt Mapper)[p1][!] */ - { 0x62ef6c79, 232, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Quattro Sports (Camerica) (Aladdin) [b1].nes */ - { 0x2705eaeb, 234, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Maxi 15 (USA) (Unl).nes */ - { 0x80cbcacb, 235, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 100-in-1 (Unl).nes */ - { 0x6175b9a0, 235, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 150_in_1_199x-ASp.nes */ - { 0x745a6791, 235, 2, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 210-in-1 and Contra 4-in-1 (212-in-1,212 Hong Kong,Reset Based)(Unl).nes */ - { 0xdf81364d, 235, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 260-in-1 [p1][!].nes */ - { 0xa38f2f1d, 235, DEFAULT, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* 1500-in-1.nes */ - { 0x6f12afc5, 235, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? Golden Game 150-in-1 */ - { 0x2537b3e6, 241, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dance Xtreme - Prima (Unl).nes */ - { 0x11611e89, 241, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Darkseed (Unl) [p1][b1].nes */ - { 0x81a37827, 241, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Darkseed (Unl) [p1].nes */ - { 0xfb2b6b10, 241, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Fan Kong Jing Ying (Asia) (Unl).nes */ - { 0xb5e83c9a, 241, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Xing Ji Zheng Ba (Asia) (Unl).nes */ - { 0x368c19a8, 241, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* LIKO Study Cartridge 3-in-1 (Unl) [!].nes */ - { 0x54d98b79, 241, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Titanic 1912 (Unl).nes */ - { 0xc2730c30, 34, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Deadly Towers (USA).nes */ - { 0xa21e675c, 34, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mashou (Japan).nes */ - { 0x6bea1235, 245, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yong Zhe Dou E Long - Dragon Quest VI (Ch) [a1].nes */ - { 0x345ee51a, 245, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yong Zhe Dou E Long - Dragon Quest VII (Ch).nes */ - { 0x57514c6c, 245, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yong Zhe Dou E Long - Dragon Quest VI (Ch).nes */ - { 0xdb9d71b7, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Donkey Kong (Unl) [o1].nes */ - - /* KT-008 PCB. These require mapper 224 for having an outer bank register at $5xxx, but are usually found set to mapper 4. */ - { 0x61fc4d20, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* (KT-1062) 口袋怪兽꞉ 水晶版.nes */ - { 0xaa666c19, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys Origin: Hugo.nes */ - { 0xb0d011d3, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys Origin: Yunica.nes */ - { 0x16143319, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys VI: 纳比斯汀的方舟.nes */ - { 0xe05fc21f, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys: 菲尔盖纳之誓约.nes */ - { 0xf8b58b59, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志 - 蜀魏争霸.nes */ - { 0xcb1bab3d, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志꞉ 蜀汉风云.nes */ - { 0xddc122ed, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 亡灵崛起.nes */ - { 0x4d2811c7, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 伏魔英雄传.nes */ - { 0x24750e5d, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 傲视天地.nes */ - { 0xc658b6a8, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 刀剑英雄传.nes */ - { 0xea831217, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 剑侠情缘.nes */ - { 0x92ebad5b, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙 III꞉ 罪恶渊源.nes */ - { 0x48210324, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 勇者的试炼.nes */ - { 0x3439d140, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 天空的新娘.nes */ - { 0x9a0a531a, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 天空篇.nes */ - { 0xb5fdb3cb, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者黑暗世界 - 混沌世界.nes */ - { 0x4f427110, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 珍珠版.nes */ - { 0xa46d6f4c, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 琥珀版.nes */ - { 0xe001de16, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 白金版.nes */ - { 0x5464d7f8, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 翡翠版.nes */ - { 0x4d735cb1, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 钻石版.nes */ - { 0x5d04547c, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 失落的神器.nes */ - { 0xcb524b42, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 征战天下.nes */ - { 0x5f362198, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 战神世界.nes */ - { 0x36de88e7, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 新魔界.nes */ - { 0xf8e9c9cf, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 无双乱舞.nes */ - { 0xa4c39535, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 神魔大陆.nes */ - { 0x76bbe916, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 落日征战.nes */ - { 0x9b518d54, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 云的彼端.nes */ - { 0x91396b3f, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 天之痕.nes */ - { 0xaa621fa0, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 枫之舞.nes */ - { 0x48d1f54a, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 王者归来.nes */ - - { 0xbdbe3c96, 238, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Contra Fighter (Unl).nes */ - { 0xcb53c523, 11, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* King Neptune's Adventure (USA) (Unl).nes */ - { 0x6e149729, 189, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Master Fighter II (Unl) [a1].nes */ - { 0x60bfeb0c, 90, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat 2 (Unl) [!].nes */ - { 0x247cc73d, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Poker II (Asia) (Ja) (Unl).nes */ - { 0x1f1326d4, 121, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Sonic 5 (1997) (Unl) [!].nes */ - { 0x99748230, 215, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* EarthWorm Jim 2 (SuperGame).nes */ - { 0x37876ac7, 215, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Golden Card 6-in-1 (Unl) [!].nes */ - { 0x1a3320a3, 215, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat 3 (SuperGame).nes */ - { 0x80eb1839, 114, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Boogerman (Sugar Softec) (Unl) [!].nes */ - { 0x071e4ee8, 114, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? m114,submapper 1 test rom */ - { 0xfe3e03a1, 197, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat III Special (YY-030) (Ch) [!].nes */ - { 0x9151d311, 197, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat III 28 Peoples (NT-328) (Ch) [!].nes */ - { 0x272709b9, 237, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Teletubbies Y2K (420-in-1).nes */ - { 0x2e27e0af, 227, DEFAULT, DEFAULT, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Bio Hazard.nes */ - { 0x0e7e9309, 189, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter II - The World Warrior (Unl) [a1].nes */ - { 0xa3ac0095, 189, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter II - The World Warrior (Unl) [a2].nes */ - { 0xeced5899, 121, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ultimate Mortal Kombat 4 (Unl) [!].nes */ - { 0x19c1ed51, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Poker III (Asia) (Ja) (Unl).nes */ - { 0x282745c5, 141, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Q Boy (Asia) (Ja) (Unl).nes */ - { 0x4b9ecfb2, 21, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wai Wai World 2 - SOS!! Paseri Jou (Japan) (Virtual Console).nes */ - { 0x33751782, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Zoda's Revenge - StarTropics II (USA, Europe) (Virtual Console).nes */ - { 0x9bbf3e5d, 15, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 168-in-1 [p1][!].nes */ - - /* TXC / Sachen / JoyVan */ - - /* This cart does not work anymore with latest mapper implementation. - * This will be run using alternate mapper using override in m132 */ - { 0x2a5f4c5a, 132, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Zhan Guo Si Chuan Sheng (C&E) (Unl).nes */ - - { 0x0acfc3cd, 132, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mahjong Block (MGC-008) (Unl) [!].nes */ - - /* ines mappers that uses iNes 2.0 numbers */ - - /* CRC32, mapperNum, SubMapper, Mirroring, hasBattery, prgRam, chrRam, region, extra flags */ - { 0xf6bd8e31, 281, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 1997 Super HIK 4-in-1 (JY-052) [p1][!].nes */ - /* dumps are assigned 281, but its 293 on nesdev */ - { 0x06256C80, 293, DEFAULT, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Super 12-in-1 NewStar (UNL) */ - { 0x5aa23a15, 361, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (OK-411)[p1][!].nes */ - { 0xf6b9d088, 366, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (K-3131GS, GN-45) [p1][!].nes */ - { 0x503566b2, 366, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (K-3131SS, GN-45) [p1][!].nes */ - { 0xdb2d2d88, 369, DEFAULT, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* Super Mario Bros. Party.nes */ - { 0x87f83ea2, 380, DEFAULT, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* 42 to 80,000 */ - { 0xc4b94bd5, 389, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Caltron - 9 in 1 (USA) (Proto) (Unl).nes */ - { 0x2F497313, 401, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 19-in-1 (VIP19) */ - - /* ines mappers that uses unif boards */ - - { 0x0073dbd8, 260, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 2-in-1 - Mortal Kombat V Turbo 30 + Super Aladdin (Unl) [p1][!].nes */ - { 0x4dc6107d, 260, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 2-in-1 - Boogerman + Flintstones, The (Unl) [p1][!].nes */ - { 0xb72b2cf4, 260, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 2-in-1 - Aladdin + Lion King, The (Unl) [p1][!].nes */ - { 0x5638ba59, 260, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat Trilogy - 8 People (M1274) (Ch) [!].nes */ - { 0xa1dc16c0, 262, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Heroes (Asia) (Ja) (Unl).nes */ - { 0x1df10182, 263, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Boogerman II (Rex-Soft) [!].nes */ - { 0xf956fcea, 521, DEFAULT, DEFAULT, 0, DEFAULT, 0x70, DEFAULT, NOEXTRA }, /* Korean Igo (Korea) (Unl).nes */ - { 0x2eed2e34, 289, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 76-in-1 [p1][a1].nes 2048 PRG, 0 CHR */ - - { 0x00000000, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, NOEXTRA } - -#endif +#ifndef _FCEU_INES_CORRECT_H +#define _FCEU_INES_CORRECT_H + + /* ROM images that have the battery-backed bit set in the header that really + don't have battery-backed RAM is not that big of a problem, so I'll + treat this differently by only listing games that should have battery-backed RAM. + */ + /* CRC32, mapperNum, SubMapper, Mirroring, hasBattery, prgRam, chrRam, region, extra flags */ + { 0xb17574f3, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* AD&D Heroes of the Lance */ + { 0x5de61639, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* AD&D Hillsfar */ + { 0x2545214c, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* DW */ + { 0x3b3f88f0, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* DW */ + { 0x8c5a784e, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* DW 2 */ + { 0x506e259d, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* DW 4*/ + { 0xa86a5318, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Dw 3 */ + { 0x45f03d2e, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Faria */ + { 0xb8b88130, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy (FFE Hack) */ + { 0xcebd2a31, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy */ + { 0xd29db3c7, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy 2 */ + { 0x466efdc2, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy J */ + { 0xeaf7ed72, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Legend of Zelda */ + { 0x3fe272fb, 1, DEFAULT, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Legend of Zelda */ + { 0xba322865, 1, DEFAULT, DEFAULT, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Zelda 2 */ + { 0x25952141, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* AD&D Pool of Radiance */ + { 0x1335cb05, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Crystalis */ + { 0x57e220d0, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Final Fantasy 3 */ + { 0x889129cb, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Startropics */ + { 0xd054ffb0, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Startropics 2*/ + { 0xb5ff71ab, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Battle Fleet */ + { 0x0c1792da, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '90 */ + { 0x47c2020b, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Hydlide 3*/ + { 0xbc11e61a, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kaijuu Monogatari */ + { 0xace56f39, 19, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mindseeker */ + { 0xe1383deb, 26, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mouryou Senki Madara */ + { 0xde9c9c64, 80, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kyonshiizu 2 */ + { 0x0e1683c5, 80, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mirai Shinwa Jarvas */ + + { 0xaf5d7aa2, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Clu Clu Land (W) [o3].nes */ + { 0xcfb224e6, 222, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ninja (J) (PRG0) [p1][!].nes */ + { 0x82f204ae, 163, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Liang Shan Ying Xiong (NJ023) (Ch) [!].nes */ + { 0xad9c63e2, 70, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Space Shadow (Japan).nes */ + { 0xe1526228, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ki no Bouken - The Quest of Ki (Japan).nes */ + { 0xaf5d7aa2, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Clu Clu Land (W) [o3].nes */ + { 0xcfb224e6, 222, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ninja (J) (PRG0) [p1][!].nes */ + { 0xfcdaca80, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Elevator Action (Japan).nes */ + { 0xc05a365b, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Chou Fuyuu Yousai Exed Exes (Japan).nes */ + { 0xc4c3949a, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mario Bros. (World).nes */ + { 0x32fa246f, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tag Team Pro-Wrestling (Japan).nes */ + { 0x43d30c2f, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ms. Pac-Man (USA) (Tengen) (Unl).nes */ + { 0xb3c30bea, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Xevious (Japan) (En).nes */ + { 0xe492d45a, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Zippy Race (Japan).nes */ + { 0x24598791, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Duck Hunt (World).nes */ + { 0x49aeb3a6, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Excitebike (Japan, USA).nes */ + { 0xb8535ca3, 0, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mahjong (Japan).nes */ + { 0x330de468, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Obake no Q Tarou - Wanwan Panic (Japan).nes */ + { 0xe28f2596, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pac-Land (J) [b2].nes */ + { 0x5112dc21, 0, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wild Gunman (World) (Rev 1).nes */ + { 0xd8ee7669, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Adventures of Rad Gravity, The (USA).nes */ + { 0x5b837e8d, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Alien Syndrome (Japan).nes */ + { 0x37ba3261, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Back to the Future Part II & III (USA).nes */ + { 0x5b6ca654, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Barbie (USA).nes */ + { 0x61a852ea, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Battle Stadium - Senbatsu Pro Yakyuu (Japan).nes */ + { 0xf6fa4453, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bigfoot (U) [b4].nes */ + { 0x391aa1b8, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Bloody Warriors - Shan-Go no Gyakushuu (Japan).nes */ + { 0xa5e8d2cd, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* BreakThru (USA).nes */ + { 0x3f56a392, 1, DEFAULT, DFAULT8, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Captain ED (Japan).nes */ + { 0x078ced30, 1, DEFAULT, DFAULT8, 1, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* Choujin - Ultra Baseball (Japan).nes */ + { 0xfe364be5, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Deep Dungeon IV - Kuro no Youjutsushi (Japan).nes */ + { 0x57c12280, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Demon Sword (U) [b1].nes */ + { 0xd09b74dc, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Great Tank (Japan).nes */ + { 0xe8baa782, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Gunhed - Aratanaru Tatakai (Japan).nes */ + { 0x970bd9c2, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hanjuku Eiyuu (J) [b1].nes */ + { 0xcd7a2fd7, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hanjuku Hero (Japan).nes */ + { 0x63469396, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Hokuto no Ken 4 - Shichisei Haken Den - Hokuto Shinken no Kanata e (Japan).nes */ + { 0xe94d5181, 1, DEFAULT, DFAULT8, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Future Wars - Mirai Senshi Lios (Japan).nes */ + { 0x7156cb4d, 1, DEFAULT, DFAULT8, 0, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Muppet Adventure - Chaos at the Carnival (USA).nes */ + { 0x70f67ab7, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Musashi no Bouken (Japan).nes */ + { 0x958e4bae, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Orb-3D (USA).nes */ + { 0x291bcd7d, 1, DEFAULT, DFAULT8, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Pachio-kun 2 (Japan).nes */ + { 0xa9a4ea4c, 1, DEFAULT, DFAULT8, 1, 0x70, DEFAULT, DEFAULT, NOEXTRA }, /* Satomi Hakkenden (J) [b2].nes */ + { 0xcc3544b0, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Triathron, The (Japan).nes */ + { 0x52ab2d17, 1, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Toukyou Pachi-Slot Adventure (Japan).nes */ + { 0x934db14a, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* All-Pro Basketball (USA).nes */ + { 0xf74dfc91, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Win, Lose or Draw (USA).nes */ + { 0xcfe02ada, 1, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Darkman (Europe).nes */ + { 0x1a71fd06, 1, DEFAULT, MI_H, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Kujaku Ou.nes */ + + /* MMC1 games with more than 8K wram */ + { 0x2225c20f, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* Genghis Khan */ + { 0xfb69743a, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) */ + { 0x4642dda6, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* Nobunaga's Ambition */ + { 0x3f7ad415, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG0) */ + { 0x2b11e0b0, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG1) */ + { 0xc6182024, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* Romance of the 3 Kingdoms */ + { 0xabbf7217, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG0) or Sangokushi */ + { 0xccf35c02, 1, DEFAULT, DEFAULT, 1, 0x77, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG1) */ + { 0xb8747abf, 1, DEFAULT, DEFAULT, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Best Play Pro Yakyuu Special (J) (PRG0) */ + { 0xc3de7c69, 1, DEFAULT, DEFAULT, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* "" "" (J) (PRG1) */ + { 0xc9556b36, 1, DEFAULT, DEFAULT, 1, 0x90, 0x07, DEFAULT, NOEXTRA }, /* Final Fantasy 1+2 */ + + { 0xe6a477b2, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3-D WorldRunner (USA).nes */ + { 0x9ea1dc76, 2, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rainbow Islands (USA).nes */ + { 0x6d65cac6, 2, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Terra Cresta (Japan).nes */ + { 0xe1b260da, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Argos no Senshi - Hachamecha Daishingeki (Japan).nes */ + { 0x1d0f4d6b, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Black Bass, The (USA).nes */ + { 0x266ce198, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* City Adventure Touch - Mystery of Triangle (J) [b1].nes */ + { 0x804f898a, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Unit (Japan).nes */ + { 0x55773880, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Adventures of Gilligan's Island, The (USA).nes */ + { 0x6e0eb43e, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Puss 'n Boots - Pero's Great Adventure (USA).nes */ + { 0x2bb6a0f8, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sherlock Holmes - Hakushaku Reijou Yuukai Jiken (Japan).nes */ + { 0x28c11d24, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sukeban Deka 3 (J) [b1].nes */ + { 0x02863604, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sukeban Deka III (Japan).nes */ + { 0x419461d0, 2, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Cars (USA).nes */ + + /* CNROM by default has bus conflicts enabled, these requires no bus conflict to play correctly */ + { 0x2915faf0, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Incantation (Asia) (Ja) (Unl).nes */ + { 0x8f154a0d, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pu Ke Jing Ling (Asia) (Unl).nes */ + { 0xb0c871c5, 3, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wei Lai Xiao Zi (Joy Van).nes */ + { 0xb3be2f71, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yanshan Chess (Unl).nes */ + { 0xd04a40e6, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bingo 75 (Asia) (Ja) (Unl).nes */ + { 0xe41b440f, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sidewinder (Joy Van).nes */ + { 0xebd0644d, 3, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Master Chu & The Drunkard Hu (Joy Van).nes */ + { 0xf283cf58, 3, 1, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Colorful Dragon (Sachen).nes */ + { 0x2deb12b8, 3, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Venice Beach Volleyball (Asia) (Ja) (Super Mega) (Unl).nes */ + + { 0xdbf90772, 3, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Alpha Mission (USA).nes */ + { 0xd858033d, 3, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ASO - Armored Scrum Object (J).nes */ + { 0xd858033d, 3, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ASO - Armored Scrum Object (J).nes */ + { 0x637ba508, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Adan y Eva (Spain) (Gluk Video) (Unl).nes */ + { 0x9bde3267, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Adventures of Dino Riki (USA).nes */ + { 0xd8eff0df, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Gradius (Japan).nes */ + { 0x1d41cc8c, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Gyruss (USA).nes */ + { 0xcf322bb3, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* John Elway's Quarterback (USA).nes */ + { 0xb5d28ea2, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mystery Quest (USA).nes */ + { 0x02cc3973, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ninja Kid (USA).nes */ + { 0xbc065fc3, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pipe Dream (U) [b1].nes */ + { 0xc9ee15a7, 3, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Aladdin III (1995) (Unl) [hM03].nes */ + { 0x8dedea07, 3, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Shui Guo Li (Ch) [a1].nes */ + { 0x684afccd, 3, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Space Hunter (Japan).nes */ + + { 0x97b6cb19, 4, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Aladdin (SuperGame) (Mapper 4) [!].nes */ + { 0xd97c31b0, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lasalle Ishii no Child's Quest (Japan).nes */ + { 0x404b2e8b, 4, DEFAULT, MI_4, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rad Racer II (USA).nes */ + { 0x15141401, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Asmik-kun Land (Japan).nes */ + { 0x4cccd878, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kyatto Ninden Teyandee (J) [b1].nes */ + { 0x59280bec, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jackie Chan (Japan).nes */ + { 0x7474ac92, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kabuki - Quantum Fighter (USA).nes */ + { 0xf2594374, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Matendouji (Japan).nes */ + { 0x5337f73c, 4, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Niji no Silk Road (Japan).nes */ + { 0x9eefb4b4, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pachi-Slot Adventure 2 - Sorotta-kun no Pachi-Slot Tanteidan (Japan).nes */ + { 0xafe03802, 4, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pachio-kun 3 (Japan) (Rev A).nes */ + { 0x21a653c7, 4, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Sky Kid (VS).nes */ + { 0xdb7f07be, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Toki (USA) (Beta).nes */ + { 0x8F6CC85A, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-220B) Totally Rad 4-in-1.nes [overdump] */ + { 0xAB9DE91F, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-220B) Totally Rad 4-in-1.nes, Commonly set to mapper 176 */ + + /* MMC5 */ + { 0x671f23a8, 5, DEFAULT, DEFAULT, 0, 0, 0, PAL, NOEXTRA }, /* Castlevania III - Dracula's Curse (E) */ + { 0xcd4e7430, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Castlevania III - Dracula's Curse (KC) */ + { 0xed2465be, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Castlevania III - Dracula's Curse (U) */ + { 0x0afb395e, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Gun Sight */ + { 0xb0480ae9, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Laser Invasion */ + { 0xb4735fac, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Metal Slader Glory */ + { 0xbb7f829a, 5, DEFAULT, DEFAULT, 0, 0, 0, DEFAULT, NOEXTRA }, /* Uchuu Keibitai SDF */ + { 0x0ec6c023, 5, DEFAULT, DEFAULT, 1, 0x70, 0, DEFAULT, NOEXTRA }, /* Gemfire */ + { 0x9cbadc25, 5, DEFAULT, DEFAULT, 1, 0x70, 0, DEFAULT, NOEXTRA }, /* Just Breed */ + { 0xbc80fb52, 5, DEFAULT, DEFAULT, 1, 0x70, 0, DEFAULT, NOEXTRA }, /* Royal Blood */ + { 0xd532e98f, 5, DEFAULT, DEFAULT, 1, 0x70, 0, DEFAULT, NOEXTRA }, /* Shin 4 Nin Uchi Mahjong - Yakuman Tengoku */ + { 0x15fe6d0f, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Bandit Kings of Ancient China */ + { 0xfe3488d1, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Daikoukai Jidai */ + { 0x1ced086f, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Ishin no Arashi */ + { 0x6396b988, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* L'Empereur (J) */ + { 0x9c18762b, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* L'Empereur (U) */ + { 0xeee9a682, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Nobunaga no Yabou - Sengoku Gunyuu Den (J) (PRG0) */ + { 0xf9b4240f, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Nobunaga no Yabou - Sengoku Gunyuu Den (J) (PRG1) */ + { 0x8ce478db, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Nobunaga's Ambition 2 */ + { 0x39f2ce4b, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Suikoden - Tenmei no Chikai */ + { 0xaca15643, 5, DEFAULT, DEFAULT, 1, 0x77, 0, DEFAULT, NOEXTRA }, /* Uncharted Waters */ + { 0x6f4e4312, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Aoki Ookami to Shiroki Mejika - Genchou Hishi */ + { 0xf540677b, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Nobunaga no Yabou - Bushou Fuuun Roku */ + { 0xf011e490, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Romance of The Three Kingdoms II */ + { 0x184c2124, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Sangokushi II (J) (PRG0) */ + { 0xee8e6553, 5, DEFAULT, DEFAULT, 1, 0x90, 0, DEFAULT, NOEXTRA }, /* Sangokushi II (J) (PRG1) */ + + { 0xf518dd58, 7, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain Skyhawk (USA).nes */ + { 0x6c4a9735, 7, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* WWF Wrestlemania (Europe).nes */ + { 0x84382231, 9, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Punch-Out!! (Japan) (Gold Edition).nes */ + { 0xbe939fce, 9, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Punch-Out!! (U) [b1].nes */ + { 0x7b837fde, 9, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mike Tyson's Punch-Out!! (PC10) [b1].nes */ + { 0x345d3a1a, 11, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Castle of Deceit (USA) (Unl).nes */ + { 0xb79f2651, 11, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Chiller (USA) (Unl).nes */ + { 0x5e66eaea, 13, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Videomation (USA).nes */ + { 0xcd373baa, 14, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 武士魂 (8 characters).nes */ + { 0xbfc7a2e9, 16, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball 3 - Gokuu Den (Japan) (Rev 1).nes */ + { 0x6e68e31a, 16, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball 3 - Gokuu Den (Japan).nes */ + { 0x33b899c9, 16, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball - Daimaou Fukkatsu (Japan).nes */ + { 0xa262a81f, 16, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rokudenashi Blues (Japan).nes */ + { 0x286fcd20, 21, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ganbare Goemon Gaiden 2 - Tenka no Zaihou (Japan).nes */ + { 0x335e6339, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* kung fu legend (unl)[!].nes */ + { 0x1a8d767b, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* kung fu legend (unl)[!p].nes */ + { 0x0e263d47, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* World Hero (Unl) (TV System Select) [!].nes */ + { 0xe4a291ce, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* World Hero (Unl) [!].nes */ + { 0x51e9cd33, 23, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* World Hero (Unl) [b1].nes */ + { 0x105dd586, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mi Hun Che (Ch)(full copyrights)[!].nes */ + { 0xbc9bb6c1, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Car (Ch)(full copyrights)[!].nes */ + { 0x43753886, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mi Hun Che (Ch)(replaced copyrights)[p1][!].nes */ + { 0x5b3de3d1, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* -- */ + { 0x511e73f8, 27, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mi Hun Che (Ch) [p1][b2].nes */ + { 0x5555fca3, 32, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Sensei no Oshiete - Watashi no Hoshi (J) [b1].nes */ + { 0x283ad224, 32, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Sensei no Oshiete - Watashi no Hoshi (Japan).nes */ + { 0x243a8735, 32, DEFAULT, 0x10|4, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Major League (Japan).nes */ + { 0x8a7d0abe, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Akira (Japan).nes */ + { 0x376138d8, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Akira (J) [a1].nes */ + { 0xadf606f6, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bakushou!! Jinsei Gekijou (Japan).nes */ + { 0xbc7b1d0f, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bakushou!! Jinsei Gekijou 2 (Japan).nes */ + { 0x7a497ae3, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Don Doko Don (Japan).nes */ + { 0xbaca10a9, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Golfkko Open (Japan).nes */ + { 0xf80bdc50, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Insector X (Japan).nes */ + { 0x2a6559a1, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Operation Wolf (Japan).nes */ + { 0xaeb7fce9, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Power Blazer (Japan).nes */ + { 0xd920f9df, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Takeshi no Sengoku Fuuunji (Japan).nes */ + { 0x3cd4b420, 33, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Takeshi no Sengoku Fuuunji (Japan) (Beta).nes */ + { 0x4c7c1af3, 34, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Caesars Palace (U) [b1].nes */ + { 0x932ff06e, 34, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Classic Concentration (U) [b1].nes */ + { 0xf46ef39a, 37, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Super Mario Bros. + Tetris + Nintendo World Cup (Europe) (Rev 1).nes */ + { 0x4686c5dd, 41, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Caltron - 6 in 1 (USA) (Unl).nes */ + { 0x090c0c17, 42, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Senshi Nicol (FDS Conversion) [p1][!].nes */ + { 0x4df84825, 42, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Senshi Nicol (FDS Conversion) [p2][!].nes */ + { 0x579e5bc5, 42, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Senshi Nicol (FDS Conversion) [p3].nes */ + { 0xc744f205, 42, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ai Senshi Nicol (FDS Conversion) [p3][t1].nes */ + { 0x71699765, 42, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Love Warrior Nicol.nes */ + { 0x6bf3f6a3, 42, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bio Miracle Bokutte Upa (J) (Mario Baby - FDS Conversion).nes */ + { 0x5ba1c5cf, 42, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Green Beret (FDS Conversion) (Unl).nes */ + { 0x50ab1ab2, 42, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? Green Beret (FDS Conversion, LH09) (Unl) [U][!][t1] (160K PRG */ + { 0x7ccb12a3, 43, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? SMB2j */ + { 0x6c71feae, 45, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kunio 8-in-1 [p1].nes */ + { 0x40c0ad47, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Flintstones, The - The Rescue of Dino & Hoppy (Japan).nes */ + { 0xaebd6549, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bakushou!! Jinsei Gekijou 3 (Japan).nes */ + { 0x6cdc0cd9, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bubble Bobble 2 (Japan).nes */ + { 0x99c395f9, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain Saver (Japan).nes */ + { 0xa7b0536c, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Don Doko Don 2 (Japan).nes */ + { 0xb17c828a, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Don Doko Don 2 (J) [a1].nes */ + { 0x40c0ad47, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Flintstones, The - The Rescue of Dino & Hoppy (J).nes */ + { 0x1500e835, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jetsons, The - Cogswell's Caper (Japan).nes */ + { 0xe2c94bc2, 48, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Bros 8 (Unl) [!].nes */ + { 0xa912b064, 51, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, 0x800 }, /* 11-in-1 Ball Games [p1][o1].nes (has CHR ROM when it shouldn't) */ + { 0x2e72a5d9, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 11-in-1 (66-in-1, 86-in-1, 63-in-1).nes */ + { 0x39f514fd, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 18 in 1 (118-in-1, 138-in-1, 198-in-1)VTxxxx.nes */ + { 0xd8b1f465, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 26-in-1 (36-in-1, 46-in-1,56-in-1) VT 335.nes */ + { 0xcf82fae9, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 28 in 1 (38-in-1, 48-in-1, 58-in1)VTxxxx.nes */ + { 0xa7a98698, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 28-in-1 (46-in-1, 63-in-1, 118-in-1)VT-5116.nes */ + { 0x21fd7143, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 41-in-1 (5-in-1,71-in-1) VT345.nes */ + { 0x49ec88d6, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 42-in-1 NT-234 Bad Game Road Fighter.nes */ + { 0x60306f19, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 42-in-1 PCB 3840.nes */ + { 0x450cd86e, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 48-in-1 (62-in-1,73-in-1,88-in-1) VTxxx.nes */ + { 0xd774e041, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 50-in-1 (60-in-1,70-in-1,80-in-1) NT-113.nes */ + { 0x3c4e94f6, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 51-in-1 (61-in-1, 71-in-1, 81-in-1) VT5310.nes */ + { 0x0422ed44, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 7-in-1 (32-in-1,66-in-1,119-in-1) VT15004.nes */ + { 0x7efc0d2c, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 7-in-1 (5000-in-1, 999999999-in-1, 10000000-in-1)NC-07N.nes */ + { 0x6d92dff1, 59, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* TN 95-in-1 (6-in-1) [p1].nes */ + { 0x39ab0fc7, 64, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Hard Drivin' (USA) (Proto) (Unl).nes */ + { 0xb19a55dd, 64, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Road Runner (USA) (Unl).nes */ + { 0xf92be3ec, 64, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Rolling Thunder (USA) (Unl).nes */ + { 0xd114f544, 66, DEFAULT, MI_H, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* AV Super Real Pachinko (Japan) (Unl).nes */ + { 0xe84274c5, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mississippi Satsujin Jiken (J) [h2].nes */ + { 0xbde3ae9b, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Doraemon (Japan).nes */ + { 0x9552e8df, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball - Shen Long no Nazo (Japan).nes */ + { 0x811f06d9, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Power (USA).nes */ + { 0xd26efd78, 66, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Mario Bros. + Duck Hunt (USA).nes */ + { 0xdd8ed0f7, 70, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kamen Rider Club (Japan).nes */ + { 0xbba58be5, 70, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Family Trainer 6 - Manhattan Police (Japan).nes */ + { 0x370ceb65, 70, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Family Trainer 5 - Meiro Daisakusen (Japan).nes */ + { 0x86be4746, 2, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dooly Bravo Land (Korea) (Unl).nes */ + { 0xe62e3382, 71, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* MiG 29 - Soviet Fighter (USA) (Unl).nes */ + { 0xac7b0742, 71, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Golden KTV (Ch) [!].nes */ + { 0x054bd3e9, 74, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Di 4 Ci - Ji Qi Ren Dai Zhan (Ch).nes */ + { 0x496ac8f7, 74, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ji Jia Zhan Shi (Ch) [b3].nes */ + { 0xae854cef, 74, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jia A Fung Yun (Ch).nes */ + { 0xba51ac6f, 78, DEFAULT, MI_4, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Holy Diver (Japan).nes */ + { 0x3d1c3137, 78, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Uchuusen Cosmo Carrier (Japan).nes */ + { 0xa4fbb438, 79, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* F-15 City War (AVE) (REV1.x) [b1].nes */ + { 0xd4a76b07, 79, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* F-15 City War (AVE) (REV1.x) [b2].nes */ + { 0x8eab381c, 79, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Deathbots (USA) (Rev 1) (Unl).nes */ + { 0x1eb4a920, 79, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Double Strike - Aerial Attack Force (USA) (v1.1) (Unl).nes */ + { 0x3e1271d5, 79, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tiles of Fate (USA) (Unl).nes */ + { 0xd2699893, 88, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Spirit - Aratanaru Densetsu (Japan).nes */ + { 0xbb7c5f7a, 89, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tenka no Goikenban - Mito Koumon (J) [f1].nes */ + { 0x082778e6, 91, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Fighter III.nes */ + { 0x10119e6b, 93, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Fantasy Zone (Japan) (Sunsoft).nes */ + { 0x2b750bf9, 101, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Urusei Yatsura - Lum no Wedding Bell (Japan) (Beta).nes */ + { 0x0da5e32e, 101, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Urusei Yatsura - Lum no Wedding Bell (Japan).nes */ + { 0x6096f84e, 104, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pegasus 5-in-1 (Golden Five) (Unl).nes */ + { 0x3d3ff543, 113, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Kazama Jun to Asama Yuuko no AV Dragon Mahjong (Japan) (Unl).nes */ + { 0x68379fdb, 113, DEFAULT, MI_V, 1, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Pipemania (Australia) (HES) (Unl).nes */ + { 0x6a03d3f3, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lion King, The (Unl) (Mapper 114).nes */ + { 0x0d98db53, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pocahontas (Unl).nes */ + { 0xf5676f0b, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Donkey Kong (Unl) [b1].nes */ + { 0xc5e5c5b2, 115, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bao Qing Tian (Ch).nes */ + { 0xe40dfb7e, 116, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Somari (SOMARI-P) (NT-616) (Unl) [!].nes */ + { 0xc9371ebb, 116, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Somari (SOMARI-W) (Unl) [!].nes */ + { 0x78b657ac, 118, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Armadillo (Japan).nes */ + { 0x90c773c1, 118, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Goal! Two (USA).nes */ + { 0xb9b4d9e0, 118, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* NES Play Action Football (USA).nes */ + { 0x07d92c31, 118, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* RPG Jinsei Game (Japan).nes */ + { 0x37b62d04, 118, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ys III - Wanderers from Ys (Japan).nes */ + { 0x318e5502, 121, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sonic 3D Blast 6 (Unl).nes */ + { 0xddcfb058, 121, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter Zero 2 '97 (Unl) [!].nes */ + { 0xd2674b0a, 132, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Qi Wang - Chinese Chess (Asia) (Ja) (Unl).nes */ + { 0x5aefbc94, 133, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Jovial Race (Asia) (Ja) (PAL) (Unl).nes */ + { 0xB550B627, 136, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Incantation (Dip Bin) (Joy Van).nes */ + { 0xc2df0a00, 140, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Bio Senshi Dan - Increaser Tono Tatakai (J) [hM66][b3].nes */ + { 0xe46b1c5d, 140, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mississippi Satsujin Jiken (Japan).nes */ + { 0x3293afea, 140, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mississippi Satsujin Jiken (Japan) (Rev A).nes */ + { 0x6bc65d7e, 140, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Youkai Club (Japan).nes */ + { 0x5caa3e61, 144, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Death Race (USA) (Unl).nes */ + { 0x48239b42, 146, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mahjang Companion (Asia) (Ja) (Hacker) (Unl).nes */ + { 0xb6a727fa, 146, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Papillon Gals (Japan) (Unl).nes */ + { 0xa62b79e1, 146, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sidewinder (HES) [o1].nes */ + { 0xcc868d4e, 149, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Taiwan Mahjong 16 (Sachen) [a1][!].nes */ + { 0x29582ca1, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mei Nu Quan (Honey Peach) (Sachen) [!].nes */ + { 0x40dbf7a2, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Olympic IQ (Asia) (Ja) (PAL) (Unl).nes */ + { 0x73fb55ac, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lightgun Game 2 in 1 - Cosmocop + Cyber Monster (Asia) (Ja) (Unl).nes */ + { 0xddcbda16, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lightgun Game 2 in 1 - Tough Cop + Super Tough Cop (Asia) (Ja) (Unl).nes */ + { 0x47918d84, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Auto-Upturn (Asia) (Ja) (PAL) (Unl).nes */ + { 0x471173e7, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Chinese Checkers (Asia) (Ja) (PAL) (Unl).nes */ + { 0x2394ae1c, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Happy Pairs (Asia) (Ja) (PAL) (Unl).nes */ + { 0xcab40a6c, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Magic Cube (Asia) (Ja) (PAL) (Unl).nes */ + { 0xbe17e27b, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Poker III (Asia) (Ja) (Alt 2) (Unl).nes */ + { 0x34ddf806, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Strategist (Asia) (Ja) (NTSC) (Unl).nes */ + { 0xc06facfc, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, PAL, NOEXTRA }, /* Strategist (Asia) (Ja) (PAL) (Unl).nes */ + { 0xa95a915a, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tasac (Asia) (Ja) (Unl).nes */ + { 0x0f141525, 152, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Arkanoid II (Japan).nes */ + { 0xbda8f8e4, 152, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Gegege no Kitarou 2 - Youkai Gundan no Chousen (Japan).nes */ + { 0xb1a94b82, 152, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pocket Zaurus - Juu Ouken no Nazo (Japan).nes */ + { 0x026c5fca, 152, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Saint Seiya - Ougon Densetsu (Japan).nes */ + { 0x3f15d20d, 153, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famicom Jump II - Saikyou no 7 Nin (Japan).nes */ + { 0xd1691028, 154, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Devil Man (Japan).nes */ + { 0xcfd4a281, 155, DEFAULT, DFAULT8, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Money Game, The (Japan).nes */ + { 0x2f27cdef, 155, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tatakae!! Rahmen Man - Sakuretsu Choujin 102 Gei (J) [b1].nes */ + { 0xc1719664, 155, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tatakae!! Rahmen Man - Sakuretsu Choujin 102 Gei (Japan).nes */ + { 0xccc03440, 156, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Buzz & Waldog (USA) (Proto) (Unl).nes */ + { 0x983d8175, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Battle Rush - Build Up Robot Tournament (Japan).nes */ + { 0x894efdbc, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Crayon Shin-chan - Ora to Poi Poi (Japan).nes */ + { 0x19e81461, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Dragon Ball Z - Gekitou Tenkaichi Budoukai (Japan).nes */ + { 0xbe06853f, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - J.League Super Top Players (Japan).nes */ + { 0x0be0a328, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - SD Gundam - Gundam Wars (Japan).nes */ + { 0x5b457641, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Ultraman Club - Supokon Fight! (Japan).nes */ + { 0xf51a7f46, 157, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Datach - Yu Yu Hakusho - Bakutou Ankoku Bujutsukai (Japan).nes */ + { 0xcbf4366f, 158, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Alien Syndrome (USA) (Unl).nes */ + { 0xe170404c, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* SD Gundam Gaiden - Knight Gundam Monogatari (Japan).nes */ + { 0x276ac722, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* SD Gundam Gaiden - Knight Gundam Monogatari (Japan) (Rev 1).nes */ + { 0x0cf42e69, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Magical Taruruuto-kun - Fantastic World!! (Japan).nes */ + { 0xdcb972ce, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Magical Taruruuto-kun - Fantastic World!! (Japan) (Rev 1).nes */ + { 0xb7f28915, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Magical Taruruuto-kun 2 - Mahou Daibouken (Japan).nes */ + { 0x183859d2, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball Z - Kyoushuu! Saiya Jin (Japan).nes */ + { 0x58152b42, 160, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pipe V (Asia) (Ja) (Unl).nes */ + { 0x1c098942, 162, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Xi You Ji Hou Zhuan (Ch).nes */ + { 0x081caaff, 163, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Commandos (Ch).nes */ + + /* Mapper 176 */ + { 0xffde0de5, 176, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 梦幻之星4[简体](修正)一战一级.nes */ + { 0xE0ED68B1, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (AA-6109) 4-in-1.nes */ + { 0xC447B9FE, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BRC-4) Super 4-in-1.nes */ + { 0x922D16FD, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-9087) Super Game 3-in-1.nes */ + { 0xC18A7BCB, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-443B) 4-in-1.nes */ + { 0x43BDB0FF, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-8095) Super Game 4-in-1.nes */ + { 0x719CCE0A, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-8394) 4-in-1.nes */ + { 0x12DDA422, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-8404) Super Game 4-in-1.nes */ + { 0xAB09C88B, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-8405) 4-in-1.nes */ + { 0xA2E2031C, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-8406) 4-in-1.nes */ + { 0x6063F4D5, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-A) Super Game.nes */ + { 0xD2F5F51D, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-1008) 10-in-1.nes */ + { 0xBF31508D, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-1102) Super 11-in-1.nes */ + { 0x2B882971, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-1501) 999999-in-1.nes */ + { 0x981AE6BB, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-1901) 19-in-1.nes */ + { 0x5D2129AC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-2001) 20-in-1.nes */ + { 0x9AD9A8E9, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-6006) 6-, 4-in-1.nes */ + { 0x521AF87B, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-6009) 6-in-1 (FK23C).nes */ + { 0xAA05C592, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-6011) Super 6-in-1.nes */ + { 0x205CF073, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-8002) 8-in-1 Supergame.nes */ + { 0xD408F0BC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-9005) 9-in-1 (FK23C).nes */ + { 0x205D476E, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-9006) 9-in-1 Super Game.nes */ + { 0x0B2CF73F, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (MK-035) 3-in-1.nes */ + { 0x2D1C667A, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (MK-036) 3-in-1.nes */ + { 0x25D7CB92, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (MK-038) 4-in-1.nes */ + { 0x8EFF9139, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (MK-042) Super Game 3-in-1.nes */ + { 0xB55103AD, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (MK-042) Super Game 3-in-1 [game name correction] */ + { 0xE83E5726, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (MK-064) Super Game 4-in-1.nes */ + { 0xBEEB0B07, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (MK-064) Super Game 4-in-1 [game name correction].nes */ + { 0xBBFBECBC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (SB-04) 4-in-1.nes */ + { 0x2A1D5933, 176, 0, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* (SC-03) Super 24-in-1.nes */ + { 0x07564AC6, 176, 0, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* (SD-01) 絡克家族大集合 - Rockman 16-in-1.nes */ + { 0xD7D2123C, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (VT-087) 4-in-1.nes */ + { 0x8CB6D32C, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (VT-089) 4-in-1.nes */ + { 0x23994975, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (VT-089) 4-in-1 [Russian].nes */ + { 0x93196E95, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (VT-208) 4-in-1.nes */ + { 0xECFE604A, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-2001) 2-in-1 Mortal-Kombat.nes */ + { 0xA232AA4E, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-3128) Super Game 3-in-1.nes */ + { 0xF565C023, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-3132) Super Game 3-in-1.nes */ + { 0x01131224, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-3133) Super Game 3-in-1.nes */ + { 0x7A76F2B9, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-3135) Super Game 3-in-1.nes */ + { 0xFCACB02A, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-346) 3-in-1.nes */ + { 0x5ADDD942, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-360) Super Game 3-in-1.nes */ + { 0x940933DC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-363) 3-in-1.nes */ + { 0xC06C9AF7, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-370) Super Game 3-in-1.nes */ + { 0x728CA4AF, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-401) 4-in-1.nes */ + { 0xF019BFEF, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-415) Super Game 4-in-1 */ + { 0x4D25A3A6, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-415) Super Game 4-in-1 [game name correction] */ + { 0x5F96184B, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4102) 4-in-1.nes [bad CHR] */ + { 0xC4D1D2F8, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4102) 4-in-1.nes */ + { 0x6D580074, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4118) 4-in-1.nes */ + { 0xFA5B1D26, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4122) 4-in-1 [b].nes */ + { 0x4410BD8D, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4126) Super Game 4-in-1.nes */ + { 0xC3166E11, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4146) 4-in-1.nes */ + { 0xBE05120A, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-417) Super Game 4-in-1.nes */ + { 0x43BDB0FF, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4219) Super Game 4-in-1.nes */ + { 0xF371BCF2, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4228) Super Game 4-in-1.nes */ + { 0xFA1CB05C, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4237) 4-in-1.nes */ + { 0x44F46BBC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4239) New 4-in-1 Supergame.nes */ + { 0x0A486DD7, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4242) Super Game 4-in-1.nes */ + { 0x634036DB, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4246) Super Game 4-in-1.nes */ + { 0xD7A8AFCA, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4247) Super Game 4-in-1.nes */ + { 0x6AB68F4F, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4248) Super Game 4-in-1.nes */ + { 0x1EF30CC8, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4253) 4-in-1.nes */ + { 0x4D18054C, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-437) Super Game 4-in-1.nes */ + { 0x18DD93BC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-437) Super Game 4-in-1 [game name correction].nes */ + { 0x63D43F22, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-451) 4-in-1.nes */ + { 0xBF31508D, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-469) Super 4-in-1.nes */ + { 0x981AE6BB, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-480) 4-in-1.nes */ + { 0x5D2129AC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-481) 4-in-1.nes */ + { 0x5D061E04, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-602) 6-in-1.nes */ + { 0xD2A4A9C6, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-602) Super Game 6-in-1 [game name correction, font change].nes */ + { 0x35974F2C, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-602) Super Game 6-in-1 [font change].nes */ + { 0x5B17FB27, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-801) Super Game 8-in-1.nes */ + { 0x0881169E, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-801) Super Game 8-in-1 [font change].nes */ + { 0xCD55A865, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8023) 4-in-1.nes */ + { 0x92B52357, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8028) 4-in-1.nes */ + { 0xDE94B7FD, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8029) 4-in-1.nes */ + { 0xD56F27AE, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8046) 4-in-1.nes */ + { 0x0E8766DC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8049) 4-in-1.nes */ + { 0x05E43745, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-904) Super Game 9-in-1.nes */ + { 0x31CADEF3, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-904) Super Game 9-in-1 [font change].nes */ + { 0x04398A9F, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (卡聖 NT-945) 2-in-1.nes */ + { 0x9BDF2424, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 12-in-1 Console TV Game Cartridge.nes */ + { 0x629FBEEC, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 125-in-1.nes */ + { 0x6EDED153, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* 16-in-1 Battle Hymn of the Republic.nes */ + { 0x68EDFDEA, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3-in-1 (Mortal Kombat MK5).nes */ + { 0x8E994BCD, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3-in-1 (The Lion King 5).nes */ + { 0x104D84DF, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3in1 (ES-Q800C) (Unl).nes */ + { 0xDC904F4C, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3in1 (ES-Q800C)(FSS).nes */ + { 0xCF7C6AE0, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 3in1 (ES-Q800C)(TRS).nes */ + { 0x4E5F123A, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (Digital Adventure).nes */ + { 0x7DB2D1F5, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 6-in-1 (Spiderman 2, Aladdin).nes */ + { 0x75DFF1A4, 176, 0, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* 6-in-1 (Super Rockman).nes */ + { 0xACCC9036, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 9-in-1 (Pokemon Yellow).nes */ + { 0x674D6CDE, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Intellivision X2 15-in-1 [missing CHR data].nes */ + { 0x0F907E7F, 176, 0, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Rockman 6-in-1 (rev0).nes */ + { 0xE6D869ED, 176, 0, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Rockman 6-in-1 (rev0)[missing CHR data].nes */ + { 0x88E0C48C, 176, 0, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Rockman 6-in-1 (rev1).nes */ + { 0xEECF01BF, 176, 0, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Rockman 6-in-1 (rev3).nes */ + { 0xC043A8DF, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 小博士教育软件系列꞉ 数学 小狀元.nes */ + { 0x2CF5DB05, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 小博士教育软件系列꞉ 智力 小狀元.nes */ + { 0x02C41438, 176, 0, DEFAULT, 1, 0x70, 0x07, DEFAULT, NOEXTRA }, /* 星河战士.nes */ + { 0xA39C9A6B, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KY-1203) Super Game 12-in-1/(YH-467) Super Game 4-in-1 */ + { 0x0F05C0E6, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-701) Super Game 4-in-1 */ + { 0x80F1E11E, 176, 0, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-701) Super Game 4-in-1 [game name correction, font change] */ + { 0xC5C30EFA, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8011) Super Game 4-in-1 */ + { 0x8858D3F7, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8011) Super Game 4-in-1 [game name correction] */ + { 0x18BEB276, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8024) Super Game 4-in-1 */ + { 0xE3A0B9E5, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8027) Super Game 4-in-1 */ + { 0x5A0E3E69, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8033) Super Game 4-in-1 */ + { 0x21D4484A, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-8042) Super Game 4-in-1 */ + { 0xF011AFD6, 4, 0, DEFAULT, 0, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Rockman 4- Minus Infinity [Infinite Life]. Basically oversize MMC3 that fails to enable WRAM before accessing it. */ + { 0x576D9589, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-0210A PCB) Super Mario 4-in-1.nes */ + { 0x01B3EDD2, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-6002) Super Game 16-in-1.nes */ + { 0x291F5318, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-6008) 210-in-1.nes */ + { 0xB12CCB95, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-6028) 180-in-1.nes */ + { 0xD5281CF3, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8002) New 4-in-1.nes */ + { 0x1F6AC22E, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8005) Super Game 3-in-1.nes */ + { 0xB48D6F26, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8008) Super Game 4-in-1.nes */ + { 0xBDDA85CE, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8013) Super Game 4-in-1.nes */ + { 0x85C2CC88, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8029) Super Game 4-in-1.nes */ + { 0x4F2CCD03, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8029) Super Game 4-in-1 [overdump] */ + { 0x40182FF6, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8045) Super Game 4-in-1.nes */ + { 0xF4CE452C, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8062) Super Game 4-in-1.nes */ + { 0x409601A5, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8088) 4-in-1.nes */ + { 0xC8AB31FD, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8103) Super Game 4-in-1.nes */ + { 0x87308F9D, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8105) Super Game 4-in-1.nes */ + { 0x95ACA7A7, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-012) 80-in-1.nes */ + { 0xE650EC91, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-014) 128-in-1.nes */ + { 0x7642F6B6, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-021) 180-in-1.nes */ + { 0x24762CE8, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-022) 178-in-1.nes */ + { 0x761CF0C0, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-026) 210-in-1.nes */ + { 0x165102DB, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-033) 52-in-1.nes */ + { 0x6614D4C0, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-037) Super Game 16-in-1.nes */ + { 0xB3277B6C, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-3004) 6-in-1.nes */ + { 0x3907578B, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8008) 4-in-1.nes */ + { 0xA391549D, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8021) 4-in-1.nes */ + { 0x36C27AE8, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8021) 4-in-1.nes [PRG banks missing] */ + { 0x06D13D9E, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8026) 4-in-1.nes */ + { 0x2EBD5FD6, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8033) 4-in-1.nes */ + { 0x23E4906A, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8043) 4-in-1.nes */ + { 0x10155A92, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8045) 4-in-1.nes */ + { 0xF66944EE, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8050) 4-in-1.nes */ + { 0x8BAEEDC0, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8052) 4-in-1.nes */ + { 0x39307391, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8056) 4-in-1.nes */ + { 0x72CEAB1E, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8078) 4-in-1.nes */ + { 0x05A1F101, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8078) 4-in-1 [bad CHR].nes */ + { 0x07D3F6CB, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8079) 4-in-1.nes */ + { 0x4E34CC0A, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8161) Super Game 12-in-1.nes */ + { 0x20379331, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-8244) 7-in-1.nes */ + { 0x622E9E35, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-xxx) 126-in-1.nes */ + { 0x666E736D, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-xxx) Super 15-in-1.nes */ + { 0x19195C7F, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-xxx) Super 35-in-1.nes */ + { 0x6F775C1A, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (FK-xxx) Super 8-in-1.nes */ + { 0x17D43AF9, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (K-5003) 5-in-1.nes */ + { 0xFE384E4B, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KB-0306N PCB) Super Game 4-in-1 #1.nes */ + { 0x425F5325, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KB-0306N PCB) Super Game 4-in-1 #2.nes */ + { 0xD206A6DF, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KB-4004) Super 4-in-1.nes */ + { 0xF350556E, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KB-4009) Super 4-in-1.nes */ + { 0x14BD2D1C, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KB-4016) Super 4-in-1 [fix Legend of Kage].nes */ + { 0xBB9258BE, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KB-4016) Super 4-in-1.nes */ + { 0x6343E6A6, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KD-1512 PCB) 128-in-1.nes */ + { 0x91A8CD7E, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KD-1512 PCB) Super 20-in-1.nes */ + { 0xE31220BE, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KD-6020) Super Game 131-in-1.nes */ + { 0xB623C3D0, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KD-6024) Super Game 168-in-1.nes */ + { 0x30FFB076, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KD-6033) 7-in-1.nes */ + { 0xF0C581B3, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KG-6009) Super Game 58-in-1.nes */ + { 0x576EC760, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-3445) Super 4-in-1.nes */ + { 0xBF015F20, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-3445A-1) Super 4-in-1.nes */ + { 0x0163CA53, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-3445A-B) 4-in-1.nes */ + { 0x3DF39CE4, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-4403) Super 3-in-1.nes */ + { 0xB8FED144, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-8017) Super Game 4-in-1.nes */ + { 0x10E7B6ED, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-8040) Super Game 4-in-1.nes */ + { 0x38E63310, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KT-8109) Super Game 4-in-1.nes */ + { 0xC6D97331, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-0210A PCB) 4-in-1.nes */ + { 0x9367D1F4, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-0210A PCB) 4-in-1 [Russian].nes */ + { 0xE6617BF1, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (SJ-0027) 180-in-1.nes */ + { 0x9206B787, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YE-C011) 60-in-1.nes */ + { 0x32CDAD83, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (晶太 JY-222) 1998 97格鬥天王 激鬥篇 6-in-1.nes */ + { 0x3C894AD1, 176, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (晶太 JY-224) 1998 97格鬥天王 激鬥篇 7-in-1.nes */ + { 0x78CE996D, 176, 1, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* (晶太 JY-225) 1998 97格鬥天王 激戰篇 6-in-1.nes */ + { 0xB5D25A20, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-0306M PCB) Super 4-in-1.nes */ + { 0x8C48BDBA, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-0306M PCB) Super 4-in-1 #2.nes */ + { 0xC51FA465, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KD-6032) 180-in-1.nes */ + { 0xA22DE99D, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (KD-6026) Super Game 210-in-1 */ + { 0xE8BD5AC3, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-6017) Super Game 28-in-1 */ + { 0x37478F0C, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8009) Super 4-in-1 */ + { 0x98C59170, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8014) Super 4-in-1 */ + { 0x7CA43C89, 176, 1, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (BS-8117) Super Game 4-in-1 */ + { 0x678DE5AA, 176, 2, DEFAULT, 0, DEFAULT, 0x0C, DENDY, NOEXTRA }, /* (外星) 120-in-1.nes */ + { 0x6C979BAC, 176, 2, DEFAULT, 0, DEFAULT, 0x0B, DENDY, NOEXTRA }, /* (奔升) 10-in-1 Omake Game.nes */ + { 0xE79F157E, 176, 2, DEFAULT, 0, DEFAULT, 0x0B, DENDY, NOEXTRA }, /* (福州 Coolboy) 245-in-1 Real Game.nes */ + { 0x3AE35EC1, 176, 2, DEFAULT, 0, DEFAULT, 0x0B, DENDY, NOEXTRA }, /* (福州 Coolboy) 400-in-1 Real Game.nes */ + { 0xD14617D7, 176, 2, DEFAULT, 0, DEFAULT, 0x0B, DENDY, NOEXTRA }, /* (福州 Coolboy) 合金装备 150-in-1 Real Game.nes */ + { 0x37290B20, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Age of Empires - 帝国时代 (970493) [protection removed].nes */ + { 0x5EE2EF97, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Age of Empires - 帝国时代 (970493).nes */ + { 0x5077CAC1, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* EverQuest - 八宝奇珠.nes */ + { 0xF354D847, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Grandia - 格蘭蒂亞傳說 (2006SR04308).nes */ + { 0xD51DD22C, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* SD 高达外传 - 骑士高达故事 3꞉ 传说之骑士团.nes */ + { 0xF29C8186, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* Shanghai Tycoon - 上海大亨 (960313).nes */ + { 0xF2398802, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 七龙珠 2꞉ 激战弗利萨!!.nes */ + { 0x53B62838, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 七龙珠 2꞉ 电光石火.nes */ + { 0xED481B7C, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 七龙珠 Z 外传꞉ 赛亚人灭绝计划 (rev1).nes */ + { 0xC768098B, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 三侠五义꞉ 御猫傳奇 (2006SR04307).nes */ + { 0xB511C04B, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 三侠五义꞉ 御猫傳奇 (2006SR04307)[protection removed].nes */ + { 0x44C20420, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 三国志 II - 中文加强版.nes */ + { 0x8FFC1864, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 三国志 II꞉ 覇王の大陸.nes */ + { 0x8F6AB5AC, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 三国忠烈传 - The Story of Three Kingdoms (FS005).nes */ + { 0x94782FBD, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 三國志꞉ 雄霸天下 (980100026).nes */ + { 0x99051CB5, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 三國志꞉ 雄霸天下 (980337).nes */ + { 0x3A1CFE21, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 上古神殿.nes */ + { 0xD6EA31C0, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 东周列国志 (2006SR04301).nes */ + { 0x03346083, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 东周列国志 (2006SR04301)[protection removed].nes */ + { 0x33443508, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 争霸世纪 (960268).nes */ + { 0x7696573A, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 亚特鲁战记.nes */ + { 0xFE383376, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 仙剑神曲 - Space General [protection removed].nes */ + { 0x97F3D7C1, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 仙剑神曲 - Space General.nes */ + { 0x8264EA52, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 侠客情꞉ 荆轲刺秦王 (FS005).nes */ + { 0x027FD794, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 剑舞者 - Sword Dancer.nes */ + { 0x095D8678, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 双月传.nes */ + { 0xD5F7AAEF, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 神风剑.nes */ + { 0x377FDB36, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 口袋精靈꞉ 金.nes */ + { 0x85DD49B6, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 口袋精靈꞉ 金 [protection removed].nes */ + { 0x3F6124C3, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 哆啦A梦 - 超时空历险 [a].nes */ + { 0x69A3CA5C, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 哆啦A梦 - 超时空历险.nes */ + { 0x548D72FF, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 哥伦布 冒险记 - 黄金中文版.nes */ + { 0xEEBEE0C8, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 哥伦布传 - 黄金中文版 (FS006).nes */ + { 0x3C9DF646, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 圣斗士.nes */ + { 0x52A5F554, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 基督山恩仇记 - Le Comte de Monte Cristo (970260).nes */ + { 0x35F8BD75, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 基督山恩仇记 - Le Comte de Monte Cristo (970260)[protection removed].nes */ + { 0xEE49F509, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 大盗伍佑卫门之天下宝藏.nes */ + { 0xC04D330D, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 夺宝小英豪꞉ 光明與黑暗傳説 (960270).nes */ + { 0x848F2D69, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 女神的救赎.nes */ + { 0x2C3D4EF0, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 宠物꞉ 翡翠 (2004SR05368).nes */ + { 0x09FC02C7, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 宠物꞉ 翡翠 (2004SR05368)[protection removed].nes */ + { 0x913B95F7, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 富甲三国 [protection removed].nes */ + { 0x0F73D488, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 富甲三国.nes */ + { 0x8947AB85, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 少年游侠꞉ 光明之神 - Young Chivalry (FS005).nes */ + { 0xEE66C5E8, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 帝国风暴 - Napoleon's War (980340) [protection removed].nes */ + { 0x351DD533, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 帝国风暴 - Napoleon's War (980340).nes */ + { 0xEABBB630, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 怪物制造者 1.nes */ + { 0xF1D40F5B, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 怪物制造者 2.nes */ + { 0x2661109F, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 戰國無雙 [protection removed].nes */ + { 0xCC6E548C, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 戰國無雙.nes */ + { 0xBA29435A, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 戰國群雄傳 (970498).nes */ + { 0x5A88B5B0, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 数码暴龙 4꞉ 水晶版 (2004SR01259).nes */ + { 0xA46353D1, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 杨家将 - Yang's Troops (980186).nes */ + { 0xC155128F, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 梁山英雄传 [protection removed].nes */ + { 0xAD223177, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 梁山英雄传.nes */ + { 0xBF6E95F5, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 梦境之王 - Dream Master.nes */ + { 0x416C07A1, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 梦幻之星 IV.nes */ + { 0x852CE16B, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 楚漢爭霸 - The War Between Chu & Han (980005).nes */ + { 0xE0DD8D77, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 楚留香꞉ 香帥傳奇之血海飘零 (FS005).nes */ + { 0x2E4F3051, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 楚留香꞉ 香帥傳奇之血海飘零 (FS005)[protection removed].nes */ + { 0x34AC5AE9, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 水滸傳 - Marsh Outlaws (960415).nes */ + { 0x1923A8C5, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 水滸神獸 [protection removed].nes */ + { 0x6B4CAC80, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 水滸神獸.nes */ + { 0xC9D968AF, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 混沌世界.nes */ + { 0x7F3DBF1B, 176, 2, DEFAULT, 1, 0x90, 0x07, PAL, NOEXTRA }, /* 混沌世界 [VirtuaNES PAL].nes */ + { 0xB616885C, 176, 2, DEFAULT, 1, 0x90, 0x07, PAL, NOEXTRA }, /* 混沌世界 [VirtuaNES PAL, SRAM bank switch removed].nes */ + { 0xF031E7CD, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 激战弗利萨之孙悟饭.nes */ + { 0xD871D3E6, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 激战弗利萨之孙悟饭 [bad CHR].nes */ + { 0xC35E9AA8, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 激战弗利萨之孙悟饭 [Traditional Chinese].nes */ + { 0xBFF7C60C, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 激斗圣战士.nes */ + { 0x8CAAFF73, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 爆笑三國 - Jacks in Tri-Empire (970261)(FS005).nes */ + { 0x97B82F53, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 爆笑三國 - Jacks in Tri-Empire (970261)(FS005)[protection removed].nes */ + { 0x95569A86, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 甲A - China Soccer League for Division A (980333).nes */ + { 0x977D22C3, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 破釜沉舟 [protection removed].nes */ + { 0xA2DC64FF, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 破釜沉舟.nes */ + { 0x356A16E9, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 絶代英雄 - Unrivalled Hero [protection removed].nes */ + { 0xDA7D586D, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 絶代英雄 - Unrivalled Hero.nes */ + { 0x50D5F94B, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 英烈群侠传 (980332).nes */ + { 0xF5C16B14, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 荣耀之骑士团 [protection removed].nes */ + { 0xFB2563D1, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 荣耀之骑士团.nes */ + { 0xF9863ADF, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 西楚霸王 (980100461)(FS005).nes */ + { 0x3FF36623, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 西楚霸王 (990031).nes */ + { 0xF1D803F3, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 西楚霸王 (990031)[protection].nes */ + { 0x49F22159, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 超级 大富翁 - Super Rich (FS005).nes */ + { 0x2DDA2835, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 超级 大战略 [protection removed].nes */ + { 0x7DCE29CB, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 超级 大战略.nes */ + { 0x0DBFF515, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 银白色沙加.nes */ + { 0x38EFFD3E, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 隋唐演义 (980185).nes */ + { 0xCC56BCFE, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 風雲 - Traitor Legend (970100684)(FS005).nes */ + { 0xFD883527, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 風雲 - Traitor Legend (980334).nes */ + { 0xBC4AC7FE, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 高达骑士物语 2꞉ 光之骑士.nes */ + { 0xB8FCD425, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 高达骑士物语.nes */ + { 0xF17E49D5, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 鬼魅战记.nes */ + { 0x4BCDB970, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 鬼魅战记.nes */ + { 0x7D9C7206, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 魔域英雄传 - Hero on Devil Lands (FS005).nes */ + { 0xB16D4268, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 魔法门之英雄无敌 (980584).nes */ + { 0x71DAF1A6, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 魔法门之英雄无敌 (980584)[protection removed].nes */ + { 0x3532A114, 176, 2, DEFAULT, 1, 0x90, DEFAULT, DENDY, NOEXTRA }, /* 魔神法师 - Demogorgon Monk (FS005).nes */ + { 0xE8EAFBC1, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙之谷 [protection removed].nes */ + { 0x27DBC407, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙之谷.nes */ + { 0xEBA09ADA, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙域天下.nes */ + { 0x62DDE924, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙珠Z3꞉ 人造人列传.nes */ + { 0x42161530, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙魂 [protection removed].nes */ + { 0x8F8FC9A7, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙魂.nes */ + { 0xB6984DAD, 176, 3, DEFAULT, 1, 0x07, 0x0B, DEFAULT, NOEXTRA }, /* Super Mario 160-in-1 Funny Time.nes */ + { 0xB6984DAD, 176, 4, DEFAULT, 1, 0x07, 0x07, DEFAULT, NOEXTRA }, /* GameStar Smart Genius Deluxe.nes */ + + /* Non-Mapper 176 files that are sometimes found erroneously set to mapper 176 */ + { 0x60AC647F, 260, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4222) Super Game 4-in-1.nes */ + + { 0x558c0dc3, 178, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 2-in-1 (Soccer Game & Crazy Dance) (Unl) [!].nes */ + { 0xc68363f6, 180, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Crazy Climber (Japan).nes */ + { 0x0f05ff0a, 181, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Seicross (Japan) (Rev 1).nes */ + { 0x96ce586e, 189, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter II - The World Warrior (Unl) [!].nes */ + { 0x0e76e4c1, 190, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Magic Kid Googoo (Korea) (Unl).nes */ + { 0x555a555e, 191, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sugoro Quest - Dice no Senshitachi (Ch).nes */ + { 0x2cc381f6, 191, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Sugoro Quest - Dice no Senshitachi (Ch) [o1].nes */ + { 0xa145fae6, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Young Chivalry (Ch) [b3].nes */ + { 0xa9115bc1, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Young Chivalry (Ch) [!].nes */ + { 0x4c7bbb0e, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Young Chivalry (Ch) [b2].nes */ + { 0x98c1cd4b, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ying Lie Qun Xia Zhuan (Asia) (Unl).nes */ + { 0xee810d55, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* You Ling Xing Dong (Asia) (Unl).nes */ + { 0x442f1a29, 192, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Young Chivalry (Ch) [b1].nes */ + { 0x637134e8, 193, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Fighting Hero (Asia) (Ja) (Unl).nes */ + { 0xa925226c, 194, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dai-2-Ji - Super Robot Taisen (Ch) [b1].nes */ + { 0x33c5df92, 195, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain Tsubasa Vol. II - Super Striker (Ch) [a1].nes */ + { 0x1bc0be6c, 195, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Captain Tsubasa Vol. II - Super Striker (Ch) [a3].nes */ + { 0xd5224fde, 195, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* God Slayer - Haruka Tenkuu no Sonata (Ch).nes */ + { 0xfdec419f, 196, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter VI 16 Peoples (Unl) [!].nes */ + { 0x700705f4, 198, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ---- */ + { 0x9a2cf02c, 198, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ---- */ + { 0xd8b401a7, 198, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ---- */ + { 0x28192599, 198, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ---- */ + { 0x19b9e732, 198, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tenchi wo Kurau II - Shokatsu Koumei Den (J) (PRG0) [T-Chi][b6].nes */ + { 0xdd431ba7, 198, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Tenchi wo kurau 2 (c) */ + { 0x05658ded, 201, 15, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 21-in-1 (CF-043) (2006-V) (Unl) [p1].nes */ + { 0x276237b3, 206, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Karnov (Japan) (Rev 1).nes */ + { 0xa5e6baf9, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Slayer IV - Drasle Family (Japan).nes */ + { 0x4f2f1846, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '89 - Kaimaku Ban!! (Japan).nes */ + { 0x22d6d5bd, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Jikuu Yuuden - Debias (Japan).nes */ + { 0x9d21fe96, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Lupin Sansei - Pandora no Isan (Japan).nes */ + { 0xae321339, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pro Yakyuu - Family Stadium '88 (Japan).nes */ + { 0x96dfc776, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* R.B.I. Baseball 2 (USA) (Unl).nes */ + { 0xfd63e7ac, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* R.B.I. Baseball 3 (USA) (Unl).nes */ + { 0x2a01f9d1, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wagyan Land (Japan).nes */ + { 0x7678f1d5, 207, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Fudou Myouou Den (Japan).nes */ + { 0x07eb2c12, 208, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* FC25-台湾格斗游戏+快打传说.nes */ + { 0xdd8ced31, 209, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Power Rangers III (Unl) [!].nes */ + { 0x063b1151, 209, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Power Rangers IV (Unl) [!].nes */ + { 0xdd4d9a62, 209, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Shin Samurai Spirits 2 - Haoumaru Jigoku Hen (Ch).nes */ + { 0x0c47946d, 210, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Chibi Maruko-chan - Uki Uki Shopping (Japan).nes */ + { 0xc247cc80, 210, 1, MI_V, 1, 0x50, DEFAULT, DEFAULT, NOEXTRA }, /* Family Circuit '91 (Japan) (En).nes */ + { 0x808606f0, 210, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '91 (Japan).nes */ + { 0x6ec51de5, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '92 (Japan).nes */ + { 0xadffd64f, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '93 (Japan).nes */ + { 0x429103c9, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Famista '94 (Japan).nes */ + { 0x81b7f1a8, 210, 1, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Heisei Tensai Bakabon (Japan).nes */ + { 0x2447e03b, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Top Striker (Japan).nes */ + { 0x1dc0f740, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wagyan Land 2 (Japan).nes */ + { 0xd323b806, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wagyan Land 3 (Japan).nes */ + { 0xbd523011, 210, 2, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Namco Prism Zone - Dream Master (Japan).nes */ + { 0x5daae69a, 211, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Aladdin - Return of Jaffar, The (Unl) [!].nes */ + { 0x1ec1dfeb, 217, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 255-in-1 (Mapper 204) [p1].nes */ + { 0x046d70cc, 217, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? 500-in-1 (Anim Splash, Alt Mapper)[p1][!] */ + { 0x12f86a4d, 217, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 500-in-1.nes */ + { 0xd09f778d, 217, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? 9999999-in-1 (Static Splash, Alt Mapper)[p1][!] */ + { 0x62ef6c79, 232, DEFAULT, DFAULT8, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Quattro Sports (Camerica) (Aladdin) [b1].nes */ + { 0x2705eaeb, 234, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Maxi 15 (USA) (Unl).nes */ + { 0x80cbcacb, 235, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 100-in-1 (Unl).nes */ + { 0x6175b9a0, 235, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 150_in_1_199x-ASp.nes */ + { 0x745a6791, 235, 2, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 210-in-1 and Contra 4-in-1 (212-in-1,212 Hong Kong,Reset Based)(Unl).nes */ + { 0xdf81364d, 235, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 260-in-1 [p1][!].nes */ + { 0xa38f2f1d, 235, DEFAULT, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* 1500-in-1.nes */ + { 0x6f12afc5, 235, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? Golden Game 150-in-1 */ + { 0x2537b3e6, 241, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dance Xtreme - Prima (Unl).nes */ + { 0x11611e89, 241, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Darkseed (Unl) [p1][b1].nes */ + { 0x81a37827, 241, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Darkseed (Unl) [p1].nes */ + { 0xfb2b6b10, 241, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Fan Kong Jing Ying (Asia) (Unl).nes */ + { 0xb5e83c9a, 241, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Xing Ji Zheng Ba (Asia) (Unl).nes */ + { 0x368c19a8, 241, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* LIKO Study Cartridge 3-in-1 (Unl) [!].nes */ + { 0x54d98b79, 241, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Titanic 1912 (Unl).nes */ + { 0xc2730c30, 34, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Deadly Towers (USA).nes */ + { 0xa21e675c, 34, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mashou (Japan).nes */ + { 0x6bea1235, 245, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yong Zhe Dou E Long - Dragon Quest VI (Ch) [a1].nes */ + { 0x345ee51a, 245, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yong Zhe Dou E Long - Dragon Quest VII (Ch).nes */ + { 0x57514c6c, 245, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Yong Zhe Dou E Long - Dragon Quest VI (Ch).nes */ + { 0xdb9d71b7, 114, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Donkey Kong (Unl) [o1].nes */ + + /* KT-008 PCB. These require mapper 224 for having an outer bank register at $5xxx, but are usually found set to mapper 4. */ + { 0x61fc4d20, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* (KT-1062) 口袋怪兽꞉ 水晶版.nes */ + { 0xaa666c19, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys Origin: Hugo.nes */ + { 0xb0d011d3, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys Origin: Yunica.nes */ + { 0x16143319, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys VI: 纳比斯汀的方舟.nes */ + { 0xe05fc21f, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Ys: 菲尔盖纳之誓约.nes */ + { 0xf8b58b59, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志 - 蜀魏争霸.nes */ + { 0xcb1bab3d, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志꞉ 蜀汉风云.nes */ + { 0xddc122ed, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 亡灵崛起.nes */ + { 0x4d2811c7, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 伏魔英雄传.nes */ + { 0x24750e5d, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 傲视天地.nes */ + { 0xc658b6a8, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 刀剑英雄传.nes */ + { 0xea831217, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 剑侠情缘.nes */ + { 0x92ebad5b, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙 III꞉ 罪恶渊源.nes */ + { 0x48210324, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 勇者的试炼.nes */ + { 0x3439d140, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 天空的新娘.nes */ + { 0x9a0a531a, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者斗恶龙꞉ 天空篇.nes */ + { 0xb5fdb3cb, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 勇者黑暗世界 - 混沌世界.nes */ + { 0x4f427110, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 珍珠版.nes */ + { 0xa46d6f4c, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 琥珀版.nes */ + { 0xe001de16, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 白金版.nes */ + { 0x5464d7f8, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 翡翠版.nes */ + { 0x4d735cb1, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋怪兽꞉ 钻石版.nes */ + { 0x5d04547c, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 失落的神器.nes */ + { 0xcb524b42, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 征战天下.nes */ + { 0x5f362198, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 战神世界.nes */ + { 0x36de88e7, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 新魔界.nes */ + { 0xf8e9c9cf, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 无双乱舞.nes */ + { 0xa4c39535, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 神魔大陆.nes */ + { 0x76bbe916, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 落日征战.nes */ + { 0x9b518d54, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 云的彼端.nes */ + { 0x91396b3f, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 天之痕.nes */ + { 0xaa621fa0, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 枫之舞.nes */ + { 0x48d1f54a, 224, DEFAULT, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑꞉ 王者归来.nes */ + + { 0xbdbe3c96, 238, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Contra Fighter (Unl).nes */ + { 0xcb53c523, 11, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* King Neptune's Adventure (USA) (Unl).nes */ + { 0x6e149729, 189, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Master Fighter II (Unl) [a1].nes */ + { 0x60bfeb0c, 90, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat 2 (Unl) [!].nes */ + { 0x247cc73d, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Poker II (Asia) (Ja) (Unl).nes */ + { 0x1f1326d4, 121, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super Sonic 5 (1997) (Unl) [!].nes */ + { 0x99748230, 215, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* EarthWorm Jim 2 (SuperGame).nes */ + { 0x37876ac7, 215, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Golden Card 6-in-1 (Unl) [!].nes */ + { 0x1a3320a3, 215, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat 3 (SuperGame).nes */ + { 0x80eb1839, 114, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Boogerman (Sugar Softec) (Unl) [!].nes */ + { 0x071e4ee8, 114, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* ?? m114,submapper 1 test rom */ + { 0xfe3e03a1, 197, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat III Special (YY-030) (Ch) [!].nes */ + { 0x9151d311, 197, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat III 28 Peoples (NT-328) (Ch) [!].nes */ + { 0x272709b9, 237, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Teletubbies Y2K (420-in-1).nes */ + { 0x2e27e0af, 227, DEFAULT, DEFAULT, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Bio Hazard.nes */ + { 0x0e7e9309, 189, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter II - The World Warrior (Unl) [a1].nes */ + { 0xa3ac0095, 189, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Fighter II - The World Warrior (Unl) [a2].nes */ + { 0xeced5899, 121, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ultimate Mortal Kombat 4 (Unl) [!].nes */ + { 0x19c1ed51, 150, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Poker III (Asia) (Ja) (Unl).nes */ + { 0x282745c5, 141, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Q Boy (Asia) (Ja) (Unl).nes */ + { 0x4b9ecfb2, 21, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Wai Wai World 2 - SOS!! Paseri Jou (Japan) (Virtual Console).nes */ + { 0x33751782, 4, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Zoda's Revenge - StarTropics II (USA, Europe) (Virtual Console).nes */ + { 0x9bbf3e5d, 15, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 168-in-1 [p1][!].nes */ + + /* TXC / Sachen / JoyVan */ + + /* This cart does not work anymore with latest mapper implementation. + * This will be run using alternate mapper using override in m132 */ + { 0x2a5f4c5a, 132, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Zhan Guo Si Chuan Sheng (C&E) (Unl).nes */ + + { 0x0acfc3cd, 132, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mahjong Block (MGC-008) (Unl) [!].nes */ + + /* ines mappers that uses iNes 2.0 numbers */ + + /* CRC32, mapperNum, SubMapper, Mirroring, hasBattery, prgRam, chrRam, region, extra flags */ + { 0xf6bd8e31, 281, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 1997 Super HIK 4-in-1 (JY-052) [p1][!].nes */ + /* dumps are assigned 281, but its 293 on nesdev */ + { 0x06256C80, 293, DEFAULT, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* Super 12-in-1 NewStar (UNL) */ + { 0x5aa23a15, 361, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (OK-411)[p1][!].nes */ + { 0xf6b9d088, 366, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (K-3131GS, GN-45) [p1][!].nes */ + { 0x503566b2, 366, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 4-in-1 (K-3131SS, GN-45) [p1][!].nes */ + { 0xdb2d2d88, 369, DEFAULT, DEFAULT, 0, 0x07, DEFAULT, DEFAULT, NOEXTRA }, /* Super Mario Bros. Party.nes */ + { 0x87f83ea2, 380, DEFAULT, DEFAULT, 0, DEFAULT, 0x07, DEFAULT, NOEXTRA }, /* 42 to 80,000 */ + { 0xc4b94bd5, 389, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Caltron - 9 in 1 (USA) (Proto) (Unl).nes */ + { 0x2F497313, 401, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Super 19-in-1 (VIP19) */ + + /* ines mappers that uses unif boards */ + + { 0x0073dbd8, 260, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 2-in-1 - Mortal Kombat V Turbo 30 + Super Aladdin (Unl) [p1][!].nes */ + { 0x4dc6107d, 260, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 2-in-1 - Boogerman + Flintstones, The (Unl) [p1][!].nes */ + { 0xb72b2cf4, 260, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 2-in-1 - Aladdin + Lion King, The (Unl) [p1][!].nes */ + { 0x5638ba59, 260, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Mortal Kombat Trilogy - 8 People (M1274) (Ch) [!].nes */ + { 0xa1dc16c0, 262, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Street Heroes (Asia) (Ja) (Unl).nes */ + { 0x1df10182, 263, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Boogerman II (Rex-Soft) [!].nes */ + { 0xf956fcea, 521, DEFAULT, DEFAULT, 0, DEFAULT, 0x70, DEFAULT, NOEXTRA }, /* Korean Igo (Korea) (Unl).nes */ + { 0x2eed2e34, 289, DEFAULT, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 76-in-1 [p1][a1].nes 2048 PRG, 0 CHR */ + + { 0x00000000, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT, NOEXTRA } + +#endif \ No newline at end of file diff --git a/src/ines.c b/src/ines.c index 8f299c1..7f807d3 100644 --- a/src/ines.c +++ b/src/ines.c @@ -290,6 +290,7 @@ static void CheckHInfo(void) { } } if (moo[x].submapper >= 0) { + iNESCart.iNES2 = 1; if (moo[x].submapper != iNESCart.submapper) { iNESCart.submapper = moo[x].submapper; } @@ -590,7 +591,7 @@ INES_BOARD_BEGIN() INES_BOARD( "Idea-Tek ET.xx", 173, Mapper173_Init ) /* INES_BOARD( "", 174, Mapper174_Init ) */ INES_BOARD( "", 175, Mapper175_Init ) - INES_BOARD( "BMCFK23C", 176, BMCFK23C_Init ) /* zero 26-may-2012 - well, i have some WXN junk games that use 176 for instance ????. i dont know what game uses this BMCFK23C as mapper 176. we'll have to make a note when we find it. */ + INES_BOARD( "BMCFK23C", 176, Mapper176_Init ) INES_BOARD( "", 177, Mapper177_Init ) INES_BOARD( "", 178, Mapper178_Init ) /* INES_BOARD( "", 179, Mapper179_Init ) */ diff --git a/src/ines.h b/src/ines.h index 94912ea..330c0a5 100644 --- a/src/ines.h +++ b/src/ines.h @@ -176,6 +176,7 @@ void Mapper171_Init(CartInfo *); void Mapper172_Init(CartInfo *); void Mapper173_Init(CartInfo *); void Mapper175_Init(CartInfo *); +void Mapper176_Init(CartInfo *); void Mapper177_Init(CartInfo *); void Mapper178_Init(CartInfo *); void Mapper180_Init(CartInfo *); From e1f4133bb2636ee06fcc22935dd8de411332f41a Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Fri, 28 May 2021 21:46:55 +0200 Subject: [PATCH 114/295] Improve the UNIF to subType heuristics, since UNIF ROMs do not use the database in ines-correct.h. --- src/boards/fk23c.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index 7f75d46..da692e8 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -527,7 +527,7 @@ void Mapper176_Init(CartInfo *info) { /* .NES file */ Init(info); } -void BMCFK23C_Init(CartInfo *info) /* UNIF FK23C */ +void BMCFK23C_Init(CartInfo *info) /* UNIF FK23C. Also includes mislabelled WAIXING-FS005, recognizable by their PRG-ROM size. */ { if (!UNIFchrrama) { @@ -537,38 +537,26 @@ void BMCFK23C_Init(CartInfo *info) /* UNIF FK23C */ } WRAMSIZE = 8 * 1024; - /* UNIF FK23C differs from UNIF FK23CA explicitly by the absence of a DIP switch */ dipsw_enable = 0; - after_power = 0; + after_power = 1; jncota523 = 0; - - /* The UNIF MAPR tells us nothing about whether it is subtype 0 or 1 */ - subType = (ROM_size ==128 && VROM_size ==256 || /* 2048+2048 */ - ROM_size ==128 && VROM_size ==128 || /* 2048+1024 */ - ROM_size ==128 && VROM_size ==64 || /* 2048+512 */ - ROM_size ==128 && VROM_size ==0 || /* 2048+0 */ - ROM_size ==64 && VROM_size ==64)? /* 1024+512 */ - 0: 1; + subType =ROM_size *16 >=4096? 2: ROM_size == 64 && VROM_size == 128? 1: 0; + if (subType == 2) + CHRRAMSIZE = 256 * 1024; Init(info); } -void BMCFK23CA_Init(CartInfo *info) /* UNIF FK23CA */ +void BMCFK23CA_Init(CartInfo *info) /* UNIF FK23CA. Also includes mislabelled WAIXING-FS005, recognizable by their PRG-ROM size. */ { WRAMSIZE = 8 * 1024; - /* UNIF FK23CA differs from UNIF FK23C explicitly by the presence of a DIP switch */ - dipsw_enable = 1; - after_power = 0; + dipsw_enable = 0; + after_power = 1; jncota523 = 0; - - /* The UNIF MAPR tells us nothing about whether it is subtype 0 or 1 */ - subType = (ROM_size ==128 && VROM_size ==256 || /* 2048+2048 */ - ROM_size ==128 && VROM_size ==128 || /* 2048+1024 */ - ROM_size ==128 && VROM_size ==64 || /* 2048+512 */ - ROM_size ==128 && VROM_size ==0 || /* 2048+0 */ - ROM_size ==64 && VROM_size ==64)? /* 1024+512 */ - 0: 1; + subType =ROM_size *16 >=2048? 2: 1; + if (subType == 2) + CHRRAMSIZE = 256 * 1024; Init(info); } From 16bec051bf87cdb3bdbb8d00f7f1ed5819ecba8a Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Fri, 28 May 2021 22:03:19 +0200 Subject: [PATCH 115/295] Make sure the comments reflect what the code actually does. --- src/boards/fk23c.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index da692e8..bbbb23b 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -33,16 +33,10 @@ Verified on real hardware: "Legend of Kage" sets CNROM latch 1 and switches between CHR bank 0 and 1 using 5FF2, causing the wrong bank (1 instead of 0) during gameplay. - Heuristics for NES 1.0: - - 1 MiB PRG+1 MiB CHR => Submapper 1 - - 256 KiB PRG+128 KiB CHR => Submapper 1 - - 128 KiB PRG+64 KiB CHR => Submapper 1 - - A001.5 ever set => Submapper 2 - - 5FF5/5FF6 written-to => Submapper 3 - Heuristic for detecting whether the DIP switch should be changed on every soft reset: The first write to the $5xxx range is to $501x => ROM always addresses $501x; changing the DIP switch on reset would break the emulation after reset, so don't do it. The first write to the $5xxx range is to $5020 or higher => ROM either uses a DIP switch or writes to $5FFx for safety; changing the DIP switch on reset is possible. + Exclude the $5FF3 address as well as $5000-$500F from this heuristic. */ #include "mapinc.h" @@ -512,7 +506,7 @@ void Mapper176_Init(CartInfo *info) { /* .NES file */ WRAMSIZE = 8 * 1024; /* Distinguishing subType 1 from subType 0 is important for the correct reset vector location. - It is safe to assume subType 1 except for 1024+512 KiB ROMs. */ + It is safe to assume subType 1 except for the following-sized ROMs. */ subType = (ROM_size ==128 && VROM_size ==256 || /* 2048+2048 */ ROM_size ==128 && VROM_size ==128 || /* 2048+1024 */ ROM_size ==128 && VROM_size ==64 || /* 2048+512 */ From 97ffbc5f833bce48e01e18471bba13562be7056e Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Sun, 30 May 2021 01:08:41 +0200 Subject: [PATCH 116/295] Rewrite mappers 162,163,164; add mapper 558. Add EEPROM support to 164. --- src/boards/162.c | 101 ++++++++++++++ src/boards/163.c | 106 +++++++++++++++ src/boards/164.c | 278 ++++++++++++-------------------------- src/boards/eeprom_93C66.c | 135 ++++++++++++++++++ src/boards/eeprom_93C66.h | 10 ++ src/ines-correct.h | 4 +- src/ines.c | 3 +- src/ines.h | 2 + src/unif.c | 2 +- src/unif.h | 1 - 10 files changed, 442 insertions(+), 200 deletions(-) create mode 100644 src/boards/162.c create mode 100644 src/boards/163.c create mode 100644 src/boards/eeprom_93C66.c create mode 100644 src/boards/eeprom_93C66.h diff --git a/src/boards/162.c b/src/boards/162.c new file mode 100644 index 0000000..973f94b --- /dev/null +++ b/src/boards/162.c @@ -0,0 +1,101 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * Copyright (C) 2005 CaH4e3 + * 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 + */ + +/* Waixing FS304 PCB */ + +#include "mapinc.h" +#include "../ines.h" + +static uint8 reg[4]; +static SFORMAT StateRegs[] = +{ + { reg, 4, "REGS" }, + { 0 } +}; + +static void sync() +{ + setprg32(0x8000, reg[2] <<4 | reg[0] &0x0C /* PRG A17-A20 always normal from $5000 and $5200 */ + | ( reg[3] &0x04 ? 0x00 : 0x02) /* PRG A16 is 1 if $5300.2=0 */ + | ( reg[3] &0x04 ?(reg[0] &0x02): 0x00) /* PRG A16 is $5000.1 if %5300.2=1 */ + | ( reg[3] &0x01? 0x00 : reg[1] >>1 &0x01) /* PRG A15 is $5100.1 if $5300.0=0 */ + | (~reg[3] &0x04 && reg[3] &0x01? 0x01 : 0x00) /* PRG A15 is 1 if $5300.2=0 and $5300.0=1 */ + | ( reg[3] &0x04 && reg[3] &0x01?(reg[0] &0x01): 0x00) /* PRG A15 is $5000.0 if $5300.2=1 and $5300.0=1 */ + ); + setprg8r(0x10, 0x6000, 0); + if (~reg[0] &0x80) + setchr8(0); +} + +static void hblank(void) { + if (reg[0] &0x80 && scanline <239) + { /* Actual hardware cannot look at the current scanline number, but instead latches PA09 on PA13 rises. This does not seem possible with the current PPU emulation however. */ + setchr4(0x0000, scanline>=127? 1: 0); + setchr4(0x1000, scanline>=127? 1: 0); + } + else + setchr8(0); +} + +static DECLFR(readReg) +{ + return 0x00; +} + +static DECLFW(writeReg) +{ + reg[A >>8 &3] = V; + sync(); +} + +static void power(void) +{ + memset(reg, 0, sizeof(reg)); + sync(); + SetReadHandler (0x5000, 0x57FF, readReg); + SetWriteHandler(0x5000, 0x57FF, writeReg); + SetReadHandler (0x6000, 0xFFFF, CartBR); + SetWriteHandler(0x6000, 0x7FFF, CartBW); +} + +static void reset() +{ + memset(reg, 0, sizeof(reg)); + sync(); +} + +void Mapper162_Init (CartInfo *info) +{ + uint32 WRAMSIZE = info->iNES2? (info->PRGRamSize + info->PRGRamSaveSize): 8192; + info->Power = power; + info->Reset = reset; + GameHBIRQHook = hblank; + AddExState(StateRegs, ~0, 0, 0); + + uint8* WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); + if (info->battery) { + info->SaveGame[0] = WRAM; + info->SaveGameLen[0] = WRAMSIZE; + } +} diff --git a/src/boards/163.c b/src/boards/163.c new file mode 100644 index 0000000..4671e0d --- /dev/null +++ b/src/boards/163.c @@ -0,0 +1,106 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * Copyright (C) 2005 CaH4e3 + * 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 + */ + +/* Nanjing FC-001 PCB */ + +#include "mapinc.h" +#include "../ines.h" + +static uint8 reg[4]; +static SFORMAT StateRegs[] = +{ + { reg, 4, "REGS" }, + { 0 } +}; + +static void sync() +{ + setprg32(0x8000, reg[2] <<4 | reg[0] &0xF | (reg[3] &0x04? 0x00: 0x03)); + setprg8r(0x10, 0x6000, 0); + if (~reg[0] &0x80) + setchr8(0); +} + +static void hblank(void) { + if (reg[0] &0x80 && scanline <239) + { /* Actual hardware cannot look at the current scanline number, but instead latches PA09 on PA13 rises. This does not seem possible with the current PPU emulation however. */ + setchr4(0x0000, scanline>=127? 1: 0); + setchr4(0x1000, scanline>=127? 1: 0); + } + else + setchr8(0); +} + +static DECLFR(readReg) +{ + return ~reg[1] &0x04; +} + +static DECLFW(writeReg) +{ + uint8 index = A >>8 &3; + + /* Swap bits of registers 0-2 again if the "swap bits" bit is set. Exclude register 2 on when PRG-ROM is 1 MiB. */ + if (reg[3] &0x01 && index <= (ROM_size == 64? 1: 2)) + V = V &~3 | V >>1 &1 | V <<1 &2; + + if (A &1) + { + if (reg[1] &0x01 && ~V &0x01) reg[1] ^=0x04; // If A0=1, flip feedback bit on falling edges of D0 + } // If A0=0, write to register + else + reg[index] = V; + sync(); +} + +static void power(void) +{ + memset(reg, 0, sizeof(reg)); + sync(); + SetReadHandler (0x5000, 0x57FF, readReg); + SetWriteHandler(0x5000, 0x57FF, writeReg); + SetReadHandler (0x6000, 0xFFFF, CartBR); + SetWriteHandler(0x6000, 0x7FFF, CartBW); +} + +static void reset() +{ + memset(reg, 0, sizeof(reg)); + sync(); +} + +void Mapper163_Init (CartInfo *info) +{ + uint32 WRAMSIZE = info->iNES2? (info->PRGRamSize + info->PRGRamSaveSize): 8192; + info->Power = power; + info->Reset = reset; + GameHBIRQHook = hblank; + AddExState(StateRegs, ~0, 0, 0); + + uint8* WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); + if (info->battery) { + info->SaveGame[0] = WRAM; + info->SaveGameLen[0] = WRAMSIZE; + } +} diff --git a/src/boards/164.c b/src/boards/164.c index 7516945..2e0f23c 100644 --- a/src/boards/164.c +++ b/src/boards/164.c @@ -1,7 +1,9 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2002 Xodnizel 2006 CaH4e3 + * Copyright (C) 2002 Xodnizel + * Copyright (C) 2005 CaH4e3 + * 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 @@ -16,217 +18,103 @@ * 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 - * - * It seems that 162/163/164 mappers are the same mapper with just different - * mapper modes enabled or disabled in software or hardware, need more nanjing - * carts */ +/* Dongda PEC-9588 educational computer. Provides the same 1bpp all-points-addressable graphics mode. + Its chipset was later used for the Yancheng cy2000-3 PCB, used on most of the games that display "Union Bond" at the start. + Some of them also use the 1bpp mode for a few screens! +*/ + #include "mapinc.h" +#include "eeprom_93C66.h" -static uint8 laststrobe, trigger; static uint8 reg[8]; -static uint8 *WRAM = NULL; -static uint32 WRAMSIZE; - -static writefunc pcmwrite; - -static void (*WSync)(void); - +static uint8 eeprom_data[512]; static SFORMAT StateRegs[] = { - { &laststrobe, 1, "STB" }, - { &trigger, 1, "TRG" }, - { reg, 8, "REGS" }, - { 0 } + { reg, 8, "REGS" }, + { eeprom_data, 512, "EEPR" }, + { 0 } }; -static void Sync(void) { - setprg8r(0x10, 0x6000, 0); - setprg32(0x8000, (reg[0] << 4) | (reg[1] & 0xF)); - setchr8(0); +static void sync() +{ + uint8 prgLow = reg[0] &0x0F | reg[0] >>1 &0x10; + uint8 prgHigh = reg[1] <<5; + switch (reg[0] >>5 &2 | reg[0] >>4 &1) + { + case 0: /* UNROM-512 */ + setprg16(0x8000, prgHigh | prgLow); + setprg16(0xC000, prgHigh | 0x1F); + break; + case 1: /* Open Bus on Yancheng cy2000-3 PCB, expansion cartridge on the Dongda PEC-9588 */ + break; + case 2: /* UNROM-448+64. Very strange mode, used for the LOGO program on the Dongda PEC-9588 */ + setprg16(0x8000, prgHigh | prgLow); + setprg16(0xC000, prgHigh |(prgLow >=0x1C? 0x1C: 0x1E)); + break; + case 3: /* UNROM-128 or BNROM */ + if (prgLow &0x10) + { + setprg16(0x8000, prgHigh | prgLow <<1 &0x10 | prgLow &0x0F); + setprg16(0xC000, prgHigh | prgLow <<1 &0x10 | 0x0F); + } + else + setprg32(0x8000, prgHigh >>1 | prgLow); + break; + } + setprg8r(0x10, 0x6000, 0); + + setchr8(0); + PEC586Hack = !!(reg[0] &0x80); + + setmirror(reg[0] &0x10 && ~reg[3] &0x80? MI_H: MI_V); + + eeprom_93C66_write(reg[2] &0x10, reg[2] &0x04, reg[2] &0x01); } -static void StateRestore(int version) { - WSync(); +static DECLFR(readReg) +{ + return eeprom_93C66_read()? 0x00: 0x04; } -static DECLFR(ReadLow) { - switch (A & 0x7700) { - case 0x5100: return reg[2] | reg[0] | reg[1] | (reg[3] ^ 0xff); break; - case 0x5500: - if (trigger) - return reg[2] | reg[1]; /* Lei Dian Huang Bi Ka Qiu Chuan Shuo (NJ046) may broke other games */ - else - return 0; - } - return 4; +static DECLFW(writeReg) +{ + reg[A >>8 &7] = V; + sync(); } -static void M163HB(void) { - if (reg[1] & 0x80) { - if (scanline == 239) { - setchr4(0x0000, 0); - setchr4(0x1000, 0); - } else if (scanline == 127) { - setchr4(0x0000, 1); - setchr4(0x1000, 1); - } -#if 0 - if(scanline>=127) /* Hu Lu Jin Gang (NJ039) (Ch) [!] don't like it */ - { - setchr4(0x0000,1); - setchr4(0x1000,1); - } - else - { - setchr4(0x0000,0); - setchr4(0x1000,0); - } -#endif - } +static void power(void) +{ + memset(reg, 0, sizeof(reg)); + eeprom_93C66_init(); + sync(); + SetReadHandler (0x5400, 0x57FF, readReg); + SetWriteHandler(0x5000, 0x57FF, writeReg); + SetReadHandler (0x6000, 0xFFFF, CartBR); + SetWriteHandler(0x6000, 0x7FFF, CartBW); } -static DECLFW(Write) { - switch (A & 0x7300) { - case 0x5100: reg[0] = V; WSync(); break; - case 0x5000: reg[1] = V; WSync(); break; - case 0x5300: reg[2] = V; break; - case 0x5200: reg[3] = V; WSync(); break; - } +static void reset() +{ + memset(reg, 0, sizeof(reg)); + sync(); } -static void Power(void) { - memset(reg, 0, 8); - reg[1] = 0xFF; - SetWriteHandler(0x5000, 0x5FFF, Write); - SetReadHandler(0x6000, 0xFFFF, CartBR); - SetWriteHandler(0x6000, 0x7FFF, CartBW); - FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); - WSync(); -} - -static void Close(void) { - if (WRAM) - FCEU_gfree(WRAM); - WRAM = NULL; -} - -void Mapper164_Init(CartInfo *info) { - info->Power = Power; - info->Close = Close; - WSync = Sync; - - WRAMSIZE = 8192; - WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); - SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); - AddExState(WRAM, WRAMSIZE, 0, "WRAM"); - - if (info->battery) { - info->SaveGame[0] = WRAM; - info->SaveGameLen[0] = WRAMSIZE; - } - - GameStateRestore = StateRestore; - AddExState(&StateRegs, ~0, 0, 0); -} - -static DECLFW(Write2) { - if (A == 0x5101) { - if (laststrobe && !V) { - trigger ^= 1; - } - laststrobe = V; - } else if (A == 0x5100 && V == 6) /* damn those protected games */ - setprg32(0x8000, 3); - else - switch (A & 0x7300) { - case 0x5200: reg[0] = V; WSync(); break; - case 0x5000: reg[1] = V; WSync(); if (!(reg[1] & 0x80) && (scanline < 128)) setchr8(0); /* setchr8(0); */ break; - case 0x5300: reg[2] = V; break; - case 0x5100: reg[3] = V; WSync(); break; - } -} - -static void Power2(void) { - memset(reg, 0, 8); - laststrobe = 1; - pcmwrite = GetWriteHandler(0x4011); - SetReadHandler(0x5000, 0x5FFF, ReadLow); - SetWriteHandler(0x5000, 0x5FFF, Write2); - SetReadHandler(0x6000, 0xFFFF, CartBR); - SetWriteHandler(0x6000, 0x7FFF, CartBW); - FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); - WSync(); -} - -void Mapper163_Init(CartInfo *info) { - info->Power = Power2; - info->Close = Close; - WSync = Sync; - GameHBIRQHook = M163HB; - - WRAMSIZE = 8192; - WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); - SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); - AddExState(WRAM, WRAMSIZE, 0, "WRAM"); - - if (info->battery) { - info->SaveGame[0] = WRAM; - info->SaveGameLen[0] = WRAMSIZE; - } - GameStateRestore = StateRestore; - AddExState(&StateRegs, ~0, 0, 0); -} - -static void Sync3(void) { - setchr8(0); - setprg8r(0x10, 0x6000, 0); - switch (reg[3] & 7) { - case 0: - case 2: setprg32(0x8000, (reg[0] & 0xc) | (reg[1] & 2) | ((reg[2] & 0xf) << 4)); break; - case 1: - case 3: setprg32(0x8000, (reg[0] & 0xc) | (reg[2] & 0xf) << 4); break; - case 4: - case 6: setprg32(0x8000, (reg[0] & 0xe) | ((reg[1] >> 1) & 1) | ((reg[2] & 0xf) << 4)); break; - case 5: - case 7: setprg32(0x8000, (reg[0] & 0xf) | ((reg[2] & 0xf) << 4)); break; - } -} - -static DECLFW(Write3) { -/* FCEU_printf("bs %04x %02x\n",A,V); */ - reg[(A >> 8) & 3] = V; - WSync(); -} - -static void Power3(void) { - reg[0] = 3; - reg[1] = 0; - reg[2] = 0; - reg[3] = 7; - SetWriteHandler(0x5000, 0x5FFF, Write3); - SetReadHandler(0x6000, 0xFFFF, CartBR); - SetWriteHandler(0x6000, 0x7FFF, CartBW); - FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); - WSync(); -} - -void UNLFS304_Init(CartInfo *info) { - info->Power = Power3; - info->Close = Close; - WSync = Sync3; - - WRAMSIZE = 8192; - WRAM = (uint8*)FCEU_gmalloc(WRAMSIZE); - SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); - AddExState(WRAM, WRAMSIZE, 0, "WRAM"); - - if (info->battery) { - info->SaveGame[0] = WRAM; - info->SaveGameLen[0] = WRAMSIZE; - } - - GameStateRestore = StateRestore; - AddExState(&StateRegs, ~0, 0, 0); +void Mapper164_Init (CartInfo *info) +{ + uint32 WRAMSIZE = info->iNES2? (info->PRGRamSize + info->PRGRamSaveSize): 8192; + WRAMSIZE &=~0x7FF; /* Do not include EEPROM in the WRAM size */ + info->Power = power; + info->Reset = reset; + AddExState(StateRegs, ~0, 0, 0); + + uint8* WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); + + eeprom_93C66_storage = eeprom_data; + info->battery = 1; + info->SaveGame[0] = eeprom_data; + info->SaveGameLen[0] = 512; } diff --git a/src/boards/eeprom_93C66.c b/src/boards/eeprom_93C66.c new file mode 100644 index 0000000..c52e602 --- /dev/null +++ b/src/boards/eeprom_93C66.c @@ -0,0 +1,135 @@ +#include "eeprom_93C66.h" + +uint8* eeprom_93C66_storage; +uint8 eeprom_93C66_opcode; +uint8 eeprom_93C66_data; +uint16 eeprom_93C66_address; +uint8 eeprom_93C66_state; +uint8 eeprom_93C66_lastCLK; +uint8 eeprom_93C66_writeEnabled; +uint8 eeprom_93C66_output; + +#define OPCODE_MISC 0 +#define OPCODE_WRITE 1 +#define OPCODE_READ 2 +#define OPCODE_ERASE 3 +#define OPCODE_WRITEDISABLE 10 +#define OPCODE_WRITEALL 11 +#define OPCODE_ERASEALL 12 +#define OPCODE_WRITEENABLE 13 + +#define STATE_STANDBY 0 +#define STATE_STARTBIT 1 +#define STATE_OPCODE 3 +#define STATE_ADDRESS 12 +#define STATE_DATA 20 +#define STATE_FINISHED 99 + +void eeprom_93C66_init () +{ + eeprom_93C66_address =0; + eeprom_93C66_state =STATE_STANDBY; + eeprom_93C66_lastCLK =0; + eeprom_93C66_writeEnabled =0; +} + +uint8 eeprom_93C66_read () +{ + return eeprom_93C66_output; +} + +void eeprom_93C66_write (uint8 CS, uint8 CLK, uint8 DAT) +{ + if (!CS && eeprom_93C66_state <= STATE_ADDRESS) + eeprom_93C66_state =STATE_STANDBY; + else + if (eeprom_93C66_state ==STATE_STANDBY && CS && CLK) + { + eeprom_93C66_state =STATE_STARTBIT; + eeprom_93C66_opcode =0; + eeprom_93C66_address =0; + eeprom_93C66_output =1; + } + else + if (CLK && !eeprom_93C66_lastCLK) + { + if (eeprom_93C66_state >=STATE_STARTBIT && eeprom_93C66_state =STATE_OPCODE && eeprom_93C66_state =STATE_ADDRESS && eeprom_93C66_state >7) + 10; + switch (eeprom_93C66_opcode) + { + case OPCODE_WRITEDISABLE: + eeprom_93C66_writeEnabled = 0; + eeprom_93C66_state = STATE_FINISHED; + break; + case OPCODE_WRITEENABLE: + eeprom_93C66_writeEnabled = 1; + eeprom_93C66_state = STATE_FINISHED; + break; + case OPCODE_ERASEALL: + if (eeprom_93C66_writeEnabled) for (int i =0; i <512; i++) eeprom_93C66_storage[i] = 0xFF; + eeprom_93C66_state = STATE_FINISHED; + break; + case OPCODE_WRITEALL: + eeprom_93C66_address = 0; + break; + } + break; + case OPCODE_ERASE: + if (eeprom_93C66_writeEnabled) eeprom_93C66_storage[eeprom_93C66_address] = 0xFF; + eeprom_93C66_state = STATE_FINISHED; + break; + case OPCODE_READ: + eeprom_93C66_data = eeprom_93C66_storage[eeprom_93C66_address++]; + break; + } + } + else + if (eeprom_93C66_state ==STATE_DATA) + { + if (eeprom_93C66_opcode ==OPCODE_WRITE) + { + eeprom_93C66_storage[eeprom_93C66_address++] = eeprom_93C66_data; + eeprom_93C66_state = STATE_FINISHED; + } + else + if (eeprom_93C66_opcode ==OPCODE_WRITEALL) + { + eeprom_93C66_storage[eeprom_93C66_address++] = eeprom_93C66_data; + eeprom_93C66_state = CS && eeprom_93C66_address <512? STATE_ADDRESS: STATE_FINISHED; + } + else + if (eeprom_93C66_opcode ==OPCODE_READ) + { + if (eeprom_93C66_address <512) eeprom_93C66_data = eeprom_93C66_storage[eeprom_93C66_address]; + eeprom_93C66_state = CS && ++eeprom_93C66_address <=512? STATE_ADDRESS: STATE_FINISHED; + } + } + if (eeprom_93C66_state == STATE_FINISHED) + { + eeprom_93C66_output = 0; + eeprom_93C66_state = STATE_STANDBY; + } + } + eeprom_93C66_lastCLK = CLK; +} diff --git a/src/boards/eeprom_93C66.h b/src/boards/eeprom_93C66.h new file mode 100644 index 0000000..458f02e --- /dev/null +++ b/src/boards/eeprom_93C66.h @@ -0,0 +1,10 @@ +#ifndef _EEPROM_93C66_H +#define _EEPROM_93C66_H +#include "mapinc.h" + +extern uint8* eeprom_93C66_storage; + +void eeprom_93C66_init (); +uint8 eeprom_93C66_read (); +void eeprom_93C66_write (uint8 CS, uint8 CLK, uint8 DAT); +#endif diff --git a/src/ines-correct.h b/src/ines-correct.h index 159e9a6..14cae2d 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -37,7 +37,8 @@ { 0xaf5d7aa2, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Clu Clu Land (W) [o3].nes */ { 0xcfb224e6, 222, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ninja (J) (PRG0) [p1][!].nes */ - { 0x82f204ae, 163, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Liang Shan Ying Xiong (NJ023) (Ch) [!].nes */ + { 0x82f204ae, 162, DEFAULT, MI_H, 0, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Liang Shan Ying Xiong (NJ023) (Ch) [!].nes */ + { 0x8589652D, 162, DEFAULT, MI_H, 0, 0x70, 0x07, DEFAULT, NOEXTRA }, /* 农场小精灵.nes */ { 0xad9c63e2, 70, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Space Shadow (Japan).nes */ { 0xe1526228, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ki no Bouken - The Quest of Ki (Japan).nes */ { 0xaf5d7aa2, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Clu Clu Land (W) [o3].nes */ @@ -355,7 +356,6 @@ { 0x183859d2, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball Z - Kyoushuu! Saiya Jin (Japan).nes */ { 0x58152b42, 160, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pipe V (Asia) (Ja) (Unl).nes */ { 0x1c098942, 162, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Xi You Ji Hou Zhuan (Ch).nes */ - { 0x081caaff, 163, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Commandos (Ch).nes */ /* Mapper 176 */ { 0xffde0de5, 176, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 梦幻之星4[简体](修正)一战一级.nes */ diff --git a/src/ines.c b/src/ines.c index 7f807d3..d3392a9 100644 --- a/src/ines.c +++ b/src/ines.c @@ -577,7 +577,7 @@ INES_BOARD_BEGIN() INES_BOARD( "BANDAI 24C01", 159, Mapper159_Init ) /* Different type of EEPROM on the bandai board */ INES_BOARD( "SA009", 160, SA009_Init ) /* INES_BOARD( "", 161, Mapper161_Init ) */ - INES_BOARD( "", 162, UNLFS304_Init ) + INES_BOARD( "", 162, Mapper162_Init ) INES_BOARD( "", 163, Mapper163_Init ) INES_BOARD( "", 164, Mapper164_Init ) INES_BOARD( "", 165, Mapper165_Init ) @@ -802,6 +802,7 @@ INES_BOARD_BEGIN() INES_BOARD( "T-230", 529, UNLT230_Init ) INES_BOARD( "AX5705", 530, UNLAX5705_Init ) INES_BOARD( "LH53", 535, LH53_Init ) + INES_BOARD( "YC-03-09", 558, Mapper558_Init ) INES_BOARD_END() static uint32 get_ines_version(void) { diff --git a/src/ines.h b/src/ines.h index 330c0a5..acdd82a 100644 --- a/src/ines.h +++ b/src/ines.h @@ -165,6 +165,7 @@ void Mapper156_Init(CartInfo *); void Mapper157_Init(CartInfo *); void Mapper158_Init(CartInfo *); void Mapper159_Init(CartInfo *); +void Mapper162_Init(CartInfo *); void Mapper163_Init(CartInfo *); void Mapper164_Init(CartInfo *); void Mapper165_Init(CartInfo *); @@ -295,5 +296,6 @@ void Mapper541_Init(CartInfo *); void Mapper543_Init(CartInfo *); void Mapper550_Init(CartInfo *); void Mapper554_Init(CartInfo *); +void Mapper558_Init(CartInfo *); #endif diff --git a/src/unif.c b/src/unif.c index e69a75a..a019f17 100644 --- a/src/unif.c +++ b/src/unif.c @@ -462,7 +462,7 @@ static BMAPPING bmap[] = { { "EWROM", 5, EWROM_Init, 0 }, { "FK23C", 176, BMCFK23C_Init, BMCFLAG_256KCHRR }, { "FK23CA", 176, BMCFK23CA_Init, BMCFLAG_256KCHRR }, - { "FS304", 162, UNLFS304_Init, 0 }, + { "FS304", 162, Mapper162_Init, 0 }, { "G-146", 349, BMCG146_Init, 0 }, { "GK-192", NO_INES, BMCGK192_Init, 0 }, /* mapper 58? */ { "GS-2004", 283, BMCGS2004_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index c53a3e8..7738608 100644 --- a/src/unif.h +++ b/src/unif.h @@ -118,7 +118,6 @@ void UNLCC21_Init(CartInfo *info); void UNLCITYFIGHT_Init(CartInfo *info); void UNLD2000_Init(CartInfo *info); void UNLEDU2000_Init(CartInfo *info); -void UNLFS304_Init(CartInfo *info); void UNLH2288_Init(CartInfo *info); void UNLKOF97_Init(CartInfo *info); void UNLKS7012_Init(CartInfo *info); From d4c0d6e85218c7ba93d69d3e45abae598fa93ea3 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Sun, 30 May 2021 10:05:10 +0200 Subject: [PATCH 117/295] Update database for mappers 162-164/558 --- src/boards/162.c | 6 +-- src/boards/163.c | 6 +-- src/boards/164.c | 3 +- src/boards/558.c | 125 +++++++++++++++++++++++++++++++++++++++++++ src/ines-correct.h | 128 +++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 257 insertions(+), 11 deletions(-) create mode 100644 src/boards/558.c diff --git a/src/boards/162.c b/src/boards/162.c index 973f94b..6a57890 100644 --- a/src/boards/162.c +++ b/src/boards/162.c @@ -49,8 +49,8 @@ static void sync() static void hblank(void) { if (reg[0] &0x80 && scanline <239) { /* Actual hardware cannot look at the current scanline number, but instead latches PA09 on PA13 rises. This does not seem possible with the current PPU emulation however. */ - setchr4(0x0000, scanline>=127? 1: 0); - setchr4(0x1000, scanline>=127? 1: 0); + setchr4(0x0000, scanline >=127? 1: 0); + setchr4(0x1000, scanline >=127? 1: 0); } else setchr8(0); @@ -96,6 +96,6 @@ void Mapper162_Init (CartInfo *info) FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); if (info->battery) { info->SaveGame[0] = WRAM; - info->SaveGameLen[0] = WRAMSIZE; + info->SaveGameLen[0] = info->PRGRamSaveSize; } } diff --git a/src/boards/163.c b/src/boards/163.c index 4671e0d..393817b 100644 --- a/src/boards/163.c +++ b/src/boards/163.c @@ -43,8 +43,8 @@ static void sync() static void hblank(void) { if (reg[0] &0x80 && scanline <239) { /* Actual hardware cannot look at the current scanline number, but instead latches PA09 on PA13 rises. This does not seem possible with the current PPU emulation however. */ - setchr4(0x0000, scanline>=127? 1: 0); - setchr4(0x1000, scanline>=127? 1: 0); + setchr4(0x0000, scanline >=127? 1: 0); + setchr4(0x1000, scanline >=127? 1: 0); } else setchr8(0); @@ -101,6 +101,6 @@ void Mapper163_Init (CartInfo *info) FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); if (info->battery) { info->SaveGame[0] = WRAM; - info->SaveGameLen[0] = WRAMSIZE; + info->SaveGameLen[0] = info->PRGRamSaveSize; } } diff --git a/src/boards/164.c b/src/boards/164.c index 2e0f23c..a9d7c9e 100644 --- a/src/boards/164.c +++ b/src/boards/164.c @@ -103,8 +103,7 @@ static void reset() void Mapper164_Init (CartInfo *info) { - uint32 WRAMSIZE = info->iNES2? (info->PRGRamSize + info->PRGRamSaveSize): 8192; - WRAMSIZE &=~0x7FF; /* Do not include EEPROM in the WRAM size */ + uint32 WRAMSIZE = info->iNES2? (info->PRGRamSize + (info->PRGRamSaveSize &~0x7FF)): 8192; info->Power = power; info->Reset = reset; AddExState(StateRegs, ~0, 0, 0); diff --git a/src/boards/558.c b/src/boards/558.c new file mode 100644 index 0000000..b622a61 --- /dev/null +++ b/src/boards/558.c @@ -0,0 +1,125 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2002 Xodnizel + * Copyright (C) 2005 CaH4e3 + * 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 + */ + +/* Yancheng YC-03-09/Waixing FS??? PCB */ + +#include "mapinc.h" +#include "eeprom_93C66.h" +#include "../ines.h" + +static uint8 reg[4]; +static uint8 haveEEPROM; +static uint8 eeprom_data[512]; +static SFORMAT StateRegs[] = +{ + { reg, 4, "REGS" }, + { 0 } +}; + +static void sync() +{ + setprg32(0x8000, reg[1] <<4 | reg[0] &0xF | (reg[3] &0x04? 0x00: 0x03)); + setprg8r(0x10, 0x6000, 0); + if (~reg[0] &0x80) + setchr8(0); + + if (haveEEPROM) + eeprom_93C66_write(reg[2] &0x04, reg[2] &0x02, reg[2] &0x01); +} + +static void hblank(void) { + if (reg[0] &0x80 && scanline <239) + { /* Actual hardware cannot look at the current scanline number, but instead latches PA09 on PA13 rises. This does not seem possible with the current PPU emulation however. */ + setchr4(0x0000, scanline >=127? 1: 0); + setchr4(0x1000, scanline >=127? 1: 0); + } + else + setchr8(0); +} + +static DECLFR(readReg) +{ + if (haveEEPROM) + return eeprom_93C66_read()? 0x04: 0x00; + else + return reg[2] &0x04; +} + +static DECLFW(writeReg) +{ + uint8 index = A >>8 &3; + + /* D0 and D1 are connected to the ASIC in reverse order, so swap once */ + V = V &~3 | V >>1 &1 | V <<1 &2; + + /* Swap bits of registers 0-2 again if the "swap bits" bit is set. Exclude register 2 on when PRG-ROM is 1 MiB. */ + if (reg[3] &0x02 && index <= (ROM_size == 64? 1: 2)) + V = V &~3 | V >>1 &1 | V <<1 &2; + + reg[index] = V; + sync(); +} + +static void power(void) +{ + memset(reg, 0, sizeof(reg)); + if (haveEEPROM) + eeprom_93C66_init(); + sync(); + SetReadHandler (0x5000, 0x57FF, readReg); + SetWriteHandler(0x5000, 0x57FF, writeReg); + SetReadHandler (0x6000, 0xFFFF, CartBR); + SetWriteHandler(0x6000, 0x7FFF, CartBW); +} + +static void reset() +{ + memset(reg, 0, sizeof(reg)); + sync(); +} + +void Mapper558_Init (CartInfo *info) +{ + uint32 WRAMSIZE = info->PRGRamSize + (info->PRGRamSaveSize &~0x7FF); + info->Power = power; + info->Reset = reset; + GameHBIRQHook = hblank; + AddExState(StateRegs, ~0, 0, 0); + + uint8* WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); + SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); + FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); + haveEEPROM =!!(info->PRGRamSaveSize &0x200); + if (haveEEPROM) + { + eeprom_93C66_storage = eeprom_data; + info->battery = 1; + info->SaveGame[0] = eeprom_data; + info->SaveGameLen[0] = 512; + } + else + if (info->battery) + { + info->SaveGame[0] = WRAM; + info->SaveGameLen[0] = (info->PRGRamSaveSize &~0x7FF); + } +} diff --git a/src/ines-correct.h b/src/ines-correct.h index 14cae2d..0f86a4e 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -37,8 +37,6 @@ { 0xaf5d7aa2, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Clu Clu Land (W) [o3].nes */ { 0xcfb224e6, 222, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ninja (J) (PRG0) [p1][!].nes */ - { 0x82f204ae, 162, DEFAULT, MI_H, 0, 0x70, 0x07, DEFAULT, NOEXTRA }, /* Liang Shan Ying Xiong (NJ023) (Ch) [!].nes */ - { 0x8589652D, 162, DEFAULT, MI_H, 0, 0x70, 0x07, DEFAULT, NOEXTRA }, /* 农场小精灵.nes */ { 0xad9c63e2, 70, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Space Shadow (Japan).nes */ { 0xe1526228, 206, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Ki no Bouken - The Quest of Ki (Japan).nes */ { 0xaf5d7aa2, 0, DEFAULT, MI_H, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Clu Clu Land (W) [o3].nes */ @@ -355,7 +353,131 @@ { 0xb7f28915, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Magical Taruruuto-kun 2 - Mahou Daibouken (Japan).nes */ { 0x183859d2, 159, DEFAULT, DEFAULT, 1, 0x10, DEFAULT, DEFAULT, NOEXTRA }, /* Dragon Ball Z - Kyoushuu! Saiya Jin (Japan).nes */ { 0x58152b42, 160, DEFAULT, MI_V, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Pipe V (Asia) (Ja) (Unl).nes */ - { 0x1c098942, 162, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* Xi You Ji Hou Zhuan (Ch).nes */ + + /* Mapper 162: Waixing FS304 */ + { 0x08FBF3F0, 162, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Mummy - 神鬼传奇 */ + { 0xF5D34C8E, 162, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Zelda 传说: 三神之力 */ + { 0xEE3A1CA8, 162, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 法老王 - Pharaoh */ + { 0xCF4ADAAD, 162, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 火焰纹章 - 圣战的系谱 */ + { 0xB2045E9C, 162, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 聖火徽章 III */ + { 0x1C098942, 162, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 西游记后传 */ + /* Mapper 162: Nanjing games that use an FS304 feature as a protection check */ + { 0x8589652D, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 农场小精灵 */ + { 0x82F204AE, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 梁山英雄 */ + + /* Mapper 163: Nanjing, running with $5300=$04 */ + { 0xC9ABA7F0, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Chrono Trigger - 时空之轮 */ + { 0x143B4D30, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Final Fantasy VII - 最终幻想 7 */ + { 0x3CC55A44, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* The Legend of Zelda - 塞尔达传说: 神奇的帽子 */ + { 0x4752BD5E, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 七國大戰 */ + { 0x1121C0D1, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志 之 傲视天地 */ + { 0x8E4294A9, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志: 曹操传 */ + { 0xF52468E7, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国无双: 猛将传 */ + { 0xEF7BA485, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 仙剑奇侠 */ + { 0x20E1CF44, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 仙界精灵 */ + { 0x9688AEEA, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 倚天传说 */ + { 0x04DFE0D4, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 倚天剑传奇 */ + { 0x6CB6D619, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋宝石 - 银 */ + { 0x8C73A47B, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 哪吒传奇 */ + { 0xE40DA18F, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 圣剑传说 */ + { 0xC07CD2CE, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 圣斗士星矢: 天马之幻想 */ + { 0x9237C200, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 大话西游 */ + { 0x4FB02A43, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 天龙八部 */ + { 0x52D7FE18, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 太空幻想 */ + { 0xA01CA587, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 幻世录 */ + { 0x89F4ACD1, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 幻想传说 */ + { 0x65C63CC3, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 数码战队 2 */ + { 0x2C01DE06, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 数码暴龙 */ + { 0xB614AAA2, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 暗黑破坏神 - Diablo */ + { 0x80A18CDC, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 机器人大战 */ + { 0x33DB45BA, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 核心危机 */ + { 0x1B74A022, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 梦幻沙漏 */ + { 0x695A7A70, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 楚汉风云 */ + { 0xD0807FD2, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 水浒 III */ + { 0x524AF6E8, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 水浒神兽 (南晶) */ + { 0x2802E40F, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 汉刘邦 */ + { 0xAC491507, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 游戏王 */ + { 0x31C1BF98, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 牧场物语 */ + { 0x191F7D5E, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 真 Samurai Spirits - 武士道列传: 侍魂 */ + { 0x1FE67BB3, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 真 Samurai Spirits - 魂之利刃 */ + { 0x4973B16B, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 石器时代 */ + { 0x09C7AED3, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 葫芦金刚 */ + { 0x4E3EDF88, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 超级机器人大战 A */ + { 0x74C1EDC7, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 轩辕剑外传 之 天之痕 */ + { 0x723C6345, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 金庸群侠传: 书剑江山 */ + { 0xDA47B05A, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 隋唐英雄 */ + { 0x056F2B8E, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 雷电皇: Pikachu传说 */ + { 0x04166E96, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 魔幻世界 */ + { 0x85FA53E1, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 魔界塔士 */ + { 0x2121DAB2, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 魔界霸主 */ + { 0xE3EF9739, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 黄金太阳 */ + /* Mapper 163: Nanjing, running with $5300=$07 */ + { 0x6F94C5E5, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Final Fantasy IV - 最终幻想 4: 光与暗 水晶纷争 */ + { 0xD6CBB05D, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Naruto RPG - 火影忍者 */ + { 0xD7A4CBA5, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 七龙珠大冒险 - Dragon Ball */ + { 0xDF27B96C, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国大乱斗: 战国 - Orochi */ + { 0x8C60CECF, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志: 吕布传 */ + { 0x44AC9C8E, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国群侠传 */ + { 0xA3193C51, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 倚天屠龙记 */ + { 0x98266D3A, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 傲视三国志 */ + { 0xA026AE52, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋宝石 - 红 */ + { 0xB6F72A18, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋宝石 - 蓝 */ + { 0x5108AB7F, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋宝石 - 金 */ + { 0x8EB1B4CF, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋水晶 */ + { 0xA66756AD, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋钻石 */ + { 0x3A613060, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 吞食天地 VI: 刘备传 */ + { 0xB35BE92F, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 圣斗士星矢: 北欧突击篇 */ + { 0x15E50ECD, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 宠物高达战记 */ + { 0xBBAB3A61, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 拳皇R-1: 最强格斗王 */ + { 0x2DA3A49C, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 时空斗士 - Pegasus Senya */ + { 0x222A136A, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 武侠天地 */ + { 0xEBC6E2E2, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 毁灭之神 */ + { 0xE08AB52E, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 魔兽世界: 恶魔猎人 */ + /* Mapper 162: Nanjing, running with $5300=$07, but dumped without taking the D0/D1 bit swap into account. + Such dumps need not be invalidated however, as they can run as mapper 162 when properly emulated. */ + { 0x9D8AA034, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Final Fantasy IV - 最终幻想4: 光与暗 水晶纷争 */ + { 0x5E66E6C4, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Naruto RPG - 火影忍者 */ + { 0x9DE10A91, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 七龙珠大冒险 - Dragon Ball */ + { 0xFC209609, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国大乱斗: 战国 - Orochi */ + { 0x696D98E3, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志: 吕布传 */ + { 0x9F197F2B, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国群侠传 */ + { 0x975F64E2, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 倚天屠龙记 */ + { 0x915C5179, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 傲视三国志 */ + { 0x852BDB36, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋宝石 - 红 */ + { 0xB41CF445, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋宝石 - 蓝 */ + { 0x7829C3A9, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋宝石 - 金 */ + { 0xBC383C09, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋水晶 */ + { 0xA9C4712A, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋钻石 */ + { 0xC2B02B71, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 吞食天地 VI: 刘备传 */ + { 0x054444A0, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 圣斗士星矢: 北欧突击篇 */ + { 0x9BA518BA, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 宠物高达战记 */ + { 0x4CE082F8, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 拳皇R-1: 最强格斗王 */ + { 0x99FE9AB5, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 时空斗士 - Pegasus Senya */ + { 0x57414FB6, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 武侠天地 */ + { 0x979239DE, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 毁灭之神 */ + { 0xEFF96E8A, 162, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 魔兽世界: 恶魔猎人 */ + + /* Mapper 164: Dongda PEC-9588 and Yancheng cy2000-3 PCB */ + { 0xFE31765B, 164, 0, MI_V, 0, 0x07, 0x07, DENDY, NOEXTRA }, /* Pyramid 金字塔 PEC-9588 家庭电脑 */ + { 0x0878A7EE, 164, 0, MI_H, 1, 0x35, 0x07, DENDY, NOEXTRA }, /* Dark Seed - 黑暗之蛊 */ + { 0x56A0D271, 164, 0, MI_H, 1, 0x35, 0x07, DENDY, NOEXTRA }, /* Final Fantasy 太空戰士 V (rev0) */ + { 0xCB1EF911, 164, 0, MI_H, 1, 0x35, 0x07, DENDY, NOEXTRA }, /* Final Fantasy 太空戰士 V (rev1) */ + { 0x8209BA79, 164, 0, MI_H, 1, 0x35, 0x07, DENDY, NOEXTRA }, /* 櫻桃小丸子 */ + { 0xBC7562A6, 164, 0, MI_H, 1, 0x35, 0x07, DENDY, NOEXTRA }, /* 口袋精靈: 金 */ + { 0x65F1DB91, 164, 0, MI_H, 1, 0x35, 0x07, DENDY, NOEXTRA }, /* 大話西游 [restored, no good dump known] */ + { 0x0A244228, 164, 0, MI_H, 1, 0x35, 0x07, DENDY, NOEXTRA }, /* 岳飛傳 [restored, no good dump known] */ + + /* Mapper 558: Waixing FS??? and Yancheng YC-03-09 PCB */ + { 0xE65A8C08, 558, 0, MI_H, 1, 0x30, 0x07, DENDY, NOEXTRA }, /* 大話三國 */ + { 0x228559A7, 558, 0, MI_H, 1, 0x30, 0x07, DENDY, NOEXTRA }, /* 口袋精靈: 水晶 */ + { 0x8B41D49C, 558, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Pet Evolve - 宠物进化史 */ + { 0x5622EC51, 558, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志 II 代 */ + { 0xE7AEB114, 558, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋妖怪: 鑽石版 */ + { 0x8EB4BB51, 558, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 口袋精靈: 紅 */ + { 0x48244391, 558, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 宠物: 红 */ + { 0x01A24301, 558, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 数码宝贝 */ + { 0x88CB68A7, 558, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 数码暴龙 4: 水晶版 */ + { 0x081CAAFF, 558, 0, MI_H, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 盟军敢死队 - Commandos */ /* Mapper 176 */ { 0xffde0de5, 176, DEFAULT, DEFAULT, 1, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* 梦幻之星4[简体](修正)一战一级.nes */ From 403f682eb7951cba41a45c4dc618819665bfdca0 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Mon, 31 May 2021 16:55:09 +0800 Subject: [PATCH 118/295] Cleanup: Remove a few extern --- Makefile.libretro | 4 ++-- src/cart.h | 3 +++ src/drivers/libretro/libretro.c | 22 ++-------------------- src/fceu.h | 3 +++ src/input.h | 2 ++ src/ppu.h | 2 ++ 6 files changed, 14 insertions(+), 22 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index 86563b0..2387bed 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -752,8 +752,8 @@ else WARNING_DEFINES = -Wno-write-strings endif -CFLAGS += $(fpic) $(WARNING_DEFINES) $(DEFINES) $(ENDIANNESS_DEFINES) -LDFLAGS += $(LIBM) +CFLAGS += $(fpic) $(WARNING_DEFINES) $(DEFINES) $(ENDIANNESS_DEFINES) -Werror=implicit-function-declaration +LDFLAGS += $(LIBM) -Werror=implicit-function-declaration ifeq ($(platform), psp1) INCFLAGS += -I$(shell psp-config --pspsdk-path)/include diff --git a/src/cart.h b/src/cart.h index 4573403..cd05d4b 100644 --- a/src/cart.h +++ b/src/cart.h @@ -104,4 +104,7 @@ void FCEU_OpenGenie(void); void FCEU_CloseGenie(void); void FCEU_KillGenie(void); +extern CartInfo iNESCart; +extern CartInfo UNIFCart; + #endif diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 39263fc..b191dcd 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -67,8 +67,6 @@ void linearFree(void* mem); RETRO_HW_RENDER_INTEFACE_GSKIT_PS2 *ps2 = NULL; #endif -extern void FCEU_ZapperSetTolerance(int t); - static retro_video_refresh_t video_cb = NULL; static retro_input_poll_t poll_cb = NULL; static retro_input_state_t input_cb = NULL; @@ -95,7 +93,7 @@ static int aspect_ratio_par; #define MAX_BUTTONS 8 #define TURBO_BUTTONS 2 -unsigned char turbo_button_toggle[MAX_PLAYERS][TURBO_BUTTONS] = { {0} }; +unsigned turbo_button_toggle[MAX_PLAYERS][TURBO_BUTTONS] = { {0} }; typedef struct { @@ -145,8 +143,6 @@ static bool libretro_supports_bitmasks = false; const size_t PPU_BIT = 1ULL << 31ULL; -extern uint8 NTARAM[0x800], PALRAM[0x20], SPRAM[0x100], PPU[4]; - /* overclock the console by adding dummy scanlines to PPU loop * disables DMC DMA and WaveHi filling for these dummies * doesn't work with new PPU */ @@ -158,14 +154,13 @@ unsigned normal_scanlines = 240; unsigned extrascanlines = 0; unsigned vblankscanlines = 0; unsigned dendy = 0; +unsigned swapDuty; static unsigned systemRegion = 0; static unsigned opt_region = 0; static unsigned opt_showAdvSoundOptions = 0; static unsigned opt_showAdvSystemOptions = 0; -int FCEUnetplay; - #if defined(PSP) || defined(PS2) static __attribute__((aligned(16))) uint16_t retro_palette[256]; #else @@ -181,24 +176,12 @@ static uint16_t* fceu_video_out; static unsigned sndsamplerate; static unsigned sndquality; static unsigned sndvolume; -unsigned swapDuty; static int32_t *sound = 0; static uint32_t Dummy = 0; static uint32_t current_palette = 0; static unsigned serialize_size; -int PPUViewScanline=0; -int PPUViewer=0; - -/* extern forward decls.*/ -extern FCEUGI *GameInfo; -extern uint8 *XBuf; -extern CartInfo iNESCart; -extern CartInfo UNIFCart; -extern int show_crosshair; -extern int option_ramstate; - /* emulator-specific callback functions */ void UpdatePPUView(int refreshchr) { } @@ -311,7 +294,6 @@ FILE *FCEUD_UTF8fopen(const char *n, const char *m) #define PAL_CUSTOM (PAL_TOTAL + 3) static int external_palette_exist = 0; -extern int ipalette; /* table for currently loaded palette */ static uint8_t base_palette[192]; diff --git a/src/fceu.h b/src/fceu.h index f97b425..d3ec9a6 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -23,6 +23,9 @@ extern unsigned swapDuty; /* Swap bits 6 & 7 of $4000/$4004 to mimic bug * found on some famiclones/Dendy models. */ +extern int show_crosshair; +extern int option_ramstate; + void ResetGameLoaded(void); #define DECLFR(x) uint8 FP_FASTAPASS(1) x(uint32 A) diff --git a/src/input.h b/src/input.h index 82061bc..1ab1e39 100644 --- a/src/input.h +++ b/src/input.h @@ -29,4 +29,6 @@ extern void (*InputScanlineHook)(uint8 *bg, uint8 *spr, uint32 linets, int final void FCEU_DoSimpleCommand(int cmd); +void FCEU_ZapperSetTolerance(int t); + #endif diff --git a/src/ppu.h b/src/ppu.h index 96338a1..d9cfcec 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -16,6 +16,8 @@ extern void FP_FASTAPASS(1) (*PPU_hook)(uint32 A); extern uint8 NTARAM[0x800], *vnapage[4]; extern uint8 PPUNTARAM; extern uint8 PPUCHRRAM; +extern uint8 PALRAM[0x20]; +extern uint8 SPRAM[0x100]; void FCEUPPU_SaveState(void); void FCEUPPU_LoadState(int version); From 46ca02a2066c058597abfadaa13401154475c58a Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Wed, 2 Jun 2021 04:18:49 +0800 Subject: [PATCH 119/295] Move settings-related vars to FSettings struct - Just some more cleanups --- src/drivers/libretro/libretro.c | 67 +++++++++++++-------------------- src/fceu.c | 26 ++++++++----- src/fceu.h | 39 +++++++++---------- src/ines.c | 3 +- src/ppu.c | 32 ++++++++-------- src/sound.c | 6 +-- src/sound.h | 1 + src/video.c | 11 +++--- src/video.h | 1 - src/x6502.c | 7 ++-- src/x6502.h | 3 +- 11 files changed, 94 insertions(+), 102 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index b191dcd..43a4d33 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -143,19 +143,6 @@ static bool libretro_supports_bitmasks = false; const size_t PPU_BIT = 1ULL << 31ULL; -/* overclock the console by adding dummy scanlines to PPU loop - * disables DMC DMA and WaveHi filling for these dummies - * doesn't work with new PPU */ -unsigned overclock_enabled = -1; -unsigned overclocked = 0; -unsigned skip_7bit_overclocking = 1; /* 7-bit samples have priority over overclocking */ -unsigned totalscanlines = 0; -unsigned normal_scanlines = 240; -unsigned extrascanlines = 0; -unsigned vblankscanlines = 0; -unsigned dendy = 0; -unsigned swapDuty; - static unsigned systemRegion = 0; static unsigned opt_region = 0; static unsigned opt_showAdvSoundOptions = 0; @@ -970,7 +957,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info) info->geometry.max_height = NES_HEIGHT; info->geometry.aspect_ratio = get_aspect_ratio(width, height); info->timing.sample_rate = (float)sndsamplerate; - if (FSettings.PAL || dendy) + if (FSettings.PAL || FSettings.dendy) info->timing.fps = 838977920.0/16777215.0; else info->timing.fps = 1008307711.0/16777215.0; @@ -1075,7 +1062,7 @@ static void FCEUD_RegionOverride(unsigned region) break; } - dendy = d; + FSettings.dendy = d; FCEUI_SetVidSystem(pal); ResetPalette(); } @@ -1131,11 +1118,11 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (!strcmp(var.value, "random")) - option_ramstate = 2; + FSettings.ramstate = 2; else if (!strcmp(var.value, "fill $00")) - option_ramstate = 1; + FSettings.ramstate = 1; else - option_ramstate = 0; + FSettings.ramstate = 0; } #ifdef HAVE_NTSC_FILTER @@ -1236,33 +1223,33 @@ static void check_variables(bool startup) bool do_reinit = false; if (!strcmp(var.value, "disabled") - && overclock_enabled != 0) + && FSettings.overclock_enabled != 0) { - skip_7bit_overclocking = 1; - extrascanlines = 0; - vblankscanlines = 0; - overclock_enabled = 0; + FSettings.skip_7bit_overclocking = 1; + FSettings.extrascanlines = 0; + FSettings.vblankscanlines = 0; + FSettings.overclock_enabled = 0; do_reinit = true; } else if (!strcmp(var.value, "2x-Postrender")) { - skip_7bit_overclocking = 1; - extrascanlines = 266; - vblankscanlines = 0; - overclock_enabled = 1; + FSettings.skip_7bit_overclocking = 1; + FSettings.extrascanlines = 266; + FSettings.vblankscanlines = 0; + FSettings.overclock_enabled = 1; do_reinit = true; } else if (!strcmp(var.value, "2x-VBlank")) { - skip_7bit_overclocking = 1; - extrascanlines = 0; - vblankscanlines = 266; - overclock_enabled = 1; + FSettings.skip_7bit_overclocking = 1; + FSettings.extrascanlines = 0; + FSettings.vblankscanlines = 266; + FSettings.overclock_enabled = 1; do_reinit = true; } - normal_scanlines = dendy ? 290 : 240; - totalscanlines = normal_scanlines + (overclock_enabled ? extrascanlines : 0); + FSettings.normal_scanlines = FSettings.dendy ? SCANLINES_DENDY : SCANLINES_NORMAL; + FSettings.totalscanlines = FSettings.normal_scanlines + (FSettings.overclock_enabled ? FSettings.extrascanlines : 0); if (do_reinit && startup) { @@ -1294,8 +1281,10 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - if (!strcmp(var.value, "enabled")) show_crosshair = 1; - else if (!strcmp(var.value, "disabled")) show_crosshair = 0; + if (!strcmp(var.value, "enabled")) + FSettings.show_crosshair = 1; + else if (!strcmp(var.value, "disabled")) + FSettings.show_crosshair = 0; } #ifdef PSP @@ -1433,8 +1422,8 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { bool newval = (!strcmp(var.value, "enabled")); - if (newval != swapDuty) - swapDuty = newval; + if (newval != FSettings.swapDuty) + FSettings.swapDuty = newval; } var.key = key; @@ -2410,8 +2399,6 @@ bool retro_load_game(const struct retro_game_info *game) #endif sndquality = 0; sndvolume = 150; - swapDuty = 0; - dendy = 0; opt_region = 0; /* Wii: initialize this or else last variable is passed through @@ -2471,7 +2458,7 @@ bool retro_load_game(const struct retro_game_info *game) FCEU_printf(" Loading custom palette: %s%cnes.pal\n", dir, slash); /* Save region and dendy mode for region-auto detect */ - systemRegion = (dendy << 1) | (retro_get_region() & 1); + systemRegion = (FSettings.dendy << 1) | (retro_get_region() & 1); current_palette = 0; diff --git a/src/fceu.c b/src/fceu.c index de3f21b..748e7f7 100644 --- a/src/fceu.c +++ b/src/fceu.c @@ -341,6 +341,14 @@ int FCEUI_Initialize(void) { FSettings.UsrLastSLine[0] = 231; FSettings.UsrLastSLine[1] = 239; FSettings.SoundVolume = 100; + FSettings.overclock_enabled = 0; + FSettings.skip_7bit_overclocking = 1; + FSettings.totalscanlines = 0; + FSettings.normal_scanlines = SCANLINES_NORMAL; + FSettings.extrascanlines = 0; + FSettings.vblankscanlines = 0; + FSettings.dendy = 0; + FSettings.swapDuty = 0; FCEUPPU_Init(); X6502_Init(); return 1; @@ -381,8 +389,6 @@ void ResetNES(void) X6502_Reset(); } -int option_ramstate = 0; - void FCEU_MemoryRand(uint8 *ptr, uint32 size) { int x = 0; @@ -397,7 +403,7 @@ void FCEU_MemoryRand(uint8 *ptr, uint32 size) /* 1942 SCORE/HISCORE is screwed... */ #endif uint8_t v = 0; - switch (option_ramstate) + switch (FSettings.ramstate) { case 0: v = 0xff; break; case 1: v = 0x00; break; @@ -466,7 +472,7 @@ void FCEU_ResetVidSys(void) else if (GameInfo->vidsys == GIV_PAL) { w = 1; - dendy = 0; + FSettings.dendy = 0; } else w = FSettings.PAL; @@ -474,12 +480,12 @@ void FCEU_ResetVidSys(void) PAL = w ? 1 : 0; if (PAL) - dendy = 0; + FSettings.dendy = 0; - normal_scanlines = dendy ? 290 : 240; - totalscanlines = normal_scanlines + (overclock_enabled ? extrascanlines : 0); + FSettings.normal_scanlines = FSettings.dendy ? SCANLINES_DENDY : SCANLINES_NORMAL; + FSettings.totalscanlines = FSettings.normal_scanlines + (FSettings.overclock_enabled ? FSettings.extrascanlines : 0); - FCEUPPU_SetVideoSystem(w || dendy); + FCEUPPU_SetVideoSystem(w || FSettings.dendy); SetSoundVariables(); } @@ -517,7 +523,7 @@ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall) FSettings.UsrLastSLine[0] = ntscl; FSettings.UsrFirstSLine[1] = palf; FSettings.UsrLastSLine[1] = pall; - if (PAL || dendy) + if (PAL || FSettings.dendy) { FSettings.FirstSLine = FSettings.UsrFirstSLine[1]; FSettings.LastSLine = FSettings.UsrLastSLine[1]; @@ -561,7 +567,7 @@ void FCEUI_SetSnapName(int a) int32 FCEUI_GetDesiredFPS(void) { - if (PAL || dendy) + if (PAL || FSettings.dendy) return(838977920); /* ~50.007 */ else return(1008307711); /* ~60.1 */ diff --git a/src/fceu.h b/src/fceu.h index d3ec9a6..27be7a2 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -5,27 +5,6 @@ extern int fceuindbg; -/* Overclocking-related */ -extern unsigned overclock_enabled; -extern unsigned overclocked; -extern unsigned skip_7bit_overclocking; -extern unsigned DMC_7bit; -extern unsigned totalscanlines; -extern unsigned normal_scanlines; -extern unsigned extrascanlines; -extern unsigned vblankscanlines; - -/* Region selection */ -extern unsigned dendy; - -/* Audio mods*/ -extern unsigned swapDuty; /* Swap bits 6 & 7 of $4000/$4004 to mimic bug - * found on some famiclones/Dendy models. - */ - -extern int show_crosshair; -extern int option_ramstate; - void ResetGameLoaded(void); #define DECLFR(x) uint8 FP_FASTAPASS(1) x(uint32 A) @@ -82,6 +61,9 @@ extern uint8 PAL; #include "driver.h" +#define SCANLINES_NORMAL 240 +#define SCANLINES_DENDY 290 + typedef struct { int PAL; int NetworkPlay; @@ -105,6 +87,21 @@ typedef struct { uint32 SndRate; int soundq; int lowpass; + + /* PPU Overclocking */ + int overclock_enabled; /* 1 : enable, 0 : disable duh! */ + int skip_7bit_overclocking; /* 7-bit samples have priority over overclocking */ + int extrascanlines; + int vblankscanlines; + int normal_scanlines; /* 240 : normal, 290 : dendy */ + int totalscanlines; + + int show_crosshair; + int ramstate; + int dendy; + int swapDuty; /* Swap bits 6 & 7 of $4000/$4004 to mimic bug + * found on some famiclones/Dendy models. + */ } FCEUS; extern FCEUS FSettings; diff --git a/src/ines.c b/src/ines.c index 7f807d3..ba524f3 100644 --- a/src/ines.c +++ b/src/ines.c @@ -1062,7 +1062,8 @@ int iNESLoad(const char *name, FCEUFILE *fp) { * 1: RP2C07 ("Licensed PAL NES") * 2: Multiple-region * 3: UMC 6527P ("Dendy") */ - if (iNESCart.region == 3) dendy = 1; + if (iNESCart.region == 3) + FSettings.dendy = 1; FCEUI_SetVidSystem((iNESCart.region == 1) ? 1 : 0); return 1; diff --git a/src/ppu.c b/src/ppu.c index 45ccc7f..fdf7675 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -660,7 +660,7 @@ static void DoLine(void) uint8 *target = NULL; uint8 *dtarget = NULL; - if (scanline >= 240 && scanline != totalscanlines) + if (scanline >= 240 && scanline != FSettings.totalscanlines) { X6502_Run(256 + 69); scanline++; @@ -1066,7 +1066,7 @@ static void CopySprites(uint8 *target) { void FCEUPPU_SetVideoSystem(int w) { if (w) { - scanlines_per_frame = dendy ? 262 : 312; + scanlines_per_frame = FSettings.dendy ? 262 : 312; FSettings.FirstSLine = FSettings.UsrFirstSLine[1]; FSettings.LastSLine = FSettings.UsrLastSLine[1]; } else { @@ -1166,11 +1166,11 @@ int FCEUPPU_Loop(int skip) { TriggerNMI(); } X6502_Run((scanlines_per_frame - 242) * (256 + 85) - 12); - if (overclock_enabled && vblankscanlines) { - if (!DMC_7bit || !skip_7bit_overclocking) { - overclocked = 1; - X6502_Run(vblankscanlines * (256 + 85) - 12); - overclocked = 0; + if (FSettings.overclock_enabled && FSettings.vblankscanlines) { + if (!DMC_7bit || !FSettings.skip_7bit_overclocking) { + overclocking = 1; + X6502_Run(FSettings.vblankscanlines * (256 + 85) - 12); + overclocking = 0; } } PPU_status &= 0x1f; @@ -1203,7 +1203,7 @@ int FCEUPPU_Loop(int skip) { kook ^= 1; } if (GameInfo->type == GIT_NSF) - X6502_Run((256 + 85) * normal_scanlines); + X6502_Run((256 + 85) * FSettings.normal_scanlines); #ifdef FRAMESKIP else if (skip) { int y; @@ -1234,21 +1234,21 @@ int FCEUPPU_Loop(int skip) { deemp = PPU[1] >> 5; /* manual samples can't play correctly with overclocking */ - if (DMC_7bit && skip_7bit_overclocking) - totalscanlines = normal_scanlines; + if (DMC_7bit && FSettings.skip_7bit_overclocking) + FSettings.totalscanlines = FSettings.normal_scanlines; else - totalscanlines = normal_scanlines + (overclock_enabled ? extrascanlines : 0); + FSettings.totalscanlines = FSettings.normal_scanlines + (FSettings.overclock_enabled ? FSettings.extrascanlines : 0); - for (scanline = 0; scanline < totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ + for (scanline = 0; scanline < FSettings.totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ deempcnt[deemp]++; /* if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1); */ DoLine(); - if (scanline < normal_scanlines || scanline == totalscanlines) - overclocked = 0; + if (scanline < FSettings.normal_scanlines || scanline == FSettings.totalscanlines) + overclocking = 0; else { - if (DMC_7bit && skip_7bit_overclocking) /* 7bit sample started after 240th line */ + if (DMC_7bit && FSettings.skip_7bit_overclocking) /* 7bit sample started after 240th line */ break; - overclocked = 1; + overclocking = 1; } } diff --git a/src/sound.c b/src/sound.c index a483d16..a72f93a 100644 --- a/src/sound.c +++ b/src/sound.c @@ -61,7 +61,7 @@ typedef struct { int reloaddec; } ENVUNIT; -unsigned DMC_7bit = 0; /* used to skip overclocking */ +uint32 DMC_7bit = 0; /* used to skip overclocking */ static ENVUNIT EnvUnits[3]; static const int RectDuties[4] = { 1, 2, 4, 6 }; @@ -195,7 +195,7 @@ static DECLFW(Write_PSG) { DoSQ1(); EnvUnits[0].Mode = (V & 0x30) >> 4; EnvUnits[0].Speed = (V & 0xF); - if (swapDuty) + if (FSettings.swapDuty) V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1); break; case 0x1: @@ -216,7 +216,7 @@ static DECLFW(Write_PSG) { DoSQ2(); EnvUnits[1].Mode = (V & 0x30) >> 4; EnvUnits[1].Speed = (V & 0xF); - if (swapDuty) + if (FSettings.swapDuty) V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1); break; case 0x5: diff --git a/src/sound.h b/src/sound.h index c4413cc..d10a56a 100644 --- a/src/sound.h +++ b/src/sound.h @@ -50,6 +50,7 @@ extern int32 Wave[2048 + 512]; extern int32 WaveFinal[2048 + 512]; extern int32 WaveHi[]; extern uint32 soundtsinc; +extern uint32 DMC_7bit; extern uint32 soundtsoffs; #define SOUNDTS (sound_timestamp + soundtsoffs) diff --git a/src/video.c b/src/video.c index 0017fc1..d54be19 100644 --- a/src/video.c +++ b/src/video.c @@ -37,7 +37,6 @@ uint8 *XBuf = NULL; uint8 *XDBuf = NULL; -int show_crosshair = 0; void FCEU_KillVirtualVideo(void) { @@ -53,15 +52,15 @@ int FCEU_InitVirtualVideo(void) { /* 256 bytes per scanline, * 240 scanline maximum, +8 for alignment, */ if (!XBuf) - XBuf = (uint8*)(FCEU_malloc(256 * (256 + extrascanlines + 8))); + XBuf = (uint8*)(FCEU_malloc(256 * (256 + FSettings.extrascanlines + 8))); if (!XDBuf) - XDBuf = (uint8*)(FCEU_malloc(256 * (256 + extrascanlines + 8))); + XDBuf = (uint8*)(FCEU_malloc(256 * (256 + FSettings.extrascanlines + 8))); if (!XBuf || !XDBuf) return 0; - memset(XBuf, 128, 256 * (256 + extrascanlines + 8)); - memset(XDBuf, 128, 256 * (256 + extrascanlines + 8)); + memset(XBuf, 128, 256 * (256 + FSettings.extrascanlines + 8)); + memset(XDBuf, 128, 256 * (256 + FSettings.extrascanlines + 8)); return 1; } @@ -82,7 +81,7 @@ void FCEU_PutImage(void) FCEU_VSUniDraw(XBuf); } if (howlong) howlong--; - if (show_crosshair) + if (FSettings.show_crosshair) FCEU_DrawInput(XBuf); } diff --git a/src/video.h b/src/video.h index 9eef95b..b98a419 100644 --- a/src/video.h +++ b/src/video.h @@ -6,7 +6,6 @@ void FCEU_KillVirtualVideo(void); int SaveSnapshot(void); extern uint8 *XBuf; extern uint8 *XDBuf; -extern int show_crosshair; void FCEU_DrawNumberRow(uint8 *XBuf, int *nstatus, int cur); #endif diff --git a/src/x6502.c b/src/x6502.c index b8bf2d9..0d00377 100644 --- a/src/x6502.c +++ b/src/x6502.c @@ -34,6 +34,7 @@ void (*X6502_Run)(int32 cycles); uint32 timestamp; uint32 sound_timestamp; +uint32 overclocking = 0; void FP_FASTAPASS(1) (*MapIRQHook)(int a); #define _PC X.PC @@ -54,7 +55,7 @@ void FP_FASTAPASS(1) (*MapIRQHook)(int a); _tcount += __x; \ _count -= __x * 48; \ timestamp += __x; \ - if (!overclocked) sound_timestamp += __x; \ + if (!overclocking) sound_timestamp += __x; \ } static INLINE uint8 RdMemNorm(uint32 A) { @@ -516,7 +517,7 @@ static void X6502_RunDebug(int32 cycles) { _tcount = 0; if (MapIRQHook) MapIRQHook(temp); - if (!overclocked) + if (!overclocking) FCEU_SoundCPUHook(temp); _PC++; @@ -613,7 +614,7 @@ void X6502_Run(int32 cycles) temp = _tcount; _tcount = 0; if (MapIRQHook) MapIRQHook(temp); - if (!overclocked) + if (!overclocking) FCEU_SoundCPUHook(temp); X.PC = pbackus; _PC++; diff --git a/src/x6502.h b/src/x6502.h index f480544..d9d8b65 100644 --- a/src/x6502.h +++ b/src/x6502.h @@ -35,6 +35,7 @@ void X6502_Run(int32 cycles); extern uint32 timestamp; extern uint32 sound_timestamp; +extern uint32 overclocking; extern X6502 X; #define N_FLAG 0x80 @@ -48,7 +49,7 @@ extern X6502 X; extern void FP_FASTAPASS(1) (*MapIRQHook)(int a); -#define NTSC_CPU (dendy ? 1773447.467 : 1789772.7272727272727272) +#define NTSC_CPU (FSettings.dendy ? 1773447.467 : 1789772.7272727272727272) #define PAL_CPU 1662607.125 #define FCEU_IQEXT 0x001 From f6cc87a8fa0f01a13376de13659a9ee2225d81e1 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Thu, 3 Jun 2021 10:50:22 +0800 Subject: [PATCH 120/295] Move overclock-related variables to ppu instead Just makes more sense since overclocking is ppu-based. --- src/drivers/libretro/libretro.c | 30 +++++++++++++++--------------- src/fceu.c | 16 ++++++++-------- src/fceu.h | 8 -------- src/ppu.c | 24 +++++++++++++----------- src/ppu.h | 12 ++++++++++++ src/video.c | 8 ++++---- 6 files changed, 52 insertions(+), 46 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 43a4d33..a83f842 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1223,33 +1223,33 @@ static void check_variables(bool startup) bool do_reinit = false; if (!strcmp(var.value, "disabled") - && FSettings.overclock_enabled != 0) + && ppu.overclock_enabled != 0) { - FSettings.skip_7bit_overclocking = 1; - FSettings.extrascanlines = 0; - FSettings.vblankscanlines = 0; - FSettings.overclock_enabled = 0; + ppu.skip_7bit_overclocking = 1; + ppu.extrascanlines = 0; + ppu.vblankscanlines = 0; + ppu.overclock_enabled = 0; do_reinit = true; } else if (!strcmp(var.value, "2x-Postrender")) { - FSettings.skip_7bit_overclocking = 1; - FSettings.extrascanlines = 266; - FSettings.vblankscanlines = 0; - FSettings.overclock_enabled = 1; + ppu.skip_7bit_overclocking = 1; + ppu.extrascanlines = 266; + ppu.vblankscanlines = 0; + ppu.overclock_enabled = 1; do_reinit = true; } else if (!strcmp(var.value, "2x-VBlank")) { - FSettings.skip_7bit_overclocking = 1; - FSettings.extrascanlines = 0; - FSettings.vblankscanlines = 266; - FSettings.overclock_enabled = 1; + ppu.skip_7bit_overclocking = 1; + ppu.extrascanlines = 0; + ppu.vblankscanlines = 266; + ppu.overclock_enabled = 1; do_reinit = true; } - FSettings.normal_scanlines = FSettings.dendy ? SCANLINES_DENDY : SCANLINES_NORMAL; - FSettings.totalscanlines = FSettings.normal_scanlines + (FSettings.overclock_enabled ? FSettings.extrascanlines : 0); + ppu.normal_scanlines = FSettings.dendy ? SCANLINES_DENDY : SCANLINES_NORMAL; + ppu.totalscanlines = ppu.normal_scanlines + (ppu.overclock_enabled ? ppu.extrascanlines : 0); if (do_reinit && startup) { diff --git a/src/fceu.c b/src/fceu.c index 748e7f7..7977e5c 100644 --- a/src/fceu.c +++ b/src/fceu.c @@ -341,14 +341,14 @@ int FCEUI_Initialize(void) { FSettings.UsrLastSLine[0] = 231; FSettings.UsrLastSLine[1] = 239; FSettings.SoundVolume = 100; - FSettings.overclock_enabled = 0; - FSettings.skip_7bit_overclocking = 1; - FSettings.totalscanlines = 0; - FSettings.normal_scanlines = SCANLINES_NORMAL; - FSettings.extrascanlines = 0; - FSettings.vblankscanlines = 0; FSettings.dendy = 0; FSettings.swapDuty = 0; + ppu.overclock_enabled = 0; + ppu.skip_7bit_overclocking = 1; + ppu.totalscanlines = 0; + ppu.normal_scanlines = SCANLINES_NORMAL; + ppu.extrascanlines = 0; + ppu.vblankscanlines = 0; FCEUPPU_Init(); X6502_Init(); return 1; @@ -482,8 +482,8 @@ void FCEU_ResetVidSys(void) if (PAL) FSettings.dendy = 0; - FSettings.normal_scanlines = FSettings.dendy ? SCANLINES_DENDY : SCANLINES_NORMAL; - FSettings.totalscanlines = FSettings.normal_scanlines + (FSettings.overclock_enabled ? FSettings.extrascanlines : 0); + ppu.normal_scanlines = FSettings.dendy ? SCANLINES_DENDY : SCANLINES_NORMAL; + ppu.totalscanlines = ppu.normal_scanlines + (ppu.overclock_enabled ? ppu.extrascanlines : 0); FCEUPPU_SetVideoSystem(w || FSettings.dendy); SetSoundVariables(); diff --git a/src/fceu.h b/src/fceu.h index 27be7a2..4756bda 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -88,14 +88,6 @@ typedef struct { int soundq; int lowpass; - /* PPU Overclocking */ - int overclock_enabled; /* 1 : enable, 0 : disable duh! */ - int skip_7bit_overclocking; /* 7-bit samples have priority over overclocking */ - int extrascanlines; - int vblankscanlines; - int normal_scanlines; /* 240 : normal, 290 : dendy */ - int totalscanlines; - int show_crosshair; int ramstate; int dendy; diff --git a/src/ppu.c b/src/ppu.c index fdf7675..ca4ea73 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -64,6 +64,8 @@ static uint32 ppulut1[256]; static uint32 ppulut2[256]; static uint32 ppulut3[128]; +FCEU_PPU ppu; + static void makeppulut(void) { int x; int y; @@ -660,7 +662,7 @@ static void DoLine(void) uint8 *target = NULL; uint8 *dtarget = NULL; - if (scanline >= 240 && scanline != FSettings.totalscanlines) + if (scanline >= 240 && scanline != ppu.totalscanlines) { X6502_Run(256 + 69); scanline++; @@ -1166,10 +1168,10 @@ int FCEUPPU_Loop(int skip) { TriggerNMI(); } X6502_Run((scanlines_per_frame - 242) * (256 + 85) - 12); - if (FSettings.overclock_enabled && FSettings.vblankscanlines) { - if (!DMC_7bit || !FSettings.skip_7bit_overclocking) { + if (ppu.overclock_enabled && ppu.vblankscanlines) { + if (!DMC_7bit || !ppu.skip_7bit_overclocking) { overclocking = 1; - X6502_Run(FSettings.vblankscanlines * (256 + 85) - 12); + X6502_Run(ppu.vblankscanlines * (256 + 85) - 12); overclocking = 0; } } @@ -1203,7 +1205,7 @@ int FCEUPPU_Loop(int skip) { kook ^= 1; } if (GameInfo->type == GIT_NSF) - X6502_Run((256 + 85) * FSettings.normal_scanlines); + X6502_Run((256 + 85) * ppu.normal_scanlines); #ifdef FRAMESKIP else if (skip) { int y; @@ -1234,19 +1236,19 @@ int FCEUPPU_Loop(int skip) { deemp = PPU[1] >> 5; /* manual samples can't play correctly with overclocking */ - if (DMC_7bit && FSettings.skip_7bit_overclocking) - FSettings.totalscanlines = FSettings.normal_scanlines; + if (DMC_7bit && ppu.skip_7bit_overclocking) + ppu.totalscanlines = ppu.normal_scanlines; else - FSettings.totalscanlines = FSettings.normal_scanlines + (FSettings.overclock_enabled ? FSettings.extrascanlines : 0); + ppu.totalscanlines = ppu.normal_scanlines + (ppu.overclock_enabled ? ppu.extrascanlines : 0); - for (scanline = 0; scanline < FSettings.totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ + for (scanline = 0; scanline < ppu.totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ deempcnt[deemp]++; /* if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1); */ DoLine(); - if (scanline < FSettings.normal_scanlines || scanline == FSettings.totalscanlines) + if (scanline < ppu.normal_scanlines || scanline == ppu.totalscanlines) overclocking = 0; else { - if (DMC_7bit && FSettings.skip_7bit_overclocking) /* 7bit sample started after 240th line */ + if (DMC_7bit && ppu.skip_7bit_overclocking) /* 7bit sample started after 240th line */ break; overclocking = 1; } diff --git a/src/ppu.h b/src/ppu.h index d9cfcec..829de71 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -1,6 +1,18 @@ #ifndef _FCEU_PPU_H #define _FCEU_PPU_H +typedef struct { + /* PPU Overclocking */ + int overclock_enabled; /* 1 : enable, 0 : disable duh! */ + int skip_7bit_overclocking; /* 7-bit samples have priority over overclocking */ + int extrascanlines; + int vblankscanlines; + int normal_scanlines; /* 240 : normal, 290 : dendy */ + int totalscanlines; +} FCEU_PPU; + +extern FCEU_PPU ppu; + void FCEUPPU_Init(void); void FCEUPPU_Reset(void); void FCEUPPU_Power(void); diff --git a/src/video.c b/src/video.c index d54be19..80da854 100644 --- a/src/video.c +++ b/src/video.c @@ -52,15 +52,15 @@ int FCEU_InitVirtualVideo(void) { /* 256 bytes per scanline, * 240 scanline maximum, +8 for alignment, */ if (!XBuf) - XBuf = (uint8*)(FCEU_malloc(256 * (256 + FSettings.extrascanlines + 8))); + XBuf = (uint8*)(FCEU_malloc(256 * (256 + ppu.extrascanlines + 8))); if (!XDBuf) - XDBuf = (uint8*)(FCEU_malloc(256 * (256 + FSettings.extrascanlines + 8))); + XDBuf = (uint8*)(FCEU_malloc(256 * (256 + ppu.extrascanlines + 8))); if (!XBuf || !XDBuf) return 0; - memset(XBuf, 128, 256 * (256 + FSettings.extrascanlines + 8)); - memset(XDBuf, 128, 256 * (256 + FSettings.extrascanlines + 8)); + memset(XBuf, 128, 256 * (256 + ppu.extrascanlines + 8)); + memset(XDBuf, 128, 256 * (256 + ppu.extrascanlines + 8)); return 1; } From e75d6be00be76ace1d91012157d4a30741942ee7 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Thu, 3 Jun 2021 13:30:16 +0800 Subject: [PATCH 121/295] Remove ununsed, commented code --- src/drivers/libretro/libretro.c | 2 -- src/ppu.c | 1 - src/ppuview.h | 2 -- 3 files changed, 5 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index a83f842..d14facc 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -171,8 +171,6 @@ static unsigned serialize_size; /* emulator-specific callback functions */ -void UpdatePPUView(int refreshchr) { } - const char * GetKeyboard(void) { return ""; diff --git a/src/ppu.c b/src/ppu.c index ca4ea73..abb24c3 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -1243,7 +1243,6 @@ int FCEUPPU_Loop(int skip) { for (scanline = 0; scanline < ppu.totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ deempcnt[deemp]++; - /* if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1); */ DoLine(); if (scanline < ppu.normal_scanlines || scanline == ppu.totalscanlines) overclocking = 0; diff --git a/src/ppuview.h b/src/ppuview.h index 740a183..7a3633c 100644 --- a/src/ppuview.h +++ b/src/ppuview.h @@ -1,8 +1,6 @@ #ifndef _FCEU_PPUVIEW_H #define _FCEU_PPUVIEW_H -extern int PPUViewScanline; -extern int PPUViewer; extern int scanline; void PPUViewDoBlit(); From 85d5c87d3d18a728281087bdf407c78f3f0763cd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 4 Jun 2021 21:01:19 +0200 Subject: [PATCH 122/295] - Simplify MakeMemWrapBuffer - FCEUI_LoadGame - UNIFLoad and FDSLoad never use 'name' so pass NULL here --- src/fceu.c | 6 ++---- src/file.c | 10 +++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/fceu.c b/src/fceu.c index de3f21b..0d471b9 100644 --- a/src/fceu.c +++ b/src/fceu.c @@ -244,8 +244,6 @@ FCEUGI *FCEUI_LoadGame(const char *name, uint8_t *databuf, size_t databufsize) GameInfo->inputfc = -1; GameInfo->cspecial = 0; - FCEU_printf("Loading %s...\n\n", name); - GetFileBase(name); fp = FCEU_fopen(name, NULL, "rb", 0, databuf, databufsize); @@ -259,9 +257,9 @@ FCEUGI *FCEUI_LoadGame(const char *name, uint8_t *databuf, size_t databufsize) goto endlseq; if (NSFLoad(fp)) goto endlseq; - if (UNIFLoad(name, fp)) + if (UNIFLoad(NULL, fp)) goto endlseq; - if (FDSLoad(name, fp)) + if (FDSLoad(NULL, fp)) goto endlseq; FCEU_PrintError("An error occurred while loading the file.\n"); diff --git a/src/file.c b/src/file.c index 07da9f8..fc05ea1 100644 --- a/src/file.c +++ b/src/file.c @@ -63,7 +63,7 @@ doret: return tmp; } -static MEMWRAP *MakeMemWrapBuffer(const char *tz, int type, uint8 *buffer, size_t bufsize) +static MEMWRAP *MakeMemWrapBuffer(uint8 *buffer, size_t bufsize) { MEMWRAP *tmp = (MEMWRAP*)FCEU_malloc(sizeof(MEMWRAP)); @@ -71,8 +71,8 @@ static MEMWRAP *MakeMemWrapBuffer(const char *tz, int type, uint8 *buffer, size_ return NULL; tmp->location = 0; - tmp->size = bufsize; - tmp->data = buffer; + tmp->size = bufsize; + tmp->data = buffer; return tmp; } @@ -82,9 +82,9 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, { FCEUFILE *fceufp = (FCEUFILE*)malloc(sizeof(FCEUFILE)); - fceufp->type = 0; + fceufp->type = 0; if (buffer) - fceufp->fp = MakeMemWrapBuffer(path, 0, buffer, bufsize); + fceufp->fp = MakeMemWrapBuffer(buffer, bufsize); else { void *t = fopen_utf8(path, mode); From 6f8be4ceddc6ad3c139a780b451000cdf2435572 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sat, 5 Jun 2021 08:26:37 +0800 Subject: [PATCH 123/295] Simplify palette core options Fetch names from palette struct instead. --- src/drivers/libretro/libretro.c | 54 +++++++++++---------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index d14facc..7ff7dcb 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -273,11 +273,6 @@ FILE *FCEUD_UTF8fopen(const char *n, const char *m) } /*palette for FCEU*/ -#define PAL_TOTAL 16 /* total no. of palettes in palettes[] */ -#define PAL_DEFAULT (PAL_TOTAL + 1) -#define PAL_RAW (PAL_TOTAL + 2) -#define PAL_CUSTOM (PAL_TOTAL + 3) - static int external_palette_exist = 0; /* table for currently loaded palette */ @@ -580,6 +575,11 @@ struct st_palettes palettes[] = { } }; +#define PAL_TOTAL (sizeof(palettes) / sizeof(palettes[0])) /* total palettes in table */ +#define PAL_DEFAULT (PAL_TOTAL + 1) +#define PAL_RAW (PAL_TOTAL + 2) +#define PAL_CUSTOM (PAL_TOTAL + 3) + #ifdef HAVE_NTSC_FILTER /* ntsc */ #include "nes_ntsc.h" @@ -1159,38 +1159,18 @@ static void check_variables(bool startup) current_palette = PAL_RAW; else if (!strcmp(var.value, "custom")) current_palette = PAL_CUSTOM; - else if (!strcmp(var.value, "asqrealc")) - current_palette = 0; - else if (!strcmp(var.value, "nintendo-vc")) - current_palette = 1; - else if (!strcmp(var.value, "rgb")) - current_palette = 2; - else if (!strcmp(var.value, "yuv-v3")) - current_palette = 3; - else if (!strcmp(var.value, "unsaturated-final")) - current_palette = 4; - else if (!strcmp(var.value, "sony-cxa2025as-us")) - current_palette = 5; - else if (!strcmp(var.value, "pal")) - current_palette = 6; - else if (!strcmp(var.value, "bmf-final2")) - current_palette = 7; - else if (!strcmp(var.value, "bmf-final3")) - current_palette = 8; - else if (!strcmp(var.value, "smooth-fbx")) - current_palette = 9; - else if (!strcmp(var.value, "composite-direct-fbx")) - current_palette = 10; - else if (!strcmp(var.value, "pvm-style-d93-fbx")) - current_palette = 11; - else if (!strcmp(var.value, "ntsc-hardware-fbx")) - current_palette = 12; - else if (!strcmp(var.value, "nes-classic-fbx-fs")) - current_palette = 13; - else if (!strcmp(var.value, "nescap")) - current_palette = 14; - else if (!strcmp(var.value, "wavebeam")) - current_palette = 15; + else + { + unsigned i; + for (i = 0; i < PAL_TOTAL; i++) + { + if (!strcmp(var.value, palettes[i].name)) + { + current_palette = i; + break; + } + } + } if (current_palette != orig_value) { From 001e3a24284484af96cd11451197dace7b295806 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sat, 5 Jun 2021 08:39:47 +0800 Subject: [PATCH 124/295] Remove this (remnants of ppuview) --- src/ppu.c | 1 - src/ppuview.h | 11 ----------- 2 files changed, 12 deletions(-) delete mode 100644 src/ppuview.h diff --git a/src/ppu.c b/src/ppu.c index abb24c3..b6ae1c5 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -32,7 +32,6 @@ #include "general.h" #include "fceu-endian.h" #include "fceu-memory.h" -#include "ppuview.h" #include "cart.h" #include "palette.h" diff --git a/src/ppuview.h b/src/ppuview.h deleted file mode 100644 index 7a3633c..0000000 --- a/src/ppuview.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _FCEU_PPUVIEW_H -#define _FCEU_PPUVIEW_H - -extern int scanline; - -void PPUViewDoBlit(); -void DoPPUView(); -void UpdatePPUView(int refreshchr); - - -#endif From cbc17a077bc84cb302475c843ba546b59ceb3a35 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 5 Jun 2021 14:55:17 +0200 Subject: [PATCH 125/295] iNESLoad - some code is not used except for printing some information, stub it out with DEBUG ifdefs --- src/ines.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ines.c b/src/ines.c index ba524f3..0c92e30 100644 --- a/src/ines.c +++ b/src/ines.c @@ -854,10 +854,12 @@ static void rom_load_ines2(void) { int iNESLoad(const char *name, FCEUFILE *fp) { const char *tv_region[] = { "NTSC", "PAL", "Multi-region", "Dendy" }; struct md5_context md5; +#ifdef DEBUG char* mappername = NULL; + uint32 mappertest = 0; +#endif uint64 filesize = FCEU_fgetsize(fp); uint64 romSize = 0; - uint32 mappertest = 0; /* used for malloc and cart mapping */ uint32 rom_size_pow2 = 0; uint32 vrom_size_pow2 = 0; @@ -949,6 +951,7 @@ int iNESLoad(const char *name, FCEUFILE *fp) { memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5)); +#ifdef DEBUG mappername = "Not Listed"; for (mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) { @@ -957,6 +960,7 @@ int iNESLoad(const char *name, FCEUFILE *fp) { break; } } +#endif if (iNESCart.iNES2 == 0) { if (strstr(name, "(E)") || strstr(name, "(e)") || @@ -974,6 +978,7 @@ int iNESLoad(const char *name, FCEUFILE *fp) { } } +#ifdef DEBUG FCEU_printf(" PRG-ROM CRC32: 0x%08X\n", iNESCart.PRGCRC32); FCEU_printf(" PRG+CHR CRC32: 0x%08X\n", iNESCart.CRC32); FCEU_printf(" PRG+CHR MD5: 0x%s\n", md5_asciistr(iNESCart.MD5)); @@ -985,6 +990,7 @@ int iNESLoad(const char *name, FCEUFILE *fp) { FCEU_printf(" Battery: %s\n", (head.ROM_type & 2) ? "Yes" : "No"); FCEU_printf(" System: %s\n", tv_region[iNESCart.region]); FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); +#endif if (iNESCart.iNES2) { unsigned PRGRAM = iNESCart.PRGRamSize + iNESCart.PRGRamSaveSize; @@ -1017,9 +1023,8 @@ int iNESLoad(const char *name, FCEUFILE *fp) { int mapper = iNESCart.mapper; int mirroring = iNESCart.mirror; - for (x = 0; x < 8; x++) { + for (x = 0; x < 8; x++) partialmd5 |= (uint64)iNESCart.MD5[7 - x] << (x * 8); - } FCEU_VSUniCheck(partialmd5, &mapper, &mirroring); From aa4615c41714b43dfe71831760494e1ce51d8597 Mon Sep 17 00:00:00 2001 From: Autechre Date: Sat, 5 Jun 2021 15:05:07 +0200 Subject: [PATCH 126/295] Revert "some cleanups" --- Makefile.libretro | 4 +- src/cart.h | 3 - src/drivers/libretro/libretro.c | 143 ++++++++++++++++++++++---------- src/fceu.c | 26 +++--- src/fceu.h | 28 ++++--- src/ines.c | 3 +- src/input.h | 2 - src/ppu.c | 36 ++++---- src/ppu.h | 14 ---- src/ppuview.h | 13 +++ src/sound.c | 6 +- src/sound.h | 1 - src/video.c | 11 +-- src/video.h | 1 + src/x6502.c | 7 +- src/x6502.h | 3 +- 16 files changed, 174 insertions(+), 127 deletions(-) create mode 100644 src/ppuview.h diff --git a/Makefile.libretro b/Makefile.libretro index 2387bed..86563b0 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -752,8 +752,8 @@ else WARNING_DEFINES = -Wno-write-strings endif -CFLAGS += $(fpic) $(WARNING_DEFINES) $(DEFINES) $(ENDIANNESS_DEFINES) -Werror=implicit-function-declaration -LDFLAGS += $(LIBM) -Werror=implicit-function-declaration +CFLAGS += $(fpic) $(WARNING_DEFINES) $(DEFINES) $(ENDIANNESS_DEFINES) +LDFLAGS += $(LIBM) ifeq ($(platform), psp1) INCFLAGS += -I$(shell psp-config --pspsdk-path)/include diff --git a/src/cart.h b/src/cart.h index cd05d4b..4573403 100644 --- a/src/cart.h +++ b/src/cart.h @@ -104,7 +104,4 @@ void FCEU_OpenGenie(void); void FCEU_CloseGenie(void); void FCEU_KillGenie(void); -extern CartInfo iNESCart; -extern CartInfo UNIFCart; - #endif diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 7ff7dcb..39263fc 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -67,6 +67,8 @@ void linearFree(void* mem); RETRO_HW_RENDER_INTEFACE_GSKIT_PS2 *ps2 = NULL; #endif +extern void FCEU_ZapperSetTolerance(int t); + static retro_video_refresh_t video_cb = NULL; static retro_input_poll_t poll_cb = NULL; static retro_input_state_t input_cb = NULL; @@ -93,7 +95,7 @@ static int aspect_ratio_par; #define MAX_BUTTONS 8 #define TURBO_BUTTONS 2 -unsigned turbo_button_toggle[MAX_PLAYERS][TURBO_BUTTONS] = { {0} }; +unsigned char turbo_button_toggle[MAX_PLAYERS][TURBO_BUTTONS] = { {0} }; typedef struct { @@ -143,11 +145,27 @@ static bool libretro_supports_bitmasks = false; const size_t PPU_BIT = 1ULL << 31ULL; +extern uint8 NTARAM[0x800], PALRAM[0x20], SPRAM[0x100], PPU[4]; + +/* overclock the console by adding dummy scanlines to PPU loop + * disables DMC DMA and WaveHi filling for these dummies + * doesn't work with new PPU */ +unsigned overclock_enabled = -1; +unsigned overclocked = 0; +unsigned skip_7bit_overclocking = 1; /* 7-bit samples have priority over overclocking */ +unsigned totalscanlines = 0; +unsigned normal_scanlines = 240; +unsigned extrascanlines = 0; +unsigned vblankscanlines = 0; +unsigned dendy = 0; + static unsigned systemRegion = 0; static unsigned opt_region = 0; static unsigned opt_showAdvSoundOptions = 0; static unsigned opt_showAdvSystemOptions = 0; +int FCEUnetplay; + #if defined(PSP) || defined(PS2) static __attribute__((aligned(16))) uint16_t retro_palette[256]; #else @@ -163,14 +181,28 @@ static uint16_t* fceu_video_out; static unsigned sndsamplerate; static unsigned sndquality; static unsigned sndvolume; +unsigned swapDuty; static int32_t *sound = 0; static uint32_t Dummy = 0; static uint32_t current_palette = 0; static unsigned serialize_size; +int PPUViewScanline=0; +int PPUViewer=0; + +/* extern forward decls.*/ +extern FCEUGI *GameInfo; +extern uint8 *XBuf; +extern CartInfo iNESCart; +extern CartInfo UNIFCart; +extern int show_crosshair; +extern int option_ramstate; + /* emulator-specific callback functions */ +void UpdatePPUView(int refreshchr) { } + const char * GetKeyboard(void) { return ""; @@ -273,7 +305,13 @@ FILE *FCEUD_UTF8fopen(const char *n, const char *m) } /*palette for FCEU*/ +#define PAL_TOTAL 16 /* total no. of palettes in palettes[] */ +#define PAL_DEFAULT (PAL_TOTAL + 1) +#define PAL_RAW (PAL_TOTAL + 2) +#define PAL_CUSTOM (PAL_TOTAL + 3) + static int external_palette_exist = 0; +extern int ipalette; /* table for currently loaded palette */ static uint8_t base_palette[192]; @@ -575,11 +613,6 @@ struct st_palettes palettes[] = { } }; -#define PAL_TOTAL (sizeof(palettes) / sizeof(palettes[0])) /* total palettes in table */ -#define PAL_DEFAULT (PAL_TOTAL + 1) -#define PAL_RAW (PAL_TOTAL + 2) -#define PAL_CUSTOM (PAL_TOTAL + 3) - #ifdef HAVE_NTSC_FILTER /* ntsc */ #include "nes_ntsc.h" @@ -955,7 +988,7 @@ void retro_get_system_av_info(struct retro_system_av_info *info) info->geometry.max_height = NES_HEIGHT; info->geometry.aspect_ratio = get_aspect_ratio(width, height); info->timing.sample_rate = (float)sndsamplerate; - if (FSettings.PAL || FSettings.dendy) + if (FSettings.PAL || dendy) info->timing.fps = 838977920.0/16777215.0; else info->timing.fps = 1008307711.0/16777215.0; @@ -1060,7 +1093,7 @@ static void FCEUD_RegionOverride(unsigned region) break; } - FSettings.dendy = d; + dendy = d; FCEUI_SetVidSystem(pal); ResetPalette(); } @@ -1116,11 +1149,11 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { if (!strcmp(var.value, "random")) - FSettings.ramstate = 2; + option_ramstate = 2; else if (!strcmp(var.value, "fill $00")) - FSettings.ramstate = 1; + option_ramstate = 1; else - FSettings.ramstate = 0; + option_ramstate = 0; } #ifdef HAVE_NTSC_FILTER @@ -1159,18 +1192,38 @@ static void check_variables(bool startup) current_palette = PAL_RAW; else if (!strcmp(var.value, "custom")) current_palette = PAL_CUSTOM; - else - { - unsigned i; - for (i = 0; i < PAL_TOTAL; i++) - { - if (!strcmp(var.value, palettes[i].name)) - { - current_palette = i; - break; - } - } - } + else if (!strcmp(var.value, "asqrealc")) + current_palette = 0; + else if (!strcmp(var.value, "nintendo-vc")) + current_palette = 1; + else if (!strcmp(var.value, "rgb")) + current_palette = 2; + else if (!strcmp(var.value, "yuv-v3")) + current_palette = 3; + else if (!strcmp(var.value, "unsaturated-final")) + current_palette = 4; + else if (!strcmp(var.value, "sony-cxa2025as-us")) + current_palette = 5; + else if (!strcmp(var.value, "pal")) + current_palette = 6; + else if (!strcmp(var.value, "bmf-final2")) + current_palette = 7; + else if (!strcmp(var.value, "bmf-final3")) + current_palette = 8; + else if (!strcmp(var.value, "smooth-fbx")) + current_palette = 9; + else if (!strcmp(var.value, "composite-direct-fbx")) + current_palette = 10; + else if (!strcmp(var.value, "pvm-style-d93-fbx")) + current_palette = 11; + else if (!strcmp(var.value, "ntsc-hardware-fbx")) + current_palette = 12; + else if (!strcmp(var.value, "nes-classic-fbx-fs")) + current_palette = 13; + else if (!strcmp(var.value, "nescap")) + current_palette = 14; + else if (!strcmp(var.value, "wavebeam")) + current_palette = 15; if (current_palette != orig_value) { @@ -1201,33 +1254,33 @@ static void check_variables(bool startup) bool do_reinit = false; if (!strcmp(var.value, "disabled") - && ppu.overclock_enabled != 0) + && overclock_enabled != 0) { - ppu.skip_7bit_overclocking = 1; - ppu.extrascanlines = 0; - ppu.vblankscanlines = 0; - ppu.overclock_enabled = 0; + skip_7bit_overclocking = 1; + extrascanlines = 0; + vblankscanlines = 0; + overclock_enabled = 0; do_reinit = true; } else if (!strcmp(var.value, "2x-Postrender")) { - ppu.skip_7bit_overclocking = 1; - ppu.extrascanlines = 266; - ppu.vblankscanlines = 0; - ppu.overclock_enabled = 1; + skip_7bit_overclocking = 1; + extrascanlines = 266; + vblankscanlines = 0; + overclock_enabled = 1; do_reinit = true; } else if (!strcmp(var.value, "2x-VBlank")) { - ppu.skip_7bit_overclocking = 1; - ppu.extrascanlines = 0; - ppu.vblankscanlines = 266; - ppu.overclock_enabled = 1; + skip_7bit_overclocking = 1; + extrascanlines = 0; + vblankscanlines = 266; + overclock_enabled = 1; do_reinit = true; } - ppu.normal_scanlines = FSettings.dendy ? SCANLINES_DENDY : SCANLINES_NORMAL; - ppu.totalscanlines = ppu.normal_scanlines + (ppu.overclock_enabled ? ppu.extrascanlines : 0); + normal_scanlines = dendy ? 290 : 240; + totalscanlines = normal_scanlines + (overclock_enabled ? extrascanlines : 0); if (do_reinit && startup) { @@ -1259,10 +1312,8 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - if (!strcmp(var.value, "enabled")) - FSettings.show_crosshair = 1; - else if (!strcmp(var.value, "disabled")) - FSettings.show_crosshair = 0; + if (!strcmp(var.value, "enabled")) show_crosshair = 1; + else if (!strcmp(var.value, "disabled")) show_crosshair = 0; } #ifdef PSP @@ -1400,8 +1451,8 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { bool newval = (!strcmp(var.value, "enabled")); - if (newval != FSettings.swapDuty) - FSettings.swapDuty = newval; + if (newval != swapDuty) + swapDuty = newval; } var.key = key; @@ -2377,6 +2428,8 @@ bool retro_load_game(const struct retro_game_info *game) #endif sndquality = 0; sndvolume = 150; + swapDuty = 0; + dendy = 0; opt_region = 0; /* Wii: initialize this or else last variable is passed through @@ -2436,7 +2489,7 @@ bool retro_load_game(const struct retro_game_info *game) FCEU_printf(" Loading custom palette: %s%cnes.pal\n", dir, slash); /* Save region and dendy mode for region-auto detect */ - systemRegion = (FSettings.dendy << 1) | (retro_get_region() & 1); + systemRegion = (dendy << 1) | (retro_get_region() & 1); current_palette = 0; diff --git a/src/fceu.c b/src/fceu.c index 564b67f..0d471b9 100644 --- a/src/fceu.c +++ b/src/fceu.c @@ -339,14 +339,6 @@ int FCEUI_Initialize(void) { FSettings.UsrLastSLine[0] = 231; FSettings.UsrLastSLine[1] = 239; FSettings.SoundVolume = 100; - FSettings.dendy = 0; - FSettings.swapDuty = 0; - ppu.overclock_enabled = 0; - ppu.skip_7bit_overclocking = 1; - ppu.totalscanlines = 0; - ppu.normal_scanlines = SCANLINES_NORMAL; - ppu.extrascanlines = 0; - ppu.vblankscanlines = 0; FCEUPPU_Init(); X6502_Init(); return 1; @@ -387,6 +379,8 @@ void ResetNES(void) X6502_Reset(); } +int option_ramstate = 0; + void FCEU_MemoryRand(uint8 *ptr, uint32 size) { int x = 0; @@ -401,7 +395,7 @@ void FCEU_MemoryRand(uint8 *ptr, uint32 size) /* 1942 SCORE/HISCORE is screwed... */ #endif uint8_t v = 0; - switch (FSettings.ramstate) + switch (option_ramstate) { case 0: v = 0xff; break; case 1: v = 0x00; break; @@ -470,7 +464,7 @@ void FCEU_ResetVidSys(void) else if (GameInfo->vidsys == GIV_PAL) { w = 1; - FSettings.dendy = 0; + dendy = 0; } else w = FSettings.PAL; @@ -478,12 +472,12 @@ void FCEU_ResetVidSys(void) PAL = w ? 1 : 0; if (PAL) - FSettings.dendy = 0; + dendy = 0; - ppu.normal_scanlines = FSettings.dendy ? SCANLINES_DENDY : SCANLINES_NORMAL; - ppu.totalscanlines = ppu.normal_scanlines + (ppu.overclock_enabled ? ppu.extrascanlines : 0); + normal_scanlines = dendy ? 290 : 240; + totalscanlines = normal_scanlines + (overclock_enabled ? extrascanlines : 0); - FCEUPPU_SetVideoSystem(w || FSettings.dendy); + FCEUPPU_SetVideoSystem(w || dendy); SetSoundVariables(); } @@ -521,7 +515,7 @@ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall) FSettings.UsrLastSLine[0] = ntscl; FSettings.UsrFirstSLine[1] = palf; FSettings.UsrLastSLine[1] = pall; - if (PAL || FSettings.dendy) + if (PAL || dendy) { FSettings.FirstSLine = FSettings.UsrFirstSLine[1]; FSettings.LastSLine = FSettings.UsrLastSLine[1]; @@ -565,7 +559,7 @@ void FCEUI_SetSnapName(int a) int32 FCEUI_GetDesiredFPS(void) { - if (PAL || FSettings.dendy) + if (PAL || dendy) return(838977920); /* ~50.007 */ else return(1008307711); /* ~60.1 */ diff --git a/src/fceu.h b/src/fceu.h index 4756bda..f97b425 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -5,6 +5,24 @@ extern int fceuindbg; +/* Overclocking-related */ +extern unsigned overclock_enabled; +extern unsigned overclocked; +extern unsigned skip_7bit_overclocking; +extern unsigned DMC_7bit; +extern unsigned totalscanlines; +extern unsigned normal_scanlines; +extern unsigned extrascanlines; +extern unsigned vblankscanlines; + +/* Region selection */ +extern unsigned dendy; + +/* Audio mods*/ +extern unsigned swapDuty; /* Swap bits 6 & 7 of $4000/$4004 to mimic bug + * found on some famiclones/Dendy models. + */ + void ResetGameLoaded(void); #define DECLFR(x) uint8 FP_FASTAPASS(1) x(uint32 A) @@ -61,9 +79,6 @@ extern uint8 PAL; #include "driver.h" -#define SCANLINES_NORMAL 240 -#define SCANLINES_DENDY 290 - typedef struct { int PAL; int NetworkPlay; @@ -87,13 +102,6 @@ typedef struct { uint32 SndRate; int soundq; int lowpass; - - int show_crosshair; - int ramstate; - int dendy; - int swapDuty; /* Swap bits 6 & 7 of $4000/$4004 to mimic bug - * found on some famiclones/Dendy models. - */ } FCEUS; extern FCEUS FSettings; diff --git a/src/ines.c b/src/ines.c index 0c92e30..ca7f2bc 100644 --- a/src/ines.c +++ b/src/ines.c @@ -1067,8 +1067,7 @@ int iNESLoad(const char *name, FCEUFILE *fp) { * 1: RP2C07 ("Licensed PAL NES") * 2: Multiple-region * 3: UMC 6527P ("Dendy") */ - if (iNESCart.region == 3) - FSettings.dendy = 1; + if (iNESCart.region == 3) dendy = 1; FCEUI_SetVidSystem((iNESCart.region == 1) ? 1 : 0); return 1; diff --git a/src/input.h b/src/input.h index 1ab1e39..82061bc 100644 --- a/src/input.h +++ b/src/input.h @@ -29,6 +29,4 @@ extern void (*InputScanlineHook)(uint8 *bg, uint8 *spr, uint32 linets, int final void FCEU_DoSimpleCommand(int cmd); -void FCEU_ZapperSetTolerance(int t); - #endif diff --git a/src/ppu.c b/src/ppu.c index b6ae1c5..45ccc7f 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -32,6 +32,7 @@ #include "general.h" #include "fceu-endian.h" #include "fceu-memory.h" +#include "ppuview.h" #include "cart.h" #include "palette.h" @@ -63,8 +64,6 @@ static uint32 ppulut1[256]; static uint32 ppulut2[256]; static uint32 ppulut3[128]; -FCEU_PPU ppu; - static void makeppulut(void) { int x; int y; @@ -661,7 +660,7 @@ static void DoLine(void) uint8 *target = NULL; uint8 *dtarget = NULL; - if (scanline >= 240 && scanline != ppu.totalscanlines) + if (scanline >= 240 && scanline != totalscanlines) { X6502_Run(256 + 69); scanline++; @@ -1067,7 +1066,7 @@ static void CopySprites(uint8 *target) { void FCEUPPU_SetVideoSystem(int w) { if (w) { - scanlines_per_frame = FSettings.dendy ? 262 : 312; + scanlines_per_frame = dendy ? 262 : 312; FSettings.FirstSLine = FSettings.UsrFirstSLine[1]; FSettings.LastSLine = FSettings.UsrLastSLine[1]; } else { @@ -1167,11 +1166,11 @@ int FCEUPPU_Loop(int skip) { TriggerNMI(); } X6502_Run((scanlines_per_frame - 242) * (256 + 85) - 12); - if (ppu.overclock_enabled && ppu.vblankscanlines) { - if (!DMC_7bit || !ppu.skip_7bit_overclocking) { - overclocking = 1; - X6502_Run(ppu.vblankscanlines * (256 + 85) - 12); - overclocking = 0; + if (overclock_enabled && vblankscanlines) { + if (!DMC_7bit || !skip_7bit_overclocking) { + overclocked = 1; + X6502_Run(vblankscanlines * (256 + 85) - 12); + overclocked = 0; } } PPU_status &= 0x1f; @@ -1204,7 +1203,7 @@ int FCEUPPU_Loop(int skip) { kook ^= 1; } if (GameInfo->type == GIT_NSF) - X6502_Run((256 + 85) * ppu.normal_scanlines); + X6502_Run((256 + 85) * normal_scanlines); #ifdef FRAMESKIP else if (skip) { int y; @@ -1235,20 +1234,21 @@ int FCEUPPU_Loop(int skip) { deemp = PPU[1] >> 5; /* manual samples can't play correctly with overclocking */ - if (DMC_7bit && ppu.skip_7bit_overclocking) - ppu.totalscanlines = ppu.normal_scanlines; + if (DMC_7bit && skip_7bit_overclocking) + totalscanlines = normal_scanlines; else - ppu.totalscanlines = ppu.normal_scanlines + (ppu.overclock_enabled ? ppu.extrascanlines : 0); + totalscanlines = normal_scanlines + (overclock_enabled ? extrascanlines : 0); - for (scanline = 0; scanline < ppu.totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ + for (scanline = 0; scanline < totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ deempcnt[deemp]++; + /* if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1); */ DoLine(); - if (scanline < ppu.normal_scanlines || scanline == ppu.totalscanlines) - overclocking = 0; + if (scanline < normal_scanlines || scanline == totalscanlines) + overclocked = 0; else { - if (DMC_7bit && ppu.skip_7bit_overclocking) /* 7bit sample started after 240th line */ + if (DMC_7bit && skip_7bit_overclocking) /* 7bit sample started after 240th line */ break; - overclocking = 1; + overclocked = 1; } } diff --git a/src/ppu.h b/src/ppu.h index 829de71..96338a1 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -1,18 +1,6 @@ #ifndef _FCEU_PPU_H #define _FCEU_PPU_H -typedef struct { - /* PPU Overclocking */ - int overclock_enabled; /* 1 : enable, 0 : disable duh! */ - int skip_7bit_overclocking; /* 7-bit samples have priority over overclocking */ - int extrascanlines; - int vblankscanlines; - int normal_scanlines; /* 240 : normal, 290 : dendy */ - int totalscanlines; -} FCEU_PPU; - -extern FCEU_PPU ppu; - void FCEUPPU_Init(void); void FCEUPPU_Reset(void); void FCEUPPU_Power(void); @@ -28,8 +16,6 @@ extern void FP_FASTAPASS(1) (*PPU_hook)(uint32 A); extern uint8 NTARAM[0x800], *vnapage[4]; extern uint8 PPUNTARAM; extern uint8 PPUCHRRAM; -extern uint8 PALRAM[0x20]; -extern uint8 SPRAM[0x100]; void FCEUPPU_SaveState(void); void FCEUPPU_LoadState(int version); diff --git a/src/ppuview.h b/src/ppuview.h new file mode 100644 index 0000000..740a183 --- /dev/null +++ b/src/ppuview.h @@ -0,0 +1,13 @@ +#ifndef _FCEU_PPUVIEW_H +#define _FCEU_PPUVIEW_H + +extern int PPUViewScanline; +extern int PPUViewer; +extern int scanline; + +void PPUViewDoBlit(); +void DoPPUView(); +void UpdatePPUView(int refreshchr); + + +#endif diff --git a/src/sound.c b/src/sound.c index a72f93a..a483d16 100644 --- a/src/sound.c +++ b/src/sound.c @@ -61,7 +61,7 @@ typedef struct { int reloaddec; } ENVUNIT; -uint32 DMC_7bit = 0; /* used to skip overclocking */ +unsigned DMC_7bit = 0; /* used to skip overclocking */ static ENVUNIT EnvUnits[3]; static const int RectDuties[4] = { 1, 2, 4, 6 }; @@ -195,7 +195,7 @@ static DECLFW(Write_PSG) { DoSQ1(); EnvUnits[0].Mode = (V & 0x30) >> 4; EnvUnits[0].Speed = (V & 0xF); - if (FSettings.swapDuty) + if (swapDuty) V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1); break; case 0x1: @@ -216,7 +216,7 @@ static DECLFW(Write_PSG) { DoSQ2(); EnvUnits[1].Mode = (V & 0x30) >> 4; EnvUnits[1].Speed = (V & 0xF); - if (FSettings.swapDuty) + if (swapDuty) V = (V & 0x3F) | ((V & 0x80) >> 1) | ((V & 0x40) << 1); break; case 0x5: diff --git a/src/sound.h b/src/sound.h index d10a56a..c4413cc 100644 --- a/src/sound.h +++ b/src/sound.h @@ -50,7 +50,6 @@ extern int32 Wave[2048 + 512]; extern int32 WaveFinal[2048 + 512]; extern int32 WaveHi[]; extern uint32 soundtsinc; -extern uint32 DMC_7bit; extern uint32 soundtsoffs; #define SOUNDTS (sound_timestamp + soundtsoffs) diff --git a/src/video.c b/src/video.c index 80da854..0017fc1 100644 --- a/src/video.c +++ b/src/video.c @@ -37,6 +37,7 @@ uint8 *XBuf = NULL; uint8 *XDBuf = NULL; +int show_crosshair = 0; void FCEU_KillVirtualVideo(void) { @@ -52,15 +53,15 @@ int FCEU_InitVirtualVideo(void) { /* 256 bytes per scanline, * 240 scanline maximum, +8 for alignment, */ if (!XBuf) - XBuf = (uint8*)(FCEU_malloc(256 * (256 + ppu.extrascanlines + 8))); + XBuf = (uint8*)(FCEU_malloc(256 * (256 + extrascanlines + 8))); if (!XDBuf) - XDBuf = (uint8*)(FCEU_malloc(256 * (256 + ppu.extrascanlines + 8))); + XDBuf = (uint8*)(FCEU_malloc(256 * (256 + extrascanlines + 8))); if (!XBuf || !XDBuf) return 0; - memset(XBuf, 128, 256 * (256 + ppu.extrascanlines + 8)); - memset(XDBuf, 128, 256 * (256 + ppu.extrascanlines + 8)); + memset(XBuf, 128, 256 * (256 + extrascanlines + 8)); + memset(XDBuf, 128, 256 * (256 + extrascanlines + 8)); return 1; } @@ -81,7 +82,7 @@ void FCEU_PutImage(void) FCEU_VSUniDraw(XBuf); } if (howlong) howlong--; - if (FSettings.show_crosshair) + if (show_crosshair) FCEU_DrawInput(XBuf); } diff --git a/src/video.h b/src/video.h index b98a419..9eef95b 100644 --- a/src/video.h +++ b/src/video.h @@ -6,6 +6,7 @@ void FCEU_KillVirtualVideo(void); int SaveSnapshot(void); extern uint8 *XBuf; extern uint8 *XDBuf; +extern int show_crosshair; void FCEU_DrawNumberRow(uint8 *XBuf, int *nstatus, int cur); #endif diff --git a/src/x6502.c b/src/x6502.c index 0d00377..b8bf2d9 100644 --- a/src/x6502.c +++ b/src/x6502.c @@ -34,7 +34,6 @@ void (*X6502_Run)(int32 cycles); uint32 timestamp; uint32 sound_timestamp; -uint32 overclocking = 0; void FP_FASTAPASS(1) (*MapIRQHook)(int a); #define _PC X.PC @@ -55,7 +54,7 @@ void FP_FASTAPASS(1) (*MapIRQHook)(int a); _tcount += __x; \ _count -= __x * 48; \ timestamp += __x; \ - if (!overclocking) sound_timestamp += __x; \ + if (!overclocked) sound_timestamp += __x; \ } static INLINE uint8 RdMemNorm(uint32 A) { @@ -517,7 +516,7 @@ static void X6502_RunDebug(int32 cycles) { _tcount = 0; if (MapIRQHook) MapIRQHook(temp); - if (!overclocking) + if (!overclocked) FCEU_SoundCPUHook(temp); _PC++; @@ -614,7 +613,7 @@ void X6502_Run(int32 cycles) temp = _tcount; _tcount = 0; if (MapIRQHook) MapIRQHook(temp); - if (!overclocking) + if (!overclocked) FCEU_SoundCPUHook(temp); X.PC = pbackus; _PC++; diff --git a/src/x6502.h b/src/x6502.h index d9d8b65..f480544 100644 --- a/src/x6502.h +++ b/src/x6502.h @@ -35,7 +35,6 @@ void X6502_Run(int32 cycles); extern uint32 timestamp; extern uint32 sound_timestamp; -extern uint32 overclocking; extern X6502 X; #define N_FLAG 0x80 @@ -49,7 +48,7 @@ extern X6502 X; extern void FP_FASTAPASS(1) (*MapIRQHook)(int a); -#define NTSC_CPU (FSettings.dendy ? 1773447.467 : 1789772.7272727272727272) +#define NTSC_CPU (dendy ? 1773447.467 : 1789772.7272727272727272) #define PAL_CPU 1662607.125 #define FCEU_IQEXT 0x001 From e154706586d523dbd33f8793872d4c7a013bfaf0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 5 Jun 2021 20:56:49 +0200 Subject: [PATCH 127/295] Some cleanups + we don't need a non-libretro codepath --- src/driver.h | 7 ------- src/drivers/libretro/libretro.c | 11 +---------- src/fceu-types.h | 4 ---- src/fceu.h | 1 - src/file.h | 10 ---------- src/ppu.c | 2 -- src/ppuview.h | 13 ------------- 7 files changed, 1 insertion(+), 47 deletions(-) delete mode 100644 src/ppuview.h diff --git a/src/driver.h b/src/driver.h index 196c733..6c83d97 100644 --- a/src/driver.h +++ b/src/driver.h @@ -101,12 +101,7 @@ void FCEUI_DisableSpriteLimitation(int a); /* -1 = no change, 0 = show, 1 = hide, 2 = internal toggle */ void FCEUI_SetRenderDisable(int sprites, int bg); -#ifdef __LIBRETRO__ FCEUGI *FCEUI_LoadGame(const char *name, uint8_t *buf, size_t bufsize); -#else -/* name=path and file to load. returns 0 on failure, 1 on success */ -FCEUGI *FCEUI_LoadGame(const char *name); -#endif #ifdef COPYFAMI /* Fake UNIF board to start new CFHI instance */ @@ -149,9 +144,7 @@ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall); below this directory. */ void FCEUI_SetBaseDirectory(char *dir); -#ifdef __LIBRETRO__ void FCEUI_SetSaveDirectory(char *sav_dir); -#endif /* Tells FCE Ultra to copy the palette data pointed to by pal and use it. diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 39263fc..8c606fd 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -188,9 +188,6 @@ static uint32_t Dummy = 0; static uint32_t current_palette = 0; static unsigned serialize_size; -int PPUViewScanline=0; -int PPUViewer=0; - /* extern forward decls.*/ extern FCEUGI *GameInfo; extern uint8 *XBuf; @@ -201,8 +198,6 @@ extern int option_ramstate; /* emulator-specific callback functions */ -void UpdatePPUView(int refreshchr) { } - const char * GetKeyboard(void) { return ""; @@ -288,9 +283,6 @@ void FCEUD_DispMessage(char *m) environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, &msg); } -void FCEUD_NetworkClose(void) -{ } - void FCEUD_SoundToggle (void) { FCEUI_SetSoundVolume(sndvolume); @@ -300,8 +292,7 @@ FILE *FCEUD_UTF8fopen(const char *n, const char *m) { if (n) return fopen(n, m); - else - return NULL; + return NULL; } /*palette for FCEU*/ diff --git a/src/fceu-types.h b/src/fceu-types.h index 86def23..9327c9b 100644 --- a/src/fceu-types.h +++ b/src/fceu-types.h @@ -22,11 +22,7 @@ #ifndef __FCEU_TYPES_H #define __FCEU_TYPES_H -#ifdef __LIBRETRO__ #include -#else -#include -#endif typedef int8_t int8; typedef int16_t int16; typedef int32_t int32; diff --git a/src/fceu.h b/src/fceu.h index f97b425..2831997 100644 --- a/src/fceu.h +++ b/src/fceu.h @@ -81,7 +81,6 @@ extern uint8 PAL; typedef struct { int PAL; - int NetworkPlay; int SoundVolume; int TriangleVolume; int SquareVolume[2]; diff --git a/src/file.h b/src/file.h index a992a66..7035e8f 100644 --- a/src/file.h +++ b/src/file.h @@ -1,28 +1,18 @@ #ifndef _FCEU_FILE_H #define _FCEU_FILE_H -#ifdef __LIBRETRO__ typedef struct { uint8 *data; uint32 size; uint32 location; } MEMWRAP; -#endif typedef struct { -#ifdef __LIBRETRO__ MEMWRAP *fp; -#else - void *fp; /* FILE* or ptr to ZIPWRAP */ -#endif uint32 type; /* 0=normal file, 1=gzip, 2=zip */ } FCEUFILE; -#ifdef __LIBRETRO__ FCEUFILE *FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext, uint8 *buffer, size_t bufsize); -#else -FCEUFILE *FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext); -#endif int FCEU_fclose(FCEUFILE*); uint64 FCEU_fread(void *ptr, size_t size, size_t nmemb, FCEUFILE*); uint64 FCEU_fwrite(void *ptr, size_t size, size_t nmemb, FCEUFILE*); diff --git a/src/ppu.c b/src/ppu.c index 45ccc7f..f3ea2a1 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -32,7 +32,6 @@ #include "general.h" #include "fceu-endian.h" #include "fceu-memory.h" -#include "ppuview.h" #include "cart.h" #include "palette.h" @@ -1241,7 +1240,6 @@ int FCEUPPU_Loop(int skip) { for (scanline = 0; scanline < totalscanlines; ) { /* scanline is incremented in DoLine. Evil. :/ */ deempcnt[deemp]++; - /* if ((PPUViewer) && (scanline == PPUViewScanline)) UpdatePPUView(1); */ DoLine(); if (scanline < normal_scanlines || scanline == totalscanlines) overclocked = 0; diff --git a/src/ppuview.h b/src/ppuview.h deleted file mode 100644 index 740a183..0000000 --- a/src/ppuview.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _FCEU_PPUVIEW_H -#define _FCEU_PPUVIEW_H - -extern int PPUViewScanline; -extern int PPUViewer; -extern int scanline; - -void PPUViewDoBlit(); -void DoPPUView(); -void UpdatePPUView(int refreshchr); - - -#endif From 3dbf430262a1f2606ba79eff489fddf6d1775e96 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 5 Jun 2021 21:07:55 +0200 Subject: [PATCH 128/295] Wrap all fopen access - go through FCEUD_UTF8fopen isntead --- src/boards/copyfami_hwi.c | 4 ++-- src/drivers/libretro/libretro.c | 3 ++- src/file.c | 8 +------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/boards/copyfami_hwi.c b/src/boards/copyfami_hwi.c index 72a05af..7660c61 100644 --- a/src/boards/copyfami_hwi.c +++ b/src/boards/copyfami_hwi.c @@ -173,7 +173,7 @@ static int32 FetchNewCHRBank(int32 slot) { CHR1KGetCmd[1] = slot << 2; SENDGET(CHR1KGetCmd, chr_data.buf[bank * 1024], 1024); sprintf(name, "%04x.chr", bank); - ofile = fopen(name, "wb"); + ofile = FCEUD_UTF8fopen(name, "wb"); fwrite((void*)&chr_data.buf[bank * 1024], 1, 1024, ofile); fclose(ofile); return bank; @@ -186,7 +186,7 @@ static int32 FetchNewPRGBank(int32 slot) { PRG8KGetCmd[1] = 0x80 + (slot << 5); SENDGET(PRG8KGetCmd, prg_data.buf[bank * 8192], 8192); sprintf(name, "%04x.prg", bank); - ofile = fopen(name, "wb"); + ofile = FCEUD_UTF8fopen(name, "wb"); fwrite((void*)&prg_data.buf[bank * 8192], 1, 8192, ofile); fclose(ofile); return bank; diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 8c606fd..ebc86b4 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -291,7 +292,7 @@ void FCEUD_SoundToggle (void) FILE *FCEUD_UTF8fopen(const char *n, const char *m) { if (n) - return fopen(n, m); + return fopen_utf8(n, m); return NULL; } diff --git a/src/file.c b/src/file.c index fc05ea1..b210e18 100644 --- a/src/file.c +++ b/src/file.c @@ -34,12 +34,6 @@ #include "driver.h" #include "general.h" -#include "compat/fopen_utf8.h" - -#ifndef __GNUC__ - #define strcasecmp strcmp -#endif - static MEMWRAP *MakeMemWrap(void *tz, int type) { MEMWRAP *tmp; @@ -87,7 +81,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, fceufp->fp = MakeMemWrapBuffer(buffer, bufsize); else { - void *t = fopen_utf8(path, mode); + void *t = FCEUD_UTF8fopen(path, mode); if (!t) { From 2b187732ea6122cd370392e313f1a8a4b48ae68a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 5 Jun 2021 21:11:41 +0200 Subject: [PATCH 129/295] Get rid of obsolete variable --- src/drivers/libretro/libretro.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index ebc86b4..cf226c7 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -165,8 +165,6 @@ static unsigned opt_region = 0; static unsigned opt_showAdvSoundOptions = 0; static unsigned opt_showAdvSystemOptions = 0; -int FCEUnetplay; - #if defined(PSP) || defined(PS2) static __attribute__((aligned(16))) uint16_t retro_palette[256]; #else From 6e1dd7cde1062eef219b528156a6d25694fc898a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 5 Jun 2021 21:13:51 +0200 Subject: [PATCH 130/295] Cleanup --- src/video.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/video.c b/src/video.c index 0017fc1..a7896cc 100644 --- a/src/video.c +++ b/src/video.c @@ -65,9 +65,6 @@ int FCEU_InitVirtualVideo(void) return 1; } -static int howlong; -static char errmsg[65]; - #include "drawing.h" void FCEUI_SaveSnapshot(void) { } @@ -81,7 +78,6 @@ void FCEU_PutImage(void) if (GameInfo->type == GIT_VSUNI) FCEU_VSUniDraw(XBuf); } - if (howlong) howlong--; if (show_crosshair) FCEU_DrawInput(XBuf); } @@ -93,18 +89,17 @@ void FCEU_PutImageDummy(void) void FCEU_DispMessage(char *format, ...) { va_list ap; + static char errmsg[65]; va_start(ap, format); vsprintf(errmsg, format, ap); va_end(ap); - howlong = 180; FCEUD_DispMessage(errmsg); } void FCEU_ResetMessages(void) { - howlong = 180; } int SaveSnapshot(void) From 36e38000eff608c29a22756f7dac02ade6caf2cd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 5 Jun 2021 21:15:36 +0200 Subject: [PATCH 131/295] Remove unused functions --- src/drawing.h | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/src/drawing.h b/src/drawing.h index 6a8a4f4..110dd48 100644 --- a/src/drawing.h +++ b/src/drawing.h @@ -1,32 +1,6 @@ #ifndef _FCEU_DRAWING_H #define _FCEU_DRAWING_H -void DrawTextLineBG(uint8 *dest) { - int x, y; - static int otable[7] = { 81, 49, 30, 17, 8, 3, 0 }; - for (y = 0; y < 14; y++) { - int offs; - - if (y >= 7) offs = otable[13 - y]; - else offs = otable[y]; - - for (x = offs; x < (256 - offs); x++) - dest[y * 256 + x] = (dest[y * 256 + x] & 0x0f) | 0xC0; - } -} - -static void DrawMessage(void) { - if (howlong) { - uint8 *t; - howlong--; - t = XBuf + (FSettings.LastSLine - 16) * 256; - if (t >= XBuf) { - DrawTextLineBG(t); - DrawTextTrans(t + 256 * 3 + (128 - strlen(errmsg) * 4), 256, (uint8*)errmsg, 4); - } - } -} - uint8 fontdata2[2048] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x81,0xa5,0x81,0xbd,0x99,0x81,0x7e,0x7e,0xff,0xdb,0xff,0xc3,0xe7,0xff,0x7e,0x36,0x7f,0x7f,0x7f,0x3e,0x1c,0x08,0x00, From 84bb7c4e9d12d0392c6d4f63160721d97f9a7d08 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 6 Jun 2021 01:53:33 +0200 Subject: [PATCH 132/295] Cleanup --- src/ines.c | 367 ++++++++++++++++++++++++++++------------------------- 1 file changed, 193 insertions(+), 174 deletions(-) diff --git a/src/ines.c b/src/ines.c index ca7f2bc..f903018 100644 --- a/src/ines.c +++ b/src/ines.c @@ -851,226 +851,245 @@ static void rom_load_ines2(void) { if (head.CHRRAM_size & 0xF0) iNESCart.CHRRamSaveSize = 64 << ((head.CHRRAM_size >> 4) & 0x0F); } -int iNESLoad(const char *name, FCEUFILE *fp) { - const char *tv_region[] = { "NTSC", "PAL", "Multi-region", "Dendy" }; - struct md5_context md5; +int iNESLoad(const char *name, FCEUFILE *fp) +{ + const char *tv_region[] = { "NTSC", "PAL", "Multi-region", "Dendy" }; + struct md5_context md5; #ifdef DEBUG - char* mappername = NULL; - uint32 mappertest = 0; + char* mappername = NULL; + uint32 mappertest = 0; #endif - uint64 filesize = FCEU_fgetsize(fp); - uint64 romSize = 0; - /* used for malloc and cart mapping */ - uint32 rom_size_pow2 = 0; - uint32 vrom_size_pow2 = 0; + uint64 filesize = FCEU_fgetsize(fp); + uint64 romSize = 0; + /* used for malloc and cart mapping */ + uint32 rom_size_pow2 = 0; + uint32 vrom_size_pow2 = 0; - if (FCEU_fread(&head, 1, 16, fp) != 16) - return 0; + if (FCEU_fread(&head, 1, 16, fp) != 16) + return 0; - filesize -= 16; /* remove header size from total size */ + filesize -= 16; /* remove header size from total size */ - if (memcmp(&head, "NES\x1a", 4)) { - FCEU_PrintError("Not an iNES file!\n"); - return 0; - } + if (memcmp(&head, "NES\x1a", 4)) + { + FCEU_PrintError("Not an iNES file!\n"); + return 0; + } - memset(&iNESCart, 0, sizeof(iNESCart)); + memset(&iNESCart, 0, sizeof(iNESCart)); - if (!memcmp((char*)(&head) + 0x7, "DiskDude", 8)) { - memset((char*)(&head) + 0x7, 0, 0x9); - } + if (!memcmp((char*)(&head) + 0x7, "DiskDude", 8)) + memset((char*)(&head) + 0x7, 0, 0x9); - if (!memcmp((char*)(&head) + 0x7, "demiforce", 9)) { - memset((char*)(&head) + 0x7, 0, 0x9); - } + if (!memcmp((char*)(&head) + 0x7, "demiforce", 9)) + memset((char*)(&head) + 0x7, 0, 0x9); - if (!memcmp((char*)(&head) + 0xA, "Ni03", 4)) { - if (!memcmp((char*)(&head) + 0x7, "Dis", 3)) - memset((char*)(&head) + 0x7, 0, 0x9); - else - memset((char*)(&head) + 0xA, 0, 0x6); - } + if (!memcmp((char*)(&head) + 0xA, "Ni03", 4)) + { + if (!memcmp((char*)(&head) + 0x7, "Dis", 3)) + memset((char*)(&head) + 0x7, 0, 0x9); + else + memset((char*)(&head) + 0xA, 0, 0x6); + } - iNESCart.iNES2 = get_ines_version(); + if ((iNESCart.iNES2 = get_ines_version())) + rom_load_ines2(); + else + rom_load_ines(); - if (!iNESCart.iNES2) - rom_load_ines(); - else - rom_load_ines2(); + if (!ROM_size) + ROM_size = 256; - if (!ROM_size) - ROM_size = 256; + /* Trainer */ + if (head.ROM_type & 4) + { + trainerpoo = (uint8*)FCEU_gmalloc(512); + FCEU_fread(trainerpoo, 512, 1, fp); + filesize -= 512; + } - /* Trainer */ - if (head.ROM_type & 4) { - trainerpoo = (uint8*)FCEU_gmalloc(512); - FCEU_fread(trainerpoo, 512, 1, fp); - filesize -= 512; - } + romSize = (ROM_size * 0x4000) + (VROM_size * 0x2000); - romSize = (ROM_size * 0x4000) + (VROM_size * 0x2000); + if (romSize > filesize) + { + FCEU_PrintError(" File length is too short to contain all data reported from header by %llu\n", romSize - filesize); + } + else if (romSize < filesize) + FCEU_PrintError(" File contains %llu bytes of unused data\n", filesize - romSize); - if (romSize > filesize) { - FCEU_PrintError(" File length is too short to contain all data reported from header by %llu\n", romSize - filesize); - } else if (romSize < filesize) - FCEU_PrintError(" File contains %llu bytes of unused data\n", filesize - romSize); + rom_size_pow2 = uppow2(ROM_size) * 0x4000; - rom_size_pow2 = uppow2(ROM_size) * 0x4000; + if ((ROM = (uint8*)FCEU_malloc(rom_size_pow2)) == NULL) + return 0; - if ((ROM = (uint8*)FCEU_malloc(rom_size_pow2)) == NULL) - return 0; + memset(ROM, 0xFF, rom_size_pow2); + FCEU_fread(ROM, 0x4000, ROM_size, fp); - memset(ROM, 0xFF, rom_size_pow2); - FCEU_fread(ROM, 0x4000, ROM_size, fp); + if (VROM_size) + { + vrom_size_pow2 = uppow2(VROM_size) * 0x2000; - if (VROM_size) { - vrom_size_pow2 = uppow2(VROM_size) * 0x2000; + if ((VROM = (uint8*)FCEU_malloc(vrom_size_pow2)) == NULL) + { + free(ROM); + ROM = NULL; + return 0; + } - if ((VROM = (uint8*)FCEU_malloc(vrom_size_pow2)) == NULL) { - free(ROM); - ROM = NULL; - return 0; - } + memset(VROM, 0xFF, vrom_size_pow2); + FCEU_fread(VROM, 0x2000, VROM_size, fp); + } - memset(VROM, 0xFF, vrom_size_pow2); - FCEU_fread(VROM, 0x2000, VROM_size, fp); - } + iNESCart.PRGRomSize = ROM_size * 0x4000; + iNESCart.CHRRomSize = VROM_size * 0x2000; - iNESCart.PRGRomSize = ROM_size * 0x4000; - iNESCart.CHRRomSize = VROM_size * 0x2000; + iNESCart.PRGCRC32 = CalcCRC32(0, ROM, ROM_size * 0x4000); + iNESCart.CHRCRC32 = CalcCRC32(0, VROM, VROM_size * 0x2000); + iNESCart.CRC32 = CalcCRC32(iNESCart.PRGCRC32, VROM, VROM_size * 0x2000); - iNESCart.PRGCRC32 = CalcCRC32(0, ROM, ROM_size * 0x4000); - iNESCart.CHRCRC32 = CalcCRC32(0, VROM, VROM_size * 0x2000); - iNESCart.CRC32 = CalcCRC32(iNESCart.PRGCRC32, VROM, VROM_size * 0x2000); + md5_starts(&md5); + md5_update(&md5, ROM, ROM_size * 0x4000); + if (VROM_size) + md5_update(&md5, VROM, VROM_size * 0x2000); + md5_finish(&md5, iNESCart.MD5); - md5_starts(&md5); - md5_update(&md5, ROM, ROM_size * 0x4000); - if (VROM_size) - md5_update(&md5, VROM, VROM_size * 0x2000); - md5_finish(&md5, iNESCart.MD5); - - memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5)); + memcpy(&GameInfo->MD5, &iNESCart.MD5, sizeof(iNESCart.MD5)); #ifdef DEBUG - mappername = "Not Listed"; + mappername = "Not Listed"; - for (mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) { - if (bmap[mappertest].number == iNESCart.mapper) { - mappername = (char*)bmap[mappertest].name; - break; - } - } + for (mappertest = 0; mappertest < (sizeof bmap / sizeof bmap[0]) - 1; mappertest++) + { + if (bmap[mappertest].number == iNESCart.mapper) + { + mappername = (char*)bmap[mappertest].name; + break; + } + } #endif - if (iNESCart.iNES2 == 0) { - 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; - } - } + if (iNESCart.iNES2 == 0) { + 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; + } + } #ifdef DEBUG - FCEU_printf(" PRG-ROM CRC32: 0x%08X\n", iNESCart.PRGCRC32); - FCEU_printf(" PRG+CHR CRC32: 0x%08X\n", iNESCart.CRC32); - FCEU_printf(" PRG+CHR MD5: 0x%s\n", md5_asciistr(iNESCart.MD5)); - FCEU_printf(" PRG-ROM: %3d x 16KiB\n", ROM_size); - FCEU_printf(" CHR-ROM: %3d x 8KiB\n", VROM_size); - FCEU_printf(" Mapper #: %3d\n", iNESCart.mapper); - FCEU_printf(" Mapper name: %s\n", mappername); - FCEU_printf(" Mirroring: %s\n", iNESCart.mirror == 2 ? "None (Four-screen)" : iNESCart.mirror ? "Vertical" : "Horizontal"); - FCEU_printf(" Battery: %s\n", (head.ROM_type & 2) ? "Yes" : "No"); - FCEU_printf(" System: %s\n", tv_region[iNESCart.region]); - FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); + FCEU_printf(" PRG-ROM CRC32: 0x%08X\n", iNESCart.PRGCRC32); + FCEU_printf(" PRG+CHR CRC32: 0x%08X\n", iNESCart.CRC32); + FCEU_printf(" PRG+CHR MD5: 0x%s\n", md5_asciistr(iNESCart.MD5)); + FCEU_printf(" PRG-ROM: %3d x 16KiB\n", ROM_size); + FCEU_printf(" CHR-ROM: %3d x 8KiB\n", VROM_size); + FCEU_printf(" Mapper #: %3d\n", iNESCart.mapper); + FCEU_printf(" Mapper name: %s\n", mappername); + FCEU_printf(" Mirroring: %s\n", iNESCart.mirror == 2 ? "None (Four-screen)" : iNESCart.mirror ? "Vertical" : "Horizontal"); + FCEU_printf(" Battery: %s\n", (head.ROM_type & 2) ? "Yes" : "No"); + FCEU_printf(" System: %s\n", tv_region[iNESCart.region]); + FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); + + if (iNESCart.iNES2) + { + unsigned PRGRAM = iNESCart.PRGRamSize + iNESCart.PRGRamSaveSize; + unsigned CHRRAM = iNESCart.CHRRamSize + iNESCart.CHRRamSaveSize; + + FCEU_printf(" NES 2.0 extended iNES.\n"); + FCEU_printf(" Sub Mapper #: %3d\n", iNESCart.submapper); + if (PRGRAM || CHRRAM) + { + if (head.ROM_type & 0x02) + { + FCEU_printf(" PRG RAM: %d KB (%d KB battery-backed)\n", PRGRAM / 1024, iNESCart.PRGRamSaveSize / 1024); + FCEU_printf(" CHR RAM: %d KB (%d KB battery-backed)\n", CHRRAM / 1024, iNESCart.CHRRamSaveSize / 1024); + } + else + { + FCEU_printf(" PRG RAM: %d KB\n", PRGRAM / 1024); + FCEU_printf(" CHR RAM: %d KB\n", CHRRAM / 1024); + } + } + } #endif - if (iNESCart.iNES2) { - unsigned PRGRAM = iNESCart.PRGRamSize + iNESCart.PRGRamSaveSize; - unsigned CHRRAM = iNESCart.CHRRamSize + iNESCart.CHRRamSaveSize; + ResetCartMapping(); + ResetExState(0, 0); - FCEU_printf(" NES 2.0 extended iNES.\n"); - FCEU_printf(" Sub Mapper #: %3d\n", iNESCart.submapper); - if (PRGRAM || CHRRAM) { - if (head.ROM_type & 0x02) { - FCEU_printf(" PRG RAM: %d KB (%d KB battery-backed)\n", PRGRAM / 1024, iNESCart.PRGRamSaveSize / 1024); - FCEU_printf(" CHR RAM: %d KB (%d KB battery-backed)\n", CHRRAM / 1024, iNESCart.CHRRamSaveSize / 1024); - } else { - FCEU_printf(" PRG RAM: %d KB\n", PRGRAM / 1024); - FCEU_printf(" CHR RAM: %d KB\n", CHRRAM / 1024); - } - } - } + SetupCartPRGMapping(0, ROM, rom_size_pow2, 0); - ResetCartMapping(); - ResetExState(0, 0); + SetInput(); + CheckHInfo(); - SetupCartPRGMapping(0, ROM, rom_size_pow2, 0); + { + int x; + uint64 partialmd5 = 0; + int mapper = iNESCart.mapper; + int mirroring = iNESCart.mirror; - SetInput(); - CheckHInfo(); + for (x = 0; x < 8; x++) + partialmd5 |= (uint64)iNESCart.MD5[7 - x] << (x * 8); - { - int x; - uint64 partialmd5 = 0; - int mapper = iNESCart.mapper; - int mirroring = iNESCart.mirror; + FCEU_VSUniCheck(partialmd5, &mapper, &mirroring); - for (x = 0; x < 8; x++) - partialmd5 |= (uint64)iNESCart.MD5[7 - x] << (x * 8); + if ((mapper != iNESCart.mapper) || (mirroring != iNESCart.mirror)) + { + FCEU_PrintError("\n"); + FCEU_PrintError(" Incorrect VS-Unisystem header information!\n"); + if (mapper != iNESCart.mapper) + FCEU_PrintError(" Mapper: %d\n", mapper); + if (mirroring != iNESCart.mirror) + FCEU_PrintError(" Mirroring: %s\n", + (mirroring == 2) ? "None (Four-screen)" : mirroring ? "Vertical" : "Horizontal"); + iNESCart.mapper = mapper; + iNESCart.mirror = mirroring; + } + } - FCEU_VSUniCheck(partialmd5, &mapper, &mirroring); + /* Must remain here because above functions might change value of + * VROM_size and free(VROM). + */ + if (VROM_size) + SetupCartCHRMapping(0, VROM, vrom_size_pow2, 0); - if ((mapper != iNESCart.mapper) || (mirroring != iNESCart.mirror)) { - FCEU_PrintError("\n"); - FCEU_PrintError(" Incorrect VS-Unisystem header information!\n"); - if (mapper != iNESCart.mapper) FCEU_PrintError(" Mapper: %d\n", mapper); - if (mirroring != iNESCart.mirror) FCEU_PrintError(" Mirroring: %s\n", - (mirroring == 2) ? "None (Four-screen)" : mirroring ? "Vertical" : "Horizontal"); - iNESCart.mapper = mapper; - iNESCart.mirror = mirroring; - } - } + if (iNESCart.mirror == 2) + { + ExtraNTARAM = (uint8*)FCEU_gmalloc(2048); + SetupCartMirroring(4, 1, ExtraNTARAM); + } + else if (iNESCart.mirror >= 0x10) + SetupCartMirroring(2 + (iNESCart.mirror & 1), 1, 0); + else + SetupCartMirroring(iNESCart.mirror & 1, (iNESCart.mirror & 4) >> 2, 0); - /* Must remain here because above functions might change value of - * VROM_size and free(VROM). - */ - if (VROM_size) - SetupCartCHRMapping(0, VROM, vrom_size_pow2, 0); + iNESCart.battery = (head.ROM_type & 2) ? 1 : 0; - if (iNESCart.mirror == 2) { - ExtraNTARAM = (uint8*)FCEU_gmalloc(2048); - SetupCartMirroring(4, 1, ExtraNTARAM); - } else if (iNESCart.mirror >= 0x10) - SetupCartMirroring(2 + (iNESCart.mirror & 1), 1, 0); - else - SetupCartMirroring(iNESCart.mirror & 1, (iNESCart.mirror & 4) >> 2, 0); + if (!iNES_Init(iNESCart.mapper)) + { + FCEU_printf("\n"); + FCEU_PrintError(" iNES mapper #%d is not supported at all.\n", + iNESCart.mapper); + return 0; + } - iNESCart.battery = (head.ROM_type & 2) ? 1 : 0; + GameInterface = iNESGI; - if (!iNES_Init(iNESCart.mapper)) { - FCEU_printf("\n"); - FCEU_PrintError(" iNES mapper #%d is not supported at all.\n", iNESCart.mapper); - return 0; - } + /* 0: RP2C02 ("NTSC NES") + * 1: RP2C07 ("Licensed PAL NES") + * 2: Multiple-region + * 3: UMC 6527P ("Dendy") */ + if (iNESCart.region == 3) + dendy = 1; + FCEUI_SetVidSystem((iNESCart.region == 1) ? 1 : 0); - GameInterface = iNESGI; - - /* 0: RP2C02 ("NTSC NES") - * 1: RP2C07 ("Licensed PAL NES") - * 2: Multiple-region - * 3: UMC 6527P ("Dendy") */ - if (iNESCart.region == 3) dendy = 1; - FCEUI_SetVidSystem((iNESCart.region == 1) ? 1 : 0); - - return 1; + return 1; } static int iNES_Init(int num) { From 8331b3c425b2ac45c32a6314d788595caa2dba60 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 6 Jun 2021 01:57:41 +0200 Subject: [PATCH 133/295] Cleanups --- src/fceu-memory.c | 6 ++---- src/ppu.h | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/fceu-memory.c b/src/fceu-memory.c index 6dfecfe..2b99dfb 100644 --- a/src/fceu-memory.c +++ b/src/fceu-memory.c @@ -28,8 +28,7 @@ void *FCEU_gmalloc(uint32 size) { - void *ret; - ret = malloc(size); + void *ret = malloc(size); if (!ret) { FCEU_PrintError("Error allocating memory! Doing a hard exit."); @@ -41,8 +40,7 @@ void *FCEU_gmalloc(uint32 size) void *FCEU_malloc(uint32 size) { - void *ret; - ret = (void*)malloc(size); + void *ret = (void*)malloc(size); if (!ret) { diff --git a/src/ppu.h b/src/ppu.h index 96338a1..e3f6cfd 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -6,7 +6,7 @@ void FCEUPPU_Reset(void); void FCEUPPU_Power(void); int FCEUPPU_Loop(int skip); -void FCEUPPU_LineUpdate(); +void FCEUPPU_LineUpdate(void); void FCEUPPU_SetVideoSystem(int w); extern void (*GameHBIRQHook)(void), (*GameHBIRQHook2)(void); From 658ef18d2e00a1123860f7c9d3546b5ce913f216 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 6 Jun 2021 02:02:46 +0200 Subject: [PATCH 134/295] Cleanups; turn some functions static --- src/ines.c | 270 +++++++++++++++++++++++++++-------------------------- 1 file changed, 138 insertions(+), 132 deletions(-) diff --git a/src/ines.c b/src/ines.c index f903018..72d8bdf 100644 --- a/src/ines.c +++ b/src/ines.c @@ -224,13 +224,16 @@ static struct BADINF BadROMImages[] = #include "ines-bad.h" }; -void CheckBad(uint64 md5partial) { +static void CheckBad(uint64 md5partial) +{ int32 x = 0; - while (BadROMImages[x].name) { - if (BadROMImages[x].md5partial == md5partial) { - FCEU_PrintError("The copy game you have loaded, \"%s\", is bad, and will not work properly in FCE Ultra.", BadROMImages[x].name); - return; - } + while (BadROMImages[x].name) + { + if (BadROMImages[x].md5partial == md5partial) + { + FCEU_PrintError("The copy game you have loaded, \"%s\", is bad, and will not work properly in FCE Ultra.", BadROMImages[x].name); + return; + } x++; } } @@ -247,148 +250,149 @@ struct CHINF { int32 extra; }; -static void CheckHInfo(void) { +static void CheckHInfo(void) +{ #define DEFAULT (-1) #define NOEXTRA (-1) -/* used for mirroring special overrides */ + /* used for mirroring special overrides */ #define MI_4 2 /* forced 4-screen mirroring */ #define DFAULT8 8 /* anything but hard-wired (4-screen) mirroring, mapper-controlled */ -/* tv system/region */ + /* tv system/region */ #define PAL 1 #define MULTI 2 #define DENDY 3 - static struct CHINF moo[] = - { - #include "ines-correct.h" - }; - int32 tofix = 0, x; - uint64 partialmd5 = 0; - int32 current_mapper = 0; - int32 cur_mirr = 0; + static struct CHINF moo[] = + { +#include "ines-correct.h" + }; + int32 tofix = 0, x; + uint64 partialmd5 = 0; + int32 current_mapper = 0; + int32 cur_mirr = 0; - for (x = 0; x < 8; x++) - partialmd5 |= (uint64)iNESCart.MD5[15 - x] << (x * 8); - CheckBad(partialmd5); + for (x = 0; x < 8; x++) + partialmd5 |= (uint64)iNESCart.MD5[15 - x] << (x * 8); + CheckBad(partialmd5); - x = 0; - do { - if (moo[x].crc32 == iNESCart.CRC32) { - if (moo[x].mapper >= 0) { - if (moo[x].extra >= 0 && moo[x].extra == 0x800 && VROM_size) { - VROM_size = 0; - free(VROM); - VROM = NULL; - tofix |= 8; - } - if (iNESCart.mapper != (moo[x].mapper & 0xFFF)) { - tofix |= 1; - current_mapper = iNESCart.mapper; - iNESCart.mapper = moo[x].mapper & 0xFFF; - } - } - if (moo[x].submapper >= 0) { - iNESCart.iNES2 = 1; - if (moo[x].submapper != iNESCart.submapper) { - iNESCart.submapper = moo[x].submapper; - } - } - if (moo[x].mirror >= 0) { - cur_mirr = iNESCart.mirror; - if (moo[x].mirror == 8) { - if (iNESCart.mirror == 2) { /* Anything but hard-wired(four screen). */ - tofix |= 2; - iNESCart.mirror = 0; - } - } else if (iNESCart.mirror != moo[x].mirror) { - if (iNESCart.mirror != (moo[x].mirror & ~4)) - if ((moo[x].mirror & ~4) <= 2) /* Don't complain if one-screen mirroring - needs to be set(the iNES header can't - hold this information). - */ - tofix |= 2; - iNESCart.mirror = moo[x].mirror; - } - } - if (moo[x].battery >= 0) { - if (!(head.ROM_type & 2) && (moo[x].battery != 0)) { - tofix |= 4; - head.ROM_type |= 2; - } - } - if (moo[x].region >= 0) { - if (iNESCart.region != moo[x].region) { - tofix |= 16; - iNESCart.region = moo[x].region; - } - } + x = 0; + do { + if (moo[x].crc32 == iNESCart.CRC32) { + if (moo[x].mapper >= 0) { + if (moo[x].extra >= 0 && moo[x].extra == 0x800 && VROM_size) { + VROM_size = 0; + free(VROM); + VROM = NULL; + tofix |= 8; + } + if (iNESCart.mapper != (moo[x].mapper & 0xFFF)) { + tofix |= 1; + current_mapper = iNESCart.mapper; + iNESCart.mapper = moo[x].mapper & 0xFFF; + } + } + if (moo[x].submapper >= 0) { + iNESCart.iNES2 = 1; + if (moo[x].submapper != iNESCart.submapper) { + iNESCart.submapper = moo[x].submapper; + } + } + if (moo[x].mirror >= 0) { + cur_mirr = iNESCart.mirror; + if (moo[x].mirror == 8) { + if (iNESCart.mirror == 2) { /* Anything but hard-wired(four screen). */ + tofix |= 2; + iNESCart.mirror = 0; + } + } else if (iNESCart.mirror != moo[x].mirror) { + if (iNESCart.mirror != (moo[x].mirror & ~4)) + if ((moo[x].mirror & ~4) <= 2) /* Don't complain if one-screen mirroring + needs to be set(the iNES header can't + hold this information). + */ + tofix |= 2; + iNESCart.mirror = moo[x].mirror; + } + } + if (moo[x].battery >= 0) { + if (!(head.ROM_type & 2) && (moo[x].battery != 0)) { + tofix |= 4; + head.ROM_type |= 2; + } + } + if (moo[x].region >= 0) { + if (iNESCart.region != moo[x].region) { + tofix |= 16; + iNESCart.region = moo[x].region; + } + } - if (moo[x].prgram >= 0) { - tofix |= 32; - iNESCart.iNES2 = 1; - iNESCart.PRGRamSize = (moo[x].prgram & 0x0F) ? (64 << ((moo[x].prgram >> 0) & 0xF)) : 0; - iNESCart.PRGRamSaveSize = (moo[x].prgram & 0xF0) ? (64 << ((moo[x].prgram >> 4) & 0xF)) : 0; - } + if (moo[x].prgram >= 0) { + tofix |= 32; + iNESCart.iNES2 = 1; + iNESCart.PRGRamSize = (moo[x].prgram & 0x0F) ? (64 << ((moo[x].prgram >> 0) & 0xF)) : 0; + iNESCart.PRGRamSaveSize = (moo[x].prgram & 0xF0) ? (64 << ((moo[x].prgram >> 4) & 0xF)) : 0; + } - if (moo[x].chrram >= 0) { - tofix |= 32; - iNESCart.iNES2 = 1; - iNESCart.CHRRamSize = (moo[x].chrram & 0x0F) ? (64 << ((moo[x].chrram >> 0) & 0xF)) : 0; - iNESCart.CHRRamSaveSize = (moo[x].chrram & 0xF0) ? (64 << ((moo[x].chrram >> 4) & 0xF)) : 0; - } + if (moo[x].chrram >= 0) { + tofix |= 32; + iNESCart.iNES2 = 1; + iNESCart.CHRRamSize = (moo[x].chrram & 0x0F) ? (64 << ((moo[x].chrram >> 0) & 0xF)) : 0; + iNESCart.CHRRamSaveSize = (moo[x].chrram & 0xF0) ? (64 << ((moo[x].chrram >> 4) & 0xF)) : 0; + } - break; - } - x++; - } while (moo[x].mirror >= 0 || moo[x].mapper >= 0); + break; + } + x++; + } while (moo[x].mirror >= 0 || moo[x].mapper >= 0); - /* Games that use these iNES mappers tend to have the four-screen bit set - when it should not be. - */ - if ((iNESCart.mapper == 118 || iNESCart.mapper == 24 || iNESCart.mapper == 26) && (iNESCart.mirror == 2)) { - iNESCart.mirror = 0; - tofix |= 2; - } + /* Games that use these iNES mappers tend to have the four-screen bit set + when it should not be. + */ + if ((iNESCart.mapper == 118 || iNESCart.mapper == 24 || iNESCart.mapper == 26) && (iNESCart.mirror == 2)) { + iNESCart.mirror = 0; + tofix |= 2; + } - /* Four-screen mirroring implicitly set. */ - if (iNESCart.mapper == 99) - iNESCart.mirror = 2; + /* Four-screen mirroring implicitly set. */ + if (iNESCart.mapper == 99) + iNESCart.mirror = 2; - if (tofix) { - char gigastr[768]; - strcpy(gigastr, " The iNES header contains incorrect information. For now, the information will be corrected in RAM. "); - if (tofix & 1) - sprintf(gigastr + strlen(gigastr), "Current mapper # is %d. The mapper number should be set to %d. ", current_mapper, iNESCart.mapper); - if (tofix & 2) { - uint8 *mstr[3] = { (uint8_t*)"Horizontal", (uint8_t*)"Vertical", (uint8_t*)"Four-screen" }; - sprintf(gigastr + strlen(gigastr), "Current mirroring is %s. Mirroring should be set to \"%s\". ", mstr[cur_mirr & 3], mstr[iNESCart.mirror & 3]); - } - if (tofix & 4) - strcat(gigastr, "The battery-backed bit should be set. "); - if (tofix & 8) - strcat(gigastr, "This game should not have any CHR ROM. "); - if (tofix & 16) { - uint8 *rstr[4] = { (uint8*)"NTSC", (uint8*)"PAL", (uint8*)"Multi", (uint8*)"Dendy" }; - sprintf(gigastr + strlen(gigastr), "This game should run with \"%s\" timings.", rstr[iNESCart.region]); - } - if (tofix & 32) { - unsigned PRGRAM = iNESCart.PRGRamSize + iNESCart.PRGRamSaveSize; - unsigned CHRRAM = iNESCart.CHRRamSize + iNESCart.CHRRamSaveSize; - if (PRGRAM || CHRRAM) { - if (iNESCart.PRGRamSaveSize == 0) - sprintf(gigastr + strlen(gigastr), "workram: %d KB, ", PRGRAM / 1024); - else if (iNESCart.PRGRamSize == 0) - sprintf(gigastr + strlen(gigastr), "saveram: %d KB, ", PRGRAM / 1024); - else - sprintf(gigastr + strlen(gigastr), "workram: %d KB (%dKB battery-backed), ", PRGRAM / 1024, iNESCart.PRGRamSaveSize / 1024); - sprintf(gigastr + strlen(gigastr), "chrram: %d KB.", (CHRRAM + iNESCart.CHRRamSaveSize) / 1024); - } - } - strcat(gigastr, "\n"); - FCEU_printf("%s\n", gigastr); - } + if (tofix) { + char gigastr[768]; + strcpy(gigastr, " The iNES header contains incorrect information. For now, the information will be corrected in RAM. "); + if (tofix & 1) + sprintf(gigastr + strlen(gigastr), "Current mapper # is %d. The mapper number should be set to %d. ", current_mapper, iNESCart.mapper); + if (tofix & 2) { + uint8 *mstr[3] = { (uint8_t*)"Horizontal", (uint8_t*)"Vertical", (uint8_t*)"Four-screen" }; + sprintf(gigastr + strlen(gigastr), "Current mirroring is %s. Mirroring should be set to \"%s\". ", mstr[cur_mirr & 3], mstr[iNESCart.mirror & 3]); + } + if (tofix & 4) + strcat(gigastr, "The battery-backed bit should be set. "); + if (tofix & 8) + strcat(gigastr, "This game should not have any CHR ROM. "); + if (tofix & 16) { + uint8 *rstr[4] = { (uint8*)"NTSC", (uint8*)"PAL", (uint8*)"Multi", (uint8*)"Dendy" }; + sprintf(gigastr + strlen(gigastr), "This game should run with \"%s\" timings.", rstr[iNESCart.region]); + } + if (tofix & 32) { + unsigned PRGRAM = iNESCart.PRGRamSize + iNESCart.PRGRamSaveSize; + unsigned CHRRAM = iNESCart.CHRRamSize + iNESCart.CHRRamSaveSize; + if (PRGRAM || CHRRAM) { + if (iNESCart.PRGRamSaveSize == 0) + sprintf(gigastr + strlen(gigastr), "workram: %d KB, ", PRGRAM / 1024); + else if (iNESCart.PRGRamSize == 0) + sprintf(gigastr + strlen(gigastr), "saveram: %d KB, ", PRGRAM / 1024); + else + sprintf(gigastr + strlen(gigastr), "workram: %d KB (%dKB battery-backed), ", PRGRAM / 1024, iNESCart.PRGRamSaveSize / 1024); + sprintf(gigastr + strlen(gigastr), "chrram: %d KB.", (CHRRAM + iNESCart.CHRRamSaveSize) / 1024); + } + } + strcat(gigastr, "\n"); + FCEU_printf("%s\n", gigastr); + } #undef DEFAULT #undef NOEXTRA @@ -804,13 +808,15 @@ INES_BOARD_BEGIN() INES_BOARD( "LH53", 535, LH53_Init ) INES_BOARD_END() -static uint32 get_ines_version(void) { +static uint32 get_ines_version(void) +{ if ((head.ROM_type2 & 0x0C) == 0x08) return 1; return 0; } -static uint32 get_ines_mapper_id(void) { +static uint32 get_ines_mapper_id(void) +{ /* If byte 7 AND $0C = $08, and the size taking into account byte 9 does not exceed the actual size of the ROM image, then NES 2.0. * If byte 7 AND $0C = $00, and bytes 12-15 are all 0, then iNES. * Otherwise, archaic iNES. - nesdev*/ From 19bba93928b480043a0e3be92c23428128fc0f50 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Mon, 7 Jun 2021 18:55:32 +0200 Subject: [PATCH 135/295] Add FF7 translation to ines-correct.h --- src/ines-correct.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ines-correct.h b/src/ines-correct.h index 0f86a4e..9634bbb 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -368,6 +368,7 @@ /* Mapper 163: Nanjing, running with $5300=$04 */ { 0xC9ABA7F0, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Chrono Trigger - 时空之轮 */ { 0x143B4D30, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Final Fantasy VII - 最终幻想 7 */ + { 0x609458B6, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* Final Fantasy VII - 最终幻想 7, English translation */ { 0x3CC55A44, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* The Legend of Zelda - 塞尔达传说: 神奇的帽子 */ { 0x4752BD5E, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 七國大戰 */ { 0x1121C0D1, 163, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* 三国志 之 傲视天地 */ From 9e7f924a6759e82a31884336be61f154cc7fde9a Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Mon, 7 Jun 2021 19:09:37 +0200 Subject: [PATCH 136/295] Add a few misheadered ROMs from a Nanjing ROM pack to ines-correct.h --- src/ines-correct.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ines-correct.h b/src/ines-correct.h index 9634bbb..5881b6b 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -783,6 +783,13 @@ { 0xB6984DAD, 176, 3, DEFAULT, 1, 0x07, 0x0B, DEFAULT, NOEXTRA }, /* Super Mario 160-in-1 Funny Time.nes */ { 0xB6984DAD, 176, 4, DEFAULT, 1, 0x07, 0x07, DEFAULT, NOEXTRA }, /* GameStar Smart Genius Deluxe.nes */ + /* Nanjing games that are sometimes found erroneously set to mapper 163 even though they use other mappers */ + { 0x3CD15707, 178, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* [NJ027] Fang Shi Yu (C) */ + { 0x2779BB41, 534, 0, MI_V, 0, DEFAULT, 0x07, DENDY, NOEXTRA }, /* [NJ064] Shu Du (Sudoku) (C) */ + { 0x1DE558A1, 178, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* [NJ085] Shan Shan De Hong Xing (C) */ + { 0xF814EC57, 178, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* [NJ090] Yong Zhe Chuan Shuo (C) */ + { 0x53A1F436, 178, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* [NJ091] Xian Jian Wen Qing (C) */ + /* Non-Mapper 176 files that are sometimes found erroneously set to mapper 176 */ { 0x60AC647F, 260, 0, DEFAULT, 0, DEFAULT, DEFAULT, DEFAULT, NOEXTRA }, /* (YH-4222) Super Game 4-in-1.nes */ From 07236cdd44689cb8f35b06b8e05d5991d9e40d00 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Mon, 7 Jun 2021 19:15:13 +0200 Subject: [PATCH 137/295] Comment style --- src/boards/163.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/boards/163.c b/src/boards/163.c index 393817b..a285fff 100644 --- a/src/boards/163.c +++ b/src/boards/163.c @@ -65,8 +65,8 @@ static DECLFW(writeReg) if (A &1) { - if (reg[1] &0x01 && ~V &0x01) reg[1] ^=0x04; // If A0=1, flip feedback bit on falling edges of D0 - } // If A0=0, write to register + if (reg[1] &0x01 && ~V &0x01) reg[1] ^=0x04; /* If A0=1, flip feedback bit on falling edges of D0 */ + } /* If A0=0, write to register */ else reg[index] = V; sync(); From 3a85082268fdec52d9da450ba069e57735725cf9 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Mon, 7 Jun 2021 19:23:09 +0200 Subject: [PATCH 138/295] Found a database mistake --- src/ines-correct.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ines-correct.h b/src/ines-correct.h index 5881b6b..b5d9458 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -781,7 +781,7 @@ { 0x42161530, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙魂 [protection removed].nes */ { 0x8F8FC9A7, 176, 2, DEFAULT, 1, 0x90, 0x07, DENDY, NOEXTRA }, /* 龙魂.nes */ { 0xB6984DAD, 176, 3, DEFAULT, 1, 0x07, 0x0B, DEFAULT, NOEXTRA }, /* Super Mario 160-in-1 Funny Time.nes */ - { 0xB6984DAD, 176, 4, DEFAULT, 1, 0x07, 0x07, DEFAULT, NOEXTRA }, /* GameStar Smart Genius Deluxe.nes */ + { 0xAD82BBEA, 176, 4, DEFAULT, 1, 0x07, 0x07, DEFAULT, NOEXTRA }, /* GameStar Smart Genius Deluxe.nes */ /* Nanjing games that are sometimes found erroneously set to mapper 163 even though they use other mappers */ { 0x3CD15707, 178, 0, MI_V, 1, 0x70, 0x07, DENDY, NOEXTRA }, /* [NJ027] Fang Shi Yu (C) */ From 152198515cb52ca9f92f4c792cd4ec9caff85b8f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 14 Jun 2021 15:26:43 +0200 Subject: [PATCH 139/295] Buildfix --- src/boards/eeprom_93C66.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/boards/eeprom_93C66.c b/src/boards/eeprom_93C66.c index c52e602..9f793ec 100644 --- a/src/boards/eeprom_93C66.c +++ b/src/boards/eeprom_93C66.c @@ -87,7 +87,12 @@ void eeprom_93C66_write (uint8 CS, uint8 CLK, uint8 DAT) eeprom_93C66_state = STATE_FINISHED; break; case OPCODE_ERASEALL: - if (eeprom_93C66_writeEnabled) for (int i =0; i <512; i++) eeprom_93C66_storage[i] = 0xFF; + if (eeprom_93C66_writeEnabled) + { + int i; + for (i =0; i <512; i++) + eeprom_93C66_storage[i] = 0xFF; + } eeprom_93C66_state = STATE_FINISHED; break; case OPCODE_WRITEALL: From 4b9f65e27be74c17fa98924119e47013051e326d Mon Sep 17 00:00:00 2001 From: negativeExponent <54053706+negativeExponent@users.noreply.github.com> Date: Sun, 4 Jul 2021 22:10:50 +0800 Subject: [PATCH 140/295] Fix controller info index --- src/drivers/libretro/libretro.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index cf226c7..2c2501b 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -927,7 +927,7 @@ void retro_set_environment(retro_environment_t cb) { pads2, 4 }, { pads3, 2 }, { pads4, 2 }, - { pads5, 5 }, + { pads5, 6 }, { 0, 0 }, }; From 82b5a135a015161f587977f1fbfcc62c18dfcbce Mon Sep 17 00:00:00 2001 From: Poligraf <> Date: Tue, 27 Jul 2021 19:55:09 +1200 Subject: [PATCH 141/295] Add retrofw target --- Makefile.libretro | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Makefile.libretro b/Makefile.libretro index 86563b0..ba9568b 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -433,7 +433,18 @@ else ifeq ($(platform), gcw0) SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined PLATFORM_DEFINES += -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float -fomit-frame-pointer EXTERNAL_ZLIB = 1 - + +# RETROFW +else ifeq ($(platform), retrofw) + TARGET := $(TARGET_NAME)_libretro.so + CC = /opt/retrofw-toolchain/usr/bin/mipsel-linux-gcc + CXX = /opt/gcw0-toolchain/usr/bin/mipsel-linux-g++ + AR = /opt/retrofw-toolchain/usr/bin/mipsel-linux-ar + fpic := -fPIC + SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined + PLATFORM_DEFINES += -ffast-math -march=mips32 -mtune=mips32 -mhard-float -fomit-frame-pointer + EXTERNAL_ZLIB = 1 + # Windows MSVC 2017 all architectures else ifneq (,$(findstring windows_msvc2017,$(platform))) CC = cl.exe From 19e7181d780206c0b04ae40ee51a06af60281607 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Thu, 29 Jul 2021 13:39:30 +0100 Subject: [PATCH 142/295] (.gitlab-ci.yml) Add RetroFW target --- .gitlab-ci.yml | 6 ++++++ Makefile.libretro | 6 +++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6771abe..f794a11 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -278,6 +278,12 @@ libretro-build-dingux-odbeta-mips32: - .libretro-dingux-odbeta-mips32-make-default - .core-defs +# RetroFW +libretro-build-retrofw-mips32: + extends: + - .libretro-retrofw-mips32-make-default + - .core-defs + #################################### MISC ################################## # Emscripten libretro-build-emscripten: diff --git a/Makefile.libretro b/Makefile.libretro index ba9568b..2f2bb5a 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -433,18 +433,18 @@ else ifeq ($(platform), gcw0) SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined PLATFORM_DEFINES += -ffast-math -march=mips32 -mtune=mips32r2 -mhard-float -fomit-frame-pointer EXTERNAL_ZLIB = 1 - + # RETROFW else ifeq ($(platform), retrofw) TARGET := $(TARGET_NAME)_libretro.so CC = /opt/retrofw-toolchain/usr/bin/mipsel-linux-gcc - CXX = /opt/gcw0-toolchain/usr/bin/mipsel-linux-g++ + CXX = /opt/retrofw-toolchain/usr/bin/mipsel-linux-g++ AR = /opt/retrofw-toolchain/usr/bin/mipsel-linux-ar fpic := -fPIC SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined PLATFORM_DEFINES += -ffast-math -march=mips32 -mtune=mips32 -mhard-float -fomit-frame-pointer EXTERNAL_ZLIB = 1 - + # Windows MSVC 2017 all architectures else ifneq (,$(findstring windows_msvc2017,$(platform))) CC = cl.exe From 0ce638d8c93da839f1b1d543aee65540652561bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juliano=20Dorig=C3=A3o?= Date: Sat, 11 Sep 2021 16:17:05 -0400 Subject: [PATCH 143/295] Added rpi3_64 to makefile --- Makefile.libretro | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile.libretro b/Makefile.libretro index 2f2bb5a..d4e86bf 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -240,6 +240,14 @@ else ifeq ($(platform), rpi3) CFLAGS += -marm -mcpu=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard -funsafe-math-optimizations CFLAGS += -fomit-frame-pointer -fstrict-aliasing -ffast-math +# Raspberry Pi 3 (64 bit) +else ifeq ($(platform), rpi3_64) + TARGET := $(TARGET_NAME)_libretro.so + fpic := -fPIC + SHARED := -shared -Wl,--version-script=src/drivers/libretro/link.T -Wl,-no-undefined + CFLAGS += -mcpu=cortex-a53 -mtune=cortex-a53 -funsafe-math-optimizations + CFLAGS += -fomit-frame-pointer -fstrict-aliasing -ffast-math + # Raspberry Pi 4 (64-bit) else ifeq ($(platform), rpi4) TARGET := $(TARGET_NAME)_libretro.so From 21c829ba435e683655cc01ad34a617ebd993517d Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Tue, 21 Sep 2021 22:21:44 +0200 Subject: [PATCH 144/295] Add mapper 236 --- src/boards/236.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ src/ines.c | 2 +- 2 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 src/boards/236.c diff --git a/src/boards/236.c b/src/boards/236.c new file mode 100644 index 0000000..f4af1c9 --- /dev/null +++ b/src/boards/236.c @@ -0,0 +1,99 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2012 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" + +static uint8 reg[2]; +static uint8 dip; +static SFORMAT StateRegs[] = +{ + { reg, 2, "REG " }, + { &dip, 1, "DIP " }, + { 0 } +}; + +static void Sync(void) +{ + int prg = reg[1] &7 | reg[0] <<3; + switch (reg[1] >>4 &3) + { + case 0: + case 1: + setprg16(0x8000, prg); + setprg16(0xC000, prg |7); + break; + case 2: + setprg32(0x8000, prg >>1); + break; + case 3: + setprg16(0x8000, prg); + setprg16(0xC000, prg); + break; + } + setchr8(reg[0] &7); + setmirror((reg[0] >>5 &1) ^1); +} + + +static DECLFR(M236Read) +{ + if ((reg[1] >>4 &3) ==1) + return CartBR(A &~0xF | dip); + else + return CartBR(A); +} + +static DECLFW(M236WriteReg) +{ + reg[A >>14 &1] =A &0xFF; + Sync(); +} + +static void M236Power(void) +{ + dip = 0; + reg[0] = 0; + reg[1] = 0; + Sync(); + SetWriteHandler(0x8000, 0xFFFF, M236WriteReg); + SetReadHandler(0x8000, 0xFFFF, M236Read); +} + +static void M236Reset(void) +{ + ++dip; + /* Soft-reset returns to menu */ + reg[0] = 0; + reg[1] = 0; + Sync(); +} + +static void StateRestore(int version) +{ + Sync(); +} + +void Mapper236_Init(CartInfo *info) +{ + info->Power = M236Power; + info->Reset = M236Reset; + AddExState(&StateRegs, ~0, 0, 0); + GameStateRestore = StateRestore; +} diff --git a/src/ines.c b/src/ines.c index 973d875..1e7f7f0 100644 --- a/src/ines.c +++ b/src/ines.c @@ -655,7 +655,7 @@ INES_BOARD_BEGIN() INES_BOARD( "BMC 22+20-in-1 RST", 233, Mapper233_Init ) INES_BOARD( "BMC MAXI", 234, Mapper234_Init ) INES_BOARD( "Golden Game", 235, Mapper235_Init ) -/* INES_BOARD( "", 236, Mapper236_Init ) */ + INES_BOARD( "Realtec 8155", 236, Mapper236_Init ) INES_BOARD( "Teletubbies / Y2K", 237, Mapper237_Init ) INES_BOARD( "UNL6035052", 238, UNL6035052_Init ) /* INES_BOARD( "", 239, Mapper239_Init ) */ From cb3a22daf0bf6da9c14c4158864c703318c2d70e Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Tue, 21 Sep 2021 23:36:44 +0200 Subject: [PATCH 145/295] Mapper 134: Add PRG/CHR A19 outer bank bits --- src/boards/Bs5652.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/boards/Bs5652.c b/src/boards/Bs5652.c index a9f8ad3..237571f 100644 --- a/src/boards/Bs5652.c +++ b/src/boards/Bs5652.c @@ -62,8 +62,8 @@ void Bs5652AnalyzeReg() readDIP = exRegs[0] & 0x40; prgAND = exRegs[1] & 0x04 ? 0x0F : 0x1F; chrAND = exRegs[1] & 0x40 ? 0x7F : 0xFF; - prgOR = (exRegs[1] & 0x03) << 4; - chrOR = (exRegs[1] & 0x30) << 3 ; + prgOR = (exRegs[1] & 0x03) << 4 | (exRegs[0] & 0x10) << 2; + chrOR = (exRegs[1] & 0x30) << 3 | (exRegs[0] & 0x20) << 4; nrom = exRegs[0] & 0x08; nrom128 = exRegs[1] & 0x08; } From 6881c1fd2a2e268c50ceac8c1605eaa6f12528f9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sat, 25 Sep 2021 03:41:39 +0200 Subject: [PATCH 146/295] Some MSVC / C89 buildfixes --- src/boards/162.c | 5 +++-- src/boards/163.c | 5 +++-- src/boards/164.c | 5 +++-- src/boards/558.c | 5 +++-- src/boards/fk23c.c | 6 ++++-- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/boards/162.c b/src/boards/162.c index 6a57890..4dd12bf 100644 --- a/src/boards/162.c +++ b/src/boards/162.c @@ -77,7 +77,7 @@ static void power(void) SetWriteHandler(0x6000, 0x7FFF, CartBW); } -static void reset() +static void reset(void) { memset(reg, 0, sizeof(reg)); sync(); @@ -85,13 +85,14 @@ static void reset() void Mapper162_Init (CartInfo *info) { + uint8 *WRAM; uint32 WRAMSIZE = info->iNES2? (info->PRGRamSize + info->PRGRamSaveSize): 8192; info->Power = power; info->Reset = reset; GameHBIRQHook = hblank; AddExState(StateRegs, ~0, 0, 0); - uint8* WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); + WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); if (info->battery) { diff --git a/src/boards/163.c b/src/boards/163.c index a285fff..94ff9d3 100644 --- a/src/boards/163.c +++ b/src/boards/163.c @@ -82,7 +82,7 @@ static void power(void) SetWriteHandler(0x6000, 0x7FFF, CartBW); } -static void reset() +static void reset(void) { memset(reg, 0, sizeof(reg)); sync(); @@ -90,13 +90,14 @@ static void reset() void Mapper163_Init (CartInfo *info) { + uint8 *WRAM; uint32 WRAMSIZE = info->iNES2? (info->PRGRamSize + info->PRGRamSaveSize): 8192; info->Power = power; info->Reset = reset; GameHBIRQHook = hblank; AddExState(StateRegs, ~0, 0, 0); - uint8* WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); + WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); if (info->battery) { diff --git a/src/boards/164.c b/src/boards/164.c index a9d7c9e..06c7b39 100644 --- a/src/boards/164.c +++ b/src/boards/164.c @@ -95,7 +95,7 @@ static void power(void) SetWriteHandler(0x6000, 0x7FFF, CartBW); } -static void reset() +static void reset(void) { memset(reg, 0, sizeof(reg)); sync(); @@ -103,12 +103,13 @@ static void reset() void Mapper164_Init (CartInfo *info) { + uint8 *WRAM; uint32 WRAMSIZE = info->iNES2? (info->PRGRamSize + (info->PRGRamSaveSize &~0x7FF)): 8192; info->Power = power; info->Reset = reset; AddExState(StateRegs, ~0, 0, 0); - uint8* WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); + WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); diff --git a/src/boards/558.c b/src/boards/558.c index b622a61..a6664c0 100644 --- a/src/boards/558.c +++ b/src/boards/558.c @@ -91,7 +91,7 @@ static void power(void) SetWriteHandler(0x6000, 0x7FFF, CartBW); } -static void reset() +static void reset(void) { memset(reg, 0, sizeof(reg)); sync(); @@ -99,13 +99,14 @@ static void reset() void Mapper558_Init (CartInfo *info) { + uint8 *WRAM; uint32 WRAMSIZE = info->PRGRamSize + (info->PRGRamSaveSize &~0x7FF); info->Power = power; info->Reset = reset; GameHBIRQHook = hblank; AddExState(StateRegs, ~0, 0, 0); - uint8* WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); + WRAM = (uint8*) FCEU_gmalloc(WRAMSIZE); SetupCartPRGMapping(0x10, WRAM, WRAMSIZE, 1); FCEU_CheatAddRAM(WRAMSIZE >> 10, 0x6000, WRAM); haveEEPROM =!!(info->PRGRamSaveSize &0x200); diff --git a/src/boards/fk23c.c b/src/boards/fk23c.c index bbbb23b..b5c13f5 100644 --- a/src/boards/fk23c.c +++ b/src/boards/fk23c.c @@ -290,8 +290,9 @@ static DECLFW(Write8000) { case 0x8000: { + uint8 old_ctrl; if (A & 2) return; /* Confirmed on real hardware: writes to 8002 and 8003, or 9FFE and 9FFF, are ignored. Needed for Dr. Mario on some of the "bouncing ball" multis. */ - uint8 old_ctrl = mmc3_ctrl; + old_ctrl = mmc3_ctrl; /* Subtype 2, 8192 or more KiB PRG-ROM, no CHR-ROM: Like Subtype 0, * but MMC3 registers $46 and $47 swapped. */ @@ -315,8 +316,9 @@ static DECLFW(Write8000) } case 0x8001: { + uint8 ctrl_mask; if (A & 2) return; /* Confirmed on real hardware: writes to 8002 and 8003, or 9FFE and 9FFF, are ignored. Needed for Dr. Mario on some of the "bouncing ball" multis. */ - uint8 ctrl_mask = MMC3_EXTENDED ? 0x0F : 0x07; + ctrl_mask = MMC3_EXTENDED ? 0x0F : 0x07; if ((mmc3_ctrl & ctrl_mask) < 12) { From 1502ca02d4297a58ab18c59e330935d34b1a7c07 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Fri, 8 Oct 2021 12:39:52 +0100 Subject: [PATCH 147/295] Fix core options version detection --- src/drivers/libretro/libretro_core_options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/libretro/libretro_core_options.h b/src/drivers/libretro/libretro_core_options.h index fe35d72..e3deb8e 100644 --- a/src/drivers/libretro/libretro_core_options.h +++ b/src/drivers/libretro/libretro_core_options.h @@ -477,7 +477,7 @@ static INLINE void libretro_set_core_options(retro_environment_t environ_cb) if (!environ_cb) return; - if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version == 1)) + if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version >= 1)) { struct retro_core_options_intl core_options_intl; unsigned language = 0; From 0c82e4c73e0771433f25648edb82608919c5a903 Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Tue, 19 Oct 2021 17:33:56 +0100 Subject: [PATCH 148/295] Update core options to v2 format (add category support) --- .../libretro-common/include/libretro.h | 799 ++++++++++++++++- src/drivers/libretro/libretro.c | 229 +++-- src/drivers/libretro/libretro_core_options.h | 806 +++++++++++------- .../libretro/libretro_core_options_intl.h | 91 ++ src/drivers/libretro/libretro_dipswitch.c | 44 +- src/drivers/libretro/libretro_dipswitch.h | 2 +- src/ntsc/nes_ntsc_config.h | 2 +- 7 files changed, 1570 insertions(+), 403 deletions(-) create mode 100644 src/drivers/libretro/libretro_core_options_intl.h diff --git a/src/drivers/libretro/libretro-common/include/libretro.h b/src/drivers/libretro/libretro-common/include/libretro.h index 8a5da86..2f17483 100644 --- a/src/drivers/libretro/libretro-common/include/libretro.h +++ b/src/drivers/libretro/libretro-common/include/libretro.h @@ -1131,6 +1131,13 @@ enum retro_mod * 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. + * + * If version is >= 2, core options may instead be set by passing + * a retro_core_options_v2 struct to RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, + * or an array of retro_core_options_v2 structs to + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL. This allows the core + * to additionally set optional core option category information + * for frontends with core option category support. */ #define RETRO_ENVIRONMENT_SET_CORE_OPTIONS 53 @@ -1172,7 +1179,7 @@ enum retro_mod * 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, + * The number of possible option values 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. @@ -1205,6 +1212,7 @@ enum retro_mod * This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION * returns an API version of >= 1. * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS. * 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 @@ -1378,6 +1386,373 @@ enum retro_mod * call will target the newly initialized driver. */ +#define RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE 64 + /* const struct retro_fastforwarding_override * -- + * Used by a libretro core to override the current + * fastforwarding mode of the frontend. + * If NULL is passed to this function, the frontend + * will return true if fastforwarding override + * functionality is supported (no change in + * fastforwarding state will occur in this case). + */ + +#define RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE 65 + /* const struct retro_system_content_info_override * -- + * Allows an implementation to override 'global' content + * info parameters reported by retro_get_system_info(). + * Overrides also affect subsystem content info parameters + * set via RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO. + * This function must be called inside retro_set_environment(). + * If callback returns false, content info overrides + * are unsupported by the frontend, and will be ignored. + * If callback returns true, extended game info may be + * retrieved by calling RETRO_ENVIRONMENT_GET_GAME_INFO_EXT + * in retro_load_game() or retro_load_game_special(). + * + * 'data' points to an array of retro_system_content_info_override + * structs terminated by a { NULL, false, false } element. + * If 'data' is NULL, no changes will be made to the frontend; + * a core may therefore pass NULL in order to test whether + * the RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE and + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT callbacks are supported + * by the frontend. + * + * For struct member descriptions, see the definition of + * struct retro_system_content_info_override. + * + * Example: + * + * - struct retro_system_info: + * { + * "My Core", // library_name + * "v1.0", // library_version + * "m3u|md|cue|iso|chd|sms|gg|sg", // valid_extensions + * true, // need_fullpath + * false // block_extract + * } + * + * - Array of struct retro_system_content_info_override: + * { + * { + * "md|sms|gg", // extensions + * false, // need_fullpath + * true // persistent_data + * }, + * { + * "sg", // extensions + * false, // need_fullpath + * false // persistent_data + * }, + * { NULL, false, false } + * } + * + * Result: + * - Files of type m3u, cue, iso, chd will not be + * loaded by the frontend. Frontend will pass a + * valid path to the core, and core will handle + * loading internally + * - Files of type md, sms, gg will be loaded by + * the frontend. A valid memory buffer will be + * passed to the core. This memory buffer will + * remain valid until retro_deinit() returns + * - Files of type sg will be loaded by the frontend. + * A valid memory buffer will be passed to the core. + * This memory buffer will remain valid until + * retro_load_game() (or retro_load_game_special()) + * returns + * + * NOTE: If an extension is listed multiple times in + * an array of retro_system_content_info_override + * structs, only the first instance will be registered + */ + +#define RETRO_ENVIRONMENT_GET_GAME_INFO_EXT 66 + /* const struct retro_game_info_ext ** -- + * Allows an implementation to fetch extended game + * information, providing additional content path + * and memory buffer status details. + * This function may only be called inside + * retro_load_game() or retro_load_game_special(). + * If callback returns false, extended game information + * is unsupported by the frontend. In this case, only + * regular retro_game_info will be available. + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT is guaranteed + * to return true if RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE + * returns true. + * + * 'data' points to an array of retro_game_info_ext structs. + * + * For struct member descriptions, see the definition of + * struct retro_game_info_ext. + * + * - If function is called inside retro_load_game(), + * the retro_game_info_ext array is guaranteed to + * have a size of 1 - i.e. the returned pointer may + * be used to access directly the members of the + * first retro_game_info_ext struct, for example: + * + * struct retro_game_info_ext *game_info_ext; + * if (environ_cb(RETRO_ENVIRONMENT_GET_GAME_INFO_EXT, &game_info_ext)) + * printf("Content Directory: %s\n", game_info_ext->dir); + * + * - If the function is called inside retro_load_game_special(), + * the retro_game_info_ext array is guaranteed to have a + * size equal to the num_info argument passed to + * retro_load_game_special() + */ + +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 67 + /* const struct retro_core_options_v2 * -- + * 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_CORE_OPTIONS_VERSION + * returns an API version of >= 2. + * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS. + * 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. + * If RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION returns an API + * version of >= 2, this callback is guaranteed to succeed + * (i.e. callback return value does not indicate success) + * If callback returns true, frontend has core option category + * support. + * If callback returns false, frontend does not have core option + * category support. + * + * 'data' points to a retro_core_options_v2 struct, containing + * of two pointers: + * - retro_core_options_v2::categories is an array of + * retro_core_option_v2_category structs terminated by a + * { NULL, NULL, NULL } element. If retro_core_options_v2::categories + * is NULL, all core options will have no category and will be shown + * at the top level of the frontend core option interface. If frontend + * does not have core option category support, categories array will + * be ignored. + * - retro_core_options_v2::definitions is an array of + * retro_core_option_v2_definition structs terminated by a + * { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL } + * element. + * + * >> retro_core_option_v2_category notes: + * + * - retro_core_option_v2_category::key should contain string + * that uniquely identifies the core option category. Valid + * key characters are [a-z, A-Z, 0-9, _, -] + * Namespace collisions with other implementations' category + * keys are permitted. + * - retro_core_option_v2_category::desc should contain a human + * readable description of the category key. + * - retro_core_option_v2_category::info should contain any + * additional human readable information text that a typical + * user may need to understand the nature of the core option + * category. + * + * Example entry: + * { + * "advanced_settings", + * "Advanced", + * "Options affecting low-level emulation performance and accuracy." + * } + * + * >> retro_core_option_v2_definition notes: + * + * - retro_core_option_v2_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'. Valid key characters + * are [a-z, A-Z, 0-9, _, -]. + * - retro_core_option_v2_definition::desc should contain a human readable + * description of the key. Will be used when the frontend does not + * have core option category support. Examples: "Aspect Ratio" or + * "Video > Aspect Ratio". + * - retro_core_option_v2_definition::desc_categorized should contain a + * human readable description of the key, which will be used when + * frontend has core option category support. Example: "Aspect Ratio", + * where associated retro_core_option_v2_category::desc is "Video". + * If empty or NULL, the string specified by + * retro_core_option_v2_definition::desc will be used instead. + * retro_core_option_v2_definition::desc_categorized will be ignored + * if retro_core_option_v2_definition::category_key is empty or NULL. + * - retro_core_option_v2_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_v2_definition::info_categorized should contain + * any additional human readable information text that a typical user + * may need to understand the functionality of the option, and will be + * used when frontend has core option category support. This is provided + * to accommodate the case where info text references an option by + * name/desc, and the desc/desc_categorized text for that option differ. + * If empty or NULL, the string specified by + * retro_core_option_v2_definition::info will be used instead. + * retro_core_option_v2_definition::info_categorized will be ignored + * if retro_core_option_v2_definition::category_key is empty or NULL. + * - retro_core_option_v2_definition::category_key should contain a + * category identifier (e.g. "video" or "audio") that will be + * assigned to the core option if frontend has core option category + * support. A categorized option will be shown in a subsection/ + * submenu of the frontend core option interface. If key is empty + * or NULL, or if key does not match one of the + * retro_core_option_v2_category::key values in the associated + * retro_core_option_v2_category array, option will have no category + * and will be shown at the top level of the frontend core option + * interface. + * - retro_core_option_v2_definition::values is an array of + * retro_core_option_value structs terminated by a { NULL, NULL } + * element. + * --> retro_core_option_v2_definition::values[index].value is an + * expected option value. + * --> retro_core_option_v2_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_v2_definition::default_value is the default + * core option setting. It must match one of the expected option + * values in the retro_core_option_v2_definition::values array. If + * it does not, or the default value is NULL, the first entry in the + * retro_core_option_v2_definition::values array is treated as the + * default. + * + * The number of possible option values 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. + * + * Example entries: + * + * - Uncategorized: + * + * { + * "foo_option", + * "Speed hack coprocessor X", + * NULL, + * "Provides increased performance at the expense of reduced accuracy.", + * NULL, + * NULL, + * { + * { "false", NULL }, + * { "true", NULL }, + * { "unstable", "Turbo (Unstable)" }, + * { NULL, NULL }, + * }, + * "false" + * } + * + * - Categorized: + * + * { + * "foo_option", + * "Advanced > Speed hack coprocessor X", + * "Speed hack coprocessor X", + * "Setting 'Advanced > Speed hack coprocessor X' to 'true' or 'Turbo' provides increased performance at the expense of reduced accuracy", + * "Setting 'Speed hack coprocessor X' to 'true' or 'Turbo' provides increased performance at the expense of reduced accuracy", + * "advanced_settings", + * { + * { "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_V2_INTL 68 + /* const struct retro_core_options_v2_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_CORE_OPTIONS_VERSION + * returns an API version of >= 2. + * This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL. + * This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2. + * 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. + * If RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION returns an API + * version of >= 2, this callback is guaranteed to succeed + * (i.e. callback return value does not indicate success) + * If callback returns true, frontend has core option category + * support. + * If callback returns false, frontend does not have core option + * category support. + * + * This is fundamentally the same as RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, + * with the addition of localisation support. The description of the + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 callback should be consulted + * for further details. + * + * 'data' points to a retro_core_options_v2_intl struct. + * + * - retro_core_options_v2_intl::us is a pointer to a + * retro_core_options_v2 struct defining the US English + * core options implementation. It must point to a valid struct. + * + * - retro_core_options_v2_intl::local is a pointer to a + * retro_core_options_v2 struct defining core options for + * the current frontend language. It may be NULL (in which case + * retro_core_options_v2_intl::us is used by the frontend). Any items + * missing from this struct will be read from + * retro_core_options_v2_intl::us instead. + * + * NOTE: Default core option values are always taken from the + * retro_core_options_v2_intl::us struct. Any default values in + * the retro_core_options_v2_intl::local struct will be ignored. + */ + +#define RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK 69 + /* const struct retro_core_options_update_display_callback * -- + * Allows a frontend to signal that a core must update + * the visibility of any dynamically hidden core options, + * and enables the frontend to detect visibility changes. + * Used by the frontend to update the menu display status + * of core options without requiring a call of retro_run(). + * Must be called in retro_set_environment(). + */ + +#define RETRO_ENVIRONMENT_SET_VARIABLE 70 + /* const struct retro_variable * -- + * Allows an implementation to notify the frontend + * that a core option value has changed. + * + * retro_variable::key and retro_variable::value + * must match strings that have been set previously + * via one of the following: + * + * - RETRO_ENVIRONMENT_SET_VARIABLES + * - RETRO_ENVIRONMENT_SET_CORE_OPTIONS + * - RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL + * - RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2 + * - RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL + * + * After changing a core option value via this + * callback, RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE + * will return true. + * + * If data is NULL, no changes will be registered + * and the callback will return true; an + * implementation may therefore pass NULL in order + * to test whether the callback is supported. + */ + +#define RETRO_ENVIRONMENT_GET_THROTTLE_STATE (71 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* struct retro_throttle_state * -- + * Allows an implementation to get details on the actual rate + * the frontend is attempting to call retro_run(). + */ + /* VFS functionality */ /* File paths: @@ -2781,6 +3156,213 @@ struct retro_system_info bool block_extract; }; +/* Defines overrides which modify frontend handling of + * specific content file types. + * An array of retro_system_content_info_override is + * passed to RETRO_ENVIRONMENT_SET_CONTENT_INFO_OVERRIDE + * NOTE: In the following descriptions, references to + * retro_load_game() may be replaced with + * retro_load_game_special() */ +struct retro_system_content_info_override +{ + /* A list of file extensions for which the override + * should apply, delimited by a 'pipe' character + * (e.g. "md|sms|gg") + * Permitted file extensions are limited to those + * included in retro_system_info::valid_extensions + * and/or retro_subsystem_rom_info::valid_extensions */ + const char *extensions; + + /* Overrides the need_fullpath value set in + * retro_system_info and/or retro_subsystem_rom_info. + * To reiterate: + * + * If need_fullpath is true and retro_load_game() is called: + * - retro_game_info::path is guaranteed to contain a valid + * path to an existent file + * - retro_game_info::data and retro_game_info::size are invalid + * + * If need_fullpath is false and retro_load_game() is called: + * - retro_game_info::path may be NULL + * - retro_game_info::data and retro_game_info::size are guaranteed + * to be valid + * + * In addition: + * + * If need_fullpath is true and retro_load_game() is called: + * - retro_game_info_ext::full_path is guaranteed to contain a valid + * path to an existent file + * - retro_game_info_ext::archive_path may be NULL + * - retro_game_info_ext::archive_file may be NULL + * - retro_game_info_ext::dir is guaranteed to contain a valid path + * to the directory in which the content file exists + * - retro_game_info_ext::name is guaranteed to contain the + * basename of the content file, without extension + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file in lower case format + * - retro_game_info_ext::data and retro_game_info_ext::size + * are invalid + * + * If need_fullpath is false and retro_load_game() is called: + * - If retro_game_info_ext::file_in_archive is false: + * - retro_game_info_ext::full_path is guaranteed to contain + * a valid path to an existent file + * - retro_game_info_ext::archive_path may be NULL + * - retro_game_info_ext::archive_file may be NULL + * - retro_game_info_ext::dir is guaranteed to contain a + * valid path to the directory in which the content file exists + * - retro_game_info_ext::name is guaranteed to contain the + * basename of the content file, without extension + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file in lower case format + * - If retro_game_info_ext::file_in_archive is true: + * - retro_game_info_ext::full_path may be NULL + * - retro_game_info_ext::archive_path is guaranteed to + * contain a valid path to an existent compressed file + * inside which the content file is located + * - retro_game_info_ext::archive_file is guaranteed to + * contain a valid path to an existent content file + * inside the compressed file referred to by + * retro_game_info_ext::archive_path + * e.g. for a compressed file '/path/to/foo.zip' + * containing 'bar.sfc' + * > retro_game_info_ext::archive_path will be '/path/to/foo.zip' + * > retro_game_info_ext::archive_file will be 'bar.sfc' + * - retro_game_info_ext::dir is guaranteed to contain a + * valid path to the directory in which the compressed file + * (containing the content file) exists + * - retro_game_info_ext::name is guaranteed to contain + * EITHER + * 1) the basename of the compressed file (containing + * the content file), without extension + * OR + * 2) the basename of the content file inside the + * compressed file, without extension + * In either case, a core should consider 'name' to + * be the canonical name/ID of the the content file + * - retro_game_info_ext::ext is guaranteed to contain the + * extension of the content file inside the compressed file, + * in lower case format + * - retro_game_info_ext::data and retro_game_info_ext::size are + * guaranteed to be valid */ + bool need_fullpath; + + /* If need_fullpath is false, specifies whether the content + * data buffer available in retro_load_game() is 'persistent' + * + * If persistent_data is false and retro_load_game() is called: + * - retro_game_info::data and retro_game_info::size + * are valid only until retro_load_game() returns + * - retro_game_info_ext::data and retro_game_info_ext::size + * are valid only until retro_load_game() returns + * + * If persistent_data is true and retro_load_game() is called: + * - retro_game_info::data and retro_game_info::size + * are valid until retro_deinit() returns + * - retro_game_info_ext::data and retro_game_info_ext::size + * are valid until retro_deinit() returns */ + bool persistent_data; +}; + +/* Similar to retro_game_info, but provides extended + * information about the source content file and + * game memory buffer status. + * And array of retro_game_info_ext is returned by + * RETRO_ENVIRONMENT_GET_GAME_INFO_EXT + * NOTE: In the following descriptions, references to + * retro_load_game() may be replaced with + * retro_load_game_special() */ +struct retro_game_info_ext +{ + /* - If file_in_archive is false, contains a valid + * path to an existent content file (UTF-8 encoded) + * - If file_in_archive is true, may be NULL */ + const char *full_path; + + /* - If file_in_archive is false, may be NULL + * - If file_in_archive is true, contains a valid path + * to an existent compressed file inside which the + * content file is located (UTF-8 encoded) */ + const char *archive_path; + + /* - If file_in_archive is false, may be NULL + * - If file_in_archive is true, contain a valid path + * to an existent content file inside the compressed + * file referred to by archive_path (UTF-8 encoded) + * e.g. for a compressed file '/path/to/foo.zip' + * containing 'bar.sfc' + * > archive_path will be '/path/to/foo.zip' + * > archive_file will be 'bar.sfc' */ + const char *archive_file; + + /* - If file_in_archive is false, contains a valid path + * to the directory in which the content file exists + * (UTF-8 encoded) + * - If file_in_archive is true, contains a valid path + * to the directory in which the compressed file + * (containing the content file) exists (UTF-8 encoded) */ + const char *dir; + + /* Contains the canonical name/ID of the content file + * (UTF-8 encoded). Intended for use when identifying + * 'complementary' content named after the loaded file - + * i.e. companion data of a different format (a CD image + * required by a ROM), texture packs, internally handled + * save files, etc. + * - If file_in_archive is false, contains the basename + * of the content file, without extension + * - If file_in_archive is true, then string is + * implementation specific. A frontend may choose to + * set a name value of: + * EITHER + * 1) the basename of the compressed file (containing + * the content file), without extension + * OR + * 2) the basename of the content file inside the + * compressed file, without extension + * RetroArch sets the 'name' value according to (1). + * A frontend that supports routine loading of + * content from archives containing multiple unrelated + * content files may set the 'name' value according + * to (2). */ + const char *name; + + /* - If file_in_archive is false, contains the extension + * of the content file in lower case format + * - If file_in_archive is true, contains the extension + * of the content file inside the compressed file, + * in lower case format */ + const char *ext; + + /* String of implementation specific meta-data. */ + const char *meta; + + /* Memory buffer of loaded game content. Will be NULL: + * IF + * - retro_system_info::need_fullpath is true and + * retro_system_content_info_override::need_fullpath + * is unset + * OR + * - retro_system_content_info_override::need_fullpath + * is true */ + const void *data; + + /* Size of game content memory buffer, in bytes */ + size_t size; + + /* True if loaded content file is inside a compressed + * archive */ + bool file_in_archive; + + /* - If data is NULL, value is unset/ignored + * - If data is non-NULL: + * - If persistent_data is false, data and size are + * valid only until retro_load_game() returns + * - If persistent_data is true, data and size are + * are valid until retro_deinit() returns */ + bool persistent_data; +}; + struct retro_game_geometry { unsigned base_width; /* Nominal video width of game. */ @@ -2892,6 +3474,143 @@ struct retro_core_options_intl struct retro_core_option_definition *local; }; +struct retro_core_option_v2_category +{ + /* Variable uniquely identifying the + * option category. Valid key characters + * are [a-z, A-Z, 0-9, _, -] */ + const char *key; + + /* Human-readable category description + * > Used as category menu label when + * frontend has core option category + * support */ + const char *desc; + + /* Human-readable category information + * > Used as category menu sublabel when + * frontend has core option category + * support + * > Optional (may be NULL or an empty + * string) */ + const char *info; +}; + +struct retro_core_option_v2_definition +{ + /* Variable to query in RETRO_ENVIRONMENT_GET_VARIABLE. + * Valid key characters are [a-z, A-Z, 0-9, _, -] */ + const char *key; + + /* Human-readable core option description + * > Used as menu label when frontend does + * not have core option category support + * e.g. "Video > Aspect Ratio" */ + const char *desc; + + /* Human-readable core option description + * > Used as menu label when frontend has + * core option category support + * e.g. "Aspect Ratio", where associated + * retro_core_option_v2_category::desc + * is "Video" + * > If empty or NULL, the string specified by + * desc will be used as the menu label + * > Will be ignored (and may be set to NULL) + * if category_key is empty or NULL */ + const char *desc_categorized; + + /* Human-readable core option information + * > Used as menu sublabel */ + const char *info; + + /* Human-readable core option information + * > Used as menu sublabel when frontend + * has core option category support + * (e.g. may be required when info text + * references an option by name/desc, + * and the desc/desc_categorized text + * for that option differ) + * > If empty or NULL, the string specified by + * info will be used as the menu sublabel + * > Will be ignored (and may be set to NULL) + * if category_key is empty or NULL */ + const char *info_categorized; + + /* Variable specifying category (e.g. "video", + * "audio") that will be assigned to the option + * if frontend has core option category support. + * > Categorized options will be displayed in a + * subsection/submenu of the frontend core + * option interface + * > Specified string must match one of the + * retro_core_option_v2_category::key values + * in the associated retro_core_option_v2_category + * array; If no match is not found, specified + * string will be considered as NULL + * > If specified string is empty or NULL, option will + * have no category and will be shown at the top + * level of the frontend core option interface */ + const char *category_key; + + /* 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_v2 +{ + /* Array of retro_core_option_v2_category structs, + * terminated by NULL + * > If NULL, all entries in definitions array + * will have no category and will be shown at + * the top level of the frontend core option + * interface + * > Will be ignored if frontend does not have + * core option category support */ + struct retro_core_option_v2_category *categories; + + /* Array of retro_core_option_v2_definition structs, + * terminated by NULL */ + struct retro_core_option_v2_definition *definitions; +}; + +struct retro_core_options_v2_intl +{ + /* Pointer to a retro_core_options_v2 struct + * > US English implementation + * > Must point to a valid struct */ + struct retro_core_options_v2 *us; + + /* Pointer to a retro_core_options_v2 struct + * - Implementation for current frontend language + * - May be NULL */ + struct retro_core_options_v2 *local; +}; + +/* Used by the frontend to monitor changes in core option + * visibility. May be called each time any core option + * value is set via the frontend. + * - On each invocation, the core must update the visibility + * of any dynamically hidden options using the + * RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY environment + * callback. + * - On the first invocation, returns 'true' if the visibility + * of any core option has changed since the last call of + * retro_load_game() or retro_load_game_special(). + * - On each subsequent invocation, returns 'true' if the + * visibility of any core option has changed since the last + * time the function was called. */ +typedef bool (RETRO_CALLCONV *retro_core_options_update_display_callback_t)(void); +struct retro_core_options_update_display_callback +{ + retro_core_options_update_display_callback_t callback; +}; + struct retro_game_info { const char *path; /* Path to game, UTF-8 encoded. @@ -2938,6 +3657,84 @@ struct retro_framebuffer Set by frontend in GET_CURRENT_SOFTWARE_FRAMEBUFFER. */ }; +/* Used by a libretro core to override the current + * fastforwarding mode of the frontend */ +struct retro_fastforwarding_override +{ + /* Specifies the runtime speed multiplier that + * will be applied when 'fastforward' is true. + * For example, a value of 5.0 when running 60 FPS + * content will cap the fast-forward rate at 300 FPS. + * Note that the target multiplier may not be achieved + * if the host hardware has insufficient processing + * power. + * Setting a value of 0.0 (or greater than 0.0 but + * less than 1.0) will result in an uncapped + * fast-forward rate (limited only by hardware + * capacity). + * If the value is negative, it will be ignored + * (i.e. the frontend will use a runtime speed + * multiplier of its own choosing) */ + float ratio; + + /* If true, fastforwarding mode will be enabled. + * If false, fastforwarding mode will be disabled. */ + bool fastforward; + + /* If true, and if supported by the frontend, an + * on-screen notification will be displayed while + * 'fastforward' is true. + * If false, and if supported by the frontend, any + * on-screen fast-forward notifications will be + * suppressed */ + bool notification; + + /* If true, the core will have sole control over + * when fastforwarding mode is enabled/disabled; + * the frontend will not be able to change the + * state set by 'fastforward' until either + * 'inhibit_toggle' is set to false, or the core + * is unloaded */ + bool inhibit_toggle; +}; + +/* During normal operation. Rate will be equal to the core's internal FPS. */ +#define RETRO_THROTTLE_NONE 0 + +/* While paused or stepping single frames. Rate will be 0. */ +#define RETRO_THROTTLE_FRAME_STEPPING 1 + +/* During fast forwarding. + * Rate will be 0 if not specifically limited to a maximum speed. */ +#define RETRO_THROTTLE_FAST_FORWARD 2 + +/* During slow motion. Rate will be less than the core's internal FPS. */ +#define RETRO_THROTTLE_SLOW_MOTION 3 + +/* While rewinding recorded save states. Rate can vary depending on the rewind + * speed or be 0 if the frontend is not aiming for a specific rate. */ +#define RETRO_THROTTLE_REWINDING 4 + +/* While vsync is active in the video driver and the target refresh rate is + * lower than the core's internal FPS. Rate is the target refresh rate. */ +#define RETRO_THROTTLE_VSYNC 5 + +/* When the frontend does not throttle in any way. Rate will be 0. + * An example could be if no vsync or audio output is active. */ +#define RETRO_THROTTLE_UNBLOCKED 6 + +struct retro_throttle_state +{ + /* The current throttling mode. Should be one of the values above. */ + unsigned mode; + + /* How many times per second the frontend aims to call retro_run. + * Depending on the mode, it can be 0 if there is no known fixed rate. + * This won't be accurate if the total processing time of the core and + * the frontend is longer than what is available for one frame. */ + float rate; +}; + /* Callbacks */ /* Environment callback. Gives implementations a way of performing diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 2c2501b..2041d3c 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -141,6 +141,7 @@ enum RetroZapperInputModes{RetroLightgun, RetroMouse, RetroPointer}; static enum RetroZapperInputModes zappermode = RetroLightgun; static bool libretro_supports_bitmasks = false; +static bool libretro_supports_option_categories = false; /* emulator-specific variables */ @@ -162,8 +163,8 @@ unsigned dendy = 0; static unsigned systemRegion = 0; static unsigned opt_region = 0; -static unsigned opt_showAdvSoundOptions = 0; -static unsigned opt_showAdvSystemOptions = 0; +static bool opt_showAdvSoundOptions = true; +static bool opt_showAdvSystemOptions = true; #if defined(PSP) || defined(PS2) static __attribute__((aligned(16))) uint16_t retro_palette[256]; @@ -615,7 +616,7 @@ struct st_palettes palettes[] = { #define NES_NTSC_WIDTH (((NES_NTSC_OUT_WIDTH(256) + 3) >> 2) << 2) static unsigned use_ntsc = 0; -static unsigned burst_phase; +static unsigned burst_phase = 0; static nes_ntsc_t nes_ntsc; static nes_ntsc_setup_t ntsc_setup; static uint16_t *ntsc_video_out = NULL; /* for ntsc blit buffer */ @@ -625,6 +626,9 @@ static void NTSCFilter_Cleanup(void) if (ntsc_video_out) free(ntsc_video_out); ntsc_video_out = NULL; + + use_ntsc = 0; + burst_phase = 0; } static void NTSCFilter_Init(void) @@ -862,25 +866,163 @@ void retro_set_controller_port_device(unsigned port, unsigned device) } } +/* Core options 'update display' callback */ +static bool update_option_visibility(void) +{ + struct retro_variable var = {0}; + bool updated = false; + size_t i, size; + + /* If frontend supports core option categories, + * then fceumm_show_adv_system_options and + * fceumm_show_adv_sound_options are ignored + * and no options should be hidden */ + if (libretro_supports_option_categories) + return false; + + var.key = "fceumm_show_adv_system_options"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool opt_showAdvSystemOptions_prev = opt_showAdvSystemOptions; + + opt_showAdvSystemOptions = true; + if (strcmp(var.value, "disabled") == 0) + opt_showAdvSystemOptions = false; + + if (opt_showAdvSystemOptions != opt_showAdvSystemOptions_prev) + { + struct retro_core_option_display option_display; + unsigned i; + unsigned size; + char options_list[][25] = { + "fceumm_overclocking", + "fceumm_ramstate", + "fceumm_nospritelimit", + "fceumm_up_down_allowed", + "fceumm_show_crosshair" + }; + + option_display.visible = opt_showAdvSystemOptions; + size = sizeof(options_list) / sizeof(options_list[0]); + for (i = 0; i < size; i++) + { + option_display.key = options_list[i]; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + } + + updated = true; + } + } + + var.key = "fceumm_show_adv_sound_options"; + var.value = NULL; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool opt_showAdvSoundOptions_prev = opt_showAdvSoundOptions; + + opt_showAdvSoundOptions = true; + if (strcmp(var.value, "disabled") == 0) + opt_showAdvSoundOptions = false; + + if (opt_showAdvSoundOptions != opt_showAdvSoundOptions_prev) + { + struct retro_core_option_display option_display; + unsigned i; + unsigned size; + char options_list[][25] = { + "fceumm_sndvolume", + "fceumm_sndquality", + "fceumm_swapduty", + "fceumm_apu_1", + "fceumm_apu_2", + "fceumm_apu_3", + "fceumm_apu_4", + "fceumm_apu_5" + }; + + option_display.visible = opt_showAdvSoundOptions; + size = sizeof(options_list) / sizeof(options_list[0]); + for (i = 0; i < size; i++) + { + option_display.key = options_list[i]; + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + } + + updated = true; + } + } + + return updated; +} + static void set_variables(void) { + struct retro_core_option_display option_display; unsigned i = 0, index = 0; + option_display.visible = false; + /* Initialize main core option struct */ - for (i = 0; i < MAX_CORE_OPTIONS; i++) - option_defs_us[i] = option_defs_empty; + memset(&option_defs_us, 0, sizeof(option_defs_us)); /* Write common core options to main struct */ - while (option_defs_common[index].key) { - option_defs_us[index] = option_defs_common[index]; + while (option_defs_us_common[index].key) { + memcpy(&option_defs_us[index], &option_defs_us_common[index], + sizeof(struct retro_core_option_v2_definition)); index++; } /* Append dipswitch settings to core options if available */ - index += set_dipswitch_variables(index, option_defs_us); - option_defs_us[index] = option_defs_empty; + set_dipswitch_variables(index, option_defs_us); - libretro_set_core_options(environ_cb); + libretro_supports_option_categories = false; + libretro_set_core_options(environ_cb, + &libretro_supports_option_categories); + + /* If frontend supports core option categories, + * fceumm_show_adv_system_options and + * fceumm_show_adv_sound_options are unused + * and should be hidden */ + if (libretro_supports_option_categories) + { + option_display.key = "fceumm_show_adv_system_options"; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + + option_display.key = "fceumm_show_adv_sound_options"; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + } + /* If frontend does not support core option + * categories, core options may be shown/hidden + * at runtime. In this case, register 'update + * display' callback, so frontend can update + * core options menu without calling retro_run() */ + else + { + struct retro_core_options_update_display_callback update_display_cb; + update_display_cb.callback = update_option_visibility; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_UPDATE_DISPLAY_CALLBACK, + &update_display_cb); + } + + /* VS UNISystem games use internal palette regardless + * of user setting, so hide fceumm_palette option */ + if (GameInfo && (GameInfo->type == GIT_VSUNI)) + { + option_display.key = "fceumm_palette"; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, + &option_display); + } } void retro_set_environment(retro_environment_t cb) @@ -1461,68 +1603,7 @@ static void check_variables(bool startup) update_dipswitch(); - var.key = "fceumm_show_adv_system_options"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - unsigned newval = (!strcmp(var.value, "enabled")) ? 1 : 0; - if ((opt_showAdvSystemOptions != newval) || startup) - { - struct retro_core_option_display option_display; - unsigned i; - unsigned size; - char options_list[][25] = { - "fceumm_overclocking", - "fceumm_ramstate", - "fceumm_nospritelimit", - "fceumm_up_down_allowed", - "fceumm_show_crosshair" - }; - - opt_showAdvSystemOptions = newval; - option_display.visible = opt_showAdvSystemOptions; - size = sizeof(options_list) / sizeof(options_list[0]); - for (i = 0; i < size; i++) - { - option_display.key = options_list[i]; - environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); - } - } - } - - var.key = "fceumm_show_adv_sound_options"; - var.value = NULL; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - unsigned newval = (!strcmp(var.value, "enabled")) ? 1 : 0; - if ((opt_showAdvSoundOptions != newval) || startup) - { - struct retro_core_option_display option_display; - unsigned i; - unsigned size; - char options_list[][25] = { - "fceumm_sndvolume", - "fceumm_sndquality", - "fceumm_swapduty", - "fceumm_apu_1", - "fceumm_apu_2", - "fceumm_apu_3", - "fceumm_apu_4", - "fceumm_apu_5" - }; - - opt_showAdvSoundOptions = newval; - option_display.visible = opt_showAdvSoundOptions; - size = sizeof(options_list) / sizeof(options_list[0]); - for (i = 0; i < size; i++) - { - option_display.key = options_list[i]; - environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY, &option_display); - } - } - } + update_option_visibility(); } static int mzx = 0, mzy = 0; @@ -1838,12 +1919,12 @@ static void retro_run_blit(uint8_t *gfx) if (!ps2) { if (!environ_cb(RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE, (void **)&ps2) || !ps2) { - printf("Failed to get HW rendering interface!\n"); + FCEU_printf(" Failed to get HW rendering interface!\n"); return; } if (ps2->interface_version != RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION) { - printf("HW render interface mismatch, expected %u, got %u!\n", + FCEU_printf(" HW render interface mismatch, expected %u, got %u!\n", RETRO_HW_RENDER_INTERFACE_GSKIT_PS2_VERSION, ps2->interface_version); return; } diff --git a/src/drivers/libretro/libretro_core_options.h b/src/drivers/libretro/libretro_core_options.h index e3deb8e..0df0a88 100644 --- a/src/drivers/libretro/libretro_core_options.h +++ b/src/drivers/libretro/libretro_core_options.h @@ -17,6 +17,8 @@ extern "C" { ******************************** */ +#define MAX_CORE_OPTIONS 34 + /* RETRO_LANGUAGE_ENGLISH */ /* Default language: @@ -26,13 +28,47 @@ extern "C" { * - Will be used as a fallback for any missing entries in * frontend language definition */ -#define MAX_CORE_OPTIONS 32 +struct retro_core_option_v2_category option_cats_us[] = { + { + "video", + "Video", +#ifdef HAVE_NTSC_FILTER + "Configure aspect ratio / display cropping / color palette / video filter options." +#else + "Configure aspect ratio / display cropping / color palette options." +#endif + }, + { + "audio", + "Audio", + "Configure sound quality / volume / channel enable settings." + }, + { + "input", + "Input", + "Configure turbo / light gun parameters." + }, + { + "hacks", + "Emulation Hacks", + "Configure processor overclocking and emulation accuracy parameters affecting low-level performance and compatibility." + }, + { + "dip_switch", + "DIP Switches", + "Configure arcade game settings." + }, + { NULL, NULL, NULL }, +}; -struct retro_core_option_definition option_defs_common[] = { +struct retro_core_option_v2_definition option_defs_us_common[] = { { "fceumm_region", "Region", + NULL, "Force core to use NTSC, PAL or Dendy region timings.", + NULL, + NULL, { { "Auto", NULL }, { "NTSC", NULL }, @@ -43,101 +79,56 @@ struct retro_core_option_definition option_defs_common[] = { "Auto", }, { - "fceumm_overclocking", - "Overclock", - "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-On Fill (Needs Restart)", - "Choose RAM startup during power up. Some games rely on initial ram values for random generator as an example.", - { - { "fill $ff", "$FF" }, - { "fill $00", "$00" }, - { "random", "random" }, - { NULL, NULL}, - }, - "fill $ff", - }, - { - "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.", + "fceumm_show_adv_system_options", + "Show Advanced System Options", + NULL, + "Show advanced system options and tweaks.", + NULL, + NULL, { { "disabled", NULL }, { "enabled", NULL }, - { NULL, NULL}, - }, - "disabled", - }, -#ifdef HAVE_NTSC_FILTER - { - "fceumm_ntsc_filter", - "NTSC Filter", - "Enable blargg NTSC filters.", - { - { "disabled", NULL }, - { "composite", NULL }, - { "svideo", NULL }, - { "rgb", NULL }, - { "monochrome", NULL }, { NULL, NULL }, }, "disabled" }, -#endif { - "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).", + "fceumm_show_adv_sound_options", + "Show Advanced Sound Options", + NULL, + "Show advanced sound options and tweaks.", + NULL, + NULL, { - { "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}, + { "disabled", NULL }, + { "enabled", NULL }, + { NULL, NULL }, }, - "default", + "disabled" }, { "fceumm_aspect", "Aspect Ratio", + NULL, "Choose preferred aspect ratio.", + NULL, + "video", { { "8:7 PAR", NULL }, { "4:3", NULL }, - { "PP", NULL }, + { "PP", "Pixel Perfect" }, { NULL, NULL}, }, "8:7 PAR", }, -#ifdef PSP +#ifdef PSP /* overscan options */ { "fceumm_overscan", "Crop Overscan", - "Removes 8 pixel overscan from all sides", + NULL, + "Removes 8 pixel overscan from all sides of the screen.", + NULL, + "video", { { "enabled", NULL }, { "disabled", NULL }, @@ -149,7 +140,10 @@ struct retro_core_option_definition option_defs_common[] = { { "fceumm_overscan_h", "Crop Horizontal Overscan", - "Removes 8 pixel from left and right side of the screen to simulate overscan seen on standard CRT television.", + NULL, + "Removes 8 pixels from left and right sides of the screen to simulate overscan seen on standard CRT televisions.", + NULL, + "video", { { "disabled", NULL }, { "enabled", NULL }, @@ -157,10 +151,13 @@ struct retro_core_option_definition option_defs_common[] = { }, "disabled", }, - { + { "fceumm_overscan_v", "Crop Vertical Overscan", - "Removes 8 pixel from the top and bottom of the screen to simulate overscan seen on standard CRT television.", + NULL, + "Removes 8 pixels from the top and bottom of the screen to simulate overscan seen on standard CRT televisions.", + NULL, + "video", { { "disabled", NULL }, { "enabled", NULL }, @@ -170,9 +167,77 @@ struct retro_core_option_definition option_defs_common[] = { }, #endif /* overscan options */ { - "fceumm_up_down_allowed", - "Allow Opposing Directions", - "Allows simultaneous UP+DOWN or LEFT+RIGHT button combinations which can create different effects in some games.", + "fceumm_palette", + "Color Palette", + NULL, + "Choose from pre-generated palettes, a custom 64x3 palette from file or raw format (needs to use a nes-decoder shader).", + NULL, + "video", + { + { "default", "Default" }, + { "asqrealc", "AspiringSquire's Real" }, + { "nintendo-vc", "Nintendo Virtual Console" }, + { "rgb", "Nintendo RGB PPU" }, + { "yuv-v3", "FBX's YUV-V3" }, + { "unsaturated-final", "FBX's Unsaturated-Final" }, + { "sony-cxa2025as-us", "Sony CXA2025AS US" }, + { "pal", "PAL" }, + { "bmf-final2", "BMF's Final 2" }, + { "bmf-final3", "BMF's Final 3" }, + { "smooth-fbx", "FBX's Smooth" }, + { "composite-direct-fbx", "FBX's Composite Direct" }, + { "pvm-style-d93-fbx", "FBX's PVM Style D93" }, + { "ntsc-hardware-fbx", "FBX's NTSC Hardware" }, + { "nes-classic-fbx-fs", "FBX's NES-Classic FS" }, + { "nescap", "RGBSource's NESCAP" }, + { "wavebeam", "nakedarthur's Wavebeam" }, + { "raw", "Raw" }, + { "custom", "Custom" }, + { NULL, NULL}, + }, + "default", + }, +#ifdef HAVE_NTSC_FILTER + { + "fceumm_ntsc_filter", + "NTSC Filter", + NULL, + "Enable blargg NTSC filters.", + NULL, + "video", + { + { "disabled", NULL }, + { "composite", "Composite" }, + { "svideo", "S-Video" }, + { "rgb", "RGB" }, + { "monochrome", "Monochrome" }, + { NULL, NULL }, + }, + "disabled" + }, +#endif + { + "fceumm_sndquality", + "Sound Quality", + NULL, + "Enable higher quality sound. Increases performance requirements.", + NULL, + "audio", + { + { "Low", NULL }, + { "High", NULL }, + { "Very High", NULL }, + { NULL, NULL}, + }, + "Low", + }, + { + "fceumm_swapduty", + "Swap Audio Duty Cycles", + "Swap Duty Cycles", + "Simulates the sound from famiclones that have the pulse wave channels duty cycle bits reversed.", + NULL, + "audio", { { "disabled", NULL }, { "enabled", NULL }, @@ -180,10 +245,106 @@ struct retro_core_option_definition option_defs_common[] = { }, "disabled", }, + { + "fceumm_sndvolume", + "Master Volume", + NULL, + "Change master volume level.", + NULL, + "audio", + { + { "0", "0%" }, + { "1", "10%" }, + { "2", "20%" }, + { "3", "30%" }, + { "4", "40%" }, + { "5", "50%" }, + { "6", "60%" }, + { "7", "70%" }, + { "8", "80%" }, + { "9", "90%" }, + { "10", "100%" }, + { NULL, NULL}, + }, + "7", + }, + { + "fceumm_apu_1", + "Audio Channel 1 (Square 1)", + "Channel 1 (Square 1)", + "Enables or disables pulse wave generator audio output 1.", + NULL, + "audio", + { + { "enabled", NULL }, + { "disabled", NULL }, + { NULL, NULL}, + }, + "enabled", + }, + { + "fceumm_apu_2", + "Audio Channel 2 (Square 2)", + "Channel 2 (Square 2)", + "Enables or disables pulse wave generator audio output 2.", + NULL, + "audio", + { + { "enabled", NULL }, + { "disabled", NULL }, + { NULL, NULL}, + }, + "enabled", + }, + { + "fceumm_apu_3", + "Audio Channel 3 (Triangle)", + "Channel 3 (Triangle)", + "Enables or disables triangle wave generator audio output.", + NULL, + "audio", + { + { "enabled", NULL }, + { "disabled", NULL }, + { NULL, NULL}, + }, + "enabled", + }, + { + "fceumm_apu_4", + "Audio Channel 4 (Noise)", + "Channel 4 (Noise)", + "Enables or disables noise generator audio output.", + NULL, + "audio", + { + { "enabled", NULL }, + { "disabled", NULL }, + { NULL, NULL}, + }, + "enabled", + }, + { + "fceumm_apu_5", + "Audio Channel 5 (PCM)", + "Channel 5 (PCM)", + "Enables or disables delta modulation channel audio output.", + NULL, + "audio", + { + { "enabled", NULL }, + { "disabled", NULL }, + { NULL, NULL}, + }, + "enabled", + }, { "fceumm_turbo_enable", "Turbo Enable", + NULL, "Enables or disables turbo buttons.", + NULL, + "input", { { "None", NULL }, { "Player 1", NULL }, @@ -196,7 +357,10 @@ struct retro_core_option_definition option_defs_common[] = { { "fceumm_turbo_delay", "Turbo Delay (in frames)", + NULL, "Repeat rate of turbo buttons in frames.", + NULL, + "input", { { "1", NULL }, { "2", NULL }, @@ -213,19 +377,25 @@ struct retro_core_option_definition option_defs_common[] = { { "fceumm_zapper_mode", "Zapper Mode", + NULL, "Selects device to use for zapper games.", + NULL, + "input", { - { "lightgun", NULL }, - { "touchscreen", NULL }, - { "mouse", NULL }, + { "lightgun", "Lightgun" }, + { "touchscreen", "Touchscreen" }, + { "mouse", "Mouse" }, { NULL, NULL}, }, "lightgun", }, { "fceumm_show_crosshair", - "Show Crosshair", + "Show Zapper Crosshair", + NULL, "Shows or hides on-screen crosshairs when using a zapper.", + NULL, + "input", { { "enabled", NULL }, { "disabled", NULL }, @@ -236,7 +406,10 @@ struct retro_core_option_definition option_defs_common[] = { { "fceumm_zapper_tolerance", "Zapper Tolerance", + NULL, "Sets how many pixels from target area is on target.", + NULL, + "input", { { "0", NULL }, { "1", NULL }, @@ -264,21 +437,12 @@ struct retro_core_option_definition option_defs_common[] = { "6", }, { - "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.", + "fceumm_up_down_allowed", + "Allow Opposing Directions", + NULL, + "Allows simultaneous UP+DOWN or LEFT+RIGHT button combinations which can create different effects in some games.", + NULL, + "input", { { "disabled", NULL }, { "enabled", NULL }, @@ -287,156 +451,68 @@ struct retro_core_option_definition option_defs_common[] = { "disabled", }, { - "fceumm_sndvolume", - "Master Volume", - "Change master volume level", + "fceumm_nospritelimit", + "No Sprite Limit", + NULL, + "Removes the 8-per-scanline hardware limit. This reduces sprite flickering but can cause some games to glitch since some use this for effects.", + NULL, + "hacks", { - { "0", NULL }, - { "1", NULL }, - { "2", NULL }, - { "3", NULL }, - { "4", NULL }, - { "5", NULL }, - { "6", NULL }, - { "7", NULL }, - { "8", NULL }, - { "9", NULL }, - { "10", NULL }, + { "disabled", NULL }, + { "enabled", NULL }, { NULL, NULL}, }, - "7", + "disabled", }, { - "fceumm_apu_1", - "Channel 1 (Square 1)", - "Enables or disables pulse wave generator audio output 1.", + "fceumm_overclocking", + "Overclock", + NULL, + "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.", + NULL, + "hacks", { - { "enabled", NULL }, - { "disabled", NULL }, + { "disabled", NULL }, + { "2x-Postrender", NULL }, + { "2x-VBlank", NULL }, { NULL, NULL}, }, - "enabled", + "disabled", }, { - "fceumm_apu_2", - "Channel 2 (Square 2)", - "Enables or disables pulse wave generator audio output 2.", + "fceumm_ramstate", + "RAM Power-On Fill (Restart)", + NULL, + "Choose RAM startup during power up. Some games rely on initial ram values for random generator as an example.", + NULL, + "hacks", { - { "enabled", NULL }, - { "disabled", NULL }, + { "fill $ff", "$FF" }, + { "fill $00", "$00" }, + { "random", "Random" }, { NULL, NULL}, }, - "enabled", + "fill $ff", }, - { - "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", - }, - { - "fceumm_show_adv_system_options", - "Show Advanced System Options", - "Show advanced system options and tweaks.", - { - { "disabled", NULL }, - { "enabled", NULL }, - { NULL, NULL }, - }, - "disabled" - }, - { - "fceumm_show_adv_sound_options", - "Show Advanced Sound Options", - "Show advanced sound options and tweaks.", - { - { "disabled", NULL }, - { "enabled", NULL }, - { NULL, NULL }, - }, - "disabled" - }, - - { NULL, NULL, NULL, { {0} }, NULL }, + { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL }, }; -struct retro_core_option_definition option_defs_empty = { - NULL, NULL, NULL, { {0} }, NULL +struct retro_core_option_v2_definition option_defs_us[MAX_CORE_OPTIONS]; + +struct retro_core_options_v2 options_us = { + option_cats_us, + option_defs_us }; -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 */ +#ifndef HAVE_NO_LANGEXTRA +struct retro_core_options_v2 *options_intl[RETRO_LANGUAGE_LAST] = { + &options_us, /* RETRO_LANGUAGE_ENGLISH */ NULL, /* RETRO_LANGUAGE_JAPANESE */ NULL, /* RETRO_LANGUAGE_FRENCH */ NULL, /* RETRO_LANGUAGE_SPANISH */ @@ -456,6 +532,7 @@ struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = { NULL, /* RETRO_LANGUAGE_GREEK */ NULL, /* RETRO_LANGUAGE_TURKISH */ }; +#endif /* ******************************** @@ -470,41 +547,61 @@ struct retro_core_option_definition *option_defs_intl[RETRO_LANGUAGE_LAST] = { * be as painless as possible for core devs) */ -static INLINE void libretro_set_core_options(retro_environment_t environ_cb) +static INLINE void libretro_set_core_options(retro_environment_t environ_cb, + bool *categories_supported) { - unsigned version = 0; + unsigned version = 0; +#ifndef HAVE_NO_LANGEXTRA + unsigned language = 0; +#endif - if (!environ_cb) + if (!environ_cb || !categories_supported) return; - if (environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version) && (version >= 1)) - { - struct retro_core_options_intl core_options_intl; - unsigned language = 0; + *categories_supported = false; - core_options_intl.us = option_defs_us; + if (!environ_cb(RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION, &version)) + version = 0; + + if (version >= 2) + { +#ifndef HAVE_NO_LANGEXTRA + struct retro_core_options_v2_intl core_options_intl; + + core_options_intl.us = &options_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]; + core_options_intl.local = options_intl[language]; - environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_intl); + *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2_INTL, + &core_options_intl); +#else + *categories_supported = environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2, + &options_us); +#endif } else { - size_t i; + size_t i, j; size_t option_index = 0; size_t num_options = 0; + struct retro_core_option_definition + *option_v1_defs_us = NULL; +#ifndef HAVE_NO_LANGEXTRA + size_t num_options_intl = 0; + struct retro_core_option_v2_definition + *option_defs_intl = NULL; + struct retro_core_option_definition + *option_v1_defs_intl = NULL; + struct retro_core_options_intl + core_options_v1_intl; +#endif 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' */ + /* Determine total number of options */ while (true) { if (option_defs_us[num_options].key) @@ -513,92 +610,193 @@ static INLINE void libretro_set_core_options(retro_environment_t environ_cb) 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++) + if (version >= 1) { - 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; + /* Allocate US array */ + option_v1_defs_us = (struct retro_core_option_definition *) + calloc(num_options + 1, sizeof(struct retro_core_option_definition)); - 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) + /* Copy parameters from option_defs_us array */ + for (i = 0; i < num_options; i++) { - size_t num_values = 0; + struct retro_core_option_v2_definition *option_def_us = &option_defs_us[i]; + struct retro_core_option_value *option_values = option_def_us->values; + struct retro_core_option_definition *option_v1_def_us = &option_v1_defs_us[i]; + struct retro_core_option_value *option_v1_values = option_v1_def_us->values; - /* Determine number of values */ + option_v1_def_us->key = option_def_us->key; + option_v1_def_us->desc = option_def_us->desc; + option_v1_def_us->info = option_def_us->info; + option_v1_def_us->default_value = option_def_us->default_value; + + /* Values must be copied individually... */ + while (option_values->value) + { + option_v1_values->value = option_values->value; + option_v1_values->label = option_values->label; + + option_values++; + option_v1_values++; + } + } + +#ifndef HAVE_NO_LANGEXTRA + if (environ_cb(RETRO_ENVIRONMENT_GET_LANGUAGE, &language) && + (language < RETRO_LANGUAGE_LAST) && (language != RETRO_LANGUAGE_ENGLISH) && + options_intl[language]) + option_defs_intl = options_intl[language]->definitions; + + if (option_defs_intl) + { + /* Determine number of intl options */ 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++; - } + if (option_defs_intl[num_options_intl].key) + num_options_intl++; else break; } - /* Build values string */ - if (num_values > 1) + /* Allocate intl array */ + option_v1_defs_intl = (struct retro_core_option_definition *) + calloc(num_options_intl + 1, sizeof(struct retro_core_option_definition)); + + /* Copy parameters from option_defs_intl array */ + for (i = 0; i < num_options_intl; i++) { - size_t j; + struct retro_core_option_v2_definition *option_def_intl = &option_defs_intl[i]; + struct retro_core_option_value *option_values = option_def_intl->values; + struct retro_core_option_definition *option_v1_def_intl = &option_v1_defs_intl[i]; + struct retro_core_option_value *option_v1_values = option_v1_def_intl->values; - buf_len += num_values - 1; - buf_len += strlen(desc); + option_v1_def_intl->key = option_def_intl->key; + option_v1_def_intl->desc = option_def_intl->desc; + option_v1_def_intl->info = option_def_intl->info; + option_v1_def_intl->default_value = option_def_intl->default_value; - 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++) + /* Values must be copied individually... */ + while (option_values->value) { - if (j != default_index) - { - strcat(values_buf[i], "|"); - strcat(values_buf[i], values[j].value); - } + option_v1_values->value = option_values->value; + option_v1_values->label = option_values->label; + + option_values++; + option_v1_values++; } } } - variables[option_index].key = key; - variables[option_index].value = values_buf[i]; - option_index++; + core_options_v1_intl.us = option_v1_defs_us; + core_options_v1_intl.local = option_v1_defs_intl; + + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS_INTL, &core_options_v1_intl); +#else + environ_cb(RETRO_ENVIRONMENT_SET_CORE_OPTIONS, option_v1_defs_us); +#endif + } + else + { + /* 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_show_adv_system_options") == 0) || + (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 > 0) + { + 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); } - /* Set variables */ - environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, variables); - error: - /* Clean up */ + + if (option_v1_defs_us) + { + free(option_v1_defs_us); + option_v1_defs_us = NULL; + } + +#ifndef HAVE_NO_LANGEXTRA + if (option_v1_defs_intl) + { + free(option_v1_defs_intl); + option_v1_defs_intl = NULL; + } +#endif + if (values_buf) { for (i = 0; i < num_options; i++) diff --git a/src/drivers/libretro/libretro_core_options_intl.h b/src/drivers/libretro/libretro_core_options_intl.h new file mode 100644 index 0000000..038553a --- /dev/null +++ b/src/drivers/libretro/libretro_core_options_intl.h @@ -0,0 +1,91 @@ +#ifndef LIBRETRO_CORE_OPTIONS_INTL_H__ +#define LIBRETRO_CORE_OPTIONS_INTL_H__ + +#if defined(_MSC_VER) && (_MSC_VER >= 1500 && _MSC_VER < 1900) +/* https://support.microsoft.com/en-us/kb/980263 */ +#pragma execution_character_set("utf-8") +#pragma warning(disable:4566) +#endif + +#include + +/* + ******************************** + * VERSION: 2.0 + ******************************** + * + * - 2.0: Add support for core options v2 interface + * - 1.3: Move translations to libretro_core_options_intl.h + * - libretro_core_options_intl.h includes BOM and utf-8 + * fix for MSVC 2010-2013 + * - Added HAVE_NO_LANGEXTRA flag to disable translations + * on platforms/compilers without BOM support + * - 1.2: Use core options v1 interface when + * RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION is >= 1 + * (previously required RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION == 1) + * - 1.1: Support generation of core options v0 retro_core_option_value + * arrays containing options with a single value + * - 1.0: First commit +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ******************************** + * Core Option Definitions + ******************************** +*/ + +/* 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 */ + +/* RETRO_LANGUAGE_SLOVAK */ + +/* RETRO_LANGUAGE_PERSIAN */ + +/* RETRO_LANGUAGE_HEBREW */ + +/* RETRO_LANGUAGE_ASTURIAN */ + +/* RETRO_LANGUAGE_FINNISH */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/drivers/libretro/libretro_dipswitch.c b/src/drivers/libretro/libretro_dipswitch.c index e31116c..accdb96 100644 --- a/src/drivers/libretro/libretro_dipswitch.c +++ b/src/drivers/libretro/libretro_dipswitch.c @@ -1069,11 +1069,7 @@ enum { DPSW_NWC, }; -static struct retro_core_option_definition option_defs_empty = { - NULL, NULL, NULL, { {0} }, NULL -}; - -static struct retro_core_option_definition vscoreopt[MAX_CORE_OPTIONS]; +static struct retro_core_option_v2_definition vscoreopt[MAX_CORE_OPTIONS]; static VSUNIGAME *vsgame = NULL; static char *core_key[MAX_CORE_OPTIONS]; @@ -1098,7 +1094,7 @@ static const char *str_to_corekey(char *s) return str; } -static void make_core_options(struct retro_core_option_definition *vs_core_options) +static void make_core_options(struct retro_core_option_v2_definition *vs_core_options) { unsigned i, j; @@ -1109,6 +1105,9 @@ static void make_core_options(struct retro_core_option_definition *vs_core_optio const char *option_name = vsgame->core_options[i].option_name; char key[100] = {0}; + memset(&vs_core_options[i], 0, + sizeof(struct retro_core_option_v2_definition)); + /* Set core key and sanitize string */ sprintf(key, "fceumm_dipswitch_%s-%s", game_name, option_name); core_key[i] = calloc(strlen(key) + 1, sizeof(char)); @@ -1118,8 +1117,8 @@ static void make_core_options(struct retro_core_option_definition *vs_core_optio /* Set desc */ vs_core_options[i].desc = option_name; - /* Set info */ - vs_core_options[i].info = NULL; + /* Set category_key */ + vs_core_options[i].category_key = "dip_switch"; /* Set core values */ for (j = 0; j < numValues[i]; j++) { @@ -1127,8 +1126,6 @@ static void make_core_options(struct retro_core_option_definition *vs_core_optio vs_core_options[i].values[j].value = var_value; } - vs_core_options[i].values[j] = vars_empty; - /* Set default value. Top entry used as default */ vs_core_options[i].default_value = vsgame->core_options[i].settings[0].name; } @@ -1241,11 +1238,14 @@ static void update_dipswitch_vsuni(void) } /* Nintendo World Championships 1990 */ -static struct retro_core_option_definition dipswitch_nwc[] = { +static struct retro_core_option_v2_definition dipswitch_nwc[] = { { "fceumm_dipswitch_nwc", "Gameplay Duration in minutes (Restart)", + NULL, "Sets the game timer in minutes.", + NULL, + "dip_switch", { { "0", "5:00" }, { "1", "5:19" }, @@ -1263,12 +1263,11 @@ static struct retro_core_option_definition dipswitch_nwc[] = { { "13", "9:04" }, { "14", "9:23" }, { "15", "9:42" }, - { NULL, NULL}, + { NULL, NULL }, }, "4", }, - - { NULL, NULL, NULL, { {0} }, NULL }, + { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL }, }; static void update_dipswitch_nwc(void) @@ -1292,7 +1291,7 @@ static void update_dipswitch_nwc(void) } } -size_t set_dipswitch_variables(unsigned current_index, struct retro_core_option_definition *vars) +void set_dipswitch_variables(unsigned current_index, struct retro_core_option_v2_definition *vars) { unsigned index = current_index; int dipsw_size = 0; @@ -1310,8 +1309,7 @@ size_t set_dipswitch_variables(unsigned current_index, struct retro_core_option_ dipswitch_type = DPSW_VSUNI; /* Initialize dipswitch struct with empty values */ - for (i = 0; i < MAX_CORE_OPTIONS; i++) - vscoreopt[i] = option_defs_empty; + memset(&vscoreopt, 0, sizeof(vscoreopt)); /* Count number of core options and the number of values for each */ for (i = 0; i < MAX_CORE_OPTIONS; i++) { @@ -1328,12 +1326,13 @@ size_t set_dipswitch_variables(unsigned current_index, struct retro_core_option_ /* Append dipswitch struct to main core options struct */ while (vscoreopt[dipsw_size].key) { - vars[index] = vscoreopt[dipsw_size]; + memcpy(&vars[index], &vscoreopt[dipsw_size], + sizeof(struct retro_core_option_v2_definition)); index++; dipsw_size++; } } - return (dipsw_size); + return; } /* Nintendo World Championship cart (Mapper 105)*/ @@ -1342,15 +1341,16 @@ size_t set_dipswitch_variables(unsigned current_index, struct retro_core_option_ dipswitch_type = DPSW_NWC; while (dipswitch_nwc[dipsw_size].key) { - vars[index] = dipswitch_nwc[dipsw_size]; + memcpy(&vars[index], &dipswitch_nwc[dipsw_size], + sizeof(struct retro_core_option_v2_definition)); index++; dipsw_size++; } - return (dipsw_size); + return; } dipswitch_type = DPSW_NONE; - return (0); + return; } void update_dipswitch(void) diff --git a/src/drivers/libretro/libretro_dipswitch.h b/src/drivers/libretro/libretro_dipswitch.h index bf6ace7..a0ef579 100644 --- a/src/drivers/libretro/libretro_dipswitch.h +++ b/src/drivers/libretro/libretro_dipswitch.h @@ -3,7 +3,7 @@ #include -size_t set_dipswitch_variables(unsigned current_index, struct retro_core_option_definition *vars); +void set_dipswitch_variables(unsigned current_index, struct retro_core_option_v2_definition *vars); void update_dipswitch(void); void DPSW_Cleanup(void); diff --git a/src/ntsc/nes_ntsc_config.h b/src/ntsc/nes_ntsc_config.h index 1a89293..56876d6 100644 --- a/src/ntsc/nes_ntsc_config.h +++ b/src/ntsc/nes_ntsc_config.h @@ -19,7 +19,7 @@ if you enable emphasis above. */ /* Each raw pixel input value is passed through this. You might want to mask the pixel index if you use the high bits as flags, etc. */ -#define NES_NTSC_ADJ_IN( in, deemp ) ( in & 0x3F ) | ( deemp << 6 ) +#define NES_NTSC_ADJ_IN( in, deemp ) (( in & 0x3F ) | ((deemp & 0x7) << 6)) /* For each pixel, this is the basic operation: output_color = color_palette [NES_NTSC_ADJ_IN( NES_NTSC_IN_T )] */ From 499f1c04de45bfaa044e307a20d97a0c18a3371b Mon Sep 17 00:00:00 2001 From: jdgleaver Date: Wed, 20 Oct 2021 16:31:45 +0100 Subject: [PATCH 149/295] Replace direct file access with VFS routines --- Makefile.common | 127 +- Makefile.libretro | 15 +- src/boards/copyfami_hwi.c | 22 +- src/cart.c | 26 +- src/cheat.c | 4 +- src/cheat.h | 4 +- src/debug.c | 28 +- src/driver.h | 13 +- src/drivers/libretro/griffin.c | 43 - .../compat/compat_posix_string.c | 104 ++ .../compat/compat_strcasestr.c | 58 + .../libretro/libretro-common/file/file_path.c | 1381 +++++++++++++++++ .../libretro-common/file/file_path_io.c | 151 ++ .../win32.h => compat/posix_string.h} | 57 +- .../include/compat/strcasestr.h | 48 + .../include/encodings/base64.h | 48 - .../libretro-common/include/file/file_path.h | 538 +++++++ .../{encodings/crc32.h => retro_assert.h} | 23 +- .../include/retro_environment.h | 114 ++ .../include/retro_miscellaneous.h | 203 +++ .../include/streams/file_stream.h | 117 ++ .../include/streams/file_stream_transforms.h | 101 ++ .../include/string/stdstring.h | 58 +- .../libretro-common/include/time/rtime.h | 48 + .../libretro-common/include/vfs/vfs.h | 111 ++ .../include/vfs/vfs_implementation.h | 76 + .../libretro-common/streams/file_stream.c | 678 ++++++++ .../streams/file_stream_transforms.c | 159 ++ .../libretro-common/string/stdstring.c | 247 ++- .../libretro/libretro-common/time/rtime.c | 81 + .../libretro-common/vfs/vfs_implementation.c | 1335 ++++++++++++++++ src/drivers/libretro/libretro.c | 98 +- src/fceu-endian.c | 45 +- src/fceu-endian.h | 7 +- src/fceu-memory.h | 17 - src/fceu-types.h | 26 - src/fceu.c | 12 +- src/fds.c | 35 +- src/file.c | 56 +- src/file.h | 14 +- src/general.c | 69 +- src/general.h | 8 +- src/palette.c | 18 +- src/state.h | 5 - 44 files changed, 5853 insertions(+), 575 deletions(-) delete mode 100644 src/drivers/libretro/griffin.c create mode 100644 src/drivers/libretro/libretro-common/compat/compat_posix_string.c create mode 100644 src/drivers/libretro/libretro-common/compat/compat_strcasestr.c create mode 100644 src/drivers/libretro/libretro-common/file/file_path.c create mode 100644 src/drivers/libretro/libretro-common/file/file_path_io.c rename src/drivers/libretro/libretro-common/include/{encodings/win32.h => compat/posix_string.h} (57%) create mode 100644 src/drivers/libretro/libretro-common/include/compat/strcasestr.h delete mode 100644 src/drivers/libretro/libretro-common/include/encodings/base64.h create mode 100644 src/drivers/libretro/libretro-common/include/file/file_path.h rename src/drivers/libretro/libretro-common/include/{encodings/crc32.h => retro_assert.h} (77%) create mode 100644 src/drivers/libretro/libretro-common/include/retro_environment.h create mode 100644 src/drivers/libretro/libretro-common/include/retro_miscellaneous.h create mode 100644 src/drivers/libretro/libretro-common/include/streams/file_stream.h create mode 100644 src/drivers/libretro/libretro-common/include/streams/file_stream_transforms.h create mode 100644 src/drivers/libretro/libretro-common/include/time/rtime.h create mode 100644 src/drivers/libretro/libretro-common/include/vfs/vfs.h create mode 100644 src/drivers/libretro/libretro-common/include/vfs/vfs_implementation.h create mode 100644 src/drivers/libretro/libretro-common/streams/file_stream.c create mode 100644 src/drivers/libretro/libretro-common/streams/file_stream_transforms.c create mode 100644 src/drivers/libretro/libretro-common/time/rtime.c create mode 100644 src/drivers/libretro/libretro-common/vfs/vfs_implementation.c diff --git a/Makefile.common b/Makefile.common index 9876d85..1aa3df5 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1,68 +1,77 @@ 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 -COREDEFINES = -D__LIBRETRO__ -DSOUND_QUALITY=0 -DPATH_MAX=1024 -DFCEU_VERSION_NUMERIC=9813 -DFRONTEND_SUPPORTS_RGB565 -ifeq ($(PSS_STYLE),2) -COREDEFINES += -DPSS_STYLE=2 -else -COREDEFINES += -DPSS_STYLE=1 +INCFLAGS := \ + -I$(CORE_DIR)/drivers/libretro \ + -I$(LIBRETRO_COMM_DIR)/include \ + -I$(CORE_DIR) \ + -I$(CORE_DIR)/input \ + -I$(CORE_DIR)/boards + +ifneq (,$(findstring msvc2003,$(platform))) + INCFLAGS += -I$(LIBRETRO_COMM_DIR)/include/compat/msvc endif -ifeq ($(TUP_CWD),) -FCEU_SRC_DIRS := $(CORE_DIR)/boards $(CORE_DIR)/input $(CORE_DIR)/mappers -SOURCES_C := $(foreach dir,$(FCEU_SRC_DIRS),$(wildcard $(dir)/*.c)) -else -SOURCES_C = $(CORE_DIR)/boards/*.c $(CORE_DIR)/input/*.c -endif +COREDEFINES = \ + -D__LIBRETRO__ \ + -DPATH_MAX=1024 \ + -DFCEU_VERSION_NUMERIC=9813 \ + -DFRONTEND_SUPPORTS_RGB565 + +FCEU_SRC_DIRS := \ + $(CORE_DIR)/boards \ + $(CORE_DIR)/input + +SOURCES_C := $(foreach dir,$(FCEU_SRC_DIRS),$(wildcard $(dir)/*.c)) ifeq ($(HAVE_NTSC),1) -COREDEFINES += -DHAVE_NTSC_FILTER -I$(CORE_DIR)/ntsc -SOURCES_C += $(CORE_DIR)/ntsc/nes_ntsc.c -endif - -ifeq ($(HAVE_GRIFFIN),1) -SOURCES_C += $(CORE_DIR)/drivers/libretro/griffin.c -else -SOURCES_C += \ - $(CORE_DIR)/drivers/libretro/libretro.c \ - $(CORE_DIR)/cart.c \ - $(CORE_DIR)/cheat.c \ - $(CORE_DIR)/crc32.c \ - $(CORE_DIR)/fceu-endian.c \ - $(CORE_DIR)/fceu-memory.c \ - $(CORE_DIR)/misc.c \ - $(CORE_DIR)/fceu.c \ - $(CORE_DIR)/fds.c \ - $(CORE_DIR)/fds_apu.c \ - $(CORE_DIR)/file.c \ - $(CORE_DIR)/filter.c \ - $(CORE_DIR)/general.c \ - $(CORE_DIR)/input.c \ - $(CORE_DIR)/md5.c \ - $(CORE_DIR)/nsf.c \ - $(CORE_DIR)/palette.c \ - $(CORE_DIR)/ppu.c \ - $(CORE_DIR)/sound.c \ - $(CORE_DIR)/state.c \ - $(CORE_DIR)/video.c \ - $(CORE_DIR)/vsuni.c - -ifeq ($(STATIC_LINKING),1) -else -SOURCES_C += $(CORE_DIR)/drivers/libretro/libretro-common/streams/memory_stream.c \ - $(CORE_DIR)/drivers/libretro/libretro-common/compat/compat_snprintf.c \ - $(CORE_DIR)/drivers/libretro/libretro-common/string/stdstring.c \ - $(CORE_DIR)/drivers/libretro/libretro-common/encodings/encoding_utf.c \ - $(CORE_DIR)/drivers/libretro/libretro-common/compat/compat_strl.c \ - $(CORE_DIR)/drivers/libretro/libretro-common/compat/fopen_utf8.c -endif - -ifeq ($(DEBUG),1) -SOURCES_C += $(CORE_DIR)/debug.c -endif + COREDEFINES += \ + -DHAVE_NTSC_FILTER \ + -I$(CORE_DIR)/ntsc + SOURCES_C += $(CORE_DIR)/ntsc/nes_ntsc.c endif SOURCES_C += \ - $(CORE_DIR)/ines.c \ - $(CORE_DIR)/unif.c $(CORE_DIR)/x6502.c \ - $(CORE_DIR)/drivers/libretro/libretro_dipswitch.c + $(CORE_DIR)/drivers/libretro/libretro.c \ + $(CORE_DIR)/drivers/libretro/libretro_dipswitch.c \ + $(CORE_DIR)/cart.c \ + $(CORE_DIR)/cheat.c \ + $(CORE_DIR)/crc32.c \ + $(CORE_DIR)/fceu-endian.c \ + $(CORE_DIR)/fceu-memory.c \ + $(CORE_DIR)/misc.c \ + $(CORE_DIR)/fceu.c \ + $(CORE_DIR)/fds.c \ + $(CORE_DIR)/fds_apu.c \ + $(CORE_DIR)/file.c \ + $(CORE_DIR)/filter.c \ + $(CORE_DIR)/general.c \ + $(CORE_DIR)/input.c \ + $(CORE_DIR)/md5.c \ + $(CORE_DIR)/nsf.c \ + $(CORE_DIR)/palette.c \ + $(CORE_DIR)/ppu.c \ + $(CORE_DIR)/sound.c \ + $(CORE_DIR)/state.c \ + $(CORE_DIR)/video.c \ + $(CORE_DIR)/vsuni.c \ + $(CORE_DIR)/ines.c \ + $(CORE_DIR)/unif.c \ + $(CORE_DIR)/x6502.c + +ifneq ($(STATIC_LINKING), 1) + SOURCES_C += \ + $(LIBRETRO_COMM_DIR)/compat/compat_posix_string.c \ + $(LIBRETRO_COMM_DIR)/compat/compat_snprintf.c \ + $(LIBRETRO_COMM_DIR)/compat/compat_strcasestr.c \ + $(LIBRETRO_COMM_DIR)/compat/compat_strl.c \ + $(LIBRETRO_COMM_DIR)/compat/fopen_utf8.c \ + $(LIBRETRO_COMM_DIR)/encodings/encoding_utf.c \ + $(LIBRETRO_COMM_DIR)/file/file_path.c \ + $(LIBRETRO_COMM_DIR)/file/file_path_io.c \ + $(LIBRETRO_COMM_DIR)/streams/file_stream.c \ + $(LIBRETRO_COMM_DIR)/streams/file_stream_transforms.c \ + $(LIBRETRO_COMM_DIR)/streams/memory_stream.c \ + $(LIBRETRO_COMM_DIR)/string/stdstring.c \ + $(LIBRETRO_COMM_DIR)/time/rtime.c \ + $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.c +endif diff --git a/Makefile.libretro b/Makefile.libretro index d4e86bf..ce0b618 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -1,7 +1,5 @@ DEBUG=0 -PSS_STYLE=1 EXTERNAL_ZLIB=0 -HAVE_GRIFFIN=1 STATIC_LINKING=0 ENDIANNESS_DEFINES= SIGNED_CHAR=0 @@ -161,7 +159,7 @@ else ifeq ($(platform), ps2) TARGET := $(TARGET_NAME)_libretro_$(platform).a CC = mips64r5900el-ps2-elf-gcc$(EXE_EXT) AR = mips64r5900el-ps2-elf-ar$(EXE_EXT) - FCEU_DEFINES := -DPATH_MAX=1024 -DINLINE=inline -DPSS_STYLE=1 -DFCEU_VERSION_NUMERIC=9813 -DHAVE_ASPRINTF + FCEU_DEFINES := -DPATH_MAX=1024 -DINLINE=inline -DFCEU_VERSION_NUMERIC=9813 -DHAVE_ASPRINTF ENDIANNESS_DEFINES := -DLSB_FIRST -DLOCAL_LE=1 PLATFORM_DEFINES := -DPS2 -D_EE -G0 -DFRONTEND_SUPPORTS_ABGR1555 -DRENDER_GSKIT_PS2 PLATFORM_DEFINES += -I$(PS2SDK)/ee/include -I$(PS2SDK)/common/include -I$(PS2DEV)/gsKit/include @@ -540,7 +538,6 @@ else ifneq (,$(findstring windows_msvc2017,$(platform))) export INCLUDE := $(INCLUDE);$(WindowsSDKSharedIncludeDir);$(WindowsSDKUCRTIncludeDir);$(WindowsSDKUMIncludeDir) export LIB := $(LIB);$(WindowsSDKUCRTLibDir);$(WindowsSDKUMLibDir) TARGET := $(TARGET_NAME)_libretro.dll - PSS_STYLE :=2 LDFLAGS += -DLL # Windows MSVC 2010 x64 @@ -564,7 +561,6 @@ INCFLAGS_PLATFORM = -I"$(WindowsSDKIncludeDir)" export INCLUDE := $(INCLUDE);$(WindowsSDKIncludeDir);$(WindowsSDKGlIncludeDir) export LIB := $(LIB);$(WindowsSDKLibDir) TARGET := $(TARGET_NAME)_libretro.dll -PSS_STYLE :=2 LDFLAGS += -DLL # Windows MSVC 2010 x86 @@ -588,7 +584,6 @@ INCFLAGS_PLATFORM = -I"$(WindowsSDKIncludeDir)" export INCLUDE := $(INCLUDE);$(WindowsSDKIncludeDir);$(WindowsSDKGlIncludeDir) export LIB := $(LIB);$(WindowsSDKLibDir) TARGET := $(TARGET_NAME)_libretro.dll -PSS_STYLE :=2 LDFLAGS += -DLL # Windows MSVC 2003 Xbox 1 @@ -602,7 +597,6 @@ export INCLUDE := $(XDK)\xbox\include export LIB := $(XDK)\xbox\lib PATH := $(call unixcygpath,$(XDK)/xbox/bin/vc71):$(PATH) -PSS_STYLE :=2 CFLAGS += -D_XBOX -D_XBOX1 CXXFLAGS += -D_XBOX -D_XBOX1 STATIC_LINKING=1 @@ -618,7 +612,6 @@ export INCLUDE := $(XEDK)/include/xbox export LIB := $(XEDK)/lib/xbox PATH := $(call unixcygpath,$(XEDK)/bin/win32):$(PATH) -PSS_STYLE :=2 CFLAGS += -D_XBOX -D_XBOX360 CXXFLAGS += -D_XBOX -D_XBOX360 ENDIANNESS_DEFINES += -DMSB_FIRST @@ -640,7 +633,6 @@ WindowsSdkDir := $(INETSDK) export INCLUDE := $(INCLUDE);$(INETSDK)/Include export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib TARGET := $(TARGET_NAME)_libretro.dll -PSS_STYLE :=2 LDFLAGS += -DLL CFLAGS += -D_CRT_SECURE_NO_DEPRECATE @@ -667,7 +659,6 @@ WindowsSDKLibDir := $(shell cygpath -w "$(WindowsSdkDir)\Lib") export INCLUDE := $(INCLUDE);$(WindowsSDKIncludeDir);$(WindowsSDKAtlIncludeDir);$(WindowsSDKCrtIncludeDir);$(WindowsSDKGlIncludeDir);$(WindowsSDKMfcIncludeDir);libretro-common/include/compat/msvc export LIB := $(LIB);$(WindowsSDKLibDir) TARGET := $(TARGET_NAME)_libretro.dll -PSS_STYLE :=2 LDFLAGS += -DLL CFLAGS += -D_CRT_SECURE_NO_DEPRECATE @@ -687,7 +678,6 @@ WindowsSdkDir := $(INETSDK) export INCLUDE := $(INCLUDE);$(INETSDK)/Include export LIB := $(LIB);$(WindowsSdkDir);$(INETSDK)/Lib TARGET := $(TARGET_NAME)_libretro.dll -PSS_STYLE :=2 LDFLAGS += -DLL CFLAGS += -D_CRT_SECURE_NO_DEPRECATE @@ -696,7 +686,6 @@ else TARGET := $(TARGET_NAME)_libretro.dll CC ?= gcc SHARED := -shared -static-libgcc -static-libstdc++ -s -Wl,--version-script=src/drivers/libretro/link.T - PSS_STYLE :=2 endif ifeq ($(DEBUG), 1) @@ -751,8 +740,6 @@ ifneq (,$(findstring msvc,$(platform))) COREDEFINES += -DINLINE=_inline endif -CFLAGS += -DWANT_GRIFFIN - OBJECTS := $(SOURCES_C:.c=.o) OBJECTS += $(RETROARCH_OBJECTS) diff --git a/src/boards/copyfami_hwi.c b/src/boards/copyfami_hwi.c index 7660c61..fde8fa4 100644 --- a/src/boards/copyfami_hwi.c +++ b/src/boards/copyfami_hwi.c @@ -26,6 +26,8 @@ #define NO_CACHE #define NO_RAM +#include + #include "__serial.h" #include "mapinc.h" @@ -167,28 +169,32 @@ static void GetStatus(SYNC_STATE *state) { } static int32 FetchNewCHRBank(int32 slot) { - FILE *ofile; + RFILE *ofile; char name[256]; int32 bank = chr_data.count++; CHR1KGetCmd[1] = slot << 2; SENDGET(CHR1KGetCmd, chr_data.buf[bank * 1024], 1024); sprintf(name, "%04x.chr", bank); - ofile = FCEUD_UTF8fopen(name, "wb"); - fwrite((void*)&chr_data.buf[bank * 1024], 1, 1024, ofile); - fclose(ofile); + ofile = filestream_open(name, + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); + filestream_write(ofile, (void*)&chr_data.buf[bank * 1024], 1024); + filestream_close(ofile); return bank; } static int32 FetchNewPRGBank(int32 slot) { - FILE *ofile; + RFILE *ofile; char name[256]; int32 bank = prg_data.count++; PRG8KGetCmd[1] = 0x80 + (slot << 5); SENDGET(PRG8KGetCmd, prg_data.buf[bank * 8192], 8192); sprintf(name, "%04x.prg", bank); - ofile = FCEUD_UTF8fopen(name, "wb"); - fwrite((void*)&prg_data.buf[bank * 8192], 1, 8192, ofile); - fclose(ofile); + ofile = filestream_open(name, + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); + filestream_write(ofile, (void*)&prg_data.buf[bank * 8192], 8192); + filestream_close(ofile); return bank; } diff --git a/src/cart.c b/src/cart.c index 911cb0c..345c419 100644 --- a/src/cart.c +++ b/src/cart.c @@ -22,6 +22,9 @@ #include #include +#include +#include + #include "fceu-types.h" #include "fceu.h" #include "ppu.h" @@ -340,7 +343,7 @@ void FixGenieMap(void); /* Called when a game(file) is opened successfully. */ void FCEU_OpenGenie(void) { - FILE *fp; + RFILE *fp = NULL; int x; if (!GENIEROM) { @@ -349,33 +352,38 @@ void FCEU_OpenGenie(void) { if (!(GENIEROM = (uint8*)FCEU_malloc(4096 + 1024))) return; fn = FCEU_MakeFName(FCEUMKF_GGROM, 0, 0); - fp = FCEUD_UTF8fopen(fn, "rb"); + + if (!string_is_empty(fn)) + fp = filestream_open(fn, + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); + if (!fp) { FCEU_PrintError("Error opening Game Genie ROM image!"); free(GENIEROM); GENIEROM = 0; return; } - if (fread(GENIEROM, 1, 16, fp) != 16) { + if (filestream_read(fp, GENIEROM, 16) != 16) { grerr: FCEU_PrintError("Error reading from Game Genie ROM image!"); free(GENIEROM); GENIEROM = 0; - fclose(fp); + filestream_close(fp); return; } if (GENIEROM[0] == 0x4E) { /* iNES ROM image */ - if (fread(GENIEROM, 1, 4096, fp) != 4096) + if (filestream_read(fp, GENIEROM, 4096) != 4096) goto grerr; - if (fseek(fp, 16384 - 4096, SEEK_CUR)) + if (filestream_seek(fp, 16384 - 4096, RETRO_VFS_SEEK_POSITION_CURRENT)) goto grerr; - if (fread(GENIEROM + 4096, 1, 256, fp) != 256) + if (filestream_read(fp, GENIEROM + 4096, 256) != 256) goto grerr; } else { - if (fread(GENIEROM + 16, 1, 4352 - 16, fp) != (4352 - 16)) + if (filestream_read(fp, GENIEROM + 16, 4352 - 16) != (4352 - 16)) goto grerr; } - fclose(fp); + filestream_close(fp); /* Workaround for the FCE Ultra CHR page size only being 1KB */ for (x = 0; x < 4; x++) diff --git a/src/cheat.c b/src/cheat.c index 0e82364..66af7b6 100644 --- a/src/cheat.c +++ b/src/cheat.c @@ -162,13 +162,13 @@ static int AddCheatEntry(char *name, uint32 addr, uint8 val, int compare, int st return(1); } -void FCEU_LoadGameCheats(FILE *override) +void FCEU_LoadGameCheats(void) { numsubcheats = savecheats = 0; RebuildSubCheats(); } -void FCEU_FlushGameCheats(FILE *override, int nosave) { +void FCEU_FlushGameCheats(void) { if (CheatComp) { free(CheatComp); diff --git a/src/cheat.h b/src/cheat.h index 9081c96..3052f54 100644 --- a/src/cheat.h +++ b/src/cheat.h @@ -6,8 +6,8 @@ extern uint8 *MMapPtrs[64]; void FCEU_CheatResetRAM(void); void FCEU_CheatAddRAM(int s, uint32 A, uint8 *p); -void FCEU_LoadGameCheats(FILE *override); -void FCEU_FlushGameCheats(FILE *override, int nosave); +void FCEU_LoadGameCheats(void); +void FCEU_FlushGameCheats(void); void FCEU_ApplyPeriodicCheats(void); void FCEU_PowerCheats(void); diff --git a/src/debug.c b/src/debug.c index 53449d6..bc48739 100644 --- a/src/debug.c +++ b/src/debug.c @@ -22,38 +22,44 @@ #include #include +#include + #include "fceu-types.h" #include "x6502.h" #include "fceu.h" #include "debug.h" #include "cart.h" - void FCEUI_DumpVid(const char *fname, uint32 start, uint32 end) { - FILE *fp = FCEUD_UTF8fopen(fname, "wb"); + RFILE *fp = filestream_open(fname, + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); fceuindbg = 1; start &= 0x3FFF; end &= 0x3FFF; for (; start <= end; start++) - fputc(VPage[start >> 10][start], fp); - fclose(fp); + filestream_putc(fp, VPage[start >> 10][start]); + filestream_close(fp); fceuindbg = 0; } void FCEUI_DumpMem(const char *fname, uint32 start, uint32 end) { - FILE *fp = FCEUD_UTF8fopen(fname, "wb"); + RFILE *fp = filestream_open(fname, + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); fceuindbg = 1; for (; start <= end; start++) - fputc(ARead[start](start), fp); - fclose(fp); + filestream_putc(fp, ARead[start](start)); + filestream_close(fp); fceuindbg = 0; } void FCEUI_LoadMem(const char *fname, uint32 start, int hl) { int t; - - FILE *fp = FCEUD_UTF8fopen(fname, "rb"); - while ((t = fgetc(fp)) >= 0) { + RFILE *fp = filestream_open(fname, + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); + while ((t = filestream_getc(fp)) >= 0) { if (start > 0xFFFF) break; if (hl) { extern uint8 *Page[32]; @@ -63,7 +69,7 @@ void FCEUI_LoadMem(const char *fname, uint32 start, int hl) { BWrite[start](start, t); start++; } - fclose(fp); + filestream_close(fp); } #ifdef FCEUDEF_DEBUGGER diff --git a/src/driver.h b/src/driver.h index 6c83d97..e16476e 100644 --- a/src/driver.h +++ b/src/driver.h @@ -27,8 +27,6 @@ extern "C" { #define FCEUNPCMD_LOADCHEATS 0x82 #define FCEUNPCMD_TEXT 0x90 -FILE *FCEUD_UTF8fopen(const char *fn, const char *mode); - /* This makes me feel dirty for some reason. */ void FCEU_printf(char *format, ...); #define FCEUI_printf FCEU_printf @@ -101,7 +99,7 @@ void FCEUI_DisableSpriteLimitation(int a); /* -1 = no change, 0 = show, 1 = hide, 2 = internal toggle */ void FCEUI_SetRenderDisable(int sprites, int bg); -FCEUGI *FCEUI_LoadGame(const char *name, uint8_t *buf, size_t bufsize); +FCEUGI *FCEUI_LoadGame(const char *name, const uint8_t *buf, size_t bufsize); #ifdef COPYFAMI /* Fake UNIF board to start new CFHI instance */ @@ -140,12 +138,9 @@ void FCEUI_FrameSkip(int x); /* First and last scanlines to render, for ntsc and pal emulation. */ void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall); -/* Sets the base directory(save states, snapshots, etc. are saved in directories - below this directory. */ -void FCEUI_SetBaseDirectory(char *dir); - -void FCEUI_SetSaveDirectory(char *sav_dir); - +/* Sets the base directory (bios and palette files are saved + in this directory. */ +void FCEUI_SetBaseDirectory(const char *dir); /* Tells FCE Ultra to copy the palette data pointed to by pal and use it. Data pointed to by pal needs to be 64*3 bytes in length. diff --git a/src/drivers/libretro/griffin.c b/src/drivers/libretro/griffin.c deleted file mode 100644 index 9a215eb..0000000 --- a/src/drivers/libretro/griffin.c +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef WANT_GRIFFIN - -#include "drivers/libretro/libretro.c" - -#ifndef STATIC_LINKING -#include "drivers/libretro/libretro-common/streams/memory_stream.c" -#include "drivers/libretro/libretro-common/string/stdstring.c" -#include "drivers/libretro/libretro-common/encodings/encoding_utf.c" -#include "drivers/libretro/libretro-common/compat/compat_strl.c" -#include "drivers/libretro/libretro-common/compat/fopen_utf8.c" -#endif - -#include "cart.c" -#include "cheat.c" -#include "crc32.c" - -#ifdef DEBUG -#include "debug.c" -#endif -#include "fceu-endian.c" -#include "fceu-memory.c" -#include "misc.c" -#include "fceu.c" -#include "fds.c" -#include "fds_apu.c" -#include "file.c" -#include "filter.c" -#include "general.c" -#include "input.c" -#include "md5.c" -#include "nsf.c" -#include "palette.c" -#include "ppu.c" -#include "sound.c" -#include "state.c" -#include "video.c" -#include "vsuni.c" - -/* #include "x6502.c" */ -/* #include "ines.c" */ -/* #include "unif.c" */ - -#endif diff --git a/src/drivers/libretro/libretro-common/compat/compat_posix_string.c b/src/drivers/libretro/libretro-common/compat/compat_posix_string.c new file mode 100644 index 0000000..6a2f07e --- /dev/null +++ b/src/drivers/libretro/libretro-common/compat/compat_posix_string.c @@ -0,0 +1,104 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (compat_posix_string.c). + * --------------------------------------------------------------------------------------- + * + * 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. + */ + +#include + +#include + +#ifdef _WIN32 + +#undef strcasecmp +#undef strdup +#undef isblank +#undef strtok_r +#include +#include +#include +#include + +#include + +int retro_strcasecmp__(const char *a, const char *b) +{ + while (*a && *b) + { + int a_ = tolower(*a); + int b_ = tolower(*b); + + if (a_ != b_) + return a_ - b_; + + a++; + b++; + } + + return tolower(*a) - tolower(*b); +} + +char *retro_strdup__(const char *orig) +{ + size_t len = strlen(orig) + 1; + char *ret = (char*)malloc(len); + if (!ret) + return NULL; + + strlcpy(ret, orig, len); + return ret; +} + +int retro_isblank__(int c) +{ + return (c == ' ') || (c == '\t'); +} + +char *retro_strtok_r__(char *str, const char *delim, char **saveptr) +{ + char *first = NULL; + if (!saveptr || !delim) + return NULL; + + if (str) + *saveptr = str; + + do + { + char *ptr = NULL; + first = *saveptr; + while (*first && strchr(delim, *first)) + *first++ = '\0'; + + if (*first == '\0') + return NULL; + + ptr = first + 1; + + while (*ptr && !strchr(delim, *ptr)) + ptr++; + + *saveptr = ptr + (*ptr ? 1 : 0); + *ptr = '\0'; + } while (strlen(first) == 0); + + return first; +} + +#endif diff --git a/src/drivers/libretro/libretro-common/compat/compat_strcasestr.c b/src/drivers/libretro/libretro-common/compat/compat_strcasestr.c new file mode 100644 index 0000000..4129dab --- /dev/null +++ b/src/drivers/libretro/libretro-common/compat/compat_strcasestr.c @@ -0,0 +1,58 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (compat_strcasestr.c). + * --------------------------------------------------------------------------------------- + * + * 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. + */ + +#include + +#include + +/* Pretty much strncasecmp. */ +static int casencmp(const char *a, const char *b, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) + { + int a_lower = tolower(a[i]); + int b_lower = tolower(b[i]); + if (a_lower != b_lower) + return a_lower - b_lower; + } + + return 0; +} + +char *strcasestr_retro__(const char *haystack, const char *needle) +{ + size_t i, search_off; + size_t hay_len = strlen(haystack); + size_t needle_len = strlen(needle); + + if (needle_len > hay_len) + return NULL; + + search_off = hay_len - needle_len; + for (i = 0; i <= search_off; i++) + if (!casencmp(haystack + i, needle, needle_len)) + return (char*)haystack + i; + + return NULL; +} diff --git a/src/drivers/libretro/libretro-common/file/file_path.c b/src/drivers/libretro/libretro-common/file/file_path.c new file mode 100644 index 0000000..fc11270 --- /dev/null +++ b/src/drivers/libretro/libretro-common/file/file_path.c @@ -0,0 +1,1381 @@ +/* Copyright (C) 2010-2020 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (file_path.c). + * --------------------------------------------------------------------------------------- + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include