dev_4VirtualNes #23

Merged
sin365 merged 35 commits from dev_4VirtualNes into master 2024-08-05 17:49:44 +08:00
45 changed files with 2702 additions and 4 deletions
Showing only changes of commit 923e41a1ba - Show all commits

View File

@ -0,0 +1,71 @@
//////////////////////////////////////////////////////////////////////////
// Mapper086 Jaleco Early Mapper #2 //
//////////////////////////////////////////////////////////////////////////
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 Mapper086 : Mapper
{
BYTE reg, cnt;
public Mapper086(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, 2, 3);
SetVROM_8K_Bank(0);
reg = 0xFF;
cnt = 0;
}
//void Mapper086::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr == 0x6000)
{
SetPROM_32K_Bank((data & 0x30) >> 4);
SetVROM_8K_Bank((data & 0x03) | ((data & 0x40) >> 4));
}
if (addr == 0x7000)
{
if ((reg & 0x10) == 0 && ((data & 0x10) != 0) && cnt==0)
{
//DEBUGOUT( "WR:$%02X\n", data );
if ((data & 0x0F) == 0 // Strike
|| (data & 0x0F) == 5)
{ // Foul
cnt = 60; // 次の発声を1秒程禁止する
}
// OSDにするべきか…
if (Config.sound.bExtraSoundEnable)
{
DirectSound.EsfAllStop();
DirectSound.EsfPlay(ESF_MOEPRO_STRIKE + (data & 0x0F));
}
}
reg = data;
}
}
//void Mapper086::VSync()
public override void VSync()
{
if (cnt!=0)
{
cnt--;
}
}
}
}

View File

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

View File

@ -0,0 +1,36 @@
//////////////////////////////////////////////////////////////////////////
// Mapper087 Konami 74161/32 //
//////////////////////////////////////////////////////////////////////////
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 Mapper087 : Mapper
{
public Mapper087(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, 2, 3);
SetVROM_8K_Bank(0);
}
//void Mapper087::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr == 0x6000)
{
SetVROM_8K_Bank((data & 0x02) >> 1);
}
}
}
}

View File

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

View File

@ -0,0 +1,107 @@
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 Mapper088 : Mapper
{
BYTE reg;
BYTE patch;
public Mapper088(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);
}
patch = 0;
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0xc1b6b2a6)
{ // Devil Man(J)
patch = 1;
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
}
if (crc == 0xd9803a35)
{ // Quinty(J)
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
}
}
//void Mapper088::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr)
{
case 0x8000:
reg = data;
if (patch != 0)
{
if ((data & 0x40) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
}
break;
case 0x8001:
switch (reg & 0x07)
{
case 0:
SetVROM_2K_Bank(0, data >> 1);
break;
case 1:
SetVROM_2K_Bank(2, data >> 1);
break;
case 2:
SetVROM_1K_Bank(4, data + 0x40);
break;
case 3:
SetVROM_1K_Bank(5, data + 0x40);
break;
case 4:
SetVROM_1K_Bank(6, data + 0x40);
break;
case 5:
SetVROM_1K_Bank(7, data + 0x40);
break;
case 6:
SetPROM_8K_Bank(4, data);
break;
case 7:
SetPROM_8K_Bank(5, data);
break;
}
break;
case 0xC000:
if (data != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
break;
}
}
//void Mapper088::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg;
}
//void Mapper088::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: 10a2fd49bb318d348842e3c6f339ce96
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,41 @@
//////////////////////////////////////////////////////////////////////////
// Mapper089 SunSoft (水戸黄門) //
//////////////////////////////////////////////////////////////////////////
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 Mapper089 : Mapper
{
public Mapper089(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);
}
//void Mapper089::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
if ((addr & 0xFF00) == 0xC000)
{
SetPROM_16K_Bank(4, (data & 0x70) >> 4);
SetVROM_8K_Bank(((data & 0x80) >> 4) | (data & 0x07));
if ((data & 0x08) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
}
}
}
}

View File

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

View File

@ -0,0 +1,482 @@
//////////////////////////////////////////////////////////////////////////
// Mapper090 PC-JY-?? //
//////////////////////////////////////////////////////////////////////////
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 Mapper090 : Mapper
{
BYTE patch;
BYTE[] prg_reg = new byte[4];
BYTE[] nth_reg = new byte[4];
BYTE[] ntl_reg = new byte[4];
BYTE[] chh_reg = new byte[8];
BYTE[] chl_reg = new byte[8];
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
BYTE irq_occur;
BYTE irq_preset;
BYTE irq_offset;
BYTE prg_6000, prg_E000;
BYTE prg_size, chr_size;
BYTE mir_mode, mir_type;
BYTE key_val;
BYTE mul_val1, mul_val2;
BYTE sw_val;
public Mapper090(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(PROM_8K_SIZE - 4, PROM_8K_SIZE - 3, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
SetVROM_8K_Bank(0);
patch = 0;
uint crc = nes.rom.GetPROM_CRC();
if (crc == 0x2a268152)
{
patch = 1;
}
if (crc == 0x2224b882)
{
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
}
irq_enable = 0; // Disable
irq_counter = 0;
irq_latch = 0;
irq_occur = 0;
irq_preset = 0;
irq_offset = 0;
prg_6000 = 0;
prg_E000 = 0;
prg_size = 0;
chr_size = 0;
mir_mode = 0;
mir_type = 0;
key_val = 0;
mul_val1 = mul_val2 = 0;
for (INT i = 0; i < 4; i++)
{
prg_reg[i] = (byte)(PROM_8K_SIZE - 4 + i);
ntl_reg[i] = 0;
nth_reg[i] = 0;
chl_reg[i] = i;
chh_reg[i] = 0;
chl_reg[i + 4] = (byte)(i + 4);
chh_reg[i + 4] = 0;
}
if (sw_val != 0)
sw_val = 0x00;
else
sw_val = 0xFF;
// nes.SetRenderMethod( NES::PRE_ALL_RENDER );
}
//BYTE Mapper090::ReadLow(WORD addr)
public override byte ReadLow(ushort addr)
{
DEBUGOUT("RD:%04X\n", addr);
switch (addr)
{
case 0x5000:
return (byte)((sw_val != 0) ? 0x00 : 0xFF);
case 0x5800:
return (BYTE)(mul_val1 * mul_val2);
case 0x5801:
return (BYTE)((mul_val1 * mul_val2) >> 8);
case 0x5803:
return key_val;
}
if (addr >= 0x6000)
{
return base.ReadLow(addr);
}
// return sw_val?0x00:0xFF;
return (BYTE)(addr >> 8);
}
//void Mapper090::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
DEBUGOUT("WR:%04X %02X\n", addr, data);
if (addr == 0x5800)
{
mul_val1 = data;
}
else
if (addr == 0x5801)
{
mul_val2 = data;
}
else
if (addr == 0x5803)
{
key_val = data;
}
}
//void Mapper090::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xF007)
{
case 0x8000:
case 0x8001:
case 0x8002:
case 0x8003:
prg_reg[addr & 3] = data;
SetBank_CPU();
break;
case 0x9000:
case 0x9001:
case 0x9002:
case 0x9003:
case 0x9004:
case 0x9005:
case 0x9006:
case 0x9007:
chl_reg[addr & 7] = data;
SetBank_PPU();
break;
case 0xA000:
case 0xA001:
case 0xA002:
case 0xA003:
case 0xA004:
case 0xA005:
case 0xA006:
case 0xA007:
chh_reg[addr & 7] = data;
SetBank_PPU();
break;
case 0xB000:
case 0xB001:
case 0xB002:
case 0xB003:
ntl_reg[addr & 3] = data;
SetBank_VRAM();
break;
case 0xB004:
case 0xB005:
case 0xB006:
case 0xB007:
nth_reg[addr & 3] = data;
SetBank_VRAM();
break;
case 0xC002:
irq_enable = 0;
irq_occur = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0xC003:
irq_enable = 0xFF;
irq_preset = 0xFF;
break;
case 0xC004:
break;
case 0xC005:
if ((irq_offset & 0x80) != 0)
{
irq_latch = (byte)(data ^ (irq_offset | 1));
}
else
{
irq_latch = (byte)(data | (irq_offset & 0x27));
}
irq_preset = 0xFF;
break;
case 0xC006:
if (patch != 0)
{
irq_offset = data;
}
break;
case 0xD000:
prg_6000 = (byte)(data & 0x80);
prg_E000 = (byte)(data & 0x04);
prg_size = (byte)(data & 0x03);
chr_size = (byte)((data & 0x18) >> 3);
mir_mode = (byte)(data & 0x20);
SetBank_CPU();
SetBank_PPU();
SetBank_VRAM();
break;
case 0xD001:
mir_type = (byte)(data & 0x03);
SetBank_VRAM();
break;
case 0xD003:
break;
}
}
//void Mapper090::HSync(INT scanline)
public override void HSync(int scanline)
{
if ((scanline >= 0 && scanline <= 239))
{
if (nes.ppu.IsDispON())
{
if (irq_preset != 0)
{
irq_counter = irq_latch;
irq_preset = 0;
}
if (irq_counter != 0)
{
irq_counter--;
}
if (irq_counter == 0)
{
if (irq_enable != 0)
{
// irq_occur = 0xFF;
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
}
}
//void Mapper090::Clock(INT cycles)
public override void Clock(int cycles)
{
// if( irq_occur ) {
// nes.cpu.IRQ_NotPending();
// }
}
void SetBank_CPU()
{
if (prg_size == 0)
{
SetPROM_32K_Bank(PROM_8K_SIZE - 4, PROM_8K_SIZE - 3, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
else
if (prg_size == 1)
{
SetPROM_32K_Bank(prg_reg[1] * 2, prg_reg[1] * 2 + 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
else
if (prg_size == 2)
{
if (prg_E000 != 0)
{
SetPROM_32K_Bank(prg_reg[0], prg_reg[1], prg_reg[2], prg_reg[3]);
}
else
{
if (prg_6000 != 0)
{
SetPROM_8K_Bank(3, prg_reg[3]);
}
SetPROM_32K_Bank(prg_reg[0], prg_reg[1], prg_reg[2], PROM_8K_SIZE - 1);
}
}
else
{
SetPROM_32K_Bank(prg_reg[3], prg_reg[2], prg_reg[1], prg_reg[0]);
}
}
void SetBank_PPU()
{
INT[] bank = new int[8];
for (INT i = 0; i < 8; i++)
{
bank[i] = ((INT)chh_reg[i] << 8) | ((INT)chl_reg[i]);
}
if (chr_size == 0)
{
SetVROM_8K_Bank(bank[0]);
}
else
if (chr_size == 1)
{
SetVROM_4K_Bank(0, bank[0]);
SetVROM_4K_Bank(4, bank[4]);
}
else
if (chr_size == 2)
{
SetVROM_2K_Bank(0, bank[0]);
SetVROM_2K_Bank(2, bank[2]);
SetVROM_2K_Bank(4, bank[4]);
SetVROM_2K_Bank(6, bank[6]);
}
else
{
SetVROM_8K_Bank(bank[0], bank[1], bank[2], bank[3], bank[4], bank[5], bank[6], bank[7]);
}
}
void SetBank_VRAM()
{
INT[] bank = new int[4];
for (INT i = 0; i < 4; i++)
{
bank[i] = ((INT)nth_reg[i] << 8) | ((INT)ntl_reg[i]);
}
if (patch == 0 && mir_mode != 0)
{
for (INT i = 0; i < 4; i++)
{
if (nth_reg[i] == 0 && (ntl_reg[i] == (BYTE)i))
{
mir_mode = 0;
}
}
if (mir_mode != 0)
{
SetVROM_1K_Bank(8, bank[0]);
SetVROM_1K_Bank(9, bank[1]);
SetVROM_1K_Bank(10, bank[2]);
SetVROM_1K_Bank(11, bank[3]);
}
}
else
{
if (mir_type == 0)
{
SetVRAM_Mirror(VRAM_VMIRROR);
}
else
if (mir_type == 1)
{
SetVRAM_Mirror(VRAM_HMIRROR);
}
else
{
SetVRAM_Mirror(VRAM_MIRROR4L);
}
}
}
//void Mapper090::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
INT i;
for (i = 0; i < 4; i++)
{
p[i] = prg_reg[i];
}
for (i = 0; i < 8; i++)
{
p[i + 4] = chh_reg[i];
}
for (i = 0; i < 8; i++)
{
p[i + 12] = chl_reg[i];
}
for (i = 0; i < 4; i++)
{
p[i + 20] = nth_reg[i];
}
for (i = 0; i < 4; i++)
{
p[i + 24] = ntl_reg[i];
}
p[28] = irq_enable;
p[29] = irq_counter;
p[30] = irq_latch;
p[31] = prg_6000;
p[32] = prg_E000;
p[33] = prg_size;
p[34] = chr_size;
p[35] = mir_mode;
p[36] = mir_type;
p[37] = mul_val1;
p[38] = mul_val2;
p[39] = key_val;
p[40] = irq_occur;
p[41] = irq_preset;
p[42] = irq_offset;
}
//void Mapper090::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
INT i;
for (i = 0; i < 4; i++)
{
prg_reg[i] = p[i];
}
for (i = 0; i < 8; i++)
{
chh_reg[i] = p[i + 4];
}
for (i = 0; i < 8; i++)
{
chl_reg[i] = p[i + 12];
}
for (i = 0; i < 4; i++)
{
nth_reg[i] = p[i + 20];
}
for (i = 0; i < 4; i++)
{
ntl_reg[i] = p[i + 24];
}
irq_enable = p[28];
irq_counter = p[29];
irq_latch = p[30];
prg_6000 = p[31];
prg_E000 = p[32];
prg_size = p[33];
chr_size = p[34];
mir_mode = p[35];
mir_type = p[36];
mul_val1 = p[37];
mul_val2 = p[38];
key_val = p[39];
irq_occur = p[40];
irq_preset = p[41];
irq_offset = p[42];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,104 @@
//////////////////////////////////////////////////////////////////////////
// Mapper091 PC-HK-SF3 //
//////////////////////////////////////////////////////////////////////////
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 Mapper091 : Mapper
{
BYTE irq_enable;
BYTE irq_counter;
public Mapper091(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(PROM_8K_SIZE - 2, PROM_8K_SIZE - 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
if (VROM_8K_SIZE != 0)
{
SetVROM_8K_Bank(0, 0, 0, 0, 0, 0, 0, 0);
}
irq_enable = 0;
irq_counter = 0;
nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER);
}
//void Mapper091::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
//DEBUGOUT( "$%04X:$%02X(%3d) L=%3d\n", addr, data, data, nes.GetScanline() );
switch (addr & 0xF003)
{
case 0x6000:
case 0x6001:
case 0x6002:
case 0x6003:
SetVROM_2K_Bank((byte)((addr & 0x03) * 2), data);
break;
case 0x7000:
SetPROM_8K_Bank(4, data);
break;
case 0x7001:
SetPROM_8K_Bank(5, data);
break;
case 0x7002:
irq_enable = 0;
irq_counter = 0;
nes.cpu.ClrIRQ(IRQ_MAPPER);
break;
case 0x7003:
irq_enable = 1;
break;
}
}
//void Mapper091::HSync(INT scanline)
public override void HSync(int scanline)
{
if ((scanline >= 0 && scanline < 240) && nes.ppu.IsDispON())
{
if (irq_enable != 0)
{
irq_counter++;
}
if (irq_counter >= 8)
{
// nes.cpu.IRQ_NotPending();
nes.cpu.SetIRQ(IRQ_MAPPER);
}
}
}
//void Mapper091::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = irq_enable;
p[1] = irq_counter;
}
//void Mapper091::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: 202340dc4e291a243913879c4b71f605
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,74 @@
/////////////////////////////////
// Mapper092 Jaleco/Type1 Higher 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 Mapper092 : Mapper
{
public Mapper092(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 Mapper092::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
//DEBUGOUT( "A:%04X D:%02X\n", addr, data );
data = (byte)(addr & 0xFF);
if (addr >= 0x9000)
{
if ((data & 0xF0) == 0xD0)
{
SetPROM_16K_Bank(6, data & 0x0F);
}
else if ((data & 0xF0) == 0xE0)
{
SetVROM_8K_Bank(data & 0x0F);
}
}
else
{
if ((data & 0xF0) == 0xB0)
{
SetPROM_16K_Bank(6, data & 0x0F);
}
else if ((data & 0xF0) == 0x70)
{
SetVROM_8K_Bank(data & 0x0F);
}
else if ((data & 0xF0) == 0xC0)
{
INT[] tbl = new int[]{ 3, 4, 5, 6, 0, 1, 2, 7,
9,10, 8,11,13,12,14,15 };
// OSDにするべきか…
if (Config.sound.bExtraSoundEnable)
{
DEBUGOUT("CODE %02X\n", data);
DirectSound.EsfAllStop();
DirectSound.EsfPlay(ESF_MOEPRO_STRIKE + tbl[data & 0x0F]);
}
}
}
}
}
}

View File

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

View File

@ -0,0 +1,38 @@
//////////////////////////////////////////////////////////////////////////
// Mapper093 SunSoft (Fantasy Zone) //
//////////////////////////////////////////////////////////////////////////
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 Mapper093 : Mapper
{
public Mapper093(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 Mapper093::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr == 0x6000)
{
SetPROM_16K_Bank(4, data);
}
}
}
}

View File

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

View File

@ -0,0 +1,35 @@
/////////////////////////////////
// Mapper094 Capcom 74161/32 //
//////////////////////////////////////////////////////////////////////////
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 Mapper094 : Mapper
{
public Mapper094(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
//void Mapper094::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
if ((addr & 0xFFF0) == 0xFF00)
{
SetPROM_16K_Bank(4, (data >> 2) & 0x7);
}
}
}
}

View File

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

View File

@ -0,0 +1,186 @@
//////////////////////////////////////////////////////////////////////////
// Mapper095 Namcot 106M (Dragon Buster) //
//////////////////////////////////////////////////////////////////////////
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 Mapper095 : Mapper
{
BYTE reg;
BYTE prg0, prg1;
BYTE chr01, chr23, chr4, chr5, chr6, chr7;
public Mapper095(NES parent) : base(parent)
{
}
public override void Reset()
{
reg = 0x00;
prg0 = 0;
prg1 = 1;
SetBank_CPU();
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_PPU();
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
}
//void Mapper095::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xE001)
{
case 0x8000:
reg = data;
SetBank_CPU();
SetBank_PPU();
break;
case 0x8001:
if (reg <= 0x05)
{
if ((data & 0x20) != 0) SetVRAM_Mirror(VRAM_MIRROR4H);
else SetVRAM_Mirror(VRAM_MIRROR4L);
data &= 0x1F;
}
switch (reg & 0x07)
{
case 0x00:
if (VROM_1K_SIZE != 0)
{
chr01 = (byte)(data & 0xFE);
SetBank_PPU();
}
break;
case 0x01:
if (VROM_1K_SIZE != 0)
{
chr23 = (byte)(data & 0xFE);
SetBank_PPU();
}
break;
case 0x02:
if (VROM_1K_SIZE != 0)
{
chr4 = data;
SetBank_PPU();
}
break;
case 0x03:
if (VROM_1K_SIZE != 0)
{
chr5 = data;
SetBank_PPU();
}
break;
case 0x04:
if (VROM_1K_SIZE != 0)
{
chr6 = data;
SetBank_PPU();
}
break;
case 0x05:
if (VROM_1K_SIZE != 0)
{
chr7 = data;
SetBank_PPU();
}
break;
case 0x06:
prg0 = data;
SetBank_CPU();
break;
case 0x07:
prg1 = data;
SetBank_CPU();
break;
}
break;
}
}
void SetBank_CPU()
{
if ((reg & 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 & 0x80) != 0)
{
SetVROM_8K_Bank(chr4, chr5, chr6, chr7,
chr01, chr01 + 1, chr23, chr23 + 1);
}
else
{
SetVROM_8K_Bank(chr01, chr01 + 1, chr23, chr23 + 1,
chr4, chr5, chr6, chr7);
}
}
}
//void Mapper095::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg;
p[1] = prg0;
p[2] = prg1;
p[3] = chr01;
p[4] = chr23;
p[5] = chr4;
p[6] = chr5;
p[7] = chr6;
p[8] = chr7;
}
//void Mapper095::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg = p[0];
prg0 = p[1];
prg1 = p[2];
chr01 = p[3];
chr23 = p[4];
chr4 = p[5];
chr5 = p[6];
chr6 = p[7];
chr7 = p[8];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,75 @@
////////////////////////////////
// Mapper096 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 Mapper096 : Mapper
{
BYTE[] reg = new byte[2];
public Mapper096(NES parent) : base(parent)
{
}
public override void Reset()
{
reg[0] = reg[1] = 0;
SetPROM_32K_Bank(0, 1, 2, 3);
SetBank();
SetVRAM_Mirror(VRAM_MIRROR4L);
}
//void Mapper096::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
SetPROM_32K_Bank(data & 0x03);
reg[0] = (byte)((data & 0x04) >> 2);
SetBank();
}
public override void PPU_Latch(ushort addr)
{
if ((addr & 0xF000) == 0x2000)
{
reg[1] = (byte)((addr >> 8) & 0x03);
SetBank();
}
}
void SetBank()
{
SetCRAM_4K_Bank(0, reg[0] * 4 + reg[1]);
SetCRAM_4K_Bank(4, reg[0] * 4 + 0x03);
}
//void Mapper096::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg[0];
p[1] = reg[1];
}
//void Mapper096::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: 3e4ba3003173d9543aa8e29ae8802e93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,43 @@
//////////////////////////////////////////////////////////////////////////
// Mapper097 Irem 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 Mapper097 : Mapper
{
public Mapper097(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(PROM_8K_SIZE - 2, PROM_8K_SIZE - 1, 0, 1);
if (VROM_8K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
}
//void Mapper097::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
if (addr < 0xC000)
{
SetPROM_16K_Bank(6, data & 0x0F);
if ((data & 0x80) != 0) SetVRAM_Mirror(VRAM_VMIRROR);
else SetVRAM_Mirror(VRAM_HMIRROR);
}
}
}
}

View File

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

View File

@ -0,0 +1,91 @@
//////////////////////////////////////////////////////////////////////////
// Mapper099 VS-Unisystem //
//////////////////////////////////////////////////////////////////////////
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 Mapper099 : Mapper
{
BYTE coin;
public Mapper099(NES parent) : base(parent)
{
}
public override void Reset()
{
// set CPU bank pointers
if (PROM_8K_SIZE > 2)
{
SetPROM_32K_Bank(0, 1, 2, 3);
}
else if (PROM_8K_SIZE > 1)
{
SetPROM_32K_Bank(0, 1, 0, 1);
}
else
{
SetPROM_32K_Bank(0, 0, 0, 0);
}
// set VROM bank
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(0);
}
coin = 0;
}
//BYTE Mapper099::ExRead(WORD addr)
public override byte ExRead(ushort addr)
{
if (addr == 0x4020)
{
return coin;
}
return (byte)(addr >> 8);
}
//void Mapper099::ExWrite(WORD addr, BYTE data)
public override void ExWrite(ushort addr, byte data)
{
if (addr == 0x4016)
{
if ((data & 0x04) != 0)
{
SetVROM_8K_Bank(1);
}
else
{
SetVROM_8K_Bank(0);
}
if (nes.rom.GetPROM_CRC() == 0xC99EC059)
{ // VS Raid on Bungeling Bay(J)
if ((data & 0x02) != 0)
{
nes.cpu.SetIRQ(IRQ_MAPPER);
}
else
{
nes.cpu.ClrIRQ(IRQ_MAPPER);
}
}
}
if (addr == 0x4020)
{
coin = data;
}
}
}
}

View File

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

View File

@ -0,0 +1,301 @@
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 Mapper100 : Mapper
{
BYTE[] reg = new byte[8];
BYTE prg0, prg1, prg2, prg3;
BYTE chr0, chr1, chr2, chr3, chr4, chr5, chr6, chr7;
BYTE irq_enable;
BYTE irq_counter;
BYTE irq_latch;
public Mapper100(NES parent) : base(parent)
{
}
public override void Reset()
{
for (INT i = 0; i < 8; i++)
{
reg[i] = 0x00;
}
prg0 = 0;
prg1 = 1;
prg2 = (byte)(PROM_8K_SIZE - 2);
prg3 = (byte)(PROM_8K_SIZE - 1);
SetBank_CPU();
if (VROM_1K_SIZE != 0)
{
chr0 = 0;
chr1 = 1;
chr2 = 2;
chr3 = 3;
chr4 = 4;
chr5 = 5;
chr6 = 6;
chr7 = 7;
SetBank_PPU();
}
else
{
chr0 = chr2 = chr4 = chr5 = chr6 = chr7 = 0;
chr1 = chr3 = 1;
}
irq_enable = 0; // Disable
irq_counter = 0;
irq_latch = 0;
}
//void Mapper100::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr & 0xE001)
{
case 0x8000:
reg[0] = data;
break;
case 0x8001:
reg[1] = data;
switch (reg[0] & 0xC7)
{
case 0x00:
if (VROM_1K_SIZE != 0)
{
chr0 = (byte)(data & 0xFE);
chr1 = (byte)(chr0 + 1);
SetBank_PPU();
}
break;
case 0x01:
if (VROM_1K_SIZE != 0)
{
chr2 = (byte)(data & 0xFE);
chr3 = (byte)(chr2 + 1);
SetBank_PPU();
}
break;
case 0x02:
if (VROM_1K_SIZE != 0)
{
chr4 = data;
SetBank_PPU();
}
break;
case 0x03:
if (VROM_1K_SIZE != 0)
{
chr5 = data;
SetBank_PPU();
}
break;
case 0x04:
if (VROM_1K_SIZE != 0)
{
chr6 = data;
SetBank_PPU();
}
break;
case 0x05:
if (VROM_1K_SIZE != 0)
{
chr7 = data;
SetBank_PPU();
}
break;
case 0x06:
prg0 = data;
SetBank_CPU();
break;
case 0x07:
prg1 = data;
SetBank_CPU();
break;
case 0x46:
prg2 = data;
SetBank_CPU();
break;
case 0x47:
prg3 = data;
SetBank_CPU();
break;
case 0x80:
if (VROM_1K_SIZE != 0)
{
chr4 = (byte)(data & 0xFE);
chr5 = (byte)(chr4 + 1);
SetBank_PPU();
}
break;
case 0x81:
if (VROM_1K_SIZE != 0)
{
chr6 = (byte)(data & 0xFE);
chr7 = (byte)(chr6 + 1);
SetBank_PPU();
}
break;
case 0x82:
if (VROM_1K_SIZE != 0)
{
chr0 = data;
SetBank_PPU();
}
break;
case 0x83:
if (VROM_1K_SIZE != 0)
{
chr1 = data;
SetBank_PPU();
}
break;
case 0x84:
if (VROM_1K_SIZE != 0)
{
chr2 = data;
SetBank_PPU();
}
break;
case 0x85:
if (VROM_1K_SIZE != 0)
{
chr3 = data;
SetBank_PPU();
}
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;
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 = 0xFF;
break;
}
}
//void Mapper100::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()
{
SetPROM_32K_Bank(prg0, prg1, prg2, prg3);
}
void SetBank_PPU()
{
if (VROM_1K_SIZE != 0)
{
SetVROM_8K_Bank(chr0, chr1, chr2, chr3, chr4, chr5, chr6, chr7);
}
}
//void Mapper100::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
for (byte i = 0; i < 8; i++)
{
p[i] = reg[i];
}
p[8] = prg0;
p[9] = prg1;
p[10] = prg2;
p[11] = prg3;
p[12] = chr0;
p[13] = chr1;
p[14] = chr2;
p[15] = chr3;
p[16] = chr4;
p[17] = chr5;
p[18] = chr6;
p[19] = chr7;
p[20] = irq_enable;
p[21] = irq_counter;
p[22] = irq_latch;
}
//void Mapper100::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
for (byte i = 0; i < 8; i++)
{
reg[i] = p[i];
}
prg0 = p[8];
prg1 = p[9];
prg2 = p[10];
prg3 = p[11];
chr0 = p[12];
chr1 = p[13];
chr2 = p[14];
chr3 = p[15];
chr4 = p[16];
chr5 = p[17];
chr6 = p[18];
chr7 = p[19];
irq_enable = p[20];
irq_counter = p[21];
irq_latch = p[22];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,42 @@
//////////////////////////////////////////////////////////////////////////
// Mapper101 Jaleco(Urusei Yatsura) //
//////////////////////////////////////////////////////////////////////////
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 Mapper101 : Mapper
{
public Mapper101(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0, 1, 2, 3);
SetVROM_8K_Bank(0);
}
//void Mapper101::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
if (addr >= 0x6000)
{
SetVROM_8K_Bank(data & 0x03);
}
}
//void Mapper101::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
SetVROM_8K_Bank(data & 0x03);
}
}
}

View File

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

View File

@ -0,0 +1,202 @@
//////////////////////////////////////////////////////////////////////////
// Mapper105 Nintendo World Championship //
//////////////////////////////////////////////////////////////////////////
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 Mapper105 : Mapper
{
BYTE init_state;
BYTE write_count;
BYTE bits;
BYTE[] reg = new byte[4];
BYTE irq_enable;
INT irq_counter;
public Mapper105(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0);
reg[0] = 0x0C;
reg[1] = 0x00;
reg[2] = 0x00;
reg[3] = 0x10;
bits = 0;
write_count = 0;
irq_counter = 0;
irq_enable = 0;
init_state = 0;
}
//void Mapper105::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
//WORD reg_num = (addr & 0x7FFF) >> 13;
uint reg_num = (byte)((addr & 0x7FFF) >> 13);
if ((data & 0x80) != 0)
{
bits = write_count = 0;
if (reg_num == 0)
{
reg[reg_num] |= 0x0C;
}
}
else
{
//bits |= (data & 1) << write_count++;
bits |= (byte)((data & 1) << write_count++);
if (write_count == 5)
{
reg[reg_num] = (byte)(bits & 0x1F);
bits = write_count = 0;
}
}
if ((reg[0] & 0x02) != 0)
{
if ((reg[0] & 0x01) != 0)
{
SetVRAM_Mirror(VRAM_HMIRROR);
}
else
{
SetVRAM_Mirror(VRAM_VMIRROR);
}
}
else
{
if ((reg[0] & 0x01) != 0)
{
SetVRAM_Mirror(VRAM_MIRROR4H);
}
else
{
SetVRAM_Mirror(VRAM_MIRROR4L);
}
}
switch (init_state)
{
case 0:
case 1:
init_state++;
break;
case 2:
if ((reg[1] & 0x08) != 0)
{
if ((reg[0] & 0x08) != 0)
{
if ((reg[0] & 0x04) != 0)
{
SetPROM_8K_Bank(4, ((reg[3] & 0x07) * 2 + 16));
SetPROM_8K_Bank(5, ((reg[3] & 0x07) * 2 + 17));
SetPROM_8K_Bank(6, 30);
SetPROM_8K_Bank(7, 31);
}
else
{
SetPROM_8K_Bank(4, 16);
SetPROM_8K_Bank(5, 17);
SetPROM_8K_Bank(6, ((reg[3] & 0x07) * 2 + 16));
SetPROM_8K_Bank(7, ((reg[3] & 0x07) * 2 + 17));
}
}
else
{
SetPROM_8K_Bank(4, ((reg[3] & 0x06) * 2 + 16));
SetPROM_8K_Bank(5, ((reg[3] & 0x06) * 2 + 17));
SetPROM_8K_Bank(6, ((reg[3] & 0x06) * 2 + 18));
SetPROM_8K_Bank(7, ((reg[3] & 0x06) * 2 + 19));
}
}
else
{
SetPROM_8K_Bank(4, ((reg[1] & 0x06) * 2 + 0));
SetPROM_8K_Bank(5, ((reg[1] & 0x06) * 2 + 1));
SetPROM_8K_Bank(6, ((reg[1] & 0x06) * 2 + 2));
SetPROM_8K_Bank(7, ((reg[1] & 0x06) * 2 + 3));
}
if ((reg[1] & 0x10) != 0)
{
irq_counter = 0;
irq_enable = 0;
}
else
{
irq_enable = 1;
}
// nes.cpu.ClrIRQ( IRQ_MAPPER );
break;
default:
break;
}
}
//void Mapper105::HSync(INT scanline)
public override void HSync(int scanline)
{
if (scanline != 0)
{
if (irq_enable != 0)
{
irq_counter += 29781;
}
if (((irq_counter | 0x21FFFFFF) & 0x3E000000) == 0x3E000000)
{
// nes.cpu.IRQ_NotPending();
// nes.cpu.SetIRQ( IRQ_MAPPER );
nes.cpu.SetIRQ(IRQ_TRIGGER2);
}
}
}
//void Mapper105::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
//for (INT i = 0; i < 4; i++)
//{
// p[i] = reg[i];
//}
//p[8] = init_state;
//p[9] = write_count;
//p[10] = bits;
//p[11] = irq_enable;
//*((INT*)&p[12]) = irq_counter;
}
//void Mapper105::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
//for (INT i = 0; i < 4; i++)
//{
// reg[i] = p[i];
//}
//init_state = p[8];
//write_count = p[9];
//bits = p[10];
//irq_enable = p[11];
//irq_counter = *((INT*)&p[12]);
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,33 @@
//////////////////////////////////////////////////////////////////////////
// Mapper107 Magic Dragon Mapper //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
namespace VirtualNes.Core
{
public class _MapName : Mapper
{
public _MapName(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);
}
//void Mapper107::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
SetPROM_32K_Bank((data >> 1) & 0x03);
SetVROM_8K_Bank(data & 0x07);
}
}
}

View File

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

View File

@ -0,0 +1,31 @@
//////////////////////////////////////////////////////////////////////////
// Mapper108 //
//////////////////////////////////////////////////////////////////////////
using static VirtualNes.MMU;
using static VirtualNes.Core.CPU;
using INT = System.Int32;
using BYTE = System.Byte;
using System;
namespace VirtualNes.Core
{
public class Mapper108 : Mapper
{
public Mapper108(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0xC, 0xD, 0xE, 0xF);
SetPROM_8K_Bank(3, 0);
}
//void Mapper108::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
SetPROM_8K_Bank(3, data);
}
}
}

View File

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

View File

@ -0,0 +1,131 @@
//////////////////////////////////////////////////////////////////////////
// Mapper109 SACHEN The Great Wall SA-019 //
//////////////////////////////////////////////////////////////////////////
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 Mapper109 : Mapper
{
BYTE reg;
BYTE chr0, chr1, chr2, chr3;
BYTE chrmode0, chrmode1;
public Mapper109(NES parent) : base(parent)
{
}
public override void Reset()
{
reg = 0;
SetPROM_32K_Bank(0);
chr0 = 0;
chr1 = 0;
chr2 = 0;
chr3 = 0;
SetBank_PPU();
chrmode0 = 0;
chrmode1 = 0;
}
//void Mapper109::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
switch (addr)
{
case 0x4100:
reg = data;
break;
case 0x4101:
switch (reg)
{
case 0:
chr0 = data;
SetBank_PPU();
break;
case 1:
chr1 = data;
SetBank_PPU();
break;
case 2:
chr2 = data;
SetBank_PPU();
break;
case 3:
chr3 = data;
SetBank_PPU();
break;
case 4:
chrmode0 = (byte)(data & 0x01);
SetBank_PPU();
break;
case 5:
SetPROM_32K_Bank(data & 0x07);
break;
case 6:
chrmode1 = (byte)(data & 0x07);
SetBank_PPU();
break;
case 7:
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
break;
}
break;
}
}
void SetBank_PPU()
{
if (VROM_1K_SIZE != 0)
{
SetVROM_1K_Bank(0, chr0);
SetVROM_1K_Bank(1, chr1 | ((chrmode1 << 3) & 0x8));
SetVROM_1K_Bank(2, chr2 | ((chrmode1 << 2) & 0x8));
SetVROM_1K_Bank(3, chr3 | ((chrmode1 << 1) & 0x8) | (chrmode0 * 0x10));
SetVROM_1K_Bank(4, VROM_1K_SIZE - 4);
SetVROM_1K_Bank(5, VROM_1K_SIZE - 3);
SetVROM_1K_Bank(6, VROM_1K_SIZE - 2);
SetVROM_1K_Bank(7, VROM_1K_SIZE - 1);
}
}
//void Mapper109::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg;
p[1] = chr0;
p[2] = chr1;
p[3] = chr2;
p[4] = chr3;
p[5] = chrmode0;
p[6] = chrmode1;
}
//void Mapper109::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg = p[0];
chr0 = p[1];
chr1 = p[2];
chr2 = p[3];
chr3 = p[4];
chrmode0 = p[5];
chrmode1 = p[6];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,87 @@
//////////////////////////////////////////////////////////////////////////
// Mapper110 //
//////////////////////////////////////////////////////////////////////////
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 Mapper110 : Mapper
{
BYTE reg0, reg1;
public Mapper110(NES parent) : base(parent)
{
}
public override void Reset()
{
SetPROM_32K_Bank(0);
SetVROM_8K_Bank(0);
reg0 = 0;
reg1 = 0;
}
//void Mapper110::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
switch (addr)
{
case 0x4100:
reg1 = (byte)(data & 0x07);
break;
case 0x4101:
switch (reg1)
{
case 5:
SetPROM_32K_Bank(data);
break;
case 0:
reg0 = (byte)(data & 0x01);
SetVROM_8K_Bank(reg0);
break;
case 2:
reg0 = data;
SetVROM_8K_Bank(reg0);
break;
case 4:
reg0 = (byte)(reg0 | (data << 1));
SetVROM_8K_Bank(reg0);
break;
case 6:
reg0 = (byte)(reg0 | (data << 2));
SetVROM_8K_Bank(reg0);
break;
default:
break;
}
break;
default:
break;
}
}
//void Mapper110::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
p[0] = reg0;
p[1] = reg1;
}
//void Mapper110::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
reg0 = p[0];
reg1 = p[1];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,167 @@
//////////////////////////////////////////////////////////////////////////
// Mapper112 Nintendo MMC3 //
//////////////////////////////////////////////////////////////////////////
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 Mapper112 : Mapper
{
BYTE[] reg = new byte[4];
BYTE prg0, prg1;
BYTE chr01, chr23, chr4, chr5, chr6, chr7;
public Mapper112(NES parent) : base(parent)
{
}
public override void Reset()
{
for (INT i = 0; i < 4; i++)
{
reg[i] = 0x00;
}
prg0 = 0;
prg1 = 1;
SetBank_CPU();
chr01 = 0;
chr23 = 2;
chr4 = 4;
chr5 = 5;
chr6 = 6;
chr7 = 7;
SetBank_PPU();
}
//void Mapper112::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
switch (addr)
{
case 0x8000:
reg[0] = data;
SetBank_CPU();
SetBank_PPU();
break;
case 0xA000:
reg[1] = data;
switch (reg[0] & 0x07)
{
case 0x00:
prg0 = (byte)((data & (PROM_8K_SIZE - 1)));
SetBank_CPU();
break;
case 0x01:
prg1 = (byte)((data & (PROM_8K_SIZE - 1)));
SetBank_CPU();
break;
case 0x02:
chr01 = (byte)(data & 0xFE);
SetBank_PPU();
break;
case 0x03:
chr23 = (byte)(data & 0xFE);
SetBank_PPU();
break;
case 0x04:
chr4 = data;
SetBank_PPU();
break;
case 0x05:
chr5 = data;
SetBank_PPU();
break;
case 0x06:
chr6 = data;
SetBank_PPU();
break;
case 0x07:
chr7 = data;
SetBank_PPU();
break;
}
break;
case 0xC000:
reg[3] = data;
SetBank_PPU();
break;//hum 源码居然没有break 语法差异呗
case 0xE000:
reg[2] = data;
if (!nes.rom.Is4SCREEN())
{
if ((data & 0x01) != 0) SetVRAM_Mirror(VRAM_HMIRROR);
else SetVRAM_Mirror(VRAM_VMIRROR);
}
SetBank_PPU();
break;
}
}
void SetBank_CPU()
{
SetPROM_32K_Bank(prg0, prg1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1);
}
void SetBank_PPU()
{
if ((reg[2] & 0x02) != 0)
{
SetVROM_8K_Bank(chr01, chr01 + 1, chr23, chr23 + 1, chr4, chr5, chr6, chr7);
}
else
{
SetVROM_8K_Bank(((reg[3] << 6) & 0x100) + chr01,
((reg[3] << 6) & 0x100) + chr01 + 1,
((reg[3] << 5) & 0x100) + chr23,
((reg[3] << 5) & 0x100) + chr23 + 1,
((reg[3] << 4) & 0x100) + chr4,
((reg[3] << 3) & 0x100) + chr5,
((reg[3] << 2) & 0x100) + chr6,
((reg[3] << 1) & 0x100) + chr7);
}
}
//void Mapper112::SaveState(LPBYTE p)
public override void SaveState(byte[] p)
{
for (INT i = 0; i < 4; i++)
{
p[i] = reg[i];
}
p[4] = chr01;
p[5] = chr23;
p[6] = chr4;
p[7] = chr5;
p[8] = chr6;
p[9] = chr7;
}
//void Mapper112::LoadState(LPBYTE p)
public override void LoadState(byte[] p)
{
for (byte i = 0; i < 4; i++)
{
reg[i] = p[i];
}
chr01 = p[4];
chr23 = p[5];
chr4 = p[6];
chr5 = p[7];
chr6 = p[8];
chr7 = p[9];
}
public override bool IsStateSave()
{
return true;
}
}
}

View File

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

View File

@ -0,0 +1,79 @@
////////////////////////////
// Mapper113 PC-Sachen/Hacker //
//////////////////////////////////////////////////////////////////////////
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 Mapper113 : Mapper
{
public Mapper113(NES parent) : base(parent)
{
}
public override void Reset()
{
// SetPROM_32K_Bank( 0, 1, PROM_8K_SIZE-2, PROM_8K_SIZE-1 );
SetPROM_32K_Bank(0);
SetVROM_8K_Bank(0);
}
//void Mapper113::WriteLow(WORD addr, BYTE data)
public override void WriteLow(ushort addr, byte data)
{
//DEBUGOUT( "$%04X:$%02X L=%3d\n", addr, data, nes.GetScanline() );
switch (addr)
{
case 0x4100:
case 0x4111:
case 0x4120:
case 0x4194:
case 0x4195:
case 0x4900:
if (nes.rom.GetPROM_CRC() == 0xA75AEDE5)
{ // HES 6-in-1
if ((data & 0x80) != 0)
{
SetVRAM_Mirror(VRAM_VMIRROR);
}
else
{
SetVRAM_Mirror(VRAM_HMIRROR);
}
}
SetPROM_32K_Bank(data >> 3);
SetVROM_8K_Bank(((data >> 3) & 0x08) + (data & 0x07));
break;
}
}
//void Mapper113::Write(WORD addr, BYTE data)
public override void Write(ushort addr, byte data)
{
//DEBUGOUT( "$%04X:$%02X L=%3d\n", addr, data, nes.GetScanline() );
switch (addr)
{
case 0x8008:
case 0x8009:
SetPROM_32K_Bank(data >> 3);
SetVROM_8K_Bank(((data >> 3) & 0x08) + (data & 0x07));
break;
case 0x8E66:
case 0x8E67:
//SetVROM_8K_Bank((data & 0x07) ? 0 : 1);
SetVROM_8K_Bank((data & 0x07) != 0 ? 0 : 1);
break;
case 0xE00A:
SetVRAM_Mirror(VRAM_MIRROR4L);
break;
}
}
}
}

View File

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

View File

@ -8,13 +8,13 @@ namespace VirtualNes.Core
{
public class _MapName : Mapper
{
public _MapName(NES parent) : base(parent)
public _MapName(NES parent) : base(parent)
{
}
public override void Reset()
{
}
{
}
}
}
}