dev_4VirtualNes #23

Merged
sin365 merged 35 commits from dev_4VirtualNes into master 2024-08-05 17:49:44 +08:00
31 changed files with 2903 additions and 1 deletions
Showing only changes of commit c0e29193f7 - Show all commits

View File

@ -0,0 +1,23 @@
//////////////////////////////////////////////////////////////////////////
// Mapper018 Jaleco SS8806 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
namespace VirtualNes.Core
{
public class Mapper018 : Mapper
{
public Mapper018(NES parent) : base(parent)
{
}
public override void Reset()
{
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d9f306005d0826a4e96ceec780568bb3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,416 @@
//////////////////////////////////////////////////////////////////////////
// Mapper019 Namcot 106 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper019 : Mapper
{
BYTE patch;
BYTE exsound_enable;
BYTE[] reg = new byte[3];
BYTE[] exram = new byte[128];
BYTE irq_enable;
ushort irq_counter;
public Mapper019(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
reg[0] = reg[1] = reg[2] = 0;
::memset(exram, 0, sizeof(exram));
irq_enable = 0;
irq_counter = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE >= 8)
{
SetVROM_8K_Bank(VROM_8K_SIZE - 1);
}
exsound_enable = 0xFF;
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0xb62a7b71)
{ // Family Circuit '91(J)
patch = 1;
}
if (crc == 0x02738c68)
{ // Wagan Land 2(J)
patch = 3;
}
if (crc == 0x14942c06)
{ // Wagan Land 3(J)
patch = 2;
}
if (crc == 0x968dcf09)
{ // Final Lap(J)
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
}
if (crc == 0x3deac303)
{ // Rolling Thunder(J)
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
}
if (crc == 0xb1b9e187)
{ // For Kaijuu Monogatari(J)
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
}
if (crc == 0x6901346e)
{ // For Sangokushi 2 - Haou no Tairiku(J)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
}
// if( crc == 0xdd454208 ) { // Hydlide 3(J)
// nes.SetRenderMethod( NES::PRE_ALL_RENDER );
// }
if (crc == 0xaf15338f // For Mindseeker(J)
|| crc == 0xb1b9e187 // For Kaijuu Monogatari(J)
|| crc == 0x96533999 // Dokuganryuu Masamune(J)
// || crc == 0x2b825ce1 // Namco Classic(J)
// || crc == 0x9a2b0641 // Namco Classic 2(J)
|| crc == 0x3296ff7a // Battle Fleet(J)
|| crc == 0xdd454208)
{ // Hydlide 3(J)
exsound_enable = 0;
}
if (crc == 0x429fd177)
{ // Famista '90(J)
exsound_enable = 0;
}
if (exsound_enable != 0)
{
nes.apu.SelectExSound(0x10);
}
}
//BYTE Mapper019::ReadLow(WORD addr)
public override byte ReadLow(ushort addr)
{
BYTE data = 0;
switch (addr & 0xF800)
{
case 0x4800:
if (addr == 0x4800)
{
if (exsound_enable != 0)
{
nes.apu.ExRead(addr);
data = exram[reg[2] & 0x7F];
}
else
{
data = WRAM[reg[2] & 0x7F];
}
if ((reg[2] & 0x80) != 0)
reg[2] = (byte)((reg[2] + 1) | 0x80);
return data;
}
break;
case 0x5000:
return (byte)((BYTE)irq_counter & 0x00FF);
case 0x5800:
return (BYTE)((irq_counter >> 8) & 0x7F);
case 0x6000:
case 0x6800:
case 0x7000:
case 0x7800:
return base.ReadLow(addr);
}
return (BYTE)(addr >> 8);
}
//void Mapper019::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
switch (addr & 0xF800)
{
case 0x4800:
if (addr == 0x4800)
{
if (exsound_enable != 0)
{
nes.apu.ExWrite(addr, data);
exram[reg[2] & 0x7F] = data;
}
else
{
WRAM[reg[2] & 0x7F] = data;
}
if ((reg[2] & 0x80) != 0)
reg[2] = (byte)((reg[2] + 1) | 0x80);
}
break;
case 0x5000:
irq_counter = (byte)((irq_counter & 0xFF00) | (ushort)data);
// if( irq_enable ) {
// irq_counter++;
// }
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0x5800:
irq_counter = (byte)((irq_counter & 0x00FF) | ((ushort)(data & 0x7F) << 8));
irq_enable = (byte)(data & 0x80);
// if( irq_enable ) {
// irq_counter++;
// }
// if( !irq_enable ) {
// nes.cpu.ClrIRQ( IRQ_MAPPER );
// }
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0x6000:
case 0x6800:
case 0x7000:
case 0x7800:
base.WriteLow(addr, data);
break;
}
}
//void Mapper019::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
//if( addr >= 0xC000 ) {
//DEBUGOUT( "W %04X %02X L:%3d\n", addr, data, nes.GetScanline() );
//}
switch (addr & 0xF800)
{
case 0x8000:
if ((data < 0xE0) || (reg[0] != 0))
{
SetVROM_1K_Bank(0, data);
}
else
{
SetCRAM_1K_Bank(0, data & 0x1F);
}
break;
case 0x8800:
if ((data < 0xE0) || (reg[0] != 0))
{
SetVROM_1K_Bank(1, data);
}
else
{
SetCRAM_1K_Bank(1, data & 0x1F);
}
break;
case 0x9000:
if ((data < 0xE0) || (reg[0] != 0))
{
SetVROM_1K_Bank(2, data);
}
else
{
SetCRAM_1K_Bank(2, data & 0x1F);
}
break;
case 0x9800:
if ((data < 0xE0) || (reg[0] != 0))
{
SetVROM_1K_Bank(3, data);
}
else
{
SetCRAM_1K_Bank(3, data & 0x1F);
}
break;
case 0xA000:
if ((data < 0xE0) || (reg[1] != 0))
{
SetVROM_1K_Bank(4, data);
}
else
{
SetCRAM_1K_Bank(4, data & 0x1F);
}
break;
case 0xA800:
if ((data < 0xE0) || (reg[1] != 0))
{
SetVROM_1K_Bank(5, data);
}
else
{
SetCRAM_1K_Bank(5, data & 0x1F);
}
break;
case 0xB000:
if ((data < 0xE0) || (reg[1] != 0))
{
SetVROM_1K_Bank(6, data);
}
else
{
SetCRAM_1K_Bank(6, data & 0x1F);
}
break;
case 0xB800:
if ((data < 0xE0) || (reg[1] != 0))
{
SetVROM_1K_Bank(7, data);
}
else
{
SetCRAM_1K_Bank(7, data & 0x1F);
}
break;
case 0xC000:
if (patch == 0)
{
if (data <= 0xDF)
{
SetVROM_1K_Bank(8, data);
}
else
{
SetVRAM_1K_Bank(8, data & 0x01);
}
}
break;
case 0xC800:
if (patch == 0)
{
if (data <= 0xDF)
{
SetVROM_1K_Bank(9, data);
}
else
{
SetVRAM_1K_Bank(9, data & 0x01);
}
}
break;
case 0xD000:
if (patch == 0)
{
if (data <= 0xDF)
{
SetVROM_1K_Bank(10, data);
}
else
{
SetVRAM_1K_Bank(10, data & 0x01);
}
}
break;
case 0xD800:
if (patch == 0)
{
if (data <= 0xDF)
{
SetVROM_1K_Bank(11, data);
}
else
{
SetVRAM_1K_Bank(11, data & 0x01);
}
}
break;
case 0xE000:
SetPROM_8K_Bank(4, data & 0x3F);
if (patch == 2)
{
if ((data & 0x40) != 0) SetVRAM_Mirror(VRAM_VMIRROR);
else SetVRAM_Mirror(VRAM_MIRROR4L);
}
if (patch == 3)
{
if ((data & 0x80) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
break;
case 0xE800:
reg[0] = (byte)(data & 0x40);
reg[1] = (byte)(data & 0x80);
SetPROM_8K_Bank(5, data & 0x3F);
break;
case 0xF000:
SetPROM_8K_Bank(6, data & 0x3F);
break;
case 0xF800:
if (addr == 0xF800)
{
if (exsound_enable != 0)
{
nes.apu.ExWrite(addr, data);
}
reg[2] = data;
}
break;
}
}
//void Mapper019::Clock(INT cycles)
public override void Clock(int cycles)
{
if (irq_enable != 0)
{
if ((irq_counter += cycles) >= 0x7FFF)
{
// irq_counter = 0x7FFF;
// nes.cpu.IRQ_NotPending();
irq_enable = 0;
// irq_counter &= 0x7FFF;
irq_counter = 0x7FFF;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
//void Mapper019::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
// p[0] = reg[0];
// p[1] = reg[1];
// p[2] = reg[2];
// p[3] = irq_enable;
// *(WORD*)&p[4] = irq_counter;
//::memcpy(&p[8], exram, sizeof(exram));
}
//void Mapper019::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
// reg[0] = p[0];
// reg[1] = p[1];
// reg[2] = p[2];
// irq_enable = p[3];
// irq_counter = *(WORD*)&p[4];
//::memcpy(exram, &p[8], sizeof(exram));
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e0d99073c4ae1444bbf4fa05498aecb8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,255 @@
//////////////////
// Mapper021 Konami VRC4 (Address mask $F006 or $F0C0) //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper021 : Mapper
{
BYTE[] reg = new byte[9];
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
INT irq_clock;
public Mapper021(NES parent) : base(parent)
{
}
public override void Reset()
{
for (byte i = 0; i < 8; i++)
{
reg[i] = i;
}
reg[8] = 0;
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
irq_clock = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
//void Mapper021::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF0CF)
{
case 0x8000:
if ((reg[8] & 0x02) != 0)
{
SetPROM_8K_Bank(6, data);
}
else
{
SetPROM_8K_Bank(4, data);
}
break;
case 0xA000:
SetPROM_8K_Bank(5, data);
break;
case 0x9000:
data &= 0x03;
if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR);
else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L);
else SetVRAM_Mirror(VRAM_MIRROR4H);
break;
case 0x9002:
case 0x9080:
reg[8] = data;
break;
case 0xB000:
reg[0] = (byte)((reg[0] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(0, reg[0]);
break;
case 0xB002:
case 0xB040:
reg[0] = (byte)((reg[0] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(0, reg[0]);
break;
case 0xB001:
case 0xB004:
case 0xB080:
reg[1] = (byte)((reg[1] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(1, reg[1]);
break;
case 0xB003:
case 0xB006:
case 0xB0C0:
reg[1] = (byte)((reg[1] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(1, reg[1]);
break;
case 0xC000:
reg[2] = (byte)((reg[2] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(2, reg[2]);
break;
case 0xC002:
case 0xC040:
reg[2] = (byte)((reg[2] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(2, reg[2]);
break;
case 0xC001:
case 0xC004:
case 0xC080:
reg[3] = (byte)((reg[3] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(3, reg[3]);
break;
case 0xC003:
case 0xC006:
case 0xC0C0:
reg[3] = (byte)((reg[3] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(3, reg[3]);
break;
case 0xD000:
reg[4] = (byte)((reg[4] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(4, reg[4]);
break;
case 0xD002:
case 0xD040:
reg[4] = (byte)((reg[4] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(4, reg[4]);
break;
case 0xD001:
case 0xD004:
case 0xD080:
reg[5] = (byte)((reg[5] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(5, reg[5]);
break;
case 0xD003:
case 0xD006:
case 0xD0C0:
reg[5] = (byte)((reg[5] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(5, reg[5]);
break;
case 0xE000:
reg[6] = (byte)((reg[6] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(6, reg[6]);
break;
case 0xE002:
case 0xE040:
reg[6] = (byte)((reg[6] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(6, reg[6]);
break;
case 0xE001:
case 0xE004:
case 0xE080:
reg[7] = (byte)((reg[7] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(7, reg[7]);
break;
case 0xE003:
case 0xE006:
case 0xE0C0:
reg[7] = (byte)((reg[7] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(7, reg[7]);
break;
case 0xF000:
irq_latch = (byte)((irq_latch & 0xF0) | (data & 0x0F));
break;
case 0xF002:
case 0xF040:
irq_latch = (byte)((irq_latch & 0x0F) | ((data & 0x0F) << 4));
break;
case 0xF003:
case 0xF0C0:
case 0xF006:
irq_enable = (byte)((irq_enable & 0x01) * 3);
irq_clock = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF004:
case 0xF080:
irq_enable = (byte)(data & 0x03);
if ((irq_enable & 0x02) != 0)
{
irq_counter = irq_latch;
irq_clock = 0;
}
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
// case 0xF006:
// nes.cpu.ClrIRQ( IRQ_MAPPER );
// break;
}
}
//void Mapper021::Clock(INT cycles)
public override void Clock(int cycles)
{
if ((irq_enable & 0x02) != 0)
{
if ((irq_clock -= cycles) < 0)
{
irq_clock += 0x72;
if (irq_counter == 0xFF)
{
irq_counter = irq_latch;
// irq_enable = (irq_enable & 0x01) * 3;
// nes.cpu.IRQ_NotPending();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
else
{
irq_counter++;
}
}
}
}
//void Mapper021::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//for (INT i = 0; i < 9; i++)
//{
// p[i] = reg[i];
//}
//p[9] = irq_enable;
//p[10] = irq_counter;
//p[11] = irq_latch;
//*(INT*)&p[12] = irq_clock;
}
//void Mapper021::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//for (INT i = 0; i < 9; i++)
//{
// reg[i] = p[i];
//}
//irq_enable = p[9];
//irq_counter = p[10];
//irq_latch = p[11];
//irq_clock = *(INT*)&p[12];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6082f7bf68f41f6439e13610e7766887
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,81 @@
//////////////////////////////////////////////////////////////////////////
// Mapper022 Konami VRC2 type A //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper022 : Mapper
{
public Mapper022(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
//void Mapper022::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr)
{
case 0x8000:
SetPROM_8K_Bank(4, data);
break;
case 0x9000:
data &= 0x03;
if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR);
else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
break;
case 0xA000:
SetPROM_8K_Bank(5, data);
break;
case 0xB000:
SetVROM_1K_Bank(0, data >> 1);
break;
case 0xB001:
SetVROM_1K_Bank(1, data >> 1);
break;
case 0xC000:
SetVROM_1K_Bank(2, data >> 1);
break;
case 0xC001:
SetVROM_1K_Bank(3, data >> 1);
break;
case 0xD000:
SetVROM_1K_Bank(4, data >> 1);
break;
case 0xD001:
SetVROM_1K_Bank(5, data >> 1);
break;
case 0xE000:
SetVROM_1K_Bank(6, data >> 1);
break;
case 0xE001:
SetVROM_1K_Bank(7, data >> 1);
break;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b618d4b61b1e6ed48ad8ab3a38947424
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,271 @@
//////////////////////////////////////////////////////////////////////////
// Mapper023 Konami VRC2 type B //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper023 : Mapper
{
ushort addrmask;
BYTE[] reg = new byte[9];
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
INT irq_clock;
public Mapper023(NES parent) : base(parent)
{
}
public override void Reset()
{
addrmask = 0xFFFF;
for (INT i = 0; i < 8; i++)
{
reg[i] = i;
}
reg[8] = 0;
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
irq_clock = 0;
reg[9] = 1;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
SetVROM_8K_Bank(0);
// nes.SetRenderMethod( NES::POST_RENDER );
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x93794634 // Akumajou Special Boku Dracula Kun(J)
|| crc == 0xc7829dae // Akumajou Special Boku Dracula Kun(T-Eng)
|| crc == 0xf82dc02f)
{ // Akumajou Special Boku Dracula Kun(T-Eng v1.02)
addrmask = 0xF00C;
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
}
if (crc == 0xdd53c4ae)
{ // Tiny Toon Adventures(J)
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
}
}
//void Mapper023::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes.GetScanline(), nes.cpu.GetTotalCycles() );
switch (addr & addrmask)
{
case 0x8000:
case 0x8004:
case 0x8008:
case 0x800C:
if (reg[8] != 0)
{
SetPROM_8K_Bank(6, data);
}
else
{
SetPROM_8K_Bank(4, data);
}
break;
case 0x9000:
if (data != 0xFF)
{
data &= 0x03;
if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR);
else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L);
else SetVRAM_Mirror(VRAM_MIRROR4H);
}
break;
case 0x9008:
reg[8] = (byte)(data & 0x02);
break;
case 0xA000:
case 0xA004:
case 0xA008:
case 0xA00C:
SetPROM_8K_Bank(5, data);
break;
case 0xB000:
reg[0] = (byte)((reg[0] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(0, reg[0]);
break;
case 0xB001:
case 0xB004:
reg[0] = ((byte)((reg[0] & 0x0F) | ((data & 0x0F) << 4)));
SetVROM_1K_Bank(0, reg[0]);
break;
case 0xB002:
case 0xB008:
reg[1] = (byte)((reg[1] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(1, reg[1]);
break;
case 0xB003:
case 0xB00C:
reg[1] = (byte)((reg[1] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(1, reg[1]);
break;
case 0xC000:
reg[2] = (byte)((reg[2] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(2, reg[2]);
break;
case 0xC001:
case 0xC004:
reg[2] = (byte)((reg[2] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(2, reg[2]);
break;
case 0xC002:
case 0xC008:
reg[3] = (byte)((reg[3] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(3, reg[3]);
break;
case 0xC003:
case 0xC00C:
reg[3] = (byte)((reg[3] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(3, reg[3]);
break;
case 0xD000:
reg[4] = (byte)((reg[4] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(4, reg[4]);
break;
case 0xD001:
case 0xD004:
reg[4] = (byte)((reg[4] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(4, reg[4]);
break;
case 0xD002:
case 0xD008:
reg[5] = (byte)((reg[5] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(5, reg[5]);
break;
case 0xD003:
case 0xD00C:
reg[5] = (byte)((reg[5] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(5, reg[5]);
break;
case 0xE000:
reg[6] = (byte)((reg[6] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(6, reg[6]);
break;
case 0xE001:
case 0xE004:
reg[6] = (byte)((reg[6] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(6, reg[6]);
break;
case 0xE002:
case 0xE008:
reg[7] = (byte)((reg[7] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(7, reg[7]);
break;
case 0xE003:
case 0xE00C:
reg[7] = ((byte)((reg[7] & 0x0F) | ((data & 0x0F) << 4)));
SetVROM_1K_Bank(7, reg[7]);
break;
case 0xF000:
irq_latch = (byte)((irq_latch & 0xF0) | (data & 0x0F));
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF004:
irq_latch = (byte)((irq_latch & 0x0F) | ((data & 0x0F) << 4));
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF008:
irq_enable = (byte)(data & 0x03);
irq_counter = irq_latch;
irq_clock = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF00C:
irq_enable = (byte)((irq_enable & 0x01) * 3);
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
}
//void Mapper023::Clock(INT cycles)
public override void Clock(int cycles)
{
if ((irq_enable & 0x02) != 0)
{
irq_clock += cycles * 3;
while (irq_clock >= 341)
{
irq_clock -= 341;
irq_counter++;
if (irq_counter == 0)
{
irq_counter = irq_latch;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
//void Mapper023::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//for (INT i = 0; i < 9; i++)
//{
// p[i] = reg[i];
//}
//p[9] = irq_enable;
//p[10] = irq_counter;
//p[11] = irq_latch;
//*(INT*)&p[12] = irq_clock;
}
//void Mapper023::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//for (INT i = 0; i < 9; i++)
//{
// reg[i] = p[i];
//}
//irq_enable = p[9];
//irq_counter = p[10];
//irq_latch = p[11];
//irq_clock = *(INT*)&p[12];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d201617d198186e41b362ea94be5533c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,174 @@
//////////////////////////////////////////////////////////////////////////
// Mapper024 Konami VRC6 (Normal) //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper024 : Mapper
{
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
INT irq_clock;
public Mapper024(NES parent) : base(parent)
{
}
public override void Reset()
{
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
irq_clock = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
// nes.SetRenderMethod( NES::PRE_RENDER );
nes.apu.SelectExSound(1);
}
//void Mapper024::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF003)
{
case 0x8000:
SetPROM_16K_Bank(4, data);
break;
case 0x9000:
case 0x9001:
case 0x9002:
case 0xA000:
case 0xA001:
case 0xA002:
case 0xB000:
case 0xB001:
case 0xB002:
nes.apu.ExWrite(addr, data);
break;
case 0xB003:
data = (byte)(data & 0x0C);
if (data == 0x00) SetVRAM_Mirror(VRAM_VMIRROR);
else if (data == 0x04) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 0x08) SetVRAM_Mirror(VRAM_MIRROR4L);
else if (data == 0x0C) SetVRAM_Mirror(VRAM_MIRROR4H);
break;
case 0xC000:
SetPROM_8K_Bank(6, data);
break;
case 0xD000:
SetVROM_1K_Bank(0, data);
break;
case 0xD001:
SetVROM_1K_Bank(1, data);
break;
case 0xD002:
SetVROM_1K_Bank(2, data);
break;
case 0xD003:
SetVROM_1K_Bank(3, data);
break;
case 0xE000:
SetVROM_1K_Bank(4, data);
break;
case 0xE001:
SetVROM_1K_Bank(5, data);
break;
case 0xE002:
SetVROM_1K_Bank(6, data);
break;
case 0xE003:
SetVROM_1K_Bank(7, data);
break;
case 0xF000:
irq_latch = data;
break;
case 0xF001:
irq_enable = (byte)(data & 0x03);
if ((irq_enable & 0x02) != 0)
{
irq_counter = irq_latch;
irq_clock = 0;
}
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF002:
irq_enable = (byte)((irq_enable & 0x01) * 3);
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
}
//void Mapper024::Clock(INT cycles)
public override void Clock(int cycles)
{
if ((irq_enable & 0x02) != 0)
{
if ((irq_clock += cycles) >= 0x72)
{
irq_clock -= 0x72;
if (irq_counter == 0xFF)
{
irq_counter = irq_latch;
// nes.cpu.IRQ_NotPending();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
else
{
irq_counter++;
}
}
}
}
//void Mapper024::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//p[1] = irq_counter;
//p[2] = irq_latch;
//*(INT*)&p[3] = irq_clock;
}
//void Mapper024::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//irq_enable = p[0];
//irq_counter = p[1];
//irq_latch = p[2];
//irq_clock = *(INT*)&p[3];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e319508c6222744dbb48902f10ab3df
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,278 @@
//////////////////////////////////////////////////////////////////////////
// Mapper025 Konami VRC4 (Normal) //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper025 : Mapper
{
BYTE[] reg = new byte[11];
BYTE irq_enable;
BYTE irq_latch;
BYTE irq_occur;
BYTE irq_counter;
INT irq_clock;
public Mapper025(NES parent) : base(parent)
{
}
public override void Reset()
{
for (INT i = 0; i < 11; i++)
{
reg[i] = 0;
}
reg[9] = (byte)(PROM_8K_SIZE - 2);
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
irq_occur = 0;
irq_clock = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0xc71d4ce7)
{ // Gradius II(J)
// nes.SetRenderMethod( NES::POST_RENDER );
}
if (crc == 0xa2e68da8)
{ // For Racer Mini Yonku - Japan Cup(J)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
}
if (crc == 0xea74c587)
{ // For Teenage Mutant Ninja Turtles(J)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
}
if (crc == 0x5f82cb7d)
{ // For Teenage Mutant Ninja Turtles 2(J)
}
if (crc == 0x0bbd85ff)
{ // For Bio Miracle Bokutte Upa(J)
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
}
}
//void Mapper025::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
//if( addr >= 0xF000 )
//DEBUGOUT( "M25 WR $%04X=$%02X L=%3d\n", addr, data, nes.GetScanline() );
switch (addr & 0xF000)
{
case 0x8000:
if ((reg[10] & 0x02) != 0)
{
reg[9] = data;
SetPROM_8K_Bank(6, data);
}
else
{
reg[8] = data;
SetPROM_8K_Bank(4, data);
}
break;
case 0xA000:
SetPROM_8K_Bank(5, data);
break;
}
switch (addr & 0xF00F)
{
case 0x9000:
data &= 0x03;
if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR);
else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L);
else SetVRAM_Mirror(VRAM_MIRROR4H);
break;
case 0x9001:
case 0x9004:
if ((reg[10] & 0x02) != (data & 0x02))
{
BYTE swap = reg[8];
reg[8] = reg[9];
reg[9] = swap;
SetPROM_8K_Bank(4, reg[8]);
SetPROM_8K_Bank(6, reg[9]);
}
reg[10] = data;
break;
case 0xB000:
reg[0] = (byte)((reg[0] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(0, reg[0]);
break;
case 0xB002:
case 0xB008:
reg[0] = (byte)((reg[0] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(0, reg[0]);
break;
case 0xB001:
case 0xB004:
reg[1] = (byte)((reg[1] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(1, reg[1]);
break;
case 0xB003:
case 0xB00C:
reg[1] = (byte)((reg[1] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(1, reg[1]);
break;
case 0xC000:
reg[2] = (byte)((reg[2] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(2, reg[2]);
break;
case 0xC002:
case 0xC008:
reg[2] = (byte)((reg[2] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(2, reg[2]);
break;
case 0xC001:
case 0xC004:
reg[3] = (byte)((reg[3] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(3, reg[3]);
break;
case 0xC003:
case 0xC00C:
reg[3] = (byte)((reg[3] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(3, reg[3]);
break;
case 0xD000:
reg[4] = (byte)((reg[4] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(4, reg[4]);
break;
case 0xD002:
case 0xD008:
reg[4] = (byte)((reg[4] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(4, reg[4]);
break;
case 0xD001:
case 0xD004:
reg[5] = (byte)((reg[5] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(5, reg[5]);
break;
case 0xD003:
case 0xD00C:
reg[5] = (byte)((reg[5] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(5, reg[5]);
break;
case 0xE000:
reg[6] = (byte)((reg[6] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(6, reg[6]);
break;
case 0xE002:
case 0xE008:
reg[6] = (byte)((reg[6] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(6, reg[6]);
break;
case 0xE001:
case 0xE004:
reg[7] = (byte)((reg[7] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(7, reg[7]);
break;
case 0xE003:
case 0xE00C:
reg[7] = (byte)((reg[7] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(7, reg[7]);
break;
case 0xF000:
irq_latch = (byte)((irq_latch & 0xF0) | (data & 0x0F));
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF002:
case 0xF008:
irq_latch = (byte)((irq_latch & 0x0F) | ((data & 0x0F) << 4));
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF001:
case 0xF004:
irq_enable = (byte)(data & 0x03);
// irq_counter = 0x100 - irq_latch;
irq_counter = irq_latch;
irq_clock = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF003:
case 0xF00C:
irq_enable = (byte)((irq_enable & 0x01) * 3);
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
}
//void Mapper025::Clock(INT cycles)
public override void Clock(int cycles)
{
if ((irq_enable & 0x02) != 0)
{
irq_clock += cycles * 3;
while (irq_clock >= 341)
{
irq_clock -= 341;
irq_counter++;
if (irq_counter == 0)
{
irq_counter = irq_latch;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
//void Mapper025::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//for (INT i = 0; i < 11; i++)
//{
// p[i] = reg[i];
//}
//p[11] = irq_enable;
//p[12] = irq_occur;
//p[13] = irq_latch;
//p[14] = irq_counter;
//*((INT*)&p[15]) = irq_clock;
}
//void Mapper025::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//for (INT i = 0; i < 11; i++)
//{
// reg[i] = p[i];
//}
//irq_enable = p[11];
//irq_occur = p[12];
//irq_latch = p[13];
//irq_counter = p[14];
//irq_clock = *((INT*)&p[15]);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6d065f0d406a26d4da372c16493e5bb9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,185 @@
//////////////////////////////////////////////////////////////////////////
// Mapper026 Konami VRC6 (PA0,PA1 reverse) //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper026 : Mapper
{
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
INT irq_clock;
public Mapper026(NES parent) : base(parent)
{
}
public override void Reset()
{
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
irq_clock = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x30e64d03)
{ // Esper Dream 2 - Aratanaru Tatakai(J)
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
}
if (crc == 0x836cc1ab)
{ // Mouryou Senki Madara(J)
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
}
nes.apu.SelectExSound(1);
}
//void Mapper026::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF003)
{
case 0x8000:
SetPROM_16K_Bank(4, data);
break;
case 0x9000:
case 0x9001:
case 0x9002:
case 0x9003:
case 0xA000:
case 0xA001:
case 0xA002:
case 0xA003:
case 0xB000:
case 0xB001:
case 0xB002:
addr = (ushort)((addr & 0xfffc) | ((addr & 1) << 1) | ((addr & 2) >> 1));
nes.apu.ExWrite(addr, data);
break;
case 0xB003:
data = (byte)(data & 0x7F);
if (data == 0x08 || data == 0x2C) SetVRAM_Mirror(VRAM_MIRROR4H);
else if (data == 0x20) SetVRAM_Mirror(VRAM_VMIRROR);
else if (data == 0x24) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 0x28) SetVRAM_Mirror(VRAM_MIRROR4L);
break;
case 0xC000:
SetPROM_8K_Bank(6, data);
break;
case 0xD000:
SetVROM_1K_Bank(0, data);
break;
case 0xD001:
SetVROM_1K_Bank(2, data);
break;
case 0xD002:
SetVROM_1K_Bank(1, data);
break;
case 0xD003:
SetVROM_1K_Bank(3, data);
break;
case 0xE000:
SetVROM_1K_Bank(4, data);
break;
case 0xE001:
SetVROM_1K_Bank(6, data);
break;
case 0xE002:
SetVROM_1K_Bank(5, data);
break;
case 0xE003:
SetVROM_1K_Bank(7, data);
break;
case 0xF000:
irq_latch = data;
break;
case 0xF001:
irq_enable = (byte)((irq_enable & 0x01) * 3);
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF002:
irq_enable = (byte)(data & 0x03);
if ((irq_enable & 0x02) != 0)
{
irq_counter = irq_latch;
irq_clock = 0;
}
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
}
//void Mapper026::Clock(INT cycles)
public override void Clock(int cycles)
{
if ((irq_enable & 0x02) != 0)
{
if ((irq_clock += cycles) >= 0x72)
{
irq_clock -= 0x72;
if (irq_counter >= 0xFF)
{
irq_counter = irq_latch;
// nes.cpu.IRQ_NotPending();
//// nes.cpu.IRQ();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
else
{
irq_counter++;
}
}
}
}
//void Mapper026::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//p[1] = irq_counter;
//p[2] = irq_latch;
//*(INT*)&p[3] = irq_clock;
}
//void Mapper026::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//irq_enable = p[0];
//irq_counter = p[1];
//irq_latch = p[2];
//irq_clock = *(INT*)&p[3];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 96c606c490146244789d313ca2cf55a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,228 @@
//////////////////////////////////////////////////////////////////////////
// Mapper027 Konami VRC4 (World Hero) //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper027 : Mapper
{
ushort[] reg = new ushort[9];
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
INT irq_clock;
public Mapper027(NES parent) : base(parent)
{
}
public override void Reset()
{
for (INT i = 0; i < 8; i++)
{
reg[i] = (byte)i;
}
reg[8] = 0;
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
irq_clock = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x47DCBCC4)
{ // Gradius II(sample)
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
}
if (crc == 0x468F21FC)
{ // Racer Mini 4 ku(sample)
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
}
}
//void Mapper027::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF0CF)
{
case 0x8000:
if ((reg[8] & 0x02) != 0)
{
SetPROM_8K_Bank(6, data);
}
else
{
SetPROM_8K_Bank(4, data);
}
break;
case 0xA000:
SetPROM_8K_Bank(5, data);
break;
case 0x9000:
data &= 0x03;
if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR);
else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L);
else SetVRAM_Mirror(VRAM_MIRROR4H);
break;
case 0x9002:
case 0x9080:
reg[8] = data;
break;
case 0xB000:
reg[0] = (ushort)((reg[0] & 0xFF0) | (data & 0x0F));
SetVROM_1K_Bank(0, reg[0]);
break;
case 0xB001:
reg[0] = (ushort)((reg[0] & 0x0F) | (data << 4));
SetVROM_1K_Bank(0, reg[0]);
break;
case 0xB002:
reg[1] = (ushort)((reg[1] & 0xFF0) | (data & 0x0F));
SetVROM_1K_Bank(1, reg[1]);
break;
case 0xB003:
reg[1] = (ushort)((reg[1] & 0x0F) | (data << 4));
SetVROM_1K_Bank(1, reg[1]);
break;
case 0xC000:
reg[2] = (ushort)((reg[2] & 0xFF0) | (data & 0x0F));
SetVROM_1K_Bank(2, reg[2]);
break;
case 0xC001:
reg[2] = (ushort)((reg[2] & 0x0F) | (data << 4));
SetVROM_1K_Bank(2, reg[2]);
break;
case 0xC002:
reg[3] = (ushort)((reg[3] & 0xFF0) | (data & 0x0F));
SetVROM_1K_Bank(3, reg[3]);
break;
case 0xC003:
reg[3] = (ushort)((reg[3] & 0x0F) | (data << 4));
SetVROM_1K_Bank(3, reg[3]);
break;
case 0xD000:
reg[4] = (ushort)((reg[4] & 0xFF0) | (data & 0x0F));
SetVROM_1K_Bank(4, reg[4]);
break;
case 0xD001:
reg[4] = (ushort)((reg[4] & 0x0F) | (data << 4));
SetVROM_1K_Bank(4, reg[4]);
break;
case 0xD002:
reg[5] = (ushort)((reg[5] & 0xFF0) | (data & 0x0F));
SetVROM_1K_Bank(5, reg[5]);
break;
case 0xD003:
reg[5] = (ushort)((reg[5] & 0x0F) | (data << 4));
SetVROM_1K_Bank(5, reg[5]);
break;
case 0xE000:
reg[6] = (ushort)((reg[6] & 0xFF0) | (data & 0x0F));
SetVROM_1K_Bank(6, reg[6]);
break;
case 0xE001:
reg[6] = (ushort)((reg[6] & 0x0F) | (data << 4));
SetVROM_1K_Bank(6, reg[6]);
break;
case 0xE002:
reg[7] = (ushort)((reg[7] & 0xFF0) | (data & 0x0F));
SetVROM_1K_Bank(7, reg[7]);
break;
case 0xE003:
reg[7] = (ushort)((reg[7] & 0x0F) | (data << 4));
SetVROM_1K_Bank(7, reg[7]);
break;
case 0xF000:
irq_latch = (byte)((irq_latch & 0xF0) | (data & 0x0F));
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF001:
irq_latch = (byte)((irq_latch & 0x0F) | ((data & 0x0F) << 4));
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF003:
irq_enable = (byte)((irq_enable & 0x01) * 3);
irq_clock = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF002:
irq_enable = (byte)(data & 0x03);
if ((irq_enable & 0x02) != 0)
{
irq_counter = irq_latch;
irq_clock = 0;
}
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
}
//void Mapper027::HSync(INT scanline)
public override void HSync(int scanline)
{
if ((irq_enable & 0x02) != 0)
{
if (irq_counter == 0xFF)
{
irq_counter = irq_latch;
// nes.cpu.IRQ_NotPending();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
else
{
irq_counter++;
}
}
}
//void Mapper027::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//for (INT i = 0; i < 9; i++)
//{
// p[i] = reg[i];
//}
//p[9] = irq_enable;
//p[10] = irq_counter;
//p[11] = irq_latch;
//*(INT*)&p[12] = irq_clock;
}
//void Mapper027::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//for (INT i = 0; i < 9; i++)
//{
// reg[i] = p[i];
//}
//irq_enable = p[9];
//irq_counter = p[10];
//irq_latch = p[11];
//irq_clock = *(INT*)&p[12];
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 764ca4c42dfc3714e99ff2bbaf56c272
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,123 @@
//////////////////////////////////////////////////////////////////////////
// Mapper032 Irem G101 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper032 : Mapper
{
BYTE patch;
BYTE reg;
public Mapper032(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
reg = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
uint crc = nes.rom.GetPROM_CRC();
// For Major League(J)
if (crc == 0xc0fed437)
{
patch = 1;
}
// For Ai Sensei no Oshiete - Watashi no Hoshi(J)
if (crc == 0xfd3fc292)
{
SetPROM_32K_Bank(30, 31, 30, 31);
}
}
//void Mapper032::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF000)
{
case 0x8000:
if ((reg & 0x02) != 0)
{
SetPROM_8K_Bank(6, data);
}
else
{
SetPROM_8K_Bank(4, data);
}
break;
case 0x9000:
reg = data;
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
case 0xA000:
SetPROM_8K_Bank(5, data);
break;
}
switch (addr & 0xF007)
{
case 0xB000:
case 0xB001:
case 0xB002:
case 0xB003:
case 0xB004:
case 0xB005:
SetVROM_1K_Bank((byte)(addr & 0x0007), data);
break;
case 0xB006:
SetVROM_1K_Bank(6, data);
if (patch != 0 && ((data & 0x40) != 0))
{
SetVRAM_Mirror(0, 0, 0, 1);
}
break;
case 0xB007:
SetVROM_1K_Bank(7, data);
if (patch != 0 && ((data & 0x40) != 0))
{
SetVRAM_Mirror(0, 0, 0, 0);
}
break;
}
}
//void Mapper032::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg;
}
//void Mapper032::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg = p[0];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 124a427e842cc7d4f879e27d559edfc7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,260 @@
//////////////////////////////////////////////////////////////////////////
// Mapper033 Taito TC0190 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper033 : Mapper
{
BYTE[] reg = new byte[7];
BYTE patch;
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
public Mapper033(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
reg[0] = 0;
reg[1] = 2;
reg[2] = 4;
reg[3] = 5;
reg[4] = 6;
reg[5] = 7;
reg[6] = 1;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE != 0)
{
SetBank();
}
uint crc = nes.rom.GetPROM_CRC();
// Check For Old #33 games.... (CRC code by NesToy)
if (crc == 0x5e9bc161 // Akira(J)
|| crc == 0xecdbafa4 // Bakushou!! Jinsei Gekijou(J)
|| crc == 0x59cd0c31 // Don Doko Don(J)
|| crc == 0x837c1342 // Golf Ko Open(J)
|| crc == 0x42d893e4 // Operation Wolf(J)
|| crc == 0x1388aeb9 // Operation Wolf(U)
|| crc == 0x07ee6d8f // Power Blazer(J)
|| crc == 0x5193fb54 // Takeshi no Sengoku Fuuunji(J)
|| crc == 0xa71c3452)
{ // Insector X(J)
patch = 1;
}
nes.SetRenderMethod(EnumRenderMethod.PRE_RENDER);
if (crc == 0x202df297)
{ // Captain Saver(J)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
}
if (crc == 0x63bb86b5)
{ // The Jetsons(J)
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
}
}
//void Mapper033::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
// LOG( "Mapper033 addr=%04X data=%02X", addr&0xFFFF, data&0xFF );
switch (addr)
{
case 0x8000:
if (patch != 0)
{
if ((data & 0x40) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
SetPROM_8K_Bank(4, data & 0x1F);
}
else
{
SetPROM_8K_Bank(4, data);
}
break;
case 0x8001:
if (patch != 0)
{
SetPROM_8K_Bank(5, data & 0x1F);
}
else
{
SetPROM_8K_Bank(5, data);
}
break;
case 0x8002:
reg[0] = data;
SetBank();
break;
case 0x8003:
reg[1] = data;
SetBank();
break;
case 0xA000:
reg[2] = data;
SetBank();
break;
case 0xA001:
reg[3] = data;
SetBank();
break;
case 0xA002:
reg[4] = data;
SetBank();
break;
case 0xA003:
reg[5] = data;
SetBank();
break;
#if FLASE//0
case 0xC003:
case 0xE003:
reg[6] = data;
SetBank();
break;
case 0xC000:
irq_counter = data;
// nes.cpu.ClrIRQ( IRQ_MAPPER );
break;
case 0xC001:
case 0xC002:
case 0xE001:
case 0xE002:
irq_enable = data;
// nes.cpu.ClrIRQ( IRQ_MAPPER );
break;
#else
case 0xC000:
irq_latch = data;
irq_counter = irq_latch;
break;
case 0xC001:
irq_counter = irq_latch;
break;
case 0xC002:
irq_enable = 1;
break;
case 0xC003:
irq_enable = 0;
break;
case 0xE001:
case 0xE002:
case 0xE003:
break;
#endif
case 0xE000:
if ((data & 0x40) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
}
}
//void Mapper033::HSync(INT scanline)
public override void HSync(int scanline)
{
#if FALSE//0
// nes.cpu.ClrIRQ( IRQ_MAPPER );
if( scanline >= 0 && scanline <= 239 ) {
if( nes.ppu.IsDispON() ) {
if( irq_enable ) {
if( irq_counter == 0xFF ) {
irq_enable = 0;
irq_counter = 0;
// nes.cpu.SetIRQ( IRQ_MAPPER );
nes.cpu.SetIRQ( IRQ_TRIGGER );
} else {
irq_counter++;
}
}
}
}
#else
if (scanline >= 0 && scanline <= 239 && nes.ppu.IsDispON())
{
if (irq_enable != 0)
{
if (++irq_counter == 0)
{
irq_enable = 0;
irq_counter = 0;
nes.cpu.SetIRQ(IRQ_TRIGGER);
}
}
}
#endif
}
void SetBank()
{
SetVROM_2K_Bank(0, reg[0]);
SetVROM_2K_Bank(2, reg[1]);
// if( reg[6] & 0x01 ) {
SetVROM_1K_Bank(4, reg[2]);
SetVROM_1K_Bank(5, reg[3]);
SetVROM_1K_Bank(6, reg[4]);
SetVROM_1K_Bank(7, reg[5]);
// } else {
// SetVROM_2K_Bank( 4, reg[0] );
// SetVROM_2K_Bank( 6, reg[1] );
// }
}
//void Mapper033::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
for (INT i = 0; i < 7; i++)
{
p[i] = reg[i];
}
p[7] = irq_enable;
p[8] = irq_counter;
p[9] = irq_latch;
}
//void Mapper033::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
for (INT i = 0; i < 7; i++)
{
reg[i] = p[i];
}
irq_enable = p[7];
irq_counter = p[8];
irq_latch = p[9];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8c7bedd1ba634c14fa3532bb9524cf80
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,54 @@
//////////////////////////////////////////////////////////////////////////
// Mapper034 Nina-1 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper034 : Mapper
{
public Mapper034(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper034::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
switch (addr)
{
case 0x7FFD:
SetPROM_32K_Bank(data);
break;
case 0x7FFE:
SetVROM_4K_Bank(0, data);
break;
case 0x7FFF:
SetVROM_4K_Bank(4, data);
break;
}
}
//void Mapper034::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
SetPROM_32K_Bank(data);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 647e21ec144715c45bbcf44a6b5757b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,90 @@
//////////////////////////////////////////////////////////////////////////
// Mapper040 SMB2J //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper040 : Mapper
{
BYTE irq_enable;
INT irq_line;
public Mapper040(NES parent) : base(parent)
{
}
public override void Reset()
{
irq_enable = 0;
irq_line = 0;
SetPROM_8K_Bank(3, 6);
SetPROM_32K_Bank(4, 5, 0, 7);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper040::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xE000)
{
case 0x8000:
irq_enable = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xA000:
irq_enable = 0xFF;
irq_line = 37;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xC000:
break;
case 0xE000:
SetPROM_8K_Bank(6, data & 0x07);
break;
}
}
//void Mapper040::HSync(INT scanline)
public override void HSync(int scanline)
{
if (irq_enable != 0)
{
if (--irq_line <= 0)
{
// nes.cpu.IRQ();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
//void Mapper040::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//*(INT*)&p[1] = irq_line;
}
//void Mapper040::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//irq_enable = p[0];
//irq_line = *(INT*)&p[1];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: de917ab62c02ecc4b87138b609896ce7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,78 @@
//////////////////////////////////////////////////////////////////////////
// Mapper041 Caltron 6-in-1 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper041 : Mapper
{
BYTE[] reg = new byte[2];
public Mapper041(NES parent) : base(parent)
{
}
public override void Reset()
{
reg[0] = reg[1] = 0;
SetPROM_32K_Bank(0, 1, 2, 3);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper041::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr >= 0x6000 && addr < 0x6800)
{
SetPROM_32K_Bank(addr & 0x07);
reg[0] = (byte)(addr & 0x04);
reg[1] &= 0x03;
reg[1] |= (byte)((addr >> 1) & 0x0C);
SetVROM_8K_Bank(reg[1]);
if ((addr & 0x20) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
}
//void Mapper041::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
if (reg[0] != 0)
{
reg[1] &= 0x0C;
reg[1] |= (byte)(addr & 0x03);
SetVROM_8K_Bank(reg[1]);
}
}
//void Mapper041::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg[0];
p[1] = reg[1];
}
//void Mapper041::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg[0] = p[0];
reg[1] = p[1];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fc0a11d806679d94da60252475da5996
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,103 @@
//////////////////////////////////////////////////////////////////////////
// Mapper042 Mario Baby //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper042 : Mapper
{
BYTE irq_enable;
BYTE irq_counter;
public Mapper042(NES parent) : base(parent)
{
}
public override void Reset()
{
irq_enable = 0;
irq_counter = 0;
SetPROM_8K_Bank(3, 0);
SetPROM_32K_Bank(PROM_8K_SIZE - 4, PROM_8K_SIZE - 3, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper042::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xE003)
{
case 0xE000:
SetPROM_8K_Bank(3, data & 0x0F);
break;
case 0xE001:
if ((data & 0x08) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
case 0xE002:
if ((data & 0x02) != 0)
{
irq_enable = 0xFF;
}
else
{
irq_enable = 0;
irq_counter = 0;
}
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
}
//void Mapper042::HSync(INT scanline)
public override void HSync(int scanline)
{
nes.cpu.ClrIRQ(IRQ_MAPPER);
if (irq_enable != 0)
{
if (irq_counter < 215)
{
irq_counter++;
}
if (irq_counter == 215)
{
irq_enable = 0;
// nes.cpu.IRQ();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
//void Mapper042::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = irq_enable;
p[1] = irq_counter;
}
//void Mapper042::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
irq_enable = p[0];
irq_counter = p[1];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0645c16b7e182fa4094ef038567fd95b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,12 +1,18 @@
using static VirtualNes.MMU; //////////////////////////////////////////////////////////////////////////
// Mapper043 SMB2J //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU; using static VirtualNes.Core.CPU;
using INT = System.Int32; using INT = System.Int32;
using BYTE = System.Byte; using BYTE = System.Byte;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core namespace VirtualNes.Core
{ {
public class Mapper043 : Mapper public class Mapper043 : Mapper
{ {
BYTE irq_enable;
INT irq_counter;
public Mapper043(NES parent) : base(parent) public Mapper043(NES parent) : base(parent)
{ {
} }
@ -14,7 +20,119 @@ namespace VirtualNes.Core
public override void Reset() public override void Reset()
{ {
irq_enable = 0xFF;
irq_counter = 0;
SetPROM_8K_Bank(3, 2);
SetPROM_32K_Bank(1, 0, 4, 9);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
} }
//BYTE Mapper043::ReadLow(WORD addr)
public override byte ReadLow(ushort addr)
{
if (0x5000 <= addr && addr < 0x6000)
{
byte[] pPtr = nes.rom.GetPROM();
return pPtr[0x2000 * 8 + 0x1000 + (addr - 0x5000)];
}
return (BYTE)(addr >> 8);
}
//void Mapper043::ExWrite(WORD addr, BYTE data)
public override void ExWrite(ushort addr, byte data)
{
if ((addr & 0xF0FF) == 0x4022)
{
switch (data & 0x07)
{
case 0x00:
case 0x02:
case 0x03:
case 0x04:
SetPROM_8K_Bank(6, 4);
break;
case 0x01:
SetPROM_8K_Bank(6, 3);
break;
case 0x05:
SetPROM_8K_Bank(6, 7);
break;
case 0x06:
SetPROM_8K_Bank(6, 5);
break;
case 0x07:
SetPROM_8K_Bank(6, 6);
break;
}
}
}
//void Mapper043::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if ((addr & 0xF0FF) == 0x4022)
{
ExWrite(addr, data);
}
}
//void Mapper043::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
if (addr == 0x8122)
{
if ((data & 0x03) != 0)
{
irq_enable = 1;
}
else
{
irq_counter = 0;
irq_enable = 0;
}
nes.cpu.ClrIRQ(IRQ_MAPPER);
}
}
//void Mapper043::HSync(INT scanline)
public override void HSync(int scanline)
{
nes.cpu.ClrIRQ(IRQ_MAPPER);
if (irq_enable != 0)
{
irq_counter += 341;
if (irq_counter >= 12288)
{
irq_counter = 0;
// nes.cpu.IRQ();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
//void Mapper043::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//*(INT*)&p[1] = irq_counter;
}
//void Mapper043::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//irq_enable = p[0];
//irq_counter = *(INT*)&p[1];
}
public override bool IsStateSave()
{
return true;
}
} }
} }