From da42e08e1a9258f14fb6775d7685e4263217e7d0 Mon Sep 17 00:00:00 2001 From: NewRisingSun <8vytz1+dhp372pv94ebg@sharklasers.com> Date: Mon, 8 Sep 2025 16:25:54 +0200 Subject: [PATCH] Mapper 468: bugfixes --- src/boards/468.c | 156 ++++++++++++++++++++----------------- src/boards/asic_mmc1.c | 2 +- src/boards/asic_mmc3.c | 2 +- src/boards/asic_mmc3.h | 2 +- src/boards/asic_vrc2and4.c | 32 ++++---- src/boards/asic_vrc6.c | 10 +-- src/boards/asic_vrc7.c | 14 ++-- 7 files changed, 114 insertions(+), 104 deletions(-) diff --git a/src/boards/468.c b/src/boards/468.c index 6b5025e..eb9eb42 100644 --- a/src/boards/468.c +++ b/src/boards/468.c @@ -129,9 +129,10 @@ static void sync_FxROM (int prgOR) { static void sync_GNROM (int prgOR) { int prgAND = reg[0] &0x08? 0x01: 0x03; - int value = prgOR &0x2000 && submapper != 1? (Latch_data >>4 &0x0F | Latch_data <<4 &0xF0): Latch_data; + int value = Latch_data; + if (submapper == 1 && ~reg[0] &0x08 || submapper != 1 && prgOR &0x2000) value = Latch_data >>4 &0x0F | Latch_data <<4 &0xF0; prgOR = prgOR >>2 | reg[0] >>1 &0x02; - setprg32(0x8000, value >>0 &prgAND | prgOR &~prgAND); + setprg32(0x8000, value &prgAND | prgOR &~prgAND); setchr8(value >>4); setmirror(reg[0] &0x10? MI_H: MI_V); } @@ -144,6 +145,11 @@ static void sync_IF12 (int prgOR) { setmirror(Custom_reg[0] &0x01? MI_H: MI_V); } +static DECLFW(IF12_writeReg) { + Custom_reg[A >>14 &1] = V; + sync(); +} + static void sync_LF36 (int prgOR) { prgOR |= reg[0] &0x08; setprg8(0x8000, 0x04 | prgOR); @@ -154,6 +160,32 @@ static void sync_LF36 (int prgOR) { setmirror(reg[0] &0x04? MI_H: MI_V); } +void FP_FASTAPASS(1) LF36_cpuCycle (int a) { + while (a--) { + if (Custom_reg[1] &1) { + if (!++Custom_reg[2]) ++Custom_reg[3]; + if (Custom_reg[3] &0x10) + X6502_IRQBegin(FCEU_IQEXT); + else + X6502_IRQEnd(FCEU_IQEXT); + } else { + Custom_reg[2] = Custom_reg[3] = 0; + X6502_IRQEnd(FCEU_IQEXT); + } + } +} + +static DECLFW(LF36_writeReg) { + switch(A >>13 &3) { + case 0: case 1: + Custom_reg[1] = A >>13 &1; + break; + case 3: + Custom_reg[0] = V; + sync(); + } +} + static void sync_Misc (int prgOR) { if (reg[0] &0x02) { setprg16(0x8000, Custom_reg[2] <<1 &0x0E | reg[0] &0x01 | prgOR >>1 &~0x0F); @@ -169,12 +201,42 @@ static void sync_Misc (int prgOR) { setmirror(Custom_reg[1] &0x10? MI_1: MI_0); } +static DECLFW(Misc_writeReg) { + switch(A >>12 &7) { + case 0: case 2: case 3: + Custom_reg[0] = V; + sync(); + break; + case 1: + Custom_reg[reg[0] &0x08? 0: 1] = V; + sync(); + break; + case 6: case 7: + Custom_reg[2] = V; + sync(); + break; + } +} + static void sync_Nanjing (int prgOR) { setprg32(0x8000, Custom_reg[2] <<4 &0x30 | Custom_reg[0] &0x0F | (Custom_reg[3] &0x04? 0x00: 0x03) | prgOR >>2); setchr8(0); setmirror(reg[0] &0x04? MI_H: MI_V); } +static void Nanjing_scanline (void) { + if (Custom_reg[0] &0x80 && scanline <239) { + setchr4(0x0000, scanline >= 127? 1: 0); + setchr4(0x1000, scanline >= 127? 1: 0); + } else + setchr8(0); +} + +static DECLFW(Nanjing_writeReg) { + Custom_reg[A >>8 &3] = V; + sync(); +} + static void sync_PNROM (int prgOR) { MMC24_syncWRAM(0); MMC2_syncPRG(0x0F, prgOR &~0x0F); @@ -197,6 +259,10 @@ static void sync_SUROM (int prgOR) { MMC1_syncMirror(); } +static int SUROM_getPRGBank(uint8 bank) { + return MMC1_getPRGBank(bank) | MMC1_getCHRBank(0) &0x10; +} + static void sync_TxROM (int prgOR) { int prgAND = reg[0] &0x08? (reg[0] &0x04? (reg[0] &0x02? (reg[2] &0x02? 0x07: 0x0F): 0x1F): 0x3F): 0x7F; prgOR |= reg[2] &0x01? 0x0C: 0x00; @@ -229,7 +295,7 @@ static void sync_TxSROM (int prgOR) { } static void sync_UxROM (int prgOR) { - int prgAND = reg[0] &0x02? 0x07: 0x0F; + int prgAND = reg[0] &0x02? 0x07: submapper == 1 && ~reg[0] &0x04? 0x1F: 0x0F; setprg16(0x8000, Latch_data &prgAND | prgOR >>1 &~prgAND); setprg16(0xC000, prgOR >>1 | prgAND); setchr8(0); @@ -277,76 +343,10 @@ static void sync_VRC7 (int prgOR) { int prgAND = reg[0] &0x08? (reg[0] &0x04? (reg[0] &0x02? 0x0F: 0x1F): 0x3F): 0x7F; VRC7_syncWRAM(0); VRC7_syncPRG(prgAND, prgOR &~prgAND); - VRC7_syncCHR(0xFF, 0x00); + VRC7_syncCHR(reg[0] &0x10? 0xFF: 0x7F, 0x00); VRC7_syncMirror(); } -/* Mapper callbacks and handlers */ -static int SUROM_getPRGBank(uint8 bank) { - return MMC1_getPRGBank(bank) | MMC1_getCHRBank(0) &0x10; -} - -static DECLFW(IF12_writeReg) { - Custom_reg[A >>14 &1] = V; - sync(); -} - -void FP_FASTAPASS(1) LF36_cpuCycle (int a) { - while (a--) { - if (Custom_reg[1] &1) { - if (!++Custom_reg[2]) ++Custom_reg[3]; - if (Custom_reg[3] &0x10) - X6502_IRQBegin(FCEU_IQEXT); - else - X6502_IRQEnd(FCEU_IQEXT); - } else { - Custom_reg[2] = Custom_reg[3] = 0; - X6502_IRQEnd(FCEU_IQEXT); - } - } -} - -static DECLFW(LF36_writeReg) { - switch(A >>13 &3) { - case 0: case 1: - Custom_reg[1] = A >>13 &1; - break; - case 3: - Custom_reg[0] = V; - sync(); - } -} - -static DECLFW(Misc_writeReg) { - switch(A >>12 &7) { - case 0: case 2: case 3: - Custom_reg[0] = V; - sync(); - break; - case 1: - Custom_reg[1] = V; - sync(); - break; - case 6: case 7: - Custom_reg[2] = V; - sync(); - break; - } -} - -static void Nanjing_scanline (void) { - if (Custom_reg[0] &0x80 && scanline <239) { - setchr4(0x0000, scanline >= 127? 1: 0); - setchr4(0x1000, scanline >= 127? 1: 0); - } else - setchr8(0); -} - -static DECLFW(Nanjing_writeReg) { - Custom_reg[A >>8 &3] = V; - sync(); -} - /* Supervisor */ static DECLFR(readReg) { switch(A) { @@ -381,6 +381,7 @@ static DECLFW(writeReg) { } static void applyMode (uint8 clear) { + uint8 previousMirroring; MapIRQHook = NULL; PPU_hook = NULL; GameHBIRQHook = NULL; @@ -404,11 +405,15 @@ static void applyMode (uint8 clear) { case 0x005: case 0x105: mapperSync = sync_Misc; /* NROM, CNROM, Fire Hawk */ SetWriteHandler(0x8000, 0xFFFF, Misc_writeReg); + if (clear) Custom_reg[0] = Custom_reg[1] = Custom_reg[2] = Custom_reg[3] = 0; + sync(); break; case 0x007: mapperSync = sync_LF36; /* SMB2J */ MapIRQHook = LF36_cpuCycle; SetWriteHandler(0x8000, 0xFFFF, LF36_writeReg); + if (clear) Custom_reg[0] = Custom_reg[1] = Custom_reg[2] = Custom_reg[3] = 0; + sync(); break; case 0x008: mapperSync = sync_FxROM; @@ -421,6 +426,8 @@ static void applyMode (uint8 clear) { } else { mapperSync = sync_IF12; /* Not Irem's actual IF-12 mapper, but something custom by BlazePro */ SetWriteHandler(0x8000, 0xFFFF, IF12_writeReg); + if (clear) Custom_reg[0] = Custom_reg[1] = Custom_reg[2] = Custom_reg[3] = 0; + sync(); } break; case 0x00A: @@ -436,13 +443,17 @@ static void applyMode (uint8 clear) { Latch_activate(clear, sync, 0x8000, 0xFFFF, NULL); break; case 0x00E: case 0x10E: - mapperSync = sync_Nanjing; /* Partial emulation only */ + mapperSync = sync_Nanjing; GameHBIRQHook = Nanjing_scanline; SetWriteHandler(0x5000, 0x53FF, Nanjing_writeReg); + if (clear) Custom_reg[0] = Custom_reg[1] = Custom_reg[2] = Custom_reg[3] = 0; + sync(); break; case 0x100: case 0x101: mapperSync = sync_TxROM; + previousMirroring = MMC3_getMirroring(); MMC3_activate(clear, sync, MMC3_TYPE_SHARP, NULL, NULL, NULL, NULL); + MMC3_writeReg(0xA000, previousMirroring); break; case 0x102: mapperSync = sync_TxSROM; @@ -464,7 +475,7 @@ static void applyMode (uint8 clear) { mapperSync = sync_VRC24; VRC4_activate(clear, sync, 0x0A, 0x05, 1, NULL, NULL, NULL, NULL, NULL); break; - case 0x300: + case 0x300: case 0x301: mapperSync = sync_VRC6; VRC6_activate(clear, sync, 0x01, 0x02, NULL, NULL, NULL, NULL); break; @@ -494,7 +505,6 @@ static void power() { reg[1] = 0xFF; reg[2] = submapper == 1? 0x10: 0x00; reg[3] = 0x00; - Custom_reg[0] = Custom_reg[1] = Custom_reg[2] = Custom_reg[3] = 0; eep_clock = command = output = 1; command = state = 0; applyMode(1); diff --git a/src/boards/asic_mmc1.c b/src/boards/asic_mmc1.c index 3093cbd..ca3eb69 100644 --- a/src/boards/asic_mmc1.c +++ b/src/boards/asic_mmc1.c @@ -116,7 +116,7 @@ DECLFW(MMC1_writeReg) { } static void MMC1_clear() { - MMC1_reg[0] = 0x0C; MMC1_reg[1] = 0; MMC1_reg[2] = 2; MMC1_reg[3] = 0; + MMC1_reg[0] = 0x0C; MMC1_reg[1] = 0; MMC1_reg[2] = 0; MMC1_reg[3] = 0; /* "Bad News Baseball" is sensitive to the initial CHR bank register content. 0/0 seems to work. */ MMC1_bits = 0; MMC1_shift = 0; MMC1_filter = 0; MMC1_cbSync(); } diff --git a/src/boards/asic_mmc3.c b/src/boards/asic_mmc3.c index fea628a..3786dba 100644 --- a/src/boards/asic_mmc3.c +++ b/src/boards/asic_mmc3.c @@ -62,7 +62,7 @@ int MMC3_getCHRBank (uint8 bank) { return bank &4? MMC3_reg[bank -2]: MMC3_reg[bank >>1] &~1 | bank &1; } -int MMC3_getMirroring (void) { +uint8 MMC3_getMirroring (void) { return MMC3_mirroring; } diff --git a/src/boards/asic_mmc3.h b/src/boards/asic_mmc3.h index 773d4f0..210940d 100644 --- a/src/boards/asic_mmc3.h +++ b/src/boards/asic_mmc3.h @@ -30,7 +30,7 @@ void MMC3_syncWRAM (int); int MMC3_getPRGBank (uint8); int MMC3_getCHRBank (uint8); -int MMC3_getMirroring (void); +uint8 MMC3_getMirroring (void); void MMC3_syncPRG (int, int); void MMC3_syncCHR (int, int); void MMC3_syncMirror (); diff --git a/src/boards/asic_vrc2and4.c b/src/boards/asic_vrc2and4.c index c2e1d3d..16166bf 100644 --- a/src/boards/asic_vrc2and4.c +++ b/src/boards/asic_vrc2and4.c @@ -42,29 +42,29 @@ static uint8 VRC4_count; static signed short int VRC4_cycles; static SFORMAT VRC24_stateRegs[] = { - { VRC24_prg, 2, "PREG" }, - { &VRC24_chr[0], 2 | FCEUSTATE_RLSB, "CRH0" }, - { &VRC24_chr[1], 2 | FCEUSTATE_RLSB, "CRH1" }, - { &VRC24_chr[2], 2 | FCEUSTATE_RLSB, "CRH2" }, - { &VRC24_chr[3], 2 | FCEUSTATE_RLSB, "CRH3" }, - { &VRC24_chr[4], 2 | FCEUSTATE_RLSB, "CRH4" }, - { &VRC24_chr[5], 2 | FCEUSTATE_RLSB, "CRH5" }, - { &VRC24_chr[6], 2 | FCEUSTATE_RLSB, "CRH6" }, - { &VRC24_chr[7], 2 | FCEUSTATE_RLSB, "CRH7" }, - { &VRC24_mirroring, 1, "MIRR" }, - { &VRC24_misc, 1, "MISC" }, + { VRC24_prg, 2, "VC2P" }, + { &VRC24_chr[0], 2 | FCEUSTATE_RLSB, "V2C0" }, + { &VRC24_chr[1], 2 | FCEUSTATE_RLSB, "V2C1" }, + { &VRC24_chr[2], 2 | FCEUSTATE_RLSB, "V2C2" }, + { &VRC24_chr[3], 2 | FCEUSTATE_RLSB, "V2C3" }, + { &VRC24_chr[4], 2 | FCEUSTATE_RLSB, "V2C4" }, + { &VRC24_chr[5], 2 | FCEUSTATE_RLSB, "V2C5" }, + { &VRC24_chr[6], 2 | FCEUSTATE_RLSB, "V2C6" }, + { &VRC24_chr[7], 2 | FCEUSTATE_RLSB, "V2C7" }, + { &VRC24_mirroring, 1, "VC2N" }, + { &VRC24_misc, 1, "VC4M" }, { 0 } }; static SFORMAT VRC2_stateRegs[] = { - { &VRC2_pins, 1, "PINS" }, + { &VRC2_pins, 1, "VC2E" }, }; static SFORMAT VRC4_stateRegs[] = { - { &VRC4_latch, 1, "LATC" }, - { &VRC4_mode, 1, "MODE" }, - { &VRC4_count, 1, "COUN" }, - { &VRC4_cycles, 2 | FCEUSTATE_RLSB, "CYCL" }, + { &VRC4_latch, 1, "V4LT" }, + { &VRC4_mode, 1, "V4MO" }, + { &VRC4_count, 1, "V4CT" }, + { &VRC4_cycles, 2 | FCEUSTATE_RLSB, "V4CY" }, { 0 } }; diff --git a/src/boards/asic_vrc6.c b/src/boards/asic_vrc6.c index 6c7d517..95df036 100644 --- a/src/boards/asic_vrc6.c +++ b/src/boards/asic_vrc6.c @@ -38,12 +38,12 @@ static signed short int VRC6_cycles; static SFORMAT VRC6_stateRegs[] = { { VRC6_prg, 2, "VC6P" }, - { VRC6_chr, 6, "VC6C" }, + { VRC6_chr, 8, "VC6C" }, { &VRC6_misc, 1, "VC6M" }, - { &VRC6_latch, 1, "LATC" }, - { &VRC6_mode, 1, "MODE" }, - { &VRC6_count, 1, "COUN" }, - { &VRC6_cycles, 2 | FCEUSTATE_RLSB, "CYCL" }, + { &VRC6_latch, 1, "V6LT" }, + { &VRC6_mode, 1, "V6MO" }, + { &VRC6_count, 1, "V6CT" }, + { &VRC6_cycles, 2 | FCEUSTATE_RLSB, "V6CY" }, { 0 } }; diff --git a/src/boards/asic_vrc7.c b/src/boards/asic_vrc7.c index 0777e5f..7c31f02 100644 --- a/src/boards/asic_vrc7.c +++ b/src/boards/asic_vrc7.c @@ -33,13 +33,13 @@ static uint8 VRC7_count; static signed short int VRC7_cycles; static SFORMAT VRC7_stateRegs[] = { - { VRC7_prg, 3, "VC6P" }, - { VRC7_chr, 6, "VC6C" }, - { &VRC7_misc, 1, "VC6M" }, - { &VRC7_latch, 1, "LATC" }, - { &VRC7_mode, 1, "MODE" }, - { &VRC7_count, 1, "COUN" }, - { &VRC7_cycles, 2 | FCEUSTATE_RLSB, "CYCL" }, + { VRC7_prg, 3, "VC7P" }, + { VRC7_chr, 8, "VC7C" }, + { &VRC7_misc, 1, "VC7M" }, + { &VRC7_latch, 1, "V7LT" }, + { &VRC7_mode, 1, "V7MO" }, + { &VRC7_count, 1, "V7CT" }, + { &VRC7_cycles, 2 | FCEUSTATE_RLSB, "V7CY" }, { 0 } };