Mapper 468: bugfixes

This commit is contained in:
NewRisingSun
2025-09-08 16:25:54 +02:00
parent 5744764e24
commit da42e08e1a
7 changed files with 114 additions and 104 deletions

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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 ();

View File

@@ -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 }
};

View File

@@ -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 }
};

View File

@@ -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 }
};