NEShawk - Mapper 17 (FFE copier hack)
This commit is contained in:
parent
86b1ab5282
commit
d8c49a7d6d
|
@ -485,6 +485,7 @@
|
|||
<Compile Include="Consoles\Nintendo\NES\Boards\DatachBarcode.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\Farid-UNROM-8-in-1.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\FFE\Mapper006.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\FFE\Mapper017.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\FS304.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\GameGenie.cs" />
|
||||
<Compile Include="Consoles\Nintendo\NES\Boards\inlnsf.cs" />
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
using BizHawk.Common;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.NES
|
||||
{
|
||||
public class Mapper017 : NES.NESBoardBase
|
||||
{
|
||||
private ByteBuffer prg_regs_8k = new ByteBuffer(4);
|
||||
private ByteBuffer chr_regs_1k = new ByteBuffer(8);
|
||||
|
||||
private int prg_mask_8k;
|
||||
private int chr_mask_1k;
|
||||
|
||||
private bool irq_enable;
|
||||
private bool irq_pending;
|
||||
private int irq_count;
|
||||
private const int IRQ_DESTINATION = 0x10000;
|
||||
|
||||
public override bool Configure(NES.EDetectionOrigin origin)
|
||||
{
|
||||
switch (Cart.board_type)
|
||||
{
|
||||
case "MAPPER017":
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
prg_mask_8k = Cart.prg_size / 8 - 1;
|
||||
chr_mask_1k = Cart.chr_size / 1 - 1;
|
||||
|
||||
prg_regs_8k[0] = 0x00;
|
||||
prg_regs_8k[1] = 0x01;
|
||||
prg_regs_8k[2] = 0xFE;
|
||||
prg_regs_8k[3] = 0xFF;
|
||||
SetMirrorType(Cart.pad_h, Cart.pad_v);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void WriteEXP(int addr, byte value)
|
||||
{
|
||||
switch (addr & 0x7FF)
|
||||
{
|
||||
//Mirroring:
|
||||
case 0x2FE:
|
||||
case 0x2FF:
|
||||
int mirroring = ((addr << 1) & 2) | ((value >> 4) & 1);
|
||||
switch (mirroring)
|
||||
{
|
||||
case 0: SetMirrorType(EMirrorType.OneScreenA); break;
|
||||
case 1: SetMirrorType(EMirrorType.OneScreenB); break;
|
||||
case 2: SetMirrorType(EMirrorType.Vertical); break;
|
||||
case 3: SetMirrorType(EMirrorType.Horizontal); break;
|
||||
}
|
||||
break;
|
||||
|
||||
//IRQ
|
||||
case 0x501:
|
||||
irq_enable = value.Bit(0);
|
||||
irq_pending = false;
|
||||
irq_count = 0;
|
||||
SyncIRQ();
|
||||
break;
|
||||
case 0x502:
|
||||
irq_count &= 0xFF00;
|
||||
irq_count |= value;
|
||||
break;
|
||||
case 0x503:
|
||||
irq_count &= 0x00FF;
|
||||
irq_count |= value << 8;
|
||||
irq_enable = true;
|
||||
irq_pending = false;
|
||||
break;
|
||||
|
||||
//PRG
|
||||
case 0x504:
|
||||
case 0x505:
|
||||
case 0x506:
|
||||
case 0x507:
|
||||
prg_regs_8k[addr & 3] = value;
|
||||
break;
|
||||
|
||||
//CHR
|
||||
case 0x510:
|
||||
case 0x511:
|
||||
case 0x512:
|
||||
case 0x513:
|
||||
case 0x514:
|
||||
case 0x515:
|
||||
case 0x516:
|
||||
case 0x517:
|
||||
chr_regs_1k[addr & 7] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
prg_regs_8k.Dispose();
|
||||
chr_regs_1k.Dispose();
|
||||
}
|
||||
|
||||
public override void SyncState(Serializer ser)
|
||||
{
|
||||
base.SyncState(ser);
|
||||
|
||||
ser.Sync("prg_regs_8k", ref prg_regs_8k);
|
||||
ser.Sync("chr_regs_1k", ref chr_regs_1k);
|
||||
|
||||
ser.Sync("irq_enable", ref irq_enable);
|
||||
ser.Sync("irq_pending", ref irq_pending);
|
||||
ser.Sync("irq_count", ref irq_count);
|
||||
}
|
||||
|
||||
public override byte ReadPRG(int addr)
|
||||
{
|
||||
int bank_8k = prg_regs_8k[addr >> 13];
|
||||
bank_8k &= prg_mask_8k;
|
||||
int offset = addr & 0x1FFF;
|
||||
return ROM[bank_8k << 13 | offset];
|
||||
}
|
||||
|
||||
public override void WritePPU(int addr, byte value)
|
||||
{
|
||||
if (addr < 0x2000 && VRAM != null)
|
||||
{
|
||||
VRAM[addr] = value;
|
||||
}
|
||||
base.WritePPU(addr, value);
|
||||
}
|
||||
|
||||
public override byte ReadPPU(int addr)
|
||||
{
|
||||
if (addr < 0x2000)
|
||||
{
|
||||
if (VRAM != null) return VRAM[addr];
|
||||
|
||||
int bank_1k = chr_regs_1k[addr >> 10];
|
||||
bank_1k &= chr_mask_1k;
|
||||
int offset = addr & 0x3FF;
|
||||
return VROM[bank_1k << 10 | offset];
|
||||
}
|
||||
return base.ReadPPU(addr);
|
||||
}
|
||||
|
||||
public override void ClockCPU()
|
||||
{
|
||||
if (irq_enable)
|
||||
{
|
||||
ClockIRQ();
|
||||
}
|
||||
}
|
||||
|
||||
private void ClockIRQ()
|
||||
{
|
||||
irq_count++;
|
||||
if (irq_count >= IRQ_DESTINATION)
|
||||
{
|
||||
irq_enable = false;
|
||||
irq_pending = true;
|
||||
}
|
||||
|
||||
SyncIRQ();
|
||||
}
|
||||
|
||||
private void SyncIRQ()
|
||||
{
|
||||
SyncIRQ(irq_pending);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue