From 71f2d5bc9ca8e6ac8dd2fe580a01651ad92b8021 Mon Sep 17 00:00:00 2001 From: CaH4e3 Date: Mon, 18 Feb 2013 13:41:44 +0000 Subject: [PATCH] UNIF DSOUNDV1 - pre beta mapper, nw various mapper improvements UNIF MALISB - Mali Splash Bomb dump mapper 19 - Dream Master mirror fix SOUND - low quality 69 mapper exp sound fix --- src/boards/186.cpp | 8 +- src/boards/206.cpp | 7 +- src/boards/208.cpp | 5 +- src/boards/69.cpp | 2 +- src/boards/__dummy_mapper.cpp | 2 +- src/boards/datalatch.cpp | 5 +- src/boards/dsoundv1.cpp | 175 ++++++++++++++++++++++++++++++++++ src/boards/mmc3.cpp | 52 +++++++--- src/ines-correct.h | 2 +- src/ines.cpp | 12 +-- src/unif.cpp | 4 +- src/unif.h | 2 + vc/vc10_fceux.vcxproj | 1 + vc/vc10_fceux.vcxproj.filters | 3 + 14 files changed, 247 insertions(+), 33 deletions(-) create mode 100644 src/boards/dsoundv1.cpp diff --git a/src/boards/186.cpp b/src/boards/186.cpp index 21bcbd78..137beaa9 100644 --- a/src/boards/186.cpp +++ b/src/boards/186.cpp @@ -22,14 +22,14 @@ #include "mapinc.h" -static uint8 SWRAM[2816]; +static uint8 SWRAM[3072]; static uint8 *WRAM = NULL; static uint8 regs[4]; static SFORMAT StateRegs[] = { { regs, 4, "DREG" }, - { SWRAM, 2816, "SWRM" }, + { SWRAM, 3072, "SWRM" }, { 0 } }; @@ -67,8 +67,8 @@ static void M186Power(void) { SetWriteHandler(0x6000, 0xFFFF, CartBW); SetReadHandler(0x4200, 0x43FF, M186Read); SetWriteHandler(0x4200, 0x43FF, M186Write); - SetReadHandler(0x4400, 0x4EFF, ASWRAM); - SetWriteHandler(0x4400, 0x4EFF, BSWRAM); + SetReadHandler(0x4400, 0x4FFF, ASWRAM); + SetWriteHandler(0x4400, 0x4FFF, BSWRAM); regs[0] = regs[1] = regs[2] = regs[3]; Sync(); } diff --git a/src/boards/206.cpp b/src/boards/206.cpp index b1bb0a1c..d013a8f1 100644 --- a/src/boards/206.cpp +++ b/src/boards/206.cpp @@ -38,6 +38,8 @@ static void Sync(void) { setchr1(0x1000 + (x << 10), DRegs[2 + x]); setprg8(0x8000, DRegs[6]); setprg8(0xa000, DRegs[7]); + setprg8(0xc000, ~1); + setprg8(0xe000, ~0); } static void StateRestore(int version) { @@ -60,10 +62,9 @@ static DECLFW(M206Write) { } static void M206Power(void) { - setprg8(0xc000, 0xE); - setprg8(0xe000, 0xF); cmd = 0; - memset(DRegs, 0, 8); + DRegs[6] = 0; + DRegs[7] = 1; Sync(); SetReadHandler(0x8000, 0xFFFF, CartBR); SetWriteHandler(0x8000, 0xFFFF, M206Write); diff --git a/src/boards/208.cpp b/src/boards/208.cpp index ffb36623..d581b1e8 100644 --- a/src/boards/208.cpp +++ b/src/boards/208.cpp @@ -63,9 +63,10 @@ static DECLFR(M208ProtRead) { static void M208Power(void) { EXPREGS[5] = 3; GenMMC3Power(); - SetWriteHandler(0x4800, 0x4FFF, M208Write); + SetWriteHandler(0x4800, 0x4fff, M208Write); + SetWriteHandler(0x6800, 0x6fff, M208Write); SetWriteHandler(0x5000, 0x5fff, M208ProtWrite); - SetReadHandler(0x5800, 0x5FFF, M208ProtRead); + SetReadHandler(0x5800, 0x5fff, M208ProtRead); SetReadHandler(0x8000, 0xffff, CartBR); } diff --git a/src/boards/69.cpp b/src/boards/69.cpp index cb49f726..b106aa36 100644 --- a/src/boards/69.cpp +++ b/src/boards/69.cpp @@ -154,7 +154,7 @@ static void DoAYSQ(int x) { CAYBC[x] = end; if (amp && !(sreg[0x7] & (1 << x))) - for (V = start; V < end; V++) { + for (V = start; V < end; V++) { if (dcount[x]) Wave[V >> 4] += amp; vcount[x] -= nesincsize; diff --git a/src/boards/__dummy_mapper.cpp b/src/boards/__dummy_mapper.cpp index 4a0eadf5..505f9169 100644 --- a/src/boards/__dummy_mapper.cpp +++ b/src/boards/__dummy_mapper.cpp @@ -1,7 +1,7 @@ /* FCE Ultra - NES/Famicom Emulator * * Copyright notice for this file: - * Copyright (C) 2012 CaH4e3 + * Copyright (C) 2013 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 diff --git a/src/boards/datalatch.cpp b/src/boards/datalatch.cpp index 7f39add0..ddff9e34 100644 --- a/src/boards/datalatch.cpp +++ b/src/boards/datalatch.cpp @@ -435,7 +435,10 @@ void Mapper240_Init(CartInfo *info) { static void M241Sync(void) { setchr8(0); setprg8r(0x10, 0x6000, 0); - setprg32(0x8000, latche); + if(latche & 0x80) + setprg32(0x8000, latche | 8); // no 241 actually, but why not afterall? + else + setprg32(0x8000, latche); } void Mapper241_Init(CartInfo *info) { diff --git a/src/boards/dsoundv1.cpp b/src/boards/dsoundv1.cpp new file mode 100644 index 00000000..fa060dbe --- /dev/null +++ b/src/boards/dsoundv1.cpp @@ -0,0 +1,175 @@ +/* FCE Ultra - NES/Famicom Emulator + * + * Copyright notice for this file: + * Copyright (C) 2013 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[4]; + +static uint8 *WRAM = NULL; +static uint32 WRAMSIZE; + +// SND Registers +static uint8 pcm_enable = 0; +static int16 pcm_latch = 0x3F6, pcm_clock = 0x3F6; +static writefunc pcmwrite; + +static SFORMAT StateRegs[] = +{ + { reg, 4, "REGS" }, + { 0 } +}; + +static int16 step_size[49] = { + 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, + 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, + 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, + 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, + 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552 + }; //49 items +static int32 step_adj[16] = { -1, -1, -1, -1, 2, 5, 7, 9, -1, -1, -1, -1, 2, 5, 7, 9 }; + +//decode stuff +static int32 jedi_table[16 * 49]; +static int32 acc = 0; //ADPCM accumulator, initial condition must be 0 +static int32 decstep = 0; //ADPCM decoding step, initial condition must be 0 + +static void jedi_table_init() +{ + int step, nib; + + for (step = 0; step < 49; step++) + { + for (nib = 0; nib < 16; nib++) + { + int value = (2 * (nib & 0x07) + 1) * step_size[step] / 8; + jedi_table[step * 16 + nib] = ((nib & 0x08) != 0) ? -value : value; + } + } +} + +static uint8 decode(uint8 code) +{ + acc += jedi_table[decstep + code]; + if ((acc & ~0x7ff) != 0) // acc is > 2047 + acc |= ~0xfff; + else acc &= 0xfff; + decstep += step_adj[code & 7] * 16; + if (decstep < 0) decstep = 0; + if (decstep > 48 * 16) decstep = 48 * 16; + return (acc >> 8) & 0xff; +} + +static void Sync(void) { + uint32 sbank = reg[1] & 0x7; + uint32 bbank = reg[2]; + setchr8(0); + setprg8r(0x10, 0x6000, reg[3] & 3); + if(reg[0] & 2) { // UNROM mode + setprg16(0x8000, (bbank << 3) | sbank); + if(reg[0] & 4) + setprg16(0xC000, (bbank << 3) | 6 | (reg[1] & 1)); + else + setprg16(0xC000, (bbank << 3) | 7); + } else { // NROM mode + uint32 bank = (bbank << 3) | sbank; + if(reg[0] & 4) { + setprg16(0x8000, bank); + setprg16(0xC000, bank); + } else + setprg32(0x8000, bank >> 1); + } + setmirror((reg[0] & 1) ^ 1); +} + +static DECLFW(UNLDSOUNDV1Write) { + reg[A & 3] = V; +// FCEU_printf("cmd %04x:%02x\n", A, V); + Sync(); +} + +static DECLFW(UNLDSOUNDV1WriteSnd) { + if(A == 0x5800) { + if(V & 0xF0) { + pcm_enable = 1; +// pcmwrite(0x4011, (V & 0xF) << 3); + pcmwrite(0x4011, decode(V & 0xf)); + } else + pcm_enable = 0; + } else + FCEU_printf("misc %04x:%02x\n", A, V); +} + +static DECLFR(UNLDSOUNDV1ReadSnd) { + if(A == 0x5800) + return (X.DB & 0xBF) | ((pcm_enable ^ 1) <<6); + else + return X.DB; +} + +static void UNLDSOUNDV1Power(void) { + reg[0] = reg[1] = reg[2] = reg[3] = 0; + Sync(); + pcmwrite = GetWriteHandler(0x4011); + SetWriteHandler(0x4800, 0x4fff, UNLDSOUNDV1Write); + SetWriteHandler(0x5800, 0x5fff, UNLDSOUNDV1WriteSnd); + SetReadHandler(0x5800, 0x5fff, UNLDSOUNDV1ReadSnd); + SetReadHandler(0x6000, 0x7fff, CartBR); + SetWriteHandler(0x6000, 0x7fff, CartBW); + SetReadHandler(0x8000, 0xffff, CartBR); +} + +static void UNLDSOUNDV1SndClk(int a) { + if (pcm_enable) { + pcm_latch -= a; + if (pcm_latch <= 0) { + pcm_latch += pcm_clock; + pcm_enable = 0; + } + } +} + +static void UNLDSOUNDV1Close(void) { + if (WRAM) + FCEU_gfree(WRAM); + WRAM = NULL; +} + +static void StateRestore(int version) { + Sync(); +} + +void UNLDSOUNDV1_Init(CartInfo *info) { + info->Power = UNLDSOUNDV1Power; + info->Close = UNLDSOUNDV1Close; + GameStateRestore = StateRestore; + MapIRQHook = UNLDSOUNDV1SndClk; + + jedi_table_init(); + + WRAMSIZE = 32768; + 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; + } + AddExState(&StateRegs, ~0, 0, 0); +} diff --git a/src/boards/mmc3.cpp b/src/boards/mmc3.cpp index dcf2f575..af570f25 100644 --- a/src/boards/mmc3.cpp +++ b/src/boards/mmc3.cpp @@ -749,8 +749,9 @@ static void M115CW(uint32 A, uint8 V) { } static DECLFW(M115Write) { - if (A == 0x5080) EXPREGS[2] = V; - if (A == 0x6000) + if (A == 0x5080) + EXPREGS[2] = V; // Extra prot hardware 2-in-1 mode + else if (A == 0x6000) EXPREGS[0] = V; else if (A == 0x6001) EXPREGS[1] = V; @@ -772,7 +773,7 @@ void Mapper115_Init(CartInfo *info) { cwrap = M115CW; pwrap = M115PW; info->Power = M115Power; - AddExState(EXPREGS, 2, 0, "EXPR"); + AddExState(EXPREGS, 3, 0, "EXPR"); } // ---------------------------- Mapper 118 ------------------------------ @@ -986,25 +987,18 @@ void Mapper195_Init(CartInfo *info) { // game static void M196PW(uint32 A, uint8 V) { - if (EXPREGS[0]) // Tenchi o Kurau II - Shokatsu Koumei Den (J) (C).nes + if (EXPREGS[0]) setprg32(0x8000, EXPREGS[1]); else setprg8(A, V); -// setprg8(A,(V&3)|((V&8)>>1)|((V&4)<<1)); // Mali Splash Bomb } -//static void M196CW(uint32 A, uint8 V) -//{ -// setchr1(A,(V&0xDD)|((V&0x20)>>4)|((V&2)<<4)); -//} - static DECLFW(Mapper196Write) { if (A >= 0xC000) { A = (A & 0xFFFE) | ((A >> 2) & 1) | ((A >> 3) & 1); MMC3_IRQWrite(A, V); } else { A = (A & 0xFFFE) | ((A >> 2) & 1) | ((A >> 3) & 1) | ((A >> 1) & 1); -// A=(A&0xFFFE)|((A>>3)&1); // Mali Splash Bomb MMC3_CMDWrite(A, V); } } @@ -1025,10 +1019,44 @@ static void Mapper196Power(void) { void Mapper196_Init(CartInfo *info) { GenMMC3_Init(info, 128, 128, 0, 0); pwrap = M196PW; -// cwrap=M196CW; // Mali Splash Bomb info->Power = Mapper196Power; } +// ---------------------------- Mali Splash Bomb---------------------------- +// The same board as for 196 mapper games, but with additional data bit swap +// Also, it is impossible to work on the combined 196 mapper source with +// all data bits merged, because it's using one of them as 8000 reg... + +static void UNLMaliSBPW(uint32 A, uint8 V) { + setprg8(A, (V & 3)|((V & 8) >> 1)|((V & 4) << 1)); +} + +static void UNLMaliSBCW(uint32 A, uint8 V) { + setchr1(A, (V & 0xDD) | ((V & 0x20) >> 4) | ((V & 2) << 4)); +} + +static DECLFW(UNLMaliSBWrite) { + if (A >= 0xC000) { + A = (A & 0xFFFE) | ((A >> 2) & 1) | ((A >> 3) & 1); + MMC3_IRQWrite(A, V); + } else { + A = (A & 0xFFFE) | ((A >> 3) & 1); + MMC3_CMDWrite(A, V); + } +} + +static void UNLMaliSBPower(void) { + GenMMC3Power(); + SetWriteHandler(0x8000, 0xFFFF, UNLMaliSBWrite); +} + +void UNLMaliSB_Init(CartInfo *info) { + GenMMC3_Init(info, 128, 128, 0, 0); + pwrap = UNLMaliSBPW; + cwrap = UNLMaliSBCW; + info->Power = UNLMaliSBPower; +} + // ---------------------------- Mapper 197 ------------------------------- static void M197CW(uint32 A, uint8 V) { diff --git a/src/ines-correct.h b/src/ines-correct.h index 08c4896b..3b2d7011 100644 --- a/src/ines-correct.h +++ b/src/ines-correct.h @@ -228,7 +228,7 @@ {0x2447e03b, 210, 1}, /* Top Striker */ {0x1dc0f740, 210, 1}, /* Wagyan Land 2 */ {0xd323b806, 210, 1}, /* Wagyan Land 3 */ - {0xbd523011, 210, 2}, /* Dream Master */ + {0xbd523011, 210, 0}, /* Dream Master */ {0x5daae69a, 211, -1}, /* Aladdin - Return of Jaffar, The (Unl) [!] */ {0x1ec1dfeb, 217, -1}, /* 255-in-1 (Cut version) [p1] */ {0x046d70cc, 217, -1}, /* 500-in-1 (Anim Splash, Alt Mapper)[p1][!] */ diff --git a/src/ines.cpp b/src/ines.cpp index 32e8fab6..e7cc5f6d 100644 --- a/src/ines.cpp +++ b/src/ines.cpp @@ -45,7 +45,7 @@ extern SFORMAT FCEUVSUNI_STATEINFO[]; //mbg merge 6/29/06 - these need to be global -uint8 *trainerpoo = 0; +uint8 *trainerpoo = NULL; uint8 *ROM = NULL; uint8 *VROM = NULL; uint8 *ExtraNTARAM = NULL; @@ -234,7 +234,6 @@ struct BADINF { uint32 type; }; - static struct BADINF BadROMImages[] = { #include "ines-bad.h" @@ -719,7 +718,10 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { MapperNo = (head.ROM_type >> 4); MapperNo |= (head.ROM_type2 & 0xF0); - Mirroring = (head.ROM_type & 1); + if (head.ROM_type & 8) { + Mirroring = 2; + } else + Mirroring = (head.ROM_type & 1); if (!head.ROM_size) ROM_size = 256; @@ -741,10 +743,6 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) { } } - if (head.ROM_type & 8) { - Mirroring = 2; - } - if ((ROM = (uint8*)FCEU_malloc(ROM_size << 14)) == NULL) return 0; memset(ROM, 0xFF, ROM_size << 14); diff --git a/src/unif.cpp b/src/unif.cpp index fabb32c5..bbb3cf0f 100644 --- a/src/unif.cpp +++ b/src/unif.cpp @@ -74,7 +74,7 @@ static uint8 *malloced[32]; static uint32 mallocedsizes[32]; static int FixRomSize(uint32 size, uint32 minimum) { - uint32 x = 1; //mbg merge 7/17/06 made uint + uint32 x = 1; if (size < minimum) return minimum; @@ -348,6 +348,7 @@ static BMAPPING bmap[] = { { "DANCE", UNLOneBus_Init, 0 }, // redundant { "DANCE2000", UNLD2000_Init, 0 }, { "DREAMTECH01", DreamTech01_Init, 0 }, + { "DSOUNDV1", UNLDSOUNDV1_Init, 0 }, { "EDU2000", UNLEDU2000_Init, 0 }, { "EKROM", EKROM_Init, 0 }, { "ELROM", ELROM_Init, 0 }, @@ -377,6 +378,7 @@ static BMAPPING bmap[] = { { "LH10", LH10_Init, 0 }, { "LH32", LH32_Init, 0 }, { "LH53", LH53_Init, 0 }, + { "MALISB", UNLMaliSB_Init, 0 }, { "MARIO1-MALEE2", MALEE_Init, 0 }, { "MHROM", MHROM_Init, 0 }, { "N625092", UNLN625092_Init, 0 }, diff --git a/src/unif.h b/src/unif.h index d7a838cd..ecc62443 100644 --- a/src/unif.h +++ b/src/unif.h @@ -105,6 +105,7 @@ void TSROM_Init(CartInfo *info); void Transformer_Init(CartInfo *info); void UNL22211_Init(CartInfo *info); void UNL3DBlock_Init(CartInfo *info); +void UNLDSOUNDV1_Init(CartInfo *info); void UNL43272_Init(CartInfo *info); void UNL6035052_Init(CartInfo *info); void UNL8157_Init(CartInfo *info); @@ -129,6 +130,7 @@ void UNLKS7032_Init(CartInfo *info); void UNLKS7037_Init(CartInfo *info); void UNLKS7057_Init(CartInfo *info); void UNLN625092_Init(CartInfo *info); +void UNLMaliSB_Init(CartInfo *info); void UNLOneBus_Init(CartInfo *info); void UNLPEC586Init(CartInfo *info); void UNLSC127_Init(CartInfo *info); diff --git a/vc/vc10_fceux.vcxproj b/vc/vc10_fceux.vcxproj index 4739306b..bf8d6027 100644 --- a/vc/vc10_fceux.vcxproj +++ b/vc/vc10_fceux.vcxproj @@ -308,6 +308,7 @@ + diff --git a/vc/vc10_fceux.vcxproj.filters b/vc/vc10_fceux.vcxproj.filters index 7adb29dd..ff566331 100644 --- a/vc/vc10_fceux.vcxproj.filters +++ b/vc/vc10_fceux.vcxproj.filters @@ -952,6 +952,9 @@ boards + + boards +