dev_4VirtualNes #23
@ -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()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9f306005d0826a4e96ceec780568bb3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0d99073c4ae1444bbf4fa05498aecb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6082f7bf68f41f6439e13610e7766887
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b618d4b61b1e6ed48ad8ab3a38947424
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d201617d198186e41b362ea94be5533c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e319508c6222744dbb48902f10ab3df
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d065f0d406a26d4da372c16493e5bb9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 96c606c490146244789d313ca2cf55a4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 764ca4c42dfc3714e99ff2bbaf56c272
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 124a427e842cc7d4f879e27d559edfc7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c7bedd1ba634c14fa3532bb9524cf80
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 647e21ec144715c45bbcf44a6b5757b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: de917ab62c02ecc4b87138b609896ce7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc0a11d806679d94da60252475da5996
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0645c16b7e182fa4094ef038567fd95b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,12 +1,18 @@
|
||||
using static VirtualNes.MMU;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Mapper043 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 Mapper043 : Mapper
|
||||
{
|
||||
BYTE irq_enable;
|
||||
INT irq_counter;
|
||||
public Mapper043(NES parent) : base(parent)
|
||||
{
|
||||
}
|
||||
@ -14,7 +20,119 @@ namespace VirtualNes.Core
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user