From ba8b656914043817f433871e804feeeb9790e2b7 Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Mon, 5 Aug 2024 11:52:43 +0800 Subject: [PATCH] =?UTF-8?q?Mapper=E8=A1=A5=E5=85=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets/VirtualNes.Core/APU.cs | 29 + .../Assets/VirtualNes.Core/ApuEX/APU_FDS.cs | 55 +- .../Assets/VirtualNes.Core/ApuEX/APU_MMC5.cs | 26 + .../VirtualNes.Core/CoreLibs/ByteArrayRef.cs | 17 +- .../Assets/VirtualNes.Core/Mapper/EEPROM.cs | 455 +++++++++ .../VirtualNes.Core/Mapper/EEPROM.cs.meta | 11 + .../VirtualNes.Core/Mapper/Mapper016.cs | 843 ++++++++-------- .../VirtualNes.Core/Mapper/Mapper019.cs | 811 +++++++-------- .../VirtualNes.Core/Mapper/Mapper023.cs | 2 +- .../VirtualNes.Core/Mapper/Mapper072.cs | 95 +- .../VirtualNes.Core/Mapper/Mapper086.cs | 111 ++- .../VirtualNes.Core/Mapper/Mapper090.cs | 941 +++++++++--------- .../VirtualNes.Core/Mapper/Mapper092.cs | 126 +-- .../VirtualNes.Core/Mapper/Mapper107.cs | 4 +- .../VirtualNes.Core/Mapper/Mapper116.cs | 5 +- .../VirtualNes.Core/Mapper/Mapper162.cs | 239 ++--- .../VirtualNes.Core/Mapper/Mapper163.cs | 7 +- .../VirtualNes.Core/Mapper/Mapper164.cs | 21 +- .../VirtualNes.Core/Mapper/Mapper165.cs | 2 +- .../VirtualNes.Core/Mapper/Mapper176.cs | 96 +- .../VirtualNes.Core/Mapper/Mapper199.cs | 458 ++++----- .../VirtualNes.Core/Mapper/Mapper225.cs | 2 +- .../Assets/VirtualNes.Core/NES.cs | 12 +- .../Assets/VirtualNes.Core/PPU.cs | 24 +- .../Assets/VirtualNes.Core/ROM.cs | 5 + virtuanessrc097-master/NES/Nes.cpp | Bin 202972 -> 202968 bytes 26 files changed, 2516 insertions(+), 1881 deletions(-) create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/EEPROM.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/EEPROM.cs.meta diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs index 63bcb2a..1558bf2 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs @@ -502,6 +502,35 @@ namespace VirtualNes.Core Debuger.LogError("exqueue overflow."); } } + + internal byte ExRead(ushort addr) + { + byte data = 0; + + if ((exsound_select & 0x10) != 0) + { + if (addr == 0x4800) + { + SetExQueue(nes.cpu.GetTotalCycles(), 0, 0); + } + } + if ((exsound_select & 0x04) != 0) + { + if (addr >= 0x4040 && addr < 0x4100) + { + data = fds.SyncRead(addr); + } + } + if ((exsound_select & 0x08) != 0) + { + if (addr >= 0x5000 && addr <= 0x5015) + { + data = mmc5.SyncRead(addr); + } + } + + return data; + } } public struct QUEUEDATA diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_FDS.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_FDS.cs index d273fc4..7cdea83 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_FDS.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_FDS.cs @@ -38,9 +38,62 @@ namespace VirtualNes.Core //todo : 实现 } + internal byte SyncRead(ushort addr) + { + byte data = (byte)(addr >> 8); + + if (addr >= 0x4040 && addr <= 0x407F) + { + data = (byte)(fds_sync.main_wavetable[addr & 0x3F] | 0x40); + } + else + if (addr == 0x4090) + { + data = (byte)((fds_sync.volenv_gain & 0x3F) | 0x40); + } + else + if (addr == 0x4092) + { + data = (byte)((fds_sync.swpenv_gain & 0x3F) | 0x40); + } + + return data; + } + private class FDSSOUND { - //todo : 实现 + public byte[] reg = new byte[0x80]; + public byte volenv_mode; // Volume Envelope + public byte volenv_gain; + public byte volenv_decay; + public double volenv_phaseacc; + public byte swpenv_mode; // Sweep Envelope + public byte swpenv_gain; + public byte swpenv_decay; + public double swpenv_phaseacc; + // For envelope unit + public byte envelope_enable; // $4083 bit6 + public byte envelope_speed; // $408A + // For $4089 + public byte wave_setup; // bit7 + public int master_volume; // bit1-0 + // For Main unit + public int[] main_wavetable = new int[64]; + public byte main_enable; + public int main_frequency; + public int main_addr; + // For Effector(LFO) unit + public byte[] lfo_wavetable = new byte[64]; + public byte lfo_enable; // 0:Enable 1:Wavetable setup + public int lfo_frequency; + public int lfo_addr; + public double lfo_phaseacc; + // For Sweep unit + public int sweep_bias; + // Misc + public int now_volume; + public int now_freq; + public int output; } } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_MMC5.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_MMC5.cs index 30ffb1e..0f9c16d 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_MMC5.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ApuEX/APU_MMC5.cs @@ -4,6 +4,9 @@ namespace VirtualNes.Core { public class APU_MMC5 : APU_INTERFACE { + SYNCRECTANGLE sch0 = new SYNCRECTANGLE(); + SYNCRECTANGLE sch1 = new SYNCRECTANGLE(); + public override void Reset(float fClock, int nRate) { //todo : 实现 @@ -29,5 +32,28 @@ namespace VirtualNes.Core { //todo : 实现 } + + internal byte SyncRead(ushort addr) + { + byte data = 0; + + if (addr == 0x5015) + { + if ((sch0.enable != 0) && sch0.vbl_length > 0) data |= (1 << 0); + if ((sch1.enable != 0) && sch1.vbl_length > 0) data |= (1 << 1); + } + + return data; + } + + public class SYNCRECTANGLE + { + // For sync + public byte[] reg = new byte[4]; + public byte enable; + public byte holdnote; + public byte[] dummy = new byte[2]; + public int vbl_length; + } } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ByteArrayRef.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ByteArrayRef.cs index 16ea18b..a2327d6 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ByteArrayRef.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ByteArrayRef.cs @@ -1,4 +1,6 @@ -namespace VirtualNes.Core +using System; + +namespace VirtualNes.Core { public class ByteArrayRef { @@ -22,6 +24,9 @@ SetArray(array, offset, length); } + public ByteArrayRef(byte[] array) : this(array, 0, array.Length) { } + public ByteArrayRef(byte[] array, int offset) : this(array, offset, array.Length - offset) { } + public void SetArray(byte[] array, int offset, int length) { m_rawArray = array; @@ -40,5 +45,15 @@ m_rawArray[(m_offset + index)] = value; } } + + public static implicit operator ByteArrayRef(byte[] array) + { + return new ByteArrayRef(array); + } + + public static implicit operator Span(ByteArrayRef array) + { + return new Span(array.m_rawArray, array.Offset, array.m_length); + } } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/EEPROM.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/EEPROM.cs new file mode 100644 index 0000000..7f6c4a0 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/EEPROM.cs @@ -0,0 +1,455 @@ +using System; + +namespace VirtualNes.Core +{ + + + public class X24C01 + { + public const int X24C01_IDLE = 0; // Idle + public const int X24C01_ADDRESS = 1; // Address set + public const int X24C01_READ = 2; // Read + public const int X24C01_WRITE = 3; // Write + public const int X24C01_ACK = 4; // Acknowledge + public const int X24C01_ACK_WAIT = 5; // Acknowledge wait + + int now_state, next_state; + int bitcnt; + byte addr, data; + byte sda; + byte scl_old, sda_old; + + ByteArrayRef pEEPDATA; + + public X24C01() + { + now_state = X24C01_IDLE; + next_state = X24C01_IDLE; + addr = 0; + data = 0; + sda = 0xFF; + scl_old = 0; + sda_old = 0; + + pEEPDATA = null; + } + + public void Reset(ByteArrayRef ptr) + { + now_state = X24C01_IDLE; + next_state = X24C01_IDLE; + addr = 0; + data = 0; + sda = 0xFF; + scl_old = 0; + sda_old = 0; + + pEEPDATA = ptr; + } + + public void Write(byte scl_in, byte sda_in) + { + // Clock line + byte scl_rise = (byte)(~scl_old & scl_in); + byte scl_fall = (byte)(scl_old & ~scl_in); + // Data line + byte sda_rise = (byte)(~sda_old & sda_in); + byte sda_fall = (byte)(sda_old & ~sda_in); + + byte scl_old_temp = scl_old; + byte sda_old_temp = sda_old; + + scl_old = scl_in; + sda_old = sda_in; + + // Start condition? + if (scl_old_temp != 0 && sda_fall != 0) + { + now_state = X24C01_ADDRESS; + bitcnt = 0; + addr = 0; + sda = 0xFF; + return; + } + + // Stop condition? + if (scl_old_temp != 0 && sda_rise != 0) + { + now_state = X24C01_IDLE; + sda = 0xFF; + return; + } + + // SCL ____---- RISE + if (scl_rise != 0) + { + switch (now_state) + { + case X24C01_ADDRESS: + if (bitcnt < 7) + { + // 本来はMSB->LSB + addr = (byte)(addr & (~(1 << bitcnt))); + addr = (byte)(addr | ((sda_in != 0 ? 1 : 0) << bitcnt)); + } + else + { + if (sda_in != 0) + { + next_state = X24C01_READ; + data = pEEPDATA[addr & 0x7F]; + } + else + { + next_state = X24C01_WRITE; + } + } + bitcnt++; + break; + case X24C01_ACK: + sda = 0; // ACK + break; + case X24C01_READ: + if (bitcnt < 8) + { + // 本来はMSB->LSB + sda = (byte)((data & (1 << bitcnt)) != 0 ? 1 : 0); + } + bitcnt++; + break; + case X24C01_WRITE: + if (bitcnt < 8) + { + // 本来はMSB->LSB + data = (byte)(data & (~(1 << bitcnt))); + data = (byte)(data | ((sda_in != 0 ? 1 : 0) << bitcnt)); + } + bitcnt++; + break; + + case X24C01_ACK_WAIT: + if (sda_in == 0) + { + next_state = X24C01_IDLE; + } + break; + } + } + + // SCL ----____ FALL + if (scl_fall != 0) + { + switch (now_state) + { + case X24C01_ADDRESS: + if (bitcnt >= 8) + { + now_state = X24C01_ACK; + sda = 0xFF; + } + break; + case X24C01_ACK: + now_state = next_state; + bitcnt = 0; + sda = 0xFF; + break; + case X24C01_READ: + if (bitcnt >= 8) + { + now_state = X24C01_ACK_WAIT; + addr = (byte)((addr + 1) & 0x7F); + } + break; + case X24C01_WRITE: + if (bitcnt >= 8) + { + now_state = X24C01_ACK; + next_state = X24C01_IDLE; + pEEPDATA[addr & 0x7F] = data; + addr = (byte)((addr + 1) & 0x7F); + } + break; + } + } + } + + public byte Read() + { + return sda; + } + + public void Load(byte[] p) + { + //now_state = *((INT*)&p[0]); + //next_state = *((INT*)&p[4]); + //bitcnt = *((INT*)&p[8]); + //addr = p[12]; + //data = p[13]; + //sda = p[14]; + //scl_old = p[15]; + //sda_old = p[16]; + } + + public void Save(byte[] p) + { + //*((INT*)&p[0]) = now_state; + //*((INT*)&p[4]) = next_state; + //*((INT*)&p[8]) = bitcnt; + //p[12] = addr; + //p[13] = data; + //p[14] = sda; + //p[15] = scl_old; + //p[16] = sda_old; + } + } + + public class X24C02 + { + public const int X24C02_IDLE = 0; // Idle + public const int X24C02_DEVADDR = 1; // Device address set + public const int X24C02_ADDRESS = 2; // Address set + public const int X24C02_READ = 3; // Read + public const int X24C02_WRITE = 4; // Write + public const int X24C02_ACK = 5; // Acknowledge + public const int X24C02_NAK = 6; // Not Acknowledge + public const int X24C02_ACK_WAIT = 7; // Acknowledge wait + + int now_state, next_state; + int bitcnt; + byte addr, data, rw; + byte sda; + byte scl_old, sda_old; + + ByteArrayRef pEEPDATA; + + public X24C02() + { + now_state = X24C02_IDLE; + next_state = X24C02_IDLE; + addr = 0; + data = 0; + rw = 0; + sda = 0xFF; + scl_old = 0; + sda_old = 0; + + pEEPDATA = null; + } + + public void Reset(ByteArrayRef ptr) + { + now_state = X24C02_IDLE; + next_state = X24C02_IDLE; + addr = 0; + data = 0; + rw = 0; + sda = 0xFF; + scl_old = 0; + sda_old = 0; + + pEEPDATA = ptr; + } + + public void Write(byte scl_in, byte sda_in) + { + // Clock line + byte scl_rise = (byte)(~scl_old & scl_in); + byte scl_fall = (byte)(scl_old & ~scl_in); + // Data line + byte sda_rise = (byte)(~sda_old & sda_in); + byte sda_fall = (byte)(sda_old & ~sda_in); + + byte scl_old_temp = scl_old; + byte sda_old_temp = sda_old; + + scl_old = scl_in; + sda_old = sda_in; + + // Start condition? + if (scl_old_temp != 0 && sda_fall != 0) + { + now_state = X24C02_DEVADDR; + bitcnt = 0; + sda = 0xFF; + return; + } + + // Stop condition? + if (scl_old_temp != 0 && sda_rise != 0) + { + now_state = X24C02_IDLE; + sda = 0xFF; + return; + } + + // SCL ____---- RISE + if (scl_rise != 0) + { + switch (now_state) + { + case X24C02_DEVADDR: + if (bitcnt < 8) + { + data = (byte)(data & (~(1 << (7 - bitcnt)))); + data = (byte)(data | ((sda_in != 0 ? 1 : 0) << (7 - bitcnt))); + } + bitcnt++; + break; + case X24C02_ADDRESS: + if (bitcnt < 8) + { + addr = (byte)(addr & (~(1 << (7 - bitcnt)))); + addr = (byte)(addr | ((sda_in != 0 ? 1 : 0) << (7 - bitcnt))); + } + bitcnt++; + break; + case X24C02_READ: + if (bitcnt < 8) + { + sda = (byte)((data & (1 << (7 - bitcnt))) != 0 ? 1 : 0); + } + bitcnt++; + break; + case X24C02_WRITE: + if (bitcnt < 8) + { + data = (byte)(data & (~(1 << (7 - bitcnt)))); + data = (byte)(data | ((sda_in != 0 ? 1 : 0) << (7 - bitcnt))); + } + bitcnt++; + break; + case X24C02_NAK: + sda = 0xFF; // NAK + break; + case X24C02_ACK: + sda = 0; // ACK + break; + case X24C02_ACK_WAIT: + if (sda_in == 0) + { + next_state = X24C02_READ; + data = pEEPDATA[addr]; + } + break; + } + } + + // SCL ----____ FALL + if (scl_fall != 0) + { + switch (now_state) + { + case X24C02_DEVADDR: + if (bitcnt >= 8) + { + if ((data & 0xA0) == 0xA0) + { + now_state = X24C02_ACK; + rw = (byte)(data & 0x01); + sda = 0xFF; + if (rw != 0) + { + // Now address read + next_state = X24C02_READ; + data = pEEPDATA[addr]; + } + else + { + next_state = X24C02_ADDRESS; + } + bitcnt = 0; + } + else + { + now_state = X24C02_NAK; + next_state = X24C02_IDLE; + sda = 0xFF; + } + } + break; + case X24C02_ADDRESS: + if (bitcnt >= 8) + { + now_state = X24C02_ACK; + sda = 0xFF; + if (rw != 0) + { + // Readでは絶対来ないが念の為 + next_state = X24C02_IDLE; + } + else + { + // to Data Write + next_state = X24C02_WRITE; + } + bitcnt = 0; + } + break; + case X24C02_READ: + if (bitcnt >= 8) + { + now_state = X24C02_ACK_WAIT; + addr = (byte)((addr + 1) & 0xFF); + } + break; + case X24C02_WRITE: + if (bitcnt >= 8) + { + pEEPDATA[addr] = data; + now_state = X24C02_ACK; + next_state = X24C02_WRITE; + addr = (byte)((addr + 1) & 0xFF); + bitcnt = 0; + } + break; + case X24C02_NAK: + now_state = X24C02_IDLE; + bitcnt = 0; + sda = 0xFF; + break; + case X24C02_ACK: + now_state = next_state; + bitcnt = 0; + sda = 0xFF; + break; + case X24C02_ACK_WAIT: + now_state = next_state; + bitcnt = 0; + sda = 0xFF; + break; + } + } + } + + public byte Read() + { + return sda; + } + + public void Load(byte[] p) + { + //now_state = *((INT*)&p[0]); + //next_state = *((INT*)&p[4]); + //bitcnt = *((INT*)&p[8]); + //addr = p[12]; + //data = p[13]; + //rw = p[14]; + //sda = p[15]; + //scl_old = p[16]; + //sda_old = p[17]; + } + + public void Save(byte[] p) + { + //*((INT*)&p[0]) = now_state; + //*((INT*)&p[4]) = next_state; + //*((INT*)&p[8]) = bitcnt; + //p[12] = addr; + //p[13] = data; + //p[14] = rw; + //p[15] = sda; + //p[16] = scl_old; + //p[17] = sda_old; + } + } +} \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/EEPROM.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/EEPROM.cs.meta new file mode 100644 index 0000000..f305afa --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/EEPROM.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: be5901dc72f4b6045a7c33edba28145f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper016.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper016.cs index 2bf76bb..4b9bce8 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper016.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper016.cs @@ -1,430 +1,429 @@ ////////////////////////////////////////////////////////////////////////// // Mapper016 Bandai Standard // ////////////////////////////////////////////////////////////////////////// -using static VirtualNes.MMU; using static VirtualNes.Core.CPU; -using INT = System.Int32; +using static VirtualNes.MMU; using BYTE = System.Byte; -using Codice.CM.Client.Differences; +using INT = System.Int32; namespace VirtualNes.Core -{ - public class Mapper016 : Mapper - { - BYTE patch; // For Famicom Jump 2 - BYTE eeprom_type; // EEPROM type - - BYTE[] reg = new byte[3]; - - BYTE irq_enable; - INT irq_counter; - INT irq_latch; - BYTE irq_type; - - X24C01 x24c01; - X24C02 x24c02; - public Mapper016(NES parent) : base(parent) - { - } - - - public override void Reset() - { - patch = 0; - - reg[0] = reg[1] = reg[2] = 0; - irq_enable = 0; - irq_counter = 0; - irq_latch = 0; - - irq_type = 0; - nes.SetIrqType( NES.IRQMETHOD.IRQ_CLOCK); - - eeprom_type = 0; - - SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1); - - uint crc = nes.rom.GetPROM_CRC(); - - if (crc == 0x3f15d20d // Famicom Jump 2(J) - || crc == 0xf76aa523) - { // Famicom Jump 2(J)(alt) - patch = 1; - eeprom_type = 0xFF; - - WRAM[0x0BBC] = 0xFF; // SRAM対策 - } - - if (crc == 0x1d6f27f7) - { // Dragon Ball Z 2(Korean Hack) - nes.SetIrqType( NES.IRQMETHOD.IRQ_HSYNC); - eeprom_type = 1; - } - if (crc == 0x6f7247c8) - { // Dragon Ball Z 3(Korean Hack) - nes.SetIrqType( NES.IRQMETHOD.IRQ_CLOCK); - eeprom_type = 1; - } - - if (crc == 0x7fb799fd) - { // Dragon Ball 2 - Dai Maou Fukkatsu(J) - } - if (crc == 0x6c6c2feb // Dragon Ball 3 - Gokuu Den(J) - || crc == 0x8edeb257) - { // Dragon Ball 3 - Gokuu Den(J)(Alt) - } - if (crc == 0x31cd9903) - { // Dragon Ball Z - Kyoushuu! Saiya Jin(J) - nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); - } - if (crc == 0xe49fc53e // Dragon Ball Z 2 - Gekishin Freeza!!(J) - || crc == 0x1582fee0) - { // Dragon Ball Z 2 - Gekishin Freeza!!(J) [alt] - nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); - eeprom_type = 1; - } - if (crc == 0x09499f4d) - { // Dragon Ball Z 3 - Ressen Jinzou Ningen(J) - nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); - eeprom_type = 1; - } - if (crc == 0x2e991109) - { // Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (J) - nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); - eeprom_type = 1; - } - if (crc == 0x146fb9c3) - { // SD Gundam Gaiden - Knight Gundam Monogatari(J) - } - - if (crc == 0x73ac76db // SD Gundam Gaiden - Knight Gundam Monogatari 2 - Hikari no Kishi(J) - || crc == 0x81a15eb8) - { // SD Gundam Gaiden - Knight Gundam Monogatari 3 - Densetsu no Kishi Dan(J) - eeprom_type = 1; - } - if (crc == 0x170250de) - { // Rokudenashi Blues(J) - nes.SetRenderMethod( EnumRenderMethod.POST_ALL_RENDER); - eeprom_type = 1; - } - - // DATACH系 - if (crc == 0x0be0a328 // Datach - SD Gundam - Gundam Wars(J) - || crc == 0x19e81461 // Datach - Dragon Ball Z - Gekitou Tenkaichi Budou Kai(J) - || crc == 0x5b457641 // Datach - Ultraman Club - Supokon Fight!(J) - || crc == 0x894efdbc // Datach - Crayon Shin Chan - Ora to Poi Poi(J) - || crc == 0x983d8175 // Datach - Battle Rush - Build Up Robot Tournament(J) - || crc == 0xbe06853f) - { // Datach - J League Super Top Players(J) - eeprom_type = 2; - } - if (crc == 0xf51a7f46) - { // Datach - Yuu Yuu Hakusho - Bakutou Ankoku Bujutsu Kai(J) - nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); - eeprom_type = 2; - } - - if (eeprom_type == 0) - { - nes.SetSAVERAM_SIZE(128); - x24c01.Reset(WRAM); - } - else - if (eeprom_type == 1) - { - nes.SetSAVERAM_SIZE(256); - x24c02.Reset(WRAM); - } - else - if (eeprom_type == 2) - { - nes.SetSAVERAM_SIZE(384); - x24c02.Reset(WRAM); - x24c01.Reset(WRAM + 256); - } - } - - //BYTE Mapper016::ReadLow(WORD addr) - public override byte ReadLow(ushort addr) - { - if (patch!=0) - { - return base.ReadLow(addr); - } - else - { - if ((addr & 0x00FF) == 0x0000) - { - BYTE ret = 0; - if (eeprom_type == 0) - { - ret = x24c01.Read(); - } - else - if (eeprom_type == 1) - { - ret = x24c02.Read(); - } - else - if (eeprom_type == 2) - { - ret = x24c02.Read() & x24c01.Read(); - } - return (ret ? 0x10 : 0) | (nes.GetBarcodeStatus()); - } - } - return 0x00; - } - - //void Mapper016::WriteLow(WORD addr, BYTE data) - public override void WriteLow(ushort addr, byte data) - { - if (patch == 0) - { - WriteSubA(addr, data); - } - else - { - Mapper::WriteLow(addr, data); - } - } - - void Mapper016::Write(WORD addr, BYTE data) - { - if (!patch) - { - WriteSubA(addr, data); - } - else - { - WriteSubB(addr, data); - } - } - - static BYTE eeprom_addinc; - - // Normal mapper #16 - void Mapper016::WriteSubA(WORD addr, BYTE data) - { - switch (addr & 0x000F) - { - case 0x0000: - case 0x0001: - case 0x0002: - case 0x0003: - case 0x0004: - case 0x0005: - case 0x0006: - case 0x0007: - if (VROM_1K_SIZE) - { - SetVROM_1K_Bank(addr & 0x0007, data); - } - if (eeprom_type == 2) - { - reg[0] = data; - x24c01.Write((data & 0x08) ? 0xFF : 0, (reg[1] & 0x40) ? 0xFF : 0); - } - break; - - case 0x0008: - SetPROM_16K_Bank(4, data); - break; - - case 0x0009: - data &= 0x03; - if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR); - else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR); - else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L); - else SetVRAM_Mirror(VRAM_MIRROR4H); - break; - - case 0x000A: - irq_enable = data & 0x01; - irq_counter = irq_latch; - nes.cpu.ClrIRQ(IRQ_MAPPER); - break; - case 0x000B: - irq_latch = (irq_latch & 0xFF00) | data; - irq_counter = (irq_counter & 0xFF00) | data; - break; - case 0x000C: - irq_latch = ((INT)data << 8) | (irq_latch & 0x00FF); - irq_counter = ((INT)data << 8) | (irq_counter & 0x00FF); - break; - - case 0x000D: - // EEPTYPE0(DragonBallZ) - if (eeprom_type == 0) - { - x24c01.Write((data & 0x20) ? 0xFF : 0, (data & 0x40) ? 0xFF : 0); - } - // EEPTYPE1(DragonBallZ2,Z3,Z Gaiden) - if (eeprom_type == 1) - { - x24c02.Write((data & 0x20) ? 0xFF : 0, (data & 0x40) ? 0xFF : 0); - } - // EEPTYPE2(DATACH) - if (eeprom_type == 2) - { - reg[1] = data; - x24c02.Write((data & 0x20) ? 0xFF : 0, (data & 0x40) ? 0xFF : 0); - x24c01.Write((reg[0] & 0x08) ? 0xFF : 0, (data & 0x40) ? 0xFF : 0); - } - break; - } - } - - // Famicom Jump 2 - void Mapper016::WriteSubB(WORD addr, BYTE data) - { - switch (addr) - { - case 0x8000: - case 0x8001: - case 0x8002: - case 0x8003: - reg[0] = data & 0x01; - SetPROM_8K_Bank(4, reg[0] * 0x20 + reg[2] * 2 + 0); - SetPROM_8K_Bank(5, reg[0] * 0x20 + reg[2] * 2 + 1); - break; - case 0x8004: - case 0x8005: - case 0x8006: - case 0x8007: - reg[1] = data & 0x01; - SetPROM_8K_Bank(6, reg[1] * 0x20 + 0x1E); - SetPROM_8K_Bank(7, reg[1] * 0x20 + 0x1F); - break; - case 0x8008: - reg[2] = data; - SetPROM_8K_Bank(4, reg[0] * 0x20 + reg[2] * 2 + 0); - SetPROM_8K_Bank(5, reg[0] * 0x20 + reg[2] * 2 + 1); - SetPROM_8K_Bank(6, reg[1] * 0x20 + 0x1E); - SetPROM_8K_Bank(7, reg[1] * 0x20 + 0x1F); - break; - - case 0x8009: - data &= 0x03; - if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR); - else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR); - else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L); - else SetVRAM_Mirror(VRAM_MIRROR4H); - break; - - case 0x800A: - irq_enable = data & 0x01; - irq_counter = irq_latch; - - // if( !irq_enable ) { - // nes.cpu.ClrIRQ( IRQ_MAPPER ); - // } - nes.cpu.ClrIRQ(IRQ_MAPPER); - break; - case 0x800B: - irq_latch = (irq_latch & 0xFF00) | data; - break; - case 0x800C: - irq_latch = ((INT)data << 8) | (irq_latch & 0x00FF); - break; - - case 0x800D: - break; - } - } - - void Mapper016::HSync(INT scanline) - { - if (irq_enable && (nes.GetIrqType() == NES.IRQMETHOD.IRQ_HSYNC)) - { - if (irq_counter <= 113) - { - nes.cpu.SetIRQ(IRQ_MAPPER); - // nes.cpu.IRQ(); - //// nes.cpu.IRQ_NotPending(); - // irq_enable = 0; - // irq_counter = 0; - irq_counter &= 0xFFFF; - } - else - { - irq_counter -= 113; - } - } - } - - void Mapper016::Clock(INT cycles) - { - if (irq_enable && (nes.GetIrqType() == NES::IRQ_CLOCK)) - { - if ((irq_counter -= cycles) <= 0) - { - nes.cpu.SetIRQ(IRQ_MAPPER); - // nes.cpu.IRQ(); - //// nes.cpu.IRQ_NotPending(); - // irq_enable = 0; - // irq_counter = 0; - irq_counter &= 0xFFFF; - } - } - } - - void Mapper016::SaveState(LPBYTE p) - { - p[0] = reg[0]; - p[1] = reg[1]; - p[2] = reg[2]; - p[3] = irq_enable; - *(INT*)&p[4] = irq_counter; - *(INT*)&p[8] = irq_latch; - - if (eeprom_type == 0) - { - x24c01.Save(&p[16]); - } - else - if (eeprom_type == 1) - { - x24c02.Save(&p[16]); - } - else - if (eeprom_type == 2) - { - x24c02.Save(&p[16]); - x24c01.Save(&p[48]); - } - } - - void Mapper016::LoadState(LPBYTE p) - { - reg[0] = p[0]; - reg[1] = p[1]; - reg[2] = p[2]; - irq_enable = p[3]; - irq_counter = *(INT*)&p[4]; - irq_latch = *(INT*)&p[8]; - if (eeprom_type == 0) - { - x24c01.Load(&p[16]); - } - else - if (eeprom_type == 1) - { - x24c02.Load(&p[16]); - } - else - if (eeprom_type == 2) - { - x24c02.Load(&p[16]); - x24c01.Load(&p[48]); - } - } - - - public override bool IsStateSave() - { - return true; - } - - } +{ + public class Mapper016 : Mapper + { + BYTE patch; // For Famicom Jump 2 + BYTE eeprom_type; // EEPROM type + + BYTE[] reg = new byte[3]; + + BYTE irq_enable; + INT irq_counter; + INT irq_latch; + BYTE irq_type; + + X24C01 x24c01; + X24C02 x24c02; + public Mapper016(NES parent) : base(parent) + { + } + + + public override void Reset() + { + patch = 0; + + reg[0] = reg[1] = reg[2] = 0; + irq_enable = 0; + irq_counter = 0; + irq_latch = 0; + + irq_type = 0; + nes.SetIrqType(NES.IRQMETHOD.IRQ_CLOCK); + + eeprom_type = 0; + + SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1); + + uint crc = nes.rom.GetPROM_CRC(); + + if (crc == 0x3f15d20d // Famicom Jump 2(J) + || crc == 0xf76aa523) + { // Famicom Jump 2(J)(alt) + patch = 1; + eeprom_type = 0xFF; + + WRAM[0x0BBC] = 0xFF; // SRAM対策 + } + + if (crc == 0x1d6f27f7) + { // Dragon Ball Z 2(Korean Hack) + nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); + eeprom_type = 1; + } + if (crc == 0x6f7247c8) + { // Dragon Ball Z 3(Korean Hack) + nes.SetIrqType(NES.IRQMETHOD.IRQ_CLOCK); + eeprom_type = 1; + } + + if (crc == 0x7fb799fd) + { // Dragon Ball 2 - Dai Maou Fukkatsu(J) + } + if (crc == 0x6c6c2feb // Dragon Ball 3 - Gokuu Den(J) + || crc == 0x8edeb257) + { // Dragon Ball 3 - Gokuu Den(J)(Alt) + } + if (crc == 0x31cd9903) + { // Dragon Ball Z - Kyoushuu! Saiya Jin(J) + nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); + } + if (crc == 0xe49fc53e // Dragon Ball Z 2 - Gekishin Freeza!!(J) + || crc == 0x1582fee0) + { // Dragon Ball Z 2 - Gekishin Freeza!!(J) [alt] + nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); + eeprom_type = 1; + } + if (crc == 0x09499f4d) + { // Dragon Ball Z 3 - Ressen Jinzou Ningen(J) + nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); + eeprom_type = 1; + } + if (crc == 0x2e991109) + { // Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (J) + nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); + eeprom_type = 1; + } + if (crc == 0x146fb9c3) + { // SD Gundam Gaiden - Knight Gundam Monogatari(J) + } + + if (crc == 0x73ac76db // SD Gundam Gaiden - Knight Gundam Monogatari 2 - Hikari no Kishi(J) + || crc == 0x81a15eb8) + { // SD Gundam Gaiden - Knight Gundam Monogatari 3 - Densetsu no Kishi Dan(J) + eeprom_type = 1; + } + if (crc == 0x170250de) + { // Rokudenashi Blues(J) + nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER); + eeprom_type = 1; + } + + // DATACH系 + if (crc == 0x0be0a328 // Datach - SD Gundam - Gundam Wars(J) + || crc == 0x19e81461 // Datach - Dragon Ball Z - Gekitou Tenkaichi Budou Kai(J) + || crc == 0x5b457641 // Datach - Ultraman Club - Supokon Fight!(J) + || crc == 0x894efdbc // Datach - Crayon Shin Chan - Ora to Poi Poi(J) + || crc == 0x983d8175 // Datach - Battle Rush - Build Up Robot Tournament(J) + || crc == 0xbe06853f) + { // Datach - J League Super Top Players(J) + eeprom_type = 2; + } + if (crc == 0xf51a7f46) + { // Datach - Yuu Yuu Hakusho - Bakutou Ankoku Bujutsu Kai(J) + nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC); + eeprom_type = 2; + } + + if (eeprom_type == 0) + { + nes.SetSAVERAM_SIZE(128); + x24c01.Reset(WRAM); + } + else + if (eeprom_type == 1) + { + nes.SetSAVERAM_SIZE(256); + x24c02.Reset(WRAM); + } + else + if (eeprom_type == 2) + { + nes.SetSAVERAM_SIZE(384); + x24c02.Reset(WRAM); + x24c01.Reset(new ByteArrayRef(WRAM, 256)); + } + } + + //BYTE Mapper016::ReadLow(WORD addr) + public override byte ReadLow(ushort addr) + { + if (patch != 0) + { + return base.ReadLow(addr); + } + else + { + if ((addr & 0x00FF) == 0x0000) + { + BYTE ret = 0; + if (eeprom_type == 0) + { + ret = x24c01.Read(); + } + else + if (eeprom_type == 1) + { + ret = x24c02.Read(); + } + else + if (eeprom_type == 2) + { + ret = (byte)(x24c02.Read() & x24c01.Read()); + } + return (byte)((ret != 0 ? 0x10 : 0) | (nes.GetBarcodeStatus())); + } + } + return 0x00; + } + + //void Mapper016::WriteLow(WORD addr, BYTE data) + public override void WriteLow(ushort addr, byte data) + { + if (patch == 0) + { + WriteSubA(addr, data); + } + else + { + base.WriteLow(addr, data); + } + } + + public override void Write(ushort addr, byte data) + { + if (patch == 0) + { + WriteSubA(addr, data); + } + else + { + WriteSubB(addr, data); + } + } + + static BYTE eeprom_addinc; + + // Normal mapper #16 + void WriteSubA(ushort addr, BYTE data) + { + switch (addr & 0x000F) + { + case 0x0000: + case 0x0001: + case 0x0002: + case 0x0003: + case 0x0004: + case 0x0005: + case 0x0006: + case 0x0007: + if (VROM_1K_SIZE != 0) + { + SetVROM_1K_Bank((byte)(addr & 0x0007), data); + } + if (eeprom_type == 2) + { + reg[0] = data; + x24c01.Write((byte)((data & 0x08) != 0 ? 0xFF : 0), (byte)((reg[1] & 0x40) != 0 ? 0xFF : 0)); + } + break; + + case 0x0008: + SetPROM_16K_Bank(4, data); + break; + + case 0x0009: + data &= 0x03; + if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR); + else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR); + else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L); + else SetVRAM_Mirror(VRAM_MIRROR4H); + break; + + case 0x000A: + irq_enable = (byte)(data & 0x01); + irq_counter = irq_latch; + nes.cpu.ClrIRQ(IRQ_MAPPER); + break; + case 0x000B: + irq_latch = (irq_latch & 0xFF00) | data; + irq_counter = (irq_counter & 0xFF00) | data; + break; + case 0x000C: + irq_latch = (data << 8) | (irq_latch & 0x00FF); + irq_counter = (data << 8) | (irq_counter & 0x00FF); + break; + + case 0x000D: + // EEPTYPE0(DragonBallZ) + if (eeprom_type == 0) + { + x24c01.Write((byte)((data & 0x20) != 0 ? 0xFF : 0), (byte)((data & 0x40) != 0 ? 0xFF : 0)); + } + // EEPTYPE1(DragonBallZ2,Z3,Z Gaiden) + if (eeprom_type == 1) + { + x24c02.Write((byte)((data & 0x20) != 0 ? 0xFF : 0), (byte)((data & 0x40) != 0 ? 0xFF : 0)); + } + // EEPTYPE2(DATACH) + if (eeprom_type == 2) + { + reg[1] = data; + x24c02.Write((byte)((data & 0x20) != 0 ? 0xFF : 0), (byte)((data & 0x40) != 0 ? 0xFF : 0)); + x24c01.Write((byte)((reg[0] & 0x08) != 0 ? 0xFF : 0), (byte)((data & 0x40) != 0 ? 0xFF : 0)); + } + break; + } + } + + // Famicom Jump 2 + void WriteSubB(ushort addr, BYTE data) + { + switch (addr) + { + case 0x8000: + case 0x8001: + case 0x8002: + case 0x8003: + reg[0] = (byte)(data & 0x01); + SetPROM_8K_Bank(4, reg[0] * 0x20 + reg[2] * 2 + 0); + SetPROM_8K_Bank(5, reg[0] * 0x20 + reg[2] * 2 + 1); + break; + case 0x8004: + case 0x8005: + case 0x8006: + case 0x8007: + reg[1] = (byte)(data & 0x01); + SetPROM_8K_Bank(6, reg[1] * 0x20 + 0x1E); + SetPROM_8K_Bank(7, reg[1] * 0x20 + 0x1F); + break; + case 0x8008: + reg[2] = data; + SetPROM_8K_Bank(4, reg[0] * 0x20 + reg[2] * 2 + 0); + SetPROM_8K_Bank(5, reg[0] * 0x20 + reg[2] * 2 + 1); + SetPROM_8K_Bank(6, reg[1] * 0x20 + 0x1E); + SetPROM_8K_Bank(7, reg[1] * 0x20 + 0x1F); + break; + + case 0x8009: + data &= 0x03; + if (data == 0) SetVRAM_Mirror(VRAM_VMIRROR); + else if (data == 1) SetVRAM_Mirror(VRAM_HMIRROR); + else if (data == 2) SetVRAM_Mirror(VRAM_MIRROR4L); + else SetVRAM_Mirror(VRAM_MIRROR4H); + break; + + case 0x800A: + irq_enable = (byte)(data & 0x01); + irq_counter = irq_latch; + + // if( !irq_enable ) { + // nes.cpu.ClrIRQ( IRQ_MAPPER ); + // } + nes.cpu.ClrIRQ(IRQ_MAPPER); + break; + case 0x800B: + irq_latch = (irq_latch & 0xFF00) | data; + break; + case 0x800C: + irq_latch = (data << 8) | (irq_latch & 0x00FF); + break; + + case 0x800D: + break; + } + } + + public override void HSync(int scanline) + { + if (irq_enable != 0 && (nes.GetIrqType() == (int)NES.IRQMETHOD.IRQ_HSYNC)) + { + if (irq_counter <= 113) + { + nes.cpu.SetIRQ(IRQ_MAPPER); + // nes.cpu.IRQ(); + //// nes.cpu.IRQ_NotPending(); + // irq_enable = 0; + // irq_counter = 0; + irq_counter &= 0xFFFF; + } + else + { + irq_counter -= 113; + } + } + } + + public override void Clock(int cycles) + { + if (irq_enable != 0 && (nes.GetIrqType() == (int)NES.IRQMETHOD.IRQ_CLOCK)) + { + if ((irq_counter -= cycles) <= 0) + { + nes.cpu.SetIRQ(IRQ_MAPPER); + // nes.cpu.IRQ(); + //// nes.cpu.IRQ_NotPending(); + // irq_enable = 0; + // irq_counter = 0; + irq_counter &= 0xFFFF; + } + } + } + + public override void SaveState(byte[] p) + { + //p[0] = reg[0]; + //p[1] = reg[1]; + //p[2] = reg[2]; + //p[3] = irq_enable; + //*(INT*)&p[4] = irq_counter; + //*(INT*)&p[8] = irq_latch; + + //if (eeprom_type == 0) + //{ + // x24c01.Save(&p[16]); + //} + //else + //if (eeprom_type == 1) + //{ + // x24c02.Save(&p[16]); + //} + //else + //if (eeprom_type == 2) + //{ + // x24c02.Save(&p[16]); + // x24c01.Save(&p[48]); + //} + } + + public override void LoadState(byte[] p) + { + //reg[0] = p[0]; + //reg[1] = p[1]; + //reg[2] = p[2]; + //irq_enable = p[3]; + //irq_counter = *(INT*)&p[4]; + //irq_latch = *(INT*)&p[8]; + //if (eeprom_type == 0) + //{ + // x24c01.Load(&p[16]); + //} + //else + //if (eeprom_type == 1) + //{ + // x24c02.Load(&p[16]); + //} + //else + //if (eeprom_type == 2) + //{ + // x24c02.Load(&p[16]); + // x24c01.Load(&p[48]); + //} + } + + + public override bool IsStateSave() + { + return true; + } + + } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs index 0072083..24bd3d0 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper019.cs @@ -8,409 +8,410 @@ 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; - } - } +{ + 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; + + MemoryUtility.ZEROMEMORY(exram, exram.Length); + + 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) + { + irq_counter = (ushort)(irq_counter + cycles); + if (irq_counter >= 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/Mapper023.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs index 0b4b8a6..894259b 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper023.cs @@ -28,7 +28,7 @@ namespace VirtualNes.Core { addrmask = 0xFFFF; - for (INT i = 0; i < 8; i++) + for (byte i = 0; i < 8; i++) { reg[i] = i; } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper072.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper072.cs index 67dec03..f3dbc62 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper072.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper072.cs @@ -7,53 +7,54 @@ using INT = System.Int32; using BYTE = System.Byte; using System; using Codice.CM.Client.Differences; +using VirtualNes.Core.Debug; namespace VirtualNes.Core -{ - public class Mapper072 : Mapper - { - public Mapper072(NES parent) : base(parent) - { - } - - public override void Reset() - { - SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1); - - if (VROM_8K_SIZE != 0) - { - SetVROM_8K_Bank(0); - } - } - - //void Mapper072::Write(WORD addr, BYTE data) - public override void Write(ushort addr, byte data) - { - if (data & 0x80) - { - SetPROM_16K_Bank(4, data & 0x0F); - } - else if (data & 0x40) - { - SetVROM_8K_Bank(data & 0x0F); - } - else - { - if (addr >= 0xC100 && addr <= 0xC11F && data == 0x20) - { - //DEBUGOUT( "ADDR:%04X DATA:%02X\n", addr, data ); - DEBUGOUT("SOUND CODE:%02X\n", addr & 0x1F); - - // OSDにするべきか… - if (Config.sound.bExtraSoundEnable) - { - DirectSound.EsfAllStop(); - DirectSound.EsfPlay(ESF_MOETENNIS_00 + (addr & 0x1F)); - } - } - } - } - - - } +{ + public class Mapper072 : Mapper + { + public Mapper072(NES parent) : base(parent) + { + } + + public override void Reset() + { + SetPROM_32K_Bank(0, 1, PROM_8K_SIZE - 2, PROM_8K_SIZE - 1); + + if (VROM_8K_SIZE != 0) + { + SetVROM_8K_Bank(0); + } + } + + //void Mapper072::Write(WORD addr, BYTE data) + public override void Write(ushort addr, byte data) + { + if ((data & 0x80) != 0) + { + SetPROM_16K_Bank(4, data & 0x0F); + } + else if ((data & 0x40) != 0) + { + SetVROM_8K_Bank(data & 0x0F); + } + else + { + if (addr >= 0xC100 && addr <= 0xC11F && data == 0x20) + { + Debuger.Log($"SOUND CODE:{addr & 0x1F:X2}"); + + // OSDにするべきか… + if (Supporter.Config.sound.bExtraSoundEnable) + { + //TODO : 似乎VirtuaNES有直接播放某个音频文件的功能 + //DirectSound.EsfAllStop(); + //DirectSound.EsfPlay(ESF_MOETENNIS_00 + (addr & 0x1F)); + } + } + } + } + + + } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper086.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper086.cs index 8f58d14..1452d92 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper086.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper086.cs @@ -10,62 +10,63 @@ using Codice.CM.Client.Differences; namespace VirtualNes.Core { - public class Mapper086 : Mapper - { - BYTE reg, cnt; - public Mapper086(NES parent) : base(parent) + 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--; - } - } - - - - } + 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 (Supporter.Config.sound.bExtraSoundEnable) + { + //TODO : 似乎VirtuaNES有直接播放某个音频文件的功能 + //DirectSound.EsfAllStop(); + //DirectSound.EsfPlay(ESF_MOEPRO_STRIKE + (data & 0x0F)); + } + } + reg = data; + } + } + + //void Mapper086::VSync() + public override void VSync() + { + if (cnt != 0) + { + cnt--; + } + } + + + + } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper090.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper090.cs index df8aa02..d6fd17d 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper090.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper090.cs @@ -7,476 +7,477 @@ using INT = System.Int32; using BYTE = System.Byte; using System; using Codice.CM.Client.Differences; +using VirtualNes.Core.Debug; 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; - } - - } +{ + 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 (byte 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) + { + Debuger.Log($"RD:{addr:X4}"); + + 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) + { + Debuger.Log($"WR:{addr:X4} {data:X2}"); + + 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; + } + + } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper092.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper092.cs index 3fbb555..37a908a 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper092.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper092.cs @@ -7,68 +7,70 @@ using INT = System.Int32; using BYTE = System.Byte; using System; using Codice.CM.Client.Differences; +using VirtualNes.Core.Debug; 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]); - } - } - } - } - - } +{ + 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 (Supporter.Config.sound.bExtraSoundEnable) + { + //TODO : 似乎VirtuaNES有直接播放某个音频文件的功能 + Debuger.Log($"CODE {data:X2}"); + //DirectSound.EsfAllStop(); + //DirectSound.EsfPlay(ESF_MOEPRO_STRIKE + tbl[data & 0x0F]); + } + } + } + } + + } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper107.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper107.cs index 34e34f4..4a673cc 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper107.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper107.cs @@ -9,9 +9,9 @@ using System; namespace VirtualNes.Core { - public class _MapName : Mapper + public class Mapper107 : Mapper { - public _MapName(NES parent) : base(parent) + public Mapper107(NES parent) : base(parent) { } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper116.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper116.cs index b9d584c..e144883 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper116.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper116.cs @@ -7,6 +7,7 @@ using INT = System.Int32; using BYTE = System.Byte; using System; using Codice.CM.Client.Differences; +using VirtualNes.Core.Debug; namespace VirtualNes.Core { @@ -73,7 +74,7 @@ namespace VirtualNes.Core //void Mapper116::WriteLow(WORD addr, BYTE data) public override void WriteLow(ushort addr, byte data) { - DEBUGOUT("MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr & 0xFFFF, data & 0xFF, nes.GetScanline(), nes.cpu.GetTotalCycles()); + Debuger.Log($"MPRWR A={addr & 0xFFFF:X4} D={data & 0xFF:X2} L={nes.GetScanline(),3} CYC={nes.cpu.GetTotalCycles()}"); if ((addr & 0x4100) == 0x4100) { ExChrSwitch = data; @@ -84,7 +85,7 @@ namespace VirtualNes.Core //void Mapper116::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()); + Debuger.Log($"MPRWR A={addr & 0xFFFF:X4} D={data & 0xFF:X2} L={nes.GetScanline(),3} CYC={nes.cpu.GetTotalCycles()}"); switch (addr & 0xE001) { diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper162.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper162.cs index d33764c..42e5bc7 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper162.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper162.cs @@ -7,125 +7,126 @@ using INT = System.Int32; using BYTE = System.Byte; using System; using Codice.CM.Client.Differences; +using VirtualNes.Core.Debug; namespace VirtualNes.Core -{ - public class Mapper162 : Mapper - { - BYTE reg5000; - BYTE reg5100; - BYTE reg5200; - BYTE reg5300; - public Mapper162(NES parent) : base(parent) - { - } - - public override void Reset() - { - reg5000 = 0; - reg5100 = 0; - reg5200 = 0; - reg5300 = 7; - SetBank_CPU(); - SetBank_PPU(); - } - - //void Mapper162::WriteLow(WORD addr, BYTE data) - public override void WriteLow(ushort addr, byte data) - { - if (addr == 0x5000) - { - reg5000 = data; - SetBank_CPU(); - SetBank_PPU(); - } - else if (addr == 0x5100) - { - reg5100 = data; - SetBank_CPU(); - SetBank_PPU(); - } - else if (addr == 0x5200) - { - reg5200 = data; - SetBank_CPU(); - SetBank_PPU(); - } - else if (addr == 0x5300) - { - reg5300 = data; - } - else if (addr >= 0x6000) - { - CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data; - } - else - { - DEBUGOUT("write to %04x:%02x\n", addr, data); - } - - } - - void SetBank_CPU() - { - BYTE bank = 0; - switch (reg5300) - { - case 4: - bank = (byte)((((reg5000 & 0xF) + ((reg5100 & 3) >> 1)) | ((reg5200 & 1) << 4))); - break; - case 7: - bank = (byte)(((reg5000 & 0xF) | ((reg5200 & 1) << 4))); - break; - } - SetPROM_32K_Bank((byte)bank); - } - - void SetBank_PPU() - { - SetCRAM_8K_Bank(0); - } - - //void Mapper162::HSync(int scanline) - public override void HSync(int scanline) - { - if ((reg5000 & 0x80) != 0 && nes.ppu.IsDispON()) - { - if (scanline < 127) - { - // SetCRAM_4K_Bank(0, 0); - SetCRAM_4K_Bank(4, 0); - } - else if (scanline < 240) - { - // SetCRAM_4K_Bank(0, 1); - SetCRAM_4K_Bank(4, 1); - } - } - } - - - //void Mapper162::SaveState(LPBYTE p) - public override void SaveState(byte[] p) - { - p[0] = reg5000; - p[1] = reg5100; - p[2] = reg5200; - p[3] = reg5300; - } - - //void Mapper162::LoadState(LPBYTE p) - public override void LoadState(byte[] p) - { - reg5000 = p[0]; - reg5100 = p[1]; - reg5200 = p[2]; - reg5300 = p[3]; - } - - public override bool IsStateSave() - { - return true; - } - } +{ + public class Mapper162 : Mapper + { + BYTE reg5000; + BYTE reg5100; + BYTE reg5200; + BYTE reg5300; + public Mapper162(NES parent) : base(parent) + { + } + + public override void Reset() + { + reg5000 = 0; + reg5100 = 0; + reg5200 = 0; + reg5300 = 7; + SetBank_CPU(); + SetBank_PPU(); + } + + //void Mapper162::WriteLow(WORD addr, BYTE data) + public override void WriteLow(ushort addr, byte data) + { + if (addr == 0x5000) + { + reg5000 = data; + SetBank_CPU(); + SetBank_PPU(); + } + else if (addr == 0x5100) + { + reg5100 = data; + SetBank_CPU(); + SetBank_PPU(); + } + else if (addr == 0x5200) + { + reg5200 = data; + SetBank_CPU(); + SetBank_PPU(); + } + else if (addr == 0x5300) + { + reg5300 = data; + } + else if (addr >= 0x6000) + { + CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data; + } + else + { + Debuger.Log($"write to {addr:X4}:{data:X2}"); + } + + } + + void SetBank_CPU() + { + BYTE bank = 0; + switch (reg5300) + { + case 4: + bank = (byte)((((reg5000 & 0xF) + ((reg5100 & 3) >> 1)) | ((reg5200 & 1) << 4))); + break; + case 7: + bank = (byte)(((reg5000 & 0xF) | ((reg5200 & 1) << 4))); + break; + } + SetPROM_32K_Bank((byte)bank); + } + + void SetBank_PPU() + { + SetCRAM_8K_Bank(0); + } + + //void Mapper162::HSync(int scanline) + public override void HSync(int scanline) + { + if ((reg5000 & 0x80) != 0 && nes.ppu.IsDispON()) + { + if (scanline < 127) + { + // SetCRAM_4K_Bank(0, 0); + SetCRAM_4K_Bank(4, 0); + } + else if (scanline < 240) + { + // SetCRAM_4K_Bank(0, 1); + SetCRAM_4K_Bank(4, 1); + } + } + } + + + //void Mapper162::SaveState(LPBYTE p) + public override void SaveState(byte[] p) + { + p[0] = reg5000; + p[1] = reg5100; + p[2] = reg5200; + p[3] = reg5300; + } + + //void Mapper162::LoadState(LPBYTE p) + public override void LoadState(byte[] p) + { + reg5000 = p[0]; + reg5100 = p[1]; + reg5200 = p[2]; + reg5300 = p[3]; + } + + public override bool IsStateSave() + { + return true; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper163.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper163.cs index 042a27c..71dfdba 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper163.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper163.cs @@ -21,7 +21,7 @@ namespace VirtualNes.Core BYTE laststrobe, trigger; BYTE[] reg = new byte[8]; public Mapper163(NES parent) : base(parent) - { + { /* reg[1] = 0xFF; strobe = 1; @@ -36,8 +36,9 @@ namespace VirtualNes.Core if( crc == 0xf52468e7 ) { // San Guo Wu Shuang - Meng Jiang Zhuan (NJ047) (Ch) [dump] rom_type = 1; } - */ - memset(reg, 0, 8); + */ + + MemoryUtility.ZEROMEMORY(reg, reg.Length); laststrobe = 1; SetPROM_32K_Bank((reg[0] << 4) | (reg[1] & 0xF)); //SetPROM_32K_Bank(0); diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper164.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper164.cs index 1395704..2ff24d8 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper164.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper164.cs @@ -7,6 +7,7 @@ using INT = System.Int32; using BYTE = System.Byte; using System; using Codice.CM.Client.Differences; +using VirtualNes.Core.Debug; namespace VirtualNes.Core { @@ -20,13 +21,12 @@ namespace VirtualNes.Core } public override void Reset() - { reg5000 = 0; reg5100 = 0; SetBank_CPU(); SetBank_PPU(); - nes.ppu.SetExtLatchMode(TRUE); + nes.ppu.SetExtLatchMode(true); } //void Mapper164::WriteLow(WORD addr, BYTE data) @@ -51,7 +51,7 @@ namespace VirtualNes.Core } else { - DEBUGOUT("write to %04x:%02x\n", addr, data); + Debuger.Log($"write to {addr:X4}:{data:X2}"); } } @@ -74,11 +74,11 @@ namespace VirtualNes.Core bank += (reg5000 & 0x20) >> 1; SetPROM_16K_Bank(4, bank + @base); SetPROM_16K_Bank(6, @base + 0x1f); - DEBUGOUT("-- normal mode: mode=%d, bank=%d --\n", mode, bank); + Debuger.Log($"-- normal mode: mode={mode}, bank={bank} --"); break; case 1: case 3: /* REG MODE */ - DEBUGOUT("-- reg mode --\n"); + Debuger.Log("-- reg mode --"); break; case 5: /* 32K MODE */ bank = (reg5000 & 0x0f); @@ -91,7 +91,7 @@ namespace VirtualNes.Core SetPROM_16K_Bank(4, bank + @base); bank = (bank & 0x10) + 0x0f; SetPROM_16K_Bank(6, @base + 0x1f); - DEBUGOUT("-- half mode --\n"); + Debuger.Log("-- half mode --"); break; default: break; @@ -116,18 +116,19 @@ namespace VirtualNes.Core { INT loopy_v = nes.ppu.GetPPUADDR(); INT loopy_y = nes.ppu.GetTILEY(); - INT tileofs = (PPUREG[0] & PPU_BGTBL_BIT) << 8; + INT tileofs = (PPUREG[0] & PPU.PPU_BGTBL_BIT) << 8; INT attradr = 0x23C0 + (loopy_v & 0x0C00) + ((loopy_v & 0x0380) >> 4); INT attrsft = (ntbladr & 0x0040) >> 4; - LPBYTE pNTBL = PPU_MEM_BANK[ntbladr >> 10]; + Span pNTBL = PPU_MEM_BANK[ntbladr >> 10]; + INT ntbl_x = ntbladr & 0x001F; INT tileadr; attradr &= 0x3FF; - attr = ((pNTBL[attradr + (ntbl_x >> 2)] >> ((ntbl_x & 2) + attrsft)) & 3) << 2; + attr = (byte)(((pNTBL[attradr + (ntbl_x >> 2)] >> ((ntbl_x & 2) + attrsft)) & 3) << 2); tileadr = tileofs + pNTBL[ntbladr & 0x03FF] * 0x10 + loopy_y; - if (p_mode) + if (p_mode != 0) { tileadr = (tileadr & 0xfff7) | a3; chr_l = chr_h = PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF]; diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper165.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper165.cs index 41119e6..cfc8284 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper165.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper165.cs @@ -41,7 +41,7 @@ namespace VirtualNes.Core we_sram = 0; // Disable - nes->ppu->SetChrLatchMode(TRUE); + nes.ppu.SetChrLatchMode(true); } //void Mapper165::Write(WORD addr, BYTE data) diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper176.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper176.cs index ab3b1dc..758f058 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper176.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper176.cs @@ -7,52 +7,52 @@ using Codice.CM.Client.Differences; using System.Runtime.ConstrainedExecution; namespace VirtualNes.Core -{ - public class Mapper176 : Mapper - { - BYTE prg, chr; - public Mapper176(NES parent) : base(parent) - { - } - - public override void Reset() - { - //prg = ~0; - prg = (~0); - chr = 0; - Sync(); - } - - void Sync() - { - //setprg8r(0x10,0x6000,0); - SetPROM_32K_Bank(prg >> 1); - SetVROM_8K_Bank(chr); - } - - //void Mapper176::WriteLow(WORD addr, BYTE data) - public override void WriteLow(ushort addr, byte data) - { - switch (addr) - { - case 0x5ff1: - prg = data; Sync(); - break; - case 0x5ff2: - chr = data; Sync(); - break; - default: - break; - } - if (addr >= 0x6000) - { - CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data; - } - } - - public override bool IsStateSave() - { - return true; - } - } +{ + public class Mapper176 : Mapper + { + BYTE prg, chr; + public Mapper176(NES parent) : base(parent) + { + } + + public override void Reset() + { + //prg = ~0; + prg = unchecked((byte)(~0)); + chr = 0; + Sync(); + } + + void Sync() + { + //setprg8r(0x10,0x6000,0); + SetPROM_32K_Bank(prg >> 1); + SetVROM_8K_Bank(chr); + } + + //void Mapper176::WriteLow(WORD addr, BYTE data) + public override void WriteLow(ushort addr, byte data) + { + switch (addr) + { + case 0x5ff1: + prg = data; Sync(); + break; + case 0x5ff2: + chr = data; Sync(); + break; + default: + break; + } + if (addr >= 0x6000) + { + CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data; + } + } + + public override bool IsStateSave() + { + return true; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper199.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper199.cs index 0edb84d..43b8daa 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper199.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper199.cs @@ -11,236 +11,236 @@ using Codice.CM.Client.Differences; namespace VirtualNes.Core { public class Mapper199 : Mapper - { - BYTE[] reg = new byte[8]; - BYTE[] prg = new byte[4]; - BYTE[] chr = new byte[8]; - BYTE we_sram; - - BYTE irq_type; - BYTE irq_enable; - BYTE irq_counter; - BYTE irq_latch; - BYTE irq_request; - public Mapper199(NES parent) : base(parent) + { + BYTE[] reg = new byte[8]; + BYTE[] prg = new byte[4]; + BYTE[] chr = new byte[8]; + BYTE we_sram; + + BYTE irq_type; + BYTE irq_enable; + BYTE irq_counter; + BYTE irq_latch; + BYTE irq_request; + public Mapper199(NES parent) : base(parent) { } - public override void Reset() - { - for (INT i = 0; i < 8; i++) - { - reg[i] = 0x00; - chr[i] = (byte)i; - } - prg[0] = 0x00; - prg[1] = 0x01; - prg[2] = 0x3e; - prg[3] = 0x3f; - SetBank_CPU(); - SetBank_PPU(); - - we_sram = 0; - irq_enable = irq_counter = irq_latch = irq_request = 0; - - - uint crcP = nes.rom.GetPROM_CRC(); - uint crcV = nes.rom.GetVROM_CRC(); - - if ((crcP == 0xE80D8741) || (crcV == 0x3846520D)) - {//ÍâÐÇ°ÔÍõµÄ´ó½ - nes.SetRenderMethod( EnumRenderMethod.POST_ALL_RENDER); - } - } - - - //BYTE Mapper199::ReadLow(WORD addr) - public override byte ReadLow(ushort addr) - { - if (addr >= 0x5000 && addr <= 0x5FFF) - { - return XRAM[addr - 0x4000]; - } - else - { - return base.ReadLow(addr); - } - } - - //void Mapper199::WriteLow(WORD addr, BYTE data) - public override void WriteLow(ushort addr, byte data) - { - if (addr >= 0x5000 && addr <= 0x5FFF) - { - XRAM[addr - 0x4000] = data; - } - else - { - base.WriteLow(addr, data); - } - } - - //void Mapper199::Write(WORD addr, BYTE data) - public override void Write(ushort addr, byte data) - { - //DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes.GetScanline(), nes.cpu.GetTotalCycles() ); - - switch (addr & 0xE001) - { - case 0x8000: - reg[0] = data; - SetBank_CPU(); - SetBank_PPU(); - break; - case 0x8001: - reg[1] = data; - - switch (reg[0] & 0x0f) - { - case 0x00: chr[0] = data; SetBank_PPU(); break; - case 0x01: chr[2] = data; SetBank_PPU(); break; - case 0x02: - case 0x03: - case 0x04: - case 0x05: chr[(reg[0] & 0x07) + 2] = data; SetBank_PPU(); break; - case 0x06: - case 0x07: - case 0x08: - case 0x09: prg[(reg[0] & 0x0f) - 6] = data; SetBank_CPU(); break; - case 0x0A: chr[1] = data; SetBank_PPU(); break; - case 0x0B: chr[3] = data; SetBank_PPU(); break; - } - break; - case 0xA000: - reg[2] = data; - //if( !nes.rom.Is4SCREEN() ) - { - 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 0xA001: - reg[3] = data; - break; - case 0xC000: - reg[4] = data; - irq_counter = data; - irq_request = 0; - break; - case 0xC001: - reg[5] = data; - irq_latch = data; - irq_request = 0; - break; - case 0xE000: - reg[6] = data; - irq_enable = 0; - irq_request = 0; - nes.cpu.ClrIRQ(IRQ_MAPPER); - break; - case 0xE001: - reg[7] = data; - irq_enable = 1; - irq_request = 0; - break; - } - - } - - //void Mapper199::HSync(INT scanline) - public override void HSync(int scanline) - { - if ((scanline >= 0 && scanline <= 239)) - { - if (nes.ppu.IsDispON()) - { - if (irq_enable != 0 && irq_request == 0) - { - if (scanline == 0) - { - if (irq_counter != 0) - { - irq_counter--; - } - } - if ((irq_counter--) == 0) - { - irq_request = 0xFF; - irq_counter = irq_latch; - nes.cpu.SetIRQ(IRQ_MAPPER); - } - } - } - } - } - - void SetBank_CPU() - { - SetPROM_8K_Bank(4, prg[0 ^ (reg[0] >> 5 & ~(0 << 1) & 2)]); - SetPROM_8K_Bank(5, prg[1 ^ (reg[0] >> 5 & ~(1 << 1) & 2)]); - SetPROM_8K_Bank(6, prg[2 ^ (reg[0] >> 5 & ~(2 << 1) & 2)]); - SetPROM_8K_Bank(7, prg[3 ^ (reg[0] >> 5 & ~(3 << 1) & 2)]); - } - - void SetBank_PPU() - { - //unsigned int bank = (reg[0] & 0x80) >> 5; - int bank = (reg[0] & 0x80) >> 5; - for (int x = 0; x < 8; x++) - { - if (chr[x] <= 7) - { - SetCRAM_1K_Bank((byte)(x ^ bank), chr[x]); - } - else - { - SetVROM_1K_Bank((byte)(x ^ bank), chr[x]); - } - } - } - - //void Mapper199::SaveState(LPBYTE p) - public override void SaveState(byte[] p) - { - for (INT i = 0; i < 8; i++) - { - p[i] = reg[i]; - p[10 + i] = chr[i]; - } - - p[8] = prg[0]; - p[9] = prg[1]; - p[18] = irq_enable; - p[19] = irq_counter; - p[20] = irq_latch; - p[21] = irq_request; - p[22] = prg[2]; - p[23] = prg[3]; - } - - //void Mapper199::LoadState(LPBYTE p) - public override void LoadState(byte[] p) - { - for (INT i = 0; i < 8; i++) - { - reg[i] = p[i]; - chr[i] = p[10 + i]; - } - prg[0] = p[8]; - prg[1] = p[9]; - irq_enable = p[18]; - irq_counter = p[19]; - irq_latch = p[20]; - irq_request = p[21]; - prg[2] = p[22]; - prg[3] = p[23]; - } - - public override bool IsStateSave() - { - return true; - } - } + public override void Reset() + { + for (INT i = 0; i < 8; i++) + { + reg[i] = 0x00; + chr[i] = (byte)i; + } + prg[0] = 0x00; + prg[1] = 0x01; + prg[2] = 0x3e; + prg[3] = 0x3f; + SetBank_CPU(); + SetBank_PPU(); + + we_sram = 0; + irq_enable = irq_counter = irq_latch = irq_request = 0; + + + uint crcP = nes.rom.GetPROM_CRC(); + uint crcV = nes.rom.GetVROM_CRC(); + + if ((crcP == 0xE80D8741) || (crcV == 0x3846520D)) + {//ÍâÐÇ°ÔÍõµÄ´ó½ + nes.SetRenderMethod(EnumRenderMethod.POST_ALL_RENDER); + } + } + + + //BYTE Mapper199::ReadLow(WORD addr) + public override byte ReadLow(ushort addr) + { + if (addr >= 0x5000 && addr <= 0x5FFF) + { + return XRAM[addr - 0x4000]; + } + else + { + return base.ReadLow(addr); + } + } + + //void Mapper199::WriteLow(WORD addr, BYTE data) + public override void WriteLow(ushort addr, byte data) + { + if (addr >= 0x5000 && addr <= 0x5FFF) + { + XRAM[addr - 0x4000] = data; + } + else + { + base.WriteLow(addr, data); + } + } + + //void Mapper199::Write(WORD addr, BYTE data) + public override void Write(ushort addr, byte data) + { + //DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes.GetScanline(), nes.cpu.GetTotalCycles() ); + + switch (addr & 0xE001) + { + case 0x8000: + reg[0] = data; + SetBank_CPU(); + SetBank_PPU(); + break; + case 0x8001: + reg[1] = data; + + switch (reg[0] & 0x0f) + { + case 0x00: chr[0] = data; SetBank_PPU(); break; + case 0x01: chr[2] = data; SetBank_PPU(); break; + case 0x02: + case 0x03: + case 0x04: + case 0x05: chr[(reg[0] & 0x07) + 2] = data; SetBank_PPU(); break; + case 0x06: + case 0x07: + case 0x08: + case 0x09: prg[(reg[0] & 0x0f) - 6] = data; SetBank_CPU(); break; + case 0x0A: chr[1] = data; SetBank_PPU(); break; + case 0x0B: chr[3] = data; SetBank_PPU(); break; + } + break; + case 0xA000: + reg[2] = data; + //if( !nes.rom.Is4SCREEN() ) + { + 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 0xA001: + reg[3] = data; + break; + case 0xC000: + reg[4] = data; + irq_counter = data; + irq_request = 0; + break; + case 0xC001: + reg[5] = data; + irq_latch = data; + irq_request = 0; + break; + case 0xE000: + reg[6] = data; + irq_enable = 0; + irq_request = 0; + nes.cpu.ClrIRQ(IRQ_MAPPER); + break; + case 0xE001: + reg[7] = data; + irq_enable = 1; + irq_request = 0; + break; + } + + } + + //void Mapper199::HSync(INT scanline) + public override void HSync(int scanline) + { + if ((scanline >= 0 && scanline <= 239)) + { + if (nes.ppu.IsDispON()) + { + if (irq_enable != 0 && irq_request == 0) + { + if (scanline == 0) + { + if (irq_counter != 0) + { + irq_counter--; + } + } + if ((irq_counter--) == 0) + { + irq_request = 0xFF; + irq_counter = irq_latch; + nes.cpu.SetIRQ(IRQ_MAPPER); + } + } + } + } + } + + void SetBank_CPU() + { + SetPROM_8K_Bank(4, prg[0 ^ (reg[0] >> 5 & ~(0 << 1) & 2)]); + SetPROM_8K_Bank(5, prg[1 ^ (reg[0] >> 5 & ~(1 << 1) & 2)]); + SetPROM_8K_Bank(6, prg[2 ^ (reg[0] >> 5 & ~(2 << 1) & 2)]); + SetPROM_8K_Bank(7, prg[3 ^ (reg[0] >> 5 & ~(3 << 1) & 2)]); + } + + void SetBank_PPU() + { + //unsigned int bank = (reg[0] & 0x80) >> 5; + int bank = (reg[0] & 0x80) >> 5; + for (int x = 0; x < 8; x++) + { + if (chr[x] <= 7) + { + SetCRAM_1K_Bank((byte)(x ^ bank), chr[x]); + } + else + { + SetVROM_1K_Bank((byte)(x ^ bank), chr[x]); + } + } + } + + //void Mapper199::SaveState(LPBYTE p) + public override void SaveState(byte[] p) + { + for (INT i = 0; i < 8; i++) + { + p[i] = reg[i]; + p[10 + i] = chr[i]; + } + + p[8] = prg[0]; + p[9] = prg[1]; + p[18] = irq_enable; + p[19] = irq_counter; + p[20] = irq_latch; + p[21] = irq_request; + p[22] = prg[2]; + p[23] = prg[3]; + } + + //void Mapper199::LoadState(LPBYTE p) + public override void LoadState(byte[] p) + { + for (INT i = 0; i < 8; i++) + { + reg[i] = p[i]; + chr[i] = p[10 + i]; + } + prg[0] = p[8]; + prg[1] = p[9]; + irq_enable = p[18]; + irq_counter = p[19]; + irq_latch = p[20]; + irq_request = p[21]; + prg[2] = p[22]; + prg[3] = p[23]; + } + + public override bool IsStateSave() + { + return true; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper225.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper225.cs index c155996..a44ca80 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper225.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Mapper/Mapper225.cs @@ -20,7 +20,7 @@ namespace VirtualNes.Core { SetPROM_32K_Bank(0, 1, 2, 3); - if (VROM_1K_SIZE) + if (VROM_1K_SIZE != 0) { SetVROM_8K_Bank(0); } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs index 39c67ce..77d5675 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs @@ -324,7 +324,7 @@ namespace VirtualNes.Core } } - private int GetIrqType() + internal int GetIrqType() { return nIRQtype; } @@ -1668,6 +1668,16 @@ namespace VirtualNes.Core return NES_scanline; } + internal void SetSAVERAM_SIZE(int size) + { + SAVERAM_SIZE = size; + } + + internal byte GetBarcodeStatus() + { + return m_BarcodeOut; + } + public enum IRQMETHOD { IRQ_HSYNC = 0, IRQ_CLOCK = 1 diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs index ffbeb54..f92f690 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PPU.cs @@ -1,4 +1,6 @@ -namespace VirtualNes.Core +using System; + +namespace VirtualNes.Core { public class PPU { @@ -1125,6 +1127,26 @@ return (MMU.PPUREG[1] & (PPU_BGDISP_BIT | PPU_SPDISP_BIT)) != 0; } + internal void SetExtLatchMode(bool bMode) + { + bExtLatch = bMode; + } + + internal ushort GetPPUADDR() + { + return MMU.loopy_v; + } + + internal ushort GetTILEY() + { + return loopy_y; + } + + internal void SetChrLatchMode(bool bMode) + { + bChrLatch = bMode; + } + public struct Sprite { public byte y diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs index d6cdd26..18607c9 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs @@ -401,6 +401,11 @@ namespace VirtualNes.Core { return path; } + + internal uint GetVROM_CRC() + { + return crcvrom; + } } diff --git a/virtuanessrc097-master/NES/Nes.cpp b/virtuanessrc097-master/NES/Nes.cpp index 5da99b579f5ef94ec9bb147364372cf61f07b787..a3e1ee33e03f1a49829a19c8e9090ed75f928a77 100644 GIT binary patch delta 30 mcmcb!k>|!no(&56lRr4HOxC)p(Hx-P9-z;-JwTtS=OqBn9t>pw delta 34 qcmcbyk>}1vo(&56lMP;SOwQ33nH->P(43*)o}tgUJwu