Compare commits

...

11 Commits

285 changed files with 21274 additions and 0 deletions

View File

@ -0,0 +1,430 @@
//////////////////////////////////////////////////////////////////////////
// Mapper016 Bandai Standard //
//////////////////////////////////////////////////////////////////////////
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 Mapper016 : Mapper
{
BYTE patch; // For Famicom Jump 2
BYTE eeprom_type; // EEPROM type
BYTE[] reg = new byte[3];
BYTE irq_enable;
INT irq_counter;
INT irq_latch;
BYTE irq_type;
X24C01 x24c01;
X24C02 x24c02;
public Mapper016(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
reg[0] = reg[1] = reg[2] = 0;
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
irq_type = 0;
nes.SetIrqType( NES.IRQMETHOD.IRQ_CLOCK);
eeprom_type = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x3f15d20d // Famicom Jump 2(J)
|| crc == 0xf76aa523)
{ // Famicom Jump 2(J)(alt)
patch = 1;
eeprom_type = 0xFF;
WRAM[0x0BBC] = 0xFF; // SRAM対策
}
if (crc == 0x1d6f27f7)
{ // Dragon Ball Z 2(Korean Hack)
nes.SetIrqType( NES.IRQMETHOD.IRQ_HSYNC);
eeprom_type = 1;
}
if (crc == 0x6f7247c8)
{ // Dragon Ball Z 3(Korean Hack)
nes.SetIrqType( NES.IRQMETHOD.IRQ_CLOCK);
eeprom_type = 1;
}
if (crc == 0x7fb799fd)
{ // Dragon Ball 2 - Dai Maou Fukkatsu(J)
}
if (crc == 0x6c6c2feb // Dragon Ball 3 - Gokuu Den(J)
|| crc == 0x8edeb257)
{ // Dragon Ball 3 - Gokuu Den(J)(Alt)
}
if (crc == 0x31cd9903)
{ // Dragon Ball Z - Kyoushuu! Saiya Jin(J)
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
}
if (crc == 0xe49fc53e // Dragon Ball Z 2 - Gekishin Freeza!!(J)
|| crc == 0x1582fee0)
{ // Dragon Ball Z 2 - Gekishin Freeza!!(J) [alt]
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
eeprom_type = 1;
}
if (crc == 0x09499f4d)
{ // Dragon Ball Z 3 - Ressen Jinzou Ningen(J)
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
eeprom_type = 1;
}
if (crc == 0x2e991109)
{ // Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (J)
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
eeprom_type = 1;
}
if (crc == 0x146fb9c3)
{ // SD Gundam Gaiden - Knight Gundam Monogatari(J)
}
if (crc == 0x73ac76db // SD Gundam Gaiden - Knight Gundam Monogatari 2 - Hikari no Kishi(J)
|| crc == 0x81a15eb8)
{ // SD Gundam Gaiden - Knight Gundam Monogatari 3 - Densetsu no Kishi Dan(J)
eeprom_type = 1;
}
if (crc == 0x170250de)
{ // Rokudenashi Blues(J)
nes.SetRenderMethod( EnumRenderMethod.POST_ALL_RENDER);
eeprom_type = 1;
}
// DATACH系
if (crc == 0x0be0a328 // Datach - SD Gundam - Gundam Wars(J)
|| crc == 0x19e81461 // Datach - Dragon Ball Z - Gekitou Tenkaichi Budou Kai(J)
|| crc == 0x5b457641 // Datach - Ultraman Club - Supokon Fight!(J)
|| crc == 0x894efdbc // Datach - Crayon Shin Chan - Ora to Poi Poi(J)
|| crc == 0x983d8175 // Datach - Battle Rush - Build Up Robot Tournament(J)
|| crc == 0xbe06853f)
{ // Datach - J League Super Top Players(J)
eeprom_type = 2;
}
if (crc == 0xf51a7f46)
{ // Datach - Yuu Yuu Hakusho - Bakutou Ankoku Bujutsu Kai(J)
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
eeprom_type = 2;
}
if (eeprom_type == 0)
{
nes.SetSAVERAM_SIZE(128);
x24c01.Reset(WRAM);
}
else
if (eeprom_type == 1)
{
nes.SetSAVERAM_SIZE(256);
x24c02.Reset(WRAM);
}
else
if (eeprom_type == 2)
{
nes.SetSAVERAM_SIZE(384);
x24c02.Reset(WRAM);
x24c01.Reset(WRAM + 256);
}
}
//BYTE Mapper016::ReadLow(WORD addr)
public override byte ReadLow(ushort addr)
{
if (patch!=0)
{
return base.ReadLow(addr);
}
else
{
if ((addr & 0x00FF) == 0x0000)
{
BYTE ret = 0;
if (eeprom_type == 0)
{
ret = x24c01.Read();
}
else
if (eeprom_type == 1)
{
ret = x24c02.Read();
}
else
if (eeprom_type == 2)
{
ret = x24c02.Read() & x24c01.Read();
}
return (ret ? 0x10 : 0) | (nes.GetBarcodeStatus());
}
}
return 0x00;
}
//void Mapper016::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (patch == 0)
{
WriteSubA(addr, data);
}
else
{
Mapper::WriteLow(addr, data);
}
}
void Mapper016::Write(WORD addr, BYTE data)
{
if (!patch)
{
WriteSubA(addr, data);
}
else
{
WriteSubB(addr, data);
}
}
static BYTE eeprom_addinc;
// Normal mapper #16
void Mapper016::WriteSubA(WORD addr, BYTE data)
{
switch (addr & 0x000F)
{
case 0x0000:
case 0x0001:
case 0x0002:
case 0x0003:
case 0x0004:
case 0x0005:
case 0x0006:
case 0x0007:
if (VROM_1K_SIZE)
{
SetVROM_1K_Bank(addr & 0x0007, data);
}
if (eeprom_type == 2)
{
reg[0] = data;
x24c01.Write((data & 0x08) ? 0xFF : 0, (reg[1] & 0x40) ? 0xFF : 0);
}
break;
case 0x0008:
SetPROM_16K_Bank(4, data);
break;
case 0x0009:
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 0x000A:
irq_enable = data & 0x01;
irq_counter = irq_latch;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0x000B:
irq_latch = (irq_latch & 0xFF00) | data;
irq_counter = (irq_counter & 0xFF00) | data;
break;
case 0x000C:
irq_latch = ((INT)data << 8) | (irq_latch & 0x00FF);
irq_counter = ((INT)data << 8) | (irq_counter & 0x00FF);
break;
case 0x000D:
// EEPTYPE0(DragonBallZ)
if (eeprom_type == 0)
{
x24c01.Write((data & 0x20) ? 0xFF : 0, (data & 0x40) ? 0xFF : 0);
}
// EEPTYPE1(DragonBallZ2,Z3,Z Gaiden)
if (eeprom_type == 1)
{
x24c02.Write((data & 0x20) ? 0xFF : 0, (data & 0x40) ? 0xFF : 0);
}
// EEPTYPE2(DATACH)
if (eeprom_type == 2)
{
reg[1] = data;
x24c02.Write((data & 0x20) ? 0xFF : 0, (data & 0x40) ? 0xFF : 0);
x24c01.Write((reg[0] & 0x08) ? 0xFF : 0, (data & 0x40) ? 0xFF : 0);
}
break;
}
}
// Famicom Jump 2
void Mapper016::WriteSubB(WORD addr, BYTE data)
{
switch (addr)
{
case 0x8000:
case 0x8001:
case 0x8002:
case 0x8003:
reg[0] = data & 0x01;
SetPROM_8K_Bank(4, reg[0] * 0x20 + reg[2] * 2 + 0);
SetPROM_8K_Bank(5, reg[0] * 0x20 + reg[2] * 2 + 1);
break;
case 0x8004:
case 0x8005:
case 0x8006:
case 0x8007:
reg[1] = data & 0x01;
SetPROM_8K_Bank(6, reg[1] * 0x20 + 0x1E);
SetPROM_8K_Bank(7, reg[1] * 0x20 + 0x1F);
break;
case 0x8008:
reg[2] = data;
SetPROM_8K_Bank(4, reg[0] * 0x20 + reg[2] * 2 + 0);
SetPROM_8K_Bank(5, reg[0] * 0x20 + reg[2] * 2 + 1);
SetPROM_8K_Bank(6, reg[1] * 0x20 + 0x1E);
SetPROM_8K_Bank(7, reg[1] * 0x20 + 0x1F);
break;
case 0x8009:
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 0x800A:
irq_enable = data & 0x01;
irq_counter = irq_latch;
// if( !irq_enable ) {
// nes.cpu.ClrIRQ( IRQ_MAPPER );
// }
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0x800B:
irq_latch = (irq_latch & 0xFF00) | data;
break;
case 0x800C:
irq_latch = ((INT)data << 8) | (irq_latch & 0x00FF);
break;
case 0x800D:
break;
}
}
void Mapper016::HSync(INT scanline)
{
if (irq_enable && (nes.GetIrqType() == NES.IRQMETHOD.IRQ_HSYNC))
{
if (irq_counter <= 113)
{
nes.cpu.SetIRQ(IRQ_MAPPER);
// nes.cpu.IRQ();
//// nes.cpu.IRQ_NotPending();
// irq_enable = 0;
// irq_counter = 0;
irq_counter &= 0xFFFF;
}
else
{
irq_counter -= 113;
}
}
}
void Mapper016::Clock(INT cycles)
{
if (irq_enable && (nes.GetIrqType() == NES::IRQ_CLOCK))
{
if ((irq_counter -= cycles) <= 0)
{
nes.cpu.SetIRQ(IRQ_MAPPER);
// nes.cpu.IRQ();
//// nes.cpu.IRQ_NotPending();
// irq_enable = 0;
// irq_counter = 0;
irq_counter &= 0xFFFF;
}
}
}
void Mapper016::SaveState(LPBYTE p)
{
p[0] = reg[0];
p[1] = reg[1];
p[2] = reg[2];
p[3] = irq_enable;
*(INT*)&p[4] = irq_counter;
*(INT*)&p[8] = irq_latch;
if (eeprom_type == 0)
{
x24c01.Save(&p[16]);
}
else
if (eeprom_type == 1)
{
x24c02.Save(&p[16]);
}
else
if (eeprom_type == 2)
{
x24c02.Save(&p[16]);
x24c01.Save(&p[48]);
}
}
void Mapper016::LoadState(LPBYTE p)
{
reg[0] = p[0];
reg[1] = p[1];
reg[2] = p[2];
irq_enable = p[3];
irq_counter = *(INT*)&p[4];
irq_latch = *(INT*)&p[8];
if (eeprom_type == 0)
{
x24c01.Load(&p[16]);
}
else
if (eeprom_type == 1)
{
x24c02.Load(&p[16]);
}
else
if (eeprom_type == 2)
{
x24c02.Load(&p[16]);
x24c01.Load(&p[48]);
}
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,127 @@
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 Mapper017 : Mapper
{
BYTE irq_enable;
INT irq_counter;
INT irq_latch;
public Mapper017(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);
}
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
}
//void Mapper017::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
switch (addr)
{
case 0x42FE:
if ((data & 0x10) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
break;
case 0x42FF:
if ((data & 0x10) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
case 0x4501:
irq_enable = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0x4502:
irq_latch = (irq_latch & 0xFF00) | data;
break;
case 0x4503:
irq_latch = (irq_latch & 0x00FF) | ((INT)data << 8);
irq_counter = irq_latch;
irq_enable = 0xFF;
break;
case 0x4504:
case 0x4505:
case 0x4506:
case 0x4507:
SetPROM_8K_Bank((byte)(addr & 0x07), data);
break;
case 0x4510:
case 0x4511:
case 0x4512:
case 0x4513:
case 0x4514:
case 0x4515:
case 0x4516:
case 0x4517:
SetVROM_1K_Bank((byte)(addr & 0x07), data);
break;
default:
base.WriteLow(addr, data);
break;
}
}
//void Mapper017::HSync(INT scanline)
public override void HSync(int scanline)
{
if (irq_enable != 0)
{
if (irq_counter >= 0xFFFF - 113)
{
nes.cpu.SetIRQ(IRQ_MAPPER);
// nes.cpu.IRQ();
// irq_counter = 0;
// irq_enable = 0;
irq_counter &= 0xFFFF;
}
else
{
irq_counter += 113;
}
}
}
//void Mapper017::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//*(INT*)&p[1] = irq_counter;
//*(INT*)&p[5] = irq_latch;
}
//void Mapper017::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//irq_enable = p[0];
//irq_counter = *(INT*)&p[1];
//irq_latch = *(INT*)&p[5];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,278 @@
//////////////////////////////////////////////////////////////////////////
// Mapper018 Jaleco SS8806 //
//////////////////////////////////////////////////////////////////////////
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 Mapper018 : Mapper
{
BYTE[] reg = new byte[11];
BYTE irq_enable;
BYTE irq_mode;
INT irq_latch;
INT irq_counter;
public Mapper018(NES parent) : base(parent)
{
}
public override void Reset()
{
for (INT i = 0; i < 11; i++)
{
reg[i] = 0;
}
reg[2] = (byte)(PROM_8K_SIZE - 2);
reg[3] = (byte)(PROM_8K_SIZE - 1);
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
irq_enable = 0;
irq_mode = 0;
irq_counter = 0xFFFF;
irq_latch = 0xFFFF;
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0xefb1df9e)
{ // The Lord of King(J)
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
}
if (crc == 0x3746f951)
{ // Pizza Pop!(J)
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
}
// nes.SetRenderMethod( NES::PRE_ALL_RENDER );
// nes.SetRenderMethod( NES::POST_ALL_RENDER );
}
//void Mapper018::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr)
{
case 0x8000:
reg[0] = (byte)((reg[0] & 0xF0) | (data & 0x0F));
SetPROM_8K_Bank(4, reg[0]);
break;
case 0x8001:
reg[0] = (byte)((reg[0] & 0x0F) | ((data & 0x0F) << 4));
SetPROM_8K_Bank(4, reg[0]);
break;
case 0x8002:
reg[1] = (byte)((reg[1] & 0xF0) | (data & 0x0F));
SetPROM_8K_Bank(5, reg[1]);
break;
case 0x8003:
reg[1] = (byte)((reg[1] & 0x0F) | ((data & 0x0F) << 4));
SetPROM_8K_Bank(5, reg[1]);
break;
case 0x9000:
reg[2] = (byte)((reg[2] & 0xF0) | (data & 0x0F));
SetPROM_8K_Bank(6, reg[2]);
break;
case 0x9001:
reg[2] = (byte)((reg[2] & 0x0F) | ((data & 0x0F) << 4));
SetPROM_8K_Bank(6, reg[2]);
break;
case 0xA000:
reg[3] = (byte)((reg[3] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(0, reg[3]);
break;
case 0xA001:
reg[3] = (byte)((reg[3] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(0, reg[3]);
break;
case 0xA002:
reg[4] = (byte)((reg[4] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(1, reg[4]);
break;
case 0xA003:
reg[4] = (byte)((reg[4] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(1, reg[4]);
break;
case 0xB000:
reg[5] = (byte)((reg[5] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(2, reg[5]);
break;
case 0xB001:
reg[5] = (byte)((reg[5] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(2, reg[5]);
break;
case 0xB002:
reg[6] = (byte)((reg[6] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(3, reg[6]);
break;
case 0xB003:
reg[6] = (byte)((reg[6] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(3, reg[6]);
break;
case 0xC000:
reg[7] = (byte)((reg[7] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(4, reg[7]);
break;
case 0xC001:
reg[7] = (byte)((reg[7] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(4, reg[7]);
break;
case 0xC002:
reg[8] = (byte)((reg[8] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(5, reg[8]);
break;
case 0xC003:
reg[8] = (byte)((reg[8] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(5, reg[8]);
break;
case 0xD000:
reg[9] = (byte)((reg[9] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(6, reg[9]);
break;
case 0xD001:
reg[9] = (byte)((reg[9] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(6, reg[9]);
break;
case 0xD002:
reg[10] = (byte)((reg[10] & 0xF0) | (data & 0x0F));
SetVROM_1K_Bank(7, reg[10]);
break;
case 0xD003:
reg[10] = (byte)((reg[10] & 0x0F) | ((data & 0x0F) << 4));
SetVROM_1K_Bank(7, reg[10]);
break;
case 0xE000:
irq_latch = (irq_latch & 0xFFF0) | (data & 0x0F);
break;
case 0xE001:
irq_latch = (irq_latch & 0xFF0F) | ((data & 0x0F) << 4);
break;
case 0xE002:
irq_latch = (irq_latch & 0xF0FF) | ((data & 0x0F) << 8);
break;
case 0xE003:
irq_latch = (irq_latch & 0x0FFF) | ((data & 0x0F) << 12);
break;
case 0xF000:
// if( data & 0x01 ) {
irq_counter = irq_latch;
// } else {
// irq_counter = 0;
// }
break;
case 0xF001:
irq_mode = (byte)((data >> 1) & 0x07);
irq_enable = ((byte)(data & 0x01));
// if( !irq_enable ) {
nes.cpu.ClrIRQ(IRQ_MAPPER);
// }
break;
case 0xF002:
data &= 0x03;
if (data == 0) SetVRAM_Mirror(VRAM_HMIRROR);
else if (data == 1) SetVRAM_Mirror(VRAM_VMIRROR);
else SetVRAM_Mirror(VRAM_MIRROR4L);
break;
}
}
//void Mapper018::Clock(INT cycles)
public override void Clock(int cycles)
{
bool bIRQ = false;
INT irq_counter_old = irq_counter;
if (irq_enable != 0 && irq_counter != 0)
{
irq_counter -= cycles;
switch (irq_mode)
{
case 0:
if (irq_counter <= 0)
{
bIRQ = true;
}
break;
case 1:
if ((irq_counter & 0xF000) != (irq_counter_old & 0xF000))
{
bIRQ = true;
}
break;
case 2:
case 3:
if ((irq_counter & 0xFF00) != (irq_counter_old & 0xFF00))
{
bIRQ = true;
}
break;
case 4:
case 5:
case 6:
case 7:
if ((irq_counter & 0xFFF0) != (irq_counter_old & 0xFFF0))
{
bIRQ = true;
}
break;
}
if (bIRQ)
{
//// irq_enable = 0;
// irq_counter = irq_latch;
irq_counter = 0;
irq_enable = 0;
// nes.cpu.IRQ_NotPending();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
//void Mapper018::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_mode;
//*(INT*)&p[13] = irq_counter;
//*(INT*)&p[17] = irq_latch;
}
//void Mapper018::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//for (INT i = 0; i < 11; i++)
//{
// p[i] = reg[i];
//}
//irq_enable = p[11];
//irq_mode = p[12];
//irq_counter = *(INT*)&p[13];
//irq_latch = *(INT*)&p[17];
}
public override bool IsStateSave()
{
return true;
}
}
}

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

@ -0,0 +1,138 @@
//////////////////////////////////////////////////////////////////////////
// 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)
{
}
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;
}
}
}

View File

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

View File

@ -0,0 +1,289 @@
//////////////////////////////////////////////////////////////////////////
// Mapper044 Super HiK 7-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 Mapper044 : Mapper
{
BYTE[] reg = new byte[8];
BYTE patch;
BYTE bank;
BYTE prg0, prg1;
BYTE chr01, chr23, chr4, chr5, chr6, chr7;
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
public Mapper044(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
if (nes.rom.GetPROM_CRC() == 0x7eef434c)
{
patch = 1;
}
for (INT i = 0; i < 8; i++)
{
reg[i] = 0;
}
bank = 0;
prg0 = 0;
prg1 = 1;
// set VROM banks
if (VROM_1K_SIZE!=0)
{
chr01 = 0;
chr23 = 2;
chr4 = 4;
chr5 = 5;
chr6 = 6;
chr7 = 7;
}
else
{
chr01 = chr23 = chr4 = chr5 = chr6 = chr7 = 0;
}
SetBank_CPU();
SetBank_PPU();
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
}
//void Mapper044::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr == 0x6000)
{
if (patch!=0)
{
bank = (byte)((data & 0x06) >> 1);
}
else
{
bank = (byte)((data & 0x01) << 1);
}
SetBank_CPU();
SetBank_PPU();
}
}
//void Mapper044::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xE001)
{
case 0x8000:
reg[0] = data;
SetBank_CPU();
SetBank_PPU();
break;
case 0x8001:
reg[1] = data;
switch (reg[0] & 0x07)
{
case 0x00:
chr01 = (byte)(data & 0xFE);
SetBank_PPU();
break;
case 0x01:
chr23 = (byte)(data & 0xFE);
SetBank_PPU();
break;
case 0x02:
chr4 = data;
SetBank_PPU();
break;
case 0x03:
chr5 = data;
SetBank_PPU();
break;
case 0x04:
chr6 = data;
SetBank_PPU();
break;
case 0x05:
chr7 = data;
SetBank_PPU();
break;
case 0x06:
prg0 = data;
SetBank_CPU();
break;
case 0x07:
prg1 = data;
SetBank_CPU();
break;
}
break;
case 0xA000:
reg[2] = data;
if (!nes.rom.Is4SCREEN())
{
if ((data & 0x01)!=0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
break;
case 0xA001:
reg[3] = data;
bank = (byte)(data & 0x07);
if (bank == 7)
{
bank = 6;
}
SetBank_CPU();
SetBank_PPU();
break;
case 0xC000:
reg[4] = data;
irq_counter = data;
break;
case 0xC001:
reg[5] = data;
irq_latch = data;
break;
case 0xE000:
reg[6] = data;
irq_enable = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xE001:
reg[7] = data;
irq_enable = 1;
// nes.cpu.ClrIRQ( IRQ_MAPPER );
break;
}
}
//void Mapper044::HSync(INT scanline)
public override void HSync(int scanline)
{
if ((scanline >= 0 && scanline <= 239))
{
if (nes.ppu.IsDispON())
{
if (irq_enable!=0)
{
if ((--irq_counter)==0)
{
irq_counter = irq_latch;
// nes.cpu.IRQ();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
}
void SetBank_CPU()
{
if ((reg[0] & 0x40)!=0)
{
SetPROM_8K_Bank(4, ((bank == 6) ? 0x1e : 0x0e) | (bank << 4));
SetPROM_8K_Bank(5, ((bank == 6) ? 0x1f & prg1 : 0x0f & prg1) | (bank << 4));
SetPROM_8K_Bank(6, ((bank == 6) ? 0x1f & prg0 : 0x0f & prg0) | (bank << 4));
SetPROM_8K_Bank(7, ((bank == 6) ? 0x1f : 0x0f) | (bank << 4));
}
else
{
SetPROM_8K_Bank(4, ((bank == 6) ? 0x1f & prg0 : 0x0f & prg0) | (bank << 4));
SetPROM_8K_Bank(5, ((bank == 6) ? 0x1f & prg1 : 0x0f & prg1) | (bank << 4));
SetPROM_8K_Bank(6, ((bank == 6) ? 0x1e : 0x0e) | (bank << 4));
SetPROM_8K_Bank(7, ((bank == 6) ? 0x1f : 0x0f) | (bank << 4));
}
}
void SetBank_PPU()
{
if (VROM_1K_SIZE!=0)
{
if ((reg[0] & 0x80)!=0)
{
SetVROM_1K_Bank(0, ((bank == 6) ? 0xff & chr4 : 0x7f & chr4) | (bank << 7));
SetVROM_1K_Bank(1, ((bank == 6) ? 0xff & chr5 : 0x7f & chr5) | (bank << 7));
SetVROM_1K_Bank(2, ((bank == 6) ? 0xff & chr6 : 0x7f & chr6) | (bank << 7));
SetVROM_1K_Bank(3, ((bank == 6) ? 0xff & chr7 : 0x7f & chr7) | (bank << 7));
SetVROM_1K_Bank(4, ((bank == 6) ? 0xff & chr01 : 0x7f & chr01) | (bank << 7));
SetVROM_1K_Bank(5, ((bank == 6) ? 0xff & (chr01 + 1) : 0x7f & (chr01 + 1)) | (bank << 7));
SetVROM_1K_Bank(6, ((bank == 6) ? 0xff & chr23 : 0x7f & chr23) | (bank << 7));
SetVROM_1K_Bank(7, ((bank == 6) ? 0xff & (chr23 + 1) : 0x7f & (chr23 + 1)) | (bank << 7));
}
else
{
SetVROM_1K_Bank(0, ((bank == 6) ? 0xff & chr01 : 0x7f & chr01) | (bank << 7));
SetVROM_1K_Bank(1, ((bank == 6) ? 0xff & (chr01 + 1) : 0x7f & (chr01 + 1)) | (bank << 7));
SetVROM_1K_Bank(2, ((bank == 6) ? 0xff & chr23 : 0x7f & chr23) | (bank << 7));
SetVROM_1K_Bank(3, ((bank == 6) ? 0xff & (chr23 + 1) : 0x7f & (chr23 + 1)) | (bank << 7));
SetVROM_1K_Bank(4, ((bank == 6) ? 0xff & chr4 : 0x7f & chr4) | (bank << 7));
SetVROM_1K_Bank(5, ((bank == 6) ? 0xff & chr5 : 0x7f & chr5) | (bank << 7));
SetVROM_1K_Bank(6, ((bank == 6) ? 0xff & chr6 : 0x7f & chr6) | (bank << 7));
SetVROM_1K_Bank(7, ((bank == 6) ? 0xff & chr7 : 0x7f & chr7) | (bank << 7));
}
}
}
//void Mapper044::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
for (INT i = 0; i < 8; i++)
{
p[i] = reg[i];
}
p[8] = prg0;
p[9] = prg1;
p[10] = chr01;
p[11] = chr23;
p[12] = chr4;
p[13] = chr5;
p[14] = chr6;
p[15] = chr7;
p[16] = irq_enable;
p[17] = irq_counter;
p[18] = irq_latch;
p[19] = bank;
}
//void Mapper044::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
for (INT i = 0; i < 8; i++)
{
reg[i] = p[i];
}
prg0 = p[8];
prg1 = p[9];
chr01 = p[10];
chr23 = p[11];
chr4 = p[12];
chr5 = p[13];
chr6 = p[14];
chr7 = p[15];
irq_enable = p[16];
irq_counter = p[17];
irq_latch = p[18];
bank = p[19];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,387 @@
//////////////////////////////////////////////////////////////////////////
// Mapper045 1000000-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 Mapper045 : Mapper
{
BYTE[] reg = new byte[8];
BYTE patch;
BYTE prg0, prg1, prg2, prg3;
BYTE chr0, chr1, chr2, chr3, chr4, chr5, chr6, chr7;
BYTE[] p = new byte[4];
INT[] c = new int[8];
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
BYTE irq_latched;
BYTE irq_reset;
public Mapper045(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
for (INT i = 0; i < 8; i++)
{
reg[i] = 0;
}
prg0 = 0;
prg1 = 1;
prg2 = (byte)(PROM_8K_SIZE - 2);
prg3 = (byte)(PROM_8K_SIZE - 1);
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x58bcacf6 // Kunio 8-in-1 (Pirate Cart)
|| crc == 0x9103cfd6 // HIK 7-in-1 (Pirate Cart)
|| crc == 0xc082e6d3)
{ // Super 8-in-1 (Pirate Cart)
patch = 1;
prg2 = 62;
prg3 = 63;
}
if (crc == 0xe0dd259d)
{ // Super 3-in-1 (Pirate Cart)
patch = 2;
}
SetPROM_32K_Bank(prg0, prg1, prg2, prg3);
p[0] = prg0;
p[1] = prg1;
p[2] = prg2;
p[3] = prg3;
SetVROM_8K_Bank(0);
// chr0 = c[0] = 0;
// chr1 = c[1] = 0
// chr2 = c[2] = 0;
// chr3 = c[3] = 0;
// chr4 = c[4] = 0;
// chr5 = c[5] = 0;
// chr6 = c[6] = 0;
// chr7 = c[7] = 0;
c[0] = chr0 = 0;
c[1] = chr1 = 1;
c[2] = chr2 = 2;
c[3] = chr3 = 3;
c[4] = chr4 = 4;
c[5] = chr5 = 5;
c[6] = chr6 = 6;
c[7] = chr7 = 7;
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
irq_latched = 0;
irq_reset = 0;
}
//void Mapper045::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
// if( addr == 0x6000 ) {
// if( addr == 0x6000 && !(reg[3]&0x40) ) {
if ((reg[3] & 0x40) == 0)
{
reg[reg[5]] = data;
reg[5] = (byte)((reg[5] + 1) & 0x03);
SetBank_CPU_4(prg0);
SetBank_CPU_5(prg1);
SetBank_CPU_6(prg2);
SetBank_CPU_7(prg3);
SetBank_PPU();
}
}
//void Mapper045::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xE001)
{
case 0x8000:
if ((data & 0x40) != (reg[6] & 0x40))
{
BYTE swp;
swp = prg0; prg0 = prg2; prg2 = swp;
swp = p[0]; p[0] = p[2]; p[2] = swp;
SetBank_CPU_4(p[0]);
SetBank_CPU_5(p[1]);
}
if (VROM_1K_SIZE != 0)
{
if ((data & 0x80) != (reg[6] & 0x80))
{
INT swp;
swp = chr4; chr4 = chr0; chr0 = (byte)swp;
swp = chr5; chr5 = chr1; chr1 = (byte)swp;
swp = chr6; chr6 = chr2; chr2 = (byte)swp;
swp = chr7; chr7 = chr3; chr3 = (byte)swp;
swp = c[4]; c[4] = c[0]; c[0] = swp;
swp = c[5]; c[5] = c[1]; c[1] = swp;
swp = c[6]; c[6] = c[2]; c[2] = swp;
swp = c[7]; c[7] = c[3]; c[3] = swp;
SetVROM_8K_Bank(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
}
}
reg[6] = data;
break;
case 0x8001:
switch (reg[6] & 0x07)
{
case 0x00:
chr0 = (byte)((data & 0xFE) + 0);
chr1 = (byte)((data & 0xFE) + 1);
SetBank_PPU();
break;
case 0x01:
chr2 = (byte)((data & 0xFE) + 0);
chr3 = (byte)((data & 0xFE) + 1);
SetBank_PPU();
break;
case 0x02:
chr4 = data;
SetBank_PPU();
break;
case 0x03:
chr5 = data;
SetBank_PPU();
break;
case 0x04:
chr6 = data;
SetBank_PPU();
break;
case 0x05:
chr7 = data;
SetBank_PPU();
break;
case 0x06:
if ((reg[6] & 0x40) != 0)
{
prg2 = (byte)(data & 0x3F);
SetBank_CPU_6(data);
}
else
{
prg0 = (byte)(data & 0x3F);
SetBank_CPU_4(data);
}
break;
case 0x07:
prg1 = (byte)(data & 0x3F);
SetBank_CPU_5(data);
break;
}
break;
case 0xA000:
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
case 0xC000:
if (patch == 2)
{
if (data == 0x29 || data == 0x70)
data = 0x07;
}
irq_latch = data;
irq_latched = 1;
if (irq_reset != 0)
{
irq_counter = data;
irq_latched = 0;
}
// irq_counter = data;
break;
case 0xC001:
// irq_latch = data;
irq_counter = irq_latch;
break;
case 0xE000:
irq_enable = 0;
irq_reset = 1;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xE001:
irq_enable = 1;
if (irq_latched != 0)
{
irq_counter = irq_latch;
}
break;
}
}
//void Mapper045::HSync(INT scanline)
public override void HSync(int scanline)
{
irq_reset = 0;
if ((scanline >= 0 && scanline <= 239) && nes.ppu.IsDispON())
{
if (irq_counter != 0)
{
irq_counter--;
if (irq_counter == 0)
{
if (irq_enable != 0)
{
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
}
void SetBank_CPU_4(INT data)
{
data &= (reg[3] & 0x3F) ^ 0xFF;
data &= 0x3F;
data |= reg[1];
SetPROM_8K_Bank(4, data);
p[0] = (byte)data;
}
void SetBank_CPU_5(INT data)
{
data &= (reg[3] & 0x3F) ^ 0xFF;
data &= 0x3F;
data |= reg[1];
SetPROM_8K_Bank(5, data);
p[1] = (byte)data;
}
void SetBank_CPU_6(INT data)
{
data &= (reg[3] & 0x3F) ^ 0xFF;
data &= 0x3F;
data |= reg[1];
SetPROM_8K_Bank(6, data);
p[2] = (byte)data;
}
void SetBank_CPU_7(INT data)
{
data &= (reg[3] & 0x3F) ^ 0xFF;
data &= 0x3F;
data |= reg[1];
SetPROM_8K_Bank(7, data);
p[3] = (byte)data;
}
void SetBank_PPU()
{
BYTE[] table = new byte[] {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF
};
c[0] = chr0;
c[1] = chr1;
c[2] = chr2;
c[3] = chr3;
c[4] = chr4;
c[5] = chr5;
c[6] = chr6;
c[7] = chr7;
for (INT i = 0; i < 8; i++)
{
c[i] &= table[reg[2] & 0x0F];
c[i] |= reg[0] & ((patch != 1) ? 0xFF : 0xC0);
c[i] += (reg[2] & ((patch != 1) ? 0x10 : 0x30)) << 4;
}
if ((reg[6] & 0x80) != 0)
{
SetVROM_8K_Bank(c[4], c[5], c[6], c[7], c[0], c[1], c[2], c[3]);
}
else
{
SetVROM_8K_Bank(c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7]);
}
}
//void Mapper045::SaveState(LPBYTE ps)
public override void SaveState(byte[] p)
{
//INT i;
//for (i = 0; i < 8; i++)
//{
// ps[i] = reg[i];
//}
//for (i = 0; i < 4; i++)
//{
// ps[i + 8] = p[i];
//}
//for (i = 0; i < 8; i++)
//{
// *(INT*)&ps[i * 4 + 64] = c[i];
//}
//ps[20] = prg0;
//ps[21] = prg1;
//ps[22] = prg2;
//ps[23] = prg3;
//ps[24] = chr0;
//ps[25] = chr1;
//ps[26] = chr2;
//ps[27] = chr3;
//ps[28] = chr4;
//ps[29] = chr5;
//ps[30] = chr6;
//ps[31] = chr7;
//ps[32] = irq_enable;
//ps[33] = irq_counter;
//ps[34] = irq_latch;
}
//void Mapper045::LoadState(LPBYTE ps)
public override void LoadState(byte[] p)
{
//INT i;
//for (i = 0; i < 8; i++)
//{
// reg[i] = ps[i];
//}
//for (i = 0; i < 4; i++)
//{
// p[i] = ps[i + 8];
//}
//for (i = 0; i < 8; i++)
//{
// c[i] = *(INT*)&ps[i * 4 + 64];
//}
//prg0 = ps[20];
//prg1 = ps[21];
//prg2 = ps[22];
//prg3 = ps[23];
//chr0 = ps[24];
//chr1 = ps[25];
//chr2 = ps[26];
//chr3 = ps[27];
//chr4 = ps[28];
//chr5 = ps[29];
//chr6 = ps[30];
//chr7 = ps[31];
//irq_enable = ps[32];
//irq_counter = ps[33];
//irq_latch = ps[34];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,88 @@
//////////////////////////////////////////////////////////////////////////
// Mapper046 Rumble Station //
//////////////////////////////////////////////////////////////////////////
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 Mapper046 : Mapper
{
int[] reg = new int[4];
public Mapper046(NES parent) : base(parent)
{
}
public override void Reset()
{
reg[0] = 0;
reg[1] = 0;
reg[2] = 0;
reg[3] = 0;
SetBank();
SetVRAM_Mirror(VRAM_VMIRROR);
}
//void Mapper046::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
reg[0] = data & 0x0F;
reg[1] = (data & 0xF0) >> 4;
SetBank();
}
//void Mapper046::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
reg[2] = data & 0x01;
reg[3] = (data & 0x70) >> 4;
SetBank();
}
void SetBank()
{
SetPROM_8K_Bank(4, reg[0] * 8 + reg[2] * 4 + 0);
SetPROM_8K_Bank(5, reg[0] * 8 + reg[2] * 4 + 1);
SetPROM_8K_Bank(6, reg[0] * 8 + reg[2] * 4 + 2);
SetPROM_8K_Bank(7, reg[0] * 8 + reg[2] * 4 + 3);
SetVROM_1K_Bank(0, reg[1] * 64 + reg[3] * 8 + 0);
SetVROM_1K_Bank(1, reg[1] * 64 + reg[3] * 8 + 1);
SetVROM_1K_Bank(2, reg[1] * 64 + reg[3] * 8 + 2);
SetVROM_1K_Bank(3, reg[1] * 64 + reg[3] * 8 + 3);
SetVROM_1K_Bank(4, reg[1] * 64 + reg[3] * 8 + 4);
SetVROM_1K_Bank(5, reg[1] * 64 + reg[3] * 8 + 5);
SetVROM_1K_Bank(6, reg[1] * 64 + reg[3] * 8 + 6);
SetVROM_1K_Bank(7, reg[1] * 64 + reg[3] * 8 + 7);
}
//void Mapper046::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = (byte)reg[0];
p[1] = (byte)reg[1];
p[2] = (byte)reg[2];
p[3] = (byte)reg[3];
}
//void Mapper046::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg[0] = p[0];
reg[1] = p[1];
reg[2] = p[2];
reg[3] = p[3];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,275 @@
//////////////////////////////////////////////////////////////////////////
// Mapper047 NES-QJ //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper047 : Mapper
{
BYTE[] reg = new byte[8];
BYTE patch;
BYTE bank;
BYTE prg0, prg1;
BYTE chr01, chr23, chr4, chr5, chr6, chr7;
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
public Mapper047(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
if (nes.rom.GetPROM_CRC() == 0x7eef434c)
{
patch = 1;
}
for (INT i = 0; i < 8; i++)
{
reg[i] = 0;
}
bank = 0;
prg0 = 0;
prg1 = 1;
// set VROM banks
if (VROM_1K_SIZE != 0)
{
chr01 = 0;
chr23 = 2;
chr4 = 4;
chr5 = 5;
chr6 = 6;
chr7 = 7;
}
else
{
chr01 = chr23 = chr4 = chr5 = chr6 = chr7 = 0;
}
SetBank_CPU();
SetBank_PPU();
irq_enable = 0;
irq_counter = 0;
irq_latch = 0;
}
//void Mapper047::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr == 0x6000)
{
if (patch != 0)
{
bank = (byte)((data & 0x06) >> 1);
}
else
{
bank = (byte)((data & 0x01) << 1);
}
SetBank_CPU();
SetBank_PPU();
}
}
//void Mapper047::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xE001)
{
case 0x8000:
reg[0] = data;
SetBank_CPU();
SetBank_PPU();
break;
case 0x8001:
reg[1] = data;
switch (reg[0] & 0x07)
{
case 0x00:
chr01 = (byte)(data & 0xFE);
SetBank_PPU();
break;
case 0x01:
chr23 = (byte)(data & 0xFE);
SetBank_PPU();
break;
case 0x02:
chr4 = data;
SetBank_PPU();
break;
case 0x03:
chr5 = data;
SetBank_PPU();
break;
case 0x04:
chr6 = data;
SetBank_PPU();
break;
case 0x05:
chr7 = data;
SetBank_PPU();
break;
case 0x06:
prg0 = data;
SetBank_CPU();
break;
case 0x07:
prg1 = data;
SetBank_CPU();
break;
}
break;
case 0xA000:
reg[2] = data;
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
case 0xA001:
reg[3] = data;
break;
case 0xC000:
reg[4] = data;
irq_counter = data;
break;
case 0xC001:
reg[5] = data;
irq_latch = data;
break;
case 0xE000:
reg[6] = data;
irq_enable = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xE001:
reg[7] = data;
irq_enable = 1;
break;
}
}
//void Mapper047::HSync(INT scanline)
public override void HSync(int scanline)
{
if ((scanline >= 0 && scanline <= 239))
{
if (nes.ppu.IsDispON())
{
if (irq_enable != 0)
{
if ((--irq_counter) == 0)
{
irq_counter = irq_latch;
// nes.cpu.IRQ();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
}
void SetBank_CPU()
{
if ((reg[0] & 0x40) != 0)
{
SetPROM_8K_Bank(4, bank * 8 + ((patch != 0 && bank != 2) ? 6 : 14));
SetPROM_8K_Bank(5, bank * 8 + prg1);
SetPROM_8K_Bank(6, bank * 8 + prg0);
SetPROM_8K_Bank(7, bank * 8 + ((patch != 0 && bank != 2) ? 7 : 15));
}
else
{
SetPROM_8K_Bank(4, bank * 8 + prg0);
SetPROM_8K_Bank(5, bank * 8 + prg1);
SetPROM_8K_Bank(6, bank * 8 + ((patch != 0 && bank != 2) ? 6 : 14));
SetPROM_8K_Bank(7, bank * 8 + ((patch != 0 && bank != 2) ? 7 : 15));
}
}
void SetBank_PPU()
{
if (VROM_1K_SIZE != 0)
{
if ((reg[0] & 0x80) != 0)
{
SetVROM_1K_Bank(0, (bank & 0x02) * 64 + chr4);
SetVROM_1K_Bank(1, (bank & 0x02) * 64 + chr5);
SetVROM_1K_Bank(2, (bank & 0x02) * 64 + chr6);
SetVROM_1K_Bank(3, (bank & 0x02) * 64 + chr7);
SetVROM_1K_Bank(4, (bank & 0x02) * 64 + chr01 + 0);
SetVROM_1K_Bank(5, (bank & 0x02) * 64 + chr01 + 1);
SetVROM_1K_Bank(6, (bank & 0x02) * 64 + chr23 + 0);
SetVROM_1K_Bank(7, (bank & 0x02) * 64 + chr23 + 1);
}
else
{
SetVROM_1K_Bank(0, (bank & 0x02) * 64 + chr01 + 0);
SetVROM_1K_Bank(1, (bank & 0x02) * 64 + chr01 + 1);
SetVROM_1K_Bank(2, (bank & 0x02) * 64 + chr23 + 0);
SetVROM_1K_Bank(3, (bank & 0x02) * 64 + chr23 + 1);
SetVROM_1K_Bank(4, (bank & 0x02) * 64 + chr4);
SetVROM_1K_Bank(5, (bank & 0x02) * 64 + chr5);
SetVROM_1K_Bank(6, (bank & 0x02) * 64 + chr6);
SetVROM_1K_Bank(7, (bank & 0x02) * 64 + chr7);
}
}
}
//void Mapper047::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
for (INT i = 0; i < 8; i++)
{
p[i] = reg[i];
}
p[8] = prg0;
p[9] = prg1;
p[10] = chr01;
p[11] = chr23;
p[12] = chr4;
p[13] = chr5;
p[14] = chr6;
p[15] = chr7;
p[16] = irq_enable;
p[17] = irq_counter;
p[18] = irq_latch;
p[19] = bank;
}
//void Mapper047::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
for (INT i = 0; i < 8; i++)
{
reg[i] = p[i];
}
prg0 = p[8];
prg1 = p[9];
chr01 = p[10];
chr23 = p[11];
chr4 = p[12];
chr5 = p[13];
chr6 = p[14];
chr7 = p[15];
irq_enable = p[16];
irq_counter = p[17];
irq_latch = p[18];
bank = p[19];
}
}
}

View File

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

View File

@ -0,0 +1,143 @@
//////////////////////////////////////////////////////////////////////////
// Mapper048 Taito TC190V //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper048 : Mapper
{
BYTE reg;
BYTE irq_enable;
BYTE irq_counter;
public Mapper048(NES parent) : base(parent)
{
}
public override void Reset()
{
reg = 0;
irq_enable = 0;
irq_counter = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
SetVROM_8K_Bank(0);
uint crc = nes.rom.GetPROM_CRC();
// if( crc == 0x547e6cc1 ) { // Flintstones - The Rescue of Dino & Hoppy(J)
// nes.SetRenderMethod( NES::POST_RENDER );
// }
}
//void Mapper048::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr)
{
case 0x8000:
if (reg == 0)
{
if ((data & 0x40) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
SetPROM_8K_Bank(4, data);
break;
case 0x8001:
SetPROM_8K_Bank(5, data);
break;
case 0x8002:
SetVROM_2K_Bank(0, data);
break;
case 0x8003:
SetVROM_2K_Bank(2, data);
break;
case 0xA000:
SetVROM_1K_Bank(4, data);
break;
case 0xA001:
SetVROM_1K_Bank(5, data);
break;
case 0xA002:
SetVROM_1K_Bank(6, data);
break;
case 0xA003:
SetVROM_1K_Bank(7, data);
break;
case 0xC000:
irq_counter = data;
irq_enable = 0;
// nes.cpu.ClrIRQ( IRQ_MAPPER );
break;
case 0xC001:
irq_counter = data;
irq_enable = 1;
// irq_enable = data & 0x01;
// nes.cpu.ClrIRQ( IRQ_MAPPER );
break;
case 0xC002:
break;
case 0xC003:
break;
case 0xE000:
if ((data & 0x40) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
reg = 1;
break;
}
}
//void Mapper048::HSync(INT scanline)
public override void HSync(int scanline)
{
if ((scanline >= 0 && scanline <= 239))
{
if (nes.ppu.IsDispON())
{
if (irq_enable != 0)
{
if (irq_counter == 0xFF)
{
// nes.cpu.IRQ_NotPending();
// nes.cpu.SetIRQ( IRQ_MAPPER );
nes.cpu.SetIRQ(IRQ_TRIGGER2);
}
irq_counter++;
}
}
}
}
//void Mapper048::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg;
p[1] = irq_enable;
p[2] = irq_counter;
}
//void Mapper048::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg = p[0];
irq_enable = p[1];
irq_counter = p[2];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,100 @@
//////////////////////////////////////////////////////////////////////////
// Mapper050 SMB2J //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper050 : Mapper
{
BYTE irq_enable;
public Mapper050(NES parent) : base(parent)
{
}
public override void Reset()
{
irq_enable = 0;
SetPROM_8K_Bank(3, 15);
SetPROM_8K_Bank(4, 8);
SetPROM_8K_Bank(5, 9);
SetPROM_8K_Bank(6, 0);
SetPROM_8K_Bank(7, 11);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper050::ExWrite(WORD addr, BYTE data)
public override void ExWrite(ushort addr, byte data)
{
if ((addr & 0xE060) == 0x4020)
{
if ((addr & 0x0100) != 0)
{
irq_enable = (byte)(data & 0x01);
nes.cpu.ClrIRQ(IRQ_MAPPER);
}
else
{
SetPROM_8K_Bank(6, (data & 0x08) | ((data & 0x01) << 2) | ((data & 0x06) >> 1));
}
}
}
//void Mapper050::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if ((addr & 0xE060) == 0x4020)
{
if ((addr & 0x0100) != 0)
{
irq_enable = (byte)(data & 0x01);
nes.cpu.ClrIRQ(IRQ_MAPPER);
}
else
{
SetPROM_8K_Bank(6, (data & 0x08) | ((data & 0x01) << 2) | ((data & 0x06) >> 1));
}
}
}
//void Mapper050::HSync(INT scanline)
public override void HSync(int scanline)
{
if (irq_enable != 0)
{
if (scanline == 21)
{
// nes.cpu.IRQ();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
//void Mapper050::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = irq_enable;
}
//void Mapper050::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
irq_enable = p[0];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,109 @@
//////////////////////////////////////////////////////////////////////////
// Mapper051 11-in-1 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper051 : Mapper
{
int mode, bank;
public Mapper051(NES parent) : base(parent)
{
}
public override void Reset()
{
bank = 0;
mode = 1;
SetBank_CPU();
SetCRAM_8K_Bank(0);
}
//void Mapper051::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr >= 0x6000)
{
mode = ((data & 0x10) >> 3) | ((data & 0x02) >> 1);
SetBank_CPU();
}
}
//void Mapper051::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
bank = (data & 0x0f) << 2;
if (0xC000 <= addr && addr <= 0xDFFF)
{
mode = (mode & 0x01) | ((data & 0x10) >> 3);
}
SetBank_CPU();
}
void SetBank_CPU()
{
switch (mode)
{
case 0:
SetVRAM_Mirror(VRAM_VMIRROR);
SetPROM_8K_Bank(3, (bank | 0x2c | 3));
SetPROM_8K_Bank(4, (bank | 0x00 | 0));
SetPROM_8K_Bank(5, (bank | 0x00 | 1));
SetPROM_8K_Bank(6, (bank | 0x0c | 2));
SetPROM_8K_Bank(7, (bank | 0x0c | 3));
break;
case 1:
SetVRAM_Mirror(VRAM_VMIRROR);
SetPROM_8K_Bank(3, (bank | 0x20 | 3));
SetPROM_8K_Bank(4, (bank | 0x00 | 0));
SetPROM_8K_Bank(5, (bank | 0x00 | 1));
SetPROM_8K_Bank(6, (bank | 0x00 | 2));
SetPROM_8K_Bank(7, (bank | 0x00 | 3));
break;
case 2:
SetVRAM_Mirror(VRAM_VMIRROR);
SetPROM_8K_Bank(3, (bank | 0x2e | 3));
SetPROM_8K_Bank(4, (bank | 0x02 | 0));
SetPROM_8K_Bank(5, (bank | 0x02 | 1));
SetPROM_8K_Bank(6, (bank | 0x0e | 2));
SetPROM_8K_Bank(7, (bank | 0x0e | 3));
break;
case 3:
SetVRAM_Mirror(VRAM_HMIRROR);
SetPROM_8K_Bank(3, (bank | 0x20 | 3));
SetPROM_8K_Bank(4, (bank | 0x00 | 0));
SetPROM_8K_Bank(5, (bank | 0x00 | 1));
SetPROM_8K_Bank(6, (bank | 0x00 | 2));
SetPROM_8K_Bank(7, (bank | 0x00 | 3));
break;
}
}
//void Mapper051::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = (byte)mode;
p[1] = (byte)bank;
}
//void Mapper051::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
mode = p[0];
bank = p[1];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,87 @@
//////////////////////////////////////////////////////////////////////////
// Mapper057 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper057 : Mapper
{
BYTE reg;
public Mapper057(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, 0, 1);
SetVROM_8K_Bank(0);
reg = 0;
}
//void Mapper057::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr)
{
case 0x8000:
case 0x8001:
case 0x8002:
case 0x8003:
if ((data & 0x40) != 0)
{
SetVROM_8K_Bank((data & 0x03) + ((reg & 0x10) >> 1) + (reg & 0x07));
}
break;
case 0x8800:
reg = data;
if ((data & 0x80) != 0)
{
SetPROM_8K_Bank(4, ((data & 0x40) >> 6) * 4 + 8 + 0);
SetPROM_8K_Bank(5, ((data & 0x40) >> 6) * 4 + 8 + 1);
SetPROM_8K_Bank(6, ((data & 0x40) >> 6) * 4 + 8 + 2);
SetPROM_8K_Bank(7, ((data & 0x40) >> 6) * 4 + 8 + 3);
}
else
{
SetPROM_8K_Bank(4, ((data & 0x60) >> 5) * 2 + 0);
SetPROM_8K_Bank(5, ((data & 0x60) >> 5) * 2 + 1);
SetPROM_8K_Bank(6, ((data & 0x60) >> 5) * 2 + 0);
SetPROM_8K_Bank(7, ((data & 0x60) >> 5) * 2 + 1);
}
SetVROM_8K_Bank((data & 0x07) + ((data & 0x10) >> 1));
if ((data & 0x08) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
}
}
//void Mapper057::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg;
}
//void Mapper057::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: 4e308cd2cba2bd046b2174191bd85e40
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,53 @@
//////////////////////////////////////////////////////////////////////////
// Mapper058 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper058 : Mapper
{
public Mapper058(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, 0, 1);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper058::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
if ((addr & 0x40) != 0)
{
SetPROM_16K_Bank(4, addr & 0x07);
SetPROM_16K_Bank(6, addr & 0x07);
}
else
{
SetPROM_32K_Bank((addr & 0x06) >> 1);
}
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank((addr & 0x38) >> 3);
}
if ((data & 0x02) != 0) SetVRAM_Mirror(VRAM_VMIRROR);
else SetVRAM_Mirror(VRAM_HMIRROR);
}
}
}

View File

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

View File

@ -0,0 +1,66 @@
//////////////////////////////////////////////////////////////////////////
// Mapper060 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper060 : Mapper
{
BYTE patch;
BYTE game_sel;
public Mapper060(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0xf9c484a0)
{ // Reset Based 4-in-1(Unl)
SetPROM_16K_Bank(4, game_sel);
SetPROM_16K_Bank(6, game_sel);
SetVROM_8K_Bank(game_sel);
game_sel++;
game_sel &= 3;
}
else
{
patch = 1;
SetPROM_32K_Bank(0);
SetVROM_8K_Bank(0);
}
}
//void Mapper060::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
if (patch != 0)
{
if ((addr & 0x80) != 0)
{
SetPROM_16K_Bank(4, (addr & 0x70) >> 4);
SetPROM_16K_Bank(6, (addr & 0x70) >> 4);
}
else
{
SetPROM_32K_Bank((addr & 0x70) >> 5);
}
SetVROM_8K_Bank(addr & 0x07);
if ((data & 0x08) != 0) SetVRAM_Mirror(VRAM_VMIRROR);
else SetVRAM_Mirror(VRAM_HMIRROR);
}
}
}
}

View File

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

View File

@ -0,0 +1,47 @@
//////////////////////////////////////////////////////////////////////////
// Mapper061 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper061 : Mapper
{
public Mapper061(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
//void Mapper061::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0x30)
{
case 0x00:
case 0x30:
SetPROM_32K_Bank(addr & 0x0F);
break;
case 0x10:
case 0x20:
SetPROM_16K_Bank(4, ((addr & 0x0F) << 1) | ((addr & 0x20) >> 4));
SetPROM_16K_Bank(6, ((addr & 0x0F) << 1) | ((addr & 0x20) >> 4));
break;
}
if ((addr & 0x80) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
}
}

View File

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

View File

@ -0,0 +1,53 @@
//////////////////////////////////////////////////////////////////////////
// Mapper062 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper062 : Mapper
{
public Mapper062(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0);
SetVROM_8K_Bank(0);
}
//void Mapper062::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xFF00)
{
case 0x8100:
SetPROM_8K_Bank(4, data);
SetPROM_8K_Bank(5, data + 1);
break;
case 0x8500:
SetPROM_8K_Bank(4, data);
break;
case 0x8700:
SetPROM_8K_Bank(5, data);
break;
SetVROM_1K_Bank(0, data + 0);
SetVROM_1K_Bank(1, data + 1);
SetVROM_1K_Bank(2, data + 2);
SetVROM_1K_Bank(3, data + 3);
SetVROM_1K_Bank(4, data + 4);
SetVROM_1K_Bank(5, data + 5);
SetVROM_1K_Bank(6, data + 6);
SetVROM_1K_Bank(7, data + 7);
}
}
}
}

View File

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

View File

@ -0,0 +1,283 @@
//////////////////////////////////////////////////////////////////////////
// Mapper064 Tengen Rambo-1 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper064 : Mapper
{
BYTE[] reg = new byte[3];
BYTE irq_enable;
BYTE irq_mode;
INT irq_counter;
INT irq_counter2;
BYTE irq_latch;
BYTE irq_reset;
public Mapper064(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(PROM_8K_SIZE - 1, PROM_8K_SIZE - 1, PROM_8K_SIZE - 1, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
reg[0] = reg[1] = reg[2] = 0;
irq_enable = 0;
irq_mode = 0;
irq_counter = 0;
irq_counter2 = 0;
irq_latch = 0;
irq_reset = 0;
}
//void Mapper064::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
//DEBUGOUT( "$%04X:$%02X\n", addr, data );
switch (addr & 0xF003)
{
case 0x8000:
reg[0] = (byte)(data & 0x0F);
reg[1] = (byte)(data & 0x40);
reg[2] = (byte)(data & 0x80);
break;
case 0x8001:
switch (reg[0])
{
case 0x00:
if (reg[2] != 0)
{
SetVROM_1K_Bank(4, data + 0);
SetVROM_1K_Bank(5, data + 1);
}
else
{
SetVROM_1K_Bank(0, data + 0);
SetVROM_1K_Bank(1, data + 1);
}
break;
case 0x01:
if (reg[2] != 0)
{
SetVROM_1K_Bank(6, data + 0);
SetVROM_1K_Bank(7, data + 1);
}
else
{
SetVROM_1K_Bank(2, data + 0);
SetVROM_1K_Bank(3, data + 1);
}
break;
case 0x02:
if (reg[2] != 0)
{
SetVROM_1K_Bank(0, data);
}
else
{
SetVROM_1K_Bank(4, data);
}
break;
case 0x03:
if (reg[2] != 0)
{
SetVROM_1K_Bank(1, data);
}
else
{
SetVROM_1K_Bank(5, data);
}
break;
case 0x04:
if (reg[2] != 0)
{
SetVROM_1K_Bank(2, data);
}
else
{
SetVROM_1K_Bank(6, data);
}
break;
case 0x05:
if (reg[2] != 0)
{
SetVROM_1K_Bank(3, data);
}
else
{
SetVROM_1K_Bank(7, data);
}
break;
case 0x06:
if (reg[1] != 0)
{
SetPROM_8K_Bank(5, data);
}
else
{
SetPROM_8K_Bank(4, data);
}
break;
case 0x07:
if (reg[1] != 0)
{
SetPROM_8K_Bank(6, data);
}
else
{
SetPROM_8K_Bank(5, data);
}
break;
case 0x08:
SetVROM_1K_Bank(1, data);
break;
case 0x09:
SetVROM_1K_Bank(3, data);
break;
case 0x0F:
if (reg[1] != 0)
{
SetPROM_8K_Bank(4, data);
}
else
{
SetPROM_8K_Bank(6, data);
}
break;
}
break;
case 0xA000:
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
case 0xC000:
irq_latch = data;
if (irq_reset != 0)
{
irq_counter = irq_latch;
}
break;
case 0xC001:
irq_reset = 0xFF;
irq_counter = irq_latch;
irq_mode = (byte)(data & 0x01);
break;
case 0xE000:
irq_enable = 0;
if (irq_reset != 0)
{
irq_counter = irq_latch;
}
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xE001:
irq_enable = 0xFF;
if (irq_reset != 0)
{
irq_counter = irq_latch;
}
break;
}
}
//void Mapper064::Clock(INT cycles)
public override void Clock(int cycles)
{
if (irq_mode == 0)
return;
irq_counter2 += cycles;
while (irq_counter2 >= 4)
{
irq_counter2 -= 4;
if (irq_counter >= 0)
{
irq_counter--;
if (irq_counter < 0)
{
if (irq_enable != 0)
{
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
}
//void Mapper064::HSync(INT scanline)
public override void HSync(int scanline)
{
if (irq_mode != 0)
return;
irq_reset = 0;
if ((scanline >= 0 && scanline <= 239))
{
if (nes.ppu.IsDispON())
{
if (irq_counter >= 0)
{
irq_counter--;
if (irq_counter < 0)
{
if (irq_enable != 0)
{
irq_reset = 1;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
}
}
//void Mapper064::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;
//p[4] = irq_mode;
//p[5] = irq_latch;
//p[6] = irq_reset;
//*((INT*)&p[8]) = irq_counter;
//*((INT*)&p[12]) = irq_counter2;
}
//void Mapper064::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_mode = p[4];
//irq_latch = p[5];
//irq_reset = p[6];
//irq_counter = *((INT*)&p[8]);
//irq_counter2 = *((INT*)&p[12]);
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,189 @@
//////////////////////////////////////////////////////////////////////////
// Mapper065 Irem H3001 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper065 : Mapper
{
BYTE patch;
BYTE irq_enable;
INT irq_counter;
INT irq_latch;
public Mapper065(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
// Kaiketsu Yanchamaru 3(J)
if (nes.rom.GetPROM_CRC() == 0xe30b7f64)
{
patch = 1;
}
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
irq_enable = 0;
irq_counter = 0;
}
//void Mapper065::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:
if (patch == 0)
{
if ((data & 0x40) != 0) SetVRAM_Mirror(VRAM_VMIRROR);
else SetVRAM_Mirror(VRAM_HMIRROR);
}
break;
case 0x9001:
if (patch != 0)
{
if ((data & 0x80) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
break;
case 0x9003:
if (patch == 0)
{
irq_enable = (byte)(data & 0x8);
nes.cpu.ClrIRQ(IRQ_MAPPER);
}
break;
case 0x9004:
if (patch == 0)
{
irq_counter = irq_latch;
}
break;
case 0x9005:
if (patch != 0)
{
irq_counter = (BYTE)(data << 1);
irq_enable = data;
nes.cpu.ClrIRQ(IRQ_MAPPER);
}
else
{
irq_latch = (irq_latch & 0x00FF) | ((INT)data << 8);
}
break;
case 0x9006:
if (patch != 0)
{
irq_enable = 1;
}
else
{
irq_latch = (irq_latch & 0xFF00) | data;
}
break;
case 0xB000:
case 0xB001:
case 0xB002:
case 0xB003:
case 0xB004:
case 0xB005:
case 0xB006:
case 0xB007:
SetVROM_1K_Bank((byte)(addr & 0x0007), data);
break;
case 0xA000:
SetPROM_8K_Bank(5, data);
break;
case 0xC000:
SetPROM_8K_Bank(6, data);
break;
}
}
//void Mapper065::HSync(INT scanline)
public override void HSync(int scanline)
{
if (patch != 0)
{
if (irq_enable != 0)
{
if (irq_counter == 0)
{
// nes.cpu.IRQ_NotPending();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
else
{
irq_counter--;
}
}
}
}
//void Mapper065::Clock(INT cycles)
public override void Clock(int cycles)
{
if (patch == 0)
{
if (irq_enable != 0)
{
if (irq_counter <= 0)
{
// nes.cpu.IRQ_NotPending();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
else
{
irq_counter -= cycles;
}
}
}
}
//void Mapper065::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//*(INT*)&p[1] = irq_counter;
//*(INT*)&p[5] = irq_latch;
}
//void Mapper065::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//irq_enable = p[0];
//irq_counter = *(INT*)&p[1];
//irq_latch = *(INT*)&p[5];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,48 @@
//////////////////////////////////////////////////////////////////////////
// Mapper066 Bandai 74161 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper066 : Mapper
{
public Mapper066(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
SetVROM_8K_Bank(0);
// if( nes->rom->GetPROM_CRC() == 0xe30552db ) { // Paris-Dakar Rally Special
// nes->SetFrameIRQmode( FALSE );
// }
}
//void Mapper066::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr >= 0x6000)
{
SetPROM_32K_Bank((data & 0xF0) >> 4);
SetVROM_8K_Bank(data & 0x0F);
}
}
//void Mapper066::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
SetPROM_32K_Bank((data & 0xF0) >> 4);
SetVROM_8K_Bank(data & 0x0F);
}
}
}

View File

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

View File

@ -0,0 +1,140 @@
//////////////////////////////////////////////////////////////////////////
// Mapper067 SunSoft Mapper 3 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper067 : Mapper
{
BYTE irq_enable;
BYTE irq_occur;
BYTE irq_toggle;
INT irq_counter;
public Mapper067(NES parent) : base(parent)
{
}
public override void Reset()
{
irq_enable = 0;
irq_toggle = 0;
irq_counter = 0;
irq_occur = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
SetVROM_4K_Bank(0, 0);
SetVROM_4K_Bank(4, VROM_4K_SIZE - 1);
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x7f2a04bf)
{ // For Fantasy Zone 2(J)
nes.SetRenderMethod(EnumRenderMethod.PRE_ALL_RENDER);
}
}
//void Mapper067::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF800)
{
case 0x8800:
SetVROM_2K_Bank(0, data);
break;
case 0x9800:
SetVROM_2K_Bank(2, data);
break;
case 0xA800:
SetVROM_2K_Bank(4, data);
break;
case 0xB800:
SetVROM_2K_Bank(6, data);
break;
case 0xC800:
if (irq_toggle == 0)
{
irq_counter = (irq_counter & 0x00FF) | ((INT)data << 8);
}
else
{
irq_counter = (irq_counter & 0xFF00) | ((INT)data & 0xFF);
}
irq_toggle ^= 1;
irq_occur = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xD800:
irq_enable = (byte)(data & 0x10);
irq_toggle = 0;
irq_occur = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xE800:
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 0xF800:
SetPROM_16K_Bank(4, data);
break;
}
}
//void Mapper067::Clock(INT cycles)
public override void Clock(int cycles)
{
if (irq_enable != 0)
{
if ((irq_counter -= cycles) <= 0)
{
irq_enable = 0;
irq_occur = 0xFF;
irq_counter = 0xFFFF;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
// if( irq_occur ) {
// nes.cpu.IRQ_NotPending();
// }
}
//void Mapper067::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//p[1] = irq_occur;
//p[2] = irq_toggle;
//*((INT*)&p[3]) = irq_counter;
}
//void Mapper067::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//irq_enable = p[0];
//irq_occur = p[1];
//irq_toggle = p[2];
//irq_counter = *((INT*)&p[3]);
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,164 @@
//////////////////////////////////////////////////////////////////////////
// Mapper068 SunSoft Mapper 4 (After Burner II) //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper068 : Mapper
{
BYTE[] reg = new byte[4];
BYTE coin;
public Mapper068(NES parent) : base(parent)
{
}
public override void Reset()
{
reg[0] = reg[1] = reg[2] = reg[3] = 0;
coin = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
#if FALSE //0
BYTE Mapper068::ExRead( WORD addr )
{
if( addr == 0x4020 ) {
DEBUGOUT( "RD $4020:%02X\n", coin );
return coin;
}
return addr>>8;
}
void Mapper068::ExWrite( WORD addr, BYTE data )
{
if( addr == 0x4020 ) {
DEBUGOUT( "WR $4020:%02X\n", data );
coin = data;
}
}
#endif
//void Mapper068::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF000)
{
case 0x8000:
SetVROM_2K_Bank(0, data);
break;
case 0x9000:
SetVROM_2K_Bank(2, data);
break;
case 0xA000:
SetVROM_2K_Bank(4, data);
break;
case 0xB000:
SetVROM_2K_Bank(6, data);
break;
case 0xC000:
reg[2] = data;
SetBank();
break;
case 0xD000:
reg[3] = data;
SetBank();
break;
case 0xE000:
reg[0] = (byte)((data & 0x10) >> 4);
reg[1] = (byte)(data & 0x03);
SetBank();
break;
case 0xF000:
SetPROM_16K_Bank(4, data);
break;
}
}
void SetBank()
{
if (reg[0] != 0)
{
switch (reg[1])
{
case 0:
SetVROM_1K_Bank(8, (INT)reg[2] + 0x80);
SetVROM_1K_Bank(9, (INT)reg[3] + 0x80);
SetVROM_1K_Bank(10, (INT)reg[2] + 0x80);
SetVROM_1K_Bank(11, (INT)reg[3] + 0x80);
break;
case 1:
SetVROM_1K_Bank(8, (INT)reg[2] + 0x80);
SetVROM_1K_Bank(9, (INT)reg[2] + 0x80);
SetVROM_1K_Bank(10, (INT)reg[3] + 0x80);
SetVROM_1K_Bank(11, (INT)reg[3] + 0x80);
break;
case 2:
SetVROM_1K_Bank(8, (INT)reg[2] + 0x80);
SetVROM_1K_Bank(9, (INT)reg[2] + 0x80);
SetVROM_1K_Bank(10, (INT)reg[2] + 0x80);
SetVROM_1K_Bank(11, (INT)reg[2] + 0x80);
break;
case 3:
SetVROM_1K_Bank(8, (INT)reg[3] + 0x80);
SetVROM_1K_Bank(9, (INT)reg[3] + 0x80);
SetVROM_1K_Bank(10, (INT)reg[3] + 0x80);
SetVROM_1K_Bank(11, (INT)reg[3] + 0x80);
break;
}
}
else
{
switch (reg[1])
{
case 0:
SetVRAM_Mirror(VRAM_VMIRROR);
break;
case 1:
SetVRAM_Mirror(VRAM_HMIRROR);
break;
case 2:
SetVRAM_Mirror(VRAM_MIRROR4L);
break;
case 3:
SetVRAM_Mirror(VRAM_MIRROR4H);
break;
}
}
}
//void Mapper068::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg[0];
p[1] = reg[1];
p[2] = reg[2];
p[3] = reg[3];
}
//void Mapper068::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg[0] = p[0];
reg[1] = p[1];
reg[2] = p[2];
reg[3] = p[3];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,177 @@
//////////////////////////////////////////////////////////////////////////
// Mapper069 SunSoft FME-7 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper069 : Mapper
{
BYTE patch;
BYTE reg;
BYTE irq_enable;
INT irq_counter;
public Mapper069(NES parent) : base(parent)
{
}
public override void Reset()
{
reg = 0;
irq_enable = 0;
irq_counter = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
nes.apu.SelectExSound(32);
nes.SetIrqType(NES.IRQMETHOD.IRQ_CLOCK);
patch = 0;
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0xfeac6916)
{ // Honoo no Toukyuuji - Dodge Danpei 2(J)
// nes.SetIrqType( NES::IRQ_HSYNC );
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
}
if (crc == 0xad28aef6)
{ // Dynamite Batman(J) / Dynamite Batman - Return of the Joker(U)
patch = 1;
}
}
//void Mapper069::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xE000)
{
case 0x8000:
reg = data;
break;
case 0xA000:
switch (reg & 0x0F)
{
case 0x00:
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
SetVROM_1K_Bank((byte)(reg & 0x07), data);
break;
case 0x08:
if (patch == 0 && (data & 0x40) == 0)
{
SetPROM_8K_Bank(3, data);
}
break;
case 0x09:
SetPROM_8K_Bank(4, data);
break;
case 0x0A:
SetPROM_8K_Bank(5, data);
break;
case 0x0B:
SetPROM_8K_Bank(6, data);
break;
case 0x0C:
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 0x0D:
irq_enable = data;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0x0E:
irq_counter = (irq_counter & 0xFF00) | data;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0x0F:
irq_counter = (irq_counter & 0x00FF) | (data << 8);
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
break;
case 0xC000:
case 0xE000:
nes.apu.ExWrite(addr, data);
break;
}
}
//void Mapper069::Clock(INT cycles)
public override void Clock(int cycles)
{
//if (irq_enable && (nes.GetIrqType() == NES::IRQ_CLOCK))
if (irq_enable != 0 && (nes.GetIrqType() == (int)NES.IRQMETHOD.IRQ_HSYNC))
{
irq_counter -= cycles;
if (irq_counter <= 0)
{
nes.cpu.SetIRQ(IRQ_MAPPER);
irq_enable = 0;
irq_counter = 0xFFFF;
}
}
}
//void Mapper069::HSync(INT scanline)
public override void HSync(int scanline)
{
if (irq_enable != 0 && (nes.GetIrqType() == (int)NES.IRQMETHOD.IRQ_HSYNC))
{
irq_counter -= 114;
if (irq_counter <= 0)
{
nes.cpu.SetIRQ(IRQ_MAPPER);
irq_enable = 0;
irq_counter = 0xFFFF;
}
}
}
//void Mapper069::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = reg;
//p[1] = irq_enable;
//*(INT*)&p[2] = irq_counter;
}
//void Mapper069::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//reg = p[0];
//irq_enable = p[1];
//irq_counter = *(INT*)&p[2];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,64 @@
//////////////////////////////////////////////////////////////////////////
// Mapper070 Bandai 74161 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper070 : Mapper
{
BYTE patch;
public Mapper070(NES parent) : base(parent)
{
}
public override void Reset()
{
patch = 0;
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0xa59ca2ef)
{ // Kamen Rider Club(J)
patch = 1;
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
}
if (crc == 0x10bb8f9a)
{ // Family Trainer - Manhattan Police(J)
patch = 1;
}
if (crc == 0x0cd00488)
{ // Space Shadow(J)
patch = 1;
}
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
SetVROM_8K_Bank(0);
}
//void Mapper070::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
SetPROM_16K_Bank(4, (data & 0x70) >> 4);
SetVROM_8K_Bank(data & 0x0F);
if (patch != 0)
{
if ((data & 0x80) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
else
{
if ((data & 0x80) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
}
}
}
}

View File

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

View File

@ -0,0 +1,54 @@
//////////////////////////////////////////////////////////////////////////
// Mapper071 Camerica //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper071 : Mapper
{
public Mapper071(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
//void Mapper071::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if ((addr & 0xE000) == 0x6000)
{
SetPROM_16K_Bank(4, data);
}
}
//void Mapper071::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF000)
{
case 0x9000:
if ((data & 0x10) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
break;
case 0xC000:
case 0xD000:
case 0xE000:
case 0xF000:
SetPROM_16K_Bank(4, data);
break;
}
}
}
}

View File

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

View File

@ -0,0 +1,59 @@
//////////////////////////////////////////////////////////////////////////
// Mapper072 Jaleco/Type1 lower bank switch //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper072 : Mapper
{
public Mapper072(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper072::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
if (data & 0x80)
{
SetPROM_16K_Bank(4, data & 0x0F);
}
else if (data & 0x40)
{
SetVROM_8K_Bank(data & 0x0F);
}
else
{
if (addr >= 0xC100 && addr <= 0xC11F && data == 0x20)
{
//DEBUGOUT( "ADDR:%04X DATA:%02X\n", addr, data );
DEBUGOUT("SOUND CODE:%02X\n", addr & 0x1F);
// OSDにするべきか…
if (Config.sound.bExtraSoundEnable)
{
DirectSound.EsfAllStop();
DirectSound.EsfPlay(ESF_MOETENNIS_00 + (addr & 0x1F));
}
}
}
}
}
}

View File

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

View File

@ -0,0 +1,94 @@
//////////////////////////////////////////////////////////////////////////
// Mapper073 Konami VRC3 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper073 : Mapper
{
BYTE irq_enable;
INT irq_counter;
public Mapper073(NES parent) : base(parent)
{
}
public override void Reset()
{
irq_enable = 0;
irq_counter = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
//void Mapper073::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr)
{
case 0xF000:
SetPROM_16K_Bank(4, data);
break;
case 0x8000:
irq_counter = (irq_counter & 0xFFF0) | (data & 0x0F);
break;
case 0x9000:
irq_counter = (irq_counter & 0xFF0F) | ((data & 0x0F) << 4);
break;
case 0xA000:
irq_counter = (irq_counter & 0xF0FF) | ((data & 0x0F) << 8);
break;
case 0xB000:
irq_counter = (irq_counter & 0x0FFF) | ((data & 0x0F) << 12);
break;
case 0xC000:
irq_enable = (byte)(data & 0x02);
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xD000:
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
}
//void Mapper073::Clock(INT cycles)
public override void Clock(int cycles)
{
if (irq_enable != 0)
{
if ((irq_counter += cycles) >= 0xFFFF)
{
irq_enable = 0;
irq_counter &= 0xFFFF;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
//void Mapper073::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//*(INT*)&p[1] = irq_counter;
}
//void Mapper073::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//irq_enable = p[0];
//irq_counter = *(INT*)&p[1];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,312 @@
//////////////////////////////////////////////////////////////////////////
// Mapper074 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper074 : Mapper
{
BYTE[] reg = new byte[8];
BYTE prg0, prg1;
BYTE chr01, chr23, chr4, chr5, chr6, chr7;
BYTE we_sram;
BYTE irq_type;
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
BYTE irq_request;
BYTE patch;
public Mapper074(NES parent) : base(parent)
{
}
public override void Reset()
{
for (INT i = 0; i < 8; i++)
{
reg[i] = 0x00;
}
prg0 = 0;
prg1 = 1;
SetBank_CPU();
chr01 = 0;
chr23 = 2;
chr4 = 4;
chr5 = 5;
chr6 = 6;
chr7 = 7;
SetBank_PPU();
we_sram = 0; // Disable
irq_enable = 0; // Disable
irq_counter = 0;
irq_latch = 0;
irq_request = 0;
uint crc = nes.rom.GetPROM_CRC();
patch = 0;
if (crc == 0x37ae04a8)
{
patch = 1;
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
}
}
//void Mapper074::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 & 0xE001)
{
case 0x8000:
reg[0] = data;
SetBank_CPU();
SetBank_PPU();
break;
case 0x8001:
reg[1] = data;
switch (reg[0] & 0x07)
{
case 0x00:
chr01 = (byte)(data & 0xFE);
SetBank_PPU();
break;
case 0x01:
chr23 = (byte)(data & 0xFE);
SetBank_PPU();
break;
case 0x02:
chr4 = data;
SetBank_PPU();
break;
case 0x03:
chr5 = data;
SetBank_PPU();
break;
case 0x04:
chr6 = data;
SetBank_PPU();
break;
case 0x05:
chr7 = data;
SetBank_PPU();
break;
case 0x06:
prg0 = data;
SetBank_CPU();
break;
case 0x07:
prg1 = data;
SetBank_CPU();
break;
}
break;
case 0xA000:
reg[2] = data;
if (!nes.rom.Is4SCREEN())
{
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
break;
case 0xA001:
reg[3] = data;
break;
case 0xC000:
reg[4] = data;
irq_counter = data;
irq_request = 0;
break;
case 0xC001:
reg[5] = data;
irq_latch = data;
irq_request = 0;
break;
case 0xE000:
reg[6] = data;
irq_enable = 0;
irq_request = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xE001:
reg[7] = data;
irq_enable = 1;
irq_request = 0;
break;
}
}
//void Mapper074::HSync(INT scanline)
public override void HSync(int scanline)
{
if ((scanline >= 0 && scanline <= 239))
{
if (nes.ppu.IsDispON())
{
if (irq_enable != 0 && irq_request == 0)
{
if (scanline == 0)
{
if (irq_counter != 0)
{
irq_counter--;
}
}
if ((irq_counter--) == 0)
{
irq_request = 0xFF;
irq_counter = irq_latch;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
}
void SetBank_CPU()
{
if ((reg[0] & 0x40) != 0)
{
SetPROM_32K_Bank(PROM_8K_SIZE - 2, prg1, prg0, PROM_8K_SIZE - 1);
}
else
{
SetPROM_32K_Bank(prg0, prg1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
}
void SetBank_PPU()
{
if (VROM_1K_SIZE != 0)
{
if ((reg[0] & 0x80) != 0)
{
// SetVROM_8K_Bank( chr4, chr5, chr6, chr7,
// chr01, chr01+1, chr23, chr23+1 );
SetBank_PPUSUB(4, chr01 + 0);
SetBank_PPUSUB(5, chr01 + 1);
SetBank_PPUSUB(6, chr23 + 0);
SetBank_PPUSUB(7, chr23 + 1);
SetBank_PPUSUB(0, chr4);
SetBank_PPUSUB(1, chr5);
SetBank_PPUSUB(2, chr6);
SetBank_PPUSUB(3, chr7);
}
else
{
// SetVROM_8K_Bank( chr01, chr01+1, chr23, chr23+1,
// chr4, chr5, chr6, chr7 );
SetBank_PPUSUB(0, chr01 + 0);
SetBank_PPUSUB(1, chr01 + 1);
SetBank_PPUSUB(2, chr23 + 0);
SetBank_PPUSUB(3, chr23 + 1);
SetBank_PPUSUB(4, chr4);
SetBank_PPUSUB(5, chr5);
SetBank_PPUSUB(6, chr6);
SetBank_PPUSUB(7, chr7);
}
}
else
{
if ((reg[0] & 0x80) != 0)
{
SetCRAM_1K_Bank(4, (chr01 + 0) & 0x07);
SetCRAM_1K_Bank(5, (chr01 + 1) & 0x07);
SetCRAM_1K_Bank(6, (chr23 + 0) & 0x07);
SetCRAM_1K_Bank(7, (chr23 + 1) & 0x07);
SetCRAM_1K_Bank(0, chr4 & 0x07);
SetCRAM_1K_Bank(1, chr5 & 0x07);
SetCRAM_1K_Bank(2, chr6 & 0x07);
SetCRAM_1K_Bank(3, chr7 & 0x07);
}
else
{
SetCRAM_1K_Bank(0, (chr01 + 0) & 0x07);
SetCRAM_1K_Bank(1, (chr01 + 1) & 0x07);
SetCRAM_1K_Bank(2, (chr23 + 0) & 0x07);
SetCRAM_1K_Bank(3, (chr23 + 1) & 0x07);
SetCRAM_1K_Bank(4, chr4 & 0x07);
SetCRAM_1K_Bank(5, chr5 & 0x07);
SetCRAM_1K_Bank(6, chr6 & 0x07);
SetCRAM_1K_Bank(7, chr7 & 0x07);
}
}
}
void SetBank_PPUSUB(int bank, int page)
{
if (patch == 0 && (page == 8 || page == 9))
{
SetCRAM_1K_Bank((byte)bank, page & 7);
}
else if (patch == 1 && page >= 128)
{
SetCRAM_1K_Bank((byte)bank, page & 7);
}
else
{
SetVROM_1K_Bank((byte)bank, page);
}
}
//void Mapper074::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
for (INT i = 0; i < 8; i++)
{
p[i] = reg[i];
}
p[8] = prg0;
p[9] = prg1;
p[10] = chr01;
p[11] = chr23;
p[12] = chr4;
p[13] = chr5;
p[14] = chr6;
p[15] = chr7;
p[16] = irq_enable;
p[17] = irq_counter;
p[18] = irq_latch;
p[19] = irq_request;
}
//void Mapper074::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
for (INT i = 0; i < 8; i++)
{
reg[i] = p[i];
}
prg0 = p[8];
prg1 = p[9];
chr01 = p[10];
chr23 = p[11];
chr4 = p[12];
chr5 = p[13];
chr6 = p[14];
chr7 = p[15];
irq_enable = p[16];
irq_counter = p[17];
irq_latch = p[18];
irq_request = p[19];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,90 @@
//////////////////////////////////////////////////////////////////////////
// Mapper075 Konami VRC1/Jaleco D65005 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper075 : Mapper
{
BYTE[] reg = new byte[2];
public Mapper075(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
reg[0] = 0;
reg[1] = 1;
}
//void Mapper075::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF000)
{
case 0x8000:
SetPROM_8K_Bank(4, data);
break;
case 0x9000:
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
reg[0] = (byte)((reg[0] & 0x0F) | ((data & 0x02) << 3));
reg[1] = (byte)((reg[1] & 0x0F) | ((data & 0x04) << 2));
SetVROM_4K_Bank(0, reg[0]);
SetVROM_4K_Bank(4, reg[1]);
break;
case 0xA000:
SetPROM_8K_Bank(5, data);
break;
case 0xC000:
SetPROM_8K_Bank(6, data);
break;
case 0xE000:
reg[0] = (byte)((reg[0] & 0x10) | (data & 0x0F));
SetVROM_4K_Bank(0, reg[0]);
break;
case 0xF000:
reg[1] = (byte)((reg[1] & 0x10) | (data & 0x0F));
SetVROM_4K_Bank(4, reg[1]);
break;
}
}
//void Mapper075::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg[0];
p[1] = reg[1];
}
//void Mapper075::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: a9e28ba92f769664690091c1434038a6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,82 @@
//////////////////////////////////////////////////////////////////////////
// Mapper076 Namcot 109 (女神転生) //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper076 : Mapper
{
BYTE reg;
public Mapper076(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 >= 8)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper076::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr)
{
case 0x8000:
reg = data;
break;
case 0x8001:
switch (reg & 0x07)
{
case 2:
SetVROM_2K_Bank(0, data);
break;
case 3:
SetVROM_2K_Bank(2, data);
break;
case 4:
SetVROM_2K_Bank(4, data);
break;
case 5:
SetVROM_2K_Bank(6, data);
break;
case 6:
SetPROM_8K_Bank(4, data);
break;
case 7:
SetPROM_8K_Bank(5, data);
break;
}
break;
}
}
//void Mapper076::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg;
}
//void Mapper076::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: 672c100cc4c4c70448bb51f3a9b62d5b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,39 @@
//////////////////////////////////////////////////////////////////////////
// Mapper077 Irem Early Mapper #0 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper077 : Mapper
{
public Mapper077(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0);
SetVROM_2K_Bank(0, 0);
SetCRAM_2K_Bank(2, 1);
SetCRAM_2K_Bank(4, 2);
SetCRAM_2K_Bank(6, 3);
}
//void Mapper077::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
SetPROM_32K_Bank(data & 0x07);
SetVROM_2K_Bank(0, (data & 0xF0) >> 4);
}
}
}

View File

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

View File

@ -0,0 +1,45 @@
//////////////////////////////////////////////////////////////////////////
// Mapper078 Jaleco(Cosmo Carrier) //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper078 : Mapper
{
public Mapper078(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper078::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
//DEBUGOUT( "MAP78 WR $%04X=$%02X L=%d\n", addr, data, nes->GetScanline() );
SetPROM_16K_Bank(4, data & 0x0F);
SetVROM_8K_Bank((data & 0xF0) >> 4);
if ((addr & 0xFE00) != 0xFE00)
{
if ((data & 0x08) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
}
}
}
}

View File

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

View File

@ -0,0 +1,41 @@
//////////////////////////////////////////////////////////////////////////
// Mapper079 Nina-3 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper079 : Mapper
{
public Mapper079(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0);
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper079::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if ((addr & 0x0100) != 0)
{
SetPROM_32K_Bank((data >> 3) & 0x01);
SetVROM_8K_Bank(data & 0x07);
}
}
}
}

View File

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

View File

@ -0,0 +1,106 @@
//////////////////////////////////////////////////////////////////////////
// Mapper080 Taito X1-005 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper080 : Mapper
{
public Mapper080(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper080::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
switch (addr)
{
case 0x7EF0:
SetVROM_2K_Bank(0, (data >> 1) & 0x3F);
if (PROM_8K_SIZE == 32)
{
if ((data & 0x80) != 0)
{
SetVRAM_1K_Bank(8, 1);
SetVRAM_1K_Bank(9, 1);
}
else
{
SetVRAM_1K_Bank(8, 0);
SetVRAM_1K_Bank(9, 0);
}
}
break;
case 0x7EF1:
SetVROM_2K_Bank(2, (data >> 1) & 0x3F);
if (PROM_8K_SIZE == 32)
{
if ((data & 0x80) != 0)
{
SetVRAM_1K_Bank(10, 1);
SetVRAM_1K_Bank(11, 1);
}
else
{
SetVRAM_1K_Bank(10, 0);
SetVRAM_1K_Bank(11, 0);
}
}
break;
case 0x7EF2:
SetVROM_1K_Bank(4, data);
break;
case 0x7EF3:
SetVROM_1K_Bank(5, data);
break;
case 0x7EF4:
SetVROM_1K_Bank(6, data);
break;
case 0x7EF5:
SetVROM_1K_Bank(7, data);
break;
case 0x7EF6:
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_VMIRROR);
else SetVRAM_Mirror(VRAM_HMIRROR);
break;
case 0x7EFA:
case 0x7EFB:
SetPROM_8K_Bank(4, data);
break;
case 0x7EFC:
case 0x7EFD:
SetPROM_8K_Bank(5, data);
break;
case 0x7EFE:
case 0x7EFF:
SetPROM_8K_Bank(6, data);
break;
default:
base.WriteLow(addr, data);
break;
}
}
}
}

View File

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

View File

@ -0,0 +1,119 @@
//////////////////////////////////////////////////////////////////////////
// Mapper082 Taito C075 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper082 : Mapper
{
BYTE reg;
public Mapper082(NES parent) : base(parent)
{
}
public override void Reset()
{
reg = 0;
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE!=0)
{
SetVROM_8K_Bank(0);
}
SetVRAM_Mirror(VRAM_VMIRROR);
}
//void Mapper082::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
switch (addr)
{
case 0x7EF0:
if (reg!=0)
{
SetVROM_2K_Bank(4, data >> 1);
}
else
{
SetVROM_2K_Bank(0, data >> 1);
}
break;
case 0x7EF1:
if (reg!=0)
{
SetVROM_2K_Bank(6, data >> 1);
}
else
{
SetVROM_2K_Bank(2, data >> 1);
}
break;
case 0x7EF2:
if (reg!=0) SetVROM_1K_Bank(0, data);
else SetVROM_1K_Bank(4, data);
break;
case 0x7EF3:
if (reg!=0) SetVROM_1K_Bank(1, data);
else SetVROM_1K_Bank(5, data);
break;
case 0x7EF4:
if (reg!=0) SetVROM_1K_Bank(2, data);
else SetVROM_1K_Bank(6, data);
break;
case 0x7EF5:
if (reg!=0) SetVROM_1K_Bank(3, data);
else SetVROM_1K_Bank(7, data);
break;
case 0x7EF6:
reg = (byte)(data & 0x02);
if ((data & 0x01)!=0) SetVRAM_Mirror(VRAM_VMIRROR);
else SetVRAM_Mirror(VRAM_HMIRROR);
break;
case 0x7EFA:
SetPROM_8K_Bank(4, data >> 2);
break;
case 0x7EFB:
SetPROM_8K_Bank(5, data >> 2);
break;
case 0x7EFC:
SetPROM_8K_Bank(6, data >> 2);
break;
default:
base.WriteLow(addr, data);
break;
}
}
//void Mapper082::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg;
}
//void Mapper082::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: 826a6bd0c5ff43b4e907171f2a901343
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,243 @@
/////////////////////////////
// Mapper083 Cony //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper083 : Mapper
{
BYTE[] reg = new byte[3];
INT chr_bank;
BYTE irq_enable;
INT irq_counter;
BYTE patch;
public Mapper083(NES parent) : base(parent)
{
}
public override void Reset()
{
for (INT i = 0; i < 3; i++)
{
reg[i] = 0x00;
}
if (PROM_8K_SIZE >= 32)
{
SetPROM_32K_Bank(0, 1, 30, 31);
reg[1] = 0x30;
}
else
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
chr_bank = 0;
irq_enable = 0; // Disable
irq_counter = 0;
patch = 0;
if (nes.rom.GetPROM_CRC() == 0x1461D1F8)
{
patch = 1;
}
}
//BYTE Mapper083::ReadLow(WORD addr)
public override byte ReadLow(ushort addr)
{
if ((addr & 0x5100) == 0x5100)
{
return reg[2];
}
else if (addr >= 0x6000)
{
return base.ReadLow(addr);
}
return (BYTE)(addr >> 8);
}
//void Mapper083::WriteLow(WORD addr, BYTE data)
public override void WriteLow(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)
{
case 0x5101:
case 0x5102:
case 0x5103:
reg[2] = data;
break;
}
if (addr >= 0x6000)
{
base.WriteLow(addr, data);
}
}
//void Mapper083::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)
{
case 0x8000:
case 0xB000:
case 0xB0FF:
case 0xB1FF:
reg[0] = data;
chr_bank = (data & 0x30) << 4;
SetPROM_16K_Bank(4, data);
SetPROM_16K_Bank(6, (data & 0x30) | 0x0F);
break;
case 0x8100:
reg[1] = (byte)(data & 0x80);
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 0x8200:
irq_counter = (irq_counter & 0xFF00) | (INT)data;
// nes.cpu.ClrIRQ( IRQ_MAPPER );
break;
case 0x8201:
irq_counter = (irq_counter & 0x00FF) | ((INT)data << 8);
irq_enable = reg[1];
// nes.cpu.ClrIRQ( IRQ_MAPPER );
break;
case 0x8300:
SetPROM_8K_Bank(4, data);
break;
case 0x8301:
SetPROM_8K_Bank(5, data);
break;
case 0x8302:
SetPROM_8K_Bank(6, data);
break;
case 0x8310:
if (patch != 0)
{
SetVROM_2K_Bank(0, chr_bank | data);
}
else
{
SetVROM_1K_Bank(0, chr_bank | data);
}
break;
case 0x8311:
if (patch != 0)
{
SetVROM_2K_Bank(2, chr_bank | data);
}
else
{
SetVROM_1K_Bank(1, chr_bank | data);
}
break;
case 0x8312:
SetVROM_1K_Bank(2, chr_bank | data);
break;
case 0x8313:
SetVROM_1K_Bank(3, chr_bank | data);
break;
case 0x8314:
SetVROM_1K_Bank(4, chr_bank | data);
break;
case 0x8315:
SetVROM_1K_Bank(5, chr_bank | data);
break;
case 0x8316:
if (patch != 0)
{
SetVROM_2K_Bank(4, chr_bank | data);
}
else
{
SetVROM_1K_Bank(6, chr_bank | data);
}
break;
case 0x8317:
if (patch != 0)
{
SetVROM_2K_Bank(6, chr_bank | data);
}
else
{
SetVROM_1K_Bank(7, chr_bank | data);
}
break;
case 0x8318:
SetPROM_16K_Bank(4, (reg[0] & 0x30) | data);
break;
}
}
//void Mapper083::HSync(INT scanline)
public override void HSync(int scanline)
{
if (irq_enable != 0)
{
if (irq_counter <= 113)
{
// nes.cpu.IRQ();
irq_enable = 0;
// nes.cpu.SetIRQ( IRQ_MAPPER );
nes.cpu.SetIRQ(IRQ_TRIGGER);
}
else
{
irq_counter -= 113;
}
}
}
//void Mapper083::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = reg[0];
//p[1] = reg[1];
//p[2] = reg[2];
//*(INT*)&p[3] = chr_bank;
//p[7] = irq_enable;
//*(INT*)&p[8] = irq_counter;
}
//void Mapper083::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//reg[0] = p[0];
//reg[1] = p[1];
//reg[2] = p[2];
//chr_bank = *(INT*)&p[3];
//irq_enable = p[7];
//irq_counter = *(INT*)&p[8];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,238 @@
//////////////////////////////////////////////////////////////////////////
// Mapper085 Konami VRC7 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
using Codice.CM.Client.Differences;
namespace VirtualNes.Core
{
public class Mapper085 : Mapper
{
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
INT irq_clock;
public Mapper085(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);
}
else
{
SetCRAM_8K_Bank(0);
}
#if FALSE//0
// DWORD crc = nes.rom.GetPROM_CRC();
// if( crc == 0x1aa0479c ) { // For Tiny Toon Adventures 2 - Montana Land he Youkoso(J)
// nes.SetRenderMethod( NES::PRE_RENDER );
// }
// if( crc == 0x33ce3ff0 ) { // For Lagrange Point(J)
// nes.SetRenderMethod( NES::TILE_RENDER );
// }
#endif
nes.apu.SelectExSound(2);
}
//void Mapper085::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF038)
{
case 0x8000:
SetPROM_8K_Bank(4, data);
break;
case 0x8008:
case 0x8010:
SetPROM_8K_Bank(5, data);
break;
case 0x9000:
SetPROM_8K_Bank(6, data);
break;
case 0x9010:
case 0x9030:
nes.apu.ExWrite(addr, data);
break;
case 0xA000:
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(0, data);
}
else
{
SetCRAM_1K_Bank(0, data);
}
break;
case 0xA008:
case 0xA010:
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(1, data);
}
else
{
SetCRAM_1K_Bank(1, data);
}
break;
case 0xB000:
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(2, data);
}
else
{
SetCRAM_1K_Bank(2, data);
}
break;
case 0xB008:
case 0xB010:
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(3, data);
}
else
{
SetCRAM_1K_Bank(3, data);
}
break;
case 0xC000:
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(4, data);
}
else
{
SetCRAM_1K_Bank(4, data);
}
break;
case 0xC008:
case 0xC010:
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(5, data);
}
else
{
SetCRAM_1K_Bank(5, data);
}
break;
case 0xD000:
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(6, data);
}
else
{
SetCRAM_1K_Bank(6, data);
}
break;
case 0xD008:
case 0xD010:
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(7, data);
}
else
{
SetCRAM_1K_Bank(7, data);
}
break;
case 0xE000:
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 0xE008:
case 0xE010:
irq_latch = data;
break;
case 0xF000:
irq_enable = (byte)(data & 0x03);
irq_counter = irq_latch;
irq_clock = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xF008:
case 0xF010:
irq_enable = (byte)((irq_enable & 0x01) * 3);
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
}
}
//void Mapper085::Clock(INT cycles)
public override void Clock(int cycles)
{
if ((irq_enable & 0x02) != 0)
{
irq_clock += cycles * 4;
while (irq_clock >= 455)
{
irq_clock -= 455;
irq_counter++;
if (irq_counter == 0)
{
irq_counter = irq_latch;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
//void Mapper085::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//p[0] = irq_enable;
//p[1] = irq_counter;
//p[2] = irq_latch;
//*((INT*)&p[4]) = irq_clock;
}
//void Mapper085::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[4]);
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

Some files were not shown because too many files have changed in this diff Show More