From 7e9b3b146d233fd09b2ab1b99dbb7819f1784621 Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Tue, 2 Jul 2019 19:34:55 +0800 Subject: [PATCH] UNIF: Initial implementation of game overrides (move exiting ones out of mapper code) --- src/boards/datalatch.c | 60 +++++++++++++++++++++-------------- src/boards/resetnromxin1.c | 15 ++------- src/cart.h | 1 + src/unif.c | 65 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 37 deletions(-) diff --git a/src/boards/datalatch.c b/src/boards/datalatch.c index 1846bb7..c221310 100644 --- a/src/boards/datalatch.c +++ b/src/boards/datalatch.c @@ -153,27 +153,29 @@ static void CNROMSync(void) { } void CNROM_Init(CartInfo *info) { + unsigned _no_busc, _busc; + + _busc = 1; /* by default, CNROM is set to emulate bus conflicts to all games */ + _no_busc = 0; + + if (GameInfo->cspecial == 1) + _no_busc = 1; + /* TODO: move these to extended database when implemented. */ - int _busc, x; - uint64 partialmd5 = 0; - _busc = 1; - for (x = 0; x < 8; x++) - partialmd5 |= (uint64)info->MD5[15 - x] << (x * 8); - if (partialmd5 == 0x117181328eb1ad23LL) /* 75 Bingo (Sachen-English) [U].unf */ - _busc = 0; - else - switch (info->CRC32) { - case 0xf283cf58: /* Colorful Dragon (Asia) (PAL) (Unl).nes */ - case 0x2915faf0: /* Incantation (Asia) (Unl).nes */ - case 0xebd0644d: /* Dao Shuai (Asia) (Unl).nes */ - case 0x8f154a0d: /* Pu Ke Jing Ling (China) (Unl).nes */ - case 0xd04a40e6: /* Bingo 75 (Asia) (Unl).nes */ - case 0xe41b440f: /* Sidewinder (Joy Van) */ - case 0xb0c871c5: /* Wei Lai Xiao Zi (Joy Van) */ - case 0xb3be2f71: /* Yanshan Chess (Unl) */ - _busc = 0; - break; + switch (info->CRC32) { + case 0xf283cf58: /* Colorful Dragon (Asia) (PAL) (Unl).nes */ + case 0x2915faf0: /* Incantation (Asia) (Unl).nes */ + case 0xebd0644d: /* Dao Shuai (Asia) (Unl).nes */ + case 0x8f154a0d: /* Pu Ke Jing Ling (China) (Unl).nes */ + case 0xd04a40e6: /* Bingo 75 (Asia) (Unl).nes */ + case 0xe41b440f: /* Sidewinder (Joy Van) */ + case 0xb0c871c5: /* Wei Lai Xiao Zi (Joy Van) */ + case 0xb3be2f71: /* Yanshan Chess (Unl) */ + _no_busc = 1; + break; } + + if (_no_busc == 1) _busc = 0; Latch_Init(info, CNROMSync, 0, 0x8000, 0xFFFF, 1, _busc); } @@ -495,22 +497,32 @@ void Mapper241_Init(CartInfo *info) { * 16 bankswitching mode and normal mirroring... But there is no any * correlations between modes and they can be used in one mapper code. */ - +static int A65ASsubmapper; static void BMCA65ASSync(void) { if (latche & 0x40) setprg32(0x8000, (latche >> 1) & 0x0F); else { - setprg16(0x8000, ((latche & 0x30) >> 1) | (latche & 7)); - setprg16(0xC000, ((latche & 0x30) >> 1) | 7); + if (A65ASsubmapper == 1) { + setprg16(0x8000, ((latche & 0x38) >> 0) | (latche & 7)); + setprg16(0xC000, ((latche & 0x38) >> 0) | 7); + } else { + setprg16(0x8000, ((latche & 0x30) >> 1) | (latche & 7)); + setprg16(0xC000, ((latche & 0x30) >> 1) | 7); + } } setchr8(0); if (latche & 0x80) setmirror(MI_0 + (((latche >> 5) & 1))); - else - setmirror(((latche >> 3) & 1) ^ 1); + else { + if (A65ASsubmapper == 1) /* added as workaround since games for this cart uses vertical mirroring */ + setmirror(MI_V); + else + setmirror(((latche >> 3) & 1) ^ 1); + } } void BMCA65AS_Init(CartInfo *info) { + A65ASsubmapper = info->submapper; /* not a real submapper */ Latch_Init(info, BMCA65ASSync, 0, 0x8000, 0xFFFF, 0, 0); } diff --git a/src/boards/resetnromxin1.c b/src/boards/resetnromxin1.c index d17bc81..76c6e84 100644 --- a/src/boards/resetnromxin1.c +++ b/src/boards/resetnromxin1.c @@ -18,7 +18,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -/* BMC-RESETNROM-XIN1 +/* NES 2.0 Mapper 343 + * BMC-RESETNROM-XIN1 * - Sheng Tian 2-in-1(Unl,ResetBase)[p1] - Kung Fu (Spartan X), Super Mario Bros (alt) * - Sheng Tian 2-in-1(Unl,ResetBase)[p2] - B-Wings, Twin-bee * @@ -58,18 +59,6 @@ static void StateRestore(int version) { } void BMCRESETNROMXIN1_Init(CartInfo *info) { - uint8 x; - uint64 partialmd5 = 0; - - for (x = 0; x < 8; x++) - partialmd5 |= (uint64)info->MD5[15 - x] << (x * 8); - - /* Mirroring override - these boards have incorrect mirroring for some reasons in their headers */ - if (partialmd5 == 0x616851e56946893bLL) /* Sheng Tian 2-in-1(Unl,ResetBase)[p1].unf */ - SetupCartMirroring(1, 1, NULL); - else if (partialmd5 == 0x4cd729b5ae23a3cfLL) /* Sheng Tian 2-in-1(Unl,ResetBase)[p2].unf */ - SetupCartMirroring(0, 1, NULL); - limit = 0x01; info->Power = BMCRESETNROMXIN1Power; info->Reset = BMCRESETNROMXIN1Reset; diff --git a/src/cart.h b/src/cart.h index fbac352..16ab243 100644 --- a/src/cart.h +++ b/src/cart.h @@ -11,6 +11,7 @@ typedef struct { /* Set by iNES/UNIF loading code. */ int mapper; /* mapper used */ + int submapper; /* submapper used */ /* TODO: */ int mirror; /* As set in the header or chunk. * iNES/UNIF specific. Intended * to help support games like "Karnov" diff --git a/src/unif.c b/src/unif.c index a7c252b..6072129 100644 --- a/src/unif.c +++ b/src/unif.c @@ -60,6 +60,8 @@ CartInfo UNIFCart; static int vramo; static int mirrortodo; +static int submapper; +static int cspecial; static uint8 *boardname; static uint8 *sboardname; @@ -317,6 +319,65 @@ static int LoadCHR(FCEUFILE *fp) { return(1); } +#define NO_BUSC 1 + +struct _unif_db { + uint64 partialMD5; + char *boardname; + int submapper; + int mirroring; + int special; /* TODO: for bus conflicts, set 1 for no bus_conflict */ +}; + +static struct _unif_db unif_db[] = { + { 0x8ebad077d08e6c78ULL, "A65AS", 1, -1 }, /* 3-in-1 (N080) [p1][U][!], not a real submapper */ + { 0x117181328eb1ad23ULL, "CNROM", 0, MI_H, NO_BUSC }, /* 75 Bingo (Sachen-English) [U] */ + { 0x616851e56946893bULL, "RESETNROM-XIN1", 0, MI_V }, /* Sheng Tian 2-in-1(Unl,ResetBase)[p1].unf */ + { 0x4cd729b5ae23a3cfULL, "RESETNROM-XIN1", 0, MI_H }, /* Sheng Tian 2-in-1(Unl,ResetBase)[p2].unf */ + + { 0, NULL, -1, -1, -1 } /* end of the line */ +}; + +static void CheckHashInfo(void) { + unsigned x = 0; + uint64 partialMD5 = 0; + + for (x = 0; x < 8; x++) + partialMD5 |= (uint64)UNIFCart.MD5[15 - x] << (x * 8); + + x = 0; + do { + if (partialMD5 == unif_db[x].partialMD5) { + FCEU_printf("\n"); + FCEU_PrintError(" The UNIF header contains incorrect information.\n"); + FCEU_PrintError(" For now, the information will be corrected in RAM.\n"); + if (unif_db[x].boardname != NULL && strcmp((char*)unif_db[x].boardname, (char*)sboardname) != 0) { + FCEU_printf(" Boardname should be set to %s\n", unif_db[x].boardname); + sboardname = unif_db[x].boardname; + } + if (unif_db[x].submapper >= 0 && unif_db[x].submapper != submapper) { + FCEU_PrintError(" Submapper should be set to %d\n", unif_db[x].submapper); + submapper = unif_db[x].submapper; + } + if (unif_db[x].mirroring >= 0 && unif_db[x].mirroring != mirrortodo) { + static char *stuffo[6] = { "Horizontal", "Vertical", "$2000", "$2400", "\"Four-screen\"", "Controlled by Mapper Hardware" }; + FCEU_PrintError(" Mirroring should be set to %s\n", stuffo[unif_db[x].mirroring]); + mirrortodo = unif_db[x].mirroring; + } + if (unif_db[x].special >= 0 && unif_db[x].special != cspecial) { + if (!(strcmp((char*)sboardname, "CNROM"))) { + FCEU_PrintError(" Special flags applied, No bus conflict.\n"); + cspecial = unif_db[x].special; + } + } + /* todo special case aka, dipswitches, busc-like in fk23c/a, etc */ + FCEU_printf("\n"); + } + x++; + } while (unif_db[x].partialMD5 > 0); + +} + #define BMCFLAG_FORCE4 0x01 #define BMCFLAG_16KCHRR 0x02 #define BMCFLAG_32KCHRR 0x04 @@ -595,6 +656,8 @@ static int InitializeBoard(void) { PRGchip_max = prg_chip_count - 1; if (chr_chip_count) CHRchip_max = chr_chip_count - 1; + UNIFCart.submapper = submapper; + GameInfo->cspecial = cspecial; bmap[x].init(&UNIFCart); return(1); @@ -655,6 +718,8 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { memcpy(GameInfo->MD5, UNIFCart.MD5, sizeof(UNIFCart.MD5)); } + CheckHashInfo(); + if (!InitializeBoard()) goto aborto;