Merge pull request #394 from negativeExponent/mapper_updates

m176: Fix address mask causing incorrect register writes
This commit is contained in:
Autechre
2020-10-20 18:49:08 +02:00
committed by GitHub

View File

@@ -156,7 +156,7 @@ static SFORMAT StateRegs[] = {
#define CHR_CNROM_MODE (fk23_regs[0] & 0x40)
#define CHR_OUTER_BANK_SIZE (fk23_regs[0] & 0x10)
static void cwrap(uint16 A, uint16 V)
static void cwrap(uint32 A, uint32 V)
{
int bank = 0;
@@ -178,10 +178,10 @@ static void SyncCHR(void)
{
if (CHR_CNROM_MODE)
{
uint8 mask = (fk23_regs[3] & 0x46) ? (CHR_OUTER_BANK_SIZE ? 0x01 : 0x03) : 0;
uint16 bank = (fk23_regs[2] | (cnrom_chr & mask)) << 3;
uint32 mask = (fk23_regs[3] & 0x46) ? (CHR_OUTER_BANK_SIZE ? 0x01 : 0x03) : 0;
uint32 bank = (fk23_regs[2] | (cnrom_chr & mask)) << 3;
cwrap(0x0000, bank);
cwrap(0x0000, bank + 0);
cwrap(0x0400, bank + 1);
cwrap(0x0800, bank + 2);
cwrap(0x0C00, bank + 3);
@@ -193,11 +193,12 @@ static void SyncCHR(void)
}
else
{
uint32 cbase = (INVERT_CHR ? 0x1000 : 0);
uint32 outer = (fk23_regs[2] << 3);
uint32 cmask = (CHR_OUTER_BANK_SIZE ? 0x7F : 0xFF);
if (MMC3_EXTENDED)
{
uint16 cbase = INVERT_CHR ? 0x1000 : 0;
uint16 outer = fk23_regs[2] << 3;
cwrap(cbase ^ 0x0000, mmc3_regs[0] | outer);
cwrap(cbase ^ 0x0400, mmc3_regs[10] | outer);
cwrap(cbase ^ 0x0800, mmc3_regs[1] | outer);
@@ -210,34 +211,30 @@ static void SyncCHR(void)
}
else
{
uint16 cbase = INVERT_CHR ? 0x1000 : 0;
uint8 mask = CHR_OUTER_BANK_SIZE ? 0x7F : 0xFF;
uint16 outer = (fk23_regs[2] << 3);
cwrap(cbase ^ 0x0000, ((mmc3_regs[0] & cmask) & 0xFE) | outer);
cwrap(cbase ^ 0x0400, ((mmc3_regs[0] & cmask) | 0x01) | outer);
cwrap(cbase ^ 0x0800, ((mmc3_regs[1] & cmask) & 0xFE) | outer);
cwrap(cbase ^ 0x0C00, ((mmc3_regs[1] & cmask) | 0x01) | outer);
cwrap(cbase ^ 0x0000, ((mmc3_regs[0] & mask) & 0xFE) | outer);
cwrap(cbase ^ 0x0400, ((mmc3_regs[0] & mask) | 0x01) | outer);
cwrap(cbase ^ 0x0800, ((mmc3_regs[1] & mask) & 0xFE) | outer);
cwrap(cbase ^ 0x0C00, ((mmc3_regs[1] & mask) | 0x01) | outer);
cwrap(cbase ^ 0x1000, (mmc3_regs[2] & mask) | outer);
cwrap(cbase ^ 0x1400, (mmc3_regs[3] & mask) | outer);
cwrap(cbase ^ 0x1800, (mmc3_regs[4] & mask) | outer);
cwrap(cbase ^ 0x1c00, (mmc3_regs[5] & mask) | outer);
cwrap(cbase ^ 0x1000, (mmc3_regs[2] & cmask) | outer);
cwrap(cbase ^ 0x1400, (mmc3_regs[3] & cmask) | outer);
cwrap(cbase ^ 0x1800, (mmc3_regs[4] & cmask) | outer);
cwrap(cbase ^ 0x1c00, (mmc3_regs[5] & cmask) | outer);
}
}
}
static void SyncPRG(void)
{
uint8 prg_mode = fk23_regs[0] & 7;
uint16 prg_base = (fk23_regs[1] & 0x07F) | ((fk23_regs[0] << 4) & 0x080) |
uint32 prg_mode = (fk23_regs[0] & 7);
uint32 prg_base = (fk23_regs[1] & 0x07F) | ((fk23_regs[0] << 4) & 0x080) |
((fk23_regs[0] << 1) & 0x100) | ((fk23_regs[2] << 3) & 0x600) |
((fk23_regs[2] << 6) & 0x800);
switch (prg_mode)
{
case 4:
setprg32(0x8000, prg_base >> 1);
setprg32(0x8000, (prg_base >> 1));
break;
case 3:
setprg16(0x8000, prg_base);
@@ -246,29 +243,29 @@ static void SyncPRG(void)
case 0:
case 1:
case 2:
{
uint32 cbase = (INVERT_PRG ? 0x4000 : 0);
uint32 mask = (0x3F >> prg_mode);
prg_base <<= 1;
if (MMC3_EXTENDED)
{
uint16 cbase = INVERT_PRG ? 0x4000 : 0;
uint16 outer = prg_base << 1;
setprg8(0x8000 ^ cbase, mmc3_regs[6] | outer);
setprg8(0xA000, mmc3_regs[7] | outer);
setprg8(0xC000 ^ cbase, mmc3_regs[8] | outer);
setprg8(0xE000, mmc3_regs[9] | outer);
setprg8(0x8000 ^ cbase, mmc3_regs[6] | prg_base);
setprg8(0xA000, mmc3_regs[7] | prg_base);
setprg8(0xC000 ^ cbase, mmc3_regs[8] | prg_base);
setprg8(0xE000, mmc3_regs[9] | prg_base);
}
else
{
uint16 cbase = INVERT_PRG ? 0x4000 : 0;
uint8 mask = 0x3F >> prg_mode;
uint16 outer = (prg_base << 1) & ~mask;
setprg8(0x8000 ^ cbase, (mmc3_regs[6] & mask) | outer);
setprg8(0xA000, (mmc3_regs[7] & mask) | outer);
setprg8(0xC000 ^ cbase, (0xFE & mask) | outer);
setprg8(0xE000, (0xFF & mask) | outer);
setprg8(0x8000 ^ cbase, (mmc3_regs[6] & mask) | (prg_base & ~mask));
setprg8(0xA000, (mmc3_regs[7] & mask) | (prg_base & ~mask));
setprg8(0xC000 ^ cbase, (0xFE & mask) | (prg_base & ~mask));
setprg8(0xE000, (0xFF & mask) | (prg_base & ~mask));
}
break;
}
}
}
static void SyncWRAM(void)
@@ -306,54 +303,24 @@ static void Sync(void)
SyncMIR();
}
static DECLFW(WriteLo)
static DECLFW(Write5000)
{
if (((WRAM_EXTENDED == 0) || FK23_ENABLED) && (A & (0x10 << dipswitch)))
{
switch (A & 3)
{
case 0:
if (fk23_regs[0] != V)
{
fk23_regs[0] = V;
SyncPRG();
SyncCHR();
}
break;
case 1:
if (fk23_regs[1] != V)
{
fk23_regs[1] = V;
SyncPRG();
}
break;
case 2:
fk23_regs[A & 3] = V;
if ((A & 3) == 2)
cnrom_chr = 0;
if (fk23_regs[2] != V)
{
fk23_regs[2] = V;
SyncPRG();
SyncCHR();
}
break;
case 3:
if (fk23_regs[3] != V)
{
fk23_regs[3] = V;
SyncPRG();
SyncCHR();
}
break;
}
SyncPRG();
SyncCHR();
}
else
/* FK23C Registers disabled, $5000-$5FFF maps to the second 4 KiB of the 8 KiB WRAM bank 2 */
CartBW(A, V);
}
static DECLFW(WriteHi)
static DECLFW(Write8000)
{
switch (A & 0xE000)
switch (A & 0xF000)
{
case 0x8000:
case 0x9000:
@@ -361,19 +328,19 @@ static DECLFW(WriteHi)
case 0xD000:
case 0xE000:
case 0xF000:
if (CHR_CNROM_MODE)
{
cnrom_chr = V & 0x03;
if (!CHR_CNROM_MODE)
break;
cnrom_chr = V & 0x03;
if ((fk23_regs[0] & 0x07) == 0x03)
cnrom_chr = 0;
if ((fk23_regs[0] & 0x07) == 0x03)
cnrom_chr = 0;
SyncCHR();
}
SyncCHR();
break;
default:
break;
}
switch (A & 0xE001)
switch (A & 0xF001)
{
case 0x8000:
{
@@ -438,6 +405,8 @@ static DECLFW(WriteHi)
case 0xE001:
irq_enabled = 1;
break;
default:
break;
}
}
@@ -508,8 +477,8 @@ static void Power(void)
Sync();
SetReadHandler(0x8000, 0xFFFF, CartBR);
SetWriteHandler(0x5000, 0x5fff, WriteLo);
SetWriteHandler(0x8000, 0xFFFF, WriteHi);
SetWriteHandler(0x5000, 0x5fff, Write5000);
SetWriteHandler(0x8000, 0xFFFF, Write8000);
if (WRAMSIZE)
{