nes: vrc 2 & 4: fix some stuff. all nescartdb dumps should now work, as well as a decent number of unidentified iNES dumps
This commit is contained in:
parent
316a61bbb5
commit
53d2f5a9c9
|
@ -9,6 +9,52 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
//If you change any of the IRQ logic here, be sure to change it in VRC 3/6/7 as well.
|
//If you change any of the IRQ logic here, be sure to change it in VRC 3/6/7 as well.
|
||||||
public sealed class VRC2_4 : NES.NESBoardBase
|
public sealed class VRC2_4 : NES.NESBoardBase
|
||||||
{
|
{
|
||||||
|
#region addressmaps
|
||||||
|
// remaps addresses into vrc2b form
|
||||||
|
// all varieties of vrc2&4 require A15 = 1 (ie, we're in 8000:ffff), and key on A14:A12 in the same way
|
||||||
|
// in addition, each variety has two other bits; a "low bit" and a "high bit"
|
||||||
|
// for vrc2b, low bit is A0 and high bit is A1, so it's represented by AddrA0A1
|
||||||
|
// other remaps are named similarly
|
||||||
|
int AddrA1A0(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7000 | (addr >> 1) & 1 | (addr << 1) & 2;
|
||||||
|
}
|
||||||
|
int AddrA0A1(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7003;
|
||||||
|
}
|
||||||
|
int AddrA1A2(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7000 | (addr >> 1) & 3;
|
||||||
|
}
|
||||||
|
int AddrA6A7(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7000 | (addr >> 6) & 3;
|
||||||
|
}
|
||||||
|
int AddrA2A3(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7000 | (addr >> 2) & 3;
|
||||||
|
}
|
||||||
|
int AddrA3A2(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7000 | (addr >> 3) & 1 | (addr >> 1) & 2;
|
||||||
|
}
|
||||||
|
// these composite mappings are what's needed for ines mappers
|
||||||
|
int AddrA1A2_A6A7(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7000 | (addr >> 1) & 3 | (addr >> 6) & 3;
|
||||||
|
}
|
||||||
|
int AddrA0A1_A2A3(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7003 | (addr >> 2) & 3;
|
||||||
|
}
|
||||||
|
int AddrA3A2_A1A0(int addr)
|
||||||
|
{
|
||||||
|
return addr & 0x7000 | (addr >> 3) & 1 | (addr >> 1) & 3 | (addr << 1) & 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
//configuration
|
//configuration
|
||||||
int prg_bank_mask_8k, chr_bank_mask_1k;
|
int prg_bank_mask_8k, chr_bank_mask_1k;
|
||||||
int prg_reg_mask_8k;
|
int prg_reg_mask_8k;
|
||||||
|
@ -102,12 +148,28 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
fix_chr = (b) => b;
|
fix_chr = (b) => b;
|
||||||
switch (Cart.board_type)
|
switch (Cart.board_type)
|
||||||
{
|
{
|
||||||
|
// for INES, we assume VRC4 in many cases where it might be VRC2
|
||||||
case "MAPPER021":
|
case "MAPPER021":
|
||||||
|
type = 4;
|
||||||
|
remap = AddrA1A2_A6A7;
|
||||||
|
Cart.wram_size = 8;
|
||||||
|
break;
|
||||||
case "MAPPER022":
|
case "MAPPER022":
|
||||||
|
type = 2;
|
||||||
|
remap = AddrA1A0;
|
||||||
|
Cart.wram_size = 8; // should be latch_exists = true but forget that
|
||||||
|
fix_chr = (b) => (b >> 1);
|
||||||
|
break;
|
||||||
case "MAPPER023":
|
case "MAPPER023":
|
||||||
|
type = 4;
|
||||||
|
remap = AddrA0A1_A2A3;
|
||||||
|
Cart.wram_size = 8;
|
||||||
|
break;
|
||||||
case "MAPPER025":
|
case "MAPPER025":
|
||||||
throw new InvalidOperationException("someone will need to bug me to set these up for failsafe mapping");
|
type = 4;
|
||||||
|
remap = AddrA3A2_A1A0;
|
||||||
|
Cart.wram_size = 8;
|
||||||
|
break;
|
||||||
case "MAPPER027":
|
case "MAPPER027":
|
||||||
//not exactly the same implementation as FCEUX, but we're taking functionality from it step by step as we discover and document it
|
//not exactly the same implementation as FCEUX, but we're taking functionality from it step by step as we discover and document it
|
||||||
//world hero (unl) is m027 and depends on the extrabig_chr functionality to have correct graphics.
|
//world hero (unl) is m027 and depends on the extrabig_chr functionality to have correct graphics.
|
||||||
|
@ -115,50 +177,59 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
extrabig_chr = true;
|
extrabig_chr = true;
|
||||||
remap = (addr) => addr;
|
remap = (addr) => addr;
|
||||||
type = 4;
|
type = 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "MAPPER116_HACKY":
|
case "MAPPER116_HACKY":
|
||||||
remap = (addr) => addr;
|
remap = (addr) => addr;
|
||||||
type = 2;
|
type = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "KONAMI-VRC-4":
|
case "KONAMI-VRC-4":
|
||||||
AssertPrg(128,256); AssertChr(128,256); AssertVram(0); AssertWram(0,2,8);
|
AssertPrg(128, 256); AssertChr(128, 256); AssertVram(0); AssertWram(0, 2, 8);
|
||||||
type = 4;
|
type = 4;
|
||||||
if (Cart.pcb == "352396")
|
switch (Cart.pcb)
|
||||||
remap = (addr) => ((addr & 0xF000) | ((addr >> 2) & 3));
|
{
|
||||||
else if (Cart.pcb == "351406")
|
case "352398": // vrc4a A1 A2
|
||||||
remap = (addr) => ((addr & 0xF000) | ((addr & 1) << 1) | ((addr & 2) >> 1));
|
remap = AddrA1A2; break;
|
||||||
else if (Cart.pcb == "351948") // Ganbare Goemon Gaiden
|
case "351406": // vrc4b A1 A0
|
||||||
throw new Exception("VRC4: Fix me!");
|
remap = AddrA1A0; break;
|
||||||
else if (Cart.pcb == "352889") // Ganbare Goemon Gaiden 2
|
case "352889": // vrc4c A6 A7
|
||||||
throw new Exception("VRC4: Fix me!");
|
remap = AddrA6A7; break;
|
||||||
else
|
case "352400": // vrc4d A3 A2
|
||||||
throw new Exception("Unknown PCB type for VRC4");
|
remap = AddrA3A2; break;
|
||||||
|
case "352396": // vrc4e A2 A3
|
||||||
|
remap = AddrA2A3; break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Unknown PCB type for VRC4");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "KONAMI-VRC-2":
|
case "KONAMI-VRC-2":
|
||||||
AssertPrg(128); AssertChr(128); AssertVram(0); AssertWram(0);
|
AssertPrg(128, 256); AssertChr(128, 256); AssertVram(0); AssertWram(0, 8);
|
||||||
type = 2;
|
type = 2;
|
||||||
latch6k_exists = true;
|
if (Cart.wram_size == 0)
|
||||||
if (Cart.pcb == "350926")
|
latch6k_exists = true;
|
||||||
//likely VRC2b [mapper 23]
|
switch (Cart.pcb)
|
||||||
remap = (addr) => addr;
|
|
||||||
else if (Cart.pcb == "351618")
|
|
||||||
{
|
{
|
||||||
//ex. ganbare pennant race - important chr note applies (VRC2a [mapper 22])
|
case "351618": // vrc2a A1 A0
|
||||||
remap = (addr) => ((addr & 0xF000) | ((addr & 1) << 1) | ((addr & 2) >> 1));
|
remap = AddrA1A0;
|
||||||
fix_chr = (b) => (b >> 1);
|
fix_chr = (b) => (b >> 1); // smaller chr regs on vrc2a
|
||||||
|
break;
|
||||||
|
case "LROG009-00":
|
||||||
|
case "350603":
|
||||||
|
case "350926":
|
||||||
|
case "350636":
|
||||||
|
case "351179": // vrc2b A0 A1
|
||||||
|
remap = AddrA0A1;
|
||||||
|
break;
|
||||||
|
case "351948": // vrc2c A1 A0
|
||||||
|
// this is a weird PCB
|
||||||
|
// it's the only vrc2 with wram, and the only one with 256 prg rom
|
||||||
|
// it also has extra chips that no other vrc2\4 has
|
||||||
|
// it crashes unless you set type = 4; i didn't bother figuring out why
|
||||||
|
remap = AddrA1A0;
|
||||||
|
type = 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception(string.Format("Unknown PCB type for VRC2: \"{0}\"", Cart.pcb));
|
||||||
}
|
}
|
||||||
else if (Cart.pcb == "LROG009-00") // Contra (J)
|
|
||||||
{
|
|
||||||
remap = (addr) => addr;
|
|
||||||
}
|
|
||||||
else if (Cart.pcb == "350603")
|
|
||||||
{
|
|
||||||
remap = (addr) => addr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw new Exception(string.Format("Unknown PCB type for VRC2: \"{0}\"", Cart.pcb));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -167,9 +238,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
prg_bank_mask_8k = Cart.prg_size / 8 - 1;
|
prg_bank_mask_8k = Cart.prg_size / 8 - 1;
|
||||||
chr_bank_mask_1k = Cart.chr_size - 1;
|
chr_bank_mask_1k = Cart.chr_size - 1;
|
||||||
|
|
||||||
if(type == 4) prg_reg_mask_8k = 0x1F;
|
if (type == 4) prg_reg_mask_8k = 0x1F;
|
||||||
else prg_reg_mask_8k = 0xF;
|
else prg_reg_mask_8k = 0xF;
|
||||||
|
|
||||||
//this VRC2 variant has an extra large PRG reg
|
//this VRC2 variant has an extra large PRG reg
|
||||||
if (Cart.board_type == "MAPPER116_HACKY")
|
if (Cart.board_type == "MAPPER116_HACKY")
|
||||||
prg_reg_mask_8k = 0x1F;
|
prg_reg_mask_8k = 0x1F;
|
||||||
|
@ -227,7 +298,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
prg_bank_reg_8k[0] = value & prg_reg_mask_8k;
|
prg_bank_reg_8k[0] = value & prg_reg_mask_8k;
|
||||||
SyncPRG();
|
SyncPRG();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000: //$9000
|
case 0x1000: //$9000
|
||||||
case 0x1001: //$9001
|
case 0x1001: //$9001
|
||||||
switch (value & 3)
|
switch (value & 3)
|
||||||
|
@ -238,7 +309,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
case 3: SetMirrorType(NES.NESBoardBase.EMirrorType.OneScreenB); break;
|
case 3: SetMirrorType(NES.NESBoardBase.EMirrorType.OneScreenB); break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1002: //$9002
|
case 0x1002: //$9002
|
||||||
case 0x1003: //$9003
|
case 0x1003: //$9003
|
||||||
if (type == 4) prg_mode = value.Bit(1);
|
if (type == 4) prg_mode = value.Bit(1);
|
||||||
|
@ -288,11 +359,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
|
|
||||||
case 0x7000: //$F000 (reload low)
|
case 0x7000: //$F000 (reload low)
|
||||||
if (type == 2) break;
|
if (type == 2) break;
|
||||||
irq_reload = (byte)((irq_reload&0xF0) | value);
|
irq_reload = (byte)((irq_reload & 0xF0) | value);
|
||||||
break;
|
break;
|
||||||
case 0x7001: //$F001 (reload high)
|
case 0x7001: //$F001 (reload high)
|
||||||
if (type == 2) break;
|
if (type == 2) break;
|
||||||
irq_reload = (byte)((irq_reload&0x0F)|(value<<4));
|
irq_reload = (byte)((irq_reload & 0x0F) | (value << 4));
|
||||||
break;
|
break;
|
||||||
case 0x7002: //$F001 (control)
|
case 0x7002: //$F001 (control)
|
||||||
if (type == 2) break;
|
if (type == 2) break;
|
||||||
|
@ -318,7 +389,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
SyncIRQ();
|
SyncIRQ();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x7003: //$F003 (ack)
|
case 0x7003: //$F003 (ack)
|
||||||
if (type == 2) break;
|
if (type == 2) break;
|
||||||
irq_pending = false;
|
irq_pending = false;
|
||||||
|
@ -383,4 +454,4 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||||
latch6k_value = value & 1;
|
latch6k_value = value & 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue