nes-support vrc3
This commit is contained in:
parent
a5d31cc488
commit
91fa1e6636
|
@ -138,6 +138,7 @@
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Consoles\Nintendo\NES\Boards\VRC2_4.cs" />
|
<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\VRC6.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\NES\Boards\VRC7.cs" />
|
<Compile Include="Consoles\Nintendo\NES\Boards\VRC7.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\NES\Core.cs" />
|
<Compile Include="Consoles\Nintendo\NES\Core.cs" />
|
||||||
|
|
|
@ -60,7 +60,7 @@ Open bus and bus conflict emulation is not considered complete or thorough in an
|
||||||
070 Misc Complete
|
070 Misc Complete
|
||||||
071 Camerica Complete
|
071 Camerica Complete
|
||||||
072 Misc (J) Nothing
|
072 Misc (J) Nothing
|
||||||
073 VRC3 Nothing
|
073 VRC3 Good
|
||||||
074 Pirate (CN) Junk
|
074 Pirate (CN) Junk
|
||||||
075 VRC1 Nothing
|
075 VRC1 Nothing
|
||||||
076 Misc (J) Nothing
|
076 Misc (J) Nothing
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Diagnostics;
|
||||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
{
|
{
|
||||||
//mapper 21 + 22 + 23 + 25 (docs largely in 021.txt for VRC4 and 22.txt for VRC2)
|
//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
|
public class VRC2_4 : NES.NESBoardBase
|
||||||
{
|
{
|
||||||
//configuration
|
//configuration
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ using System.Diagnostics;
|
||||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
{
|
{
|
||||||
//mapper 24 + 26
|
//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
|
public class VRC6 : NES.NESBoardBase
|
||||||
{
|
{
|
||||||
//configuration
|
//configuration
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Diagnostics;
|
||||||
namespace BizHawk.Emulation.Consoles.Nintendo
|
namespace BizHawk.Emulation.Consoles.Nintendo
|
||||||
{
|
{
|
||||||
//mapper 85
|
//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
|
public class VRC7 : NES.NESBoardBase
|
||||||
{
|
{
|
||||||
//configuration
|
//configuration
|
||||||
|
|
Loading…
Reference in New Issue