nes-support vrc3

This commit is contained in:
zeromus 2011-09-25 01:07:24 +00:00
parent a5d31cc488
commit 91fa1e6636
6 changed files with 188 additions and 4 deletions

View File

@ -138,6 +138,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Consoles\Nintendo\NES\Boards\VRC2_4.cs" />
<Compile Include="Consoles\Nintendo\NES\Boards\VRC3.cs" />
<Compile Include="Consoles\Nintendo\NES\Boards\VRC6.cs" />
<Compile Include="Consoles\Nintendo\NES\Boards\VRC7.cs" />
<Compile Include="Consoles\Nintendo\NES\Core.cs" />

View File

@ -60,7 +60,7 @@ Open bus and bus conflict emulation is not considered complete or thorough in an
070 Misc Complete
071 Camerica Complete
072 Misc (J) Nothing
073 VRC3 Nothing
073 VRC3 Good
074 Pirate (CN) Junk
075 VRC1 Nothing
076 Misc (J) Nothing

View File

@ -5,7 +5,7 @@ using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo
{
//mapper 21 + 22 + 23 + 25 (docs largely in 021.txt for VRC4 and 22.txt for VRC2)
//If you change any of the IRQ logic here, be sure to change it in VRC 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 class VRC2_4 : NES.NESBoardBase
{
//configuration

View File

@ -0,0 +1,183 @@
using System;
using System.IO;
using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo
{
//mapper 73 AKA salamander
//different IRQ logic than other VRC
public class VRC3 : NES.NESBoardBase
{
//configuration
int prg_bank_mask_16k;
//state
IntBuffer prg_banks_16k = new IntBuffer(2);
bool irq_mode;
bool irq_enabled, irq_pending, irq_autoen;
ushort irq_reload;
ushort irq_counter;
int irq_cycles;
public override void Dispose()
{
base.Dispose();
prg_banks_16k.Dispose();
}
public override void SyncState(Serializer ser)
{
base.SyncState(ser);
ser.Sync("prg_banks_16k", ref prg_banks_16k);
ser.Sync("irq_mode", ref irq_mode);
ser.Sync("irq_enabled", ref irq_enabled);
ser.Sync("irq_pending", ref irq_pending);
ser.Sync("irq_autoen", ref irq_autoen);
ser.Sync("irq_reload", ref irq_reload);
ser.Sync("irq_counter", ref irq_counter);
ser.Sync("irq_cycles", ref irq_cycles);
}
void SyncIRQ()
{
NES.irq_cart = (irq_pending && irq_enabled);
}
public override bool Configure(NES.EDetectionOrigin origin)
{
switch (Cart.board_type)
{
case "KONAMI-VRC-3":
AssertPrg(128,512); AssertChr(0,128); AssertVram(0,8); AssertWram(0,8);
break;
default:
return false;
}
prg_bank_mask_16k = Cart.prg_size / 16 - 1;
SetMirrorType(EMirrorType.Vertical);
prg_banks_16k[1] = (byte)(0xFF & prg_bank_mask_16k);
return true;
}
public override byte ReadPRG(int addr)
{
int bank_16k = addr >> 14;
int ofs = addr & ((1 << 14) - 1);
bank_16k = prg_banks_16k[bank_16k];
addr = (bank_16k << 14) | ofs;
return ROM[addr];
}
void WriteIrqReload(int bit, byte value)
{
int mask = 0xF << bit;
irq_reload = (ushort)((irq_reload & ~mask) | (value << bit));
}
public override void WritePRG(int addr, byte value)
{
switch (addr)
{
case 0x0000: WriteIrqReload(0, value); break;
case 0x1000: WriteIrqReload(4, value); break;
case 0x2000: WriteIrqReload(8, value); break;
case 0x3000: WriteIrqReload(12, value); break;
case 0x4000:
irq_mode = value.Bit(2);
irq_autoen = value.Bit(0);
if (value.Bit(1))
{
//enabled
irq_enabled = true;
if (irq_mode)
{
//8bit..
irq_counter &= 0xFF00;
irq_counter |= (ushort)(irq_reload & 0xFF);
}
else
{
irq_counter = irq_reload;
}
irq_cycles = 3;
}
else
{
//disabled
irq_enabled = false;
}
//acknowledge
irq_pending = false;
SyncIRQ();
break;
case 0x5000:
irq_pending = false;
irq_enabled = irq_autoen;
SyncIRQ();
break;
case 0x7000:
prg_banks_16k[0] = value & 0xF;
prg_banks_16k[0] &= prg_bank_mask_16k;
break;
}
}
void ClockIRQ()
{
if (irq_mode)
{
//8 bit mode
ushort temp = irq_counter;
temp &= 0xFF;
irq_counter &= 0xFF00;
if (temp == 0xFF)
{
irq_pending = true;
irq_counter = irq_reload;
irq_counter |= (ushort)(irq_reload & 0xFF);
SyncIRQ();
}
else
{
temp++;
irq_counter |= temp;
}
}
else
{
//16 bit mode
if (irq_counter == 0xFFFF)
{
irq_pending = true;
irq_counter = irq_reload;
SyncIRQ();
}
else
irq_counter++;
}
}
public override void ClockPPU()
{
if (!irq_enabled) return;
irq_cycles--;
if (irq_cycles == 0)
{
irq_cycles += 3;
ClockIRQ();
}
}
}
}

View File

@ -5,7 +5,7 @@ using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo
{
//mapper 24 + 26
//If you change any of the IRQ logic here, be sure to change it in VRC 2/4/7 as well.
//If you change any of the IRQ logic here, be sure to change it in VRC 2/3/4/7 as well.
public class VRC6 : NES.NESBoardBase
{
//configuration

View File

@ -5,7 +5,7 @@ using System.Diagnostics;
namespace BizHawk.Emulation.Consoles.Nintendo
{
//mapper 85
//If you change any of the IRQ logic here, be sure to change it in VRC 2/4/6 as well.
//If you change any of the IRQ logic here, be sure to change it in VRC 2/3/4/6 as well.
public class VRC7 : NES.NESBoardBase
{
//configuration