From b6df914538d02df2cd5bf72d745a30fe853fd83a Mon Sep 17 00:00:00 2001 From: FIX94 Date: Sun, 31 Mar 2019 23:38:14 +0200 Subject: [PATCH] -added support for mapper 224 -improved vrc7 audio emulation, now volumes behave more accurately -added newly dumped data for accurate vrc7 instruments --- README.md | 2 +- audio_vrc7.c | 76 ++++++++++++++++++++++++------------------------- main.c | 2 +- mapper/mmc3.c | 17 ++++++++++- mapperList.c | 2 +- mapper_h/mmc3.h | 3 +- 6 files changed, 58 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index fe4d9f8..00199fa 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ To start a file, simply drag and drop it into the fixNES Application or call it You can also load from a .zip file, the first found supported file from that .zip will be used. Supported .nes Mappers: -0,1,2,3,4,5,7,9,10,11,12,13,15,19,21,22,23,24,25,26,28,30,31,32,33,34,36,37,38,41,44,45,46,47,48,49,52,57,58,60,61,62,64,65,66,67,68,69,70,71,73,75,76,77,78,79,80,82,85,87,88,89,93,94,95,97,101,107,112,113,118,119,132,133,136,137,138,139,140,141,144,145,146,147,148,149,152,154,155,156,158,172,173,174,180,184,185,193,200,201,202,203,205,206,207,210,212,221,225,226,228,229,230,231,232,235,237,240 and 242. +0,1,2,3,4,5,7,9,10,11,12,13,15,19,21,22,23,24,25,26,28,30,31,32,33,34,36,37,38,41,44,45,46,47,48,49,52,57,58,60,61,62,64,65,66,67,68,69,70,71,73,75,76,77,78,79,80,82,85,87,88,89,93,94,95,97,101,107,112,113,118,119,132,133,136,137,138,139,140,141,144,145,146,147,148,149,152,154,155,156,158,172,173,174,180,184,185,193,200,201,202,203,205,206,207,210,212,221,224,225,226,228,229,230,231,232,235,237,240 and 242. Supported Audio Expansions (for both ROMs and NSF Files): VRC6, VRC7, FDS, MMC5, N163, Sunsoft 5B diff --git a/audio_vrc7.c b/audio_vrc7.c index 875ebf7..693e8cb 100644 --- a/audio_vrc7.c +++ b/audio_vrc7.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 - 2018 FIX94 + * Copyright (C) 2017 - 2019 FIX94 * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -22,25 +22,25 @@ extern uint8_t audioExpansion; int32_t vrc7Out; -//rainwarrior's VRC7 patches +//https://siliconpr0n.org/archive/doku.php?id=vendor:yamaha:opl2#vrc7_instrument_rom_dump static const uint8_t vrc7instrumentTbl[16][8] = { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - { 0x03, 0x21, 0x05, 0x06, 0xB8, 0x82, 0x42, 0x27 }, - { 0x13, 0x41, 0x13, 0x0D, 0xD8, 0xD6, 0x23, 0x12 }, - { 0x31, 0x11, 0x08, 0x08, 0xFA, 0x9A, 0x22, 0x02 }, - { 0x31, 0x61, 0x18, 0x07, 0x78, 0x64, 0x30, 0x27 }, - { 0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28 }, - { 0x02, 0x01, 0x06, 0x00, 0xF0, 0xF2, 0x03, 0xF5 }, - { 0x21, 0x61, 0x1D, 0x07, 0x82, 0x81, 0x16, 0x07 }, - { 0x23, 0x21, 0x1A, 0x17, 0xCF, 0x72, 0x25, 0x17 }, - { 0x15, 0x11, 0x25, 0x00, 0x4F, 0x71, 0x00, 0x11 }, - { 0x85, 0x01, 0x12, 0x0F, 0x99, 0xA2, 0x40, 0x02 }, - { 0x07, 0xC1, 0x69, 0x07, 0xF3, 0xF5, 0xA7, 0x12 }, - { 0x71, 0x23, 0x0D, 0x06, 0x66, 0x75, 0x23, 0x16 }, - { 0x01, 0x02, 0xD3, 0x05, 0xA3, 0x92, 0xF7, 0x52 }, - { 0x61, 0x63, 0x0C, 0x00, 0x94, 0xAF, 0x34, 0x06 }, - { 0x21, 0x62, 0x0D, 0x00, 0xB1, 0xA0, 0x54, 0x17 }, + { 0x03, 0x21, 0x05, 0x06, 0xE8, 0x81, 0x42, 0x27 }, + { 0x13, 0x41, 0x14, 0x0D, 0xD8, 0xF6, 0x23, 0x12 }, + { 0x11, 0x11, 0x08, 0x08, 0xFA, 0xB2, 0x20, 0x12 }, + { 0x31, 0x61, 0x0C, 0x07, 0xA8, 0x64, 0x61, 0x27 }, + { 0x32, 0x21, 0x1E, 0x06, 0xE1, 0x76, 0x01, 0x28 }, + { 0x02, 0x01, 0x06, 0x00, 0xA3, 0xE2, 0xF4, 0xF4 }, + { 0x21, 0x61, 0x1D, 0x07, 0x82, 0x81, 0x11, 0x07 }, + { 0x23, 0x21, 0x22, 0x17, 0xA2, 0x72, 0x01, 0x17 }, + { 0x35, 0x11, 0x25, 0x00, 0x40, 0x73, 0x72, 0x01 }, + { 0xB5, 0x01, 0x0F, 0x0F, 0xA8, 0xA5, 0x51, 0x02 }, + { 0x17, 0xC1, 0x24, 0x07, 0xF8, 0xF8, 0x22, 0x12 }, + { 0x71, 0x23, 0x11, 0x06, 0x65, 0x74, 0x18, 0x16 }, + { 0x01, 0x02, 0xD3, 0x05, 0xC9, 0x95, 0x03, 0x02 }, + { 0x61, 0x63, 0x0C, 0x00, 0x94, 0xC0, 0x33, 0xF6 }, + { 0x21, 0x72, 0x0D, 0x00, 0xC1, 0xD5, 0x56, 0x06 }, }; static const uint8_t vrc7multiTbl[16] = @@ -92,8 +92,8 @@ enum vrc7StateRelease }; -#define vrc7MaxAtten (1<<23) -#define attenDb ((double)(1<<23)) / 48.0 +#define vrc7MaxAtten (1<<22) +#define attenDb ((double)(1<<22)) / 48.0 static inline int32_t vrc7FromDb(double in) { @@ -162,7 +162,7 @@ void vrc7AudioInit() // Attack Lut for(i = 0; i < 256; ++i) { - double baselog = log((double)(vrc7MaxAtten >> 15)); + double baselog = log((double)(vrc7MaxAtten >> 14)); vrc7_apu.attackLut[i] = vrc7FromDb(48) - (uint32_t)(vrc7FromDb(48) * log((double)(i)) / baselog); } @@ -177,7 +177,7 @@ void vrc7AudioInit() // Am Lut for(i = 0; i < 256; ++i) - vrc7_apu.amLut[i] = (uint32_t)((1.0 + sin(M_2PI * i / 256)) * vrc7FromDb(0.6)); + vrc7_apu.amLut[i] = (uint32_t)((1.0 + sin(M_2PI * i / 256)) * vrc7FromDb(1.2)); // Fm Lut for(i = 0; i < 256; ++i) @@ -232,7 +232,7 @@ static void vrc7CalcSlotVals(vrc7chan_t *chan, vrc7slot_t *slot, uint8_t slotNum slot->releaseRate = slot->sustainRate; else slot->releaseRate = 7; - + // sustain hold if(vrc7_apu.instrument[chan->instrument][0 | slotNum] & 0x20) slot->sustainRate = 0; @@ -240,7 +240,10 @@ static void vrc7CalcSlotVals(vrc7chan_t *chan, vrc7slot_t *slot, uint8_t slotNum if(slot->attackRate) { vrc7SetR(&vrc7_apu.ksr, slot->attackRate); - slot->attackRate = (12 * (vrc7_apu.ksr.RL+4)) << vrc7_apu.ksr.RH; + if(slot->attackRate < 15) + slot->attackRate = (3 * (vrc7_apu.ksr.RL+4)) << (vrc7_apu.ksr.RH+1); + else //rate 15 is like rate 0 + slot->attackRate = 0; } if(slot->decayRate) { @@ -269,22 +272,16 @@ static void vrc7KeyOn(vrc7slot_t *slot) static void vrc7KeyOff(vrc7slot_t *slot) { if(slot->state == vrc7StateAttack) - slot->envPhase = vrc7_apu.attackLut[(slot->envPhase >> 15) & 0xFF]; + slot->envPhase = vrc7_apu.attackLut[(slot->envPhase >> 14) & 0xFF]; slot->state = vrc7StateRelease; } -static void vrc7UpdateEnable(vrc7chan_t *chan, vrc7slot_t *slot) +static void vrc7UpdateEnable(vrc7chan_t *chan, vrc7slot_t *slot, uint8_t slotNum, bool wasenabled) { - if(chan->enabled) - { - if((slot->state == vrc7StateIdle) || (slot->state == vrc7StateRelease)) - vrc7KeyOn(slot); - } - else - { - if((slot->state != vrc7StateIdle) && (slot->state != vrc7StateRelease)) - vrc7KeyOff(slot); - } + if(chan->enabled && !wasenabled) + vrc7KeyOn(slot); + else if(wasenabled && !chan->enabled && slotNum) + vrc7KeyOff(slot); } static uint32_t vrc7Env(vrc7chan_t *chan, vrc7slot_t *slot, uint8_t slotNum) @@ -294,9 +291,9 @@ static uint32_t vrc7Env(vrc7chan_t *chan, vrc7slot_t *slot, uint8_t slotNum) switch(slot->state) { case vrc7StateAttack: - out = vrc7_apu.attackLut[(slot->envPhase >> 15) & 0xFF]; + out = vrc7_apu.attackLut[(slot->envPhase >> 14) & 0xFF]; slot->envPhase += slot->attackRate; - if(slot->envPhase >= vrc7MaxAtten) + if(slot->envPhase >= vrc7MaxAtten || (vrc7_apu.instrument[chan->instrument][4 | slotNum] >> 4) == 0xF) { slot->envPhase = 0; slot->state = vrc7StateDecay; @@ -408,10 +405,11 @@ void vrc7AudioSet9030(uint16_t addr, uint8_t val) c->freq &= 0xFF; c->freq |= (val&1)<<8; c->block = (val>>1)&7; + bool prevenabled = c->enabled; c->enabled = ((val&0x10) != 0); c->s = ((val&0x20) != 0); - vrc7UpdateEnable(c, &c->mod); - vrc7UpdateEnable(c, &c->carry); + vrc7UpdateEnable(c, &c->mod, 0, prevenabled); + vrc7UpdateEnable(c, &c->carry, 1, prevenabled); vrc7CalcSlotVals(c, &c->mod, 0); vrc7CalcSlotVals(c, &c->carry, 1); } diff --git a/main.c b/main.c index e88b5ed..aad87a1 100644 --- a/main.c +++ b/main.c @@ -38,7 +38,7 @@ #define DEBUG_KEY 0 #define DEBUG_LOAD_INFO 1 -const char *VERSION_STRING = "fixNES Alpha v1.2.6"; +const char *VERSION_STRING = "fixNES Alpha v1.2.7"; static char window_title[256]; static char window_title_pause[256]; diff --git a/mapper/mmc3.c b/mapper/mmc3.c index f33e737..11d3425 100644 --- a/mapper/mmc3.c +++ b/mapper/mmc3.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 - 2018 FIX94 + * Copyright (C) 2017 - 2019 FIX94 * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -407,6 +407,21 @@ void m119initSet8(uint16_t ori_addr) mmc3initSet8(ori_addr); } +static void m224setParams5XXX(uint16_t addr, uint8_t val) +{ + (void)addr; + mmc3_prgROMadd = (val&4)<<17; + mmc3SetPrgROMBankPtr(); +} +void m224initSet8(uint16_t ori_addr) +{ + uint16_t proc_addr = ori_addr&0xF003; + //special pirate regs + if(proc_addr == 0x5000) memInitMapperSetPointer(ori_addr, m224setParams5XXX); + else //do normal mmc3 sets + mmc3initSet8(ori_addr); +} + extern void ppuPrintCurLineDot(); void mmc3clock(uint16_t addr) { diff --git a/mapperList.c b/mapperList.c index 6985eea..8e84228 100644 --- a/mapperList.c +++ b/mapperList.c @@ -277,7 +277,7 @@ mapperList_t mapperList[256] = { { m221_init, prg16initGet8, m221_initSet8, chr8initPPUGet8, chr8initPPUSet8, NULL, m221_reset }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, + { mmc3init, mmc3initGet8, m224initSet8, mmc3initPPUGet8, mmc3initPPUSet8, NULL, NULL }, { m225init, m225initGet8, m225initSet8, chr8initPPUGet8, chr8initPPUSet8, NULL, m225reset }, { m226_init, prg16initGet8, m226_initSet8, chr8initPPUGet8, chr8initPPUSet8, NULL, m226_reset }, { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, diff --git a/mapper_h/mmc3.h b/mapper_h/mmc3.h index ec02ecb..64de7a6 100644 --- a/mapper_h/mmc3.h +++ b/mapper_h/mmc3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 - 2018 FIX94 + * Copyright (C) 2017 - 2019 FIX94 * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. @@ -25,6 +25,7 @@ void mmc3initSet8(uint16_t addr); void m12initSet8(uint16_t addr); void m118initSet8(uint16_t ori_addr); void m119initSet8(uint16_t ori_addr); +void m224initSet8(uint16_t ori_addr); void mmc3initPPUGet8(uint16_t addr); void mmc3initPPUSet8(uint16_t addr); void m119initPPUSet8(uint16_t addr);