From c0e29193f760d4238fad0869dc1ef7f864b715ec Mon Sep 17 00:00:00 2001 From: sin365 <353374337@qq.com> Date: Mon, 5 Aug 2024 01:33:07 +0800 Subject: [PATCH] transfer Mapper 18-43 --- .../VirtualNes.Core/Mapper/Mapper018.cs | 23 + .../VirtualNes.Core/Mapper/Mapper018.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper019.cs | 416 ++++++++++++++++++ .../VirtualNes.Core/Mapper/Mapper019.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper021.cs | 255 +++++++++++ .../VirtualNes.Core/Mapper/Mapper021.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper022.cs | 81 ++++ .../VirtualNes.Core/Mapper/Mapper022.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper023.cs | 271 ++++++++++++ .../VirtualNes.Core/Mapper/Mapper023.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper024.cs | 174 ++++++++ .../VirtualNes.Core/Mapper/Mapper024.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper025.cs | 278 ++++++++++++ .../VirtualNes.Core/Mapper/Mapper025.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper026.cs | 185 ++++++++ .../VirtualNes.Core/Mapper/Mapper026.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper027.cs | 228 ++++++++++ .../VirtualNes.Core/Mapper/Mapper027.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper032.cs | 123 ++++++ .../VirtualNes.Core/Mapper/Mapper032.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper033.cs | 260 +++++++++++ .../VirtualNes.Core/Mapper/Mapper033.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper034.cs | 54 +++ .../VirtualNes.Core/Mapper/Mapper034.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper040.cs | 90 ++++ .../VirtualNes.Core/Mapper/Mapper040.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper041.cs | 78 ++++ .../VirtualNes.Core/Mapper/Mapper041.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper042.cs | 103 +++++ .../VirtualNes.Core/Mapper/Mapper042.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper043.cs | 120 ++++- 31 files changed, 2903 insertions(+), 1 deletion(-) create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper018.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper018.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper021.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper021.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper022.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper022.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper024.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper024.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper025.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper025.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper026.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper026.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper027.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper027.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper032.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper032.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper033.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper033.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper034.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper034.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper040.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper040.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper041.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper041.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper042.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper042.cs.meta diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper018.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper018.cs new file mode 100644 index 0000000..b416798 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper018.cs @@ -0,0 +1,23 @@ +////////////////////////////////////////////////////////////////////////// +// Mapper018 Jaleco SS8806 // +////////////////////////////////////////////////////////////////////////// +using static VirtualNes.MMU; +using static VirtualNes.Core.CPU; +using INT = System.Int32; +using BYTE = System.Byte; + +namespace VirtualNes.Core +{ + public class Mapper018 : Mapper + { + public Mapper018(NES parent) : base(parent) + { + } + + + public override void Reset() + { + } + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper018.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper018.cs.meta new file mode 100644 index 0000000..1e6d762 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper018.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d9f306005d0826a4e96ceec780568bb3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs new file mode 100644 index 0000000..0072083 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs @@ -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; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs.meta new file mode 100644 index 0000000..1204e14 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e0d99073c4ae1444bbf4fa05498aecb8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper021.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper021.cs new file mode 100644 index 0000000..5e367f5 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper021.cs @@ -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; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper021.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper021.cs.meta new file mode 100644 index 0000000..db8c641 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper021.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6082f7bf68f41f6439e13610e7766887 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper022.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper022.cs new file mode 100644 index 0000000..6b20420 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper022.cs @@ -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; + } + } + + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper022.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper022.cs.meta new file mode 100644 index 0000000..989544d --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper022.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b618d4b61b1e6ed48ad8ab3a38947424 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs new file mode 100644 index 0000000..0b4b8a6 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs @@ -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; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs.meta new file mode 100644 index 0000000..0b14e76 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d201617d198186e41b362ea94be5533c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper024.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper024.cs new file mode 100644 index 0000000..77d31af --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper024.cs @@ -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; + } + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper024.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper024.cs.meta new file mode 100644 index 0000000..d1dce11 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper024.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6e319508c6222744dbb48902f10ab3df +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper025.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper025.cs new file mode 100644 index 0000000..20a74ff --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper025.cs @@ -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]); + } + + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper025.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper025.cs.meta new file mode 100644 index 0000000..dd1a8a4 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper025.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d065f0d406a26d4da372c16493e5bb9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper026.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper026.cs new file mode 100644 index 0000000..e677177 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper026.cs @@ -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; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper026.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper026.cs.meta new file mode 100644 index 0000000..e517984 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper026.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 96c606c490146244789d313ca2cf55a4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper027.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper027.cs new file mode 100644 index 0000000..994c4f7 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper027.cs @@ -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]; + } + + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper027.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper027.cs.meta new file mode 100644 index 0000000..a6e847b --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper027.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 764ca4c42dfc3714e99ff2bbaf56c272 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper032.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper032.cs new file mode 100644 index 0000000..8c843af --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper032.cs @@ -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; + } + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper032.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper032.cs.meta new file mode 100644 index 0000000..72e1982 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper032.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 124a427e842cc7d4f879e27d559edfc7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper033.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper033.cs new file mode 100644 index 0000000..f2ac3ba --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper033.cs @@ -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; + } + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper033.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper033.cs.meta new file mode 100644 index 0000000..0938cbf --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper033.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8c7bedd1ba634c14fa3532bb9524cf80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper034.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper034.cs new file mode 100644 index 0000000..6b4231e --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper034.cs @@ -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); + } + + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper034.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper034.cs.meta new file mode 100644 index 0000000..cd0633b --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper034.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 647e21ec144715c45bbcf44a6b5757b1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper040.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper040.cs new file mode 100644 index 0000000..584a6ff --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper040.cs @@ -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; + } + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper040.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper040.cs.meta new file mode 100644 index 0000000..38ae7af --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper040.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: de917ab62c02ecc4b87138b609896ce7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper041.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper041.cs new file mode 100644 index 0000000..2a5df03 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper041.cs @@ -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; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper041.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper041.cs.meta new file mode 100644 index 0000000..f4a1119 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper041.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: fc0a11d806679d94da60252475da5996 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper042.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper042.cs new file mode 100644 index 0000000..a9c8be4 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper042.cs @@ -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; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper042.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper042.cs.meta new file mode 100644 index 0000000..5a79206 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper042.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0645c16b7e182fa4094ef038567fd95b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper043.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper043.cs index 567b6d2..97894ac 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper043.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper043.cs @@ -1,12 +1,18 @@ -using static VirtualNes.MMU; +////////////////////////////////////////////////////////////////////////// +// Mapper043 SMB2J // +////////////////////////////////////////////////////////////////////////// +using static VirtualNes.MMU; using static VirtualNes.Core.CPU; using INT = System.Int32; using BYTE = System.Byte; +using Codice.CM.Client.Differences; namespace VirtualNes.Core { public class Mapper043 : Mapper { + BYTE irq_enable; + INT irq_counter; public Mapper043(NES parent) : base(parent) { } @@ -14,7 +20,119 @@ namespace VirtualNes.Core public override void Reset() { + irq_enable = 0xFF; + irq_counter = 0; + + SetPROM_8K_Bank(3, 2); + SetPROM_32K_Bank(1, 0, 4, 9); + + if (VROM_1K_SIZE != 0) + { + SetVROM_8K_Bank(0); + } } + //BYTE Mapper043::ReadLow(WORD addr) + public override byte ReadLow(ushort addr) + { + if (0x5000 <= addr && addr < 0x6000) + { + byte[] pPtr = nes.rom.GetPROM(); + return pPtr[0x2000 * 8 + 0x1000 + (addr - 0x5000)]; + } + return (BYTE)(addr >> 8); + } + + //void Mapper043::ExWrite(WORD addr, BYTE data) + public override void ExWrite(ushort addr, byte data) + { + if ((addr & 0xF0FF) == 0x4022) + { + switch (data & 0x07) + { + case 0x00: + case 0x02: + case 0x03: + case 0x04: + SetPROM_8K_Bank(6, 4); + break; + case 0x01: + SetPROM_8K_Bank(6, 3); + break; + case 0x05: + SetPROM_8K_Bank(6, 7); + break; + case 0x06: + SetPROM_8K_Bank(6, 5); + break; + case 0x07: + SetPROM_8K_Bank(6, 6); + break; + } + } + } + + //void Mapper043::WriteLow(WORD addr, BYTE data) + public override void WriteLow(ushort addr, byte data) + { + if ((addr & 0xF0FF) == 0x4022) + { + ExWrite(addr, data); + } + } + + //void Mapper043::Write(WORD addr, BYTE data) + public override void Write(ushort addr, byte data) + { + if (addr == 0x8122) + { + if ((data & 0x03) != 0) + { + irq_enable = 1; + } + else + { + irq_counter = 0; + irq_enable = 0; + } + nes.cpu.ClrIRQ(IRQ_MAPPER); + } + } + + //void Mapper043::HSync(INT scanline) + public override void HSync(int scanline) + { + nes.cpu.ClrIRQ(IRQ_MAPPER); + if (irq_enable != 0) + { + irq_counter += 341; + if (irq_counter >= 12288) + { + irq_counter = 0; + // nes.cpu.IRQ(); + nes.cpu.SetIRQ(IRQ_MAPPER); + } + } + } + + //void Mapper043::SaveState(LPBYTE p) + public override void SaveState(byte[] p) + { + //p[0] = irq_enable; + //*(INT*)&p[1] = irq_counter; + } + + //void Mapper043::LoadState(LPBYTE p) + public override void LoadState(byte[] p) + { + //irq_enable = p[0]; + //irq_counter = *(INT*)&p[1]; + } + + + public override bool IsStateSave() + { + return true; + } } }