diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Bandai.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Bandai.cs index 0eb3ef7..2aa82d9 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Bandai.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Bandai.cs @@ -1,143 +1,140 @@ -using System.IO; - -namespace MyNes.Core +using System.IO; + +namespace MyNes.Core; + +internal abstract class Bandai : Board { + private bool irq_enable; + private int irq_counter; - internal abstract class Bandai : Board - { - private bool irq_enable; + private Eprom eprom; - private int irq_counter; + internal override void Initialize(IRom rom) + { + base.Initialize(rom); + if (base.BoardType.ToLower().Contains("24c01")) + { + eprom = new Eprom(128); + } + else + { + eprom = new Eprom((base.MapperNumber == 16) ? 256 : 128); + } + } - private Eprom eprom; + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + irq_enable = false; + irq_counter = 0; + eprom.HardReset(); + } - internal override void Initialize(IRom rom) - { - base.Initialize(rom); - if (base.BoardType.ToLower().Contains("24c01")) - { - eprom = new Eprom(128); - } - else - { - eprom = new Eprom((base.MapperNumber == 16) ? 256 : 128); - } - } + internal override void WriteSRM(ref ushort address, ref byte data) + { + WritePRG(ref address, ref data); + } - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - irq_enable = false; - irq_counter = 0; - eprom.HardReset(); - } + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF) + { + case 0: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 1: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 2: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 3: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 4: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 5: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 6: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 7: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 8: + Switch16KPRG(data, PRGArea.Area8000); + break; + case 9: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 10: + irq_enable = (data & 1) == 1; + NesEmu.IRQFlags &= -9; + break; + case 11: + irq_counter = (irq_counter & 0xFF00) | data; + break; + case 12: + irq_counter = (irq_counter & 0xFF) | (data << 8); + break; + case 13: + eprom.Write(address, data); + break; + } + } - internal override void WriteSRM(ref ushort address, ref byte data) - { - WritePRG(ref address, ref data); - } + internal override void ReadSRM(ref ushort address, out byte value) + { + value = eprom.Read(address); + } - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF) - { - case 0: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 1: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 2: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 3: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 4: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 5: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 6: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 7: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 8: - Switch16KPRG(data, PRGArea.Area8000); - break; - case 9: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 10: - irq_enable = (data & 1) == 1; - NesEmu.IRQFlags &= -9; - break; - case 11: - irq_counter = (irq_counter & 0xFF00) | data; - break; - case 12: - irq_counter = (irq_counter & 0xFF) | (data << 8); - break; - case 13: - eprom.Write(address, data); - break; - } - } + internal override void OnCPUClock() + { + if (irq_enable) + { + irq_counter--; + if (irq_counter == 0) + { + NesEmu.IRQFlags |= 8; + } + if (irq_counter < 0) + { + irq_counter = 65535; + } + } + } - internal override void ReadSRM(ref ushort address, out byte value) - { - value = eprom.Read(address); - } + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_enable); + stream.Write(irq_counter); + eprom.SaveState(stream); + } - internal override void OnCPUClock() - { - if (irq_enable) - { - irq_counter--; - if (irq_counter == 0) - { - NesEmu.IRQFlags |= 8; - } - if (irq_counter < 0) - { - irq_counter = 65535; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_enable); - stream.Write(irq_counter); - eprom.SaveState(stream); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_enable = stream.ReadBoolean(); - irq_counter = stream.ReadInt32(); - eprom.LoadState(stream); - } - } -} + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_enable = stream.ReadBoolean(); + irq_counter = stream.ReadInt32(); + eprom.LoadState(stream); + } +} diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/BankInfo.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/BankInfo.cs index 3adbcac..0d7ce86 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/BankInfo.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/BankInfo.cs @@ -1,29 +1,26 @@ -namespace MyNes.Core +namespace MyNes.Core; + +internal struct BankInfo { + public bool IsRAM; + public bool Enabled; - internal struct BankInfo - { - public bool IsRAM; + public bool Writable; - public bool Enabled; + public bool IsBattery; - public bool Writable; + public string ID; - public bool IsBattery; + public byte[] DATA; - public string ID; - - public byte[] DATA; - - public BankInfo(string ID, bool IsRAM, bool Writable, bool Enabled, bool IsBattery, byte[] DATA) - { - this.ID = ID; - this.IsRAM = IsRAM; - this.Writable = Writable; - this.Enabled = Enabled; - this.DATA = DATA; - this.IsBattery = IsBattery; - } - } -} + public BankInfo(string ID, bool IsRAM, bool Writable, bool Enabled, bool IsBattery, byte[] DATA) + { + this.ID = ID; + this.IsRAM = IsRAM; + this.Writable = Writable; + this.Enabled = Enabled; + this.DATA = DATA; + this.IsBattery = IsBattery; + } +} diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/BankInfoSorter.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/BankInfoSorter.cs index c0c8fbd..a19fc3d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/BankInfoSorter.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/BankInfoSorter.cs @@ -1,16 +1,15 @@ -using System.Collections.Generic; - -namespace MyNes.Core +using System.Collections.Generic; + +namespace MyNes.Core; + +internal class BankInfoSorter : IComparer { - internal class BankInfoSorter : IComparer - { - public int Compare(BankInfo x, BankInfo y) - { - int result = 0; - int result2 = 0; - int.TryParse(x.ID, out result); - int.TryParse(y.ID, out result2); - return result2 - result; - } - } -} + public int Compare(BankInfo x, BankInfo y) + { + int result = 0; + int result2 = 0; + int.TryParse(x.ID, out result); + int.TryParse(y.ID, out result2); + return result2 - result; + } +} diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/BlankJoypad.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/BlankJoypad.cs index 40de415..96c26f1 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/BlankJoypad.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/BlankJoypad.cs @@ -1,9 +1,8 @@ -namespace MyNes.Core +namespace MyNes.Core; + +internal class BlankJoypad : IJoypadConnecter { - internal class BlankJoypad : IJoypadConnecter - { - public override void Update() - { - } - } -} + public override void Update() + { + } +} diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/BlankShortuctsHandler.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/BlankShortuctsHandler.cs index 3280702..401a5ae 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/BlankShortuctsHandler.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/BlankShortuctsHandler.cs @@ -1,10 +1,8 @@ -namespace MyNes.Core -{ +namespace MyNes.Core; - internal class BlankShortuctsHandler : IShortcutsHandler - { - public void Update() - { - } - } -} +internal class BlankShortuctsHandler : IShortcutsHandler +{ + public void Update() + { + } +} diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Board.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Board.cs index 95c0f95..f9bada1 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Board.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Board.cs @@ -1,1117 +1,1116 @@ -using System; -using System.Collections.Generic; -using System.IO; - -namespace MyNes.Core -{ - internal abstract class Board - { - protected byte[][] PRG_RAM; - - protected bool[] PRG_RAM_ENABLED; - - protected bool[] PRG_RAM_WRITABLE; - - protected bool[] PRG_RAM_BATTERY; - - protected byte[][] PRG_ROM; - - protected int PRG_RAM_08KB_DEFAULT_BLK_Count; - - internal int PRG_ROM_04KB_Count; - - protected int PRG_ROM_08KB_Count; - - protected int PRG_ROM_16KB_Count; - - protected int PRG_ROM_32KB_Count; - - protected int PRG_ROM_04KB_Mask; - - protected int PRG_ROM_08KB_Mask; - - protected int PRG_ROM_16KB_Mask; - - protected int PRG_ROM_32KB_Mask; - - internal int PRG_RAM_04KB_Count; - - protected int PRG_RAM_08KB_Count; - - protected int PRG_RAM_16KB_Count; - - protected int PRG_RAM_32KB_Count; - - protected int PRG_RAM_04KB_Mask; - - protected int PRG_RAM_08KB_Mask; - - protected int PRG_RAM_16KB_Mask; - - protected int PRG_RAM_32KB_Mask; - - protected bool[] PRG_AREA_BLK_RAM; - - protected int[] PRG_AREA_BLK_INDEX; - - protected int PRG_TMP_INDX; - - protected int PRG_TMP_AREA; - - protected byte[][] CHR_RAM; - - protected bool[] CHR_RAM_ENABLED; - - protected bool[] CHR_RAM_WRITABLE; - - protected bool[] CHR_RAM_BATTERY; - - protected byte[][] CHR_ROM; - - protected bool[] CHR_AREA_BLK_RAM; - - protected int[] CHR_AREA_BLK_INDEX; - - protected int CHR_TMP_INDX; - - protected int CHR_TMP_AREA; - - protected int CHR_ROM_01KB_DEFAULT_BLK_Count; - - internal int CHR_ROM_01KB_Count; - - protected int CHR_ROM_02KB_Count; - - protected int CHR_ROM_04KB_Count; - - protected int CHR_ROM_08KB_Count; - - internal int CHR_ROM_01KB_Mask; - - protected int CHR_ROM_02KB_Mask; - - protected int CHR_ROM_04KB_Mask; - - protected int CHR_ROM_08KB_Mask; - - internal int CHR_RAM_01KB_Count; - - protected int CHR_RAM_02KB_Count; - - protected int CHR_RAM_04KB_Count; - - protected int CHR_RAM_08KB_Count; - - internal int CHR_RAM_01KB_Mask; - - protected int CHR_RAM_02KB_Mask; - - protected int CHR_RAM_04KB_Mask; - - protected int CHR_RAM_08KB_Mask; - - protected byte[][] NMT_RAM; - - internal int[] NMT_AREA_BLK_INDEX; - - protected int NMT_TMP_INDX; - - protected int NMT_TMP_AREA; - - internal Mirroring NMT_DEFAULT_MIRROR; - - internal string SHA1 = ""; - - internal string CRC = ""; - - internal bool IsGameFoundOnDB; - - internal NesCartDatabaseGameInfo GameInfo; - - internal NesCartDatabaseCartridgeInfo GameCartInfo; - - internal bool SRAMSaveRequired; - - protected bool enabled_ppuA12ToggleTimer; - - protected bool ppuA12TogglesOnRaisingEdge; - - protected int old_vram_address; - - protected int new_vram_address; - - protected int ppu_cycles_timer; - - internal bool enable_external_sound; - - internal bool IsGameGenieActive; - - internal GameGenieCode[] GameGenieCodes; - - internal string BoardType { get; private set; } - - internal string BoardPCB { get; private set; } - - internal List Chips { get; private set; } - - internal string Name { get; set; } - - internal int MapperNumber { get; set; } - - internal bool HasIssues { get; set; } - - internal virtual string Issues { get; set; } - - public Board() - { - MapperNumber = -1; - PRG_RAM_08KB_DEFAULT_BLK_Count = 1; - CHR_ROM_01KB_DEFAULT_BLK_Count = 8; - LoadAttrs(); - } - - internal virtual void Initialize(IRom rom) - { - SHA1 = rom.SHA1; - SRAMSaveRequired = false; - IsGameGenieActive = false; - BoardType = "N/A"; - BoardPCB = "N/A"; - Chips = new List(); - if (NesCartDatabase.Ready) - { - Tracer.WriteLine("Looking for rom in the database .."); - GameInfo = NesCartDatabase.Find(SHA1, out IsGameFoundOnDB); - if (GameInfo.Cartridges != null) - { - foreach (NesCartDatabaseCartridgeInfo cartridge in GameInfo.Cartridges) - { - if (cartridge.SHA1.ToLower() == SHA1.ToLower()) - { - GameCartInfo = cartridge; - break; - } - } - } - if (IsGameFoundOnDB) - { - Tracer.WriteInformation("Game found in Database !!"); - Tracer.WriteLine("> Game name: " + GameInfo.Game_Name); - Tracer.WriteLine("> Game alt name: " + GameInfo.Game_AltName); - BoardType = GameCartInfo.Board_Type; - Tracer.WriteLine("> Board Type: " + BoardType); - BoardPCB = GameCartInfo.Board_Pcb; - Tracer.WriteLine("> Board Pcb: " + BoardPCB); - if (GameCartInfo.chip_type != null) - { - for (int i = 0; i < GameCartInfo.chip_type.Count; i++) - { - Console.WriteLine($"> CHIP {(i + 1).ToString()}: {GameCartInfo.chip_type[i]}"); - Chips.Add(GameCartInfo.chip_type[i]); - } - } - } - else - { - Tracer.WriteWarning("Game is not found in database ."); - } - } - Tracer.WriteLine("Initializing the board (Mapper # " + MapperNumber + ") ...."); - Tracer.WriteLine("Loading PRG ROM ..."); - PRG_AREA_BLK_RAM = new bool[16]; - PRG_AREA_BLK_INDEX = new int[16]; - PRG_ROM = new byte[0][]; - int num = 0; - for (int j = 0; j < rom.PRG.Length; j += 4096) - { - Array.Resize(ref PRG_ROM, PRG_ROM.GetLength(0) + 1); - PRG_ROM[num] = new byte[4096]; - for (int k = 0; k < 4096; k++) - { - PRG_ROM[num][k] = rom.PRG[j + k]; - } - num++; - } - PRG_ROM_04KB_Count = PRG_ROM.GetLength(0); - PRG_ROM_04KB_Mask = PRG_ROM_04KB_Count - 1; - PRG_ROM_08KB_Count = PRG_ROM_04KB_Count / 2; - PRG_ROM_08KB_Mask = PRG_ROM_08KB_Count - 1; - PRG_ROM_16KB_Count = PRG_ROM_04KB_Count / 4; - PRG_ROM_16KB_Mask = PRG_ROM_16KB_Count - 1; - PRG_ROM_32KB_Count = PRG_ROM_04KB_Count / 8; - PRG_ROM_32KB_Mask = PRG_ROM_32KB_Count - 1; - Tracer.WriteLine("PRG ROM loaded successfully."); - Tracer.WriteLine("PRG ROM Size = " + PRG_ROM_04KB_Count * 4 + "KB"); - Tracer.WriteLine("Loading PRG RAM ..."); - SRAMBankInfo[] pRGRAM8KCountFromDB = GetPRGRAM8KCountFromDB(); - PRG_RAM = new byte[0][]; - PRG_RAM_BATTERY = new bool[0]; - PRG_RAM_ENABLED = new bool[0]; - PRG_RAM_WRITABLE = new bool[0]; - SRAMBankInfo[] array = pRGRAM8KCountFromDB; - for (int l = 0; l < array.Length; l++) - { - SRAMBankInfo sRAMBankInfo = array[l]; - if (sRAMBankInfo.BATTERY) - { - SRAMSaveRequired = true; - } - int result = 0; - int.TryParse(sRAMBankInfo.SIZE.Replace("k", ""), out result); - if (result > 0) - { - int num2 = result / 2; - for (int m = 0; m < num2; m++) - { - Array.Resize(ref PRG_RAM_BATTERY, PRG_RAM_BATTERY.Length + 1); - Array.Resize(ref PRG_RAM_ENABLED, PRG_RAM_ENABLED.Length + 1); - Array.Resize(ref PRG_RAM_WRITABLE, PRG_RAM_WRITABLE.Length + 1); - Array.Resize(ref PRG_RAM, PRG_RAM.GetLength(0) + 1); - PRG_RAM[PRG_RAM.GetLength(0) - 1] = new byte[4096]; - PRG_RAM_BATTERY[PRG_RAM_BATTERY.Length - 1] = sRAMBankInfo.BATTERY; - PRG_RAM_ENABLED[PRG_RAM_ENABLED.Length - 1] = true; - PRG_RAM_WRITABLE[PRG_RAM_WRITABLE.Length - 1] = true; - } - } - } - PRG_RAM_04KB_Count = PRG_RAM.GetLength(0); - PRG_RAM_04KB_Mask = PRG_RAM_04KB_Count - 1; - PRG_RAM_08KB_Count = PRG_RAM_04KB_Count / 2; - PRG_RAM_08KB_Mask = PRG_RAM_08KB_Count - 1; - PRG_RAM_16KB_Count = PRG_RAM_04KB_Count / 4; - PRG_RAM_16KB_Mask = PRG_RAM_16KB_Count - 1; - PRG_RAM_32KB_Count = PRG_RAM_04KB_Count / 8; - PRG_RAM_32KB_Mask = PRG_RAM_32KB_Count - 1; - Tracer.WriteLine("PRG RAM loaded successfully."); - Tracer.WriteLine("PRG RAM Size = " + PRG_RAM_04KB_Count * 4 + "KB"); - if (rom.HasTrainer) - { - rom.Trainer.CopyTo(PRG_RAM[3], 0); - } - Tracer.WriteLine("Loading CHR ROM ..."); - CHR_ROM = new byte[0][]; - CHR_AREA_BLK_RAM = new bool[8]; - CHR_AREA_BLK_INDEX = new int[8]; - num = 0; - for (int n = 0; n < rom.CHR.Length; n += 1024) - { - Array.Resize(ref CHR_ROM, CHR_ROM.GetLength(0) + 1); - CHR_ROM[num] = new byte[1024]; - for (int num3 = 0; num3 < 1024; num3++) - { - CHR_ROM[num][num3] = rom.CHR[n + num3]; - } - num++; - } - CHR_ROM_01KB_Count = CHR_ROM.GetLength(0); - CHR_ROM_01KB_Mask = CHR_ROM_01KB_Count - 1; - CHR_ROM_02KB_Count = CHR_ROM_01KB_Count / 2; - CHR_ROM_02KB_Mask = CHR_ROM_02KB_Count - 1; - CHR_ROM_04KB_Count = CHR_ROM_01KB_Count / 4; - CHR_ROM_04KB_Mask = CHR_ROM_04KB_Count - 1; - CHR_ROM_08KB_Count = CHR_ROM_01KB_Count / 8; - CHR_ROM_08KB_Mask = CHR_ROM_08KB_Count - 1; - Tracer.WriteLine("CHR ROM loaded successfully."); - Tracer.WriteLine("CHR ROM Size = " + CHR_ROM_01KB_Count + "KB"); - Tracer.WriteLine("Loading CHR RAM ..."); - int cHRRAM1KCountFromDB = GetCHRRAM1KCountFromDB(); - CHR_RAM = new byte[0][]; - CHR_RAM_BATTERY = new bool[cHRRAM1KCountFromDB]; - CHR_RAM_ENABLED = new bool[cHRRAM1KCountFromDB]; - CHR_RAM_WRITABLE = new bool[cHRRAM1KCountFromDB]; - for (int num4 = 0; num4 < cHRRAM1KCountFromDB; num4++) - { - Array.Resize(ref CHR_RAM, CHR_RAM.GetLength(0) + 1); - CHR_RAM[num4] = new byte[1024]; - CHR_RAM_BATTERY[num4] = false; - CHR_RAM_ENABLED[num4] = true; - CHR_RAM_WRITABLE[num4] = true; - } - CHR_RAM_01KB_Count = CHR_RAM.GetLength(0); - CHR_RAM_01KB_Mask = CHR_RAM_01KB_Count - 1; - CHR_RAM_02KB_Count = CHR_RAM_01KB_Count / 2; - CHR_RAM_02KB_Mask = CHR_RAM_02KB_Count - 1; - CHR_RAM_04KB_Count = CHR_RAM_01KB_Count / 4; - CHR_RAM_04KB_Mask = CHR_RAM_04KB_Count - 1; - CHR_RAM_08KB_Count = CHR_RAM_01KB_Count / 8; - CHR_RAM_08KB_Mask = CHR_RAM_08KB_Count - 1; - Tracer.WriteLine("CHR RAM loaded successfully."); - Tracer.WriteLine("CHR RAM Size = " + CHR_RAM_01KB_Count + "KB"); - Tracer.WriteLine("Loading Nametables ..."); - NMT_AREA_BLK_INDEX = new int[4]; - NMT_RAM = new byte[0][]; - for (int num5 = 0; num5 < 4; num5++) - { - Array.Resize(ref NMT_RAM, NMT_RAM.GetLength(0) + 1); - NMT_RAM[num5] = new byte[1024]; - } - NMT_DEFAULT_MIRROR = rom.Mirroring; - Tracer.WriteLine("Mirroring set to " + NMT_DEFAULT_MIRROR); - Tracer.WriteLine("Board (Mapper # " + MapperNumber + ") initialized successfully."); - } - - internal virtual void HardReset() - { - Tracer.WriteLine("Hard reset board (Mapper # " + MapperNumber + ") ...."); - Tracer.WriteLine("Switching 16KB PRG RAM at 0x4000 - 0x7000"); - Toggle16KPRG_RAM(ram: true, PRGArea.Area4000); - Switch16KPRG(0, PRGArea.Area4000); - Tracer.WriteLine("Switching 32KB PRG ROM at 0x8000 - 0xF000"); - Toggle32KPRG_RAM(ram: false, PRGArea.Area8000); - Switch32KPRG(0, PRGArea.Area8000); - Tracer.WriteLine("Switching 8KB CHR " + ((CHR_ROM_01KB_Count == 0) ? "RAM" : "ROM") + " at 0x0000 - 0x1000"); - Toggle08KCHR_RAM(CHR_ROM_01KB_Count == 0); - Switch08KCHR(0); - Tracer.WriteLine("Switching to mirroring: " + NMT_DEFAULT_MIRROR); - Switch01KNMTFromMirroring(NMT_DEFAULT_MIRROR); - Tracer.WriteLine("Hard reset board (Mapper # " + MapperNumber + ") is done successfully."); - } - - internal virtual void SoftReset() - { - } - - protected virtual void LoadAttrs() - { - enable_external_sound = false; - Attribute[] customAttributes = Attribute.GetCustomAttributes(GetType()); - foreach (Attribute attribute in customAttributes) - { - if (attribute.GetType() == typeof(BoardInfoAttribute)) - { - BoardInfoAttribute boardInfoAttribute = (BoardInfoAttribute)attribute; - Name = boardInfoAttribute.Name; - MapperNumber = boardInfoAttribute.Mapper; - PRG_RAM_08KB_DEFAULT_BLK_Count = boardInfoAttribute.DefaultPRG_RAM_8KB_BanksCount; - CHR_ROM_01KB_DEFAULT_BLK_Count = boardInfoAttribute.DefaultCHR_RAM_1KB_BanksCount; - enabled_ppuA12ToggleTimer = boardInfoAttribute.Enabled_ppuA12ToggleTimer; - ppuA12TogglesOnRaisingEdge = boardInfoAttribute.PPUA12TogglesOnRaisingEdge; - } - else if (attribute.GetType() == typeof(WithExternalSoundAttribute)) - { - enable_external_sound = true; - } - else if (attribute.GetType() == typeof(HassIssuesAttribute)) - { - HasIssues = true; - } - } - } - - protected SRAMBankInfo[] GetPRGRAM8KCountFromDB() - { - Tracer.WriteLine("Retrieving PRG RAM information from database ...."); - List list = new List(); - if (IsGameFoundOnDB) - { - if (GameCartInfo.WRAMBanks.Count > 0) - { - foreach (SRAMBankInfo wRAMBank in GameCartInfo.WRAMBanks) - { - list.Add(wRAMBank); - } - } - else - { - Tracer.WriteLine("This game has no PRG RAM !"); - Tracer.WriteWarning("> Adding 8K x " + PRG_RAM_08KB_DEFAULT_BLK_Count + " PRG RAM BANKS to avoid exceptions."); - SRAMBankInfo item = new SRAMBankInfo(0, PRG_RAM_08KB_DEFAULT_BLK_Count * 8 + "k", BATTERY: true); - list.Add(item); - } - } - else - { - Tracer.WriteWarning("Could't find this game in database .... Adding 8K x " + PRG_RAM_08KB_DEFAULT_BLK_Count + " PRG RAM BANKS to avoid exceptions."); - SRAMBankInfo item2 = new SRAMBankInfo(0, PRG_RAM_08KB_DEFAULT_BLK_Count * 8 + "k", BATTERY: true); - list.Add(item2); - } - return list.ToArray(); - } - - protected int GetCHRRAM1KCountFromDB() - { - int num = 0; - Tracer.WriteLine("Retrieving CHR RAM information from database ...."); - if (IsGameFoundOnDB) - { - bool flag = false; - if (GameCartInfo.VRAM_sizes != null) - { - Tracer.WriteLine("Using database to initialize CHR RAM ....."); - foreach (string vRAM_size in GameCartInfo.VRAM_sizes) - { - int result = 0; - if (int.TryParse(vRAM_size.Replace("k", ""), out result)) - { - Tracer.WriteLine(">CHR RAM CHIP SIZE " + vRAM_size + " KB added"); - num += result; - if (num > 0) - { - flag = true; - } - } - } - } - if (!flag) - { - Tracer.WriteLine("Game not found in database to initialize CHR RAM; CHR RAM size set to " + CHR_ROM_01KB_DEFAULT_BLK_Count + " KB"); - num = CHR_ROM_01KB_DEFAULT_BLK_Count; - } - } - else - { - Tracer.WriteWarning("Game not found in database to initialize CHR RAM; CHR RAM size set to " + CHR_ROM_01KB_DEFAULT_BLK_Count + " KB"); - num = CHR_ROM_01KB_DEFAULT_BLK_Count; - } - return num; - } - - internal virtual void WriteEX(ref ushort addr, ref byte val) - { - PRG_TMP_AREA = (addr >> 12) & 0xF; - if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; - if (PRG_RAM_ENABLED[PRG_TMP_INDX] && PRG_RAM_WRITABLE[PRG_TMP_INDX]) - { - PRG_RAM[PRG_TMP_INDX][addr & 0xFFF] = val; - } - } - } - - internal virtual void WriteSRM(ref ushort addr, ref byte val) - { - PRG_TMP_AREA = (addr >> 12) & 0xF; - if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; - if (PRG_RAM_ENABLED[PRG_TMP_INDX] && PRG_RAM_WRITABLE[PRG_TMP_INDX]) - { - PRG_RAM[PRG_TMP_INDX][addr & 0xFFF] = val; - } - } - } - - internal virtual void WritePRG(ref ushort addr, ref byte val) - { - PRG_TMP_AREA = (addr >> 12) & 0xF; - if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; - if (PRG_RAM_ENABLED[PRG_TMP_INDX] && PRG_RAM_WRITABLE[PRG_TMP_INDX]) - { - PRG_RAM[PRG_TMP_INDX][addr & 0xFFF] = val; - } - } - } - - internal virtual void ReadEX(ref ushort addr, out byte val) - { - PRG_TMP_AREA = (addr >> 12) & 0xF; - if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; - if (PRG_RAM_ENABLED[PRG_TMP_INDX]) - { - val = PRG_RAM[PRG_TMP_INDX][addr & 0xFFF]; - } - else - { - val = 0; - } - } - else - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_ROM_04KB_Mask; - val = PRG_ROM[PRG_TMP_INDX][addr & 0xFFF]; - } - } - - internal virtual void ReadSRM(ref ushort addr, out byte val) - { - PRG_TMP_AREA = (addr >> 12) & 0xF; - if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; - if (PRG_RAM_ENABLED[PRG_TMP_INDX]) - { - val = PRG_RAM[PRG_TMP_INDX][addr & 0xFFF]; - } - else - { - val = 0; - } - } - else - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_ROM_04KB_Mask; - val = PRG_ROM[PRG_TMP_INDX][addr & 0xFFF]; - } - } - - internal virtual void ReadPRG(ref ushort addr, out byte val) - { - PRG_TMP_AREA = (addr >> 12) & 0xF; - if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; - if (PRG_RAM_ENABLED[PRG_TMP_INDX]) - { - val = PRG_RAM[PRG_TMP_INDX][addr & 0xFFF]; - } - else - { - val = 0; - } - } - else - { - PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_ROM_04KB_Mask; - val = PRG_ROM[PRG_TMP_INDX][addr & 0xFFF]; - } - if (!IsGameGenieActive) - { - return; - } - GameGenieCode[] gameGenieCodes = GameGenieCodes; - for (int i = 0; i < gameGenieCodes.Length; i++) - { - GameGenieCode gameGenieCode = gameGenieCodes[i]; - if (!gameGenieCode.Enabled || gameGenieCode.Address != addr) - { - continue; - } - if (gameGenieCode.IsCompare) - { - if (gameGenieCode.Compare == val) - { - val = gameGenieCode.Value; - } - } - else - { - val = gameGenieCode.Value; - } - break; - } - } - - internal virtual void WriteCHR(ref ushort addr, ref byte val) - { - CHR_TMP_AREA = (addr >> 10) & 7; - if (CHR_AREA_BLK_RAM[CHR_TMP_AREA]) - { - CHR_TMP_INDX = CHR_AREA_BLK_INDEX[CHR_TMP_AREA] & CHR_RAM_01KB_Mask; - if (CHR_RAM_ENABLED[CHR_TMP_INDX] && CHR_RAM_WRITABLE[CHR_TMP_INDX]) - { - CHR_RAM[CHR_TMP_INDX][addr & 0x3FF] = val; - } - } - } - - internal virtual void ReadCHR(ref ushort addr, out byte val) - { - CHR_TMP_AREA = (addr >> 10) & 7; - CHR_TMP_INDX = CHR_AREA_BLK_INDEX[CHR_TMP_AREA]; - if (CHR_AREA_BLK_RAM[CHR_TMP_AREA]) - { - CHR_TMP_INDX &= CHR_RAM_01KB_Mask; - if (CHR_RAM_ENABLED[CHR_TMP_INDX]) - { - val = CHR_RAM[CHR_TMP_INDX][addr & 0x3FF]; - } - else - { - val = 0; - } - } - else - { - CHR_TMP_INDX &= CHR_ROM_01KB_Mask; - val = CHR_ROM[CHR_TMP_INDX][addr & 0x3FF]; - } - } - - internal virtual void WriteNMT(ref ushort addr, ref byte val) - { - NMT_TMP_AREA = (addr >> 10) & 3; - NMT_TMP_INDX = NMT_AREA_BLK_INDEX[NMT_TMP_AREA]; - NMT_RAM[NMT_TMP_INDX][addr & 0x3FF] = val; - } - - internal virtual void ReadNMT(ref ushort addr, out byte val) - { - NMT_TMP_AREA = (addr >> 10) & 3; - NMT_TMP_INDX = NMT_AREA_BLK_INDEX[NMT_TMP_AREA]; - val = NMT_RAM[NMT_TMP_INDX][addr & 0x3FF]; - } - - protected void Switch04KPRG(int index, PRGArea area) - { - PRG_AREA_BLK_INDEX[(uint)area] = index; - } - - protected void Switch08KPRG(int index, PRGArea area) - { - index *= 2; - PRG_AREA_BLK_INDEX[(uint)area] = index; - PRG_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; - } - - protected void Switch16KPRG(int index, PRGArea area) - { - index *= 4; - PRG_AREA_BLK_INDEX[(uint)area] = index; - PRG_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; - PRG_AREA_BLK_INDEX[(uint)(area + 2)] = index + 2; - PRG_AREA_BLK_INDEX[(uint)(area + 3)] = index + 3; - } - - protected void Switch32KPRG(int index, PRGArea area) - { - index *= 8; - PRG_AREA_BLK_INDEX[(uint)area] = index; - PRG_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; - PRG_AREA_BLK_INDEX[(uint)(area + 2)] = index + 2; - PRG_AREA_BLK_INDEX[(uint)(area + 3)] = index + 3; - PRG_AREA_BLK_INDEX[(uint)(area + 4)] = index + 4; - PRG_AREA_BLK_INDEX[(uint)(area + 5)] = index + 5; - PRG_AREA_BLK_INDEX[(uint)(area + 6)] = index + 6; - PRG_AREA_BLK_INDEX[(uint)(area + 7)] = index + 7; - } - - protected void Toggle04KPRG_RAM(bool ram, PRGArea area) - { - PRG_AREA_BLK_RAM[(uint)area] = ram; - } - - protected void Toggle08KPRG_RAM(bool ram, PRGArea area) - { - PRG_AREA_BLK_RAM[(uint)area] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 1)] = ram; - } - - protected void Toggle16KPRG_RAM(bool ram, PRGArea area) - { - PRG_AREA_BLK_RAM[(uint)area] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 1)] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 2)] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 3)] = ram; - } - - protected void Toggle32KPRG_RAM(bool ram, PRGArea area) - { - PRG_AREA_BLK_RAM[(uint)area] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 1)] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 2)] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 3)] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 4)] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 5)] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 6)] = ram; - PRG_AREA_BLK_RAM[(uint)(area + 7)] = ram; - } - - protected void TogglePRGRAMEnable(bool enable) - { - for (int i = 0; i < PRG_RAM_ENABLED.Length; i++) - { - PRG_RAM_ENABLED[i] = enable; - } - } - - protected void TogglePRGRAMWritableEnable(bool enable) - { - for (int i = 0; i < PRG_RAM_WRITABLE.Length; i++) - { - PRG_RAM_WRITABLE[i] = enable; - } - } - - protected void Toggle04KPRG_RAM_Enabled(bool enable, int index) - { - PRG_RAM_ENABLED[index] = enable; - } - - protected void Toggle04KPRG_RAM_Writable(bool enable, int index) - { - PRG_RAM_WRITABLE[index] = enable; - } - - protected void Toggle04KPRG_RAM_Battery(bool enable, int index) - { - PRG_RAM_BATTERY[index] = enable; - } - - protected void Switch01KCHR(int index, CHRArea area) - { - CHR_AREA_BLK_INDEX[(uint)area] = index; - } - - protected void Switch02KCHR(int index, CHRArea area) - { - index *= 2; - CHR_AREA_BLK_INDEX[(uint)area] = index; - CHR_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; - } - - protected void Switch04KCHR(int index, CHRArea area) - { - index *= 4; - CHR_AREA_BLK_INDEX[(uint)area] = index; - CHR_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; - CHR_AREA_BLK_INDEX[(uint)(area + 2)] = index + 2; - CHR_AREA_BLK_INDEX[(uint)(area + 3)] = index + 3; - } - - protected void Switch08KCHR(int index) - { - index *= 8; - CHR_AREA_BLK_INDEX[0] = index; - CHR_AREA_BLK_INDEX[1] = index + 1; - CHR_AREA_BLK_INDEX[2] = index + 2; - CHR_AREA_BLK_INDEX[3] = index + 3; - CHR_AREA_BLK_INDEX[4] = index + 4; - CHR_AREA_BLK_INDEX[5] = index + 5; - CHR_AREA_BLK_INDEX[6] = index + 6; - CHR_AREA_BLK_INDEX[7] = index + 7; - } - - protected void Toggle01KCHR_RAM(bool ram, CHRArea area) - { - CHR_AREA_BLK_RAM[(uint)area] = ram; - } - - protected void Toggle02KCHR_RAM(bool ram, CHRArea area) - { - CHR_AREA_BLK_RAM[(uint)area] = ram; - CHR_AREA_BLK_RAM[(uint)(area + 1)] = ram; - } - - protected void Toggle04KCHR_RAM(bool ram, CHRArea area) - { - CHR_AREA_BLK_RAM[(uint)area] = ram; - CHR_AREA_BLK_RAM[(uint)(area + 1)] = ram; - CHR_AREA_BLK_RAM[(uint)(area + 2)] = ram; - CHR_AREA_BLK_RAM[(uint)(area + 3)] = ram; - } - - protected void Toggle08KCHR_RAM(bool ram) - { - CHR_AREA_BLK_RAM[0] = ram; - CHR_AREA_BLK_RAM[1] = ram; - CHR_AREA_BLK_RAM[2] = ram; - CHR_AREA_BLK_RAM[3] = ram; - CHR_AREA_BLK_RAM[4] = ram; - CHR_AREA_BLK_RAM[5] = ram; - CHR_AREA_BLK_RAM[6] = ram; - CHR_AREA_BLK_RAM[7] = ram; - } - - protected void Toggle01KCHR_RAM_Enabled(bool enable, int index) - { - CHR_RAM_ENABLED[index] = enable; - } - - protected void Toggle01KCHR_RAM_Writable(bool enable, int index) - { - CHR_RAM_WRITABLE[index] = enable; - } - - protected void ToggleCHRRAMWritableEnable(bool enable) - { - for (int i = 0; i < CHR_RAM_WRITABLE.Length; i++) - { - CHR_RAM_WRITABLE[i] = enable; - } - } - - protected void Toggle01KCHR_RAM_Battery(bool enable, int index) - { - CHR_RAM_BATTERY[index] = enable; - } - - protected void Switch01KNMT(int index, byte area) - { - NMT_AREA_BLK_INDEX[area] = index; - } - - protected void Switch01KNMT(byte mirroring) - { - NMT_AREA_BLK_INDEX[0] = mirroring & 3; - NMT_AREA_BLK_INDEX[1] = (mirroring >> 2) & 3; - NMT_AREA_BLK_INDEX[2] = (mirroring >> 4) & 3; - NMT_AREA_BLK_INDEX[3] = (mirroring >> 6) & 3; - } - - protected void Switch01KNMTFromMirroring(Mirroring mirroring) - { - NMT_AREA_BLK_INDEX[0] = (int)(mirroring & (Mirroring)3); - NMT_AREA_BLK_INDEX[1] = ((int)mirroring >> 2) & 3; - NMT_AREA_BLK_INDEX[2] = ((int)mirroring >> 4) & 3; - NMT_AREA_BLK_INDEX[3] = ((int)mirroring >> 6) & 3; - } - - internal virtual void OnPPUAddressUpdate(ref ushort address) - { - if (!enabled_ppuA12ToggleTimer) - { - return; - } - old_vram_address = new_vram_address; - new_vram_address = address & 0x1000; - if (ppuA12TogglesOnRaisingEdge) - { - if (old_vram_address < new_vram_address) - { - if (ppu_cycles_timer > 8) - { - OnPPUA12RaisingEdge(); - } - ppu_cycles_timer = 0; - } - } - else if (old_vram_address > new_vram_address) - { - if (ppu_cycles_timer > 8) - { - OnPPUA12RaisingEdge(); - } - ppu_cycles_timer = 0; - } - } - - internal virtual void OnCPUClock() - { - } - - internal virtual void OnPPUClock() - { - if (enabled_ppuA12ToggleTimer) - { - ppu_cycles_timer++; - } - } - - internal virtual void OnPPUA12RaisingEdge() - { - } - - internal virtual void OnPPUScanlineTick() - { - } - - internal virtual void OnAPUClockDuration() - { - } - - internal virtual void OnAPUClockEnvelope() - { - } - - internal virtual void OnAPUClockSingle() - { - } - - internal virtual void OnAPUClock() - { - } - - internal virtual double APUGetSample() - { - return 0.0; - } - - internal virtual void APUApplyChannelsSettings() - { - } - - internal void SetupGameGenie(bool IsGameGenieActive, GameGenieCode[] GameGenieCodes) - { - this.IsGameGenieActive = IsGameGenieActive; - this.GameGenieCodes = GameGenieCodes; - } - - internal virtual void WriteStateData(ref BinaryWriter bin) - { - for (int i = 0; i < PRG_RAM.Length; i++) - { - bin.Write(PRG_RAM[i]); - } - for (int j = 0; j < PRG_RAM_ENABLED.Length; j++) - { - bin.Write(PRG_RAM_ENABLED[j]); - } - for (int k = 0; k < PRG_RAM_WRITABLE.Length; k++) - { - bin.Write(PRG_RAM_WRITABLE[k]); - } - for (int l = 0; l < PRG_RAM_BATTERY.Length; l++) - { - bin.Write(PRG_RAM_BATTERY[l]); - } - for (int m = 0; m < PRG_AREA_BLK_RAM.Length; m++) - { - bin.Write(PRG_AREA_BLK_RAM[m]); - } - for (int n = 0; n < PRG_AREA_BLK_INDEX.Length; n++) - { - bin.Write(PRG_AREA_BLK_INDEX[n]); - } - bin.Write(PRG_TMP_INDX); - bin.Write(PRG_TMP_AREA); - for (int num = 0; num < CHR_RAM.Length; num++) - { - bin.Write(CHR_RAM[num]); - } - for (int num2 = 0; num2 < CHR_RAM_ENABLED.Length; num2++) - { - bin.Write(CHR_RAM_ENABLED[num2]); - } - for (int num3 = 0; num3 < CHR_RAM_WRITABLE.Length; num3++) - { - bin.Write(CHR_RAM_WRITABLE[num3]); - } - for (int num4 = 0; num4 < CHR_RAM_BATTERY.Length; num4++) - { - bin.Write(CHR_RAM_BATTERY[num4]); - } - for (int num5 = 0; num5 < CHR_AREA_BLK_RAM.Length; num5++) - { - bin.Write(CHR_AREA_BLK_RAM[num5]); - } - for (int num6 = 0; num6 < CHR_AREA_BLK_INDEX.Length; num6++) - { - bin.Write(CHR_AREA_BLK_INDEX[num6]); - } - bin.Write(CHR_TMP_INDX); - bin.Write(CHR_TMP_AREA); - for (int num7 = 0; num7 < NMT_RAM.Length; num7++) - { - bin.Write(NMT_RAM[num7]); - } - for (int num8 = 0; num8 < NMT_AREA_BLK_INDEX.Length; num8++) - { - bin.Write(NMT_AREA_BLK_INDEX[num8]); - } - bin.Write(NMT_TMP_INDX); - bin.Write(NMT_TMP_AREA); - } - - internal virtual void ReadStateData(ref BinaryReader bin) - { - for (int i = 0; i < PRG_RAM.Length; i++) - { - bin.Read(PRG_RAM[i], 0, PRG_RAM[i].Length); - } - for (int j = 0; j < PRG_RAM_ENABLED.Length; j++) - { - PRG_RAM_ENABLED[j] = bin.ReadBoolean(); - } - for (int k = 0; k < PRG_RAM_WRITABLE.Length; k++) - { - PRG_RAM_WRITABLE[k] = bin.ReadBoolean(); - } - for (int l = 0; l < PRG_RAM_BATTERY.Length; l++) - { - PRG_RAM_BATTERY[l] = bin.ReadBoolean(); - } - for (int m = 0; m < PRG_AREA_BLK_RAM.Length; m++) - { - PRG_AREA_BLK_RAM[m] = bin.ReadBoolean(); - } - for (int n = 0; n < PRG_AREA_BLK_INDEX.Length; n++) - { - PRG_AREA_BLK_INDEX[n] = bin.ReadInt32(); - } - PRG_TMP_INDX = bin.ReadInt32(); - PRG_TMP_AREA = bin.ReadInt32(); - for (int num = 0; num < CHR_RAM.Length; num++) - { - bin.Read(CHR_RAM[num], 0, CHR_RAM[num].Length); - } - for (int num2 = 0; num2 < CHR_RAM_ENABLED.Length; num2++) - { - CHR_RAM_ENABLED[num2] = bin.ReadBoolean(); - } - for (int num3 = 0; num3 < CHR_RAM_WRITABLE.Length; num3++) - { - CHR_RAM_WRITABLE[num3] = bin.ReadBoolean(); - } - for (int num4 = 0; num4 < CHR_RAM_BATTERY.Length; num4++) - { - CHR_RAM_BATTERY[num4] = bin.ReadBoolean(); - } - for (int num5 = 0; num5 < CHR_AREA_BLK_RAM.Length; num5++) - { - CHR_AREA_BLK_RAM[num5] = bin.ReadBoolean(); - } - for (int num6 = 0; num6 < CHR_AREA_BLK_INDEX.Length; num6++) - { - CHR_AREA_BLK_INDEX[num6] = bin.ReadInt32(); - } - CHR_TMP_INDX = bin.ReadInt32(); - CHR_TMP_AREA = bin.ReadInt32(); - for (int num7 = 0; num7 < NMT_RAM.Length; num7++) - { - bin.Read(NMT_RAM[num7], 0, NMT_RAM[num7].Length); - } - for (int num8 = 0; num8 < NMT_AREA_BLK_INDEX.Length; num8++) - { - NMT_AREA_BLK_INDEX[num8] = bin.ReadInt32(); - } - NMT_TMP_INDX = bin.ReadInt32(); - NMT_TMP_AREA = bin.ReadInt32(); - } - - internal void SaveSRAM(Stream stream) - { - for (int i = 0; i < PRG_RAM_04KB_Count; i++) - { - if (PRG_RAM_BATTERY[i]) - { - stream.Write(PRG_RAM[i], 0, 4096); - } - } - } - - internal byte[] GetSRAMBuffer() - { - List list = new List(); - for (int i = 0; i < PRG_RAM_04KB_Count; i++) - { - if (PRG_RAM_BATTERY[i]) - { - list.AddRange(PRG_RAM[i]); - } - } - return list.ToArray(); - } - - internal void LoadSRAM(Stream stream) - { - for (int i = 0; i < PRG_RAM_04KB_Count; i++) - { - if (PRG_RAM_BATTERY[i]) - { - stream.Read(PRG_RAM[i], 0, 4096); - } - } - } - - internal void LoadSRAM(byte[] buffer) - { - int num = 0; - for (int i = 0; i < PRG_RAM_04KB_Count; i++) - { - if (PRG_RAM_BATTERY[i]) - { - for (int j = 0; j < 4096; j++) - { - PRG_RAM[i][j] = buffer[j + num]; - } - num += 4096; - } - } - } - } +using System; +using System.Collections.Generic; +using System.IO; + +namespace MyNes.Core; + +internal abstract class Board +{ + protected byte[][] PRG_RAM; + + protected bool[] PRG_RAM_ENABLED; + + protected bool[] PRG_RAM_WRITABLE; + + protected bool[] PRG_RAM_BATTERY; + + protected byte[][] PRG_ROM; + + protected int PRG_RAM_08KB_DEFAULT_BLK_Count; + + internal int PRG_ROM_04KB_Count; + + protected int PRG_ROM_08KB_Count; + + protected int PRG_ROM_16KB_Count; + + protected int PRG_ROM_32KB_Count; + + protected int PRG_ROM_04KB_Mask; + + protected int PRG_ROM_08KB_Mask; + + protected int PRG_ROM_16KB_Mask; + + protected int PRG_ROM_32KB_Mask; + + internal int PRG_RAM_04KB_Count; + + protected int PRG_RAM_08KB_Count; + + protected int PRG_RAM_16KB_Count; + + protected int PRG_RAM_32KB_Count; + + protected int PRG_RAM_04KB_Mask; + + protected int PRG_RAM_08KB_Mask; + + protected int PRG_RAM_16KB_Mask; + + protected int PRG_RAM_32KB_Mask; + + protected bool[] PRG_AREA_BLK_RAM; + + protected int[] PRG_AREA_BLK_INDEX; + + protected int PRG_TMP_INDX; + + protected int PRG_TMP_AREA; + + protected byte[][] CHR_RAM; + + protected bool[] CHR_RAM_ENABLED; + + protected bool[] CHR_RAM_WRITABLE; + + protected bool[] CHR_RAM_BATTERY; + + protected byte[][] CHR_ROM; + + protected bool[] CHR_AREA_BLK_RAM; + + protected int[] CHR_AREA_BLK_INDEX; + + protected int CHR_TMP_INDX; + + protected int CHR_TMP_AREA; + + protected int CHR_ROM_01KB_DEFAULT_BLK_Count; + + internal int CHR_ROM_01KB_Count; + + protected int CHR_ROM_02KB_Count; + + protected int CHR_ROM_04KB_Count; + + protected int CHR_ROM_08KB_Count; + + internal int CHR_ROM_01KB_Mask; + + protected int CHR_ROM_02KB_Mask; + + protected int CHR_ROM_04KB_Mask; + + protected int CHR_ROM_08KB_Mask; + + internal int CHR_RAM_01KB_Count; + + protected int CHR_RAM_02KB_Count; + + protected int CHR_RAM_04KB_Count; + + protected int CHR_RAM_08KB_Count; + + internal int CHR_RAM_01KB_Mask; + + protected int CHR_RAM_02KB_Mask; + + protected int CHR_RAM_04KB_Mask; + + protected int CHR_RAM_08KB_Mask; + + protected byte[][] NMT_RAM; + + internal int[] NMT_AREA_BLK_INDEX; + + protected int NMT_TMP_INDX; + + protected int NMT_TMP_AREA; + + internal Mirroring NMT_DEFAULT_MIRROR; + + internal string SHA1 = ""; + + internal string CRC = ""; + + internal bool IsGameFoundOnDB; + + internal NesCartDatabaseGameInfo GameInfo; + + internal NesCartDatabaseCartridgeInfo GameCartInfo; + + internal bool SRAMSaveRequired; + + protected bool enabled_ppuA12ToggleTimer; + + protected bool ppuA12TogglesOnRaisingEdge; + + protected int old_vram_address; + + protected int new_vram_address; + + protected int ppu_cycles_timer; + + internal bool enable_external_sound; + + internal bool IsGameGenieActive; + + internal GameGenieCode[] GameGenieCodes; + + internal string BoardType { get; private set; } + + internal string BoardPCB { get; private set; } + + internal List Chips { get; private set; } + + internal string Name { get; set; } + + internal int MapperNumber { get; set; } + + internal bool HasIssues { get; set; } + + internal virtual string Issues { get; set; } + + public Board() + { + MapperNumber = -1; + PRG_RAM_08KB_DEFAULT_BLK_Count = 1; + CHR_ROM_01KB_DEFAULT_BLK_Count = 8; + LoadAttrs(); + } + + internal virtual void Initialize(IRom rom) + { + SHA1 = rom.SHA1; + SRAMSaveRequired = false; + IsGameGenieActive = false; + BoardType = "N/A"; + BoardPCB = "N/A"; + Chips = new List(); + if (NesCartDatabase.Ready) + { + Tracer.WriteLine("Looking for rom in the database .."); + GameInfo = NesCartDatabase.Find(SHA1, out IsGameFoundOnDB); + if (GameInfo.Cartridges != null) + { + foreach (NesCartDatabaseCartridgeInfo cartridge in GameInfo.Cartridges) + { + if (cartridge.SHA1.ToLower() == SHA1.ToLower()) + { + GameCartInfo = cartridge; + break; + } + } + } + if (IsGameFoundOnDB) + { + Tracer.WriteInformation("Game found in Database !!"); + Tracer.WriteLine("> Game name: " + GameInfo.Game_Name); + Tracer.WriteLine("> Game alt name: " + GameInfo.Game_AltName); + BoardType = GameCartInfo.Board_Type; + Tracer.WriteLine("> Board Type: " + BoardType); + BoardPCB = GameCartInfo.Board_Pcb; + Tracer.WriteLine("> Board Pcb: " + BoardPCB); + if (GameCartInfo.chip_type != null) + { + for (int i = 0; i < GameCartInfo.chip_type.Count; i++) + { + Console.WriteLine($"> CHIP {(i + 1).ToString()}: {GameCartInfo.chip_type[i]}"); + Chips.Add(GameCartInfo.chip_type[i]); + } + } + } + else + { + Tracer.WriteWarning("Game is not found in database ."); + } + } + Tracer.WriteLine("Initializing the board (Mapper # " + MapperNumber + ") ...."); + Tracer.WriteLine("Loading PRG ROM ..."); + PRG_AREA_BLK_RAM = new bool[16]; + PRG_AREA_BLK_INDEX = new int[16]; + PRG_ROM = new byte[0][]; + int num = 0; + for (int j = 0; j < rom.PRG.Length; j += 4096) + { + Array.Resize(ref PRG_ROM, PRG_ROM.GetLength(0) + 1); + PRG_ROM[num] = new byte[4096]; + for (int k = 0; k < 4096; k++) + { + PRG_ROM[num][k] = rom.PRG[j + k]; + } + num++; + } + PRG_ROM_04KB_Count = PRG_ROM.GetLength(0); + PRG_ROM_04KB_Mask = PRG_ROM_04KB_Count - 1; + PRG_ROM_08KB_Count = PRG_ROM_04KB_Count / 2; + PRG_ROM_08KB_Mask = PRG_ROM_08KB_Count - 1; + PRG_ROM_16KB_Count = PRG_ROM_04KB_Count / 4; + PRG_ROM_16KB_Mask = PRG_ROM_16KB_Count - 1; + PRG_ROM_32KB_Count = PRG_ROM_04KB_Count / 8; + PRG_ROM_32KB_Mask = PRG_ROM_32KB_Count - 1; + Tracer.WriteLine("PRG ROM loaded successfully."); + Tracer.WriteLine("PRG ROM Size = " + PRG_ROM_04KB_Count * 4 + "KB"); + Tracer.WriteLine("Loading PRG RAM ..."); + SRAMBankInfo[] pRGRAM8KCountFromDB = GetPRGRAM8KCountFromDB(); + PRG_RAM = new byte[0][]; + PRG_RAM_BATTERY = new bool[0]; + PRG_RAM_ENABLED = new bool[0]; + PRG_RAM_WRITABLE = new bool[0]; + SRAMBankInfo[] array = pRGRAM8KCountFromDB; + for (int l = 0; l < array.Length; l++) + { + SRAMBankInfo sRAMBankInfo = array[l]; + if (sRAMBankInfo.BATTERY) + { + SRAMSaveRequired = true; + } + int result = 0; + int.TryParse(sRAMBankInfo.SIZE.Replace("k", ""), out result); + if (result > 0) + { + int num2 = result / 2; + for (int m = 0; m < num2; m++) + { + Array.Resize(ref PRG_RAM_BATTERY, PRG_RAM_BATTERY.Length + 1); + Array.Resize(ref PRG_RAM_ENABLED, PRG_RAM_ENABLED.Length + 1); + Array.Resize(ref PRG_RAM_WRITABLE, PRG_RAM_WRITABLE.Length + 1); + Array.Resize(ref PRG_RAM, PRG_RAM.GetLength(0) + 1); + PRG_RAM[PRG_RAM.GetLength(0) - 1] = new byte[4096]; + PRG_RAM_BATTERY[PRG_RAM_BATTERY.Length - 1] = sRAMBankInfo.BATTERY; + PRG_RAM_ENABLED[PRG_RAM_ENABLED.Length - 1] = true; + PRG_RAM_WRITABLE[PRG_RAM_WRITABLE.Length - 1] = true; + } + } + } + PRG_RAM_04KB_Count = PRG_RAM.GetLength(0); + PRG_RAM_04KB_Mask = PRG_RAM_04KB_Count - 1; + PRG_RAM_08KB_Count = PRG_RAM_04KB_Count / 2; + PRG_RAM_08KB_Mask = PRG_RAM_08KB_Count - 1; + PRG_RAM_16KB_Count = PRG_RAM_04KB_Count / 4; + PRG_RAM_16KB_Mask = PRG_RAM_16KB_Count - 1; + PRG_RAM_32KB_Count = PRG_RAM_04KB_Count / 8; + PRG_RAM_32KB_Mask = PRG_RAM_32KB_Count - 1; + Tracer.WriteLine("PRG RAM loaded successfully."); + Tracer.WriteLine("PRG RAM Size = " + PRG_RAM_04KB_Count * 4 + "KB"); + if (rom.HasTrainer) + { + rom.Trainer.CopyTo(PRG_RAM[3], 0); + } + Tracer.WriteLine("Loading CHR ROM ..."); + CHR_ROM = new byte[0][]; + CHR_AREA_BLK_RAM = new bool[8]; + CHR_AREA_BLK_INDEX = new int[8]; + num = 0; + for (int n = 0; n < rom.CHR.Length; n += 1024) + { + Array.Resize(ref CHR_ROM, CHR_ROM.GetLength(0) + 1); + CHR_ROM[num] = new byte[1024]; + for (int num3 = 0; num3 < 1024; num3++) + { + CHR_ROM[num][num3] = rom.CHR[n + num3]; + } + num++; + } + CHR_ROM_01KB_Count = CHR_ROM.GetLength(0); + CHR_ROM_01KB_Mask = CHR_ROM_01KB_Count - 1; + CHR_ROM_02KB_Count = CHR_ROM_01KB_Count / 2; + CHR_ROM_02KB_Mask = CHR_ROM_02KB_Count - 1; + CHR_ROM_04KB_Count = CHR_ROM_01KB_Count / 4; + CHR_ROM_04KB_Mask = CHR_ROM_04KB_Count - 1; + CHR_ROM_08KB_Count = CHR_ROM_01KB_Count / 8; + CHR_ROM_08KB_Mask = CHR_ROM_08KB_Count - 1; + Tracer.WriteLine("CHR ROM loaded successfully."); + Tracer.WriteLine("CHR ROM Size = " + CHR_ROM_01KB_Count + "KB"); + Tracer.WriteLine("Loading CHR RAM ..."); + int cHRRAM1KCountFromDB = GetCHRRAM1KCountFromDB(); + CHR_RAM = new byte[0][]; + CHR_RAM_BATTERY = new bool[cHRRAM1KCountFromDB]; + CHR_RAM_ENABLED = new bool[cHRRAM1KCountFromDB]; + CHR_RAM_WRITABLE = new bool[cHRRAM1KCountFromDB]; + for (int num4 = 0; num4 < cHRRAM1KCountFromDB; num4++) + { + Array.Resize(ref CHR_RAM, CHR_RAM.GetLength(0) + 1); + CHR_RAM[num4] = new byte[1024]; + CHR_RAM_BATTERY[num4] = false; + CHR_RAM_ENABLED[num4] = true; + CHR_RAM_WRITABLE[num4] = true; + } + CHR_RAM_01KB_Count = CHR_RAM.GetLength(0); + CHR_RAM_01KB_Mask = CHR_RAM_01KB_Count - 1; + CHR_RAM_02KB_Count = CHR_RAM_01KB_Count / 2; + CHR_RAM_02KB_Mask = CHR_RAM_02KB_Count - 1; + CHR_RAM_04KB_Count = CHR_RAM_01KB_Count / 4; + CHR_RAM_04KB_Mask = CHR_RAM_04KB_Count - 1; + CHR_RAM_08KB_Count = CHR_RAM_01KB_Count / 8; + CHR_RAM_08KB_Mask = CHR_RAM_08KB_Count - 1; + Tracer.WriteLine("CHR RAM loaded successfully."); + Tracer.WriteLine("CHR RAM Size = " + CHR_RAM_01KB_Count + "KB"); + Tracer.WriteLine("Loading Nametables ..."); + NMT_AREA_BLK_INDEX = new int[4]; + NMT_RAM = new byte[0][]; + for (int num5 = 0; num5 < 4; num5++) + { + Array.Resize(ref NMT_RAM, NMT_RAM.GetLength(0) + 1); + NMT_RAM[num5] = new byte[1024]; + } + NMT_DEFAULT_MIRROR = rom.Mirroring; + Tracer.WriteLine("Mirroring set to " + NMT_DEFAULT_MIRROR); + Tracer.WriteLine("Board (Mapper # " + MapperNumber + ") initialized successfully."); + } + + internal virtual void HardReset() + { + Tracer.WriteLine("Hard reset board (Mapper # " + MapperNumber + ") ...."); + Tracer.WriteLine("Switching 16KB PRG RAM at 0x4000 - 0x7000"); + Toggle16KPRG_RAM(ram: true, PRGArea.Area4000); + Switch16KPRG(0, PRGArea.Area4000); + Tracer.WriteLine("Switching 32KB PRG ROM at 0x8000 - 0xF000"); + Toggle32KPRG_RAM(ram: false, PRGArea.Area8000); + Switch32KPRG(0, PRGArea.Area8000); + Tracer.WriteLine("Switching 8KB CHR " + ((CHR_ROM_01KB_Count == 0) ? "RAM" : "ROM") + " at 0x0000 - 0x1000"); + Toggle08KCHR_RAM(CHR_ROM_01KB_Count == 0); + Switch08KCHR(0); + Tracer.WriteLine("Switching to mirroring: " + NMT_DEFAULT_MIRROR); + Switch01KNMTFromMirroring(NMT_DEFAULT_MIRROR); + Tracer.WriteLine("Hard reset board (Mapper # " + MapperNumber + ") is done successfully."); + } + + internal virtual void SoftReset() + { + } + + protected virtual void LoadAttrs() + { + enable_external_sound = false; + Attribute[] customAttributes = Attribute.GetCustomAttributes(GetType()); + foreach (Attribute attribute in customAttributes) + { + if (attribute.GetType() == typeof(BoardInfoAttribute)) + { + BoardInfoAttribute boardInfoAttribute = (BoardInfoAttribute)attribute; + Name = boardInfoAttribute.Name; + MapperNumber = boardInfoAttribute.Mapper; + PRG_RAM_08KB_DEFAULT_BLK_Count = boardInfoAttribute.DefaultPRG_RAM_8KB_BanksCount; + CHR_ROM_01KB_DEFAULT_BLK_Count = boardInfoAttribute.DefaultCHR_RAM_1KB_BanksCount; + enabled_ppuA12ToggleTimer = boardInfoAttribute.Enabled_ppuA12ToggleTimer; + ppuA12TogglesOnRaisingEdge = boardInfoAttribute.PPUA12TogglesOnRaisingEdge; + } + else if (attribute.GetType() == typeof(WithExternalSoundAttribute)) + { + enable_external_sound = true; + } + else if (attribute.GetType() == typeof(HassIssuesAttribute)) + { + HasIssues = true; + } + } + } + + protected SRAMBankInfo[] GetPRGRAM8KCountFromDB() + { + Tracer.WriteLine("Retrieving PRG RAM information from database ...."); + List list = new List(); + if (IsGameFoundOnDB) + { + if (GameCartInfo.WRAMBanks.Count > 0) + { + foreach (SRAMBankInfo wRAMBank in GameCartInfo.WRAMBanks) + { + list.Add(wRAMBank); + } + } + else + { + Tracer.WriteLine("This game has no PRG RAM !"); + Tracer.WriteWarning("> Adding 8K x " + PRG_RAM_08KB_DEFAULT_BLK_Count + " PRG RAM BANKS to avoid exceptions."); + SRAMBankInfo item = new SRAMBankInfo(0, PRG_RAM_08KB_DEFAULT_BLK_Count * 8 + "k", BATTERY: true); + list.Add(item); + } + } + else + { + Tracer.WriteWarning("Could't find this game in database .... Adding 8K x " + PRG_RAM_08KB_DEFAULT_BLK_Count + " PRG RAM BANKS to avoid exceptions."); + SRAMBankInfo item2 = new SRAMBankInfo(0, PRG_RAM_08KB_DEFAULT_BLK_Count * 8 + "k", BATTERY: true); + list.Add(item2); + } + return list.ToArray(); + } + + protected int GetCHRRAM1KCountFromDB() + { + int num = 0; + Tracer.WriteLine("Retrieving CHR RAM information from database ...."); + if (IsGameFoundOnDB) + { + bool flag = false; + if (GameCartInfo.VRAM_sizes != null) + { + Tracer.WriteLine("Using database to initialize CHR RAM ....."); + foreach (string vRAM_size in GameCartInfo.VRAM_sizes) + { + int result = 0; + if (int.TryParse(vRAM_size.Replace("k", ""), out result)) + { + Tracer.WriteLine(">CHR RAM CHIP SIZE " + vRAM_size + " KB added"); + num += result; + if (num > 0) + { + flag = true; + } + } + } + } + if (!flag) + { + Tracer.WriteLine("Game not found in database to initialize CHR RAM; CHR RAM size set to " + CHR_ROM_01KB_DEFAULT_BLK_Count + " KB"); + num = CHR_ROM_01KB_DEFAULT_BLK_Count; + } + } + else + { + Tracer.WriteWarning("Game not found in database to initialize CHR RAM; CHR RAM size set to " + CHR_ROM_01KB_DEFAULT_BLK_Count + " KB"); + num = CHR_ROM_01KB_DEFAULT_BLK_Count; + } + return num; + } + + internal virtual void WriteEX(ref ushort addr, ref byte val) + { + PRG_TMP_AREA = (addr >> 12) & 0xF; + if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; + if (PRG_RAM_ENABLED[PRG_TMP_INDX] && PRG_RAM_WRITABLE[PRG_TMP_INDX]) + { + PRG_RAM[PRG_TMP_INDX][addr & 0xFFF] = val; + } + } + } + + internal virtual void WriteSRM(ref ushort addr, ref byte val) + { + PRG_TMP_AREA = (addr >> 12) & 0xF; + if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; + if (PRG_RAM_ENABLED[PRG_TMP_INDX] && PRG_RAM_WRITABLE[PRG_TMP_INDX]) + { + PRG_RAM[PRG_TMP_INDX][addr & 0xFFF] = val; + } + } + } + + internal virtual void WritePRG(ref ushort addr, ref byte val) + { + PRG_TMP_AREA = (addr >> 12) & 0xF; + if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; + if (PRG_RAM_ENABLED[PRG_TMP_INDX] && PRG_RAM_WRITABLE[PRG_TMP_INDX]) + { + PRG_RAM[PRG_TMP_INDX][addr & 0xFFF] = val; + } + } + } + + internal virtual void ReadEX(ref ushort addr, out byte val) + { + PRG_TMP_AREA = (addr >> 12) & 0xF; + if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; + if (PRG_RAM_ENABLED[PRG_TMP_INDX]) + { + val = PRG_RAM[PRG_TMP_INDX][addr & 0xFFF]; + } + else + { + val = 0; + } + } + else + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_ROM_04KB_Mask; + val = PRG_ROM[PRG_TMP_INDX][addr & 0xFFF]; + } + } + + internal virtual void ReadSRM(ref ushort addr, out byte val) + { + PRG_TMP_AREA = (addr >> 12) & 0xF; + if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; + if (PRG_RAM_ENABLED[PRG_TMP_INDX]) + { + val = PRG_RAM[PRG_TMP_INDX][addr & 0xFFF]; + } + else + { + val = 0; + } + } + else + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_ROM_04KB_Mask; + val = PRG_ROM[PRG_TMP_INDX][addr & 0xFFF]; + } + } + + internal virtual void ReadPRG(ref ushort addr, out byte val) + { + PRG_TMP_AREA = (addr >> 12) & 0xF; + if (PRG_AREA_BLK_RAM[PRG_TMP_AREA]) + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_RAM_04KB_Mask; + if (PRG_RAM_ENABLED[PRG_TMP_INDX]) + { + val = PRG_RAM[PRG_TMP_INDX][addr & 0xFFF]; + } + else + { + val = 0; + } + } + else + { + PRG_TMP_INDX = PRG_AREA_BLK_INDEX[PRG_TMP_AREA] & PRG_ROM_04KB_Mask; + val = PRG_ROM[PRG_TMP_INDX][addr & 0xFFF]; + } + if (!IsGameGenieActive) + { + return; + } + GameGenieCode[] gameGenieCodes = GameGenieCodes; + for (int i = 0; i < gameGenieCodes.Length; i++) + { + GameGenieCode gameGenieCode = gameGenieCodes[i]; + if (!gameGenieCode.Enabled || gameGenieCode.Address != addr) + { + continue; + } + if (gameGenieCode.IsCompare) + { + if (gameGenieCode.Compare == val) + { + val = gameGenieCode.Value; + } + } + else + { + val = gameGenieCode.Value; + } + break; + } + } + + internal virtual void WriteCHR(ref ushort addr, ref byte val) + { + CHR_TMP_AREA = (addr >> 10) & 7; + if (CHR_AREA_BLK_RAM[CHR_TMP_AREA]) + { + CHR_TMP_INDX = CHR_AREA_BLK_INDEX[CHR_TMP_AREA] & CHR_RAM_01KB_Mask; + if (CHR_RAM_ENABLED[CHR_TMP_INDX] && CHR_RAM_WRITABLE[CHR_TMP_INDX]) + { + CHR_RAM[CHR_TMP_INDX][addr & 0x3FF] = val; + } + } + } + + internal virtual void ReadCHR(ref ushort addr, out byte val) + { + CHR_TMP_AREA = (addr >> 10) & 7; + CHR_TMP_INDX = CHR_AREA_BLK_INDEX[CHR_TMP_AREA]; + if (CHR_AREA_BLK_RAM[CHR_TMP_AREA]) + { + CHR_TMP_INDX &= CHR_RAM_01KB_Mask; + if (CHR_RAM_ENABLED[CHR_TMP_INDX]) + { + val = CHR_RAM[CHR_TMP_INDX][addr & 0x3FF]; + } + else + { + val = 0; + } + } + else + { + CHR_TMP_INDX &= CHR_ROM_01KB_Mask; + val = CHR_ROM[CHR_TMP_INDX][addr & 0x3FF]; + } + } + + internal virtual void WriteNMT(ref ushort addr, ref byte val) + { + NMT_TMP_AREA = (addr >> 10) & 3; + NMT_TMP_INDX = NMT_AREA_BLK_INDEX[NMT_TMP_AREA]; + NMT_RAM[NMT_TMP_INDX][addr & 0x3FF] = val; + } + + internal virtual void ReadNMT(ref ushort addr, out byte val) + { + NMT_TMP_AREA = (addr >> 10) & 3; + NMT_TMP_INDX = NMT_AREA_BLK_INDEX[NMT_TMP_AREA]; + val = NMT_RAM[NMT_TMP_INDX][addr & 0x3FF]; + } + + protected void Switch04KPRG(int index, PRGArea area) + { + PRG_AREA_BLK_INDEX[(uint)area] = index; + } + + protected void Switch08KPRG(int index, PRGArea area) + { + index *= 2; + PRG_AREA_BLK_INDEX[(uint)area] = index; + PRG_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; + } + + protected void Switch16KPRG(int index, PRGArea area) + { + index *= 4; + PRG_AREA_BLK_INDEX[(uint)area] = index; + PRG_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; + PRG_AREA_BLK_INDEX[(uint)(area + 2)] = index + 2; + PRG_AREA_BLK_INDEX[(uint)(area + 3)] = index + 3; + } + + protected void Switch32KPRG(int index, PRGArea area) + { + index *= 8; + PRG_AREA_BLK_INDEX[(uint)area] = index; + PRG_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; + PRG_AREA_BLK_INDEX[(uint)(area + 2)] = index + 2; + PRG_AREA_BLK_INDEX[(uint)(area + 3)] = index + 3; + PRG_AREA_BLK_INDEX[(uint)(area + 4)] = index + 4; + PRG_AREA_BLK_INDEX[(uint)(area + 5)] = index + 5; + PRG_AREA_BLK_INDEX[(uint)(area + 6)] = index + 6; + PRG_AREA_BLK_INDEX[(uint)(area + 7)] = index + 7; + } + + protected void Toggle04KPRG_RAM(bool ram, PRGArea area) + { + PRG_AREA_BLK_RAM[(uint)area] = ram; + } + + protected void Toggle08KPRG_RAM(bool ram, PRGArea area) + { + PRG_AREA_BLK_RAM[(uint)area] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 1)] = ram; + } + + protected void Toggle16KPRG_RAM(bool ram, PRGArea area) + { + PRG_AREA_BLK_RAM[(uint)area] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 1)] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 2)] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 3)] = ram; + } + + protected void Toggle32KPRG_RAM(bool ram, PRGArea area) + { + PRG_AREA_BLK_RAM[(uint)area] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 1)] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 2)] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 3)] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 4)] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 5)] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 6)] = ram; + PRG_AREA_BLK_RAM[(uint)(area + 7)] = ram; + } + + protected void TogglePRGRAMEnable(bool enable) + { + for (int i = 0; i < PRG_RAM_ENABLED.Length; i++) + { + PRG_RAM_ENABLED[i] = enable; + } + } + + protected void TogglePRGRAMWritableEnable(bool enable) + { + for (int i = 0; i < PRG_RAM_WRITABLE.Length; i++) + { + PRG_RAM_WRITABLE[i] = enable; + } + } + + protected void Toggle04KPRG_RAM_Enabled(bool enable, int index) + { + PRG_RAM_ENABLED[index] = enable; + } + + protected void Toggle04KPRG_RAM_Writable(bool enable, int index) + { + PRG_RAM_WRITABLE[index] = enable; + } + + protected void Toggle04KPRG_RAM_Battery(bool enable, int index) + { + PRG_RAM_BATTERY[index] = enable; + } + + protected void Switch01KCHR(int index, CHRArea area) + { + CHR_AREA_BLK_INDEX[(uint)area] = index; + } + + protected void Switch02KCHR(int index, CHRArea area) + { + index *= 2; + CHR_AREA_BLK_INDEX[(uint)area] = index; + CHR_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; + } + + protected void Switch04KCHR(int index, CHRArea area) + { + index *= 4; + CHR_AREA_BLK_INDEX[(uint)area] = index; + CHR_AREA_BLK_INDEX[(uint)(area + 1)] = index + 1; + CHR_AREA_BLK_INDEX[(uint)(area + 2)] = index + 2; + CHR_AREA_BLK_INDEX[(uint)(area + 3)] = index + 3; + } + + protected void Switch08KCHR(int index) + { + index *= 8; + CHR_AREA_BLK_INDEX[0] = index; + CHR_AREA_BLK_INDEX[1] = index + 1; + CHR_AREA_BLK_INDEX[2] = index + 2; + CHR_AREA_BLK_INDEX[3] = index + 3; + CHR_AREA_BLK_INDEX[4] = index + 4; + CHR_AREA_BLK_INDEX[5] = index + 5; + CHR_AREA_BLK_INDEX[6] = index + 6; + CHR_AREA_BLK_INDEX[7] = index + 7; + } + + protected void Toggle01KCHR_RAM(bool ram, CHRArea area) + { + CHR_AREA_BLK_RAM[(uint)area] = ram; + } + + protected void Toggle02KCHR_RAM(bool ram, CHRArea area) + { + CHR_AREA_BLK_RAM[(uint)area] = ram; + CHR_AREA_BLK_RAM[(uint)(area + 1)] = ram; + } + + protected void Toggle04KCHR_RAM(bool ram, CHRArea area) + { + CHR_AREA_BLK_RAM[(uint)area] = ram; + CHR_AREA_BLK_RAM[(uint)(area + 1)] = ram; + CHR_AREA_BLK_RAM[(uint)(area + 2)] = ram; + CHR_AREA_BLK_RAM[(uint)(area + 3)] = ram; + } + + protected void Toggle08KCHR_RAM(bool ram) + { + CHR_AREA_BLK_RAM[0] = ram; + CHR_AREA_BLK_RAM[1] = ram; + CHR_AREA_BLK_RAM[2] = ram; + CHR_AREA_BLK_RAM[3] = ram; + CHR_AREA_BLK_RAM[4] = ram; + CHR_AREA_BLK_RAM[5] = ram; + CHR_AREA_BLK_RAM[6] = ram; + CHR_AREA_BLK_RAM[7] = ram; + } + + protected void Toggle01KCHR_RAM_Enabled(bool enable, int index) + { + CHR_RAM_ENABLED[index] = enable; + } + + protected void Toggle01KCHR_RAM_Writable(bool enable, int index) + { + CHR_RAM_WRITABLE[index] = enable; + } + + protected void ToggleCHRRAMWritableEnable(bool enable) + { + for (int i = 0; i < CHR_RAM_WRITABLE.Length; i++) + { + CHR_RAM_WRITABLE[i] = enable; + } + } + + protected void Toggle01KCHR_RAM_Battery(bool enable, int index) + { + CHR_RAM_BATTERY[index] = enable; + } + + protected void Switch01KNMT(int index, byte area) + { + NMT_AREA_BLK_INDEX[area] = index; + } + + protected void Switch01KNMT(byte mirroring) + { + NMT_AREA_BLK_INDEX[0] = mirroring & 3; + NMT_AREA_BLK_INDEX[1] = (mirroring >> 2) & 3; + NMT_AREA_BLK_INDEX[2] = (mirroring >> 4) & 3; + NMT_AREA_BLK_INDEX[3] = (mirroring >> 6) & 3; + } + + protected void Switch01KNMTFromMirroring(Mirroring mirroring) + { + NMT_AREA_BLK_INDEX[0] = (int)(mirroring & (Mirroring)3); + NMT_AREA_BLK_INDEX[1] = ((int)mirroring >> 2) & 3; + NMT_AREA_BLK_INDEX[2] = ((int)mirroring >> 4) & 3; + NMT_AREA_BLK_INDEX[3] = ((int)mirroring >> 6) & 3; + } + + internal virtual void OnPPUAddressUpdate(ref ushort address) + { + if (!enabled_ppuA12ToggleTimer) + { + return; + } + old_vram_address = new_vram_address; + new_vram_address = address & 0x1000; + if (ppuA12TogglesOnRaisingEdge) + { + if (old_vram_address < new_vram_address) + { + if (ppu_cycles_timer > 8) + { + OnPPUA12RaisingEdge(); + } + ppu_cycles_timer = 0; + } + } + else if (old_vram_address > new_vram_address) + { + if (ppu_cycles_timer > 8) + { + OnPPUA12RaisingEdge(); + } + ppu_cycles_timer = 0; + } + } + + internal virtual void OnCPUClock() + { + } + + internal virtual void OnPPUClock() + { + if (enabled_ppuA12ToggleTimer) + { + ppu_cycles_timer++; + } + } + + internal virtual void OnPPUA12RaisingEdge() + { + } + + internal virtual void OnPPUScanlineTick() + { + } + + internal virtual void OnAPUClockDuration() + { + } + + internal virtual void OnAPUClockEnvelope() + { + } + + internal virtual void OnAPUClockSingle() + { + } + + internal virtual void OnAPUClock() + { + } + + internal virtual double APUGetSample() + { + return 0.0; + } + + internal virtual void APUApplyChannelsSettings() + { + } + + internal void SetupGameGenie(bool IsGameGenieActive, GameGenieCode[] GameGenieCodes) + { + this.IsGameGenieActive = IsGameGenieActive; + this.GameGenieCodes = GameGenieCodes; + } + + internal virtual void WriteStateData(ref BinaryWriter bin) + { + for (int i = 0; i < PRG_RAM.Length; i++) + { + bin.Write(PRG_RAM[i]); + } + for (int j = 0; j < PRG_RAM_ENABLED.Length; j++) + { + bin.Write(PRG_RAM_ENABLED[j]); + } + for (int k = 0; k < PRG_RAM_WRITABLE.Length; k++) + { + bin.Write(PRG_RAM_WRITABLE[k]); + } + for (int l = 0; l < PRG_RAM_BATTERY.Length; l++) + { + bin.Write(PRG_RAM_BATTERY[l]); + } + for (int m = 0; m < PRG_AREA_BLK_RAM.Length; m++) + { + bin.Write(PRG_AREA_BLK_RAM[m]); + } + for (int n = 0; n < PRG_AREA_BLK_INDEX.Length; n++) + { + bin.Write(PRG_AREA_BLK_INDEX[n]); + } + bin.Write(PRG_TMP_INDX); + bin.Write(PRG_TMP_AREA); + for (int num = 0; num < CHR_RAM.Length; num++) + { + bin.Write(CHR_RAM[num]); + } + for (int num2 = 0; num2 < CHR_RAM_ENABLED.Length; num2++) + { + bin.Write(CHR_RAM_ENABLED[num2]); + } + for (int num3 = 0; num3 < CHR_RAM_WRITABLE.Length; num3++) + { + bin.Write(CHR_RAM_WRITABLE[num3]); + } + for (int num4 = 0; num4 < CHR_RAM_BATTERY.Length; num4++) + { + bin.Write(CHR_RAM_BATTERY[num4]); + } + for (int num5 = 0; num5 < CHR_AREA_BLK_RAM.Length; num5++) + { + bin.Write(CHR_AREA_BLK_RAM[num5]); + } + for (int num6 = 0; num6 < CHR_AREA_BLK_INDEX.Length; num6++) + { + bin.Write(CHR_AREA_BLK_INDEX[num6]); + } + bin.Write(CHR_TMP_INDX); + bin.Write(CHR_TMP_AREA); + for (int num7 = 0; num7 < NMT_RAM.Length; num7++) + { + bin.Write(NMT_RAM[num7]); + } + for (int num8 = 0; num8 < NMT_AREA_BLK_INDEX.Length; num8++) + { + bin.Write(NMT_AREA_BLK_INDEX[num8]); + } + bin.Write(NMT_TMP_INDX); + bin.Write(NMT_TMP_AREA); + } + + internal virtual void ReadStateData(ref BinaryReader bin) + { + for (int i = 0; i < PRG_RAM.Length; i++) + { + bin.Read(PRG_RAM[i], 0, PRG_RAM[i].Length); + } + for (int j = 0; j < PRG_RAM_ENABLED.Length; j++) + { + PRG_RAM_ENABLED[j] = bin.ReadBoolean(); + } + for (int k = 0; k < PRG_RAM_WRITABLE.Length; k++) + { + PRG_RAM_WRITABLE[k] = bin.ReadBoolean(); + } + for (int l = 0; l < PRG_RAM_BATTERY.Length; l++) + { + PRG_RAM_BATTERY[l] = bin.ReadBoolean(); + } + for (int m = 0; m < PRG_AREA_BLK_RAM.Length; m++) + { + PRG_AREA_BLK_RAM[m] = bin.ReadBoolean(); + } + for (int n = 0; n < PRG_AREA_BLK_INDEX.Length; n++) + { + PRG_AREA_BLK_INDEX[n] = bin.ReadInt32(); + } + PRG_TMP_INDX = bin.ReadInt32(); + PRG_TMP_AREA = bin.ReadInt32(); + for (int num = 0; num < CHR_RAM.Length; num++) + { + bin.Read(CHR_RAM[num], 0, CHR_RAM[num].Length); + } + for (int num2 = 0; num2 < CHR_RAM_ENABLED.Length; num2++) + { + CHR_RAM_ENABLED[num2] = bin.ReadBoolean(); + } + for (int num3 = 0; num3 < CHR_RAM_WRITABLE.Length; num3++) + { + CHR_RAM_WRITABLE[num3] = bin.ReadBoolean(); + } + for (int num4 = 0; num4 < CHR_RAM_BATTERY.Length; num4++) + { + CHR_RAM_BATTERY[num4] = bin.ReadBoolean(); + } + for (int num5 = 0; num5 < CHR_AREA_BLK_RAM.Length; num5++) + { + CHR_AREA_BLK_RAM[num5] = bin.ReadBoolean(); + } + for (int num6 = 0; num6 < CHR_AREA_BLK_INDEX.Length; num6++) + { + CHR_AREA_BLK_INDEX[num6] = bin.ReadInt32(); + } + CHR_TMP_INDX = bin.ReadInt32(); + CHR_TMP_AREA = bin.ReadInt32(); + for (int num7 = 0; num7 < NMT_RAM.Length; num7++) + { + bin.Read(NMT_RAM[num7], 0, NMT_RAM[num7].Length); + } + for (int num8 = 0; num8 < NMT_AREA_BLK_INDEX.Length; num8++) + { + NMT_AREA_BLK_INDEX[num8] = bin.ReadInt32(); + } + NMT_TMP_INDX = bin.ReadInt32(); + NMT_TMP_AREA = bin.ReadInt32(); + } + + internal void SaveSRAM(Stream stream) + { + for (int i = 0; i < PRG_RAM_04KB_Count; i++) + { + if (PRG_RAM_BATTERY[i]) + { + stream.Write(PRG_RAM[i], 0, 4096); + } + } + } + + internal byte[] GetSRAMBuffer() + { + List list = new List(); + for (int i = 0; i < PRG_RAM_04KB_Count; i++) + { + if (PRG_RAM_BATTERY[i]) + { + list.AddRange(PRG_RAM[i]); + } + } + return list.ToArray(); + } + + internal void LoadSRAM(Stream stream) + { + for (int i = 0; i < PRG_RAM_04KB_Count; i++) + { + if (PRG_RAM_BATTERY[i]) + { + stream.Read(PRG_RAM[i], 0, 4096); + } + } + } + + internal void LoadSRAM(byte[] buffer) + { + int num = 0; + for (int i = 0; i < PRG_RAM_04KB_Count; i++) + { + if (PRG_RAM_BATTERY[i]) + { + for (int j = 0; j < 4096; j++) + { + PRG_RAM[i][j] = buffer[j + num]; + } + num += 4096; + } + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/BoardInfoAttribute.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/BoardInfoAttribute.cs index f128856..3994f03 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/BoardInfoAttribute.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/BoardInfoAttribute.cs @@ -1,57 +1,56 @@ -using System; - -namespace MyNes.Core -{ - internal class BoardInfoAttribute : Attribute - { - public string Name { get; private set; } - - public int Mapper { get; private set; } - - public int DefaultPRG_RAM_8KB_BanksCount { get; private set; } - - public int DefaultCHR_RAM_1KB_BanksCount { get; private set; } - - public bool Enabled_ppuA12ToggleTimer { get; private set; } - - public bool PPUA12TogglesOnRaisingEdge { get; private set; } - - public BoardInfoAttribute(string boardName, int inesMapperNumber) - { - Name = boardName; - Mapper = inesMapperNumber; - DefaultPRG_RAM_8KB_BanksCount = 1; - DefaultCHR_RAM_1KB_BanksCount = 8; - Enabled_ppuA12ToggleTimer = (PPUA12TogglesOnRaisingEdge = false); - } - - public BoardInfoAttribute(string boardName, int inesMapperNumber, int defaultPRG_RAM_8KB_BanksCount, int defaultCHR_RAM_1KB_BanksCount) - { - Name = boardName; - Mapper = inesMapperNumber; - DefaultPRG_RAM_8KB_BanksCount = defaultPRG_RAM_8KB_BanksCount; - DefaultCHR_RAM_1KB_BanksCount = defaultCHR_RAM_1KB_BanksCount; - Enabled_ppuA12ToggleTimer = (PPUA12TogglesOnRaisingEdge = false); - } - - public BoardInfoAttribute(string boardName, int inesMapperNumber, bool Enabled_ppuA12ToggleTimer, bool PPUA12TogglesOnRaisingEdge) - { - Name = boardName; - Mapper = inesMapperNumber; - DefaultPRG_RAM_8KB_BanksCount = 1; - DefaultCHR_RAM_1KB_BanksCount = 8; - this.Enabled_ppuA12ToggleTimer = Enabled_ppuA12ToggleTimer; - this.PPUA12TogglesOnRaisingEdge = PPUA12TogglesOnRaisingEdge; - } - - public BoardInfoAttribute(string boardName, int inesMapperNumber, int defaultPRG_RAM_8KB_BanksCount, int defaultCHR_RAM_1KB_BanksCount, bool Enabled_ppuA12ToggleTimer, bool PPUA12TogglesOnRaisingEdge) - { - Name = boardName; - Mapper = inesMapperNumber; - DefaultPRG_RAM_8KB_BanksCount = defaultPRG_RAM_8KB_BanksCount; - DefaultCHR_RAM_1KB_BanksCount = defaultCHR_RAM_1KB_BanksCount; - this.Enabled_ppuA12ToggleTimer = Enabled_ppuA12ToggleTimer; - this.PPUA12TogglesOnRaisingEdge = PPUA12TogglesOnRaisingEdge; - } - } +using System; + +namespace MyNes.Core; + +internal class BoardInfoAttribute : Attribute +{ + public string Name { get; private set; } + + public int Mapper { get; private set; } + + public int DefaultPRG_RAM_8KB_BanksCount { get; private set; } + + public int DefaultCHR_RAM_1KB_BanksCount { get; private set; } + + public bool Enabled_ppuA12ToggleTimer { get; private set; } + + public bool PPUA12TogglesOnRaisingEdge { get; private set; } + + public BoardInfoAttribute(string boardName, int inesMapperNumber) + { + Name = boardName; + Mapper = inesMapperNumber; + DefaultPRG_RAM_8KB_BanksCount = 1; + DefaultCHR_RAM_1KB_BanksCount = 8; + Enabled_ppuA12ToggleTimer = (PPUA12TogglesOnRaisingEdge = false); + } + + public BoardInfoAttribute(string boardName, int inesMapperNumber, int defaultPRG_RAM_8KB_BanksCount, int defaultCHR_RAM_1KB_BanksCount) + { + Name = boardName; + Mapper = inesMapperNumber; + DefaultPRG_RAM_8KB_BanksCount = defaultPRG_RAM_8KB_BanksCount; + DefaultCHR_RAM_1KB_BanksCount = defaultCHR_RAM_1KB_BanksCount; + Enabled_ppuA12ToggleTimer = (PPUA12TogglesOnRaisingEdge = false); + } + + public BoardInfoAttribute(string boardName, int inesMapperNumber, bool Enabled_ppuA12ToggleTimer, bool PPUA12TogglesOnRaisingEdge) + { + Name = boardName; + Mapper = inesMapperNumber; + DefaultPRG_RAM_8KB_BanksCount = 1; + DefaultCHR_RAM_1KB_BanksCount = 8; + this.Enabled_ppuA12ToggleTimer = Enabled_ppuA12ToggleTimer; + this.PPUA12TogglesOnRaisingEdge = PPUA12TogglesOnRaisingEdge; + } + + public BoardInfoAttribute(string boardName, int inesMapperNumber, int defaultPRG_RAM_8KB_BanksCount, int defaultCHR_RAM_1KB_BanksCount, bool Enabled_ppuA12ToggleTimer, bool PPUA12TogglesOnRaisingEdge) + { + Name = boardName; + Mapper = inesMapperNumber; + DefaultPRG_RAM_8KB_BanksCount = defaultPRG_RAM_8KB_BanksCount; + DefaultCHR_RAM_1KB_BanksCount = defaultCHR_RAM_1KB_BanksCount; + this.Enabled_ppuA12ToggleTimer = Enabled_ppuA12ToggleTimer; + this.PPUA12TogglesOnRaisingEdge = PPUA12TogglesOnRaisingEdge; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/BoardInfoObject.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/BoardInfoObject.cs index a18d060..a88579f 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/BoardInfoObject.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/BoardInfoObject.cs @@ -1,15 +1,14 @@ -namespace MyNes.Core -{ - public class BoardInfoObject - { - public string Name { get; internal set; } - - public int MapperNumber { get; internal set; } - - public bool IsSupported { get; internal set; } - - public string Issues { get; internal set; } - - public bool HasIssues { get; internal set; } - } +namespace MyNes.Core; + +public class BoardInfoObject +{ + public string Name { get; internal set; } + + public int MapperNumber { get; internal set; } + + public bool IsSupported { get; internal set; } + + public string Issues { get; internal set; } + + public bool HasIssues { get; internal set; } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/CHRArea.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/CHRArea.cs index 2d66b9a..c1fffa3 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/CHRArea.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/CHRArea.cs @@ -1,14 +1,13 @@ -namespace MyNes.Core -{ - internal enum CHRArea : byte - { - Area0000, - Area0400, - Area0800, - Area0C00, - Area1000, - Area1400, - Area1800, - Area1C00 - } +namespace MyNes.Core; + +internal enum CHRArea : byte +{ + Area0000, + Area0400, + Area0800, + Area0C00, + Area1000, + Area1400, + Area1800, + Area1C00 } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Adler32.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Adler32.cs index 8265834..0a5c8f1 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Adler32.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Adler32.cs @@ -1,72 +1,71 @@ -namespace ComponentAce.Compression.Libs.zlib -{ - internal sealed class Adler32 - { - private const int BASE = 65521; - - private const int NMAX = 5552; - - internal long adler32(long adler, byte[] buf, int index, int len) - { - if (buf == null) - { - return 1L; - } - long num = adler & 0xFFFF; - long num2 = (adler >> 16) & 0xFFFF; - while (len > 0) - { - int num3 = ((len < 5552) ? len : 5552); - len -= num3; - while (num3 >= 16) - { - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num += buf[index++] & 0xFF; - num2 += num; - num3 -= 16; - } - if (num3 != 0) - { - do - { - num += buf[index++] & 0xFF; - num2 += num; - } - while (--num3 != 0); - } - num %= 65521; - num2 %= 65521; - } - return (num2 << 16) | num; - } - } +namespace ComponentAce.Compression.Libs.zlib; + +internal sealed class Adler32 +{ + private const int BASE = 65521; + + private const int NMAX = 5552; + + internal long adler32(long adler, byte[] buf, int index, int len) + { + if (buf == null) + { + return 1L; + } + long num = adler & 0xFFFF; + long num2 = (adler >> 16) & 0xFFFF; + while (len > 0) + { + int num3 = ((len < 5552) ? len : 5552); + len -= num3; + while (num3 >= 16) + { + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num += buf[index++] & 0xFF; + num2 += num; + num3 -= 16; + } + if (num3 != 0) + { + do + { + num += buf[index++] & 0xFF; + num2 += num; + } + while (--num3 != 0); + } + num %= 65521; + num2 %= 65521; + } + return (num2 << 16) | num; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Deflate.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Deflate.cs index ce31c52..a0862ed 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Deflate.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Deflate.cs @@ -1,1379 +1,1411 @@ -using System; - -namespace ComponentAce.Compression.Libs.zlib -{ - public sealed class Deflate - { - internal class Config - { - internal int good_length; - - internal int max_lazy; - - internal int nice_length; - - internal int max_chain; - - internal int func; - - internal Config(int good_length, int max_lazy, int nice_length, int max_chain, int func) - { - this.good_length = good_length; - this.max_lazy = max_lazy; - this.nice_length = nice_length; - this.max_chain = max_chain; - this.func = func; - } - } - - private const int MAX_MEM_LEVEL = 9; - - private const int Z_DEFAULT_COMPRESSION = -1; - - private const int MAX_WBITS = 15; - - private const int DEF_MEM_LEVEL = 8; - - private const int STORED = 0; - - private const int FAST = 1; - - private const int SLOW = 2; - - private static Config[] config_table; - - private static readonly string[] z_errmsg; - - private const int NeedMore = 0; - - private const int BlockDone = 1; - - private const int FinishStarted = 2; - - private const int FinishDone = 3; - - private const int PRESET_DICT = 32; - - private const int Z_FILTERED = 1; - - private const int Z_HUFFMAN_ONLY = 2; - - private const int Z_DEFAULT_STRATEGY = 0; - - private const int Z_NO_FLUSH = 0; - - private const int Z_PARTIAL_FLUSH = 1; - - private const int Z_SYNC_FLUSH = 2; - - private const int Z_FULL_FLUSH = 3; - - private const int Z_FINISH = 4; - - private const int Z_OK = 0; - - private const int Z_STREAM_END = 1; - - private const int Z_NEED_DICT = 2; - - private const int Z_ERRNO = -1; - - private const int Z_STREAM_ERROR = -2; - - private const int Z_DATA_ERROR = -3; - - private const int Z_MEM_ERROR = -4; - - private const int Z_BUF_ERROR = -5; - - private const int Z_VERSION_ERROR = -6; - - private const int INIT_STATE = 42; - - private const int BUSY_STATE = 113; - - private const int FINISH_STATE = 666; - - private const int Z_DEFLATED = 8; - - private const int STORED_BLOCK = 0; - - private const int STATIC_TREES = 1; - - private const int DYN_TREES = 2; - - private const int Z_BINARY = 0; - - private const int Z_ASCII = 1; - - private const int Z_UNKNOWN = 2; - - private const int Buf_size = 16; - - private const int REP_3_6 = 16; - - private const int REPZ_3_10 = 17; - - private const int REPZ_11_138 = 18; - - private const int MIN_MATCH = 3; - - private const int MAX_MATCH = 258; - - private static readonly int MIN_LOOKAHEAD; - - private const int MAX_BITS = 15; - - private const int D_CODES = 30; - - private const int BL_CODES = 19; - - private const int LENGTH_CODES = 29; - - private const int LITERALS = 256; - - private static readonly int L_CODES; - - private static readonly int HEAP_SIZE; - - private const int END_BLOCK = 256; - - internal ZStream strm; - - internal int status; - - internal byte[] pending_buf; - - internal int pending_buf_size; - - internal int pending_out; - - internal int pending; - - internal int noheader; - - internal byte data_type; - - internal byte method; - - internal int last_flush; - - internal int w_size; - - internal int w_bits; - - internal int w_mask; - - internal byte[] window; - - internal int window_size; - - internal short[] prev; - - internal short[] head; - - internal int ins_h; - - internal int hash_size; - - internal int hash_bits; - - internal int hash_mask; - - internal int hash_shift; - - internal int block_start; - - internal int match_length; - - internal int prev_match; - - internal int match_available; - - internal int strstart; - - internal int match_start; - - internal int lookahead; - - internal int prev_length; - - internal int max_chain_length; - - internal int max_lazy_match; - - internal int level; - - internal int strategy; - - internal int good_match; - - internal int nice_match; - - internal short[] dyn_ltree; - - internal short[] dyn_dtree; - - internal short[] bl_tree; - - internal Tree l_desc = new Tree(); - - internal Tree d_desc = new Tree(); - - internal Tree bl_desc = new Tree(); - - internal short[] bl_count = new short[16]; - - internal int[] heap = new int[2 * L_CODES + 1]; - - internal int heap_len; - - internal int heap_max; - - internal byte[] depth = new byte[2 * L_CODES + 1]; - - internal int l_buf; - - internal int lit_bufsize; - - internal int last_lit; - - internal int d_buf; - - internal int opt_len; - - internal int static_len; - - internal int matches; - - internal int last_eob_len; - - internal short bi_buf; - - internal int bi_valid; - - internal Deflate() - { - dyn_ltree = new short[HEAP_SIZE * 2]; - dyn_dtree = new short[122]; - bl_tree = new short[78]; - } - - internal void lm_init() - { - window_size = 2 * w_size; - head[hash_size - 1] = 0; - for (int i = 0; i < hash_size - 1; i++) - { - head[i] = 0; - } - max_lazy_match = config_table[level].max_lazy; - good_match = config_table[level].good_length; - nice_match = config_table[level].nice_length; - max_chain_length = config_table[level].max_chain; - strstart = 0; - block_start = 0; - lookahead = 0; - match_length = (prev_length = 2); - match_available = 0; - ins_h = 0; - } - - internal void tr_init() - { - l_desc.dyn_tree = dyn_ltree; - l_desc.stat_desc = StaticTree.static_l_desc; - d_desc.dyn_tree = dyn_dtree; - d_desc.stat_desc = StaticTree.static_d_desc; - bl_desc.dyn_tree = bl_tree; - bl_desc.stat_desc = StaticTree.static_bl_desc; - bi_buf = 0; - bi_valid = 0; - last_eob_len = 8; - init_block(); - } - - internal void init_block() - { - for (int i = 0; i < L_CODES; i++) - { - dyn_ltree[i * 2] = 0; - } - for (int j = 0; j < 30; j++) - { - dyn_dtree[j * 2] = 0; - } - for (int k = 0; k < 19; k++) - { - bl_tree[k * 2] = 0; - } - dyn_ltree[512] = 1; - opt_len = (static_len = 0); - last_lit = (matches = 0); - } - - internal void pqdownheap(short[] tree, int k) - { - int num = heap[k]; - for (int num2 = k << 1; num2 <= heap_len; num2 <<= 1) - { - if (num2 < heap_len && smaller(tree, heap[num2 + 1], heap[num2], depth)) - { - num2++; - } - if (smaller(tree, num, heap[num2], depth)) - { - break; - } - heap[k] = heap[num2]; - k = num2; - } - heap[k] = num; - } - - internal static bool smaller(short[] tree, int n, int m, byte[] depth) - { - return tree[n * 2] < tree[m * 2] || (tree[n * 2] == tree[m * 2] && depth[n] <= depth[m]); - } - - internal void scan_tree(short[] tree, int max_code) - { - int num = -1; - int num2 = tree[1]; - int num3 = 0; - int num4 = 7; - int num5 = 4; - if (num2 == 0) - { - num4 = 138; - num5 = 3; - } - tree[(max_code + 1) * 2 + 1] = (short)SupportClass.Identity(65535L); - for (int i = 0; i <= max_code; i++) - { - int num6 = num2; - num2 = tree[(i + 1) * 2 + 1]; - if (++num3 < num4 && num6 == num2) - { - continue; - } - if (num3 < num5) - { - bl_tree[num6 * 2] = (short)(bl_tree[num6 * 2] + num3); - } - else if (num6 != 0) - { - if (num6 != num) - { - bl_tree[num6 * 2]++; - } - bl_tree[32]++; - } - else if (num3 <= 10) - { - bl_tree[34]++; - } - else - { - bl_tree[36]++; - } - num3 = 0; - num = num6; - if (num2 == 0) - { - num4 = 138; - num5 = 3; - } - else if (num6 == num2) - { - num4 = 6; - num5 = 3; - } - else - { - num4 = 7; - num5 = 4; - } - } - } - - internal int build_bl_tree() - { - scan_tree(dyn_ltree, l_desc.max_code); - scan_tree(dyn_dtree, d_desc.max_code); - bl_desc.build_tree(this); - int num = 18; - while (num >= 3 && bl_tree[Tree.bl_order[num] * 2 + 1] == 0) - { - num--; - } - opt_len += 3 * (num + 1) + 5 + 5 + 4; - return num; - } - - internal void send_all_trees(int lcodes, int dcodes, int blcodes) - { - send_bits(lcodes - 257, 5); - send_bits(dcodes - 1, 5); - send_bits(blcodes - 4, 4); - for (int i = 0; i < blcodes; i++) - { - send_bits(bl_tree[Tree.bl_order[i] * 2 + 1], 3); - } - send_tree(dyn_ltree, lcodes - 1); - send_tree(dyn_dtree, dcodes - 1); - } - - internal void send_tree(short[] tree, int max_code) - { - int num = -1; - int num2 = tree[1]; - int num3 = 0; - int num4 = 7; - int num5 = 4; - if (num2 == 0) - { - num4 = 138; - num5 = 3; - } - for (int i = 0; i <= max_code; i++) - { - int num6 = num2; - num2 = tree[(i + 1) * 2 + 1]; - if (++num3 < num4 && num6 == num2) - { - continue; - } - if (num3 < num5) - { - do - { - send_code(num6, bl_tree); - } - while (--num3 != 0); - } - else if (num6 != 0) - { - if (num6 != num) - { - send_code(num6, bl_tree); - num3--; - } - send_code(16, bl_tree); - send_bits(num3 - 3, 2); - } - else if (num3 <= 10) - { - send_code(17, bl_tree); - send_bits(num3 - 3, 3); - } - else - { - send_code(18, bl_tree); - send_bits(num3 - 11, 7); - } - num3 = 0; - num = num6; - if (num2 == 0) - { - num4 = 138; - num5 = 3; - } - else if (num6 == num2) - { - num4 = 6; - num5 = 3; - } - else - { - num4 = 7; - num5 = 4; - } - } - } - - internal void put_byte(byte[] p, int start, int len) - { - Array.Copy(p, start, pending_buf, pending, len); - pending += len; - } - - internal void put_byte(byte c) - { - pending_buf[pending++] = c; - } - - internal void put_short(int w) - { - put_byte((byte)w); - put_byte((byte)SupportClass.URShift(w, 8)); - } - - internal void putShortMSB(int b) - { - put_byte((byte)(b >> 8)); - put_byte((byte)b); - } - - internal void send_code(int c, short[] tree) - { - send_bits(tree[c * 2] & 0xFFFF, tree[c * 2 + 1] & 0xFFFF); - } - - internal void send_bits(int value_Renamed, int length) - { - if (bi_valid > 16 - length) - { - bi_buf = (short)((ushort)bi_buf | (ushort)((value_Renamed << bi_valid) & 0xFFFF)); - put_short(bi_buf); - bi_buf = (short)SupportClass.URShift(value_Renamed, 16 - bi_valid); - bi_valid += length - 16; - } - else - { - bi_buf = (short)((ushort)bi_buf | (ushort)((value_Renamed << bi_valid) & 0xFFFF)); - bi_valid += length; - } - } - - internal void _tr_align() - { - send_bits(2, 3); - send_code(256, StaticTree.static_ltree); - bi_flush(); - if (1 + last_eob_len + 10 - bi_valid < 9) - { - send_bits(2, 3); - send_code(256, StaticTree.static_ltree); - bi_flush(); - } - last_eob_len = 7; - } - - internal bool _tr_tally(int dist, int lc) - { - pending_buf[d_buf + last_lit * 2] = (byte)SupportClass.URShift(dist, 8); - pending_buf[d_buf + last_lit * 2 + 1] = (byte)dist; - pending_buf[l_buf + last_lit] = (byte)lc; - last_lit++; - if (dist == 0) - { - dyn_ltree[lc * 2]++; - } - else - { - matches++; - dist--; - dyn_ltree[(Tree._length_code[lc] + 256 + 1) * 2]++; - dyn_dtree[Tree.d_code(dist) * 2]++; - } - if ((last_lit & 0x1FFF) == 0 && level > 2) - { - int num = last_lit * 8; - int num2 = strstart - block_start; - for (int i = 0; i < 30; i++) - { - num = (int)(num + dyn_dtree[i * 2] * (5L + (long)Tree.extra_dbits[i])); - } - num = SupportClass.URShift(num, 3); - if (matches < last_lit / 2 && num < num2 / 2) - { - return true; - } - } - return last_lit == lit_bufsize - 1; - } - - internal void compress_block(short[] ltree, short[] dtree) - { - int num = 0; - if (last_lit != 0) - { - do - { - int num2 = ((pending_buf[d_buf + num * 2] << 8) & 0xFF00) | (pending_buf[d_buf + num * 2 + 1] & 0xFF); - int num3 = pending_buf[l_buf + num] & 0xFF; - num++; - if (num2 == 0) - { - send_code(num3, ltree); - continue; - } - int num4 = Tree._length_code[num3]; - send_code(num4 + 256 + 1, ltree); - int num5 = Tree.extra_lbits[num4]; - if (num5 != 0) - { - num3 -= Tree.base_length[num4]; - send_bits(num3, num5); - } - num2--; - num4 = Tree.d_code(num2); - send_code(num4, dtree); - num5 = Tree.extra_dbits[num4]; - if (num5 != 0) - { - num2 -= Tree.base_dist[num4]; - send_bits(num2, num5); - } - } - while (num < last_lit); - } - send_code(256, ltree); - last_eob_len = ltree[513]; - } - - internal void set_data_type() - { - int i = 0; - int num = 0; - int num2 = 0; - for (; i < 7; i++) - { - num2 += dyn_ltree[i * 2]; - } - for (; i < 128; i++) - { - num += dyn_ltree[i * 2]; - } - for (; i < 256; i++) - { - num2 += dyn_ltree[i * 2]; - } - data_type = (byte)((num2 <= SupportClass.URShift(num, 2)) ? 1u : 0u); - } - - internal void bi_flush() - { - if (bi_valid == 16) - { - put_short(bi_buf); - bi_buf = 0; - bi_valid = 0; - } - else if (bi_valid >= 8) - { - put_byte((byte)bi_buf); - bi_buf = (short)SupportClass.URShift(bi_buf, 8); - bi_valid -= 8; - } - } - - internal void bi_windup() - { - if (bi_valid > 8) - { - put_short(bi_buf); - } - else if (bi_valid > 0) - { - put_byte((byte)bi_buf); - } - bi_buf = 0; - bi_valid = 0; - } - - internal void copy_block(int buf, int len, bool header) - { - bi_windup(); - last_eob_len = 8; - if (header) - { - put_short((short)len); - put_short((short)(~len)); - } - put_byte(window, buf, len); - } - - internal void flush_block_only(bool eof) - { - _tr_flush_block((block_start >= 0) ? block_start : (-1), strstart - block_start, eof); - block_start = strstart; - strm.flush_pending(); - } - - internal int deflate_stored(int flush) - { - int num = 65535; - if (num > pending_buf_size - 5) - { - num = pending_buf_size - 5; - } - while (true) - { - if (lookahead <= 1) - { - fill_window(); - if (lookahead == 0 && flush == 0) - { - return 0; - } - if (lookahead == 0) - { - break; - } - } - strstart += lookahead; - lookahead = 0; - int num2 = block_start + num; - if (strstart == 0 || strstart >= num2) - { - lookahead = strstart - num2; - strstart = num2; - flush_block_only(eof: false); - if (strm.avail_out == 0) - { - return 0; - } - } - if (strstart - block_start >= w_size - MIN_LOOKAHEAD) - { - flush_block_only(eof: false); - if (strm.avail_out == 0) - { - return 0; - } - } - } - flush_block_only(flush == 4); - if (strm.avail_out == 0) - { - return (flush == 4) ? 2 : 0; - } - return (flush != 4) ? 1 : 3; - } - - internal void _tr_stored_block(int buf, int stored_len, bool eof) - { - send_bits(eof ? 1 : 0, 3); - copy_block(buf, stored_len, header: true); - } - - internal void _tr_flush_block(int buf, int stored_len, bool eof) - { - int num = 0; - int num2; - int num3; - if (level > 0) - { - if (data_type == 2) - { - set_data_type(); - } - l_desc.build_tree(this); - d_desc.build_tree(this); - num = build_bl_tree(); - num2 = SupportClass.URShift(opt_len + 3 + 7, 3); - num3 = SupportClass.URShift(static_len + 3 + 7, 3); - if (num3 <= num2) - { - num2 = num3; - } - } - else - { - num2 = (num3 = stored_len + 5); - } - if (stored_len + 4 <= num2 && buf != -1) - { - _tr_stored_block(buf, stored_len, eof); - } - else if (num3 == num2) - { - send_bits(2 + (eof ? 1 : 0), 3); - compress_block(StaticTree.static_ltree, StaticTree.static_dtree); - } - else - { - send_bits(4 + (eof ? 1 : 0), 3); - send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, num + 1); - compress_block(dyn_ltree, dyn_dtree); - } - init_block(); - if (eof) - { - bi_windup(); - } - } - - internal void fill_window() - { - do - { - int num = window_size - lookahead - strstart; - int num2; - if (num == 0 && strstart == 0 && lookahead == 0) - { - num = w_size; - } - else if (num == -1) - { - num--; - } - else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) - { - Array.Copy(window, w_size, window, 0, w_size); - match_start -= w_size; - strstart -= w_size; - block_start -= w_size; - num2 = hash_size; - int num3 = num2; - do - { - int num4 = head[--num3] & 0xFFFF; - head[num3] = (short)((num4 >= w_size) ? (num4 - w_size) : 0); - } - while (--num2 != 0); - num2 = w_size; - num3 = num2; - do - { - int num4 = prev[--num3] & 0xFFFF; - prev[num3] = (short)((num4 >= w_size) ? (num4 - w_size) : 0); - } - while (--num2 != 0); - num += w_size; - } - if (strm.avail_in == 0) - { - break; - } - num2 = strm.read_buf(window, strstart + lookahead, num); - lookahead += num2; - if (lookahead >= 3) - { - ins_h = window[strstart] & 0xFF; - ins_h = ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xFF)) & hash_mask; - } - } - while (lookahead < MIN_LOOKAHEAD && strm.avail_in != 0); - } - - internal int deflate_fast(int flush) - { - int num = 0; - while (true) - { - if (lookahead < MIN_LOOKAHEAD) - { - fill_window(); - if (lookahead < MIN_LOOKAHEAD && flush == 0) - { - return 0; - } - if (lookahead == 0) - { - break; - } - } - if (lookahead >= 3) - { - ins_h = ((ins_h << hash_shift) ^ (window[strstart + 2] & 0xFF)) & hash_mask; - num = head[ins_h] & 0xFFFF; - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = (short)strstart; - } - if (num != 0L && ((strstart - num) & 0xFFFF) <= w_size - MIN_LOOKAHEAD && strategy != 2) - { - match_length = longest_match(num); - } - bool flag; - if (match_length >= 3) - { - flag = _tr_tally(strstart - match_start, match_length - 3); - lookahead -= match_length; - if (match_length <= max_lazy_match && lookahead >= 3) - { - match_length--; - do - { - strstart++; - ins_h = ((ins_h << hash_shift) ^ (window[strstart + 2] & 0xFF)) & hash_mask; - num = head[ins_h] & 0xFFFF; - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = (short)strstart; - } - while (--match_length != 0); - strstart++; - } - else - { - strstart += match_length; - match_length = 0; - ins_h = window[strstart] & 0xFF; - ins_h = ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xFF)) & hash_mask; - } - } - else - { - flag = _tr_tally(0, window[strstart] & 0xFF); - lookahead--; - strstart++; - } - if (flag) - { - flush_block_only(eof: false); - if (strm.avail_out == 0) - { - return 0; - } - } - } - flush_block_only(flush == 4); - if (strm.avail_out == 0) - { - if (flush == 4) - { - return 2; - } - return 0; - } - return (flush != 4) ? 1 : 3; - } - - internal int deflate_slow(int flush) - { - int num = 0; - while (true) - { - if (lookahead < MIN_LOOKAHEAD) - { - fill_window(); - if (lookahead < MIN_LOOKAHEAD && flush == 0) - { - return 0; - } - if (lookahead == 0) - { - break; - } - } - if (lookahead >= 3) - { - ins_h = ((ins_h << hash_shift) ^ (window[strstart + 2] & 0xFF)) & hash_mask; - num = head[ins_h] & 0xFFFF; - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = (short)strstart; - } - prev_length = match_length; - prev_match = match_start; - match_length = 2; - if (num != 0 && prev_length < max_lazy_match && ((strstart - num) & 0xFFFF) <= w_size - MIN_LOOKAHEAD) - { - if (strategy != 2) - { - match_length = longest_match(num); - } - if (match_length <= 5 && (strategy == 1 || (match_length == 3 && strstart - match_start > 4096))) - { - match_length = 2; - } - } - if (prev_length >= 3 && match_length <= prev_length) - { - int num2 = strstart + lookahead - 3; - bool flag = _tr_tally(strstart - 1 - prev_match, prev_length - 3); - lookahead -= prev_length - 1; - prev_length -= 2; - do - { - if (++strstart <= num2) - { - ins_h = ((ins_h << hash_shift) ^ (window[strstart + 2] & 0xFF)) & hash_mask; - num = head[ins_h] & 0xFFFF; - prev[strstart & w_mask] = head[ins_h]; - head[ins_h] = (short)strstart; - } - } - while (--prev_length != 0); - match_available = 0; - match_length = 2; - strstart++; - if (flag) - { - flush_block_only(eof: false); - if (strm.avail_out == 0) - { - return 0; - } - } - } - else if (match_available != 0) - { - if (_tr_tally(0, window[strstart - 1] & 0xFF)) - { - flush_block_only(eof: false); - } - strstart++; - lookahead--; - if (strm.avail_out == 0) - { - return 0; - } - } - else - { - match_available = 1; - strstart++; - lookahead--; - } - } - if (match_available != 0) - { - bool flag = _tr_tally(0, window[strstart - 1] & 0xFF); - match_available = 0; - } - flush_block_only(flush == 4); - if (strm.avail_out == 0) - { - if (flush == 4) - { - return 2; - } - return 0; - } - return (flush != 4) ? 1 : 3; - } - - internal int longest_match(int cur_match) - { - int num = max_chain_length; - int num2 = strstart; - int num3 = prev_length; - int num4 = ((strstart > w_size - MIN_LOOKAHEAD) ? (strstart - (w_size - MIN_LOOKAHEAD)) : 0); - int num5 = nice_match; - int num6 = w_mask; - int num7 = strstart + 258; - byte b = window[num2 + num3 - 1]; - byte b2 = window[num2 + num3]; - if (prev_length >= good_match) - { - num >>= 2; - } - if (num5 > lookahead) - { - num5 = lookahead; - } - do - { - int num8 = cur_match; - if (window[num8 + num3] != b2 || window[num8 + num3 - 1] != b || window[num8] != window[num2] || window[++num8] != window[num2 + 1]) - { - continue; - } - num2 += 2; - num8++; - while (window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && num2 < num7) - { - } - int num9 = 258 - (num7 - num2); - num2 = num7 - 258; - if (num9 > num3) - { - match_start = cur_match; - num3 = num9; - if (num9 >= num5) - { - break; - } - b = window[num2 + num3 - 1]; - b2 = window[num2 + num3]; - } - } - while ((cur_match = prev[cur_match & num6] & 0xFFFF) > num4 && --num != 0); - if (num3 <= lookahead) - { - return num3; - } - return lookahead; - } - - internal int deflateInit(ZStream strm, int level, int bits) - { - return deflateInit2(strm, level, 8, bits, 8, 0); - } - - internal int deflateInit(ZStream strm, int level) - { - return deflateInit(strm, level, 15); - } - - internal int deflateInit2(ZStream strm, int level, int method, int windowBits, int memLevel, int strategy) - { - int num = 0; - strm.msg = null; - if (level == -1) - { - level = 6; - } - if (windowBits < 0) - { - num = 1; - windowBits = -windowBits; - } - if (memLevel < 1 || memLevel > 9 || method != 8 || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > 2) - { - return -2; - } - strm.dstate = this; - noheader = num; - w_bits = windowBits; - w_size = 1 << w_bits; - w_mask = w_size - 1; - hash_bits = memLevel + 7; - hash_size = 1 << hash_bits; - hash_mask = hash_size - 1; - hash_shift = (hash_bits + 3 - 1) / 3; - window = new byte[w_size * 2]; - prev = new short[w_size]; - head = new short[hash_size]; - lit_bufsize = 1 << memLevel + 6; - pending_buf = new byte[lit_bufsize * 4]; - pending_buf_size = lit_bufsize * 4; - d_buf = lit_bufsize; - l_buf = 3 * lit_bufsize; - this.level = level; - this.strategy = strategy; - this.method = (byte)method; - return deflateReset(strm); - } - - internal int deflateReset(ZStream strm) - { - strm.total_in = (strm.total_out = 0L); - strm.msg = null; - strm.data_type = 2; - pending = 0; - pending_out = 0; - if (noheader < 0) - { - noheader = 0; - } - status = ((noheader != 0) ? 113 : 42); - strm.adler = strm._adler.adler32(0L, null, 0, 0); - last_flush = 0; - tr_init(); - lm_init(); - return 0; - } - - internal int deflateEnd() - { - if (status != 42 && status != 113 && status != 666) - { - return -2; - } - pending_buf = null; - head = null; - prev = null; - window = null; - return (status == 113) ? (-3) : 0; - } - - internal int deflateParams(ZStream strm, int _level, int _strategy) - { - int result = 0; - if (_level == -1) - { - _level = 6; - } - if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > 2) - { - return -2; - } - if (config_table[level].func != config_table[_level].func && strm.total_in != 0) - { - result = strm.deflate(1); - } - if (level != _level) - { - level = _level; - max_lazy_match = config_table[level].max_lazy; - good_match = config_table[level].good_length; - nice_match = config_table[level].nice_length; - max_chain_length = config_table[level].max_chain; - } - strategy = _strategy; - return result; - } - - internal int deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength) - { - int num = dictLength; - int sourceIndex = 0; - if (dictionary == null || status != 42) - { - return -2; - } - strm.adler = strm._adler.adler32(strm.adler, dictionary, 0, dictLength); - if (num < 3) - { - return 0; - } - if (num > w_size - MIN_LOOKAHEAD) - { - num = w_size - MIN_LOOKAHEAD; - sourceIndex = dictLength - num; - } - Array.Copy(dictionary, sourceIndex, window, 0, num); - strstart = num; - block_start = num; - ins_h = window[0] & 0xFF; - ins_h = ((ins_h << hash_shift) ^ (window[1] & 0xFF)) & hash_mask; - for (int i = 0; i <= num - 3; i++) - { - ins_h = ((ins_h << hash_shift) ^ (window[i + 2] & 0xFF)) & hash_mask; - prev[i & w_mask] = head[ins_h]; - head[ins_h] = (short)i; - } - return 0; - } - - internal int deflate(ZStream strm, int flush) - { - if (flush > 4 || flush < 0) - { - return -2; - } - if (strm.next_out == null || (strm.next_in == null && strm.avail_in != 0) || (status == 666 && flush != 4)) - { - strm.msg = z_errmsg[4]; - return -2; - } - if (strm.avail_out == 0) - { - strm.msg = z_errmsg[7]; - return -5; - } - this.strm = strm; - int num = last_flush; - last_flush = flush; - if (status == 42) - { - int num2 = 8 + (w_bits - 8 << 4) << 8; - int num3 = ((level - 1) & 0xFF) >> 1; - if (num3 > 3) - { - num3 = 3; - } - num2 |= num3 << 6; - if (strstart != 0) - { - num2 |= 0x20; - } - num2 += 31 - num2 % 31; - status = 113; - putShortMSB(num2); - if (strstart != 0) - { - putShortMSB((int)SupportClass.URShift(strm.adler, 16)); - putShortMSB((int)(strm.adler & 0xFFFF)); - } - strm.adler = strm._adler.adler32(0L, null, 0, 0); - } - if (pending != 0) - { - strm.flush_pending(); - if (strm.avail_out == 0) - { - last_flush = -1; - return 0; - } - } - else if (strm.avail_in == 0 && flush <= num && flush != 4) - { - strm.msg = z_errmsg[7]; - return -5; - } - if (status == 666 && strm.avail_in != 0) - { - strm.msg = z_errmsg[7]; - return -5; - } - if (strm.avail_in != 0 || lookahead != 0 || (flush != 0 && status != 666)) - { - int num4 = -1; - switch (config_table[level].func) - { - case 0: - num4 = deflate_stored(flush); - break; - case 1: - num4 = deflate_fast(flush); - break; - case 2: - num4 = deflate_slow(flush); - break; - } - if (num4 == 2 || num4 == 3) - { - status = 666; - } - if (num4 == 0 || num4 == 2) - { - if (strm.avail_out == 0) - { - last_flush = -1; - } - return 0; - } - if (num4 == 1) - { - if (flush == 1) - { - _tr_align(); - } - else - { - _tr_stored_block(0, 0, eof: false); - if (flush == 3) - { - for (int i = 0; i < hash_size; i++) - { - head[i] = 0; - } - } - } - strm.flush_pending(); - if (strm.avail_out == 0) - { - last_flush = -1; - return 0; - } - } - } - if (flush != 4) - { - return 0; - } - if (noheader != 0) - { - return 1; - } - putShortMSB((int)SupportClass.URShift(strm.adler, 16)); - putShortMSB((int)(strm.adler & 0xFFFF)); - strm.flush_pending(); - noheader = -1; - return (pending == 0) ? 1 : 0; - } - - static Deflate() - { - z_errmsg = new string[10] { "need dictionary", "stream end", "", "file error", "stream error", "data error", "insufficient memory", "buffer error", "incompatible version", "" }; - MIN_LOOKAHEAD = 262; - L_CODES = 286; - HEAP_SIZE = 2 * L_CODES + 1; - config_table = new Config[10]; - config_table[0] = new Config(0, 0, 0, 0, 0); - config_table[1] = new Config(4, 4, 8, 4, 1); - config_table[2] = new Config(4, 5, 16, 8, 1); - config_table[3] = new Config(4, 6, 32, 32, 1); - config_table[4] = new Config(4, 4, 16, 16, 2); - config_table[5] = new Config(8, 16, 32, 32, 2); - config_table[6] = new Config(8, 16, 128, 128, 2); - config_table[7] = new Config(8, 32, 128, 256, 2); - config_table[8] = new Config(32, 128, 258, 1024, 2); - config_table[9] = new Config(32, 258, 258, 4096, 2); - } - } +using System; + +namespace ComponentAce.Compression.Libs.zlib; + +public sealed class Deflate +{ + internal class Config + { + internal int good_length; + + internal int max_lazy; + + internal int nice_length; + + internal int max_chain; + + internal int func; + + internal Config(int good_length, int max_lazy, int nice_length, int max_chain, int func) + { + this.good_length = good_length; + this.max_lazy = max_lazy; + this.nice_length = nice_length; + this.max_chain = max_chain; + this.func = func; + } + } + + private const int MAX_MEM_LEVEL = 9; + + private const int Z_DEFAULT_COMPRESSION = -1; + + private const int MAX_WBITS = 15; + + private const int DEF_MEM_LEVEL = 8; + + private const int STORED = 0; + + private const int FAST = 1; + + private const int SLOW = 2; + + private static Config[] config_table; + + private static readonly string[] z_errmsg; + + private const int NeedMore = 0; + + private const int BlockDone = 1; + + private const int FinishStarted = 2; + + private const int FinishDone = 3; + + private const int PRESET_DICT = 32; + + private const int Z_FILTERED = 1; + + private const int Z_HUFFMAN_ONLY = 2; + + private const int Z_DEFAULT_STRATEGY = 0; + + private const int Z_NO_FLUSH = 0; + + private const int Z_PARTIAL_FLUSH = 1; + + private const int Z_SYNC_FLUSH = 2; + + private const int Z_FULL_FLUSH = 3; + + private const int Z_FINISH = 4; + + private const int Z_OK = 0; + + private const int Z_STREAM_END = 1; + + private const int Z_NEED_DICT = 2; + + private const int Z_ERRNO = -1; + + private const int Z_STREAM_ERROR = -2; + + private const int Z_DATA_ERROR = -3; + + private const int Z_MEM_ERROR = -4; + + private const int Z_BUF_ERROR = -5; + + private const int Z_VERSION_ERROR = -6; + + private const int INIT_STATE = 42; + + private const int BUSY_STATE = 113; + + private const int FINISH_STATE = 666; + + private const int Z_DEFLATED = 8; + + private const int STORED_BLOCK = 0; + + private const int STATIC_TREES = 1; + + private const int DYN_TREES = 2; + + private const int Z_BINARY = 0; + + private const int Z_ASCII = 1; + + private const int Z_UNKNOWN = 2; + + private const int Buf_size = 16; + + private const int REP_3_6 = 16; + + private const int REPZ_3_10 = 17; + + private const int REPZ_11_138 = 18; + + private const int MIN_MATCH = 3; + + private const int MAX_MATCH = 258; + + private static readonly int MIN_LOOKAHEAD; + + private const int MAX_BITS = 15; + + private const int D_CODES = 30; + + private const int BL_CODES = 19; + + private const int LENGTH_CODES = 29; + + private const int LITERALS = 256; + + private static readonly int L_CODES; + + private static readonly int HEAP_SIZE; + + private const int END_BLOCK = 256; + + internal ZStream strm; + + internal int status; + + internal byte[] pending_buf; + + internal int pending_buf_size; + + internal int pending_out; + + internal int pending; + + internal int noheader; + + internal byte data_type; + + internal byte method; + + internal int last_flush; + + internal int w_size; + + internal int w_bits; + + internal int w_mask; + + internal byte[] window; + + internal int window_size; + + internal short[] prev; + + internal short[] head; + + internal int ins_h; + + internal int hash_size; + + internal int hash_bits; + + internal int hash_mask; + + internal int hash_shift; + + internal int block_start; + + internal int match_length; + + internal int prev_match; + + internal int match_available; + + internal int strstart; + + internal int match_start; + + internal int lookahead; + + internal int prev_length; + + internal int max_chain_length; + + internal int max_lazy_match; + + internal int level; + + internal int strategy; + + internal int good_match; + + internal int nice_match; + + internal short[] dyn_ltree; + + internal short[] dyn_dtree; + + internal short[] bl_tree; + + internal Tree l_desc = new Tree(); + + internal Tree d_desc = new Tree(); + + internal Tree bl_desc = new Tree(); + + internal short[] bl_count = new short[16]; + + internal int[] heap = new int[2 * L_CODES + 1]; + + internal int heap_len; + + internal int heap_max; + + internal byte[] depth = new byte[2 * L_CODES + 1]; + + internal int l_buf; + + internal int lit_bufsize; + + internal int last_lit; + + internal int d_buf; + + internal int opt_len; + + internal int static_len; + + internal int matches; + + internal int last_eob_len; + + internal short bi_buf; + + internal int bi_valid; + + internal Deflate() + { + dyn_ltree = new short[HEAP_SIZE * 2]; + dyn_dtree = new short[122]; + bl_tree = new short[78]; + } + + internal void lm_init() + { + window_size = 2 * w_size; + head[hash_size - 1] = 0; + for (int i = 0; i < hash_size - 1; i++) + { + head[i] = 0; + } + max_lazy_match = config_table[level].max_lazy; + good_match = config_table[level].good_length; + nice_match = config_table[level].nice_length; + max_chain_length = config_table[level].max_chain; + strstart = 0; + block_start = 0; + lookahead = 0; + match_length = (prev_length = 2); + match_available = 0; + ins_h = 0; + } + + internal void tr_init() + { + l_desc.dyn_tree = dyn_ltree; + l_desc.stat_desc = StaticTree.static_l_desc; + d_desc.dyn_tree = dyn_dtree; + d_desc.stat_desc = StaticTree.static_d_desc; + bl_desc.dyn_tree = bl_tree; + bl_desc.stat_desc = StaticTree.static_bl_desc; + bi_buf = 0; + bi_valid = 0; + last_eob_len = 8; + init_block(); + } + + internal void init_block() + { + for (int i = 0; i < L_CODES; i++) + { + dyn_ltree[i * 2] = 0; + } + for (int j = 0; j < 30; j++) + { + dyn_dtree[j * 2] = 0; + } + for (int k = 0; k < 19; k++) + { + bl_tree[k * 2] = 0; + } + dyn_ltree[512] = 1; + opt_len = (static_len = 0); + last_lit = (matches = 0); + } + + internal void pqdownheap(short[] tree, int k) + { + int num = heap[k]; + for (int num2 = k << 1; num2 <= heap_len; num2 <<= 1) + { + if (num2 < heap_len && smaller(tree, heap[num2 + 1], heap[num2], depth)) + { + num2++; + } + if (smaller(tree, num, heap[num2], depth)) + { + break; + } + heap[k] = heap[num2]; + k = num2; + } + heap[k] = num; + } + + internal static bool smaller(short[] tree, int n, int m, byte[] depth) + { + if (tree[n * 2] >= tree[m * 2]) + { + if (tree[n * 2] == tree[m * 2]) + { + return depth[n] <= depth[m]; + } + return false; + } + return true; + } + + internal void scan_tree(short[] tree, int max_code) + { + int num = -1; + int num2 = tree[1]; + int num3 = 0; + int num4 = 7; + int num5 = 4; + if (num2 == 0) + { + num4 = 138; + num5 = 3; + } + tree[(max_code + 1) * 2 + 1] = (short)SupportClass.Identity(65535L); + for (int i = 0; i <= max_code; i++) + { + int num6 = num2; + num2 = tree[(i + 1) * 2 + 1]; + if (++num3 < num4 && num6 == num2) + { + continue; + } + if (num3 < num5) + { + bl_tree[num6 * 2] = (short)(bl_tree[num6 * 2] + num3); + } + else if (num6 != 0) + { + if (num6 != num) + { + bl_tree[num6 * 2]++; + } + bl_tree[32]++; + } + else if (num3 <= 10) + { + bl_tree[34]++; + } + else + { + bl_tree[36]++; + } + num3 = 0; + num = num6; + if (num2 == 0) + { + num4 = 138; + num5 = 3; + } + else if (num6 == num2) + { + num4 = 6; + num5 = 3; + } + else + { + num4 = 7; + num5 = 4; + } + } + } + + internal int build_bl_tree() + { + scan_tree(dyn_ltree, l_desc.max_code); + scan_tree(dyn_dtree, d_desc.max_code); + bl_desc.build_tree(this); + int num = 18; + while (num >= 3 && bl_tree[Tree.bl_order[num] * 2 + 1] == 0) + { + num--; + } + opt_len += 3 * (num + 1) + 5 + 5 + 4; + return num; + } + + internal void send_all_trees(int lcodes, int dcodes, int blcodes) + { + send_bits(lcodes - 257, 5); + send_bits(dcodes - 1, 5); + send_bits(blcodes - 4, 4); + for (int i = 0; i < blcodes; i++) + { + send_bits(bl_tree[Tree.bl_order[i] * 2 + 1], 3); + } + send_tree(dyn_ltree, lcodes - 1); + send_tree(dyn_dtree, dcodes - 1); + } + + internal void send_tree(short[] tree, int max_code) + { + int num = -1; + int num2 = tree[1]; + int num3 = 0; + int num4 = 7; + int num5 = 4; + if (num2 == 0) + { + num4 = 138; + num5 = 3; + } + for (int i = 0; i <= max_code; i++) + { + int num6 = num2; + num2 = tree[(i + 1) * 2 + 1]; + if (++num3 < num4 && num6 == num2) + { + continue; + } + if (num3 < num5) + { + do + { + send_code(num6, bl_tree); + } + while (--num3 != 0); + } + else if (num6 != 0) + { + if (num6 != num) + { + send_code(num6, bl_tree); + num3--; + } + send_code(16, bl_tree); + send_bits(num3 - 3, 2); + } + else if (num3 <= 10) + { + send_code(17, bl_tree); + send_bits(num3 - 3, 3); + } + else + { + send_code(18, bl_tree); + send_bits(num3 - 11, 7); + } + num3 = 0; + num = num6; + if (num2 == 0) + { + num4 = 138; + num5 = 3; + } + else if (num6 == num2) + { + num4 = 6; + num5 = 3; + } + else + { + num4 = 7; + num5 = 4; + } + } + } + + internal void put_byte(byte[] p, int start, int len) + { + Array.Copy(p, start, pending_buf, pending, len); + pending += len; + } + + internal void put_byte(byte c) + { + pending_buf[pending++] = c; + } + + internal void put_short(int w) + { + put_byte((byte)w); + put_byte((byte)SupportClass.URShift(w, 8)); + } + + internal void putShortMSB(int b) + { + put_byte((byte)(b >> 8)); + put_byte((byte)b); + } + + internal void send_code(int c, short[] tree) + { + send_bits(tree[c * 2] & 0xFFFF, tree[c * 2 + 1] & 0xFFFF); + } + + internal void send_bits(int value_Renamed, int length) + { + if (bi_valid > 16 - length) + { + bi_buf = (short)((ushort)bi_buf | (ushort)((value_Renamed << bi_valid) & 0xFFFF)); + put_short(bi_buf); + bi_buf = (short)SupportClass.URShift(value_Renamed, 16 - bi_valid); + bi_valid += length - 16; + } + else + { + bi_buf = (short)((ushort)bi_buf | (ushort)((value_Renamed << bi_valid) & 0xFFFF)); + bi_valid += length; + } + } + + internal void _tr_align() + { + send_bits(2, 3); + send_code(256, StaticTree.static_ltree); + bi_flush(); + if (1 + last_eob_len + 10 - bi_valid < 9) + { + send_bits(2, 3); + send_code(256, StaticTree.static_ltree); + bi_flush(); + } + last_eob_len = 7; + } + + internal bool _tr_tally(int dist, int lc) + { + pending_buf[d_buf + last_lit * 2] = (byte)SupportClass.URShift(dist, 8); + pending_buf[d_buf + last_lit * 2 + 1] = (byte)dist; + pending_buf[l_buf + last_lit] = (byte)lc; + last_lit++; + if (dist == 0) + { + dyn_ltree[lc * 2]++; + } + else + { + matches++; + dist--; + dyn_ltree[(Tree._length_code[lc] + 256 + 1) * 2]++; + dyn_dtree[Tree.d_code(dist) * 2]++; + } + if ((last_lit & 0x1FFF) == 0 && level > 2) + { + int num = last_lit * 8; + int num2 = strstart - block_start; + for (int i = 0; i < 30; i++) + { + num = (int)(num + dyn_dtree[i * 2] * (5L + (long)Tree.extra_dbits[i])); + } + num = SupportClass.URShift(num, 3); + if (matches < last_lit / 2 && num < num2 / 2) + { + return true; + } + } + return last_lit == lit_bufsize - 1; + } + + internal void compress_block(short[] ltree, short[] dtree) + { + int num = 0; + if (last_lit != 0) + { + do + { + int num2 = ((pending_buf[d_buf + num * 2] << 8) & 0xFF00) | (pending_buf[d_buf + num * 2 + 1] & 0xFF); + int num3 = pending_buf[l_buf + num] & 0xFF; + num++; + if (num2 == 0) + { + send_code(num3, ltree); + continue; + } + int num4 = Tree._length_code[num3]; + send_code(num4 + 256 + 1, ltree); + int num5 = Tree.extra_lbits[num4]; + if (num5 != 0) + { + num3 -= Tree.base_length[num4]; + send_bits(num3, num5); + } + num2--; + num4 = Tree.d_code(num2); + send_code(num4, dtree); + num5 = Tree.extra_dbits[num4]; + if (num5 != 0) + { + num2 -= Tree.base_dist[num4]; + send_bits(num2, num5); + } + } + while (num < last_lit); + } + send_code(256, ltree); + last_eob_len = ltree[513]; + } + + internal void set_data_type() + { + int i = 0; + int num = 0; + int num2 = 0; + for (; i < 7; i++) + { + num2 += dyn_ltree[i * 2]; + } + for (; i < 128; i++) + { + num += dyn_ltree[i * 2]; + } + for (; i < 256; i++) + { + num2 += dyn_ltree[i * 2]; + } + data_type = (byte)((num2 <= SupportClass.URShift(num, 2)) ? 1u : 0u); + } + + internal void bi_flush() + { + if (bi_valid == 16) + { + put_short(bi_buf); + bi_buf = 0; + bi_valid = 0; + } + else if (bi_valid >= 8) + { + put_byte((byte)bi_buf); + bi_buf = (short)SupportClass.URShift(bi_buf, 8); + bi_valid -= 8; + } + } + + internal void bi_windup() + { + if (bi_valid > 8) + { + put_short(bi_buf); + } + else if (bi_valid > 0) + { + put_byte((byte)bi_buf); + } + bi_buf = 0; + bi_valid = 0; + } + + internal void copy_block(int buf, int len, bool header) + { + bi_windup(); + last_eob_len = 8; + if (header) + { + put_short((short)len); + put_short((short)(~len)); + } + put_byte(window, buf, len); + } + + internal void flush_block_only(bool eof) + { + _tr_flush_block((block_start >= 0) ? block_start : (-1), strstart - block_start, eof); + block_start = strstart; + strm.flush_pending(); + } + + internal int deflate_stored(int flush) + { + int num = 65535; + if (num > pending_buf_size - 5) + { + num = pending_buf_size - 5; + } + while (true) + { + if (lookahead <= 1) + { + fill_window(); + if (lookahead == 0 && flush == 0) + { + return 0; + } + if (lookahead == 0) + { + break; + } + } + strstart += lookahead; + lookahead = 0; + int num2 = block_start + num; + if (strstart == 0 || strstart >= num2) + { + lookahead = strstart - num2; + strstart = num2; + flush_block_only(eof: false); + if (strm.avail_out == 0) + { + return 0; + } + } + if (strstart - block_start >= w_size - MIN_LOOKAHEAD) + { + flush_block_only(eof: false); + if (strm.avail_out == 0) + { + return 0; + } + } + } + flush_block_only(flush == 4); + if (strm.avail_out == 0) + { + if (flush != 4) + { + return 0; + } + return 2; + } + if (flush != 4) + { + return 1; + } + return 3; + } + + internal void _tr_stored_block(int buf, int stored_len, bool eof) + { + send_bits(eof ? 1 : 0, 3); + copy_block(buf, stored_len, header: true); + } + + internal void _tr_flush_block(int buf, int stored_len, bool eof) + { + int num = 0; + int num2; + int num3; + if (level > 0) + { + if (data_type == 2) + { + set_data_type(); + } + l_desc.build_tree(this); + d_desc.build_tree(this); + num = build_bl_tree(); + num2 = SupportClass.URShift(opt_len + 3 + 7, 3); + num3 = SupportClass.URShift(static_len + 3 + 7, 3); + if (num3 <= num2) + { + num2 = num3; + } + } + else + { + num2 = (num3 = stored_len + 5); + } + if (stored_len + 4 <= num2 && buf != -1) + { + _tr_stored_block(buf, stored_len, eof); + } + else if (num3 == num2) + { + send_bits(2 + (eof ? 1 : 0), 3); + compress_block(StaticTree.static_ltree, StaticTree.static_dtree); + } + else + { + send_bits(4 + (eof ? 1 : 0), 3); + send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, num + 1); + compress_block(dyn_ltree, dyn_dtree); + } + init_block(); + if (eof) + { + bi_windup(); + } + } + + internal void fill_window() + { + do + { + int num = window_size - lookahead - strstart; + int num2; + if (num == 0 && strstart == 0 && lookahead == 0) + { + num = w_size; + } + else if (num == -1) + { + num--; + } + else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) + { + Array.Copy(window, w_size, window, 0, w_size); + match_start -= w_size; + strstart -= w_size; + block_start -= w_size; + num2 = hash_size; + int num3 = num2; + do + { + int num4 = head[--num3] & 0xFFFF; + head[num3] = (short)((num4 >= w_size) ? (num4 - w_size) : 0); + } + while (--num2 != 0); + num2 = w_size; + num3 = num2; + do + { + int num4 = prev[--num3] & 0xFFFF; + prev[num3] = (short)((num4 >= w_size) ? (num4 - w_size) : 0); + } + while (--num2 != 0); + num += w_size; + } + if (strm.avail_in == 0) + { + break; + } + num2 = strm.read_buf(window, strstart + lookahead, num); + lookahead += num2; + if (lookahead >= 3) + { + ins_h = window[strstart] & 0xFF; + ins_h = ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xFF)) & hash_mask; + } + } + while (lookahead < MIN_LOOKAHEAD && strm.avail_in != 0); + } + + internal int deflate_fast(int flush) + { + int num = 0; + while (true) + { + if (lookahead < MIN_LOOKAHEAD) + { + fill_window(); + if (lookahead < MIN_LOOKAHEAD && flush == 0) + { + return 0; + } + if (lookahead == 0) + { + break; + } + } + if (lookahead >= 3) + { + ins_h = ((ins_h << hash_shift) ^ (window[strstart + 2] & 0xFF)) & hash_mask; + num = head[ins_h] & 0xFFFF; + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = (short)strstart; + } + if (num != 0L && ((strstart - num) & 0xFFFF) <= w_size - MIN_LOOKAHEAD && strategy != 2) + { + match_length = longest_match(num); + } + bool flag; + if (match_length >= 3) + { + flag = _tr_tally(strstart - match_start, match_length - 3); + lookahead -= match_length; + if (match_length <= max_lazy_match && lookahead >= 3) + { + match_length--; + do + { + strstart++; + ins_h = ((ins_h << hash_shift) ^ (window[strstart + 2] & 0xFF)) & hash_mask; + num = head[ins_h] & 0xFFFF; + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = (short)strstart; + } + while (--match_length != 0); + strstart++; + } + else + { + strstart += match_length; + match_length = 0; + ins_h = window[strstart] & 0xFF; + ins_h = ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xFF)) & hash_mask; + } + } + else + { + flag = _tr_tally(0, window[strstart] & 0xFF); + lookahead--; + strstart++; + } + if (flag) + { + flush_block_only(eof: false); + if (strm.avail_out == 0) + { + return 0; + } + } + } + flush_block_only(flush == 4); + if (strm.avail_out == 0) + { + if (flush == 4) + { + return 2; + } + return 0; + } + if (flush != 4) + { + return 1; + } + return 3; + } + + internal int deflate_slow(int flush) + { + int num = 0; + while (true) + { + if (lookahead < MIN_LOOKAHEAD) + { + fill_window(); + if (lookahead < MIN_LOOKAHEAD && flush == 0) + { + return 0; + } + if (lookahead == 0) + { + break; + } + } + if (lookahead >= 3) + { + ins_h = ((ins_h << hash_shift) ^ (window[strstart + 2] & 0xFF)) & hash_mask; + num = head[ins_h] & 0xFFFF; + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = (short)strstart; + } + prev_length = match_length; + prev_match = match_start; + match_length = 2; + if (num != 0 && prev_length < max_lazy_match && ((strstart - num) & 0xFFFF) <= w_size - MIN_LOOKAHEAD) + { + if (strategy != 2) + { + match_length = longest_match(num); + } + if (match_length <= 5 && (strategy == 1 || (match_length == 3 && strstart - match_start > 4096))) + { + match_length = 2; + } + } + if (prev_length >= 3 && match_length <= prev_length) + { + int num2 = strstart + lookahead - 3; + bool flag = _tr_tally(strstart - 1 - prev_match, prev_length - 3); + lookahead -= prev_length - 1; + prev_length -= 2; + do + { + if (++strstart <= num2) + { + ins_h = ((ins_h << hash_shift) ^ (window[strstart + 2] & 0xFF)) & hash_mask; + num = head[ins_h] & 0xFFFF; + prev[strstart & w_mask] = head[ins_h]; + head[ins_h] = (short)strstart; + } + } + while (--prev_length != 0); + match_available = 0; + match_length = 2; + strstart++; + if (flag) + { + flush_block_only(eof: false); + if (strm.avail_out == 0) + { + return 0; + } + } + } + else if (match_available != 0) + { + if (_tr_tally(0, window[strstart - 1] & 0xFF)) + { + flush_block_only(eof: false); + } + strstart++; + lookahead--; + if (strm.avail_out == 0) + { + return 0; + } + } + else + { + match_available = 1; + strstart++; + lookahead--; + } + } + if (match_available != 0) + { + bool flag = _tr_tally(0, window[strstart - 1] & 0xFF); + match_available = 0; + } + flush_block_only(flush == 4); + if (strm.avail_out == 0) + { + if (flush == 4) + { + return 2; + } + return 0; + } + if (flush != 4) + { + return 1; + } + return 3; + } + + internal int longest_match(int cur_match) + { + int num = max_chain_length; + int num2 = strstart; + int num3 = prev_length; + int num4 = ((strstart > w_size - MIN_LOOKAHEAD) ? (strstart - (w_size - MIN_LOOKAHEAD)) : 0); + int num5 = nice_match; + int num6 = w_mask; + int num7 = strstart + 258; + byte b = window[num2 + num3 - 1]; + byte b2 = window[num2 + num3]; + if (prev_length >= good_match) + { + num >>= 2; + } + if (num5 > lookahead) + { + num5 = lookahead; + } + do + { + int num8 = cur_match; + if (window[num8 + num3] != b2 || window[num8 + num3 - 1] != b || window[num8] != window[num2] || window[++num8] != window[num2 + 1]) + { + continue; + } + num2 += 2; + num8++; + while (window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && window[++num2] == window[++num8] && num2 < num7) + { + } + int num9 = 258 - (num7 - num2); + num2 = num7 - 258; + if (num9 > num3) + { + match_start = cur_match; + num3 = num9; + if (num9 >= num5) + { + break; + } + b = window[num2 + num3 - 1]; + b2 = window[num2 + num3]; + } + } + while ((cur_match = prev[cur_match & num6] & 0xFFFF) > num4 && --num != 0); + if (num3 <= lookahead) + { + return num3; + } + return lookahead; + } + + internal int deflateInit(ZStream strm, int level, int bits) + { + return deflateInit2(strm, level, 8, bits, 8, 0); + } + + internal int deflateInit(ZStream strm, int level) + { + return deflateInit(strm, level, 15); + } + + internal int deflateInit2(ZStream strm, int level, int method, int windowBits, int memLevel, int strategy) + { + int num = 0; + strm.msg = null; + if (level == -1) + { + level = 6; + } + if (windowBits < 0) + { + num = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > 9 || method != 8 || windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || strategy < 0 || strategy > 2) + { + return -2; + } + strm.dstate = this; + noheader = num; + w_bits = windowBits; + w_size = 1 << w_bits; + w_mask = w_size - 1; + hash_bits = memLevel + 7; + hash_size = 1 << hash_bits; + hash_mask = hash_size - 1; + hash_shift = (hash_bits + 3 - 1) / 3; + window = new byte[w_size * 2]; + prev = new short[w_size]; + head = new short[hash_size]; + lit_bufsize = 1 << memLevel + 6; + pending_buf = new byte[lit_bufsize * 4]; + pending_buf_size = lit_bufsize * 4; + d_buf = lit_bufsize; + l_buf = 3 * lit_bufsize; + this.level = level; + this.strategy = strategy; + this.method = (byte)method; + return deflateReset(strm); + } + + internal int deflateReset(ZStream strm) + { + strm.total_in = (strm.total_out = 0L); + strm.msg = null; + strm.data_type = 2; + pending = 0; + pending_out = 0; + if (noheader < 0) + { + noheader = 0; + } + status = ((noheader != 0) ? 113 : 42); + strm.adler = strm._adler.adler32(0L, null, 0, 0); + last_flush = 0; + tr_init(); + lm_init(); + return 0; + } + + internal int deflateEnd() + { + if (status != 42 && status != 113 && status != 666) + { + return -2; + } + pending_buf = null; + head = null; + prev = null; + window = null; + if (status != 113) + { + return 0; + } + return -3; + } + + internal int deflateParams(ZStream strm, int _level, int _strategy) + { + int result = 0; + if (_level == -1) + { + _level = 6; + } + if (_level < 0 || _level > 9 || _strategy < 0 || _strategy > 2) + { + return -2; + } + if (config_table[level].func != config_table[_level].func && strm.total_in != 0L) + { + result = strm.deflate(1); + } + if (level != _level) + { + level = _level; + max_lazy_match = config_table[level].max_lazy; + good_match = config_table[level].good_length; + nice_match = config_table[level].nice_length; + max_chain_length = config_table[level].max_chain; + } + strategy = _strategy; + return result; + } + + internal int deflateSetDictionary(ZStream strm, byte[] dictionary, int dictLength) + { + int num = dictLength; + int sourceIndex = 0; + if (dictionary == null || status != 42) + { + return -2; + } + strm.adler = strm._adler.adler32(strm.adler, dictionary, 0, dictLength); + if (num < 3) + { + return 0; + } + if (num > w_size - MIN_LOOKAHEAD) + { + num = w_size - MIN_LOOKAHEAD; + sourceIndex = dictLength - num; + } + Array.Copy(dictionary, sourceIndex, window, 0, num); + strstart = num; + block_start = num; + ins_h = window[0] & 0xFF; + ins_h = ((ins_h << hash_shift) ^ (window[1] & 0xFF)) & hash_mask; + for (int i = 0; i <= num - 3; i++) + { + ins_h = ((ins_h << hash_shift) ^ (window[i + 2] & 0xFF)) & hash_mask; + prev[i & w_mask] = head[ins_h]; + head[ins_h] = (short)i; + } + return 0; + } + + internal int deflate(ZStream strm, int flush) + { + if (flush > 4 || flush < 0) + { + return -2; + } + if (strm.next_out == null || (strm.next_in == null && strm.avail_in != 0) || (status == 666 && flush != 4)) + { + strm.msg = z_errmsg[4]; + return -2; + } + if (strm.avail_out == 0) + { + strm.msg = z_errmsg[7]; + return -5; + } + this.strm = strm; + int num = last_flush; + last_flush = flush; + if (status == 42) + { + int num2 = 8 + (w_bits - 8 << 4) << 8; + int num3 = ((level - 1) & 0xFF) >> 1; + if (num3 > 3) + { + num3 = 3; + } + num2 |= num3 << 6; + if (strstart != 0) + { + num2 |= 0x20; + } + num2 += 31 - num2 % 31; + status = 113; + putShortMSB(num2); + if (strstart != 0) + { + putShortMSB((int)SupportClass.URShift(strm.adler, 16)); + putShortMSB((int)(strm.adler & 0xFFFF)); + } + strm.adler = strm._adler.adler32(0L, null, 0, 0); + } + if (pending != 0) + { + strm.flush_pending(); + if (strm.avail_out == 0) + { + last_flush = -1; + return 0; + } + } + else if (strm.avail_in == 0 && flush <= num && flush != 4) + { + strm.msg = z_errmsg[7]; + return -5; + } + if (status == 666 && strm.avail_in != 0) + { + strm.msg = z_errmsg[7]; + return -5; + } + if (strm.avail_in != 0 || lookahead != 0 || (flush != 0 && status != 666)) + { + int num4 = -1; + switch (config_table[level].func) + { + case 0: + num4 = deflate_stored(flush); + break; + case 1: + num4 = deflate_fast(flush); + break; + case 2: + num4 = deflate_slow(flush); + break; + } + if (num4 == 2 || num4 == 3) + { + status = 666; + } + switch (num4) + { + case 0: + case 2: + if (strm.avail_out == 0) + { + last_flush = -1; + } + return 0; + case 1: + if (flush == 1) + { + _tr_align(); + } + else + { + _tr_stored_block(0, 0, eof: false); + if (flush == 3) + { + for (int i = 0; i < hash_size; i++) + { + head[i] = 0; + } + } + } + strm.flush_pending(); + if (strm.avail_out == 0) + { + last_flush = -1; + return 0; + } + break; + } + } + if (flush != 4) + { + return 0; + } + if (noheader != 0) + { + return 1; + } + putShortMSB((int)SupportClass.URShift(strm.adler, 16)); + putShortMSB((int)(strm.adler & 0xFFFF)); + strm.flush_pending(); + noheader = -1; + if (pending == 0) + { + return 1; + } + return 0; + } + + static Deflate() + { + z_errmsg = new string[10] { "need dictionary", "stream end", "", "file error", "stream error", "data error", "insufficient memory", "buffer error", "incompatible version", "" }; + MIN_LOOKAHEAD = 262; + L_CODES = 286; + HEAP_SIZE = 2 * L_CODES + 1; + config_table = new Config[10]; + config_table[0] = new Config(0, 0, 0, 0, 0); + config_table[1] = new Config(4, 4, 8, 4, 1); + config_table[2] = new Config(4, 5, 16, 8, 1); + config_table[3] = new Config(4, 6, 32, 32, 1); + config_table[4] = new Config(4, 4, 16, 16, 2); + config_table[5] = new Config(8, 16, 32, 32, 2); + config_table[6] = new Config(8, 16, 128, 128, 2); + config_table[7] = new Config(8, 32, 128, 256, 2); + config_table[8] = new Config(32, 128, 258, 1024, 2); + config_table[9] = new Config(32, 258, 258, 4096, 2); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfBlocks.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfBlocks.cs index d8550da..7de1126 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfBlocks.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfBlocks.cs @@ -1,658 +1,660 @@ -using System; - -namespace ComponentAce.Compression.Libs.zlib -{ - internal sealed class InfBlocks - { - private const int MANY = 1440; - - private static readonly int[] inflate_mask = new int[17] - { - 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, - 1023, 2047, 4095, 8191, 16383, 32767, 65535 - }; - - internal static readonly int[] border = new int[19] - { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, - 11, 4, 12, 3, 13, 2, 14, 1, 15 - }; - - private const int Z_OK = 0; - - private const int Z_STREAM_END = 1; - - private const int Z_NEED_DICT = 2; - - private const int Z_ERRNO = -1; - - private const int Z_STREAM_ERROR = -2; - - private const int Z_DATA_ERROR = -3; - - private const int Z_MEM_ERROR = -4; - - private const int Z_BUF_ERROR = -5; - - private const int Z_VERSION_ERROR = -6; - - private const int TYPE = 0; - - private const int LENS = 1; - - private const int STORED = 2; - - private const int TABLE = 3; - - private const int BTREE = 4; - - private const int DTREE = 5; - - private const int CODES = 6; - - private const int DRY = 7; - - private const int DONE = 8; - - private const int BAD = 9; - - internal int mode; - - internal int left; - - internal int table; - - internal int index; - - internal int[] blens; - - internal int[] bb = new int[1]; - - internal int[] tb = new int[1]; - - internal InfCodes codes; - - internal int last; - - internal int bitk; - - internal int bitb; - - internal int[] hufts; - - internal byte[] window; - - internal int end; - - internal int read; - - internal int write; - - internal object checkfn; - - internal long check; - - internal InfBlocks(ZStream z, object checkfn, int w) - { - hufts = new int[4320]; - window = new byte[w]; - end = w; - this.checkfn = checkfn; - mode = 0; - reset(z, null); - } - - internal void reset(ZStream z, long[] c) - { - if (c != null) - { - c[0] = check; - } - if (mode == 4 || mode == 5) - { - blens = null; - } - if (mode == 6) - { - codes.free(z); - } - mode = 0; - bitk = 0; - bitb = 0; - read = (write = 0); - if (checkfn != null) - { - z.adler = (check = z._adler.adler32(0L, null, 0, 0)); - } - } - - internal int proc(ZStream z, int r) - { - int num = z.next_in_index; - int num2 = z.avail_in; - int num3 = bitb; - int i = bitk; - int num4 = write; - int num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); - while (true) - { - switch (mode) - { - case 0: - { - for (; i < 3; i += 8) - { - if (num2 != 0) - { - r = 0; - num2--; - num3 |= (z.next_in[num++] & 0xFF) << i; - continue; - } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - int num6 = num3 & 7; - last = num6 & 1; - switch (SupportClass.URShift(num6, 1)) - { - case 0: - num3 = SupportClass.URShift(num3, 3); - i -= 3; - num6 = i & 7; - num3 = SupportClass.URShift(num3, num6); - i -= num6; - mode = 1; - break; - case 1: - { - int[] array5 = new int[1]; - int[] array6 = new int[1]; - int[][] array7 = new int[1][]; - int[][] array8 = new int[1][]; - InfTree.inflate_trees_fixed(array5, array6, array7, array8, z); - codes = new InfCodes(array5[0], array6[0], array7[0], array8[0], z); - num3 = SupportClass.URShift(num3, 3); - i -= 3; - mode = 6; - break; - } - case 2: - num3 = SupportClass.URShift(num3, 3); - i -= 3; - mode = 3; - break; - case 3: - num3 = SupportClass.URShift(num3, 3); - i -= 3; - mode = 9; - z.msg = "invalid block type"; - r = -3; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - break; - } - case 1: - for (; i < 32; i += 8) - { - if (num2 != 0) - { - r = 0; - num2--; - num3 |= (z.next_in[num++] & 0xFF) << i; - continue; - } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - if ((SupportClass.URShift(~num3, 16) & 0xFFFF) != (num3 & 0xFFFF)) - { - mode = 9; - z.msg = "invalid stored block lengths"; - r = -3; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - left = num3 & 0xFFFF; - num3 = (i = 0); - mode = ((left != 0) ? 2 : ((last != 0) ? 7 : 0)); - break; - case 2: - { - if (num2 == 0) - { - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - if (num5 == 0) - { - if (num4 == end && read != 0) - { - num4 = 0; - num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); - } - if (num5 == 0) - { - write = num4; - r = inflate_flush(z, r); - num4 = write; - num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); - if (num4 == end && read != 0) - { - num4 = 0; - num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); - } - if (num5 == 0) - { - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - } - } - r = 0; - int num6 = left; - if (num6 > num2) - { - num6 = num2; - } - if (num6 > num5) - { - num6 = num5; - } - Array.Copy(z.next_in, num, window, num4, num6); - num += num6; - num2 -= num6; - num4 += num6; - num5 -= num6; - if ((left -= num6) == 0) - { - mode = ((last != 0) ? 7 : 0); - } - break; - } - case 3: - { - for (; i < 14; i += 8) - { - if (num2 != 0) - { - r = 0; - num2--; - num3 |= (z.next_in[num++] & 0xFF) << i; - continue; - } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - int num6 = (table = num3 & 0x3FFF); - if ((num6 & 0x1F) > 29 || ((num6 >> 5) & 0x1F) > 29) - { - mode = 9; - z.msg = "too many length or distance symbols"; - r = -3; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - num6 = 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F); - blens = new int[num6]; - num3 = SupportClass.URShift(num3, 14); - i -= 14; - index = 0; - mode = 4; - goto case 4; - } - case 4: - { - while (index < 4 + SupportClass.URShift(table, 10)) - { - for (; i < 3; i += 8) - { - if (num2 != 0) - { - r = 0; - num2--; - num3 |= (z.next_in[num++] & 0xFF) << i; - continue; - } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - blens[border[index++]] = num3 & 7; - num3 = SupportClass.URShift(num3, 3); - i -= 3; - } - while (index < 19) - { - blens[border[index++]] = 0; - } - bb[0] = 7; - int num6 = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z); - if (num6 != 0) - { - r = num6; - if (r == -3) - { - blens = null; - mode = 9; - } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - index = 0; - mode = 5; - goto case 5; - } - case 5: - { - int num6; - while (true) - { - num6 = table; - if (index >= 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F)) - { - break; - } - for (num6 = bb[0]; i < num6; i += 8) - { - if (num2 != 0) - { - r = 0; - num2--; - num3 |= (z.next_in[num++] & 0xFF) << i; - continue; - } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - if (tb[0] == -1) - { - } - num6 = hufts[(tb[0] + (num3 & inflate_mask[num6])) * 3 + 1]; - int num7 = hufts[(tb[0] + (num3 & inflate_mask[num6])) * 3 + 2]; - if (num7 < 16) - { - num3 = SupportClass.URShift(num3, num6); - i -= num6; - blens[index++] = num7; - continue; - } - int num8 = ((num7 == 18) ? 7 : (num7 - 14)); - int num9 = ((num7 == 18) ? 11 : 3); - for (; i < num6 + num8; i += 8) - { - if (num2 != 0) - { - r = 0; - num2--; - num3 |= (z.next_in[num++] & 0xFF) << i; - continue; - } - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - num3 = SupportClass.URShift(num3, num6); - i -= num6; - num9 += num3 & inflate_mask[num8]; - num3 = SupportClass.URShift(num3, num8); - i -= num8; - num8 = index; - num6 = table; - if (num8 + num9 > 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F) || (num7 == 16 && num8 < 1)) - { - blens = null; - mode = 9; - z.msg = "invalid bit length repeat"; - r = -3; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - num7 = ((num7 == 16) ? blens[num8 - 1] : 0); - do - { - blens[num8++] = num7; - } - while (--num9 != 0); - index = num8; - } - tb[0] = -1; - int[] array = new int[1]; - int[] array2 = new int[1]; - int[] array3 = new int[1]; - int[] array4 = new int[1]; - array[0] = 9; - array2[0] = 6; - num6 = table; - num6 = InfTree.inflate_trees_dynamic(257 + (num6 & 0x1F), 1 + ((num6 >> 5) & 0x1F), blens, array, array2, array3, array4, hufts, z); - if (num6 != 0) - { - if (num6 == -3) - { - blens = null; - mode = 9; - } - r = num6; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - codes = new InfCodes(array[0], array2[0], hufts, array3[0], hufts, array4[0], z); - blens = null; - mode = 6; - goto case 6; - } - case 6: - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - if ((r = codes.proc(this, z, r)) != 1) - { - return inflate_flush(z, r); - } - r = 0; - codes.free(z); - num = z.next_in_index; - num2 = z.avail_in; - num3 = bitb; - i = bitk; - num4 = write; - num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); - if (last == 0) - { - mode = 0; - break; - } - mode = 7; - goto case 7; - case 7: - write = num4; - r = inflate_flush(z, r); - num4 = write; - num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); - if (read != write) - { - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - mode = 8; - goto case 8; - case 8: - r = 1; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - case 9: - r = -3; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - default: - r = -2; - bitb = num3; - bitk = i; - z.avail_in = num2; - z.total_in += num - z.next_in_index; - z.next_in_index = num; - write = num4; - return inflate_flush(z, r); - } - } - } - - internal void free(ZStream z) - { - reset(z, null); - window = null; - hufts = null; - } - - internal void set_dictionary(byte[] d, int start, int n) - { - Array.Copy(d, start, window, 0, n); - read = (write = n); - } - - internal int sync_point() - { - return (mode == 1) ? 1 : 0; - } - - internal int inflate_flush(ZStream z, int r) - { - int next_out_index = z.next_out_index; - int num = read; - int num2 = ((num <= write) ? write : end) - num; - if (num2 > z.avail_out) - { - num2 = z.avail_out; - } - if (num2 != 0 && r == -5) - { - r = 0; - } - z.avail_out -= num2; - z.total_out += num2; - if (checkfn != null) - { - z.adler = (check = z._adler.adler32(check, window, num, num2)); - } - Array.Copy(window, num, z.next_out, next_out_index, num2); - next_out_index += num2; - num += num2; - if (num == end) - { - num = 0; - if (write == end) - { - write = 0; - } - num2 = write - num; - if (num2 > z.avail_out) - { - num2 = z.avail_out; - } - if (num2 != 0 && r == -5) - { - r = 0; - } - z.avail_out -= num2; - z.total_out += num2; - if (checkfn != null) - { - z.adler = (check = z._adler.adler32(check, window, num, num2)); - } - Array.Copy(window, num, z.next_out, next_out_index, num2); - next_out_index += num2; - num += num2; - } - z.next_out_index = next_out_index; - read = num; - return r; - } - } +using System; + +namespace ComponentAce.Compression.Libs.zlib; + +internal sealed class InfBlocks +{ + private const int MANY = 1440; + + private static readonly int[] inflate_mask = new int[17] + { + 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, + 1023, 2047, 4095, 8191, 16383, 32767, 65535 + }; + + internal static readonly int[] border = new int[19] + { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, + 11, 4, 12, 3, 13, 2, 14, 1, 15 + }; + + private const int Z_OK = 0; + + private const int Z_STREAM_END = 1; + + private const int Z_NEED_DICT = 2; + + private const int Z_ERRNO = -1; + + private const int Z_STREAM_ERROR = -2; + + private const int Z_DATA_ERROR = -3; + + private const int Z_MEM_ERROR = -4; + + private const int Z_BUF_ERROR = -5; + + private const int Z_VERSION_ERROR = -6; + + private const int TYPE = 0; + + private const int LENS = 1; + + private const int STORED = 2; + + private const int TABLE = 3; + + private const int BTREE = 4; + + private const int DTREE = 5; + + private const int CODES = 6; + + private const int DRY = 7; + + private const int DONE = 8; + + private const int BAD = 9; + + internal int mode; + + internal int left; + + internal int table; + + internal int index; + + internal int[] blens; + + internal int[] bb = new int[1]; + + internal int[] tb = new int[1]; + + internal InfCodes codes; + + internal int last; + + internal int bitk; + + internal int bitb; + + internal int[] hufts; + + internal byte[] window; + + internal int end; + + internal int read; + + internal int write; + + internal object checkfn; + + internal long check; + + internal InfBlocks(ZStream z, object checkfn, int w) + { + hufts = new int[4320]; + window = new byte[w]; + end = w; + this.checkfn = checkfn; + mode = 0; + reset(z, null); + } + + internal void reset(ZStream z, long[] c) + { + if (c != null) + { + c[0] = check; + } + if (mode == 4 || mode == 5) + { + blens = null; + } + if (mode == 6) + { + codes.free(z); + } + mode = 0; + bitk = 0; + bitb = 0; + read = (write = 0); + if (checkfn != null) + { + z.adler = (check = z._adler.adler32(0L, null, 0, 0)); + } + } + + internal int proc(ZStream z, int r) + { + int num = z.next_in_index; + int num2 = z.avail_in; + int num3 = bitb; + int i = bitk; + int num4 = write; + int num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); + while (true) + { + switch (mode) + { + case 0: + { + for (; i < 3; i += 8) + { + if (num2 != 0) + { + r = 0; + num2--; + num3 |= (z.next_in[num++] & 0xFF) << i; + continue; + } + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + int num6 = num3 & 7; + last = num6 & 1; + switch (SupportClass.URShift(num6, 1)) + { + case 0: + num3 = SupportClass.URShift(num3, 3); + i -= 3; + num6 = i & 7; + num3 = SupportClass.URShift(num3, num6); + i -= num6; + mode = 1; + break; + case 1: + { + int[] array5 = new int[1]; + int[] array6 = new int[1]; + int[][] array7 = new int[1][]; + int[][] array8 = new int[1][]; + InfTree.inflate_trees_fixed(array5, array6, array7, array8, z); + codes = new InfCodes(array5[0], array6[0], array7[0], array8[0], z); + num3 = SupportClass.URShift(num3, 3); + i -= 3; + mode = 6; + break; + } + case 2: + num3 = SupportClass.URShift(num3, 3); + i -= 3; + mode = 3; + break; + case 3: + num3 = SupportClass.URShift(num3, 3); + i -= 3; + mode = 9; + z.msg = "invalid block type"; + r = -3; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + break; + } + case 1: + for (; i < 32; i += 8) + { + if (num2 != 0) + { + r = 0; + num2--; + num3 |= (z.next_in[num++] & 0xFF) << i; + continue; + } + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + if ((SupportClass.URShift(~num3, 16) & 0xFFFF) != (num3 & 0xFFFF)) + { + mode = 9; + z.msg = "invalid stored block lengths"; + r = -3; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + left = num3 & 0xFFFF; + num3 = (i = 0); + mode = ((left != 0) ? 2 : ((last != 0) ? 7 : 0)); + break; + case 2: + { + if (num2 == 0) + { + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + if (num5 == 0) + { + if (num4 == end && read != 0) + { + num4 = 0; + num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); + } + if (num5 == 0) + { + write = num4; + r = inflate_flush(z, r); + num4 = write; + num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); + if (num4 == end && read != 0) + { + num4 = 0; + num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); + } + if (num5 == 0) + { + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + } + } + r = 0; + int num6 = left; + if (num6 > num2) + { + num6 = num2; + } + if (num6 > num5) + { + num6 = num5; + } + Array.Copy(z.next_in, num, window, num4, num6); + num += num6; + num2 -= num6; + num4 += num6; + num5 -= num6; + if ((left -= num6) == 0) + { + mode = ((last != 0) ? 7 : 0); + } + break; + } + case 3: + { + for (; i < 14; i += 8) + { + if (num2 != 0) + { + r = 0; + num2--; + num3 |= (z.next_in[num++] & 0xFF) << i; + continue; + } + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + int num6 = (table = num3 & 0x3FFF); + if ((num6 & 0x1F) > 29 || ((num6 >> 5) & 0x1F) > 29) + { + mode = 9; + z.msg = "too many length or distance symbols"; + r = -3; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + num6 = 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F); + blens = new int[num6]; + num3 = SupportClass.URShift(num3, 14); + i -= 14; + index = 0; + mode = 4; + goto case 4; + } + case 4: + { + while (index < 4 + SupportClass.URShift(table, 10)) + { + for (; i < 3; i += 8) + { + if (num2 != 0) + { + r = 0; + num2--; + num3 |= (z.next_in[num++] & 0xFF) << i; + continue; + } + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + blens[border[index++]] = num3 & 7; + num3 = SupportClass.URShift(num3, 3); + i -= 3; + } + while (index < 19) + { + blens[border[index++]] = 0; + } + bb[0] = 7; + int num6 = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z); + if (num6 != 0) + { + r = num6; + if (r == -3) + { + blens = null; + mode = 9; + } + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + index = 0; + mode = 5; + goto case 5; + } + case 5: + { + int num6; + while (true) + { + num6 = table; + if (index >= 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F)) + { + break; + } + for (num6 = bb[0]; i < num6; i += 8) + { + if (num2 != 0) + { + r = 0; + num2--; + num3 |= (z.next_in[num++] & 0xFF) << i; + continue; + } + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + _ = tb[0]; + _ = -1; + num6 = hufts[(tb[0] + (num3 & inflate_mask[num6])) * 3 + 1]; + int num7 = hufts[(tb[0] + (num3 & inflate_mask[num6])) * 3 + 2]; + if (num7 < 16) + { + num3 = SupportClass.URShift(num3, num6); + i -= num6; + blens[index++] = num7; + continue; + } + int num8 = ((num7 == 18) ? 7 : (num7 - 14)); + int num9 = ((num7 == 18) ? 11 : 3); + for (; i < num6 + num8; i += 8) + { + if (num2 != 0) + { + r = 0; + num2--; + num3 |= (z.next_in[num++] & 0xFF) << i; + continue; + } + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + num3 = SupportClass.URShift(num3, num6); + i -= num6; + num9 += num3 & inflate_mask[num8]; + num3 = SupportClass.URShift(num3, num8); + i -= num8; + num8 = index; + num6 = table; + if (num8 + num9 > 258 + (num6 & 0x1F) + ((num6 >> 5) & 0x1F) || (num7 == 16 && num8 < 1)) + { + blens = null; + mode = 9; + z.msg = "invalid bit length repeat"; + r = -3; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + num7 = ((num7 == 16) ? blens[num8 - 1] : 0); + do + { + blens[num8++] = num7; + } + while (--num9 != 0); + index = num8; + } + tb[0] = -1; + int[] array = new int[1]; + int[] array2 = new int[1]; + int[] array3 = new int[1]; + int[] array4 = new int[1]; + array[0] = 9; + array2[0] = 6; + num6 = table; + num6 = InfTree.inflate_trees_dynamic(257 + (num6 & 0x1F), 1 + ((num6 >> 5) & 0x1F), blens, array, array2, array3, array4, hufts, z); + if (num6 != 0) + { + if (num6 == -3) + { + blens = null; + mode = 9; + } + r = num6; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + codes = new InfCodes(array[0], array2[0], hufts, array3[0], hufts, array4[0], z); + blens = null; + mode = 6; + goto case 6; + } + case 6: + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + if ((r = codes.proc(this, z, r)) != 1) + { + return inflate_flush(z, r); + } + r = 0; + codes.free(z); + num = z.next_in_index; + num2 = z.avail_in; + num3 = bitb; + i = bitk; + num4 = write; + num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); + if (last == 0) + { + mode = 0; + break; + } + mode = 7; + goto case 7; + case 7: + write = num4; + r = inflate_flush(z, r); + num4 = write; + num5 = ((num4 < read) ? (read - num4 - 1) : (end - num4)); + if (read != write) + { + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + mode = 8; + goto case 8; + case 8: + r = 1; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + case 9: + r = -3; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + default: + r = -2; + bitb = num3; + bitk = i; + z.avail_in = num2; + z.total_in += num - z.next_in_index; + z.next_in_index = num; + write = num4; + return inflate_flush(z, r); + } + } + } + + internal void free(ZStream z) + { + reset(z, null); + window = null; + hufts = null; + } + + internal void set_dictionary(byte[] d, int start, int n) + { + Array.Copy(d, start, window, 0, n); + read = (write = n); + } + + internal int sync_point() + { + if (mode != 1) + { + return 0; + } + return 1; + } + + internal int inflate_flush(ZStream z, int r) + { + int next_out_index = z.next_out_index; + int num = read; + int num2 = ((num <= write) ? write : end) - num; + if (num2 > z.avail_out) + { + num2 = z.avail_out; + } + if (num2 != 0 && r == -5) + { + r = 0; + } + z.avail_out -= num2; + z.total_out += num2; + if (checkfn != null) + { + z.adler = (check = z._adler.adler32(check, window, num, num2)); + } + Array.Copy(window, num, z.next_out, next_out_index, num2); + next_out_index += num2; + num += num2; + if (num == end) + { + num = 0; + if (write == end) + { + write = 0; + } + num2 = write - num; + if (num2 > z.avail_out) + { + num2 = z.avail_out; + } + if (num2 != 0 && r == -5) + { + r = 0; + } + z.avail_out -= num2; + z.total_out += num2; + if (checkfn != null) + { + z.adler = (check = z._adler.adler32(check, window, num, num2)); + } + Array.Copy(window, num, z.next_out, next_out_index, num2); + next_out_index += num2; + num += num2; + } + z.next_out_index = next_out_index; + read = num; + return r; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfCodes.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfCodes.cs index 544a8b0..fd2b030 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfCodes.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfCodes.cs @@ -1,666 +1,663 @@ -using System; - -namespace ComponentAce.Compression.Libs.zlib -{ - internal sealed class InfCodes - { - private static readonly int[] inflate_mask = new int[17] - { - 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, - 1023, 2047, 4095, 8191, 16383, 32767, 65535 - }; - - private const int Z_OK = 0; - - private const int Z_STREAM_END = 1; - - private const int Z_NEED_DICT = 2; - - private const int Z_ERRNO = -1; - - private const int Z_STREAM_ERROR = -2; - - private const int Z_DATA_ERROR = -3; - - private const int Z_MEM_ERROR = -4; - - private const int Z_BUF_ERROR = -5; - - private const int Z_VERSION_ERROR = -6; - - private const int START = 0; - - private const int LEN = 1; - - private const int LENEXT = 2; - - private const int DIST = 3; - - private const int DISTEXT = 4; - - private const int COPY = 5; - - private const int LIT = 6; - - private const int WASH = 7; - - private const int END = 8; - - private const int BADCODE = 9; - - internal int mode; - - internal int len; - - internal int[] tree; - - internal int tree_index = 0; - - internal int need; - - internal int lit; - - internal int get_Renamed; - - internal int dist; - - internal byte lbits; - - internal byte dbits; - - internal int[] ltree; - - internal int ltree_index; - - internal int[] dtree; - - internal int dtree_index; - - internal InfCodes(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, ZStream z) - { - mode = 0; - lbits = (byte)bl; - dbits = (byte)bd; - ltree = tl; - ltree_index = tl_index; - dtree = td; - dtree_index = td_index; - } - - internal InfCodes(int bl, int bd, int[] tl, int[] td, ZStream z) - { - mode = 0; - lbits = (byte)bl; - dbits = (byte)bd; - ltree = tl; - ltree_index = 0; - dtree = td; - dtree_index = 0; - } - - internal int proc(InfBlocks s, ZStream z, int r) - { - int num = 0; - int num2 = 0; - int num3 = 0; - num3 = z.next_in_index; - int num4 = z.avail_in; - num = s.bitb; - num2 = s.bitk; - int num5 = s.write; - int num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - while (true) - { - switch (mode) - { - case 0: - if (num6 >= 258 && num4 >= 10) - { - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); - num3 = z.next_in_index; - num4 = z.avail_in; - num = s.bitb; - num2 = s.bitk; - num5 = s.write; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - if (r != 0) - { - mode = ((r == 1) ? 7 : 9); - break; - } - } - need = lbits; - tree = ltree; - tree_index = ltree_index; - mode = 1; - goto case 1; - case 1: - { - int num7; - for (num7 = need; num2 < num7; num2 += 8) - { - if (num4 != 0) - { - r = 0; - num4--; - num |= (z.next_in[num3++] & 0xFF) << num2; - continue; - } - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - int num8 = (tree_index + (num & inflate_mask[num7])) * 3; - num = SupportClass.URShift(num, tree[num8 + 1]); - num2 -= tree[num8 + 1]; - int num9 = tree[num8]; - if (num9 == 0) - { - lit = tree[num8 + 2]; - mode = 6; - break; - } - if (((uint)num9 & 0x10u) != 0) - { - get_Renamed = num9 & 0xF; - len = tree[num8 + 2]; - mode = 2; - break; - } - if ((num9 & 0x40) == 0) - { - need = num9; - tree_index = num8 / 3 + tree[num8 + 2]; - break; - } - if (((uint)num9 & 0x20u) != 0) - { - mode = 7; - break; - } - mode = 9; - z.msg = "invalid literal/length code"; - r = -3; - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - case 2: - { - int num7; - for (num7 = get_Renamed; num2 < num7; num2 += 8) - { - if (num4 != 0) - { - r = 0; - num4--; - num |= (z.next_in[num3++] & 0xFF) << num2; - continue; - } - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - len += num & inflate_mask[num7]; - num >>= num7; - num2 -= num7; - need = dbits; - tree = dtree; - tree_index = dtree_index; - mode = 3; - goto case 3; - } - case 3: - { - int num7; - for (num7 = need; num2 < num7; num2 += 8) - { - if (num4 != 0) - { - r = 0; - num4--; - num |= (z.next_in[num3++] & 0xFF) << num2; - continue; - } - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - int num8 = (tree_index + (num & inflate_mask[num7])) * 3; - num >>= tree[num8 + 1]; - num2 -= tree[num8 + 1]; - int num9 = tree[num8]; - if (((uint)num9 & 0x10u) != 0) - { - get_Renamed = num9 & 0xF; - dist = tree[num8 + 2]; - mode = 4; - break; - } - if ((num9 & 0x40) == 0) - { - need = num9; - tree_index = num8 / 3 + tree[num8 + 2]; - break; - } - mode = 9; - z.msg = "invalid distance code"; - r = -3; - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - case 4: - { - int num7; - for (num7 = get_Renamed; num2 < num7; num2 += 8) - { - if (num4 != 0) - { - r = 0; - num4--; - num |= (z.next_in[num3++] & 0xFF) << num2; - continue; - } - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - dist += num & inflate_mask[num7]; - num >>= num7; - num2 -= num7; - mode = 5; - goto case 5; - } - case 5: - { - int i; - for (i = num5 - dist; i < 0; i += s.end) - { - } - while (len != 0) - { - if (num6 == 0) - { - if (num5 == s.end && s.read != 0) - { - num5 = 0; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - } - if (num6 == 0) - { - s.write = num5; - r = s.inflate_flush(z, r); - num5 = s.write; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - if (num5 == s.end && s.read != 0) - { - num5 = 0; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - } - if (num6 == 0) - { - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - } - } - s.window[num5++] = s.window[i++]; - num6--; - if (i == s.end) - { - i = 0; - } - len--; - } - mode = 0; - break; - } - case 6: - if (num6 == 0) - { - if (num5 == s.end && s.read != 0) - { - num5 = 0; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - } - if (num6 == 0) - { - s.write = num5; - r = s.inflate_flush(z, r); - num5 = s.write; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - if (num5 == s.end && s.read != 0) - { - num5 = 0; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - } - if (num6 == 0) - { - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - } - } - r = 0; - s.window[num5++] = (byte)lit; - num6--; - mode = 0; - break; - case 7: - if (num2 > 7) - { - num2 -= 8; - num4++; - num3--; - } - s.write = num5; - r = s.inflate_flush(z, r); - num5 = s.write; - num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); - if (s.read != s.write) - { - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - mode = 8; - goto case 8; - case 8: - r = 1; - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - case 9: - r = -3; - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - default: - r = -2; - s.bitb = num; - s.bitk = num2; - z.avail_in = num4; - z.total_in += num3 - z.next_in_index; - z.next_in_index = num3; - s.write = num5; - return s.inflate_flush(z, r); - } - } - } - - internal void free(ZStream z) - { - } - - internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InfBlocks s, ZStream z) - { - int next_in_index = z.next_in_index; - int num = z.avail_in; - int num2 = s.bitb; - int num3 = s.bitk; - int num4 = s.write; - int num5 = ((num4 < s.read) ? (s.read - num4 - 1) : (s.end - num4)); - int num6 = inflate_mask[bl]; - int num7 = inflate_mask[bd]; - int num11; - while (true) - { - if (num3 < 20) - { - num--; - num2 |= (z.next_in[next_in_index++] & 0xFF) << num3; - num3 += 8; - continue; - } - int num8 = num2 & num6; - int[] array = tl; - int num9 = tl_index; - int num10; - if ((num10 = array[(num9 + num8) * 3]) == 0) - { - num2 >>= array[(num9 + num8) * 3 + 1]; - num3 -= array[(num9 + num8) * 3 + 1]; - s.window[num4++] = (byte)array[(num9 + num8) * 3 + 2]; - num5--; - } - else - { - while (true) - { - num2 >>= array[(num9 + num8) * 3 + 1]; - num3 -= array[(num9 + num8) * 3 + 1]; - if (((uint)num10 & 0x10u) != 0) - { - num10 &= 0xF; - num11 = array[(num9 + num8) * 3 + 2] + (num2 & inflate_mask[num10]); - num2 >>= num10; - for (num3 -= num10; num3 < 15; num3 += 8) - { - num--; - num2 |= (z.next_in[next_in_index++] & 0xFF) << num3; - } - num8 = num2 & num7; - array = td; - num9 = td_index; - num10 = array[(num9 + num8) * 3]; - while (true) - { - num2 >>= array[(num9 + num8) * 3 + 1]; - num3 -= array[(num9 + num8) * 3 + 1]; - if (((uint)num10 & 0x10u) != 0) - { - break; - } - if ((num10 & 0x40) == 0) - { - num8 += array[(num9 + num8) * 3 + 2]; - num8 += num2 & inflate_mask[num10]; - num10 = array[(num9 + num8) * 3]; - bool flag = true; - continue; - } - z.msg = "invalid distance code"; - num11 = z.avail_in - num; - num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); - num += num11; - next_in_index -= num11; - num3 -= num11 << 3; - s.bitb = num2; - s.bitk = num3; - z.avail_in = num; - z.total_in += next_in_index - z.next_in_index; - z.next_in_index = next_in_index; - s.write = num4; - return -3; - } - for (num10 &= 0xF; num3 < num10; num3 += 8) - { - num--; - num2 |= (z.next_in[next_in_index++] & 0xFF) << num3; - } - int num12 = array[(num9 + num8) * 3 + 2] + (num2 & inflate_mask[num10]); - num2 >>= num10; - num3 -= num10; - num5 -= num11; - int num13; - if (num4 >= num12) - { - num13 = num4 - num12; - if (num4 - num13 > 0 && 2 > num4 - num13) - { - s.window[num4++] = s.window[num13++]; - num11--; - s.window[num4++] = s.window[num13++]; - num11--; - } - else - { - Array.Copy(s.window, num13, s.window, num4, 2); - num4 += 2; - num13 += 2; - num11 -= 2; - } - } - else - { - num13 = num4 - num12; - do - { - num13 += s.end; - } - while (num13 < 0); - num10 = s.end - num13; - if (num11 > num10) - { - num11 -= num10; - if (num4 - num13 > 0 && num10 > num4 - num13) - { - do - { - s.window[num4++] = s.window[num13++]; - } - while (--num10 != 0); - } - else - { - Array.Copy(s.window, num13, s.window, num4, num10); - num4 += num10; - num13 += num10; - num10 = 0; - } - num13 = 0; - } - } - if (num4 - num13 > 0 && num11 > num4 - num13) - { - do - { - s.window[num4++] = s.window[num13++]; - } - while (--num11 != 0); - break; - } - Array.Copy(s.window, num13, s.window, num4, num11); - num4 += num11; - num13 += num11; - num11 = 0; - break; - } - if ((num10 & 0x40) == 0) - { - num8 += array[(num9 + num8) * 3 + 2]; - num8 += num2 & inflate_mask[num10]; - if ((num10 = array[(num9 + num8) * 3]) == 0) - { - num2 >>= array[(num9 + num8) * 3 + 1]; - num3 -= array[(num9 + num8) * 3 + 1]; - s.window[num4++] = (byte)array[(num9 + num8) * 3 + 2]; - num5--; - break; - } - bool flag2 = true; - continue; - } - if (((uint)num10 & 0x20u) != 0) - { - num11 = z.avail_in - num; - num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); - num += num11; - next_in_index -= num11; - num3 -= num11 << 3; - s.bitb = num2; - s.bitk = num3; - z.avail_in = num; - z.total_in += next_in_index - z.next_in_index; - z.next_in_index = next_in_index; - s.write = num4; - return 1; - } - z.msg = "invalid literal/length code"; - num11 = z.avail_in - num; - num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); - num += num11; - next_in_index -= num11; - num3 -= num11 << 3; - s.bitb = num2; - s.bitk = num3; - z.avail_in = num; - z.total_in += next_in_index - z.next_in_index; - z.next_in_index = next_in_index; - s.write = num4; - return -3; - } - } - if (num5 < 258 || num < 10) - { - break; - } - } - num11 = z.avail_in - num; - num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); - num += num11; - next_in_index -= num11; - num3 -= num11 << 3; - s.bitb = num2; - s.bitk = num3; - z.avail_in = num; - z.total_in += next_in_index - z.next_in_index; - z.next_in_index = next_in_index; - s.write = num4; - return 0; - } - } +using System; + +namespace ComponentAce.Compression.Libs.zlib; + +internal sealed class InfCodes +{ + private static readonly int[] inflate_mask = new int[17] + { + 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, + 1023, 2047, 4095, 8191, 16383, 32767, 65535 + }; + + private const int Z_OK = 0; + + private const int Z_STREAM_END = 1; + + private const int Z_NEED_DICT = 2; + + private const int Z_ERRNO = -1; + + private const int Z_STREAM_ERROR = -2; + + private const int Z_DATA_ERROR = -3; + + private const int Z_MEM_ERROR = -4; + + private const int Z_BUF_ERROR = -5; + + private const int Z_VERSION_ERROR = -6; + + private const int START = 0; + + private const int LEN = 1; + + private const int LENEXT = 2; + + private const int DIST = 3; + + private const int DISTEXT = 4; + + private const int COPY = 5; + + private const int LIT = 6; + + private const int WASH = 7; + + private const int END = 8; + + private const int BADCODE = 9; + + internal int mode; + + internal int len; + + internal int[] tree; + + internal int tree_index; + + internal int need; + + internal int lit; + + internal int get_Renamed; + + internal int dist; + + internal byte lbits; + + internal byte dbits; + + internal int[] ltree; + + internal int ltree_index; + + internal int[] dtree; + + internal int dtree_index; + + internal InfCodes(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, ZStream z) + { + mode = 0; + lbits = (byte)bl; + dbits = (byte)bd; + ltree = tl; + ltree_index = tl_index; + dtree = td; + dtree_index = td_index; + } + + internal InfCodes(int bl, int bd, int[] tl, int[] td, ZStream z) + { + mode = 0; + lbits = (byte)bl; + dbits = (byte)bd; + ltree = tl; + ltree_index = 0; + dtree = td; + dtree_index = 0; + } + + internal int proc(InfBlocks s, ZStream z, int r) + { + int num = 0; + int num2 = 0; + int num3 = 0; + num3 = z.next_in_index; + int num4 = z.avail_in; + num = s.bitb; + num2 = s.bitk; + int num5 = s.write; + int num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + while (true) + { + switch (mode) + { + case 0: + if (num6 >= 258 && num4 >= 10) + { + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + r = inflate_fast(lbits, dbits, ltree, ltree_index, dtree, dtree_index, s, z); + num3 = z.next_in_index; + num4 = z.avail_in; + num = s.bitb; + num2 = s.bitk; + num5 = s.write; + num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + if (r != 0) + { + mode = ((r == 1) ? 7 : 9); + break; + } + } + need = lbits; + tree = ltree; + tree_index = ltree_index; + mode = 1; + goto case 1; + case 1: + { + int num7; + for (num7 = need; num2 < num7; num2 += 8) + { + if (num4 != 0) + { + r = 0; + num4--; + num |= (z.next_in[num3++] & 0xFF) << num2; + continue; + } + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + int num8 = (tree_index + (num & inflate_mask[num7])) * 3; + num = SupportClass.URShift(num, tree[num8 + 1]); + num2 -= tree[num8 + 1]; + int num9 = tree[num8]; + if (num9 == 0) + { + lit = tree[num8 + 2]; + mode = 6; + break; + } + if (((uint)num9 & 0x10u) != 0) + { + get_Renamed = num9 & 0xF; + len = tree[num8 + 2]; + mode = 2; + break; + } + if ((num9 & 0x40) == 0) + { + need = num9; + tree_index = num8 / 3 + tree[num8 + 2]; + break; + } + if (((uint)num9 & 0x20u) != 0) + { + mode = 7; + break; + } + mode = 9; + z.msg = "invalid literal/length code"; + r = -3; + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + case 2: + { + int num7; + for (num7 = get_Renamed; num2 < num7; num2 += 8) + { + if (num4 != 0) + { + r = 0; + num4--; + num |= (z.next_in[num3++] & 0xFF) << num2; + continue; + } + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + len += num & inflate_mask[num7]; + num >>= num7; + num2 -= num7; + need = dbits; + tree = dtree; + tree_index = dtree_index; + mode = 3; + goto case 3; + } + case 3: + { + int num7; + for (num7 = need; num2 < num7; num2 += 8) + { + if (num4 != 0) + { + r = 0; + num4--; + num |= (z.next_in[num3++] & 0xFF) << num2; + continue; + } + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + int num8 = (tree_index + (num & inflate_mask[num7])) * 3; + num >>= tree[num8 + 1]; + num2 -= tree[num8 + 1]; + int num9 = tree[num8]; + if (((uint)num9 & 0x10u) != 0) + { + get_Renamed = num9 & 0xF; + dist = tree[num8 + 2]; + mode = 4; + break; + } + if ((num9 & 0x40) == 0) + { + need = num9; + tree_index = num8 / 3 + tree[num8 + 2]; + break; + } + mode = 9; + z.msg = "invalid distance code"; + r = -3; + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + case 4: + { + int num7; + for (num7 = get_Renamed; num2 < num7; num2 += 8) + { + if (num4 != 0) + { + r = 0; + num4--; + num |= (z.next_in[num3++] & 0xFF) << num2; + continue; + } + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + dist += num & inflate_mask[num7]; + num >>= num7; + num2 -= num7; + mode = 5; + goto case 5; + } + case 5: + { + int i; + for (i = num5 - dist; i < 0; i += s.end) + { + } + while (len != 0) + { + if (num6 == 0) + { + if (num5 == s.end && s.read != 0) + { + num5 = 0; + num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + } + if (num6 == 0) + { + s.write = num5; + r = s.inflate_flush(z, r); + num5 = s.write; + num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + if (num5 == s.end && s.read != 0) + { + num5 = 0; + num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + } + if (num6 == 0) + { + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + } + } + s.window[num5++] = s.window[i++]; + num6--; + if (i == s.end) + { + i = 0; + } + len--; + } + mode = 0; + break; + } + case 6: + if (num6 == 0) + { + if (num5 == s.end && s.read != 0) + { + num5 = 0; + num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + } + if (num6 == 0) + { + s.write = num5; + r = s.inflate_flush(z, r); + num5 = s.write; + num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + if (num5 == s.end && s.read != 0) + { + num5 = 0; + num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + } + if (num6 == 0) + { + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + } + } + r = 0; + s.window[num5++] = (byte)lit; + num6--; + mode = 0; + break; + case 7: + if (num2 > 7) + { + num2 -= 8; + num4++; + num3--; + } + s.write = num5; + r = s.inflate_flush(z, r); + num5 = s.write; + num6 = ((num5 < s.read) ? (s.read - num5 - 1) : (s.end - num5)); + if (s.read != s.write) + { + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + mode = 8; + goto case 8; + case 8: + r = 1; + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + case 9: + r = -3; + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + default: + r = -2; + s.bitb = num; + s.bitk = num2; + z.avail_in = num4; + z.total_in += num3 - z.next_in_index; + z.next_in_index = num3; + s.write = num5; + return s.inflate_flush(z, r); + } + } + } + + internal void free(ZStream z) + { + } + + internal int inflate_fast(int bl, int bd, int[] tl, int tl_index, int[] td, int td_index, InfBlocks s, ZStream z) + { + int next_in_index = z.next_in_index; + int num = z.avail_in; + int num2 = s.bitb; + int num3 = s.bitk; + int num4 = s.write; + int num5 = ((num4 < s.read) ? (s.read - num4 - 1) : (s.end - num4)); + int num6 = inflate_mask[bl]; + int num7 = inflate_mask[bd]; + int num11; + while (true) + { + if (num3 < 20) + { + num--; + num2 |= (z.next_in[next_in_index++] & 0xFF) << num3; + num3 += 8; + continue; + } + int num8 = num2 & num6; + int[] array = tl; + int num9 = tl_index; + int num10; + if ((num10 = array[(num9 + num8) * 3]) == 0) + { + num2 >>= array[(num9 + num8) * 3 + 1]; + num3 -= array[(num9 + num8) * 3 + 1]; + s.window[num4++] = (byte)array[(num9 + num8) * 3 + 2]; + num5--; + } + else + { + while (true) + { + num2 >>= array[(num9 + num8) * 3 + 1]; + num3 -= array[(num9 + num8) * 3 + 1]; + if (((uint)num10 & 0x10u) != 0) + { + num10 &= 0xF; + num11 = array[(num9 + num8) * 3 + 2] + (num2 & inflate_mask[num10]); + num2 >>= num10; + for (num3 -= num10; num3 < 15; num3 += 8) + { + num--; + num2 |= (z.next_in[next_in_index++] & 0xFF) << num3; + } + num8 = num2 & num7; + array = td; + num9 = td_index; + num10 = array[(num9 + num8) * 3]; + while (true) + { + num2 >>= array[(num9 + num8) * 3 + 1]; + num3 -= array[(num9 + num8) * 3 + 1]; + if (((uint)num10 & 0x10u) != 0) + { + break; + } + if ((num10 & 0x40) == 0) + { + num8 += array[(num9 + num8) * 3 + 2]; + num8 += num2 & inflate_mask[num10]; + num10 = array[(num9 + num8) * 3]; + continue; + } + z.msg = "invalid distance code"; + num11 = z.avail_in - num; + num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); + num += num11; + next_in_index -= num11; + num3 -= num11 << 3; + s.bitb = num2; + s.bitk = num3; + z.avail_in = num; + z.total_in += next_in_index - z.next_in_index; + z.next_in_index = next_in_index; + s.write = num4; + return -3; + } + for (num10 &= 0xF; num3 < num10; num3 += 8) + { + num--; + num2 |= (z.next_in[next_in_index++] & 0xFF) << num3; + } + int num12 = array[(num9 + num8) * 3 + 2] + (num2 & inflate_mask[num10]); + num2 >>= num10; + num3 -= num10; + num5 -= num11; + int num13; + if (num4 >= num12) + { + num13 = num4 - num12; + if (num4 - num13 > 0 && 2 > num4 - num13) + { + s.window[num4++] = s.window[num13++]; + num11--; + s.window[num4++] = s.window[num13++]; + num11--; + } + else + { + Array.Copy(s.window, num13, s.window, num4, 2); + num4 += 2; + num13 += 2; + num11 -= 2; + } + } + else + { + num13 = num4 - num12; + do + { + num13 += s.end; + } + while (num13 < 0); + num10 = s.end - num13; + if (num11 > num10) + { + num11 -= num10; + if (num4 - num13 > 0 && num10 > num4 - num13) + { + do + { + s.window[num4++] = s.window[num13++]; + } + while (--num10 != 0); + } + else + { + Array.Copy(s.window, num13, s.window, num4, num10); + num4 += num10; + num13 += num10; + num10 = 0; + } + num13 = 0; + } + } + if (num4 - num13 > 0 && num11 > num4 - num13) + { + do + { + s.window[num4++] = s.window[num13++]; + } + while (--num11 != 0); + break; + } + Array.Copy(s.window, num13, s.window, num4, num11); + num4 += num11; + num13 += num11; + num11 = 0; + break; + } + if ((num10 & 0x40) == 0) + { + num8 += array[(num9 + num8) * 3 + 2]; + num8 += num2 & inflate_mask[num10]; + if ((num10 = array[(num9 + num8) * 3]) == 0) + { + num2 >>= array[(num9 + num8) * 3 + 1]; + num3 -= array[(num9 + num8) * 3 + 1]; + s.window[num4++] = (byte)array[(num9 + num8) * 3 + 2]; + num5--; + break; + } + continue; + } + if (((uint)num10 & 0x20u) != 0) + { + num11 = z.avail_in - num; + num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); + num += num11; + next_in_index -= num11; + num3 -= num11 << 3; + s.bitb = num2; + s.bitk = num3; + z.avail_in = num; + z.total_in += next_in_index - z.next_in_index; + z.next_in_index = next_in_index; + s.write = num4; + return 1; + } + z.msg = "invalid literal/length code"; + num11 = z.avail_in - num; + num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); + num += num11; + next_in_index -= num11; + num3 -= num11 << 3; + s.bitb = num2; + s.bitk = num3; + z.avail_in = num; + z.total_in += next_in_index - z.next_in_index; + z.next_in_index = next_in_index; + s.write = num4; + return -3; + } + } + if (num5 < 258 || num < 10) + { + break; + } + } + num11 = z.avail_in - num; + num11 = ((num3 >> 3 < num11) ? (num3 >> 3) : num11); + num += num11; + next_in_index -= num11; + num3 -= num11 << 3; + s.bitb = num2; + s.bitk = num3; + z.avail_in = num; + z.total_in += next_in_index - z.next_in_index; + z.next_in_index = next_in_index; + s.write = num4; + return 0; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfTree.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfTree.cs index 49ad715..7f81fa9 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfTree.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/InfTree.cs @@ -1,475 +1,478 @@ -using System; - -namespace ComponentAce.Compression.Libs.zlib -{ - internal sealed class InfTree - { - private const int MANY = 1440; - - private const int Z_OK = 0; - - private const int Z_STREAM_END = 1; - - private const int Z_NEED_DICT = 2; - - private const int Z_ERRNO = -1; - - private const int Z_STREAM_ERROR = -2; - - private const int Z_DATA_ERROR = -3; - - private const int Z_MEM_ERROR = -4; - - private const int Z_BUF_ERROR = -5; - - private const int Z_VERSION_ERROR = -6; - - internal const int fixed_bl = 9; - - internal const int fixed_bd = 5; - - internal static readonly int[] fixed_tl = new int[1536] - { - 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, - 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, - 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, - 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, - 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, - 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, - 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, - 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, - 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, - 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, - 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, - 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, - 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, - 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, - 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, - 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, - 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, - 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, - 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, - 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, - 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, - 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, - 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, - 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, - 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, - 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, - 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, - 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, - 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, - 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, - 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, - 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, - 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, - 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, - 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, - 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, - 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, - 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, - 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, - 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, - 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, - 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, - 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, - 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, - 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, - 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, - 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, - 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, - 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, - 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, - 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, - 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, - 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, - 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, - 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, - 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, - 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, - 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, - 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, - 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, - 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, - 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, - 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, - 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, - 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, - 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, - 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, - 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, - 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, - 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, - 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, - 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, - 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, - 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, - 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, - 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, - 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, - 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, - 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, - 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, - 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, - 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, - 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, - 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, - 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, - 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, - 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, - 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, - 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, - 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, - 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, - 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, - 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, - 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, - 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, - 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, - 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, - 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, - 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, - 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, - 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, - 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, - 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, - 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, - 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, - 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, - 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, - 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, - 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, - 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, - 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, - 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, - 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, - 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, - 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, - 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, - 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, - 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, - 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, - 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, - 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, - 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, - 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, - 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, - 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, - 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, - 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, - 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, - 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, - 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, - 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, - 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, - 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, - 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, - 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, - 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, - 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, - 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, - 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, - 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, - 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, - 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, - 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, - 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, - 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, - 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, - 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, - 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, - 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, - 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, - 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, - 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, - 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, - 0, 8, 79, 0, 9, 255 - }; - - internal static readonly int[] fixed_td = new int[96] - { - 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, - 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, - 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, - 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, - 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, - 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, - 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, - 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, - 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, - 86, 5, 193, 192, 5, 24577 - }; - - internal static readonly int[] cplens = new int[31] - { - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, - 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, - 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, - 0 - }; - - internal static readonly int[] cplext = new int[31] - { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, - 112 - }; - - internal static readonly int[] cpdist = new int[30] - { - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, - 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, - 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 - }; - - internal static readonly int[] cpdext = new int[30] - { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 - }; - - internal const int BMAX = 15; - - internal static int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) - { - int[] array = new int[16]; - int[] array2 = new int[3]; - int[] array3 = new int[15]; - int[] array4 = new int[16]; - int num = 0; - int num2 = n; - do - { - array[b[bindex + num]]++; - num++; - num2--; - } - while (num2 != 0); - if (array[0] == n) - { - t[0] = -1; - m[0] = 0; - return 0; - } - int num3 = m[0]; - int i; - for (i = 1; i <= 15 && array[i] == 0; i++) - { - } - int j = i; - if (num3 < i) - { - num3 = i; - } - num2 = 15; - while (num2 != 0 && array[num2] == 0) - { - num2--; - } - int num4 = num2; - if (num3 > num2) - { - num3 = num2; - } - m[0] = num3; - int num5 = 1 << i; - while (i < num2) - { - if ((num5 -= array[i]) < 0) - { - return -3; - } - i++; - num5 <<= 1; - } - if ((num5 -= array[num2]) < 0) - { - return -3; - } - array[num2] += num5; - i = (array4[1] = 0); - num = 1; - int num6 = 2; - while (--num2 != 0) - { - i = (array4[num6] = i + array[num]); - num6++; - num++; - } - num2 = 0; - num = 0; - do - { - if ((i = b[bindex + num]) != 0) - { - v[array4[i]++] = num2; - } - num++; - } - while (++num2 < n); - n = array4[num4]; - num2 = (array4[0] = 0); - num = 0; - int num7 = -1; - int num8 = -num3; - array3[0] = 0; - int num9 = 0; - int num10 = 0; - for (; j <= num4; j++) - { - int num11 = array[j]; - while (num11-- != 0) - { - int num12; - while (j > num8 + num3) - { - num7++; - num8 += num3; - num10 = num4 - num8; - num10 = ((num10 > num3) ? num3 : num10); - if ((num12 = 1 << (i = j - num8)) > num11 + 1) - { - num12 -= num11 + 1; - num6 = j; - if (i < num10) - { - while (++i < num10 && (num12 <<= 1) > array[++num6]) - { - num12 -= array[num6]; - } - } - } - num10 = 1 << i; - if (hn[0] + num10 > 1440) - { - return -3; - } - num9 = (array3[num7] = hn[0]); - hn[0] += num10; - if (num7 != 0) - { - array4[num7] = num2; - array2[0] = (byte)i; - array2[1] = (byte)num3; - i = SupportClass.URShift(num2, num8 - num3); - array2[2] = num9 - array3[num7 - 1] - i; - Array.Copy(array2, 0, hp, (array3[num7 - 1] + i) * 3, 3); - } - else - { - t[0] = num9; - } - } - array2[1] = (byte)(j - num8); - if (num >= n) - { - array2[0] = 192; - } - else if (v[num] < s) - { - array2[0] = (byte)((v[num] >= 256) ? 96 : 0); - array2[2] = v[num++]; - } - else - { - array2[0] = (byte)(e[v[num] - s] + 16 + 64); - array2[2] = d[v[num++] - s]; - } - num12 = 1 << j - num8; - for (i = SupportClass.URShift(num2, num8); i < num10; i += num12) - { - Array.Copy(array2, 0, hp, (num9 + i) * 3, 3); - } - i = 1 << j - 1; - while ((num2 & i) != 0) - { - num2 ^= i; - i = SupportClass.URShift(i, 1); - } - num2 ^= i; - int num13 = (1 << num8) - 1; - while ((num2 & num13) != array4[num7]) - { - num7--; - num8 -= num3; - num13 = (1 << num8) - 1; - } - } - } - return (num5 != 0 && num4 != 1) ? (-5) : 0; - } - - internal static int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZStream z) - { - int[] hn = new int[1]; - int[] v = new int[19]; - int num = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); - if (num == -3) - { - z.msg = "oversubscribed dynamic bit lengths tree"; - } - else if (num == -5 || bb[0] == 0) - { - z.msg = "incomplete dynamic bit lengths tree"; - num = -3; - } - return num; - } - - internal static int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZStream z) - { - int[] hn = new int[1]; - int[] v = new int[288]; - int num = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); - if (num != 0 || bl[0] == 0) - { - switch (num) - { - case -3: - z.msg = "oversubscribed literal/length tree"; - break; - default: - z.msg = "incomplete literal/length tree"; - num = -3; - break; - case -4: - break; - } - return num; - } - num = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); - if (num != 0 || (bd[0] == 0 && nl > 257)) - { - switch (num) - { - case -3: - z.msg = "oversubscribed distance tree"; - break; - case -5: - z.msg = "incomplete distance tree"; - num = -3; - break; - default: - z.msg = "empty distance tree with lengths"; - num = -3; - break; - case -4: - break; - } - return num; - } - return 0; - } - - internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZStream z) - { - bl[0] = 9; - bd[0] = 5; - tl[0] = fixed_tl; - td[0] = fixed_td; - return 0; - } - } +using System; + +namespace ComponentAce.Compression.Libs.zlib; + +internal sealed class InfTree +{ + private const int MANY = 1440; + + private const int Z_OK = 0; + + private const int Z_STREAM_END = 1; + + private const int Z_NEED_DICT = 2; + + private const int Z_ERRNO = -1; + + private const int Z_STREAM_ERROR = -2; + + private const int Z_DATA_ERROR = -3; + + private const int Z_MEM_ERROR = -4; + + private const int Z_BUF_ERROR = -5; + + private const int Z_VERSION_ERROR = -6; + + internal const int fixed_bl = 9; + + internal const int fixed_bd = 5; + + internal static readonly int[] fixed_tl = new int[1536] + { + 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, + 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, + 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, + 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, + 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, + 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, + 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, + 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, + 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, + 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, + 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, + 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, + 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, + 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, + 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, + 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, + 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, + 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, + 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, + 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, + 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, + 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, + 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, + 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, + 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, + 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, + 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, + 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, + 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, + 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, + 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, + 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, + 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, + 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, + 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, + 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, + 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, + 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, + 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, + 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, + 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, + 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, + 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, + 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, + 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, + 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, + 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, + 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, + 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, + 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, + 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, + 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, + 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, + 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, + 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, + 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, + 45, 0, 9, 186, 0, 8, 13, 0, 8, 141, + 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, + 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, + 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, + 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, + 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, + 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, + 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, + 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, + 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, + 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, + 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, + 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, + 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, + 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, + 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, + 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, + 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, + 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, + 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, + 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, + 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, + 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, + 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, + 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, + 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, + 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, + 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, + 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, + 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, + 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, + 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, + 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, + 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, + 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, + 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, + 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, + 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, + 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, + 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, + 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, + 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, + 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, + 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, + 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, + 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, + 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, + 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, + 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, + 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, + 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, + 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, + 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, + 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, + 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, + 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, + 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, + 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, + 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, + 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, + 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, + 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, + 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, + 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, + 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, + 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, + 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, + 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, + 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, + 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, + 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, + 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, + 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, + 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, + 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, + 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, + 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, + 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, + 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, + 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, + 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, + 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, + 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, + 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, + 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, + 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, + 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, + 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, + 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, + 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, + 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, + 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, + 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, + 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, + 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, + 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, + 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, + 0, 8, 79, 0, 9, 255 + }; + + internal static readonly int[] fixed_td = new int[96] + { + 80, 5, 1, 87, 5, 257, 83, 5, 17, 91, + 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, + 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, + 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, + 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, + 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, + 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, + 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, + 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, + 86, 5, 193, 192, 5, 24577 + }; + + internal static readonly int[] cplens = new int[31] + { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, + 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, + 0 + }; + + internal static readonly int[] cplext = new int[31] + { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, + 112 + }; + + internal static readonly int[] cpdist = new int[30] + { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, + 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, + 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577 + }; + + internal static readonly int[] cpdext = new int[30] + { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 + }; + + internal const int BMAX = 15; + + internal static int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) + { + int[] array = new int[16]; + int[] array2 = new int[3]; + int[] array3 = new int[15]; + int[] array4 = new int[16]; + int num = 0; + int num2 = n; + do + { + array[b[bindex + num]]++; + num++; + num2--; + } + while (num2 != 0); + if (array[0] == n) + { + t[0] = -1; + m[0] = 0; + return 0; + } + int num3 = m[0]; + int i; + for (i = 1; i <= 15 && array[i] == 0; i++) + { + } + int j = i; + if (num3 < i) + { + num3 = i; + } + num2 = 15; + while (num2 != 0 && array[num2] == 0) + { + num2--; + } + int num4 = num2; + if (num3 > num2) + { + num3 = num2; + } + m[0] = num3; + int num5 = 1 << i; + while (i < num2) + { + if ((num5 -= array[i]) < 0) + { + return -3; + } + i++; + num5 <<= 1; + } + if ((num5 -= array[num2]) < 0) + { + return -3; + } + array[num2] += num5; + i = (array4[1] = 0); + num = 1; + int num6 = 2; + while (--num2 != 0) + { + i = (array4[num6] = i + array[num]); + num6++; + num++; + } + num2 = 0; + num = 0; + do + { + if ((i = b[bindex + num]) != 0) + { + v[array4[i]++] = num2; + } + num++; + } + while (++num2 < n); + n = array4[num4]; + num2 = (array4[0] = 0); + num = 0; + int num7 = -1; + int num8 = -num3; + array3[0] = 0; + int num9 = 0; + int num10 = 0; + for (; j <= num4; j++) + { + int num11 = array[j]; + while (num11-- != 0) + { + int num12; + while (j > num8 + num3) + { + num7++; + num8 += num3; + num10 = num4 - num8; + num10 = ((num10 > num3) ? num3 : num10); + if ((num12 = 1 << (i = j - num8)) > num11 + 1) + { + num12 -= num11 + 1; + num6 = j; + if (i < num10) + { + while (++i < num10 && (num12 <<= 1) > array[++num6]) + { + num12 -= array[num6]; + } + } + } + num10 = 1 << i; + if (hn[0] + num10 > 1440) + { + return -3; + } + num9 = (array3[num7] = hn[0]); + hn[0] += num10; + if (num7 != 0) + { + array4[num7] = num2; + array2[0] = (byte)i; + array2[1] = (byte)num3; + i = SupportClass.URShift(num2, num8 - num3); + array2[2] = num9 - array3[num7 - 1] - i; + Array.Copy(array2, 0, hp, (array3[num7 - 1] + i) * 3, 3); + } + else + { + t[0] = num9; + } + } + array2[1] = (byte)(j - num8); + if (num >= n) + { + array2[0] = 192; + } + else if (v[num] < s) + { + array2[0] = (byte)((v[num] >= 256) ? 96 : 0); + array2[2] = v[num++]; + } + else + { + array2[0] = (byte)(e[v[num] - s] + 16 + 64); + array2[2] = d[v[num++] - s]; + } + num12 = 1 << j - num8; + for (i = SupportClass.URShift(num2, num8); i < num10; i += num12) + { + Array.Copy(array2, 0, hp, (num9 + i) * 3, 3); + } + i = 1 << j - 1; + while ((num2 & i) != 0) + { + num2 ^= i; + i = SupportClass.URShift(i, 1); + } + num2 ^= i; + int num13 = (1 << num8) - 1; + while ((num2 & num13) != array4[num7]) + { + num7--; + num8 -= num3; + num13 = (1 << num8) - 1; + } + } + } + if (num5 == 0 || num4 == 1) + { + return 0; + } + return -5; + } + + internal static int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZStream z) + { + int[] hn = new int[1]; + int[] v = new int[19]; + int num = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); + if (num == -3) + { + z.msg = "oversubscribed dynamic bit lengths tree"; + } + else if (num == -5 || bb[0] == 0) + { + z.msg = "incomplete dynamic bit lengths tree"; + num = -3; + } + return num; + } + + internal static int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZStream z) + { + int[] hn = new int[1]; + int[] v = new int[288]; + int num = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); + if (num != 0 || bl[0] == 0) + { + switch (num) + { + case -3: + z.msg = "oversubscribed literal/length tree"; + break; + default: + z.msg = "incomplete literal/length tree"; + num = -3; + break; + case -4: + break; + } + return num; + } + num = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); + if (num != 0 || (bd[0] == 0 && nl > 257)) + { + switch (num) + { + case -3: + z.msg = "oversubscribed distance tree"; + break; + case -5: + z.msg = "incomplete distance tree"; + num = -3; + break; + default: + z.msg = "empty distance tree with lengths"; + num = -3; + break; + case -4: + break; + } + return num; + } + return 0; + } + + internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZStream z) + { + bl[0] = 9; + bd[0] = 5; + tl[0] = fixed_tl; + td[0] = fixed_td; + return 0; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Inflate.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Inflate.cs index 8fac406..772c418 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Inflate.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Inflate.cs @@ -1,409 +1,408 @@ -namespace ComponentAce.Compression.Libs.zlib -{ - internal sealed class Inflate - { - private const int MAX_WBITS = 15; - - private const int PRESET_DICT = 32; - - internal const int Z_NO_FLUSH = 0; - - internal const int Z_PARTIAL_FLUSH = 1; - - internal const int Z_SYNC_FLUSH = 2; - - internal const int Z_FULL_FLUSH = 3; - - internal const int Z_FINISH = 4; - - private const int Z_DEFLATED = 8; - - private const int Z_OK = 0; - - private const int Z_STREAM_END = 1; - - private const int Z_NEED_DICT = 2; - - private const int Z_ERRNO = -1; - - private const int Z_STREAM_ERROR = -2; - - private const int Z_DATA_ERROR = -3; - - private const int Z_MEM_ERROR = -4; - - private const int Z_BUF_ERROR = -5; - - private const int Z_VERSION_ERROR = -6; - - private const int METHOD = 0; - - private const int FLAG = 1; - - private const int DICT4 = 2; - - private const int DICT3 = 3; - - private const int DICT2 = 4; - - private const int DICT1 = 5; - - private const int DICT0 = 6; - - private const int BLOCKS = 7; - - private const int CHECK4 = 8; - - private const int CHECK3 = 9; - - private const int CHECK2 = 10; - - private const int CHECK1 = 11; - - private const int DONE = 12; - - private const int BAD = 13; - - internal int mode; - - internal int method; - - internal long[] was = new long[1]; - - internal long need; - - internal int marker; - - internal int nowrap; - - internal int wbits; - - internal InfBlocks blocks; - - private static byte[] mark = new byte[4] - { - 0, - 0, - (byte)SupportClass.Identity(255L), - (byte)SupportClass.Identity(255L) - }; - - internal int inflateReset(ZStream z) - { - if (z == null || z.istate == null) - { - return -2; - } - z.total_in = (z.total_out = 0L); - z.msg = null; - z.istate.mode = ((z.istate.nowrap != 0) ? 7 : 0); - z.istate.blocks.reset(z, null); - return 0; - } - - internal int inflateEnd(ZStream z) - { - if (blocks != null) - { - blocks.free(z); - } - blocks = null; - return 0; - } - - internal int inflateInit(ZStream z, int w) - { - z.msg = null; - blocks = null; - nowrap = 0; - if (w < 0) - { - w = -w; - nowrap = 1; - } - if (w < 8 || w > 15) - { - inflateEnd(z); - return -2; - } - wbits = w; - z.istate.blocks = new InfBlocks(z, (z.istate.nowrap != 0) ? null : this, 1 << w); - inflateReset(z); - return 0; - } - - internal int inflate(ZStream z, int f) - { - if (z == null || z.istate == null || z.next_in == null) - { - return -2; - } - f = ((f == 4) ? (-5) : 0); - int num = -5; - while (true) - { - switch (z.istate.mode) - { - case 0: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xF) != 8) - { - z.istate.mode = 13; - z.msg = "unknown compression method"; - z.istate.marker = 5; - break; - } - if ((z.istate.method >> 4) + 8 > z.istate.wbits) - { - z.istate.mode = 13; - z.msg = "invalid window size"; - z.istate.marker = 5; - break; - } - z.istate.mode = 1; - goto case 1; - case 1: - { - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - int num2 = z.next_in[z.next_in_index++] & 0xFF; - if (((z.istate.method << 8) + num2) % 31 != 0) - { - z.istate.mode = 13; - z.msg = "incorrect header check"; - z.istate.marker = 5; - break; - } - if ((num2 & 0x20) == 0) - { - z.istate.mode = 7; - break; - } - z.istate.mode = 2; - goto case 2; - } - case 2: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - z.istate.need = ((z.next_in[z.next_in_index++] & 0xFF) << 24) & -16777216; - z.istate.mode = 3; - goto case 3; - case 3: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 16) & 0xFF0000uL); - z.istate.mode = 4; - goto case 4; - case 4: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 8) & 0xFF00uL); - z.istate.mode = 5; - goto case 5; - case 5: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - z.istate.need += (long)((ulong)z.next_in[z.next_in_index++] & 0xFFuL); - z.adler = z.istate.need; - z.istate.mode = 6; - return 2; - case 6: - z.istate.mode = 13; - z.msg = "need dictionary"; - z.istate.marker = 0; - return -2; - case 7: - num = z.istate.blocks.proc(z, num); - switch (num) - { - case -3: - z.istate.mode = 13; - z.istate.marker = 0; - goto end_IL_004b; - case 0: - num = f; - break; - } - if (num != 1) - { - return num; - } - num = f; - z.istate.blocks.reset(z, z.istate.was); - if (z.istate.nowrap != 0) - { - z.istate.mode = 12; - break; - } - z.istate.mode = 8; - goto case 8; - case 8: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - z.istate.need = ((z.next_in[z.next_in_index++] & 0xFF) << 24) & -16777216; - z.istate.mode = 9; - goto case 9; - case 9: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 16) & 0xFF0000uL); - z.istate.mode = 10; - goto case 10; - case 10: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 8) & 0xFF00uL); - z.istate.mode = 11; - goto case 11; - case 11: - if (z.avail_in == 0) - { - return num; - } - num = f; - z.avail_in--; - z.total_in++; - z.istate.need += (long)((ulong)z.next_in[z.next_in_index++] & 0xFFuL); - if ((int)z.istate.was[0] != (int)z.istate.need) - { - z.istate.mode = 13; - z.msg = "incorrect data check"; - z.istate.marker = 5; - break; - } - z.istate.mode = 12; - goto case 12; - case 12: - return 1; - case 13: - return -3; - default: - { - return -2; - } - end_IL_004b: - break; - } - } - } - - internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) - { - int start = 0; - int num = dictLength; - if (z == null || z.istate == null || z.istate.mode != 6) - { - return -2; - } - if (z._adler.adler32(1L, dictionary, 0, dictLength) != z.adler) - { - return -3; - } - z.adler = z._adler.adler32(0L, null, 0, 0); - if (num >= 1 << z.istate.wbits) - { - num = (1 << z.istate.wbits) - 1; - start = dictLength - num; - } - z.istate.blocks.set_dictionary(dictionary, start, num); - z.istate.mode = 7; - return 0; - } - - internal int inflateSync(ZStream z) - { - if (z == null || z.istate == null) - { - return -2; - } - if (z.istate.mode != 13) - { - z.istate.mode = 13; - z.istate.marker = 0; - } - int num; - if ((num = z.avail_in) == 0) - { - return -5; - } - int num2 = z.next_in_index; - int num3 = z.istate.marker; - while (num != 0 && num3 < 4) - { - num3 = ((z.next_in[num2] != mark[num3]) ? ((z.next_in[num2] == 0) ? (4 - num3) : 0) : (num3 + 1)); - num2++; - num--; - } - z.total_in += num2 - z.next_in_index; - z.next_in_index = num2; - z.avail_in = num; - z.istate.marker = num3; - if (num3 != 4) - { - return -3; - } - long total_in = z.total_in; - long total_out = z.total_out; - inflateReset(z); - z.total_in = total_in; - z.total_out = total_out; - z.istate.mode = 7; - return 0; - } - - internal int inflateSyncPoint(ZStream z) - { - if (z == null || z.istate == null || z.istate.blocks == null) - { - return -2; - } - return z.istate.blocks.sync_point(); - } - } +namespace ComponentAce.Compression.Libs.zlib; + +internal sealed class Inflate +{ + private const int MAX_WBITS = 15; + + private const int PRESET_DICT = 32; + + internal const int Z_NO_FLUSH = 0; + + internal const int Z_PARTIAL_FLUSH = 1; + + internal const int Z_SYNC_FLUSH = 2; + + internal const int Z_FULL_FLUSH = 3; + + internal const int Z_FINISH = 4; + + private const int Z_DEFLATED = 8; + + private const int Z_OK = 0; + + private const int Z_STREAM_END = 1; + + private const int Z_NEED_DICT = 2; + + private const int Z_ERRNO = -1; + + private const int Z_STREAM_ERROR = -2; + + private const int Z_DATA_ERROR = -3; + + private const int Z_MEM_ERROR = -4; + + private const int Z_BUF_ERROR = -5; + + private const int Z_VERSION_ERROR = -6; + + private const int METHOD = 0; + + private const int FLAG = 1; + + private const int DICT4 = 2; + + private const int DICT3 = 3; + + private const int DICT2 = 4; + + private const int DICT1 = 5; + + private const int DICT0 = 6; + + private const int BLOCKS = 7; + + private const int CHECK4 = 8; + + private const int CHECK3 = 9; + + private const int CHECK2 = 10; + + private const int CHECK1 = 11; + + private const int DONE = 12; + + private const int BAD = 13; + + internal int mode; + + internal int method; + + internal long[] was = new long[1]; + + internal long need; + + internal int marker; + + internal int nowrap; + + internal int wbits; + + internal InfBlocks blocks; + + private static byte[] mark = new byte[4] + { + 0, + 0, + (byte)SupportClass.Identity(255L), + (byte)SupportClass.Identity(255L) + }; + + internal int inflateReset(ZStream z) + { + if (z == null || z.istate == null) + { + return -2; + } + z.total_in = (z.total_out = 0L); + z.msg = null; + z.istate.mode = ((z.istate.nowrap != 0) ? 7 : 0); + z.istate.blocks.reset(z, null); + return 0; + } + + internal int inflateEnd(ZStream z) + { + if (blocks != null) + { + blocks.free(z); + } + blocks = null; + return 0; + } + + internal int inflateInit(ZStream z, int w) + { + z.msg = null; + blocks = null; + nowrap = 0; + if (w < 0) + { + w = -w; + nowrap = 1; + } + if (w < 8 || w > 15) + { + inflateEnd(z); + return -2; + } + wbits = w; + z.istate.blocks = new InfBlocks(z, (z.istate.nowrap != 0) ? null : this, 1 << w); + inflateReset(z); + return 0; + } + + internal int inflate(ZStream z, int f) + { + if (z == null || z.istate == null || z.next_in == null) + { + return -2; + } + f = ((f == 4) ? (-5) : 0); + int num = -5; + while (true) + { + switch (z.istate.mode) + { + case 0: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xF) != 8) + { + z.istate.mode = 13; + z.msg = "unknown compression method"; + z.istate.marker = 5; + break; + } + if ((z.istate.method >> 4) + 8 > z.istate.wbits) + { + z.istate.mode = 13; + z.msg = "invalid window size"; + z.istate.marker = 5; + break; + } + z.istate.mode = 1; + goto case 1; + case 1: + { + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + int num2 = z.next_in[z.next_in_index++] & 0xFF; + if (((z.istate.method << 8) + num2) % 31 != 0) + { + z.istate.mode = 13; + z.msg = "incorrect header check"; + z.istate.marker = 5; + break; + } + if ((num2 & 0x20) == 0) + { + z.istate.mode = 7; + break; + } + z.istate.mode = 2; + goto case 2; + } + case 2: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + z.istate.need = ((z.next_in[z.next_in_index++] & 0xFF) << 24) & -16777216; + z.istate.mode = 3; + goto case 3; + case 3: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 16) & 0xFF0000uL); + z.istate.mode = 4; + goto case 4; + case 4: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 8) & 0xFF00uL); + z.istate.mode = 5; + goto case 5; + case 5: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + z.istate.need += (long)((ulong)z.next_in[z.next_in_index++] & 0xFFuL); + z.adler = z.istate.need; + z.istate.mode = 6; + return 2; + case 6: + z.istate.mode = 13; + z.msg = "need dictionary"; + z.istate.marker = 0; + return -2; + case 7: + num = z.istate.blocks.proc(z, num); + switch (num) + { + case -3: + z.istate.mode = 13; + z.istate.marker = 0; + goto end_IL_0031; + case 0: + num = f; + break; + } + if (num != 1) + { + return num; + } + num = f; + z.istate.blocks.reset(z, z.istate.was); + if (z.istate.nowrap != 0) + { + z.istate.mode = 12; + break; + } + z.istate.mode = 8; + goto case 8; + case 8: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + z.istate.need = ((z.next_in[z.next_in_index++] & 0xFF) << 24) & -16777216; + z.istate.mode = 9; + goto case 9; + case 9: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 16) & 0xFF0000uL); + z.istate.mode = 10; + goto case 10; + case 10: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + z.istate.need += (long)((ulong)((z.next_in[z.next_in_index++] & 0xFF) << 8) & 0xFF00uL); + z.istate.mode = 11; + goto case 11; + case 11: + if (z.avail_in == 0) + { + return num; + } + num = f; + z.avail_in--; + z.total_in++; + z.istate.need += (long)((ulong)z.next_in[z.next_in_index++] & 0xFFuL); + if ((int)z.istate.was[0] != (int)z.istate.need) + { + z.istate.mode = 13; + z.msg = "incorrect data check"; + z.istate.marker = 5; + break; + } + z.istate.mode = 12; + goto case 12; + case 12: + return 1; + case 13: + return -3; + default: + { + return -2; + } + end_IL_0031: + break; + } + } + } + + internal int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) + { + int start = 0; + int num = dictLength; + if (z == null || z.istate == null || z.istate.mode != 6) + { + return -2; + } + if (z._adler.adler32(1L, dictionary, 0, dictLength) != z.adler) + { + return -3; + } + z.adler = z._adler.adler32(0L, null, 0, 0); + if (num >= 1 << z.istate.wbits) + { + num = (1 << z.istate.wbits) - 1; + start = dictLength - num; + } + z.istate.blocks.set_dictionary(dictionary, start, num); + z.istate.mode = 7; + return 0; + } + + internal int inflateSync(ZStream z) + { + if (z == null || z.istate == null) + { + return -2; + } + if (z.istate.mode != 13) + { + z.istate.mode = 13; + z.istate.marker = 0; + } + int num; + if ((num = z.avail_in) == 0) + { + return -5; + } + int num2 = z.next_in_index; + int num3 = z.istate.marker; + while (num != 0 && num3 < 4) + { + num3 = ((z.next_in[num2] != mark[num3]) ? ((z.next_in[num2] == 0) ? (4 - num3) : 0) : (num3 + 1)); + num2++; + num--; + } + z.total_in += num2 - z.next_in_index; + z.next_in_index = num2; + z.avail_in = num; + z.istate.marker = num3; + if (num3 != 4) + { + return -3; + } + long total_in = z.total_in; + long total_out = z.total_out; + inflateReset(z); + z.total_in = total_in; + z.total_out = total_out; + z.istate.mode = 7; + return 0; + } + + internal int inflateSyncPoint(ZStream z) + { + if (z == null || z.istate == null || z.istate.blocks == null) + { + return -2; + } + return z.istate.blocks.sync_point(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/StaticTree.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/StaticTree.cs index a5964a8..346261a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/StaticTree.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/StaticTree.cs @@ -1,126 +1,125 @@ -namespace ComponentAce.Compression.Libs.zlib -{ - internal sealed class StaticTree - { - private const int MAX_BITS = 15; - - private const int BL_CODES = 19; - - private const int D_CODES = 30; - - private const int LITERALS = 256; - - private const int LENGTH_CODES = 29; - - private static readonly int L_CODES; - - internal const int MAX_BL_BITS = 7; - - internal static readonly short[] static_ltree; - - internal static readonly short[] static_dtree; - - internal static StaticTree static_l_desc; - - internal static StaticTree static_d_desc; - - internal static StaticTree static_bl_desc; - - internal short[] static_tree; - - internal int[] extra_bits; - - internal int extra_base; - - internal int elems; - - internal int max_length; - - internal StaticTree(short[] static_tree, int[] extra_bits, int extra_base, int elems, int max_length) - { - this.static_tree = static_tree; - this.extra_bits = extra_bits; - this.extra_base = extra_base; - this.elems = elems; - this.max_length = max_length; - } - - static StaticTree() - { - L_CODES = 286; - static_ltree = new short[576] - { - 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, - 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, - 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, - 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, - 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, - 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, - 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, - 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, - 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, - 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, - 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, - 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, - 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, - 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, - 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, - 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, - 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, - 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, - 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, - 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, - 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, - 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, - 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, - 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, - 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, - 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, - 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, - 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, - 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, - 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, - 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, - 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, - 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, - 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, - 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, - 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, - 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, - 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, - 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, - 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, - 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, - 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, - 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, - 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, - 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, - 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, - 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, - 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, - 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, - 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, - 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, - 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, - 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, - 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, - 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, - 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, - 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, - 163, 8, 99, 8, 227, 8 - }; - static_dtree = new short[60] - { - 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, - 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, - 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, - 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, - 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, - 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 - }; - static_l_desc = new StaticTree(static_ltree, Tree.extra_lbits, 257, L_CODES, 15); - static_d_desc = new StaticTree(static_dtree, Tree.extra_dbits, 0, 30, 15); - static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, 19, 7); - } - } +namespace ComponentAce.Compression.Libs.zlib; + +internal sealed class StaticTree +{ + private const int MAX_BITS = 15; + + private const int BL_CODES = 19; + + private const int D_CODES = 30; + + private const int LITERALS = 256; + + private const int LENGTH_CODES = 29; + + private static readonly int L_CODES; + + internal const int MAX_BL_BITS = 7; + + internal static readonly short[] static_ltree; + + internal static readonly short[] static_dtree; + + internal static StaticTree static_l_desc; + + internal static StaticTree static_d_desc; + + internal static StaticTree static_bl_desc; + + internal short[] static_tree; + + internal int[] extra_bits; + + internal int extra_base; + + internal int elems; + + internal int max_length; + + internal StaticTree(short[] static_tree, int[] extra_bits, int extra_base, int elems, int max_length) + { + this.static_tree = static_tree; + this.extra_bits = extra_bits; + this.extra_base = extra_base; + this.elems = elems; + this.max_length = max_length; + } + + static StaticTree() + { + L_CODES = 286; + static_ltree = new short[576] + { + 12, 8, 140, 8, 76, 8, 204, 8, 44, 8, + 172, 8, 108, 8, 236, 8, 28, 8, 156, 8, + 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, + 252, 8, 2, 8, 130, 8, 66, 8, 194, 8, + 34, 8, 162, 8, 98, 8, 226, 8, 18, 8, + 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, + 114, 8, 242, 8, 10, 8, 138, 8, 74, 8, + 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, + 26, 8, 154, 8, 90, 8, 218, 8, 58, 8, + 186, 8, 122, 8, 250, 8, 6, 8, 134, 8, + 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, + 230, 8, 22, 8, 150, 8, 86, 8, 214, 8, + 54, 8, 182, 8, 118, 8, 246, 8, 14, 8, + 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, + 110, 8, 238, 8, 30, 8, 158, 8, 94, 8, + 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, + 1, 8, 129, 8, 65, 8, 193, 8, 33, 8, + 161, 8, 97, 8, 225, 8, 17, 8, 145, 8, + 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, + 241, 8, 9, 8, 137, 8, 73, 8, 201, 8, + 41, 8, 169, 8, 105, 8, 233, 8, 25, 8, + 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, + 121, 8, 249, 8, 5, 8, 133, 8, 69, 8, + 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, + 21, 8, 149, 8, 85, 8, 213, 8, 53, 8, + 181, 8, 117, 8, 245, 8, 13, 8, 141, 8, + 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, + 237, 8, 29, 8, 157, 8, 93, 8, 221, 8, + 61, 8, 189, 8, 125, 8, 253, 8, 19, 9, + 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, + 211, 9, 467, 9, 51, 9, 307, 9, 179, 9, + 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, + 11, 9, 267, 9, 139, 9, 395, 9, 75, 9, + 331, 9, 203, 9, 459, 9, 43, 9, 299, 9, + 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, + 491, 9, 27, 9, 283, 9, 155, 9, 411, 9, + 91, 9, 347, 9, 219, 9, 475, 9, 59, 9, + 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, + 251, 9, 507, 9, 7, 9, 263, 9, 135, 9, + 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, + 39, 9, 295, 9, 167, 9, 423, 9, 103, 9, + 359, 9, 231, 9, 487, 9, 23, 9, 279, 9, + 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, + 471, 9, 55, 9, 311, 9, 183, 9, 439, 9, + 119, 9, 375, 9, 247, 9, 503, 9, 15, 9, + 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, + 207, 9, 463, 9, 47, 9, 303, 9, 175, 9, + 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, + 31, 9, 287, 9, 159, 9, 415, 9, 95, 9, + 351, 9, 223, 9, 479, 9, 63, 9, 319, 9, + 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, + 511, 9, 0, 7, 64, 7, 32, 7, 96, 7, + 16, 7, 80, 7, 48, 7, 112, 7, 8, 7, + 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, + 56, 7, 120, 7, 4, 7, 68, 7, 36, 7, + 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, + 3, 8, 131, 8, 67, 8, 195, 8, 35, 8, + 163, 8, 99, 8, 227, 8 + }; + static_dtree = new short[60] + { + 0, 5, 16, 5, 8, 5, 24, 5, 4, 5, + 20, 5, 12, 5, 28, 5, 2, 5, 18, 5, + 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, + 30, 5, 1, 5, 17, 5, 9, 5, 25, 5, + 5, 5, 21, 5, 13, 5, 29, 5, 3, 5, + 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 + }; + static_l_desc = new StaticTree(static_ltree, Tree.extra_lbits, 257, L_CODES, 15); + static_d_desc = new StaticTree(static_dtree, Tree.extra_dbits, 0, 30, 15); + static_bl_desc = new StaticTree(null, Tree.extra_blbits, 0, 19, 7); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/SupportClass.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/SupportClass.cs index 7b9f174..50a31b9 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/SupportClass.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/SupportClass.cs @@ -1,104 +1,103 @@ -using System.IO; -using System.Text; - -namespace ComponentAce.Compression.Libs.zlib -{ - public class SupportClass - { - public static long Identity(long literal) - { - return literal; - } - - public static ulong Identity(ulong literal) - { - return literal; - } - - public static float Identity(float literal) - { - return literal; - } - - public static double Identity(double literal) - { - return literal; - } - - public static int URShift(int number, int bits) - { - if (number >= 0) - { - return number >> bits; - } - return (number >> bits) + (2 << ~bits); - } - - public static int URShift(int number, long bits) - { - return URShift(number, (int)bits); - } - - public static long URShift(long number, int bits) - { - if (number >= 0) - { - return number >> bits; - } - return (number >> bits) + (2L << ~bits); - } - - public static long URShift(long number, long bits) - { - return URShift(number, (int)bits); - } - - public static int ReadInput(Stream sourceStream, byte[] target, int start, int count) - { - if (target.Length == 0) - { - return 0; - } - byte[] array = new byte[target.Length]; - int num = sourceStream.Read(array, start, count); - if (num == 0) - { - return -1; - } - for (int i = start; i < start + num; i++) - { - target[i] = array[i]; - } - return num; - } - - public static int ReadInput(TextReader sourceTextReader, byte[] target, int start, int count) - { - if (target.Length == 0) - { - return 0; - } - char[] array = new char[target.Length]; - int num = sourceTextReader.Read(array, start, count); - if (num == 0) - { - return -1; - } - for (int i = start; i < start + num; i++) - { - target[i] = (byte)array[i]; - } - return num; - } - - public static byte[] ToByteArray(string sourceString) - { - return Encoding.UTF8.GetBytes(sourceString); - } - - public static char[] ToCharArray(byte[] byteArray) - { - return Encoding.UTF8.GetChars(byteArray); - } - } +using System.IO; +using System.Text; + +namespace ComponentAce.Compression.Libs.zlib; + +public class SupportClass +{ + public static long Identity(long literal) + { + return literal; + } + + public static ulong Identity(ulong literal) + { + return literal; + } + + public static float Identity(float literal) + { + return literal; + } + + public static double Identity(double literal) + { + return literal; + } + + public static int URShift(int number, int bits) + { + if (number >= 0) + { + return number >> bits; + } + return (number >> bits) + (2 << ~bits); + } + + public static int URShift(int number, long bits) + { + return URShift(number, (int)bits); + } + + public static long URShift(long number, int bits) + { + if (number >= 0) + { + return number >> bits; + } + return (number >> bits) + (2L << ~bits); + } + + public static long URShift(long number, long bits) + { + return URShift(number, (int)bits); + } + + public static int ReadInput(Stream sourceStream, byte[] target, int start, int count) + { + if (target.Length == 0) + { + return 0; + } + byte[] array = new byte[target.Length]; + int num = sourceStream.Read(array, start, count); + if (num == 0) + { + return -1; + } + for (int i = start; i < start + num; i++) + { + target[i] = array[i]; + } + return num; + } + + public static int ReadInput(TextReader sourceTextReader, byte[] target, int start, int count) + { + if (target.Length == 0) + { + return 0; + } + char[] array = new char[target.Length]; + int num = sourceTextReader.Read(array, start, count); + if (num == 0) + { + return -1; + } + for (int i = start; i < start + num; i++) + { + target[i] = (byte)array[i]; + } + return num; + } + + public static byte[] ToByteArray(string sourceString) + { + return Encoding.UTF8.GetBytes(sourceString); + } + + public static char[] ToCharArray(byte[] byteArray) + { + return Encoding.UTF8.GetChars(byteArray); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Tree.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Tree.cs index 00b1236..9990c3c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Tree.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/Tree.cs @@ -1,337 +1,340 @@ -using System; - -namespace ComponentAce.Compression.Libs.zlib -{ - internal sealed class Tree - { - private const int MAX_BITS = 15; - - private const int BL_CODES = 19; - - private const int D_CODES = 30; - - private const int LITERALS = 256; - - private const int LENGTH_CODES = 29; - - private static readonly int L_CODES = 286; - - private static readonly int HEAP_SIZE = 2 * L_CODES + 1; - - internal const int MAX_BL_BITS = 7; - - internal const int END_BLOCK = 256; - - internal const int REP_3_6 = 16; - - internal const int REPZ_3_10 = 17; - - internal const int REPZ_11_138 = 18; - - internal static readonly int[] extra_lbits = new int[29] - { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, - 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 0 - }; - - internal static readonly int[] extra_dbits = new int[30] - { - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, - 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 - }; - - internal static readonly int[] extra_blbits = new int[19] - { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 3, 7 - }; - - internal static readonly byte[] bl_order = new byte[19] - { - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, - 11, 4, 12, 3, 13, 2, 14, 1, 15 - }; - - internal const int Buf_size = 16; - - internal const int DIST_CODE_LEN = 512; - - internal static readonly byte[] _dist_code = new byte[512] - { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, - 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, - 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, - 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, - 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29 - }; - - internal static readonly byte[] _length_code = new byte[256] - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, - 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, - 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, - 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, - 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, - 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 28 - }; - - internal static readonly int[] base_length = new int[29] - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, - 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, - 64, 80, 96, 112, 128, 160, 192, 224, 0 - }; - - internal static readonly int[] base_dist = new int[30] - { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 - }; - - internal short[] dyn_tree; - - internal int max_code; - - internal StaticTree stat_desc; - - internal static int d_code(int dist) - { - return (dist < 256) ? _dist_code[dist] : _dist_code[256 + SupportClass.URShift(dist, 7)]; - } - - internal void gen_bitlen(Deflate s) - { - short[] array = dyn_tree; - short[] static_tree = stat_desc.static_tree; - int[] extra_bits = stat_desc.extra_bits; - int extra_base = stat_desc.extra_base; - int max_length = stat_desc.max_length; - int num = 0; - for (int i = 0; i <= 15; i++) - { - s.bl_count[i] = 0; - } - array[s.heap[s.heap_max] * 2 + 1] = 0; - int j; - for (j = s.heap_max + 1; j < HEAP_SIZE; j++) - { - int num2 = s.heap[j]; - int i = array[array[num2 * 2 + 1] * 2 + 1] + 1; - if (i > max_length) - { - i = max_length; - num++; - } - array[num2 * 2 + 1] = (short)i; - if (num2 <= max_code) - { - s.bl_count[i]++; - int num3 = 0; - if (num2 >= extra_base) - { - num3 = extra_bits[num2 - extra_base]; - } - short num4 = array[num2 * 2]; - s.opt_len += num4 * (i + num3); - if (static_tree != null) - { - s.static_len += num4 * (static_tree[num2 * 2 + 1] + num3); - } - } - } - if (num == 0) - { - return; - } - do - { - int i = max_length - 1; - while (s.bl_count[i] == 0) - { - i--; - } - s.bl_count[i]--; - s.bl_count[i + 1] = (short)(s.bl_count[i + 1] + 2); - s.bl_count[max_length]--; - num -= 2; - } - while (num > 0); - for (int i = max_length; i != 0; i--) - { - int num2 = s.bl_count[i]; - while (num2 != 0) - { - int num5 = s.heap[--j]; - if (num5 <= max_code) - { - if (array[num5 * 2 + 1] != i) - { - s.opt_len = (int)(s.opt_len + ((long)i - (long)array[num5 * 2 + 1]) * array[num5 * 2]); - array[num5 * 2 + 1] = (short)i; - } - num2--; - } - } - } - } - - internal void build_tree(Deflate s) - { - short[] array = dyn_tree; - short[] static_tree = stat_desc.static_tree; - int elems = stat_desc.elems; - int num = -1; - s.heap_len = 0; - s.heap_max = HEAP_SIZE; - for (int i = 0; i < elems; i++) - { - if (array[i * 2] != 0) - { - num = (s.heap[++s.heap_len] = i); - s.depth[i] = 0; - } - else - { - array[i * 2 + 1] = 0; - } - } - int num2; - while (s.heap_len < 2) - { - num2 = (s.heap[++s.heap_len] = ((num < 2) ? (++num) : 0)); - array[num2 * 2] = 1; - s.depth[num2] = 0; - s.opt_len--; - if (static_tree != null) - { - s.static_len -= static_tree[num2 * 2 + 1]; - } - } - max_code = num; - for (int i = s.heap_len / 2; i >= 1; i--) - { - s.pqdownheap(array, i); - } - num2 = elems; - do - { - int i = s.heap[1]; - s.heap[1] = s.heap[s.heap_len--]; - s.pqdownheap(array, 1); - int num3 = s.heap[1]; - s.heap[--s.heap_max] = i; - s.heap[--s.heap_max] = num3; - array[num2 * 2] = (short)(array[i * 2] + array[num3 * 2]); - s.depth[num2] = (byte)(Math.Max(s.depth[i], s.depth[num3]) + 1); - array[i * 2 + 1] = (array[num3 * 2 + 1] = (short)num2); - s.heap[1] = num2++; - s.pqdownheap(array, 1); - } - while (s.heap_len >= 2); - s.heap[--s.heap_max] = s.heap[1]; - gen_bitlen(s); - gen_codes(array, num, s.bl_count); - } - - internal static void gen_codes(short[] tree, int max_code, short[] bl_count) - { - short[] array = new short[16]; - short num = 0; - for (int i = 1; i <= 15; i++) - { - num = (array[i] = (short)(num + bl_count[i - 1] << 1)); - } - for (int j = 0; j <= max_code; j++) - { - int num2 = tree[j * 2 + 1]; - if (num2 != 0) - { - tree[j * 2] = (short)bi_reverse(array[num2]++, num2); - } - } - } - - internal static int bi_reverse(int code, int len) - { - int num = 0; - do - { - num |= code & 1; - code = SupportClass.URShift(code, 1); - num <<= 1; - } - while (--len > 0); - return SupportClass.URShift(num, 1); - } - } +using System; + +namespace ComponentAce.Compression.Libs.zlib; + +internal sealed class Tree +{ + private const int MAX_BITS = 15; + + private const int BL_CODES = 19; + + private const int D_CODES = 30; + + private const int LITERALS = 256; + + private const int LENGTH_CODES = 29; + + private static readonly int L_CODES = 286; + + private static readonly int HEAP_SIZE = 2 * L_CODES + 1; + + internal const int MAX_BL_BITS = 7; + + internal const int END_BLOCK = 256; + + internal const int REP_3_6 = 16; + + internal const int REPZ_3_10 = 17; + + internal const int REPZ_11_138 = 18; + + internal static readonly int[] extra_lbits = new int[29] + { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 0 + }; + + internal static readonly int[] extra_dbits = new int[30] + { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 + }; + + internal static readonly int[] extra_blbits = new int[19] + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 3, 7 + }; + + internal static readonly byte[] bl_order = new byte[19] + { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, + 11, 4, 12, 3, 13, 2, 14, 1, 15 + }; + + internal const int Buf_size = 16; + + internal const int DIST_CODE_LEN = 512; + + internal static readonly byte[] _dist_code = new byte[512] + { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, + 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, + 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, + 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29 + }; + + internal static readonly byte[] _length_code = new byte[256] + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, + 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, + 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, + 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 28 + }; + + internal static readonly int[] base_length = new int[29] + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, + 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 160, 192, 224, 0 + }; + + internal static readonly int[] base_dist = new int[30] + { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 + }; + + internal short[] dyn_tree; + + internal int max_code; + + internal StaticTree stat_desc; + + internal static int d_code(int dist) + { + if (dist >= 256) + { + return _dist_code[256 + SupportClass.URShift(dist, 7)]; + } + return _dist_code[dist]; + } + + internal void gen_bitlen(Deflate s) + { + short[] array = dyn_tree; + short[] static_tree = stat_desc.static_tree; + int[] extra_bits = stat_desc.extra_bits; + int extra_base = stat_desc.extra_base; + int max_length = stat_desc.max_length; + int num = 0; + for (int i = 0; i <= 15; i++) + { + s.bl_count[i] = 0; + } + array[s.heap[s.heap_max] * 2 + 1] = 0; + int j; + for (j = s.heap_max + 1; j < HEAP_SIZE; j++) + { + int num2 = s.heap[j]; + int i = array[array[num2 * 2 + 1] * 2 + 1] + 1; + if (i > max_length) + { + i = max_length; + num++; + } + array[num2 * 2 + 1] = (short)i; + if (num2 <= max_code) + { + s.bl_count[i]++; + int num3 = 0; + if (num2 >= extra_base) + { + num3 = extra_bits[num2 - extra_base]; + } + short num4 = array[num2 * 2]; + s.opt_len += num4 * (i + num3); + if (static_tree != null) + { + s.static_len += num4 * (static_tree[num2 * 2 + 1] + num3); + } + } + } + if (num == 0) + { + return; + } + do + { + int i = max_length - 1; + while (s.bl_count[i] == 0) + { + i--; + } + s.bl_count[i]--; + s.bl_count[i + 1] = (short)(s.bl_count[i + 1] + 2); + s.bl_count[max_length]--; + num -= 2; + } + while (num > 0); + for (int i = max_length; i != 0; i--) + { + int num2 = s.bl_count[i]; + while (num2 != 0) + { + int num5 = s.heap[--j]; + if (num5 <= max_code) + { + if (array[num5 * 2 + 1] != i) + { + s.opt_len = (int)(s.opt_len + ((long)i - (long)array[num5 * 2 + 1]) * array[num5 * 2]); + array[num5 * 2 + 1] = (short)i; + } + num2--; + } + } + } + } + + internal void build_tree(Deflate s) + { + short[] array = dyn_tree; + short[] static_tree = stat_desc.static_tree; + int elems = stat_desc.elems; + int num = -1; + s.heap_len = 0; + s.heap_max = HEAP_SIZE; + for (int i = 0; i < elems; i++) + { + if (array[i * 2] != 0) + { + num = (s.heap[++s.heap_len] = i); + s.depth[i] = 0; + } + else + { + array[i * 2 + 1] = 0; + } + } + int num2; + while (s.heap_len < 2) + { + num2 = (s.heap[++s.heap_len] = ((num < 2) ? (++num) : 0)); + array[num2 * 2] = 1; + s.depth[num2] = 0; + s.opt_len--; + if (static_tree != null) + { + s.static_len -= static_tree[num2 * 2 + 1]; + } + } + max_code = num; + for (int i = s.heap_len / 2; i >= 1; i--) + { + s.pqdownheap(array, i); + } + num2 = elems; + do + { + int i = s.heap[1]; + s.heap[1] = s.heap[s.heap_len--]; + s.pqdownheap(array, 1); + int num3 = s.heap[1]; + s.heap[--s.heap_max] = i; + s.heap[--s.heap_max] = num3; + array[num2 * 2] = (short)(array[i * 2] + array[num3 * 2]); + s.depth[num2] = (byte)(Math.Max(s.depth[i], s.depth[num3]) + 1); + array[i * 2 + 1] = (array[num3 * 2 + 1] = (short)num2); + s.heap[1] = num2++; + s.pqdownheap(array, 1); + } + while (s.heap_len >= 2); + s.heap[--s.heap_max] = s.heap[1]; + gen_bitlen(s); + gen_codes(array, num, s.bl_count); + } + + internal static void gen_codes(short[] tree, int max_code, short[] bl_count) + { + short[] array = new short[16]; + short num = 0; + for (int i = 1; i <= 15; i++) + { + num = (array[i] = (short)(num + bl_count[i - 1] << 1)); + } + for (int j = 0; j <= max_code; j++) + { + int num2 = tree[j * 2 + 1]; + if (num2 != 0) + { + tree[j * 2] = (short)bi_reverse(array[num2]++, num2); + } + } + } + + internal static int bi_reverse(int code, int len) + { + int num = 0; + do + { + num |= code & 1; + code = SupportClass.URShift(code, 1); + num <<= 1; + } + while (--len > 0); + return SupportClass.URShift(num, 1); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZInputStream.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZInputStream.cs index 4cc396b..bcd9731 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZInputStream.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZInputStream.cs @@ -1,134 +1,133 @@ -using System.IO; - -namespace ComponentAce.Compression.Libs.zlib -{ - public class ZInputStream : BinaryReader - { - protected ZStream z = new ZStream(); - - protected int bufsize = 512; - - protected int flush; - - protected byte[] buf; - - protected byte[] buf1 = new byte[1]; - - protected bool compress; - - internal Stream in_Renamed = null; - - internal bool nomoreinput = false; - - public virtual int FlushMode - { - get - { - return flush; - } - set - { - flush = value; - } - } - - public virtual long TotalIn => z.total_in; - - public virtual long TotalOut => z.total_out; - - internal void InitBlock() - { - flush = 0; - buf = new byte[bufsize]; - } - - public ZInputStream(Stream in_Renamed) - : base(in_Renamed) - { - InitBlock(); - this.in_Renamed = in_Renamed; - z.inflateInit(); - compress = false; - z.next_in = buf; - z.next_in_index = 0; - z.avail_in = 0; - } - - public ZInputStream(Stream in_Renamed, int level) - : base(in_Renamed) - { - InitBlock(); - this.in_Renamed = in_Renamed; - z.deflateInit(level); - compress = true; - z.next_in = buf; - z.next_in_index = 0; - z.avail_in = 0; - } - - public override int Read() - { - if (read(buf1, 0, 1) == -1) - { - return -1; - } - return buf1[0] & 0xFF; - } - - public int read(byte[] b, int off, int len) - { - if (len == 0) - { - return 0; - } - z.next_out = b; - z.next_out_index = off; - z.avail_out = len; - int num; - do - { - if (z.avail_in == 0 && !nomoreinput) - { - z.next_in_index = 0; - z.avail_in = SupportClass.ReadInput(in_Renamed, buf, 0, bufsize); - if (z.avail_in == -1) - { - z.avail_in = 0; - nomoreinput = true; - } - } - num = ((!compress) ? z.inflate(flush) : z.deflate(flush)); - if (nomoreinput && num == -5) - { - return -1; - } - if (num != 0 && num != 1) - { - throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); - } - if (nomoreinput && z.avail_out == len) - { - return -1; - } - } - while (z.avail_out == len && num == 0); - return len - z.avail_out; - } - - public long skip(long n) - { - int num = 512; - if (n < num) - { - num = (int)n; - } - byte[] array = new byte[num]; - return SupportClass.ReadInput(BaseStream, array, 0, array.Length); - } - - public override void Close() - { - in_Renamed.Close(); - } - } +using System.IO; + +namespace ComponentAce.Compression.Libs.zlib; + +public class ZInputStream : BinaryReader +{ + protected ZStream z = new ZStream(); + + protected int bufsize = 512; + + protected int flush; + + protected byte[] buf; + + protected byte[] buf1 = new byte[1]; + + protected bool compress; + + internal Stream in_Renamed; + + internal bool nomoreinput; + + public virtual int FlushMode + { + get + { + return flush; + } + set + { + flush = value; + } + } + + public virtual long TotalIn => z.total_in; + + public virtual long TotalOut => z.total_out; + + internal void InitBlock() + { + flush = 0; + buf = new byte[bufsize]; + } + + public ZInputStream(Stream in_Renamed) + : base(in_Renamed) + { + InitBlock(); + this.in_Renamed = in_Renamed; + z.inflateInit(); + compress = false; + z.next_in = buf; + z.next_in_index = 0; + z.avail_in = 0; + } + + public ZInputStream(Stream in_Renamed, int level) + : base(in_Renamed) + { + InitBlock(); + this.in_Renamed = in_Renamed; + z.deflateInit(level); + compress = true; + z.next_in = buf; + z.next_in_index = 0; + z.avail_in = 0; + } + + public override int Read() + { + if (read(buf1, 0, 1) == -1) + { + return -1; + } + return buf1[0] & 0xFF; + } + + public int read(byte[] b, int off, int len) + { + if (len == 0) + { + return 0; + } + z.next_out = b; + z.next_out_index = off; + z.avail_out = len; + int num; + do + { + if (z.avail_in == 0 && !nomoreinput) + { + z.next_in_index = 0; + z.avail_in = SupportClass.ReadInput(in_Renamed, buf, 0, bufsize); + if (z.avail_in == -1) + { + z.avail_in = 0; + nomoreinput = true; + } + } + num = ((!compress) ? z.inflate(flush) : z.deflate(flush)); + if (nomoreinput && num == -5) + { + return -1; + } + if (num != 0 && num != 1) + { + throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); + } + if (nomoreinput && z.avail_out == len) + { + return -1; + } + } + while (z.avail_out == len && num == 0); + return len - z.avail_out; + } + + public long skip(long n) + { + int num = 512; + if (n < num) + { + num = (int)n; + } + byte[] array = new byte[num]; + return SupportClass.ReadInput(BaseStream, array, 0, array.Length); + } + + public override void Close() + { + in_Renamed.Close(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZOutputStream.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZOutputStream.cs index c0c0e38..193ca6b 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZOutputStream.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZOutputStream.cs @@ -1,193 +1,192 @@ -using System; -using System.IO; - -namespace ComponentAce.Compression.Libs.zlib -{ - public class ZOutputStream : Stream - { - protected internal ZStream z = new ZStream(); - - protected internal int bufsize = 4096; - - protected internal int flush_Renamed_Field; - - protected internal byte[] buf; - - protected internal byte[] buf1 = new byte[1]; - - protected internal bool compress; - - private Stream out_Renamed; - - public virtual int FlushMode - { - get - { - return flush_Renamed_Field; - } - set - { - flush_Renamed_Field = value; - } - } - - public virtual long TotalIn => z.total_in; - - public virtual long TotalOut => z.total_out; - - public override bool CanRead => false; - - public override bool CanSeek => false; - - public override bool CanWrite => false; - - public override long Length => 0L; - - public override long Position - { - get - { - return 0L; - } - set - { - } - } - - private void InitBlock() - { - flush_Renamed_Field = 0; - buf = new byte[bufsize]; - } - - public ZOutputStream(Stream out_Renamed) - { - InitBlock(); - this.out_Renamed = out_Renamed; - z.inflateInit(); - compress = false; - } - - public ZOutputStream(Stream out_Renamed, int level) - { - InitBlock(); - this.out_Renamed = out_Renamed; - z.deflateInit(level); - compress = true; - } - - public void WriteByte(int b) - { - buf1[0] = (byte)b; - Write(buf1, 0, 1); - } - - public override void WriteByte(byte b) - { - WriteByte(b); - } - - public override void Write(byte[] b1, int off, int len) - { - if (len == 0) - { - return; - } - byte[] array = new byte[b1.Length]; - Array.Copy(b1, 0, array, 0, b1.Length); - z.next_in = array; - z.next_in_index = off; - z.avail_in = len; - do - { - z.next_out = buf; - z.next_out_index = 0; - z.avail_out = bufsize; - int num = ((!compress) ? z.inflate(flush_Renamed_Field) : z.deflate(flush_Renamed_Field)); - if (num != 0 && num != 1) - { - throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); - } - out_Renamed.Write(buf, 0, bufsize - z.avail_out); - } - while (z.avail_in > 0 || z.avail_out == 0); - } - - public virtual void finish() - { - do - { - z.next_out = buf; - z.next_out_index = 0; - z.avail_out = bufsize; - int num = ((!compress) ? z.inflate(4) : z.deflate(4)); - if (num != 1 && num != 0) - { - throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); - } - if (bufsize - z.avail_out > 0) - { - out_Renamed.Write(buf, 0, bufsize - z.avail_out); - } - } - while (z.avail_in > 0 || z.avail_out == 0); - try - { - Flush(); - } - catch - { - } - } - - public virtual void end() - { - if (compress) - { - z.deflateEnd(); - } - else - { - z.inflateEnd(); - } - z.free(); - z = null; - } - - public override void Close() - { - try - { - finish(); - } - catch - { - } - finally - { - end(); - out_Renamed.Close(); - out_Renamed = null; - } - } - - public override void Flush() - { - out_Renamed.Flush(); - } - - public override int Read(byte[] buffer, int offset, int count) - { - return 0; - } - - public override void SetLength(long value) - { - } - - public override long Seek(long offset, SeekOrigin origin) - { - return 0L; - } - } +using System; +using System.IO; + +namespace ComponentAce.Compression.Libs.zlib; + +public class ZOutputStream : Stream +{ + protected internal ZStream z = new ZStream(); + + protected internal int bufsize = 4096; + + protected internal int flush_Renamed_Field; + + protected internal byte[] buf; + + protected internal byte[] buf1 = new byte[1]; + + protected internal bool compress; + + private Stream out_Renamed; + + public virtual int FlushMode + { + get + { + return flush_Renamed_Field; + } + set + { + flush_Renamed_Field = value; + } + } + + public virtual long TotalIn => z.total_in; + + public virtual long TotalOut => z.total_out; + + public override bool CanRead => false; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override long Length => 0L; + + public override long Position + { + get + { + return 0L; + } + set + { + } + } + + private void InitBlock() + { + flush_Renamed_Field = 0; + buf = new byte[bufsize]; + } + + public ZOutputStream(Stream out_Renamed) + { + InitBlock(); + this.out_Renamed = out_Renamed; + z.inflateInit(); + compress = false; + } + + public ZOutputStream(Stream out_Renamed, int level) + { + InitBlock(); + this.out_Renamed = out_Renamed; + z.deflateInit(level); + compress = true; + } + + public void WriteByte(int b) + { + buf1[0] = (byte)b; + Write(buf1, 0, 1); + } + + public override void WriteByte(byte b) + { + WriteByte(b); + } + + public override void Write(byte[] b1, int off, int len) + { + if (len == 0) + { + return; + } + byte[] array = new byte[b1.Length]; + Array.Copy(b1, 0, array, 0, b1.Length); + z.next_in = array; + z.next_in_index = off; + z.avail_in = len; + do + { + z.next_out = buf; + z.next_out_index = 0; + z.avail_out = bufsize; + int num = ((!compress) ? z.inflate(flush_Renamed_Field) : z.deflate(flush_Renamed_Field)); + if (num != 0 && num != 1) + { + throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); + } + out_Renamed.Write(buf, 0, bufsize - z.avail_out); + } + while (z.avail_in > 0 || z.avail_out == 0); + } + + public virtual void finish() + { + do + { + z.next_out = buf; + z.next_out_index = 0; + z.avail_out = bufsize; + int num = ((!compress) ? z.inflate(4) : z.deflate(4)); + if (num != 1 && num != 0) + { + throw new ZStreamException((compress ? "de" : "in") + "flating: " + z.msg); + } + if (bufsize - z.avail_out > 0) + { + out_Renamed.Write(buf, 0, bufsize - z.avail_out); + } + } + while (z.avail_in > 0 || z.avail_out == 0); + try + { + Flush(); + } + catch + { + } + } + + public virtual void end() + { + if (compress) + { + z.deflateEnd(); + } + else + { + z.inflateEnd(); + } + z.free(); + z = null; + } + + public override void Close() + { + try + { + finish(); + } + catch + { + } + finally + { + end(); + out_Renamed.Close(); + out_Renamed = null; + } + } + + public override void Flush() + { + out_Renamed.Flush(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + return 0; + } + + public override void SetLength(long value) + { + } + + public override long Seek(long offset, SeekOrigin origin) + { + return 0L; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZStream.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZStream.cs index eb44bf8..9a7e241 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZStream.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZStream.cs @@ -1,222 +1,223 @@ -using System; - -namespace ComponentAce.Compression.Libs.zlib -{ - public sealed class ZStream - { - private const int MAX_WBITS = 15; - - private static readonly int DEF_WBITS = 15; - - private const int Z_NO_FLUSH = 0; - - private const int Z_PARTIAL_FLUSH = 1; - - private const int Z_SYNC_FLUSH = 2; - - private const int Z_FULL_FLUSH = 3; - - private const int Z_FINISH = 4; - - private const int MAX_MEM_LEVEL = 9; - - private const int Z_OK = 0; - - private const int Z_STREAM_END = 1; - - private const int Z_NEED_DICT = 2; - - private const int Z_ERRNO = -1; - - private const int Z_STREAM_ERROR = -2; - - private const int Z_DATA_ERROR = -3; - - private const int Z_MEM_ERROR = -4; - - private const int Z_BUF_ERROR = -5; - - private const int Z_VERSION_ERROR = -6; - - public byte[] next_in; - - public int next_in_index; - - public int avail_in; - - public long total_in; - - public byte[] next_out; - - public int next_out_index; - - public int avail_out; - - public long total_out; - - public string msg; - - internal Deflate dstate; - - internal Inflate istate; - - internal int data_type; - - public long adler; - - internal Adler32 _adler = new Adler32(); - - public int inflateInit() - { - return inflateInit(DEF_WBITS); - } - - public int inflateInit(int w) - { - istate = new Inflate(); - return istate.inflateInit(this, w); - } - - public int inflate(int f) - { - if (istate == null) - { - return -2; - } - return istate.inflate(this, f); - } - - public int inflateEnd() - { - if (istate == null) - { - return -2; - } - int result = istate.inflateEnd(this); - istate = null; - return result; - } - - public int inflateSync() - { - if (istate == null) - { - return -2; - } - return istate.inflateSync(this); - } - - public int inflateSetDictionary(byte[] dictionary, int dictLength) - { - if (istate == null) - { - return -2; - } - return istate.inflateSetDictionary(this, dictionary, dictLength); - } - - public int deflateInit(int level) - { - return deflateInit(level, 15); - } - - public int deflateInit(int level, int bits) - { - dstate = new Deflate(); - return dstate.deflateInit(this, level, bits); - } - - public int deflate(int flush) - { - if (dstate == null) - { - return -2; - } - return dstate.deflate(this, flush); - } - - public int deflateEnd() - { - if (dstate == null) - { - return -2; - } - int result = dstate.deflateEnd(); - dstate = null; - return result; - } - - public int deflateParams(int level, int strategy) - { - if (dstate == null) - { - return -2; - } - return dstate.deflateParams(this, level, strategy); - } - - public int deflateSetDictionary(byte[] dictionary, int dictLength) - { - if (dstate == null) - { - return -2; - } - return dstate.deflateSetDictionary(this, dictionary, dictLength); - } - - internal void flush_pending() - { - int pending = dstate.pending; - if (pending > avail_out) - { - pending = avail_out; - } - if (pending != 0) - { - if (dstate.pending_buf.Length <= dstate.pending_out || next_out.Length <= next_out_index || dstate.pending_buf.Length < dstate.pending_out + pending || next_out.Length < next_out_index + pending) - { - } - Array.Copy(dstate.pending_buf, dstate.pending_out, next_out, next_out_index, pending); - next_out_index += pending; - dstate.pending_out += pending; - total_out += pending; - avail_out -= pending; - dstate.pending -= pending; - if (dstate.pending == 0) - { - dstate.pending_out = 0; - } - } - } - - internal int read_buf(byte[] buf, int start, int size) - { - int num = avail_in; - if (num > size) - { - num = size; - } - if (num == 0) - { - return 0; - } - avail_in -= num; - if (dstate.noheader == 0) - { - adler = _adler.adler32(adler, next_in, next_in_index, num); - } - Array.Copy(next_in, next_in_index, buf, start, num); - next_in_index += num; - total_in += num; - return num; - } - - public void free() - { - next_in = null; - next_out = null; - msg = null; - _adler = null; - } - } +using System; + +namespace ComponentAce.Compression.Libs.zlib; + +public sealed class ZStream +{ + private const int MAX_WBITS = 15; + + private static readonly int DEF_WBITS = 15; + + private const int Z_NO_FLUSH = 0; + + private const int Z_PARTIAL_FLUSH = 1; + + private const int Z_SYNC_FLUSH = 2; + + private const int Z_FULL_FLUSH = 3; + + private const int Z_FINISH = 4; + + private const int MAX_MEM_LEVEL = 9; + + private const int Z_OK = 0; + + private const int Z_STREAM_END = 1; + + private const int Z_NEED_DICT = 2; + + private const int Z_ERRNO = -1; + + private const int Z_STREAM_ERROR = -2; + + private const int Z_DATA_ERROR = -3; + + private const int Z_MEM_ERROR = -4; + + private const int Z_BUF_ERROR = -5; + + private const int Z_VERSION_ERROR = -6; + + public byte[] next_in; + + public int next_in_index; + + public int avail_in; + + public long total_in; + + public byte[] next_out; + + public int next_out_index; + + public int avail_out; + + public long total_out; + + public string msg; + + internal Deflate dstate; + + internal Inflate istate; + + internal int data_type; + + public long adler; + + internal Adler32 _adler = new Adler32(); + + public int inflateInit() + { + return inflateInit(DEF_WBITS); + } + + public int inflateInit(int w) + { + istate = new Inflate(); + return istate.inflateInit(this, w); + } + + public int inflate(int f) + { + if (istate == null) + { + return -2; + } + return istate.inflate(this, f); + } + + public int inflateEnd() + { + if (istate == null) + { + return -2; + } + int result = istate.inflateEnd(this); + istate = null; + return result; + } + + public int inflateSync() + { + if (istate == null) + { + return -2; + } + return istate.inflateSync(this); + } + + public int inflateSetDictionary(byte[] dictionary, int dictLength) + { + if (istate == null) + { + return -2; + } + return istate.inflateSetDictionary(this, dictionary, dictLength); + } + + public int deflateInit(int level) + { + return deflateInit(level, 15); + } + + public int deflateInit(int level, int bits) + { + dstate = new Deflate(); + return dstate.deflateInit(this, level, bits); + } + + public int deflate(int flush) + { + if (dstate == null) + { + return -2; + } + return dstate.deflate(this, flush); + } + + public int deflateEnd() + { + if (dstate == null) + { + return -2; + } + int result = dstate.deflateEnd(); + dstate = null; + return result; + } + + public int deflateParams(int level, int strategy) + { + if (dstate == null) + { + return -2; + } + return dstate.deflateParams(this, level, strategy); + } + + public int deflateSetDictionary(byte[] dictionary, int dictLength) + { + if (dstate == null) + { + return -2; + } + return dstate.deflateSetDictionary(this, dictionary, dictLength); + } + + internal void flush_pending() + { + int pending = dstate.pending; + if (pending > avail_out) + { + pending = avail_out; + } + if (pending != 0) + { + if (dstate.pending_buf.Length > dstate.pending_out && next_out.Length > next_out_index && dstate.pending_buf.Length >= dstate.pending_out + pending) + { + _ = next_out.Length; + _ = next_out_index + pending; + } + Array.Copy(dstate.pending_buf, dstate.pending_out, next_out, next_out_index, pending); + next_out_index += pending; + dstate.pending_out += pending; + total_out += pending; + avail_out -= pending; + dstate.pending -= pending; + if (dstate.pending == 0) + { + dstate.pending_out = 0; + } + } + } + + internal int read_buf(byte[] buf, int start, int size) + { + int num = avail_in; + if (num > size) + { + num = size; + } + if (num == 0) + { + return 0; + } + avail_in -= num; + if (dstate.noheader == 0) + { + adler = _adler.adler32(adler, next_in, next_in_index, num); + } + Array.Copy(next_in, next_in_index, buf, start, num); + next_in_index += num; + total_in += num; + return num; + } + + public void free() + { + next_in = null; + next_out = null; + msg = null; + _adler = null; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZStreamException.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZStreamException.cs index b1655f0..167764f 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZStreamException.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/ZStreamException.cs @@ -1,16 +1,15 @@ -using System.IO; - -namespace ComponentAce.Compression.Libs.zlib -{ - public class ZStreamException : IOException - { - public ZStreamException() - { - } - - public ZStreamException(string s) - : base(s) - { - } - } +using System.IO; + +namespace ComponentAce.Compression.Libs.zlib; + +public class ZStreamException : IOException +{ + public ZStreamException() + { + } + + public ZStreamException(string s) + : base(s) + { + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/zlibConst.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/zlibConst.cs index b37980b..3fb5e98 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/zlibConst.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ComponentAce.Compression.Libs.zlib/zlibConst.cs @@ -1,54 +1,53 @@ -namespace ComponentAce.Compression.Libs.zlib -{ - public sealed class zlibConst - { - private const string version_Renamed_Field = "1.0.2"; - - public const int Z_NO_COMPRESSION = 0; - - public const int Z_BEST_SPEED = 1; - - public const int Z_BEST_COMPRESSION = 9; - - public const int Z_DEFAULT_COMPRESSION = -1; - - public const int Z_FILTERED = 1; - - public const int Z_HUFFMAN_ONLY = 2; - - public const int Z_DEFAULT_STRATEGY = 0; - - public const int Z_NO_FLUSH = 0; - - public const int Z_PARTIAL_FLUSH = 1; - - public const int Z_SYNC_FLUSH = 2; - - public const int Z_FULL_FLUSH = 3; - - public const int Z_FINISH = 4; - - public const int Z_OK = 0; - - public const int Z_STREAM_END = 1; - - public const int Z_NEED_DICT = 2; - - public const int Z_ERRNO = -1; - - public const int Z_STREAM_ERROR = -2; - - public const int Z_DATA_ERROR = -3; - - public const int Z_MEM_ERROR = -4; - - public const int Z_BUF_ERROR = -5; - - public const int Z_VERSION_ERROR = -6; - - public static string version() - { - return "1.0.2"; - } - } +namespace ComponentAce.Compression.Libs.zlib; + +public sealed class zlibConst +{ + private const string version_Renamed_Field = "1.0.2"; + + public const int Z_NO_COMPRESSION = 0; + + public const int Z_BEST_SPEED = 1; + + public const int Z_BEST_COMPRESSION = 9; + + public const int Z_DEFAULT_COMPRESSION = -1; + + public const int Z_FILTERED = 1; + + public const int Z_HUFFMAN_ONLY = 2; + + public const int Z_DEFAULT_STRATEGY = 0; + + public const int Z_NO_FLUSH = 0; + + public const int Z_PARTIAL_FLUSH = 1; + + public const int Z_SYNC_FLUSH = 2; + + public const int Z_FULL_FLUSH = 3; + + public const int Z_FINISH = 4; + + public const int Z_OK = 0; + + public const int Z_STREAM_END = 1; + + public const int Z_NEED_DICT = 2; + + public const int Z_ERRNO = -1; + + public const int Z_STREAM_ERROR = -2; + + public const int Z_DATA_ERROR = -3; + + public const int Z_MEM_ERROR = -4; + + public const int Z_BUF_ERROR = -5; + + public const int Z_VERSION_ERROR = -6; + + public static string version() + { + return "1.0.2"; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Crc32.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Crc32.cs index 6c99dd9..e92dd74 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Crc32.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Crc32.cs @@ -1,109 +1,108 @@ -using System.Security.Cryptography; - -namespace MyNes.Core -{ - public class Crc32 : HashAlgorithm - { - public const uint DefaultPolynomial = 3988292384u; - - public const uint DefaultSeed = uint.MaxValue; - - private uint hash; - - private uint seed; - - private uint[] table; - - private static uint[] defaultTable; - - public override int HashSize => 32; - - public Crc32() - { - table = InitializeTable(3988292384u); - seed = uint.MaxValue; - Initialize(); - } - - public Crc32(uint polynomial, uint seed) - { - table = InitializeTable(polynomial); - this.seed = seed; - Initialize(); - } - - public override void Initialize() - { - hash = seed; - } - - protected override void HashCore(byte[] buffer, int start, int length) - { - hash = CalculateHash(table, hash, buffer, start, length); - } - - protected override byte[] HashFinal() - { - return HashValue = UInt32ToBigEndianBytes(~hash); - } - - public static uint Compute(byte[] buffer) - { - return ~CalculateHash(InitializeTable(3988292384u), uint.MaxValue, buffer, 0, buffer.Length); - } - - public static uint Compute(uint seed, byte[] buffer) - { - return ~CalculateHash(InitializeTable(3988292384u), seed, buffer, 0, buffer.Length); - } - - public static uint Compute(uint polynomial, uint seed, byte[] buffer) - { - return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); - } - - private static uint[] InitializeTable(uint polynomial) - { - if (polynomial == 3988292384u && defaultTable != null) - { - return defaultTable; - } - uint[] array = new uint[256]; - for (int i = 0; i < 256; i++) - { - uint num = (uint)i; - for (int j = 0; j < 8; j++) - { - num = (((num & 1) != 1) ? (num >> 1) : ((num >> 1) ^ polynomial)); - } - array[i] = num; - } - if (polynomial == 3988292384u) - { - defaultTable = array; - } - return array; - } - - private static uint CalculateHash(uint[] table, uint seed, byte[] buffer, int start, int size) - { - uint num = seed; - for (int i = start; i < size; i++) - { - num = (num >> 8) ^ table[buffer[i] ^ (num & 0xFF)]; - } - return num; - } - - private byte[] UInt32ToBigEndianBytes(uint x) - { - return new byte[4] - { - (byte)((x >> 24) & 0xFFu), - (byte)((x >> 16) & 0xFFu), - (byte)((x >> 8) & 0xFFu), - (byte)(x & 0xFFu) - }; - } - } +using System.Security.Cryptography; + +namespace MyNes.Core; + +public class Crc32 : HashAlgorithm +{ + public const uint DefaultPolynomial = 3988292384u; + + public const uint DefaultSeed = uint.MaxValue; + + private uint hash; + + private uint seed; + + private uint[] table; + + private static uint[] defaultTable; + + public override int HashSize => 32; + + public Crc32() + { + table = InitializeTable(3988292384u); + seed = uint.MaxValue; + Initialize(); + } + + public Crc32(uint polynomial, uint seed) + { + table = InitializeTable(polynomial); + this.seed = seed; + Initialize(); + } + + public override void Initialize() + { + hash = seed; + } + + protected override void HashCore(byte[] buffer, int start, int length) + { + hash = CalculateHash(table, hash, buffer, start, length); + } + + protected override byte[] HashFinal() + { + return HashValue = UInt32ToBigEndianBytes(~hash); + } + + public static uint Compute(byte[] buffer) + { + return ~CalculateHash(InitializeTable(3988292384u), uint.MaxValue, buffer, 0, buffer.Length); + } + + public static uint Compute(uint seed, byte[] buffer) + { + return ~CalculateHash(InitializeTable(3988292384u), seed, buffer, 0, buffer.Length); + } + + public static uint Compute(uint polynomial, uint seed, byte[] buffer) + { + return ~CalculateHash(InitializeTable(polynomial), seed, buffer, 0, buffer.Length); + } + + private static uint[] InitializeTable(uint polynomial) + { + if (polynomial == 3988292384u && defaultTable != null) + { + return defaultTable; + } + uint[] array = new uint[256]; + for (int i = 0; i < 256; i++) + { + uint num = (uint)i; + for (int j = 0; j < 8; j++) + { + num = (((num & 1) != 1) ? (num >> 1) : ((num >> 1) ^ polynomial)); + } + array[i] = num; + } + if (polynomial == 3988292384u) + { + defaultTable = array; + } + return array; + } + + private static uint CalculateHash(uint[] table, uint seed, byte[] buffer, int start, int size) + { + uint num = seed; + for (int i = start; i < size; i++) + { + num = (num >> 8) ^ table[buffer[i] ^ (num & 0xFF)]; + } + return num; + } + + private byte[] UInt32ToBigEndianBytes(uint x) + { + return new byte[4] + { + (byte)((x >> 24) & 0xFFu), + (byte)((x >> 16) & 0xFFu), + (byte)((x >> 8) & 0xFFu), + (byte)(x & 0xFFu) + }; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/EmuRegion.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/EmuRegion.cs index 2d6c875..7708d42 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/EmuRegion.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/EmuRegion.cs @@ -1,9 +1,8 @@ -namespace MyNes.Core -{ - public enum EmuRegion - { - NTSC, - PALB, - DENDY - } +namespace MyNes.Core; + +public enum EmuRegion +{ + NTSC, + PALB, + DENDY } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/EmuSettings.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/EmuSettings.cs index b55e644..bb5e161 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/EmuSettings.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/EmuSettings.cs @@ -1,100 +1,99 @@ -using System.IO; - -namespace MyNes.Core -{ - public class EmuSettings : ISettings - { - public string SnapsFolder = "Snaps"; - - public string WavesFolder = "SoundRecords"; - - public string SnapsFormat = ".png"; - - public bool SnapsReplace = false; - - public int RegionSetting = 0; - - public string StateFolder = "States"; - - public string GameGenieFolder = "GMCodes"; - - public string SRAMFolder = "Srams"; - - public bool SaveSRAMAtEmuShutdown = true; - - public EmuSettings(string path) - : base(path) - { - } - - public override void LoadSettings() - { - base.LoadSettings(); - if (MyNesMain.WorkingFolder == null) - { - MyNesMain.MakeWorkingFolder(); - } - if (SnapsFolder == "Snaps") - { - SnapsFolder = Path.Combine(MyNesMain.WorkingFolder, "Snaps"); - } - if (StateFolder == "States") - { - StateFolder = Path.Combine(MyNesMain.WorkingFolder, "States"); - } - if (GameGenieFolder == "GMCodes") - { - GameGenieFolder = Path.Combine(MyNesMain.WorkingFolder, "GMCodes"); - } - if (SRAMFolder == "Srams") - { - SRAMFolder = Path.Combine(MyNesMain.WorkingFolder, "Srams"); - } - if (WavesFolder == "SoundRecords") - { - WavesFolder = Path.Combine(MyNesMain.WorkingFolder, "SoundRecords"); - } - try - { - Directory.CreateDirectory(WavesFolder); - } - catch - { - Tracer.WriteError("Cannot create sound records folder !!"); - } - try - { - Directory.CreateDirectory(SnapsFolder); - } - catch - { - Tracer.WriteError("Cannot create snaps folder !!"); - } - try - { - Directory.CreateDirectory(StateFolder); - } - catch - { - Tracer.WriteError("Cannot create states folder !!"); - } - try - { - Directory.CreateDirectory(SRAMFolder); - } - catch - { - Tracer.WriteError("Cannot create srams folder !!"); - } - try - { - Directory.CreateDirectory(GameGenieFolder); - } - catch - { - Tracer.WriteError("Cannot create game genie codes folder !!"); - } - StateHandler.StateFolder = StateFolder; - } - } +using System.IO; + +namespace MyNes.Core; + +public class EmuSettings : ISettings +{ + public string SnapsFolder = "Snaps"; + + public string WavesFolder = "SoundRecords"; + + public string SnapsFormat = ".png"; + + public bool SnapsReplace; + + public int RegionSetting; + + public string StateFolder = "States"; + + public string GameGenieFolder = "GMCodes"; + + public string SRAMFolder = "Srams"; + + public bool SaveSRAMAtEmuShutdown = true; + + public EmuSettings(string path) + : base(path) + { + } + + public override void LoadSettings() + { + base.LoadSettings(); + if (MyNesMain.WorkingFolder == null) + { + MyNesMain.MakeWorkingFolder(); + } + if (SnapsFolder == "Snaps") + { + SnapsFolder = Path.Combine(MyNesMain.WorkingFolder, "Snaps"); + } + if (StateFolder == "States") + { + StateFolder = Path.Combine(MyNesMain.WorkingFolder, "States"); + } + if (GameGenieFolder == "GMCodes") + { + GameGenieFolder = Path.Combine(MyNesMain.WorkingFolder, "GMCodes"); + } + if (SRAMFolder == "Srams") + { + SRAMFolder = Path.Combine(MyNesMain.WorkingFolder, "Srams"); + } + if (WavesFolder == "SoundRecords") + { + WavesFolder = Path.Combine(MyNesMain.WorkingFolder, "SoundRecords"); + } + try + { + Directory.CreateDirectory(WavesFolder); + } + catch + { + Tracer.WriteError("Cannot create sound records folder !!"); + } + try + { + Directory.CreateDirectory(SnapsFolder); + } + catch + { + Tracer.WriteError("Cannot create snaps folder !!"); + } + try + { + Directory.CreateDirectory(StateFolder); + } + catch + { + Tracer.WriteError("Cannot create states folder !!"); + } + try + { + Directory.CreateDirectory(SRAMFolder); + } + catch + { + Tracer.WriteError("Cannot create srams folder !!"); + } + try + { + Directory.CreateDirectory(GameGenieFolder); + } + catch + { + Tracer.WriteError("Cannot create game genie codes folder !!"); + } + StateHandler.StateFolder = StateFolder; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Eprom.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Eprom.cs index 41b481a..72e0363 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Eprom.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Eprom.cs @@ -1,383 +1,382 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - internal class Eprom - { - private enum EpromDevice - { - X24C01, - X24C02 - } - - private enum EpromMode - { - Data, - Addressing, - Idle, - Read, - Write, - Ack, - NotAck, - AckWait - } - - private byte[] data; - - private EpromMode mode = EpromMode.Data; - - private EpromMode nextmode = EpromMode.Data; - - private EpromDevice device = EpromDevice.X24C01; - - private bool psda; - - private bool pscl; - - private int output = 0; - - private int cbit = 0; - - private int caddress = 0; - - private int cdata = 0; - - private bool isRead; - - private bool cSCL; - - private bool cSDA; - - public Eprom(int memorySize) - { - Console.WriteLine("Initializing Eprom ..."); - data = new byte[memorySize]; - device = ((memorySize == 256) ? EpromDevice.X24C02 : EpromDevice.X24C01); - Console.WriteLine("Eprom memory size = " + memorySize); - Console.WriteLine("Eprom device = " + device); - } - - public void HardReset() - { - pscl = false; - psda = false; - mode = EpromMode.Idle; - nextmode = EpromMode.Idle; - cbit = 0; - caddress = 0; - cdata = 0; - isRead = false; - output = 16; - } - - public void Write(int address, byte data) - { - cSCL = (data & 0x20) == 32; - cSDA = (data & 0x40) == 64; - if (pscl && (!cSDA & psda)) - { - Start(); - } - else if (pscl && (cSDA & !psda)) - { - Stop(); - } - else if (cSCL & !pscl) - { - switch (device) - { - case EpromDevice.X24C01: - RiseX24C01((data >> 6) & 1); - break; - case EpromDevice.X24C02: - RiseX24C02((data >> 6) & 1); - break; - } - } - else if (!cSCL & pscl) - { - switch (device) - { - case EpromDevice.X24C01: - FallX24C01(); - break; - case EpromDevice.X24C02: - FallX24C02(); - break; - } - } - pscl = cSCL; - psda = cSDA; - } - - public byte Read(int address) - { - return (byte)output; - } - - private void Start() - { - switch (device) - { - case EpromDevice.X24C01: - mode = EpromMode.Addressing; - cbit = 0; - caddress = 0; - output = 16; - break; - case EpromDevice.X24C02: - mode = EpromMode.Data; - cbit = 0; - output = 16; - break; - } - } - - private void Stop() - { - mode = EpromMode.Idle; - output = 16; - } - - private void RiseX24C01(int bit) - { - switch (mode) - { - case EpromMode.Addressing: - if (cbit < 7) - { - caddress &= ~(1 << cbit); - caddress |= bit << cbit++; - } - else if (cbit < 8) - { - cbit = 8; - if (bit != 0) - { - nextmode = EpromMode.Read; - cdata = data[caddress]; - } - else - { - nextmode = EpromMode.Write; - } - } - break; - case EpromMode.Ack: - output = 0; - break; - case EpromMode.Read: - if (cbit < 8) - { - output = (((cdata & (1 << cbit++)) != 0) ? 16 : 0); - } - break; - case EpromMode.Write: - if (cbit < 8) - { - cdata &= ~(1 << cbit); - cdata |= bit << cbit++; - } - break; - case EpromMode.AckWait: - if (bit == 0) - { - nextmode = EpromMode.Idle; - } - break; - case EpromMode.Idle: - case EpromMode.NotAck: - break; - } - } - - private void RiseX24C02(int bit) - { - switch (mode) - { - case EpromMode.Data: - if (cbit < 8) - { - cdata &= ~(1 << 7 - cbit); - cdata |= bit << 7 - cbit++; - } - break; - case EpromMode.Addressing: - if (cbit < 8) - { - caddress &= ~(1 << 7 - cbit); - caddress |= bit << 7 - cbit++; - } - break; - case EpromMode.Read: - if (cbit < 8) - { - output = (((cdata & (1 << 7 - cbit++)) != 0) ? 16 : 0); - } - break; - case EpromMode.Write: - if (cbit < 8) - { - cdata &= ~(1 << 7 - cbit); - cdata |= bit << 7 - cbit++; - } - break; - case EpromMode.NotAck: - output = 16; - break; - case EpromMode.Ack: - output = 0; - break; - case EpromMode.AckWait: - if (bit == 0) - { - nextmode = EpromMode.Read; - cdata = data[caddress]; - } - break; - case EpromMode.Idle: - break; - } - } - - private void FallX24C01() - { - switch (mode) - { - case EpromMode.Addressing: - if (cbit == 8) - { - mode = EpromMode.Ack; - output = 16; - } - break; - case EpromMode.Ack: - mode = nextmode; - cbit = 0; - output = 16; - break; - case EpromMode.Read: - if (cbit == 8) - { - mode = EpromMode.AckWait; - caddress = (caddress + 1) & 0x7F; - } - break; - case EpromMode.Write: - if (cbit == 8) - { - mode = EpromMode.Ack; - nextmode = EpromMode.Idle; - data[caddress] = (byte)cdata; - caddress = (caddress + 1) & 0x7F; - } - break; - case EpromMode.Idle: - break; - } - } - - private void FallX24C02() - { - switch (mode) - { - case EpromMode.Data: - if (cbit != 8) - { - break; - } - if ((cdata & 0xA0) == 160) - { - cbit = 0; - mode = EpromMode.Ack; - isRead = (cdata & 1) == 1; - output = 16; - if (isRead) - { - nextmode = EpromMode.Read; - cdata = data[caddress]; - } - else - { - nextmode = EpromMode.Addressing; - } - } - else - { - mode = EpromMode.NotAck; - nextmode = EpromMode.Idle; - output = 16; - } - break; - case EpromMode.Addressing: - if (cbit == 8) - { - cbit = 0; - mode = EpromMode.Ack; - nextmode = (isRead ? EpromMode.Idle : EpromMode.Write); - output = 16; - } - break; - case EpromMode.Read: - if (cbit == 8) - { - mode = EpromMode.AckWait; - caddress = (caddress + 1) & 0xFF; - } - break; - case EpromMode.Write: - if (cbit == 8) - { - cbit = 0; - mode = EpromMode.Ack; - nextmode = EpromMode.Write; - data[caddress] = (byte)cdata; - caddress = (caddress + 1) & 0xFF; - } - break; - case EpromMode.NotAck: - mode = EpromMode.Idle; - cbit = 0; - output = 16; - break; - case EpromMode.Ack: - case EpromMode.AckWait: - mode = nextmode; - cbit = 0; - output = 16; - break; - case EpromMode.Idle: - break; - } - } - - public void SaveState(BinaryWriter stream) - { - stream.Write(data); - stream.Write((int)mode); - stream.Write((int)nextmode); - stream.Write(psda); - stream.Write(pscl); - stream.Write(output); - stream.Write(cbit); - stream.Write(caddress); - stream.Write(cdata); - stream.Write(isRead); - } - - public void LoadState(BinaryReader stream) - { - stream.Read(data, 0, data.Length); - mode = (EpromMode)stream.ReadInt32(); - nextmode = (EpromMode)stream.ReadInt32(); - psda = stream.ReadBoolean(); - pscl = stream.ReadBoolean(); - output = stream.ReadInt32(); - cbit = stream.ReadInt32(); - caddress = stream.ReadInt32(); - cdata = stream.ReadInt32(); - isRead = stream.ReadBoolean(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +internal class Eprom +{ + private enum EpromDevice + { + X24C01, + X24C02 + } + + private enum EpromMode + { + Data, + Addressing, + Idle, + Read, + Write, + Ack, + NotAck, + AckWait + } + + private byte[] data; + + private EpromMode mode; + + private EpromMode nextmode; + + private EpromDevice device; + + private bool psda; + + private bool pscl; + + private int output; + + private int cbit; + + private int caddress; + + private int cdata; + + private bool isRead; + + private bool cSCL; + + private bool cSDA; + + public Eprom(int memorySize) + { + Console.WriteLine("Initializing Eprom ..."); + data = new byte[memorySize]; + device = ((memorySize == 256) ? EpromDevice.X24C02 : EpromDevice.X24C01); + Console.WriteLine("Eprom memory size = " + memorySize); + Console.WriteLine("Eprom device = " + device); + } + + public void HardReset() + { + pscl = false; + psda = false; + mode = EpromMode.Idle; + nextmode = EpromMode.Idle; + cbit = 0; + caddress = 0; + cdata = 0; + isRead = false; + output = 16; + } + + public void Write(int address, byte data) + { + cSCL = (data & 0x20) == 32; + cSDA = (data & 0x40) == 64; + if (pscl && (!cSDA & psda)) + { + Start(); + } + else if (pscl && (cSDA & !psda)) + { + Stop(); + } + else if (cSCL & !pscl) + { + switch (device) + { + case EpromDevice.X24C01: + RiseX24C01((data >> 6) & 1); + break; + case EpromDevice.X24C02: + RiseX24C02((data >> 6) & 1); + break; + } + } + else if (!cSCL & pscl) + { + switch (device) + { + case EpromDevice.X24C01: + FallX24C01(); + break; + case EpromDevice.X24C02: + FallX24C02(); + break; + } + } + pscl = cSCL; + psda = cSDA; + } + + public byte Read(int address) + { + return (byte)output; + } + + private void Start() + { + switch (device) + { + case EpromDevice.X24C01: + mode = EpromMode.Addressing; + cbit = 0; + caddress = 0; + output = 16; + break; + case EpromDevice.X24C02: + mode = EpromMode.Data; + cbit = 0; + output = 16; + break; + } + } + + private void Stop() + { + mode = EpromMode.Idle; + output = 16; + } + + private void RiseX24C01(int bit) + { + switch (mode) + { + case EpromMode.Addressing: + if (cbit < 7) + { + caddress &= ~(1 << cbit); + caddress |= bit << cbit++; + } + else if (cbit < 8) + { + cbit = 8; + if (bit != 0) + { + nextmode = EpromMode.Read; + cdata = data[caddress]; + } + else + { + nextmode = EpromMode.Write; + } + } + break; + case EpromMode.Ack: + output = 0; + break; + case EpromMode.Read: + if (cbit < 8) + { + output = (((cdata & (1 << cbit++)) != 0) ? 16 : 0); + } + break; + case EpromMode.Write: + if (cbit < 8) + { + cdata &= ~(1 << cbit); + cdata |= bit << cbit++; + } + break; + case EpromMode.AckWait: + if (bit == 0) + { + nextmode = EpromMode.Idle; + } + break; + case EpromMode.Idle: + case EpromMode.NotAck: + break; + } + } + + private void RiseX24C02(int bit) + { + switch (mode) + { + case EpromMode.Data: + if (cbit < 8) + { + cdata &= ~(1 << 7 - cbit); + cdata |= bit << 7 - cbit++; + } + break; + case EpromMode.Addressing: + if (cbit < 8) + { + caddress &= ~(1 << 7 - cbit); + caddress |= bit << 7 - cbit++; + } + break; + case EpromMode.Read: + if (cbit < 8) + { + output = (((cdata & (1 << 7 - cbit++)) != 0) ? 16 : 0); + } + break; + case EpromMode.Write: + if (cbit < 8) + { + cdata &= ~(1 << 7 - cbit); + cdata |= bit << 7 - cbit++; + } + break; + case EpromMode.NotAck: + output = 16; + break; + case EpromMode.Ack: + output = 0; + break; + case EpromMode.AckWait: + if (bit == 0) + { + nextmode = EpromMode.Read; + cdata = data[caddress]; + } + break; + case EpromMode.Idle: + break; + } + } + + private void FallX24C01() + { + switch (mode) + { + case EpromMode.Addressing: + if (cbit == 8) + { + mode = EpromMode.Ack; + output = 16; + } + break; + case EpromMode.Ack: + mode = nextmode; + cbit = 0; + output = 16; + break; + case EpromMode.Read: + if (cbit == 8) + { + mode = EpromMode.AckWait; + caddress = (caddress + 1) & 0x7F; + } + break; + case EpromMode.Write: + if (cbit == 8) + { + mode = EpromMode.Ack; + nextmode = EpromMode.Idle; + data[caddress] = (byte)cdata; + caddress = (caddress + 1) & 0x7F; + } + break; + case EpromMode.Idle: + break; + } + } + + private void FallX24C02() + { + switch (mode) + { + case EpromMode.Data: + if (cbit != 8) + { + break; + } + if ((cdata & 0xA0) == 160) + { + cbit = 0; + mode = EpromMode.Ack; + isRead = (cdata & 1) == 1; + output = 16; + if (isRead) + { + nextmode = EpromMode.Read; + cdata = data[caddress]; + } + else + { + nextmode = EpromMode.Addressing; + } + } + else + { + mode = EpromMode.NotAck; + nextmode = EpromMode.Idle; + output = 16; + } + break; + case EpromMode.Addressing: + if (cbit == 8) + { + cbit = 0; + mode = EpromMode.Ack; + nextmode = (isRead ? EpromMode.Idle : EpromMode.Write); + output = 16; + } + break; + case EpromMode.Read: + if (cbit == 8) + { + mode = EpromMode.AckWait; + caddress = (caddress + 1) & 0xFF; + } + break; + case EpromMode.Write: + if (cbit == 8) + { + cbit = 0; + mode = EpromMode.Ack; + nextmode = EpromMode.Write; + data[caddress] = (byte)cdata; + caddress = (caddress + 1) & 0xFF; + } + break; + case EpromMode.NotAck: + mode = EpromMode.Idle; + cbit = 0; + output = 16; + break; + case EpromMode.Ack: + case EpromMode.AckWait: + mode = nextmode; + cbit = 0; + output = 16; + break; + case EpromMode.Idle: + break; + } + } + + public void SaveState(BinaryWriter stream) + { + stream.Write(data); + stream.Write((int)mode); + stream.Write((int)nextmode); + stream.Write(psda); + stream.Write(pscl); + stream.Write(output); + stream.Write(cbit); + stream.Write(caddress); + stream.Write(cdata); + stream.Write(isRead); + } + + public void LoadState(BinaryReader stream) + { + stream.Read(data, 0, data.Length); + mode = (EpromMode)stream.ReadInt32(); + nextmode = (EpromMode)stream.ReadInt32(); + psda = stream.ReadBoolean(); + pscl = stream.ReadBoolean(); + output = stream.ReadInt32(); + cbit = stream.ReadInt32(); + caddress = stream.ReadInt32(); + cdata = stream.ReadInt32(); + isRead = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/FFE.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/FFE.cs index 9232f55..a158fe2 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/FFE.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/FFE.cs @@ -1,56 +1,55 @@ -using System.IO; - -namespace MyNes.Core -{ - internal abstract class FFE : Board - { - protected bool irqEnable; - - protected int irqCounter; - - internal override void WriteEX(ref ushort address, ref byte data) - { - switch (address) - { - case 17665: - irqEnable = false; - NesEmu.IRQFlags &= -9; - break; - case 17666: - irqCounter = (irqCounter & 0xFF00) | data; - break; - case 17667: - irqEnable = true; - irqCounter = (irqCounter & 0xFF) | (data << 8); - break; - } - } - - internal override void OnCPUClock() - { - if (irqEnable) - { - irqCounter++; - if (irqCounter >= 65535) - { - irqCounter = 0; - NesEmu.IRQFlags |= 8; - } - } - } - - internal override void WriteStateData(ref BinaryWriter bin) - { - base.WriteStateData(ref bin); - bin.Write(irqEnable); - bin.Write(irqCounter); - } - - internal override void ReadStateData(ref BinaryReader bin) - { - base.ReadStateData(ref bin); - irqEnable = bin.ReadBoolean(); - irqCounter = bin.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +internal abstract class FFE : Board +{ + protected bool irqEnable; + + protected int irqCounter; + + internal override void WriteEX(ref ushort address, ref byte data) + { + switch (address) + { + case 17665: + irqEnable = false; + NesEmu.IRQFlags &= -9; + break; + case 17666: + irqCounter = (irqCounter & 0xFF00) | data; + break; + case 17667: + irqEnable = true; + irqCounter = (irqCounter & 0xFF) | (data << 8); + break; + } + } + + internal override void OnCPUClock() + { + if (irqEnable) + { + irqCounter++; + if (irqCounter >= 65535) + { + irqCounter = 0; + NesEmu.IRQFlags |= 8; + } + } + } + + internal override void WriteStateData(ref BinaryWriter bin) + { + base.WriteStateData(ref bin); + bin.Write(irqEnable); + bin.Write(irqCounter); + } + + internal override void ReadStateData(ref BinaryReader bin) + { + base.ReadStateData(ref bin); + irqEnable = bin.ReadBoolean(); + irqCounter = bin.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/GameGenie.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/GameGenie.cs index 3c893a0..ef9d880 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/GameGenie.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/GameGenie.cs @@ -1,153 +1,151 @@ -using System.Collections.Generic; - -namespace MyNes.Core -{ - public class GameGenie - { - public string[] LettersTable = new string[16] - { - "A", "P", "Z", "L", "G", "I", "T", "Y", "E", "O", - "X", "U", "K", "S", "V", "N" - }; - - public byte[] HEXTable = new byte[16] - { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15 - }; - - private List lettersTable = new List(); - - public GameGenie() - { - lettersTable = new List(LettersTable); - } - - public int GetCodeAsHEX(string code) - { - int num = 0; - int num2 = code.ToCharArray().Length - 1; - char[] array = code.ToCharArray(); - foreach (char c in array) - { - num |= HEXTable[lettersTable.IndexOf(c.ToString())] << num2 * 4; - num2--; - } - return num; - } - - public byte GetGGValue(int code, int length) - { - int num = 0; - int num2 = 0; - int num3 = 0; - int num4 = 0; - int num5 = 0; - int num6 = 0; - int num7 = 0; - int num8 = 0; - switch (length) - { - case 6: - num8 = (code & 0x800000) >> 23; - num7 = (code & 0x40000) >> 18; - num6 = (code & 0x20000) >> 17; - num5 = (code & 0x10000) >> 16; - num4 = (code & 8) >> 3; - num3 = (code & 0x400000) >> 22; - num2 = (code & 0x200000) >> 21; - num = (code & 0x100000) >> 20; - break; - case 8: - num8 = (code >> 31) & 1; - num7 = (code >> 27) & 1; - num6 = (code >> 26) & 1; - num5 = (code >> 25) & 1; - num4 = (code >> 3) & 1; - num3 = (code >> 30) & 1; - num2 = (code >> 29) & 1; - num = (code >> 28) & 1; - break; - } - return (byte)((num8 << 7) | (num7 << 6) | (num6 << 5) | (num5 << 4) | (num4 << 3) | (num3 << 2) | (num2 << 1) | num); - } - - public int GetGGAddress(int code, int length) - { - int num = 0; - int num2 = 0; - int num3 = 0; - int num4 = 0; - int num5 = 0; - int num6 = 0; - int num7 = 0; - int num8 = 0; - int num9 = 0; - int num10 = 0; - int num11 = 0; - int num12 = 0; - int num13 = 0; - int num14 = 0; - int num15 = 0; - switch (length) - { - case 6: - num15 = (code >> 10) & 1; - num14 = (code >> 9) & 1; - num13 = (code >> 8) & 1; - num12 = (code >> 7) & 1; - num11 = (code >> 2) & 1; - num10 = (code >> 1) & 1; - num9 = code & 1; - num8 = (code >> 19) & 1; - num7 = (code >> 14) & 1; - num6 = (code >> 13) & 1; - num5 = (code >> 12) & 1; - num4 = (code >> 11) & 1; - num3 = (code >> 6) & 1; - num2 = (code >> 5) & 1; - num = (code >> 4) & 1; - break; - case 8: - num15 = (code >> 18) & 1; - num14 = (code >> 17) & 1; - num13 = (code >> 16) & 1; - num12 = (code >> 15) & 1; - num11 = (code >> 10) & 1; - num10 = (code >> 9) & 1; - num9 = (code >> 8) & 1; - num8 = (code >> 25) & 1; - num7 = (code >> 22) & 1; - num6 = (code >> 21) & 1; - num5 = (code >> 20) & 1; - num4 = (code >> 19) & 1; - num3 = (code >> 14) & 1; - num2 = (code >> 13) & 1; - num = (code >> 12) & 1; - break; - } - return (num15 << 14) | (num14 << 13) | (num13 << 12) | (num12 << 11) | (num11 << 10) | (num10 << 9) | (num9 << 8) | (num8 << 7) | (num7 << 6) | (num6 << 5) | (num5 << 4) | (num4 << 3) | (num3 << 2) | (num2 << 1) | num; - } - - public byte GetGGCompareValue(int code) - { - int num = 0; - int num2 = 0; - int num3 = 0; - int num4 = 0; - int num5 = 0; - int num6 = 0; - int num7 = 0; - int num8 = 0; - num8 = (code >> 7) & 1; - num7 = (code >> 2) & 1; - num6 = (code >> 1) & 1; - num5 = code & 1; - num4 = (code >> 11) & 1; - num3 = (code >> 6) & 1; - num2 = (code >> 5) & 1; - num = (code >> 4) & 1; - return (byte)((num8 << 7) | (num7 << 6) | (num6 << 5) | (num5 << 4) | (num4 << 3) | (num3 << 2) | (num2 << 1) | num); - } - } +using System.Collections.Generic; + +namespace MyNes.Core; + +public class GameGenie +{ + public string[] LettersTable = new string[16] + { + "A", "P", "Z", "L", "G", "I", "T", "Y", "E", "O", + "X", "U", "K", "S", "V", "N" + }; + + public byte[] HEXTable = new byte[16] + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15 + }; + + private List lettersTable = new List(); + + public GameGenie() + { + lettersTable = new List(LettersTable); + } + + public int GetCodeAsHEX(string code) + { + int num = 0; + int num2 = code.ToCharArray().Length - 1; + char[] array = code.ToCharArray(); + foreach (char c in array) + { + num |= HEXTable[lettersTable.IndexOf(c.ToString())] << num2 * 4; + num2--; + } + return num; + } + + public byte GetGGValue(int code, int length) + { + int num = 0; + int num2 = 0; + int num3 = 0; + int num4 = 0; + int num5 = 0; + int num6 = 0; + int num7 = 0; + int num8 = 0; + switch (length) + { + case 6: + num8 = (code & 0x800000) >> 23; + num7 = (code & 0x40000) >> 18; + num6 = (code & 0x20000) >> 17; + num5 = (code & 0x10000) >> 16; + num4 = (code & 8) >> 3; + num3 = (code & 0x400000) >> 22; + num2 = (code & 0x200000) >> 21; + num = (code & 0x100000) >> 20; + break; + case 8: + num8 = (code >> 31) & 1; + num7 = (code >> 27) & 1; + num6 = (code >> 26) & 1; + num5 = (code >> 25) & 1; + num4 = (code >> 3) & 1; + num3 = (code >> 30) & 1; + num2 = (code >> 29) & 1; + num = (code >> 28) & 1; + break; + } + return (byte)((num8 << 7) | (num7 << 6) | (num6 << 5) | (num5 << 4) | (num4 << 3) | (num3 << 2) | (num2 << 1) | num); + } + + public int GetGGAddress(int code, int length) + { + int num = 0; + int num2 = 0; + int num3 = 0; + int num4 = 0; + int num5 = 0; + int num6 = 0; + int num7 = 0; + int num8 = 0; + int num9 = 0; + int num10 = 0; + int num11 = 0; + int num12 = 0; + int num13 = 0; + int num14 = 0; + int num15 = 0; + switch (length) + { + case 6: + num15 = (code >> 10) & 1; + num14 = (code >> 9) & 1; + num13 = (code >> 8) & 1; + num12 = (code >> 7) & 1; + num11 = (code >> 2) & 1; + num10 = (code >> 1) & 1; + num9 = code & 1; + num8 = (code >> 19) & 1; + num7 = (code >> 14) & 1; + num6 = (code >> 13) & 1; + num5 = (code >> 12) & 1; + num4 = (code >> 11) & 1; + num3 = (code >> 6) & 1; + num2 = (code >> 5) & 1; + num = (code >> 4) & 1; + break; + case 8: + num15 = (code >> 18) & 1; + num14 = (code >> 17) & 1; + num13 = (code >> 16) & 1; + num12 = (code >> 15) & 1; + num11 = (code >> 10) & 1; + num10 = (code >> 9) & 1; + num9 = (code >> 8) & 1; + num8 = (code >> 25) & 1; + num7 = (code >> 22) & 1; + num6 = (code >> 21) & 1; + num5 = (code >> 20) & 1; + num4 = (code >> 19) & 1; + num3 = (code >> 14) & 1; + num2 = (code >> 13) & 1; + num = (code >> 12) & 1; + break; + } + return (num15 << 14) | (num14 << 13) | (num13 << 12) | (num12 << 11) | (num11 << 10) | (num10 << 9) | (num9 << 8) | (num8 << 7) | (num7 << 6) | (num6 << 5) | (num5 << 4) | (num4 << 3) | (num3 << 2) | (num2 << 1) | num; + } + + public byte GetGGCompareValue(int code) + { + int num = 0; + int num2 = 0; + int num3 = 0; + int num4 = 0; + int num5 = 0; + int num6 = 0; + int num7 = 0; + int num8 = (code >> 7) & 1; + num7 = (code >> 2) & 1; + num6 = (code >> 1) & 1; + num5 = code & 1; + num4 = (code >> 11) & 1; + num3 = (code >> 6) & 1; + num2 = (code >> 5) & 1; + num = (code >> 4) & 1; + return (byte)((num8 << 7) | (num7 << 6) | (num6 << 5) | (num5 << 4) | (num4 << 3) | (num3 << 2) | (num2 << 1) | num); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/GameGenieCode.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/GameGenieCode.cs index a46c121..62a8535 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/GameGenieCode.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/GameGenieCode.cs @@ -1,19 +1,18 @@ -namespace MyNes.Core -{ - public struct GameGenieCode - { - public string Name; - - public string Descreption; - - public int Address; - - public byte Compare; - - public byte Value; - - public bool IsCompare; - - public bool Enabled; - } +namespace MyNes.Core; + +public struct GameGenieCode +{ + public string Name; + + public string Descreption; + + public int Address; + + public byte Compare; + + public byte Value; + + public bool IsCompare; + + public bool Enabled; } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/GetIsPlaying.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/GetIsPlaying.cs index 6bedd57..b74b2ae 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/GetIsPlaying.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/GetIsPlaying.cs @@ -1,4 +1,3 @@ -namespace MyNes.Core -{ - internal delegate void GetIsPlaying(out bool playing); -} +namespace MyNes.Core; + +internal delegate void GetIsPlaying(out bool playing); diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/HassIssuesAttribute.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/HassIssuesAttribute.cs index d5e29a6..a8bbe3c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/HassIssuesAttribute.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/HassIssuesAttribute.cs @@ -1,8 +1,7 @@ -using System; - -namespace MyNes.Core -{ - internal class HassIssuesAttribute : Attribute - { - } +using System; + +namespace MyNes.Core; + +internal class HassIssuesAttribute : Attribute +{ } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/HelperTools.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/HelperTools.cs index 78d7aaf..2bbac75 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/HelperTools.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/HelperTools.cs @@ -1,181 +1,173 @@ -using System.IO; -using System.Security.Cryptography; - -namespace MyNes.Core -{ - public class HelperTools - { - public static string GetFileSize(string FilePath) - { - if (File.Exists(Path.GetFullPath(FilePath))) - { - FileInfo fileInfo = new FileInfo(FilePath); - string text = " Byte"; - double num = fileInfo.Length; - if (fileInfo.Length >= 1024) - { - num = (double)fileInfo.Length / 1024.0; - text = " KB"; - } - if (num >= 1024.0) - { - num /= 1024.0; - text = " MB"; - } - if (num >= 1024.0) - { - num /= 1024.0; - text = " GB"; - } - return num.ToString("F2") + text; - } - return ""; - } - - public static string GetSize(long size) - { - string text = " Byte"; - double num = size; - if (size >= 1024) - { - num = (double)size / 1024.0; - text = " KB"; - } - if (num >= 1024.0) - { - num /= 1024.0; - text = " MB"; - } - if (num >= 1024.0) - { - num /= 1024.0; - text = " GB"; - } - if (num < 0.0) - { - return "???"; - } - return num.ToString("F2") + text; - } - - public static string GetSize(ulong size) - { - string text = " Byte"; - double num = size; - if (size >= 1024) - { - num = (double)size / 1024.0; - text = " KB"; - } - if (num >= 1024.0) - { - num /= 1024.0; - text = " MB"; - } - if (num >= 1024.0) - { - num /= 1024.0; - text = " GB"; - } - if (num < 0.0) - { - return "???"; - } - return num.ToString("F2") + text; - } - - public static long GetSizeAsBytes(string FilePath) - { - if (File.Exists(FilePath)) - { - FileInfo fileInfo = new FileInfo(FilePath); - return fileInfo.Length; - } - return 0L; - } - - public static bool IsStringContainsNumbers(string text) - { - char[] array = text.ToCharArray(); - foreach (char c in array) - { - int result = 0; - if (int.TryParse(c.ToString(), out result)) - { - return true; - } - } - return false; - } - - public static string CalculateCRC(string filePath) - { - if (File.Exists(filePath)) - { - Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); - byte[] buffer = new byte[stream.Length]; - stream.Read(buffer, 0, (int)stream.Length); - stream.Close(); - string text = ""; - Crc32 crc = new Crc32(); - byte[] array = crc.ComputeHash(buffer); - byte[] array2 = array; - foreach (byte b in array2) - { - text += b.ToString("x2").ToLower(); - } - return text; - } - return ""; - } - - public static string CalculateCRC(string filePath, int bytesToSkip) - { - if (File.Exists(filePath)) - { - Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); - stream.Read(new byte[bytesToSkip], 0, bytesToSkip); - byte[] buffer = new byte[stream.Length - bytesToSkip]; - stream.Read(buffer, 0, (int)(stream.Length - bytesToSkip)); - stream.Close(); - string text = ""; - Crc32 crc = new Crc32(); - byte[] array = crc.ComputeHash(buffer); - byte[] array2 = array; - foreach (byte b in array2) - { - text += b.ToString("x2").ToLower(); - } - return text; - } - return ""; - } - - public static string CalculateSHA1(string filePath) - { - if (File.Exists(filePath)) - { - byte[] buffer = GetBuffer(filePath); - string text = ""; - SHA1Managed sHA1Managed = new SHA1Managed(); - byte[] array = sHA1Managed.ComputeHash(buffer); - byte[] array2 = array; - foreach (byte b in array2) - { - text += b.ToString("x2").ToLower(); - } - return text; - } - return ""; - } - - public static byte[] GetBuffer(string filePath) - { - Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); - byte[] array = new byte[stream.Length]; - stream.Read(array, 0, (int)stream.Length); - stream.Close(); - return array; - } - } +using System.IO; +using System.Security.Cryptography; + +namespace MyNes.Core; + +public class HelperTools +{ + public static string GetFileSize(string FilePath) + { + if (File.Exists(Path.GetFullPath(FilePath))) + { + FileInfo fileInfo = new FileInfo(FilePath); + string text = " Byte"; + double num = fileInfo.Length; + if (fileInfo.Length >= 1024) + { + num = (double)fileInfo.Length / 1024.0; + text = " KB"; + } + if (num >= 1024.0) + { + num /= 1024.0; + text = " MB"; + } + if (num >= 1024.0) + { + num /= 1024.0; + text = " GB"; + } + return num.ToString("F2") + text; + } + return ""; + } + + public static string GetSize(long size) + { + string text = " Byte"; + double num = size; + if (size >= 1024) + { + num = (double)size / 1024.0; + text = " KB"; + } + if (num >= 1024.0) + { + num /= 1024.0; + text = " MB"; + } + if (num >= 1024.0) + { + num /= 1024.0; + text = " GB"; + } + if (num < 0.0) + { + return "???"; + } + return num.ToString("F2") + text; + } + + public static string GetSize(ulong size) + { + string text = " Byte"; + double num = size; + if (size >= 1024) + { + num = (double)size / 1024.0; + text = " KB"; + } + if (num >= 1024.0) + { + num /= 1024.0; + text = " MB"; + } + if (num >= 1024.0) + { + num /= 1024.0; + text = " GB"; + } + if (num < 0.0) + { + return "???"; + } + return num.ToString("F2") + text; + } + + public static long GetSizeAsBytes(string FilePath) + { + if (File.Exists(FilePath)) + { + return new FileInfo(FilePath).Length; + } + return 0L; + } + + public static bool IsStringContainsNumbers(string text) + { + char[] array = text.ToCharArray(); + foreach (char c in array) + { + int result = 0; + if (int.TryParse(c.ToString(), out result)) + { + return true; + } + } + return false; + } + + public static string CalculateCRC(string filePath) + { + if (File.Exists(filePath)) + { + Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); + byte[] buffer = new byte[stream.Length]; + stream.Read(buffer, 0, (int)stream.Length); + stream.Close(); + string text = ""; + byte[] array = new Crc32().ComputeHash(buffer); + foreach (byte b in array) + { + text += b.ToString("x2").ToLower(); + } + return text; + } + return ""; + } + + public static string CalculateCRC(string filePath, int bytesToSkip) + { + if (File.Exists(filePath)) + { + Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); + stream.Read(new byte[bytesToSkip], 0, bytesToSkip); + byte[] buffer = new byte[stream.Length - bytesToSkip]; + stream.Read(buffer, 0, (int)(stream.Length - bytesToSkip)); + stream.Close(); + string text = ""; + byte[] array = new Crc32().ComputeHash(buffer); + foreach (byte b in array) + { + text += b.ToString("x2").ToLower(); + } + return text; + } + return ""; + } + + public static string CalculateSHA1(string filePath) + { + if (File.Exists(filePath)) + { + byte[] buffer = GetBuffer(filePath); + string text = ""; + byte[] array = new SHA1Managed().ComputeHash(buffer); + foreach (byte b in array) + { + text += b.ToString("x2").ToLower(); + } + return text; + } + return ""; + } + + public static byte[] GetBuffer(string filePath) + { + Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); + byte[] array = new byte[stream.Length]; + stream.Read(array, 0, (int)stream.Length); + stream.Close(); + return array; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/IAudioProvider.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/IAudioProvider.cs index 057b1a2..a6f1b20 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/IAudioProvider.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/IAudioProvider.cs @@ -1,29 +1,28 @@ -namespace MyNes.Core -{ - public interface IAudioProvider - { - string Name { get; } - - string ID { get; } - - bool AllowBufferChange { get; } - - bool AllowFrequencyChange { get; } - - void SubmitSamples(ref short[] buffer, ref int samples_added); - - void TogglePause(bool paused); - - void GetIsPlaying(out bool playing); - - void Initialize(); - - void ShutDown(); - - void Reset(); - - void SignalToggle(bool started); - - void SetVolume(int Vol); - } +namespace MyNes.Core; + +public interface IAudioProvider +{ + string Name { get; } + + string ID { get; } + + bool AllowBufferChange { get; } + + bool AllowFrequencyChange { get; } + + void SubmitSamples(ref short[] buffer, ref int samples_added); + + void TogglePause(bool paused); + + void GetIsPlaying(out bool playing); + + void Initialize(); + + void ShutDown(); + + void Reset(); + + void SignalToggle(bool started); + + void SetVolume(int Vol); } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/IJoypadConnecter.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/IJoypadConnecter.cs index e42d920..980acdf 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/IJoypadConnecter.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/IJoypadConnecter.cs @@ -1,18 +1,17 @@ -namespace MyNes.Core -{ - public abstract class IJoypadConnecter - { - protected byte DATA; - - public abstract void Update(); - - public virtual void Destroy() - { - } - - public virtual byte GetData() - { - return DATA; - } - } +namespace MyNes.Core; + +public abstract class IJoypadConnecter +{ + protected byte DATA; + + public abstract void Update(); + + public virtual void Destroy() + { + } + + public virtual byte GetData() + { + return DATA; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/INes.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/INes.cs index 548a5ee..689473c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/INes.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/INes.cs @@ -1,97 +1,94 @@ -using System.IO; -using System.Security.Cryptography; - -namespace MyNes.Core -{ - public class INes : IRom - { - public bool HasBattery { get; private set; } - - public bool IsPlaychoice10 { get; private set; } - - public bool IsVSUnisystem { get; private set; } - - public override void Load(string fileName, bool loadDumps) - { - FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); - if (fileStream.Length < 16) - { - fileStream.Close(); - base.IsValid = false; - return; - } - byte[] array = new byte[16]; - fileStream.Read(array, 0, 16); - byte[] buffer = new byte[fileStream.Length - 16]; - fileStream.Read(buffer, 0, (int)(fileStream.Length - 16)); - base.SHA1 = ""; - SHA1Managed sHA1Managed = new SHA1Managed(); - byte[] array2 = sHA1Managed.ComputeHash(buffer); - byte[] array3 = array2; - foreach (byte b in array3) - { - base.SHA1 += b.ToString("x2").ToLower(); - } - if (array[0] != 78 || array[1] != 69 || array[2] != 83 || array[3] != 26) - { - fileStream.Close(); - base.IsValid = false; - return; - } - base.PRGCount = array[4]; - base.CHRCount = array[5]; - switch (array[6] & 9) - { - case 0: - base.Mirroring = Mirroring.Horz; - break; - case 1: - base.Mirroring = Mirroring.Vert; - break; - case 8: - case 9: - base.Mirroring = Mirroring.Full; - break; - } - HasBattery = (array[6] & 2) != 0; - base.HasTrainer = (array[6] & 4) != 0; - if ((array[7] & 0xF) == 0) - { - base.MapperNumber = (byte)((array[7] & 0xF0) | (array[6] >> 4)); - } - else - { - base.MapperNumber = (byte)(array[6] >> 4); - } - IsVSUnisystem = (array[7] & 1) != 0; - IsPlaychoice10 = (array[7] & 2) != 0; - if (loadDumps) - { - fileStream.Seek(16L, SeekOrigin.Begin); - if (base.HasTrainer) - { - base.Trainer = new byte[512]; - fileStream.Read(base.Trainer, 0, 512); - } - else - { - base.Trainer = new byte[0]; - } - base.PRG = new byte[base.PRGCount * 16384]; - fileStream.Read(base.PRG, 0, base.PRGCount * 16384); - if (base.CHRCount > 0) - { - base.CHR = new byte[base.CHRCount * 8192]; - fileStream.Read(base.CHR, 0, base.CHRCount * 8192); - } - else - { - base.CHR = new byte[0]; - } - } - base.IsValid = true; - fileStream.Dispose(); - fileStream.Close(); - } - } +using System.IO; +using System.Security.Cryptography; + +namespace MyNes.Core; + +public class INes : IRom +{ + public bool HasBattery { get; private set; } + + public bool IsPlaychoice10 { get; private set; } + + public bool IsVSUnisystem { get; private set; } + + public override void Load(string fileName, bool loadDumps) + { + FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); + if (fileStream.Length < 16) + { + fileStream.Close(); + base.IsValid = false; + return; + } + byte[] array = new byte[16]; + fileStream.Read(array, 0, 16); + byte[] buffer = new byte[fileStream.Length - 16]; + fileStream.Read(buffer, 0, (int)(fileStream.Length - 16)); + base.SHA1 = ""; + byte[] array2 = new SHA1Managed().ComputeHash(buffer); + foreach (byte b in array2) + { + base.SHA1 += b.ToString("x2").ToLower(); + } + if (array[0] != 78 || array[1] != 69 || array[2] != 83 || array[3] != 26) + { + fileStream.Close(); + base.IsValid = false; + return; + } + base.PRGCount = array[4]; + base.CHRCount = array[5]; + switch (array[6] & 9) + { + case 0: + base.Mirroring = Mirroring.Horz; + break; + case 1: + base.Mirroring = Mirroring.Vert; + break; + case 8: + case 9: + base.Mirroring = Mirroring.Full; + break; + } + HasBattery = (array[6] & 2) != 0; + base.HasTrainer = (array[6] & 4) != 0; + if ((array[7] & 0xF) == 0) + { + base.MapperNumber = (byte)((array[7] & 0xF0) | (array[6] >> 4)); + } + else + { + base.MapperNumber = (byte)(array[6] >> 4); + } + IsVSUnisystem = (array[7] & 1) != 0; + IsPlaychoice10 = (array[7] & 2) != 0; + if (loadDumps) + { + fileStream.Seek(16L, SeekOrigin.Begin); + if (base.HasTrainer) + { + base.Trainer = new byte[512]; + fileStream.Read(base.Trainer, 0, 512); + } + else + { + base.Trainer = new byte[0]; + } + base.PRG = new byte[base.PRGCount * 16384]; + fileStream.Read(base.PRG, 0, base.PRGCount * 16384); + if (base.CHRCount > 0) + { + base.CHR = new byte[base.CHRCount * 8192]; + fileStream.Read(base.CHR, 0, base.CHRCount * 8192); + } + else + { + base.CHR = new byte[0]; + } + } + base.IsValid = true; + fileStream.Dispose(); + fileStream.Close(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/IRom.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/IRom.cs index e713361..3def451 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/IRom.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/IRom.cs @@ -1,29 +1,28 @@ -namespace MyNes.Core -{ - public abstract class IRom - { - public bool IsValid { get; set; } - - public int PRGCount { get; set; } - - public int CHRCount { get; set; } - - public int MapperNumber { get; set; } - - public Mirroring Mirroring { get; set; } - - public bool HasTrainer { get; set; } - - public byte[] PRG { get; set; } - - public byte[] CHR { get; set; } - - public byte[] Trainer { get; set; } - - public string SHA1 { get; set; } - - public virtual void Load(string fileName, bool loadDumps) - { - } - } +namespace MyNes.Core; + +public abstract class IRom +{ + public bool IsValid { get; set; } + + public int PRGCount { get; set; } + + public int CHRCount { get; set; } + + public int MapperNumber { get; set; } + + public Mirroring Mirroring { get; set; } + + public bool HasTrainer { get; set; } + + public byte[] PRG { get; set; } + + public byte[] CHR { get; set; } + + public byte[] Trainer { get; set; } + + public string SHA1 { get; set; } + + public virtual void Load(string fileName, bool loadDumps) + { + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ISettings.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ISettings.cs index 5375ac6..62093cb 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ISettings.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ISettings.cs @@ -1,149 +1,152 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; - -namespace MyNes.Core -{ - public abstract class ISettings - { - protected string filePath; - - protected FieldInfo[] Fields; - - public ISettings(string filePath) - { - this.filePath = filePath; - } - - public virtual void LoadSettings() - { - Fields = GetType().GetFields(); - if (!File.Exists(filePath)) - { - return; - } - string[] array = File.ReadAllLines(filePath); - for (int i = 0; i < array.Length; i++) - { - string[] array2 = array[i].Split('='); - if (array2 != null && array2.Length == 2) - { - SetField(array2[0], array2[1]); - } - } - } - - public virtual void SaveSettings() - { - Fields = GetType().GetFields(); - List list = new List(); - FieldInfo[] fields = Fields; - foreach (FieldInfo fieldInfo in fields) - { - if (fieldInfo.IsPublic) - { - list.Add(fieldInfo.Name + "=" + GetFieldValue(fieldInfo)); - } - } - File.WriteAllLines(filePath, list.ToArray()); - } - - protected virtual void SetField(string fieldName, string val) - { - for (int i = 0; i < Fields.Length; i++) - { - if (!(Fields[i].Name == fieldName)) - { - continue; - } - if (Fields[i].FieldType == typeof(string)) - { - Fields[i].SetValue(this, val); - } - else if (Fields[i].FieldType == typeof(bool)) - { - Fields[i].SetValue(this, val == "1"); - } - else if (Fields[i].FieldType == typeof(int)) - { - int result = 0; - if (int.TryParse(val, out result)) - { - Fields[i].SetValue(this, result); - } - } - else if (Fields[i].FieldType == typeof(float)) - { - float result2 = 0f; - if (float.TryParse(val, out result2)) - { - Fields[i].SetValue(this, result2); - } - } - else if (Fields[i].FieldType == typeof(string[])) - { - string[] value = val.Split(new string[1] { "*" }, StringSplitOptions.RemoveEmptyEntries); - Fields[i].SetValue(this, value); - } - else - { - Tracer.WriteLine("Unknown setting type = " + Fields[i].FieldType); - } - break; - } - } - - protected virtual string GetFieldValue(string fieldName) - { - for (int i = 0; i < Fields.Length; i++) - { - if (Fields[i].Name == fieldName) - { - return GetFieldValue(Fields[i]); - } - } - return ""; - } - - protected virtual string GetFieldValue(FieldInfo field) - { - object value = field.GetValue(this); - if (field.FieldType == typeof(string)) - { - return value.ToString(); - } - if (field.FieldType == typeof(bool)) - { - return ((bool)value) ? "1" : "0"; - } - if (field.FieldType == typeof(int)) - { - return value.ToString(); - } - if (field.FieldType == typeof(float)) - { - return value.ToString(); - } - if (field.FieldType == typeof(string[])) - { - string text = ""; - string[] array = (string[])value; - if (array != null) - { - string[] array2 = array; - foreach (string text2 in array2) - { - text = text + text2 + "*"; - } - } - if (text.Length > 0) - { - return text.Substring(0, text.Length - 1); - } - return ""; - } - return ""; - } - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +namespace MyNes.Core; + +public abstract class ISettings +{ + protected string filePath; + + protected FieldInfo[] Fields; + + public ISettings(string filePath) + { + this.filePath = filePath; + } + + public virtual void LoadSettings() + { + Fields = GetType().GetFields(); + if (!File.Exists(filePath)) + { + return; + } + string[] array = File.ReadAllLines(filePath); + for (int i = 0; i < array.Length; i++) + { + string[] array2 = array[i].Split('='); + if (array2 != null && array2.Length == 2) + { + SetField(array2[0], array2[1]); + } + } + } + + public virtual void SaveSettings() + { + Fields = GetType().GetFields(); + List list = new List(); + FieldInfo[] fields = Fields; + foreach (FieldInfo fieldInfo in fields) + { + if (fieldInfo.IsPublic) + { + list.Add(fieldInfo.Name + "=" + GetFieldValue(fieldInfo)); + } + } + File.WriteAllLines(filePath, list.ToArray()); + } + + protected virtual void SetField(string fieldName, string val) + { + for (int i = 0; i < Fields.Length; i++) + { + if (!(Fields[i].Name == fieldName)) + { + continue; + } + if (Fields[i].FieldType == typeof(string)) + { + Fields[i].SetValue(this, val); + } + else if (Fields[i].FieldType == typeof(bool)) + { + Fields[i].SetValue(this, val == "1"); + } + else if (Fields[i].FieldType == typeof(int)) + { + int result = 0; + if (int.TryParse(val, out result)) + { + Fields[i].SetValue(this, result); + } + } + else if (Fields[i].FieldType == typeof(float)) + { + float result2 = 0f; + if (float.TryParse(val, out result2)) + { + Fields[i].SetValue(this, result2); + } + } + else if (Fields[i].FieldType == typeof(string[])) + { + string[] value = val.Split(new string[1] { "*" }, StringSplitOptions.RemoveEmptyEntries); + Fields[i].SetValue(this, value); + } + else + { + Tracer.WriteLine("Unknown setting type = " + Fields[i].FieldType); + } + break; + } + } + + protected virtual string GetFieldValue(string fieldName) + { + for (int i = 0; i < Fields.Length; i++) + { + if (Fields[i].Name == fieldName) + { + return GetFieldValue(Fields[i]); + } + } + return ""; + } + + protected virtual string GetFieldValue(FieldInfo field) + { + object value = field.GetValue(this); + if (field.FieldType == typeof(string)) + { + return value.ToString(); + } + if (field.FieldType == typeof(bool)) + { + if (!(bool)value) + { + return "0"; + } + return "1"; + } + if (field.FieldType == typeof(int)) + { + return value.ToString(); + } + if (field.FieldType == typeof(float)) + { + return value.ToString(); + } + if (field.FieldType == typeof(string[])) + { + string text = ""; + string[] array = (string[])value; + if (array != null) + { + string[] array2 = array; + foreach (string text2 in array2) + { + text = text + text2 + "*"; + } + } + if (text.Length > 0) + { + return text.Substring(0, text.Length - 1); + } + return ""; + } + return ""; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/IShortcutsHandler.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/IShortcutsHandler.cs index bf19593..72f1fcb 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/IShortcutsHandler.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/IShortcutsHandler.cs @@ -1,7 +1,6 @@ -namespace MyNes.Core -{ - public interface IShortcutsHandler - { - void Update(); - } +namespace MyNes.Core; + +public interface IShortcutsHandler +{ + void Update(); } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/IVSUnisystemDIPConnecter.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/IVSUnisystemDIPConnecter.cs index 3a79e82..471ae2e 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/IVSUnisystemDIPConnecter.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/IVSUnisystemDIPConnecter.cs @@ -1,25 +1,24 @@ -namespace MyNes.Core -{ - public abstract class IVSUnisystemDIPConnecter - { - public abstract void Update(); - - public virtual void OnEmuShutdown() - { - } - - public virtual byte GetData4016() - { - return 0; - } - - public virtual byte GetData4017() - { - return 0; - } - - public virtual void Write4020(ref byte data) - { - } - } +namespace MyNes.Core; + +public abstract class IVSUnisystemDIPConnecter +{ + public abstract void Update(); + + public virtual void OnEmuShutdown() + { + } + + public virtual byte GetData4016() + { + return 0; + } + + public virtual byte GetData4017() + { + return 0; + } + + public virtual void Write4020(ref byte data) + { + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/IVideoProvider.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/IVideoProvider.cs index b510009..f043781 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/IVideoProvider.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/IVideoProvider.cs @@ -1,41 +1,40 @@ -namespace MyNes.Core -{ - public interface IVideoProvider - { - string Name { get; } - - string ID { get; } - - void WriteErrorNotification(string message, bool instant); - - void WriteInfoNotification(string message, bool instant); - - void WriteWarningNotification(string message, bool instant); - - void TakeSnapshotAs(string path, string format); - - void TakeSnapshot(); - - void Initialize(); - - void ShutDown(); - - void SignalToggle(bool started); - - void SubmitFrame(ref int[] buffer); - - void ResizeBegin(); - - void ResizeEnd(); - - void ApplyRegionChanges(); - - void Resume(); - - void ToggleAspectRatio(bool keep_aspect); - - void ToggleFPS(bool show_fps); - - void ApplyFilter(); - } +namespace MyNes.Core; + +public interface IVideoProvider +{ + string Name { get; } + + string ID { get; } + + void WriteErrorNotification(string message, bool instant); + + void WriteInfoNotification(string message, bool instant); + + void WriteWarningNotification(string message, bool instant); + + void TakeSnapshotAs(string path, string format); + + void TakeSnapshot(); + + void Initialize(); + + void ShutDown(); + + void SignalToggle(bool started); + + void SubmitFrame(ref int[] buffer); + + void ResizeBegin(); + + void ResizeEnd(); + + void ApplyRegionChanges(); + + void Resume(); + + void ToggleAspectRatio(bool keep_aspect); + + void ToggleFPS(bool show_fps); + + void ApplyFilter(); } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/IZapperConnecter.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/IZapperConnecter.cs index 65d651d..9a5d717 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/IZapperConnecter.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/IZapperConnecter.cs @@ -1,16 +1,15 @@ -namespace MyNes.Core -{ - public abstract class IZapperConnecter - { - protected bool Trigger; - - protected bool State; - - public abstract void Update(); - - public virtual byte GetData() - { - return (byte)((Trigger ? 16u : 0u) | (State ? 8u : 0u)); - } - } +namespace MyNes.Core; + +public abstract class IZapperConnecter +{ + protected bool Trigger; + + protected bool State; + + public abstract void Update(); + + public virtual byte GetData() + { + return (byte)((Trigger ? 16u : 0u) | (State ? 8u : 0u)); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC2.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC2.cs index eeab14f..29b8840 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC2.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC2.cs @@ -1,116 +1,115 @@ -using System.IO; - -namespace MyNes.Core -{ - internal abstract class MMC2 : Board - { - private byte chr_reg0A; - - private byte chr_reg0B; - - private byte chr_reg1A; - - private byte chr_reg1B; - - private byte latch_a = 254; - - private byte latch_b = 254; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask - 2, PRGArea.AreaA000); - Switch08KPRG(PRG_ROM_08KB_Mask - 1, PRGArea.AreaC000); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - chr_reg0B = 4; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF000) - { - case 40960: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 45056: - chr_reg0A = data; - if (latch_a == 253) - { - Switch04KCHR(chr_reg0A, CHRArea.Area0000); - } - break; - case 49152: - chr_reg0B = data; - if (latch_a == 254) - { - Switch04KCHR(chr_reg0B, CHRArea.Area0000); - } - break; - case 53248: - chr_reg1A = data; - if (latch_b == 253) - { - Switch04KCHR(chr_reg1A, CHRArea.Area1000); - } - break; - case 57344: - chr_reg1B = data; - if (latch_b == 254) - { - Switch04KCHR(chr_reg1B, CHRArea.Area1000); - } - break; - case 61440: - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - break; - } - } - - internal override void ReadCHR(ref ushort address, out byte data) - { - if ((address & 0x1FF0) == 4048 && latch_a != 253) - { - latch_a = 253; - Switch04KCHR(chr_reg0A, CHRArea.Area0000); - } - else if ((address & 0x1FF0) == 4064 && latch_a != 254) - { - latch_a = 254; - Switch04KCHR(chr_reg0B, CHRArea.Area0000); - } - else if ((address & 0x1FF0) == 8144 && latch_b != 253) - { - latch_b = 253; - Switch04KCHR(chr_reg1A, CHRArea.Area1000); - } - else if ((address & 0x1FF0) == 8160 && latch_b != 254) - { - latch_b = 254; - Switch04KCHR(chr_reg1B, CHRArea.Area1000); - } - base.ReadCHR(ref address, out data); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(chr_reg0A); - stream.Write(chr_reg0B); - stream.Write(chr_reg1A); - stream.Write(chr_reg1B); - stream.Write(latch_a); - stream.Write(latch_b); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - chr_reg0A = stream.ReadByte(); - chr_reg0B = stream.ReadByte(); - chr_reg1A = stream.ReadByte(); - chr_reg1B = stream.ReadByte(); - latch_a = stream.ReadByte(); - latch_b = stream.ReadByte(); - } - } +using System.IO; + +namespace MyNes.Core; + +internal abstract class MMC2 : Board +{ + private byte chr_reg0A; + + private byte chr_reg0B; + + private byte chr_reg1A; + + private byte chr_reg1B; + + private byte latch_a = 254; + + private byte latch_b = 254; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask - 2, PRGArea.AreaA000); + Switch08KPRG(PRG_ROM_08KB_Mask - 1, PRGArea.AreaC000); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + chr_reg0B = 4; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF000) + { + case 40960: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 45056: + chr_reg0A = data; + if (latch_a == 253) + { + Switch04KCHR(chr_reg0A, CHRArea.Area0000); + } + break; + case 49152: + chr_reg0B = data; + if (latch_a == 254) + { + Switch04KCHR(chr_reg0B, CHRArea.Area0000); + } + break; + case 53248: + chr_reg1A = data; + if (latch_b == 253) + { + Switch04KCHR(chr_reg1A, CHRArea.Area1000); + } + break; + case 57344: + chr_reg1B = data; + if (latch_b == 254) + { + Switch04KCHR(chr_reg1B, CHRArea.Area1000); + } + break; + case 61440: + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + break; + } + } + + internal override void ReadCHR(ref ushort address, out byte data) + { + if ((address & 0x1FF0) == 4048 && latch_a != 253) + { + latch_a = 253; + Switch04KCHR(chr_reg0A, CHRArea.Area0000); + } + else if ((address & 0x1FF0) == 4064 && latch_a != 254) + { + latch_a = 254; + Switch04KCHR(chr_reg0B, CHRArea.Area0000); + } + else if ((address & 0x1FF0) == 8144 && latch_b != 253) + { + latch_b = 253; + Switch04KCHR(chr_reg1A, CHRArea.Area1000); + } + else if ((address & 0x1FF0) == 8160 && latch_b != 254) + { + latch_b = 254; + Switch04KCHR(chr_reg1B, CHRArea.Area1000); + } + base.ReadCHR(ref address, out data); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(chr_reg0A); + stream.Write(chr_reg0B); + stream.Write(chr_reg1A); + stream.Write(chr_reg1B); + stream.Write(latch_a); + stream.Write(latch_b); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + chr_reg0A = stream.ReadByte(); + chr_reg0B = stream.ReadByte(); + chr_reg1A = stream.ReadByte(); + chr_reg1B = stream.ReadByte(); + latch_a = stream.ReadByte(); + latch_b = stream.ReadByte(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC5Pcm.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC5Pcm.cs index 3904317..731a17a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC5Pcm.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC5Pcm.cs @@ -1,86 +1,85 @@ -using System.IO; - -namespace MyNes.Core -{ - internal class MMC5Pcm - { - internal byte output; - - internal bool Outputable; - - private bool readMode; - - private bool PCMIRQenable; - - private bool irqTrip; - - internal void HardReset() - { - output = 0; - readMode = false; - PCMIRQenable = false; - irqTrip = false; - } - - internal void SoftReset() - { - HardReset(); - } - - internal void Write5010(byte data) - { - readMode = (data & 1) == 1; - PCMIRQenable = (data & 0x80) == 128; - if (PCMIRQenable && irqTrip) - { - NesEmu.IRQFlags |= 8; - } - } - - internal byte Read5010() - { - byte result = (byte)((irqTrip & PCMIRQenable) ? 128u : 0u); - irqTrip = false; - NesEmu.IRQFlags &= -9; - return result; - } - - internal void Write5011(byte data) - { - if (readMode) - { - return; - } - if (data == 0) - { - irqTrip = true; - } - else - { - irqTrip = false; - if (Outputable) - { - output = data; - } - } - if (PCMIRQenable && irqTrip) - { - NesEmu.IRQFlags |= 8; - } - } - - internal void SaveState(ref BinaryWriter stream) - { - stream.Write(readMode); - stream.Write(PCMIRQenable); - stream.Write(irqTrip); - } - - internal void LoadState(ref BinaryReader stream) - { - readMode = stream.ReadBoolean(); - PCMIRQenable = stream.ReadBoolean(); - irqTrip = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +internal class MMC5Pcm +{ + internal byte output; + + internal bool Outputable; + + private bool readMode; + + private bool PCMIRQenable; + + private bool irqTrip; + + internal void HardReset() + { + output = 0; + readMode = false; + PCMIRQenable = false; + irqTrip = false; + } + + internal void SoftReset() + { + HardReset(); + } + + internal void Write5010(byte data) + { + readMode = (data & 1) == 1; + PCMIRQenable = (data & 0x80) == 128; + if (PCMIRQenable && irqTrip) + { + NesEmu.IRQFlags |= 8; + } + } + + internal byte Read5010() + { + byte result = (byte)((irqTrip & PCMIRQenable) ? 128 : 0); + irqTrip = false; + NesEmu.IRQFlags &= -9; + return result; + } + + internal void Write5011(byte data) + { + if (readMode) + { + return; + } + if (data == 0) + { + irqTrip = true; + } + else + { + irqTrip = false; + if (Outputable) + { + output = data; + } + } + if (PCMIRQenable && irqTrip) + { + NesEmu.IRQFlags |= 8; + } + } + + internal void SaveState(ref BinaryWriter stream) + { + stream.Write(readMode); + stream.Write(PCMIRQenable); + stream.Write(irqTrip); + } + + internal void LoadState(ref BinaryReader stream) + { + readMode = stream.ReadBoolean(); + PCMIRQenable = stream.ReadBoolean(); + irqTrip = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC5Sqr.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC5Sqr.cs index d1c7bf3..6ff1d1f 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC5Sqr.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/MMC5Sqr.cs @@ -1,214 +1,213 @@ -using System.IO; - -namespace MyNes.Core -{ - internal class MMC5Sqr - { - private byte[][] duty_cycle_sequences = new byte[4][] - { - new byte[8] { 0, 0, 0, 0, 0, 0, 0, 1 }, - new byte[8] { 0, 0, 0, 0, 0, 0, 1, 1 }, - new byte[8] { 0, 0, 0, 0, 1, 1, 1, 1 }, - new byte[8] { 1, 1, 1, 1, 1, 1, 0, 0 } - }; - - private byte[] duration_table = new byte[32] - { - 10, 254, 20, 2, 40, 4, 80, 6, 160, 8, - 60, 10, 14, 12, 26, 14, 12, 16, 24, 18, - 48, 20, 96, 22, 192, 24, 72, 26, 16, 28, - 32, 30 - }; - - private byte duty_cycle; - - private bool length_halt; - - private bool constant_volume_envelope; - - private byte volume_devider_period; - - private int timer; - - private int period_devider; - - private byte seqencer; - - private bool length_enabled; - - private int length_counter; - - private bool envelope_start_flag; - - private byte envelope_devider; - - private byte envelope_decay_level_counter; - - private byte envelope; - - internal int output; - - internal bool Outputable; - - internal void HardReset() - { - duty_cycle = 0; - length_halt = false; - constant_volume_envelope = false; - volume_devider_period = 0; - timer = 0; - period_devider = 0; - seqencer = 0; - length_enabled = false; - length_counter = 0; - envelope_start_flag = false; - envelope_devider = 0; - envelope_decay_level_counter = 0; - envelope = 0; - } - - internal void SoftReset() - { - HardReset(); - } - - internal void Clock() - { - period_devider--; - if (period_devider > 0) - { - return; - } - period_devider = timer + 1; - if (length_counter > 0) - { - if (Outputable) - { - output = duty_cycle_sequences[duty_cycle][seqencer] * envelope; - } - } - else - { - output = 0; - } - if (seqencer == 0) - { - seqencer = 7; - } - else - { - seqencer--; - } - } - - internal void ClockLength() - { - if (length_counter > 0 && !length_halt) - { - length_counter--; - } - } - - internal void ClockEnvelope() - { - if (envelope_start_flag) - { - envelope_start_flag = false; - envelope_decay_level_counter = 15; - envelope_devider = (byte)(volume_devider_period + 1); - } - else if (envelope_devider > 0) - { - envelope_devider--; - } - else - { - envelope_devider = (byte)(volume_devider_period + 1); - if (envelope_decay_level_counter > 0) - { - envelope_decay_level_counter--; - } - else if (length_halt) - { - envelope_decay_level_counter = 15; - } - } - envelope = (constant_volume_envelope ? volume_devider_period : envelope_decay_level_counter); - } - - internal void Write0(ref byte value) - { - duty_cycle = (byte)((value & 0xC0) >> 6); - volume_devider_period = (byte)(value & 0xFu); - length_halt = (value & 0x20) != 0; - constant_volume_envelope = (value & 0x10) != 0; - envelope = (constant_volume_envelope ? volume_devider_period : envelope_decay_level_counter); - } - - internal void Write2(ref byte value) - { - timer = (timer & 0xFF00) | value; - } - - internal void Write3(ref byte value) - { - timer = (timer & 0xFF) | ((value & 7) << 8); - if (length_enabled) - { - length_counter = duration_table[value >> 3]; - } - seqencer = 0; - envelope_start_flag = true; - } - - internal void WriteEnabled(bool enabled) - { - length_enabled = enabled; - if (!length_enabled) - { - length_counter = 0; - } - } - - internal bool ReadEnable() - { - return length_counter > 0; - } - - internal void WriteStateData(ref BinaryWriter bin) - { - bin.Write(duty_cycle); - bin.Write(length_halt); - bin.Write(constant_volume_envelope); - bin.Write(volume_devider_period); - bin.Write(timer); - bin.Write(period_devider); - bin.Write(seqencer); - bin.Write(length_enabled); - bin.Write(length_counter); - bin.Write(envelope_start_flag); - bin.Write(envelope_devider); - bin.Write(envelope_decay_level_counter); - bin.Write(envelope); - bin.Write(output); - } - - internal void ReadStateData(ref BinaryReader bin) - { - duty_cycle = bin.ReadByte(); - length_halt = bin.ReadBoolean(); - constant_volume_envelope = bin.ReadBoolean(); - volume_devider_period = bin.ReadByte(); - timer = bin.ReadInt32(); - period_devider = bin.ReadInt32(); - seqencer = bin.ReadByte(); - length_enabled = bin.ReadBoolean(); - length_counter = bin.ReadInt32(); - envelope_start_flag = bin.ReadBoolean(); - envelope_devider = bin.ReadByte(); - envelope_decay_level_counter = bin.ReadByte(); - envelope = bin.ReadByte(); - output = bin.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +internal class MMC5Sqr +{ + private byte[][] duty_cycle_sequences = new byte[4][] + { + new byte[8] { 0, 0, 0, 0, 0, 0, 0, 1 }, + new byte[8] { 0, 0, 0, 0, 0, 0, 1, 1 }, + new byte[8] { 0, 0, 0, 0, 1, 1, 1, 1 }, + new byte[8] { 1, 1, 1, 1, 1, 1, 0, 0 } + }; + + private byte[] duration_table = new byte[32] + { + 10, 254, 20, 2, 40, 4, 80, 6, 160, 8, + 60, 10, 14, 12, 26, 14, 12, 16, 24, 18, + 48, 20, 96, 22, 192, 24, 72, 26, 16, 28, + 32, 30 + }; + + private byte duty_cycle; + + private bool length_halt; + + private bool constant_volume_envelope; + + private byte volume_devider_period; + + private int timer; + + private int period_devider; + + private byte seqencer; + + private bool length_enabled; + + private int length_counter; + + private bool envelope_start_flag; + + private byte envelope_devider; + + private byte envelope_decay_level_counter; + + private byte envelope; + + internal int output; + + internal bool Outputable; + + internal void HardReset() + { + duty_cycle = 0; + length_halt = false; + constant_volume_envelope = false; + volume_devider_period = 0; + timer = 0; + period_devider = 0; + seqencer = 0; + length_enabled = false; + length_counter = 0; + envelope_start_flag = false; + envelope_devider = 0; + envelope_decay_level_counter = 0; + envelope = 0; + } + + internal void SoftReset() + { + HardReset(); + } + + internal void Clock() + { + period_devider--; + if (period_devider > 0) + { + return; + } + period_devider = timer + 1; + if (length_counter > 0) + { + if (Outputable) + { + output = duty_cycle_sequences[duty_cycle][seqencer] * envelope; + } + } + else + { + output = 0; + } + if (seqencer == 0) + { + seqencer = 7; + } + else + { + seqencer--; + } + } + + internal void ClockLength() + { + if (length_counter > 0 && !length_halt) + { + length_counter--; + } + } + + internal void ClockEnvelope() + { + if (envelope_start_flag) + { + envelope_start_flag = false; + envelope_decay_level_counter = 15; + envelope_devider = (byte)(volume_devider_period + 1); + } + else if (envelope_devider > 0) + { + envelope_devider--; + } + else + { + envelope_devider = (byte)(volume_devider_period + 1); + if (envelope_decay_level_counter > 0) + { + envelope_decay_level_counter--; + } + else if (length_halt) + { + envelope_decay_level_counter = 15; + } + } + envelope = (constant_volume_envelope ? volume_devider_period : envelope_decay_level_counter); + } + + internal void Write0(ref byte value) + { + duty_cycle = (byte)((value & 0xC0) >> 6); + volume_devider_period = (byte)(value & 0xFu); + length_halt = (value & 0x20) != 0; + constant_volume_envelope = (value & 0x10) != 0; + envelope = (constant_volume_envelope ? volume_devider_period : envelope_decay_level_counter); + } + + internal void Write2(ref byte value) + { + timer = (timer & 0xFF00) | value; + } + + internal void Write3(ref byte value) + { + timer = (timer & 0xFF) | ((value & 7) << 8); + if (length_enabled) + { + length_counter = duration_table[value >> 3]; + } + seqencer = 0; + envelope_start_flag = true; + } + + internal void WriteEnabled(bool enabled) + { + length_enabled = enabled; + if (!length_enabled) + { + length_counter = 0; + } + } + + internal bool ReadEnable() + { + return length_counter > 0; + } + + internal void WriteStateData(ref BinaryWriter bin) + { + bin.Write(duty_cycle); + bin.Write(length_halt); + bin.Write(constant_volume_envelope); + bin.Write(volume_devider_period); + bin.Write(timer); + bin.Write(period_devider); + bin.Write(seqencer); + bin.Write(length_enabled); + bin.Write(length_counter); + bin.Write(envelope_start_flag); + bin.Write(envelope_devider); + bin.Write(envelope_decay_level_counter); + bin.Write(envelope); + bin.Write(output); + } + + internal void ReadStateData(ref BinaryReader bin) + { + duty_cycle = bin.ReadByte(); + length_halt = bin.ReadBoolean(); + constant_volume_envelope = bin.ReadBoolean(); + volume_devider_period = bin.ReadByte(); + timer = bin.ReadInt32(); + period_devider = bin.ReadInt32(); + seqencer = bin.ReadByte(); + length_enabled = bin.ReadBoolean(); + length_counter = bin.ReadInt32(); + envelope_start_flag = bin.ReadBoolean(); + envelope_devider = bin.ReadByte(); + envelope_decay_level_counter = bin.ReadByte(); + envelope = bin.ReadByte(); + output = bin.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/MNInterfaceLanguage.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/MNInterfaceLanguage.cs index cc870c1..585f63b 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/MNInterfaceLanguage.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/MNInterfaceLanguage.cs @@ -1,129 +1,128 @@ -namespace MyNes.Core -{ - public class MNInterfaceLanguage - { - public static string Message_RomInfoCanBeOnlyShown = "Rom info can be shown only when emulation is on (i.e. game is loaded)"; - - public static string Message_StateSlotSetTo = "State slot set to"; - - public static string Message_LoadStateCanBeUsedOnly = "Load state as can be used only when emulation is on (i.e. game is loaded)"; - - public static string Message_SaveStateCanBeUseOnly = "Save state as can be used only when emulation is on (i.e. game is loaded)"; - - public static string Message_HardResetCanBeUsedOnly = "Hard reset can be used only when emulation is on (i.e. game is loaded)"; - - public static string Message_SoftResetCanBeUsedOnly = "Soft reset can be used only when emulation is on (i.e. game is loaded)"; - - public static string Message_TurboCanBeToggledOnly = "Turbo can be toggled only when emulation is on (i.e. game is loaded)"; - - public static string Message_GameGenieCanBeConfiguredOnly = "Game Genie can be enabled/configured only when emulation is on (i.e. game is loaded)"; - - public static string Message_Error1 = "Can't save state, emu is off."; - - public static string Message_Error2 = "Can't save state, no rom file is loaded."; - - public static string Message_Error3 = "Can't save state while loading a state !"; - - public static string Message_Error4 = "Already saving state !!"; - - public static string Message_Error5 = "Can't load state, emu is off."; - - public static string Message_Error6 = "Can't load state, no rom file is loaded."; - - public static string Message_Error7 = "Can't load state while saving a state !"; - - public static string Message_Error8 = "Already loading state !!"; - - public static string Message_Error9 = "No state found in slot"; - - public static string Message_Error10 = "Unable load state at slot"; - - public static string Message_Error11 = "Not My Nes State File !"; - - public static string Message_Error12 = "Not compatible state file version !"; - - public static string Message_Error13 = "This state file is not for this game; not same SHA1 !"; - - public static string Message_Error14 = "IS NOT LOCATED, mapper is not supported or unable to find it."; - - public static string Message_Error15 = "will be used instead, assigned successfully."; - - public static string Message_Error16 = "Game Genie code length cannot be more than 8 letters"; - - public static string Message_Error17 = "has issues and may not function probably with this game."; - - public static string Message_Info1 = "State saved at slot"; - - public static string Message_Info2 = "State loaded from slot"; - - public static string Message_Info3 = "Snapshot saved"; - - public static string Message_Info4 = "Interface language set to"; - - public static string Message_PleaseRestartToApply = "Please restart My Nes to apply."; - - public static string Message_HardReset = "HARD RESET !"; - - public static string Message_SoftReset = "SOFT RESET !"; - - public static string Message_Paused = "PAUSED"; - - public static string Mapper = "Mapper"; - - public static string IssueMapper5 = "Split screen not implemented.\nUchuu Keibitai SDF game graphic corruption for unknown reason in the intro (not in the split screen)."; - - public static string IssueMapper6 = "Mapper 6 is not tested, issues may occur"; - - public static string IssueMapper8 = "Mapper 8 is not tested, issues may occur"; - - public static string IssueMapper33 = "Mapper 33: Akira is not working for unknown reason."; - - public static string IssueMapper44 = "In game Super Big 7 - in - 1 : Double Dragon 3 game does not work."; - - public static string IssueMapper53 = "Mapper 53 does not work with the test roms i have, maybe something wrong with the implementation or the roms themselves"; - - public static string IssueMapper56 = "Mapper 56 does not work with the test roms i have, maybe something wrong with the implementation or the roms themselves"; - - public static string IssueMapper58 = "Study and Game 32-in-1 (Ch) [!].nes needs keyboard ?"; - - public static string IssueMapper60 = "Mapper 60 does not work with the test roms i have, maybe something wrong with the implementation or the roms themselves"; - - public static string IssueMapper85 = "VRC7 sound channels are not supported"; - - public static string IssueMapper90 = "DipSwitch is not implemented, the irq modes 2-3 are not implemented yet."; - - public static string IssueMapper96 = "Mapper 96 does not function probably and needs special controller to be implemented."; - - public static string IssueMapper105 = "Game hangs on title screen !"; - - public static string IssueMapper119 = "Mapper 119 does not function probably"; - - public static string IssueMapper154 = "Game shows glitches with chr"; - - public static string IssueMapper180 = "Crazy Climber needs special controller which not implemented yet."; - - public static string IssueMapper191 = "Mapper 191 is not tested, issues may occur"; - - public static string IssueMapper193 = "Game show nothing but fighter sprite !"; - - public static string IssueMapper202 = "150 in 1: some games not work well. Is it mapper or rom dump ?"; - - public static string IssueMapper203 = "64-in-1: some games not work, maybe something wrong with the implementation or the rom itself"; - - public static string IssueMapper207 = "Fudou Myouou Den is not assigned as mapper 207 while it should be !"; - - public static string IssueMapper222 = "Mapper 222 is not tested, issues may occur"; - - public static string IssueMapper228 = "Mapper 228 does not function probably"; - - public static string IssueMapper229 = "Mapper 229 is not tested, issues may occur"; - - public static string IssueMapper230 = "Only Contra works !?"; - - public static string IssueMapper243 = "Shows glitches in some games."; - - public static string IssueMapper245 = "Graphic glitches, maybe chr switches."; - - public static string IssueMapper255 = "Mapper 255 is not tested, issues may occur"; - } +namespace MyNes.Core; + +public class MNInterfaceLanguage +{ + public static string Message_RomInfoCanBeOnlyShown = "Rom info can be shown only when emulation is on (i.e. game is loaded)"; + + public static string Message_StateSlotSetTo = "State slot set to"; + + public static string Message_LoadStateCanBeUsedOnly = "Load state as can be used only when emulation is on (i.e. game is loaded)"; + + public static string Message_SaveStateCanBeUseOnly = "Save state as can be used only when emulation is on (i.e. game is loaded)"; + + public static string Message_HardResetCanBeUsedOnly = "Hard reset can be used only when emulation is on (i.e. game is loaded)"; + + public static string Message_SoftResetCanBeUsedOnly = "Soft reset can be used only when emulation is on (i.e. game is loaded)"; + + public static string Message_TurboCanBeToggledOnly = "Turbo can be toggled only when emulation is on (i.e. game is loaded)"; + + public static string Message_GameGenieCanBeConfiguredOnly = "Game Genie can be enabled/configured only when emulation is on (i.e. game is loaded)"; + + public static string Message_Error1 = "Can't save state, emu is off."; + + public static string Message_Error2 = "Can't save state, no rom file is loaded."; + + public static string Message_Error3 = "Can't save state while loading a state !"; + + public static string Message_Error4 = "Already saving state !!"; + + public static string Message_Error5 = "Can't load state, emu is off."; + + public static string Message_Error6 = "Can't load state, no rom file is loaded."; + + public static string Message_Error7 = "Can't load state while saving a state !"; + + public static string Message_Error8 = "Already loading state !!"; + + public static string Message_Error9 = "No state found in slot"; + + public static string Message_Error10 = "Unable load state at slot"; + + public static string Message_Error11 = "Not My Nes State File !"; + + public static string Message_Error12 = "Not compatible state file version !"; + + public static string Message_Error13 = "This state file is not for this game; not same SHA1 !"; + + public static string Message_Error14 = "IS NOT LOCATED, mapper is not supported or unable to find it."; + + public static string Message_Error15 = "will be used instead, assigned successfully."; + + public static string Message_Error16 = "Game Genie code length cannot be more than 8 letters"; + + public static string Message_Error17 = "has issues and may not function probably with this game."; + + public static string Message_Info1 = "State saved at slot"; + + public static string Message_Info2 = "State loaded from slot"; + + public static string Message_Info3 = "Snapshot saved"; + + public static string Message_Info4 = "Interface language set to"; + + public static string Message_PleaseRestartToApply = "Please restart My Nes to apply."; + + public static string Message_HardReset = "HARD RESET !"; + + public static string Message_SoftReset = "SOFT RESET !"; + + public static string Message_Paused = "PAUSED"; + + public static string Mapper = "Mapper"; + + public static string IssueMapper5 = "Split screen not implemented.\nUchuu Keibitai SDF game graphic corruption for unknown reason in the intro (not in the split screen)."; + + public static string IssueMapper6 = "Mapper 6 is not tested, issues may occur"; + + public static string IssueMapper8 = "Mapper 8 is not tested, issues may occur"; + + public static string IssueMapper33 = "Mapper 33: Akira is not working for unknown reason."; + + public static string IssueMapper44 = "In game Super Big 7 - in - 1 : Double Dragon 3 game does not work."; + + public static string IssueMapper53 = "Mapper 53 does not work with the test roms i have, maybe something wrong with the implementation or the roms themselves"; + + public static string IssueMapper56 = "Mapper 56 does not work with the test roms i have, maybe something wrong with the implementation or the roms themselves"; + + public static string IssueMapper58 = "Study and Game 32-in-1 (Ch) [!].nes needs keyboard ?"; + + public static string IssueMapper60 = "Mapper 60 does not work with the test roms i have, maybe something wrong with the implementation or the roms themselves"; + + public static string IssueMapper85 = "VRC7 sound channels are not supported"; + + public static string IssueMapper90 = "DipSwitch is not implemented, the irq modes 2-3 are not implemented yet."; + + public static string IssueMapper96 = "Mapper 96 does not function probably and needs special controller to be implemented."; + + public static string IssueMapper105 = "Game hangs on title screen !"; + + public static string IssueMapper119 = "Mapper 119 does not function probably"; + + public static string IssueMapper154 = "Game shows glitches with chr"; + + public static string IssueMapper180 = "Crazy Climber needs special controller which not implemented yet."; + + public static string IssueMapper191 = "Mapper 191 is not tested, issues may occur"; + + public static string IssueMapper193 = "Game show nothing but fighter sprite !"; + + public static string IssueMapper202 = "150 in 1: some games not work well. Is it mapper or rom dump ?"; + + public static string IssueMapper203 = "64-in-1: some games not work, maybe something wrong with the implementation or the rom itself"; + + public static string IssueMapper207 = "Fudou Myouou Den is not assigned as mapper 207 while it should be !"; + + public static string IssueMapper222 = "Mapper 222 is not tested, issues may occur"; + + public static string IssueMapper228 = "Mapper 228 does not function probably"; + + public static string IssueMapper229 = "Mapper 229 is not tested, issues may occur"; + + public static string IssueMapper230 = "Only Contra works !?"; + + public static string IssueMapper243 = "Shows glitches in some games."; + + public static string IssueMapper245 = "Graphic glitches, maybe chr switches."; + + public static string IssueMapper255 = "Mapper 255 is not tested, issues may occur"; } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper000.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper000.cs index f1d18bd..9668724 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper000.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper000.cs @@ -1,7 +1,6 @@ -namespace MyNes.Core -{ - [BoardInfo("NROM", 0)] - internal class Mapper000 : Board - { - } +namespace MyNes.Core; + +[BoardInfo("NROM", 0)] +internal class Mapper000 : Board +{ } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper001.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper001.cs index 5cd492b..726111d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper001.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper001.cs @@ -1,245 +1,244 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("MMC1", 1, 4, 64)] - internal class Mapper001 : Board - { - private int address_reg; - - private byte[] reg = new byte[4]; - - private byte shift = 0; - - private byte buffer = 0; - - private bool flag_p; - - private bool flag_c; - - private bool flag_s; - - private bool enable_wram_enable; - - private int prg_hijackedbit; - - private bool use_hijacked; - - private bool use_sram_switch; - - private int sram_switch_mask; - - private int cpuCycles; - - internal override void HardReset() - { - base.HardReset(); - cpuCycles = 0; - address_reg = 0; - reg = new byte[4]; - reg[0] = 12; - flag_c = false; - flag_s = (flag_p = true); - prg_hijackedbit = 0; - reg[1] = (reg[2] = (reg[3] = 0)); - buffer = 0; - shift = 0; - if (base.Chips.Contains("MMC1B") || base.Chips.Contains("MMC1B2")) - { - TogglePRGRAMEnable(enable: false); - Console.WriteLine("MMC1: SRAM Disabled."); - } - enable_wram_enable = !base.Chips.Contains("MMC1A"); - Console.WriteLine("MMC1: enable_wram_enable = " + enable_wram_enable); - use_hijacked = (PRG_ROM_16KB_Mask & 0x10) == 16; - if (use_hijacked) - { - prg_hijackedbit = 16; - } - use_sram_switch = false; - if (PRG_RAM_08KB_Count > 0) - { - use_sram_switch = true; - sram_switch_mask = (use_hijacked ? 8 : 24); - sram_switch_mask &= PRG_RAM_08KB_Mask << 3; - if (sram_switch_mask == 0) - { - use_sram_switch = false; - } - } - Switch16KPRG(0xF | prg_hijackedbit, PRGArea.AreaC000); - Console.WriteLine("MMC1: use_hijacked = " + use_hijacked); - Console.WriteLine("MMC1: use_sram_switch = " + use_sram_switch); - Console.WriteLine("MMC1: sram_switch_mask = " + sram_switch_mask.ToString("X2")); - } - - internal override void WritePRG(ref ushort address, ref byte value) - { - if (cpuCycles > 0) - { - return; - } - cpuCycles = 3; - if ((value & 0x80) == 128) - { - reg[0] |= 12; - flag_s = (flag_p = true); - shift = (buffer = 0); - return; - } - if ((value & 1) == 1) - { - buffer |= (byte)(1 << (int)shift); - } - if (++shift < 5) - { - return; - } - address_reg = (address & 0x7FFF) >> 13; - reg[address_reg] = buffer; - shift = (buffer = 0); - switch (address_reg) - { - case 0: - flag_c = (reg[0] & 0x10) != 0; - flag_p = (reg[0] & 8) != 0; - flag_s = (reg[0] & 4) != 0; - UpdatePRG(); - UpdateCHR(); - switch (reg[0] & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - } - break; - case 1: - if (!flag_c) - { - Switch08KCHR(reg[1] >> 1); - } - else - { - Switch04KCHR(reg[1], CHRArea.Area0000); - } - if (use_sram_switch) - { - Switch08KPRG((reg[1] & sram_switch_mask) >> 3, PRGArea.Area6000); - } - if (use_hijacked) - { - prg_hijackedbit = reg[1] & 0x10; - UpdatePRG(); - } - break; - case 2: - if (flag_c) - { - Switch04KCHR(reg[2], CHRArea.Area1000); - } - if (use_sram_switch) - { - Switch08KPRG((reg[2] & sram_switch_mask) >> 3, PRGArea.Area6000); - } - if (use_hijacked) - { - prg_hijackedbit = reg[2] & 0x10; - UpdatePRG(); - } - break; - case 3: - if (enable_wram_enable) - { - TogglePRGRAMEnable((reg[3] & 0x10) == 0); - } - UpdatePRG(); - break; - } - } - - private void UpdateCHR() - { - if (!flag_c) - { - Switch08KCHR(reg[1] >> 1); - } - else - { - Switch04KCHR(reg[1], CHRArea.Area0000); - Switch04KCHR(reg[2], CHRArea.Area1000); - } - if (use_sram_switch) - { - Switch08KPRG((reg[1] & sram_switch_mask) >> 3, PRGArea.Area6000); - } - } - - private void UpdatePRG() - { - if (!flag_p) - { - Switch32KPRG(((reg[3] & 0xF) | prg_hijackedbit) >> 1, PRGArea.Area8000); - } - else if (flag_s) - { - Switch16KPRG((reg[3] & 0xF) | prg_hijackedbit, PRGArea.Area8000); - Switch16KPRG(0xF | prg_hijackedbit, PRGArea.AreaC000); - } - else - { - Switch16KPRG(prg_hijackedbit, PRGArea.Area8000); - Switch16KPRG((reg[3] & 0xF) | prg_hijackedbit, PRGArea.AreaC000); - } - } - - internal override void OnCPUClock() - { - if (cpuCycles > 0) - { - cpuCycles--; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(reg); - stream.Write(shift); - stream.Write(buffer); - stream.Write(flag_p); - stream.Write(flag_c); - stream.Write(flag_s); - stream.Write(enable_wram_enable); - stream.Write(prg_hijackedbit); - stream.Write(use_hijacked); - stream.Write(use_sram_switch); - stream.Write(cpuCycles); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - stream.Read(reg, 0, reg.Length); - shift = stream.ReadByte(); - buffer = stream.ReadByte(); - flag_p = stream.ReadBoolean(); - flag_c = stream.ReadBoolean(); - flag_s = stream.ReadBoolean(); - enable_wram_enable = stream.ReadBoolean(); - prg_hijackedbit = stream.ReadInt32(); - use_hijacked = stream.ReadBoolean(); - use_sram_switch = stream.ReadBoolean(); - cpuCycles = stream.ReadInt32(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("MMC1", 1, 4, 64)] +internal class Mapper001 : Board +{ + private int address_reg; + + private byte[] reg = new byte[4]; + + private byte shift; + + private byte buffer; + + private bool flag_p; + + private bool flag_c; + + private bool flag_s; + + private bool enable_wram_enable; + + private int prg_hijackedbit; + + private bool use_hijacked; + + private bool use_sram_switch; + + private int sram_switch_mask; + + private int cpuCycles; + + internal override void HardReset() + { + base.HardReset(); + cpuCycles = 0; + address_reg = 0; + reg = new byte[4]; + reg[0] = 12; + flag_c = false; + flag_s = (flag_p = true); + prg_hijackedbit = 0; + reg[1] = (reg[2] = (reg[3] = 0)); + buffer = 0; + shift = 0; + if (base.Chips.Contains("MMC1B") || base.Chips.Contains("MMC1B2")) + { + TogglePRGRAMEnable(enable: false); + Console.WriteLine("MMC1: SRAM Disabled."); + } + enable_wram_enable = !base.Chips.Contains("MMC1A"); + Console.WriteLine("MMC1: enable_wram_enable = " + enable_wram_enable); + use_hijacked = (PRG_ROM_16KB_Mask & 0x10) == 16; + if (use_hijacked) + { + prg_hijackedbit = 16; + } + use_sram_switch = false; + if (PRG_RAM_08KB_Count > 0) + { + use_sram_switch = true; + sram_switch_mask = (use_hijacked ? 8 : 24); + sram_switch_mask &= PRG_RAM_08KB_Mask << 3; + if (sram_switch_mask == 0) + { + use_sram_switch = false; + } + } + Switch16KPRG(0xF | prg_hijackedbit, PRGArea.AreaC000); + Console.WriteLine("MMC1: use_hijacked = " + use_hijacked); + Console.WriteLine("MMC1: use_sram_switch = " + use_sram_switch); + Console.WriteLine("MMC1: sram_switch_mask = " + sram_switch_mask.ToString("X2")); + } + + internal override void WritePRG(ref ushort address, ref byte value) + { + if (cpuCycles > 0) + { + return; + } + cpuCycles = 3; + if ((value & 0x80) == 128) + { + reg[0] |= 12; + flag_s = (flag_p = true); + shift = (buffer = 0); + return; + } + if ((value & 1) == 1) + { + buffer |= (byte)(1 << (int)shift); + } + if (++shift < 5) + { + return; + } + address_reg = (address & 0x7FFF) >> 13; + reg[address_reg] = buffer; + shift = (buffer = 0); + switch (address_reg) + { + case 0: + flag_c = (reg[0] & 0x10) != 0; + flag_p = (reg[0] & 8) != 0; + flag_s = (reg[0] & 4) != 0; + UpdatePRG(); + UpdateCHR(); + switch (reg[0] & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + } + break; + case 1: + if (!flag_c) + { + Switch08KCHR(reg[1] >> 1); + } + else + { + Switch04KCHR(reg[1], CHRArea.Area0000); + } + if (use_sram_switch) + { + Switch08KPRG((reg[1] & sram_switch_mask) >> 3, PRGArea.Area6000); + } + if (use_hijacked) + { + prg_hijackedbit = reg[1] & 0x10; + UpdatePRG(); + } + break; + case 2: + if (flag_c) + { + Switch04KCHR(reg[2], CHRArea.Area1000); + } + if (use_sram_switch) + { + Switch08KPRG((reg[2] & sram_switch_mask) >> 3, PRGArea.Area6000); + } + if (use_hijacked) + { + prg_hijackedbit = reg[2] & 0x10; + UpdatePRG(); + } + break; + case 3: + if (enable_wram_enable) + { + TogglePRGRAMEnable((reg[3] & 0x10) == 0); + } + UpdatePRG(); + break; + } + } + + private void UpdateCHR() + { + if (!flag_c) + { + Switch08KCHR(reg[1] >> 1); + } + else + { + Switch04KCHR(reg[1], CHRArea.Area0000); + Switch04KCHR(reg[2], CHRArea.Area1000); + } + if (use_sram_switch) + { + Switch08KPRG((reg[1] & sram_switch_mask) >> 3, PRGArea.Area6000); + } + } + + private void UpdatePRG() + { + if (!flag_p) + { + Switch32KPRG(((reg[3] & 0xF) | prg_hijackedbit) >> 1, PRGArea.Area8000); + } + else if (flag_s) + { + Switch16KPRG((reg[3] & 0xF) | prg_hijackedbit, PRGArea.Area8000); + Switch16KPRG(0xF | prg_hijackedbit, PRGArea.AreaC000); + } + else + { + Switch16KPRG(prg_hijackedbit, PRGArea.Area8000); + Switch16KPRG((reg[3] & 0xF) | prg_hijackedbit, PRGArea.AreaC000); + } + } + + internal override void OnCPUClock() + { + if (cpuCycles > 0) + { + cpuCycles--; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(reg); + stream.Write(shift); + stream.Write(buffer); + stream.Write(flag_p); + stream.Write(flag_c); + stream.Write(flag_s); + stream.Write(enable_wram_enable); + stream.Write(prg_hijackedbit); + stream.Write(use_hijacked); + stream.Write(use_sram_switch); + stream.Write(cpuCycles); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + stream.Read(reg, 0, reg.Length); + shift = stream.ReadByte(); + buffer = stream.ReadByte(); + flag_p = stream.ReadBoolean(); + flag_c = stream.ReadBoolean(); + flag_s = stream.ReadBoolean(); + enable_wram_enable = stream.ReadBoolean(); + prg_hijackedbit = stream.ReadInt32(); + use_hijacked = stream.ReadBoolean(); + use_sram_switch = stream.ReadBoolean(); + cpuCycles = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper002.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper002.cs index 0573b03..0f6bffd 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper002.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper002.cs @@ -1,17 +1,16 @@ -namespace MyNes.Core -{ - [BoardInfo("UxROM", 2)] - internal class Mapper002 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort addr, ref byte val) - { - Switch16KPRG(val, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("UxROM", 2)] +internal class Mapper002 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort addr, ref byte val) + { + Switch16KPRG(val, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper003.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper003.cs index 11684f6..637e609 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper003.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper003.cs @@ -1,15 +1,14 @@ -namespace MyNes.Core -{ - [BoardInfo("CNROM", 3)] - internal class Mapper003 : Board - { - private byte data_temp; - - internal override void WritePRG(ref ushort address, ref byte data) - { - ReadPRG(ref address, out data_temp); - data_temp &= data; - Switch08KCHR(data_temp); - } - } +namespace MyNes.Core; + +[BoardInfo("CNROM", 3)] +internal class Mapper003 : Board +{ + private byte data_temp; + + internal override void WritePRG(ref ushort address, ref byte data) + { + ReadPRG(ref address, out data_temp); + data_temp &= data; + Switch08KCHR(data_temp); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper004.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper004.cs index 785b24e..ed5dfd0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper004.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper004.cs @@ -1,224 +1,223 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("MMC3", 4, true, true)] - internal class Mapper004 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - mmc3_alt_behavior = false; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Tracer.WriteWarning("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Tracer.WriteWarning("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Tracer.WriteWarning("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WritePRG(ref ushort addr, ref byte val) - { - switch (addr & 0xE001) - { - case 32768: - address_8001 = val & 7; - flag_c = (val & 0x80) != 0; - flag_p = (val & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = val; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = val & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((val & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((val & 0x80) != 0); - TogglePRGRAMWritableEnable((val & 0x40) == 0); - break; - case 49152: - irq_reload = val; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter bin) - { - base.WriteStateData(ref bin); - bin.Write(flag_c); - bin.Write(flag_p); - bin.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - bin.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - bin.Write(prg_reg[j]); - } - bin.Write(irq_enabled); - bin.Write(irq_counter); - bin.Write(old_irq_counter); - bin.Write(irq_reload); - bin.Write(irq_clear); - bin.Write(mmc3_alt_behavior); - } - - internal override void ReadStateData(ref BinaryReader bin) - { - base.ReadStateData(ref bin); - flag_c = bin.ReadBoolean(); - flag_p = bin.ReadBoolean(); - address_8001 = bin.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = bin.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = bin.ReadInt32(); - } - irq_enabled = bin.ReadBoolean(); - irq_counter = bin.ReadByte(); - old_irq_counter = bin.ReadInt32(); - irq_reload = bin.ReadByte(); - irq_clear = bin.ReadBoolean(); - mmc3_alt_behavior = bin.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("MMC3", 4, true, true)] +internal class Mapper004 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + mmc3_alt_behavior = false; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Tracer.WriteWarning("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Tracer.WriteWarning("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Tracer.WriteWarning("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WritePRG(ref ushort addr, ref byte val) + { + switch (addr & 0xE001) + { + case 32768: + address_8001 = val & 7; + flag_c = (val & 0x80) != 0; + flag_p = (val & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = val; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = val & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((val & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((val & 0x80) != 0); + TogglePRGRAMWritableEnable((val & 0x40) == 0); + break; + case 49152: + irq_reload = val; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter bin) + { + base.WriteStateData(ref bin); + bin.Write(flag_c); + bin.Write(flag_p); + bin.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + bin.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + bin.Write(prg_reg[j]); + } + bin.Write(irq_enabled); + bin.Write(irq_counter); + bin.Write(old_irq_counter); + bin.Write(irq_reload); + bin.Write(irq_clear); + bin.Write(mmc3_alt_behavior); + } + + internal override void ReadStateData(ref BinaryReader bin) + { + base.ReadStateData(ref bin); + flag_c = bin.ReadBoolean(); + flag_p = bin.ReadBoolean(); + address_8001 = bin.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = bin.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = bin.ReadInt32(); + } + irq_enabled = bin.ReadBoolean(); + irq_counter = bin.ReadByte(); + old_irq_counter = bin.ReadInt32(); + irq_reload = bin.ReadByte(); + irq_clear = bin.ReadBoolean(); + mmc3_alt_behavior = bin.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper005.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper005.cs index d9f8a48..4f0f00b 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper005.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper005.cs @@ -1,890 +1,869 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("MMC5", 5, 8, 16)] - [WithExternalSound] - [HassIssues] - internal class Mapper005 : Board - { - private int ram_protectA; - - private int ram_protectB; - - private int ExRAM_mode; - - private int[] CHROffset_spr; - - private int[] CHROffsetEX; - - private int[] CHROffsetSP; - - private int[] chrRegA; - - private int[] chrRegB; - - private int[] prgReg; - - private bool useSRAMmirroring; - - private int chr_high; - - private int chr_mode; - - private int prg_mode; - - private bool chr_setB_last; - - private byte temp_val; - - private byte temp_fill; - - private int lastAccessVRAM; - - private int paletteNo; - - private int shift; - - private int EXtilenumber; - - private byte multiplicand; - - private byte multiplier; - - private ushort product; - - private bool split_enable; - - private bool split_right; - - private int split_tile; - - private int split_yscroll; - - private bool split_doit; - - private int split_watch_tile; - - private byte irq_line; - - private byte irq_enable; - - private int irq_pending; - - private int irq_current_counter; - - private int irq_current_inframe; - - private MMC5Sqr snd_1; - - private MMC5Sqr snd_2; - - private MMC5Pcm snd_3; - - private double[][][][][] mix_table; - - internal override string Issues => MNInterfaceLanguage.IssueMapper5; - - internal override void Initialize(IRom rom) - { - base.Initialize(rom); - snd_1 = new MMC5Sqr(); - snd_2 = new MMC5Sqr(); - snd_3 = new MMC5Pcm(); - mix_table = new double[16][][][][]; - for (int i = 0; i < 16; i++) - { - mix_table[i] = new double[16][][][]; - for (int j = 0; j < 16; j++) - { - mix_table[i][j] = new double[16][][]; - for (int k = 0; k < 16; k++) - { - mix_table[i][j][k] = new double[16][]; - for (int l = 0; l < 16; l++) - { - mix_table[i][j][k][l] = new double[256]; - for (int m = 0; m < 256; m++) - { - double num = 95.88 / (8128.0 / (double)(i + j) + 100.0); - double num2 = 159.79 / (1.0 / ((double)k / 8227.0 + (double)l / 12241.0 + (double)m / 22638.0) + 100.0); - mix_table[i][j][k][l][m] = num + num2; - } - } - } - } - } - } - - internal override void HardReset() - { - base.HardReset(); - string text = SHA1.ToUpper(); - string text2 = text; - if (!(text2 == "37267833C984F176DB4B0BC9D45DABA0FFF45304")) - { - if (text2 == "800AEFE756E85A0A78CCB4DAE68EBBA5DF24BF41") - { - useSRAMmirroring = true; - } - } - else - { - useSRAMmirroring = true; - } - Console.WriteLine("MMC5: using PRG RAM mirroring = " + useSRAMmirroring); - CHROffset_spr = new int[8]; - CHROffsetEX = new int[8]; - CHROffsetSP = new int[8]; - chrRegA = new int[8]; - chrRegB = new int[4]; - prgReg = new int[4]; - prgReg[3] = PRG_ROM_08KB_Mask; - prg_mode = 3; - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.Area8000); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaA000); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaC000); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - Switch04kCHREX(0, 0); - Switch04kCHRSP(0, 0); - Switch08kCHR_spr(0); - TogglePRGRAMWritableEnable(enable: true); - TogglePRGRAMEnable(enable: true); - APUApplyChannelsSettings(); - snd_1.HardReset(); - snd_2.HardReset(); - snd_3.HardReset(); - } - - internal override void SoftReset() - { - base.SoftReset(); - snd_1.SoftReset(); - snd_2.SoftReset(); - snd_3.SoftReset(); - } - - internal override void WriteEX(ref ushort address, ref byte value) - { - if (address >= 23552) - { - if (ExRAM_mode == 2) - { - NMT_RAM[2][address & 0x3FF] = value; - } - else if (ExRAM_mode < 2) - { - if (irq_current_inframe == 64) - { - NMT_RAM[2][address & 0x3FF] = value; - } - else - { - NMT_RAM[2][address & 0x3FF] = 0; - } - } - return; - } - switch (address) - { - case 20480: - snd_1.Write0(ref value); - break; - case 20482: - snd_1.Write2(ref value); - break; - case 20483: - snd_1.Write3(ref value); - break; - case 20484: - snd_2.Write0(ref value); - break; - case 20486: - snd_2.Write2(ref value); - break; - case 20487: - snd_2.Write3(ref value); - break; - case 20496: - snd_3.Write5010(value); - break; - case 20497: - snd_3.Write5011(value); - break; - case 20501: - snd_1.WriteEnabled((value & 1) != 0); - snd_2.WriteEnabled((value & 2) != 0); - break; - case 20736: - prg_mode = value & 3; - break; - case 20737: - chr_mode = value & 3; - break; - case 20738: - ram_protectA = value & 3; - UpdateRamProtect(); - break; - case 20739: - ram_protectB = value & 3; - UpdateRamProtect(); - break; - case 20740: - ExRAM_mode = value & 3; - break; - case 20741: - Switch01KNMT(value); - break; - case 20755: - if (!useSRAMmirroring) - { - Switch08KPRG(value & 7, PRGArea.Area6000); - } - else - { - Switch08KPRG((value >> 2) & 1, PRGArea.Area6000); - } - break; - case 20756: - if (prg_mode == 3) - { - Toggle08KPRG_RAM((value & 0x80) == 0, PRGArea.Area8000); - Switch08KPRG(value & 0x7F, PRGArea.Area8000); - } - break; - case 20757: - switch (prg_mode) - { - case 1: - Toggle16KPRG_RAM((value & 0x80) == 0, PRGArea.Area8000); - Switch16KPRG((value & 0x7F) >> 1, PRGArea.Area8000); - break; - case 2: - Toggle16KPRG_RAM((value & 0x80) == 0, PRGArea.Area8000); - Switch16KPRG((value & 0x7F) >> 1, PRGArea.Area8000); - break; - case 3: - Toggle08KPRG_RAM((value & 0x80) == 0, PRGArea.AreaA000); - Switch08KPRG(value & 0x7F, PRGArea.AreaA000); - break; - } - break; - case 20758: - { - int num = prg_mode; - int num2 = num; - if ((uint)(num2 - 2) <= 1u) - { - Toggle08KPRG_RAM((value & 0x80) == 0, PRGArea.AreaC000); - Switch08KPRG(value & 0x7F, PRGArea.AreaC000); - } - break; - } - case 20759: - switch (prg_mode) - { - case 0: - Switch32KPRG((value & 0x7C) >> 2, PRGArea.Area8000); - break; - case 1: - Switch16KPRG((value & 0x7F) >> 1, PRGArea.AreaC000); - break; - case 2: - Switch08KPRG(value & 0x7F, PRGArea.AreaE000); - break; - case 3: - Switch08KPRG(value & 0x7F, PRGArea.AreaE000); - break; - } - break; - case 20768: - chr_setB_last = false; - if (chr_mode == 3) - { - Switch01kCHR_spr(value | chr_high, 0); - } - break; - case 20769: - chr_setB_last = false; - switch (chr_mode) - { - case 2: - Switch02kCHR_spr(value | chr_high, 0); - break; - case 3: - Switch01kCHR_spr(value | chr_high, 1024); - break; - } - break; - case 20770: - chr_setB_last = false; - if (chr_mode == 3) - { - Switch01kCHR_spr(value | chr_high, 2048); - } - break; - case 20771: - chr_setB_last = false; - switch (chr_mode) - { - case 1: - Switch04kCHR_spr(value | chr_high, 0); - break; - case 2: - Switch02kCHR_spr(value | chr_high, 2048); - break; - case 3: - Switch01kCHR_spr(value | chr_high, 3072); - break; - } - break; - case 20772: - chr_setB_last = false; - if (chr_mode == 3) - { - Switch01kCHR_spr(value | chr_high, 4096); - } - break; - case 20773: - chr_setB_last = false; - switch (chr_mode) - { - case 2: - Switch02kCHR_spr(value | chr_high, 4096); - break; - case 3: - Switch01kCHR_spr(value | chr_high, 5120); - break; - } - break; - case 20774: - chr_setB_last = false; - if (chr_mode == 3) - { - Switch01kCHR_spr(value | chr_high, 6144); - } - break; - case 20775: - chr_setB_last = false; - switch (chr_mode) - { - case 0: - Switch08kCHR_spr(value | chr_high); - break; - case 1: - Switch04kCHR_spr(value | chr_high, 4096); - break; - case 2: - Switch02kCHR_spr(value | chr_high, 6144); - break; - case 3: - Switch01kCHR_spr(value | chr_high, 7168); - break; - } - break; - case 20776: - chr_setB_last = true; - if (chr_mode == 3) - { - Switch01KCHR(value | chr_high, CHRArea.Area0000); - Switch01KCHR(value | chr_high, CHRArea.Area1000); - } - break; - case 20777: - chr_setB_last = true; - switch (chr_mode) - { - case 2: - Switch02KCHR(value | chr_high, CHRArea.Area0000); - Switch02KCHR(value | chr_high, CHRArea.Area1000); - break; - case 3: - Switch01KCHR(value | chr_high, CHRArea.Area0400); - Switch01KCHR(value | chr_high, CHRArea.Area1400); - break; - } - break; - case 20778: - chr_setB_last = true; - if (chr_mode == 3) - { - Switch01KCHR(value | chr_high, CHRArea.Area0800); - Switch01KCHR(value | chr_high, CHRArea.Area1800); - } - break; - case 20779: - chr_setB_last = true; - switch (chr_mode) - { - case 0: - Switch04kCHR_bkg(value | chr_high, 0); - Switch04kCHR_bkg(value | chr_high, 4096); - break; - case 1: - Switch04KCHR(value | chr_high, CHRArea.Area0000); - Switch04KCHR(value | chr_high, CHRArea.Area1000); - break; - case 2: - Switch02KCHR(value | chr_high, CHRArea.Area0800); - Switch02KCHR(value | chr_high, CHRArea.Area1800); - break; - case 3: - Switch01KCHR(value | chr_high, CHRArea.Area0C00); - Switch01KCHR(value | chr_high, CHRArea.Area1C00); - break; - } - break; - case 20784: - chr_high = (value & 3) << 8; - break; - case 20742: - { - for (int j = 0; j < 960; j++) - { - NMT_RAM[3][j] = value; - } - break; - } - case 20743: - { - for (int i = 960; i < 1024; i++) - { - temp_fill = (byte)((uint)(2 << (value & 3)) | (value & 3u)); - temp_fill |= (byte)((temp_fill & 0xF) << 4); - NMT_RAM[3][i] = temp_fill; - } - break; - } - case 20992: - split_tile = value & 0x1F; - split_enable = (value & 0x80) == 128; - split_right = (value & 0x40) == 64; - break; - case 20993: - split_yscroll = value; - break; - case 20994: - Switch04kCHRSP(value, address & 0); - Switch04kCHRSP(value, address & 0x1000); - break; - case 20995: - irq_line = value; - break; - case 20996: - irq_enable = value; - break; - case 20997: - multiplicand = value; - product = (ushort)(multiplicand * multiplier); - break; - case 20998: - multiplier = value; - product = (ushort)(multiplicand * multiplier); - break; - } - } - - internal override void ReadEX(ref ushort address, out byte data) - { - if (address >= 23552 && ExRAM_mode >= 2) - { - data = NMT_RAM[2][address & 0x3FF]; - return; - } - switch (address) - { - case 20496: - data = snd_3.Read5010(); - break; - case 20996: - data = (byte)(irq_current_inframe | irq_pending); - irq_pending = 0; - NesEmu.IRQFlags &= -9; - break; - case 20997: - data = (byte)(product & 0xFFu); - break; - case 20998: - data = (byte)((product & 0xFF00) >> 8); - break; - case 20501: - data = (byte)((snd_1.ReadEnable() ? 1u : 0u) | (snd_2.ReadEnable() ? 2u : 0u)); - data = 0; - break; - default: - data = 0; - break; - } - } - - internal override void ReadCHR(ref ushort address, out byte data) - { - if (!NesEmu.ppu_is_sprfetch && split_enable && ExRAM_mode < 2) - { - split_watch_tile = address & 0x3F; - if (!split_right) - { - split_doit = split_watch_tile < split_tile; - } - else - { - split_doit = split_watch_tile >= split_tile; - } - if (!split_doit) - { - } - } - if (ExRAM_mode == 1) - { - if (!NesEmu.ppu_is_sprfetch) - { - EXtilenumber = NMT_RAM[2][lastAccessVRAM] & 0x3F; - Switch04kCHREX(EXtilenumber | chr_high, address & 0x1000); - data = CHR_ROM[CHROffsetEX[(address >> 10) & 7]][address & 0x3FF]; - } - else - { - data = CHR_ROM[CHROffset_spr[(address >> 10) & 7]][address & 0x3FF]; - } - } - else if (NesEmu.ppu_reg_2000_Sprite_size == 16) - { - if (!NesEmu.ppu_is_sprfetch) - { - data = CHR_ROM[CHR_AREA_BLK_INDEX[(address >> 10) & 7]][address & 0x3FF]; - } - else - { - data = CHR_ROM[CHROffset_spr[(address >> 10) & 7]][address & 0x3FF]; - } - } - else if (chr_setB_last) - { - data = CHR_ROM[CHR_AREA_BLK_INDEX[(address >> 10) & 7]][address & 0x3FF]; - } - else - { - data = CHR_ROM[CHROffset_spr[(address >> 10) & 7]][address & 0x3FF]; - } - } - - internal override void ReadNMT(ref ushort address, out byte data) - { - if (split_doit) - { - } - if (ExRAM_mode == 1) - { - if ((address & 0x3FF) <= 959) - { - lastAccessVRAM = address & 0x3FF; - } - else - { - paletteNo = NMT_RAM[2][lastAccessVRAM] & 0xC0; - shift = ((lastAccessVRAM >> 4) & 4) | (lastAccessVRAM & 2); - switch (shift) - { - case 0: - data = (byte)(paletteNo >> 6); - return; - case 2: - data = (byte)(paletteNo >> 4); - return; - case 4: - data = (byte)(paletteNo >> 2); - return; - case 6: - data = (byte)paletteNo; - return; - } - } - } - data = NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF]; - } - - internal override void WriteNMT(ref ushort address, ref byte value) - { - if (ExRAM_mode == 1 && (address & 0x3FF) <= 959) - { - lastAccessVRAM = address & 0x3FF; - } - NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF] = value; - } - - private void UpdateRamProtect() - { - TogglePRGRAMWritableEnable(ram_protectA == 2 && ram_protectB == 1); - } - - private void Switch04kCHR_bkg(int index, int where) - { - int num = (where >> 10) & 7; - index <<= 2; - CHR_AREA_BLK_INDEX[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHR_AREA_BLK_INDEX[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHR_AREA_BLK_INDEX[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHR_AREA_BLK_INDEX[num] = index & CHR_ROM_01KB_Mask; - } - - private void Switch01kCHR_spr(int index, int where) - { - CHROffset_spr[(where >> 10) & 7] = index & CHR_ROM_01KB_Mask; - } - - private void Switch02kCHR_spr(int index, int where) - { - int num = (where >> 10) & 7; - index <<= 1; - CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; - index++; - CHROffset_spr[num + 1] = index & CHR_ROM_01KB_Mask; - } - - private void Switch04kCHR_spr(int index, int where) - { - int num = (where >> 10) & 7; - index <<= 2; - CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; - } - - private void Switch08kCHR_spr(int index) - { - index <<= 3; - CHROffset_spr[0] = index & CHR_ROM_01KB_Mask; - index++; - CHROffset_spr[1] = index & CHR_ROM_01KB_Mask; - index++; - CHROffset_spr[2] = index & CHR_ROM_01KB_Mask; - index++; - CHROffset_spr[3] = index & CHR_ROM_01KB_Mask; - index++; - CHROffset_spr[4] = index & CHR_ROM_01KB_Mask; - index++; - CHROffset_spr[5] = index & CHR_ROM_01KB_Mask; - index++; - CHROffset_spr[6] = index & CHR_ROM_01KB_Mask; - index++; - CHROffset_spr[7] = index & CHR_ROM_01KB_Mask; - } - - private void Switch04kCHREX(int index, int where) - { - int num = (where >> 10) & 7; - index <<= 2; - CHROffsetEX[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffsetEX[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffsetEX[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffsetEX[num] = index & CHR_ROM_01KB_Mask; - } - - private void Switch04kCHRSP(int index, int where) - { - int num = (where >> 10) & 7; - index <<= 2; - CHROffsetSP[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffsetSP[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffsetSP[num] = index & CHR_ROM_01KB_Mask; - num++; - index++; - CHROffsetSP[num] = index & CHR_ROM_01KB_Mask; - } - - internal override void OnPPUScanlineTick() - { - irq_current_inframe = ((NesEmu.IsInRender() && NesEmu.IsRenderingOn()) ? 64 : 0); - if (irq_current_inframe == 0) - { - irq_current_inframe = 64; - irq_current_counter = 0; - irq_pending = 0; - NesEmu.IRQFlags &= -9; - return; - } - irq_current_counter++; - if (irq_current_counter == irq_line) - { - irq_pending = 128; - if (irq_enable == 128) - { - NesEmu.IRQFlags |= 8; - } - } - } - - internal override void OnAPUClock() - { - base.OnAPUClock(); - snd_1.Clock(); - snd_2.Clock(); - } - - internal override void OnAPUClockEnvelope() - { - base.OnAPUClockEnvelope(); - snd_1.ClockLength(); - snd_2.ClockLength(); - snd_1.ClockEnvelope(); - snd_2.ClockEnvelope(); - } - - internal override double APUGetSample() - { - return mix_table[snd_1.output][snd_2.output][0][0][snd_3.output]; - } - - internal override void APUApplyChannelsSettings() - { - base.APUApplyChannelsSettings(); - snd_1.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_MMC5_SQ1; - snd_2.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_MMC5_SQ2; - snd_3.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_MMC5_PCM; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(ram_protectA); - stream.Write(ram_protectB); - stream.Write(ExRAM_mode); - for (int i = 0; i < CHROffset_spr.Length; i++) - { - stream.Write(CHROffset_spr[i]); - } - for (int j = 0; j < CHROffsetEX.Length; j++) - { - stream.Write(CHROffsetEX[j]); - } - for (int k = 0; k < CHROffsetSP.Length; k++) - { - stream.Write(CHROffsetSP[k]); - } - for (int l = 0; l < chrRegA.Length; l++) - { - stream.Write(chrRegA[l]); - } - for (int m = 0; m < chrRegB.Length; m++) - { - stream.Write(chrRegB[m]); - } - for (int n = 0; n < prgReg.Length; n++) - { - stream.Write(prgReg[n]); - } - stream.Write(useSRAMmirroring); - stream.Write(chr_high); - stream.Write(chr_mode); - stream.Write(prg_mode); - stream.Write(chr_setB_last); - stream.Write(temp_val); - stream.Write(temp_fill); - stream.Write(lastAccessVRAM); - stream.Write(paletteNo); - stream.Write(shift); - stream.Write(EXtilenumber); - stream.Write(multiplicand); - stream.Write(multiplier); - stream.Write(product); - stream.Write(split_enable); - stream.Write(split_right); - stream.Write(split_tile); - stream.Write(split_yscroll); - stream.Write(split_doit); - stream.Write(split_watch_tile); - stream.Write(irq_line); - stream.Write(irq_enable); - stream.Write(irq_pending); - stream.Write(irq_current_counter); - stream.Write(irq_current_inframe); - snd_1.WriteStateData(ref stream); - snd_2.WriteStateData(ref stream); - snd_3.SaveState(ref stream); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - ram_protectA = stream.ReadInt32(); - ram_protectB = stream.ReadInt32(); - ExRAM_mode = stream.ReadInt32(); - for (int i = 0; i < CHROffset_spr.Length; i++) - { - CHROffset_spr[i] = stream.ReadInt32(); - } - for (int j = 0; j < CHROffsetEX.Length; j++) - { - CHROffsetEX[j] = stream.ReadInt32(); - } - for (int k = 0; k < CHROffsetSP.Length; k++) - { - CHROffsetSP[k] = stream.ReadInt32(); - } - for (int l = 0; l < chrRegA.Length; l++) - { - chrRegA[l] = stream.ReadInt32(); - } - for (int m = 0; m < chrRegB.Length; m++) - { - chrRegB[m] = stream.ReadInt32(); - } - for (int n = 0; n < prgReg.Length; n++) - { - prgReg[n] = stream.ReadInt32(); - } - useSRAMmirroring = stream.ReadBoolean(); - chr_high = stream.ReadInt32(); - chr_mode = stream.ReadInt32(); - prg_mode = stream.ReadInt32(); - chr_setB_last = stream.ReadBoolean(); - temp_val = stream.ReadByte(); - temp_fill = stream.ReadByte(); - lastAccessVRAM = stream.ReadInt32(); - paletteNo = stream.ReadInt32(); - shift = stream.ReadInt32(); - EXtilenumber = stream.ReadInt32(); - multiplicand = stream.ReadByte(); - multiplier = stream.ReadByte(); - product = stream.ReadUInt16(); - split_enable = stream.ReadBoolean(); - split_right = stream.ReadBoolean(); - split_tile = stream.ReadInt32(); - split_yscroll = stream.ReadInt32(); - split_doit = stream.ReadBoolean(); - split_watch_tile = stream.ReadInt32(); - irq_line = stream.ReadByte(); - irq_enable = stream.ReadByte(); - irq_pending = stream.ReadInt32(); - irq_current_counter = stream.ReadInt32(); - irq_current_inframe = stream.ReadInt32(); - snd_1.ReadStateData(ref stream); - snd_2.ReadStateData(ref stream); - snd_3.LoadState(ref stream); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("MMC5", 5, 8, 16)] +[WithExternalSound] +[HassIssues] +internal class Mapper005 : Board +{ + private int ram_protectA; + + private int ram_protectB; + + private int ExRAM_mode; + + private int[] CHROffset_spr; + + private int[] CHROffsetEX; + + private int[] CHROffsetSP; + + private int[] chrRegA; + + private int[] chrRegB; + + private int[] prgReg; + + private bool useSRAMmirroring; + + private int chr_high; + + private int chr_mode; + + private int prg_mode; + + private bool chr_setB_last; + + private byte temp_val; + + private byte temp_fill; + + private int lastAccessVRAM; + + private int paletteNo; + + private int shift; + + private int EXtilenumber; + + private byte multiplicand; + + private byte multiplier; + + private ushort product; + + private bool split_enable; + + private bool split_right; + + private int split_tile; + + private int split_yscroll; + + private bool split_doit; + + private int split_watch_tile; + + private byte irq_line; + + private byte irq_enable; + + private int irq_pending; + + private int irq_current_counter; + + private int irq_current_inframe; + + private MMC5Sqr snd_1; + + private MMC5Sqr snd_2; + + private MMC5Pcm snd_3; + + private double[] audio_pulse_table; + + private double[] audio_tnd_table; + + internal override string Issues => MNInterfaceLanguage.IssueMapper5; + + internal override void Initialize(IRom rom) + { + base.Initialize(rom); + snd_1 = new MMC5Sqr(); + snd_2 = new MMC5Sqr(); + snd_3 = new MMC5Pcm(); + audio_pulse_table = new double[32]; + for (int i = 0; i < 32; i++) + { + audio_pulse_table[i] = 95.52 / (8128.0 / (double)i + 100.0); + } + audio_tnd_table = new double[204]; + for (int j = 0; j < 204; j++) + { + audio_tnd_table[j] = 163.67 / (24329.0 / (double)j + 100.0); + } + } + + internal override void HardReset() + { + base.HardReset(); + switch (SHA1.ToUpper()) + { + case "37267833C984F176DB4B0BC9D45DABA0FFF45304": + useSRAMmirroring = true; + break; + case "800AEFE756E85A0A78CCB4DAE68EBBA5DF24BF41": + useSRAMmirroring = true; + break; + } + Console.WriteLine("MMC5: using PRG RAM mirroring = " + useSRAMmirroring); + CHROffset_spr = new int[8]; + CHROffsetEX = new int[8]; + CHROffsetSP = new int[8]; + chrRegA = new int[8]; + chrRegB = new int[4]; + prgReg = new int[4]; + prgReg[3] = PRG_ROM_08KB_Mask; + prg_mode = 3; + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.Area8000); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaA000); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaC000); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + Switch04kCHREX(0, 0); + Switch04kCHRSP(0, 0); + Switch08kCHR_spr(0); + TogglePRGRAMWritableEnable(enable: true); + TogglePRGRAMEnable(enable: true); + APUApplyChannelsSettings(); + snd_1.HardReset(); + snd_2.HardReset(); + snd_3.HardReset(); + } + + internal override void SoftReset() + { + base.SoftReset(); + snd_1.SoftReset(); + snd_2.SoftReset(); + snd_3.SoftReset(); + } + + internal override void WriteEX(ref ushort address, ref byte value) + { + if (address >= 23552) + { + if (ExRAM_mode == 2) + { + NMT_RAM[2][address & 0x3FF] = value; + } + else if (ExRAM_mode < 2) + { + if (irq_current_inframe == 64) + { + NMT_RAM[2][address & 0x3FF] = value; + } + else + { + NMT_RAM[2][address & 0x3FF] = 0; + } + } + return; + } + switch (address) + { + case 20480: + snd_1.Write0(ref value); + break; + case 20482: + snd_1.Write2(ref value); + break; + case 20483: + snd_1.Write3(ref value); + break; + case 20484: + snd_2.Write0(ref value); + break; + case 20486: + snd_2.Write2(ref value); + break; + case 20487: + snd_2.Write3(ref value); + break; + case 20496: + snd_3.Write5010(value); + break; + case 20497: + snd_3.Write5011(value); + break; + case 20501: + snd_1.WriteEnabled((value & 1) != 0); + snd_2.WriteEnabled((value & 2) != 0); + break; + case 20736: + prg_mode = value & 3; + break; + case 20737: + chr_mode = value & 3; + break; + case 20738: + ram_protectA = value & 3; + UpdateRamProtect(); + break; + case 20739: + ram_protectB = value & 3; + UpdateRamProtect(); + break; + case 20740: + ExRAM_mode = value & 3; + break; + case 20741: + Switch01KNMT(value); + break; + case 20755: + if (!useSRAMmirroring) + { + Switch08KPRG(value & 7, PRGArea.Area6000); + } + else + { + Switch08KPRG((value >> 2) & 1, PRGArea.Area6000); + } + break; + case 20756: + if (prg_mode == 3) + { + Toggle08KPRG_RAM((value & 0x80) == 0, PRGArea.Area8000); + Switch08KPRG(value & 0x7F, PRGArea.Area8000); + } + break; + case 20757: + switch (prg_mode) + { + case 1: + Toggle16KPRG_RAM((value & 0x80) == 0, PRGArea.Area8000); + Switch16KPRG((value & 0x7F) >> 1, PRGArea.Area8000); + break; + case 2: + Toggle16KPRG_RAM((value & 0x80) == 0, PRGArea.Area8000); + Switch16KPRG((value & 0x7F) >> 1, PRGArea.Area8000); + break; + case 3: + Toggle08KPRG_RAM((value & 0x80) == 0, PRGArea.AreaA000); + Switch08KPRG(value & 0x7F, PRGArea.AreaA000); + break; + } + break; + case 20758: + { + int num = prg_mode; + if ((uint)(num - 2) <= 1u) + { + Toggle08KPRG_RAM((value & 0x80) == 0, PRGArea.AreaC000); + Switch08KPRG(value & 0x7F, PRGArea.AreaC000); + } + break; + } + case 20759: + switch (prg_mode) + { + case 0: + Switch32KPRG((value & 0x7C) >> 2, PRGArea.Area8000); + break; + case 1: + Switch16KPRG((value & 0x7F) >> 1, PRGArea.AreaC000); + break; + case 2: + Switch08KPRG(value & 0x7F, PRGArea.AreaE000); + break; + case 3: + Switch08KPRG(value & 0x7F, PRGArea.AreaE000); + break; + } + break; + case 20768: + chr_setB_last = false; + if (chr_mode == 3) + { + Switch01kCHR_spr(value | chr_high, 0); + } + break; + case 20769: + chr_setB_last = false; + switch (chr_mode) + { + case 2: + Switch02kCHR_spr(value | chr_high, 0); + break; + case 3: + Switch01kCHR_spr(value | chr_high, 1024); + break; + } + break; + case 20770: + chr_setB_last = false; + if (chr_mode == 3) + { + Switch01kCHR_spr(value | chr_high, 2048); + } + break; + case 20771: + chr_setB_last = false; + switch (chr_mode) + { + case 1: + Switch04kCHR_spr(value | chr_high, 0); + break; + case 2: + Switch02kCHR_spr(value | chr_high, 2048); + break; + case 3: + Switch01kCHR_spr(value | chr_high, 3072); + break; + } + break; + case 20772: + chr_setB_last = false; + if (chr_mode == 3) + { + Switch01kCHR_spr(value | chr_high, 4096); + } + break; + case 20773: + chr_setB_last = false; + switch (chr_mode) + { + case 2: + Switch02kCHR_spr(value | chr_high, 4096); + break; + case 3: + Switch01kCHR_spr(value | chr_high, 5120); + break; + } + break; + case 20774: + chr_setB_last = false; + if (chr_mode == 3) + { + Switch01kCHR_spr(value | chr_high, 6144); + } + break; + case 20775: + chr_setB_last = false; + switch (chr_mode) + { + case 0: + Switch08kCHR_spr(value | chr_high); + break; + case 1: + Switch04kCHR_spr(value | chr_high, 4096); + break; + case 2: + Switch02kCHR_spr(value | chr_high, 6144); + break; + case 3: + Switch01kCHR_spr(value | chr_high, 7168); + break; + } + break; + case 20776: + chr_setB_last = true; + if (chr_mode == 3) + { + Switch01KCHR(value | chr_high, CHRArea.Area0000); + Switch01KCHR(value | chr_high, CHRArea.Area1000); + } + break; + case 20777: + chr_setB_last = true; + switch (chr_mode) + { + case 2: + Switch02KCHR(value | chr_high, CHRArea.Area0000); + Switch02KCHR(value | chr_high, CHRArea.Area1000); + break; + case 3: + Switch01KCHR(value | chr_high, CHRArea.Area0400); + Switch01KCHR(value | chr_high, CHRArea.Area1400); + break; + } + break; + case 20778: + chr_setB_last = true; + if (chr_mode == 3) + { + Switch01KCHR(value | chr_high, CHRArea.Area0800); + Switch01KCHR(value | chr_high, CHRArea.Area1800); + } + break; + case 20779: + chr_setB_last = true; + switch (chr_mode) + { + case 0: + Switch04kCHR_bkg(value | chr_high, 0); + Switch04kCHR_bkg(value | chr_high, 4096); + break; + case 1: + Switch04KCHR(value | chr_high, CHRArea.Area0000); + Switch04KCHR(value | chr_high, CHRArea.Area1000); + break; + case 2: + Switch02KCHR(value | chr_high, CHRArea.Area0800); + Switch02KCHR(value | chr_high, CHRArea.Area1800); + break; + case 3: + Switch01KCHR(value | chr_high, CHRArea.Area0C00); + Switch01KCHR(value | chr_high, CHRArea.Area1C00); + break; + } + break; + case 20784: + chr_high = (value & 3) << 8; + break; + case 20742: + { + for (int j = 0; j < 960; j++) + { + NMT_RAM[3][j] = value; + } + break; + } + case 20743: + { + for (int i = 960; i < 1024; i++) + { + temp_fill = (byte)((uint)(2 << (value & 3)) | (value & 3u)); + temp_fill |= (byte)((temp_fill & 0xF) << 4); + NMT_RAM[3][i] = temp_fill; + } + break; + } + case 20992: + split_tile = value & 0x1F; + split_enable = (value & 0x80) == 128; + split_right = (value & 0x40) == 64; + break; + case 20993: + split_yscroll = value; + break; + case 20994: + Switch04kCHRSP(value, address & 0); + Switch04kCHRSP(value, address & 0x1000); + break; + case 20995: + irq_line = value; + break; + case 20996: + irq_enable = value; + break; + case 20997: + multiplicand = value; + product = (ushort)(multiplicand * multiplier); + break; + case 20998: + multiplier = value; + product = (ushort)(multiplicand * multiplier); + break; + } + } + + internal override void ReadEX(ref ushort address, out byte data) + { + if (address >= 23552 && ExRAM_mode >= 2) + { + data = NMT_RAM[2][address & 0x3FF]; + return; + } + switch (address) + { + case 20496: + data = snd_3.Read5010(); + break; + case 20996: + data = (byte)(irq_current_inframe | irq_pending); + irq_pending = 0; + NesEmu.IRQFlags &= -9; + break; + case 20997: + data = (byte)(product & 0xFFu); + break; + case 20998: + data = (byte)((product & 0xFF00) >> 8); + break; + case 20501: + data = (byte)((snd_1.ReadEnable() ? 1u : 0u) | (snd_2.ReadEnable() ? 2u : 0u)); + data = 0; + break; + default: + data = 0; + break; + } + } + + internal override void ReadCHR(ref ushort address, out byte data) + { + if (!NesEmu.ppu_is_sprfetch && split_enable && ExRAM_mode < 2) + { + split_watch_tile = address & 0x3F; + if (!split_right) + { + split_doit = split_watch_tile < split_tile; + } + else + { + split_doit = split_watch_tile >= split_tile; + } + _ = split_doit; + } + if (ExRAM_mode == 1) + { + if (!NesEmu.ppu_is_sprfetch) + { + EXtilenumber = NMT_RAM[2][lastAccessVRAM] & 0x3F; + Switch04kCHREX(EXtilenumber | chr_high, address & 0x1000); + data = CHR_ROM[CHROffsetEX[(address >> 10) & 7]][address & 0x3FF]; + } + else + { + data = CHR_ROM[CHROffset_spr[(address >> 10) & 7]][address & 0x3FF]; + } + } + else if (NesEmu.ppu_reg_2000_Sprite_size == 16) + { + if (!NesEmu.ppu_is_sprfetch) + { + data = CHR_ROM[CHR_AREA_BLK_INDEX[(address >> 10) & 7]][address & 0x3FF]; + } + else + { + data = CHR_ROM[CHROffset_spr[(address >> 10) & 7]][address & 0x3FF]; + } + } + else if (chr_setB_last) + { + data = CHR_ROM[CHR_AREA_BLK_INDEX[(address >> 10) & 7]][address & 0x3FF]; + } + else + { + data = CHR_ROM[CHROffset_spr[(address >> 10) & 7]][address & 0x3FF]; + } + } + + internal override void ReadNMT(ref ushort address, out byte data) + { + _ = split_doit; + if (ExRAM_mode == 1) + { + if ((address & 0x3FF) <= 959) + { + lastAccessVRAM = address & 0x3FF; + } + else + { + paletteNo = NMT_RAM[2][lastAccessVRAM] & 0xC0; + shift = ((lastAccessVRAM >> 4) & 4) | (lastAccessVRAM & 2); + switch (shift) + { + case 0: + data = (byte)(paletteNo >> 6); + return; + case 2: + data = (byte)(paletteNo >> 4); + return; + case 4: + data = (byte)(paletteNo >> 2); + return; + case 6: + data = (byte)paletteNo; + return; + } + } + } + data = NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF]; + } + + internal override void WriteNMT(ref ushort address, ref byte value) + { + if (ExRAM_mode == 1 && (address & 0x3FF) <= 959) + { + lastAccessVRAM = address & 0x3FF; + } + NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF] = value; + } + + private void UpdateRamProtect() + { + TogglePRGRAMWritableEnable(ram_protectA == 2 && ram_protectB == 1); + } + + private void Switch04kCHR_bkg(int index, int where) + { + int num = (where >> 10) & 7; + index <<= 2; + CHR_AREA_BLK_INDEX[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHR_AREA_BLK_INDEX[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHR_AREA_BLK_INDEX[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHR_AREA_BLK_INDEX[num] = index & CHR_ROM_01KB_Mask; + } + + private void Switch01kCHR_spr(int index, int where) + { + CHROffset_spr[(where >> 10) & 7] = index & CHR_ROM_01KB_Mask; + } + + private void Switch02kCHR_spr(int index, int where) + { + int num = (where >> 10) & 7; + index <<= 1; + CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; + index++; + CHROffset_spr[num + 1] = index & CHR_ROM_01KB_Mask; + } + + private void Switch04kCHR_spr(int index, int where) + { + int num = (where >> 10) & 7; + index <<= 2; + CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffset_spr[num] = index & CHR_ROM_01KB_Mask; + } + + private void Switch08kCHR_spr(int index) + { + index <<= 3; + CHROffset_spr[0] = index & CHR_ROM_01KB_Mask; + index++; + CHROffset_spr[1] = index & CHR_ROM_01KB_Mask; + index++; + CHROffset_spr[2] = index & CHR_ROM_01KB_Mask; + index++; + CHROffset_spr[3] = index & CHR_ROM_01KB_Mask; + index++; + CHROffset_spr[4] = index & CHR_ROM_01KB_Mask; + index++; + CHROffset_spr[5] = index & CHR_ROM_01KB_Mask; + index++; + CHROffset_spr[6] = index & CHR_ROM_01KB_Mask; + index++; + CHROffset_spr[7] = index & CHR_ROM_01KB_Mask; + } + + private void Switch04kCHREX(int index, int where) + { + int num = (where >> 10) & 7; + index <<= 2; + CHROffsetEX[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffsetEX[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffsetEX[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffsetEX[num] = index & CHR_ROM_01KB_Mask; + } + + private void Switch04kCHRSP(int index, int where) + { + int num = (where >> 10) & 7; + index <<= 2; + CHROffsetSP[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffsetSP[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffsetSP[num] = index & CHR_ROM_01KB_Mask; + num++; + index++; + CHROffsetSP[num] = index & CHR_ROM_01KB_Mask; + } + + internal override void OnPPUScanlineTick() + { + irq_current_inframe = ((NesEmu.IsInRender() && NesEmu.IsRenderingOn()) ? 64 : 0); + if (irq_current_inframe == 0) + { + irq_current_inframe = 64; + irq_current_counter = 0; + irq_pending = 0; + NesEmu.IRQFlags &= -9; + return; + } + irq_current_counter++; + if (irq_current_counter == irq_line) + { + irq_pending = 128; + if (irq_enable == 128) + { + NesEmu.IRQFlags |= 8; + } + } + } + + internal override void OnAPUClock() + { + base.OnAPUClock(); + snd_1.Clock(); + snd_2.Clock(); + } + + internal override void OnAPUClockEnvelope() + { + base.OnAPUClockEnvelope(); + snd_1.ClockLength(); + snd_2.ClockLength(); + snd_1.ClockEnvelope(); + snd_2.ClockEnvelope(); + } + + internal override double APUGetSample() + { + return audio_pulse_table[snd_1.output + snd_2.output] + audio_tnd_table[snd_3.output]; + } + + internal override void APUApplyChannelsSettings() + { + base.APUApplyChannelsSettings(); + snd_1.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_MMC5_SQ1; + snd_2.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_MMC5_SQ2; + snd_3.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_MMC5_PCM; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(ram_protectA); + stream.Write(ram_protectB); + stream.Write(ExRAM_mode); + for (int i = 0; i < CHROffset_spr.Length; i++) + { + stream.Write(CHROffset_spr[i]); + } + for (int j = 0; j < CHROffsetEX.Length; j++) + { + stream.Write(CHROffsetEX[j]); + } + for (int k = 0; k < CHROffsetSP.Length; k++) + { + stream.Write(CHROffsetSP[k]); + } + for (int l = 0; l < chrRegA.Length; l++) + { + stream.Write(chrRegA[l]); + } + for (int m = 0; m < chrRegB.Length; m++) + { + stream.Write(chrRegB[m]); + } + for (int n = 0; n < prgReg.Length; n++) + { + stream.Write(prgReg[n]); + } + stream.Write(useSRAMmirroring); + stream.Write(chr_high); + stream.Write(chr_mode); + stream.Write(prg_mode); + stream.Write(chr_setB_last); + stream.Write(temp_val); + stream.Write(temp_fill); + stream.Write(lastAccessVRAM); + stream.Write(paletteNo); + stream.Write(shift); + stream.Write(EXtilenumber); + stream.Write(multiplicand); + stream.Write(multiplier); + stream.Write(product); + stream.Write(split_enable); + stream.Write(split_right); + stream.Write(split_tile); + stream.Write(split_yscroll); + stream.Write(split_doit); + stream.Write(split_watch_tile); + stream.Write(irq_line); + stream.Write(irq_enable); + stream.Write(irq_pending); + stream.Write(irq_current_counter); + stream.Write(irq_current_inframe); + snd_1.WriteStateData(ref stream); + snd_2.WriteStateData(ref stream); + snd_3.SaveState(ref stream); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + ram_protectA = stream.ReadInt32(); + ram_protectB = stream.ReadInt32(); + ExRAM_mode = stream.ReadInt32(); + for (int i = 0; i < CHROffset_spr.Length; i++) + { + CHROffset_spr[i] = stream.ReadInt32(); + } + for (int j = 0; j < CHROffsetEX.Length; j++) + { + CHROffsetEX[j] = stream.ReadInt32(); + } + for (int k = 0; k < CHROffsetSP.Length; k++) + { + CHROffsetSP[k] = stream.ReadInt32(); + } + for (int l = 0; l < chrRegA.Length; l++) + { + chrRegA[l] = stream.ReadInt32(); + } + for (int m = 0; m < chrRegB.Length; m++) + { + chrRegB[m] = stream.ReadInt32(); + } + for (int n = 0; n < prgReg.Length; n++) + { + prgReg[n] = stream.ReadInt32(); + } + useSRAMmirroring = stream.ReadBoolean(); + chr_high = stream.ReadInt32(); + chr_mode = stream.ReadInt32(); + prg_mode = stream.ReadInt32(); + chr_setB_last = stream.ReadBoolean(); + temp_val = stream.ReadByte(); + temp_fill = stream.ReadByte(); + lastAccessVRAM = stream.ReadInt32(); + paletteNo = stream.ReadInt32(); + shift = stream.ReadInt32(); + EXtilenumber = stream.ReadInt32(); + multiplicand = stream.ReadByte(); + multiplier = stream.ReadByte(); + product = stream.ReadUInt16(); + split_enable = stream.ReadBoolean(); + split_right = stream.ReadBoolean(); + split_tile = stream.ReadInt32(); + split_yscroll = stream.ReadInt32(); + split_doit = stream.ReadBoolean(); + split_watch_tile = stream.ReadInt32(); + irq_line = stream.ReadByte(); + irq_enable = stream.ReadByte(); + irq_pending = stream.ReadInt32(); + irq_current_counter = stream.ReadInt32(); + irq_current_inframe = stream.ReadInt32(); + snd_1.ReadStateData(ref stream); + snd_2.ReadStateData(ref stream); + snd_3.LoadState(ref stream); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper006.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper006.cs index c16526c..872083a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper006.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper006.cs @@ -1,21 +1,20 @@ -namespace MyNes.Core -{ - [BoardInfo("FFE F4xxx", 6)] - [HassIssues] - internal class Mapper006 : FFE - { - internal override string Issues => MNInterfaceLanguage.IssueMapper6; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(7, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(data & 3); - Switch16KPRG((data >> 2) & 0xF, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("FFE F4xxx", 6)] +[HassIssues] +internal class Mapper006 : FFE +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper6; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(7, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(data & 3); + Switch16KPRG((data >> 2) & 0xF, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper007.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper007.cs index 5e2a319..14412f6 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper007.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper007.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("AxROM", 7)] - internal class Mapper007 : Board - { - internal override void WritePRG(ref ushort addr, ref byte val) - { - Switch01KNMTFromMirroring(((val & 0x10) == 16) ? Mirroring.OneScB : Mirroring.OneScA); - Switch32KPRG(val & 7, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("AxROM", 7)] +internal class Mapper007 : Board +{ + internal override void WritePRG(ref ushort addr, ref byte val) + { + Switch01KNMTFromMirroring(((val & 0x10) == 16) ? Mirroring.OneScB : Mirroring.OneScA); + Switch32KPRG(val & 7, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper008.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper008.cs index 3a44584..2015214 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper008.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper008.cs @@ -1,15 +1,14 @@ -namespace MyNes.Core -{ - [BoardInfo("FFE F3xxx", 8)] - [HassIssues] - internal class Mapper008 : FFE - { - internal override string Issues => MNInterfaceLanguage.IssueMapper8; - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch32KPRG((data >> 4) & 3, PRGArea.Area8000); - Switch08KCHR(data & 3); - } - } +namespace MyNes.Core; + +[BoardInfo("FFE F3xxx", 8)] +[HassIssues] +internal class Mapper008 : FFE +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper8; + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch32KPRG((data >> 4) & 3, PRGArea.Area8000); + Switch08KCHR(data & 3); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper009.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper009.cs index fe7a816..683e285 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper009.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper009.cs @@ -1,7 +1,6 @@ -namespace MyNes.Core -{ - [BoardInfo("MMC2", 9)] - internal class Mapper009 : MMC2 - { - } +namespace MyNes.Core; + +[BoardInfo("MMC2", 9)] +internal class Mapper009 : MMC2 +{ } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper010.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper010.cs index 22399d0..521d809 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper010.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper010.cs @@ -1,25 +1,24 @@ -namespace MyNes.Core -{ - [BoardInfo("MMC4", 10)] - internal class Mapper010 : MMC2 - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(0, PRGArea.Area8000); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if ((address & 0xF000) == 40960) - { - Switch16KPRG(data, PRGArea.Area8000); - } - else - { - base.WritePRG(ref address, ref data); - } - } - } +namespace MyNes.Core; + +[BoardInfo("MMC4", 10)] +internal class Mapper010 : MMC2 +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(0, PRGArea.Area8000); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if ((address & 0xF000) == 40960) + { + Switch16KPRG(data, PRGArea.Area8000); + } + else + { + base.WritePRG(ref address, ref data); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper011.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper011.cs index f0144a0..9a87377 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper011.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper011.cs @@ -1,16 +1,15 @@ -namespace MyNes.Core -{ - [BoardInfo("Color Dreams", 11)] - internal class Mapper011 : Board - { - private byte writeData; - - internal override void WritePRG(ref ushort address, ref byte data) - { - ReadPRG(ref address, out writeData); - writeData &= data; - Switch32KPRG(writeData & 3, PRGArea.Area8000); - Switch08KCHR((writeData >> 4) & 0xF); - } - } +namespace MyNes.Core; + +[BoardInfo("Color Dreams", 11)] +internal class Mapper011 : Board +{ + private byte writeData; + + internal override void WritePRG(ref ushort address, ref byte data) + { + ReadPRG(ref address, out writeData); + writeData &= data; + Switch32KPRG(writeData & 3, PRGArea.Area8000); + Switch08KCHR((writeData >> 4) & 0xF); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper013.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper013.cs index 206cfbd..3074387 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper013.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper013.cs @@ -1,21 +1,20 @@ -namespace MyNes.Core -{ - [BoardInfo("CPROM", 13, 1, 16)] - internal class Mapper013 : Board - { - private byte writeData; - - internal override void HardReset() - { - base.HardReset(); - Toggle08KCHR_RAM(ram: true); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - ReadPRG(ref address, out writeData); - writeData &= data; - Switch04KCHR(writeData & 3, CHRArea.Area1000); - } - } +namespace MyNes.Core; + +[BoardInfo("CPROM", 13, 1, 16)] +internal class Mapper013 : Board +{ + private byte writeData; + + internal override void HardReset() + { + base.HardReset(); + Toggle08KCHR_RAM(ram: true); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + ReadPRG(ref address, out writeData); + writeData &= data; + Switch04KCHR(writeData & 3, CHRArea.Area1000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper015.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper015.cs index b3b1246..ed2b105 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper015.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper015.cs @@ -1,36 +1,35 @@ -namespace MyNes.Core -{ - [BoardInfo("100-in-1 Contra Function 16", 15)] - internal class Mapper015 : Board - { - private int temp; - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 3) - { - case 0: - Switch16KPRG(data & 0x3F, PRGArea.Area8000); - Switch16KPRG((data & 0x3F) | 1, PRGArea.AreaC000); - break; - case 1: - Switch16KPRG(data & 0x3F, PRGArea.Area8000); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - break; - case 2: - temp = data << 1; - temp = ((data & 0x3F) << 1) | ((data >> 7) & 1); - Switch08KPRG(temp, PRGArea.Area8000); - Switch08KPRG(temp, PRGArea.AreaA000); - Switch08KPRG(temp, PRGArea.AreaC000); - Switch08KPRG(temp, PRGArea.AreaE000); - break; - case 3: - Switch16KPRG(data & 0x3F, PRGArea.Area8000); - Switch16KPRG(data & 0x3F, PRGArea.AreaC000); - break; - } - Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); - } - } +namespace MyNes.Core; + +[BoardInfo("100-in-1 Contra Function 16", 15)] +internal class Mapper015 : Board +{ + private int temp; + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 3) + { + case 0: + Switch16KPRG(data & 0x3F, PRGArea.Area8000); + Switch16KPRG((data & 0x3F) | 1, PRGArea.AreaC000); + break; + case 1: + Switch16KPRG(data & 0x3F, PRGArea.Area8000); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + break; + case 2: + temp = data << 1; + temp = ((data & 0x3F) << 1) | ((data >> 7) & 1); + Switch08KPRG(temp, PRGArea.Area8000); + Switch08KPRG(temp, PRGArea.AreaA000); + Switch08KPRG(temp, PRGArea.AreaC000); + Switch08KPRG(temp, PRGArea.AreaE000); + break; + case 3: + Switch16KPRG(data & 0x3F, PRGArea.Area8000); + Switch16KPRG(data & 0x3F, PRGArea.AreaC000); + break; + } + Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper016.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper016.cs index f72f00c..f643a3d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper016.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper016.cs @@ -1,7 +1,6 @@ -namespace MyNes.Core -{ - [BoardInfo("Bandai", 16)] - internal class Mapper016 : Bandai - { - } +namespace MyNes.Core; + +[BoardInfo("Bandai", 16)] +internal class Mapper016 : Bandai +{ } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper017.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper017.cs index e6734a3..e231da3 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper017.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper017.cs @@ -1,64 +1,63 @@ -namespace MyNes.Core -{ - [BoardInfo("FFE F8xxx", 17)] - internal class Mapper017 : FFE - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - switch (address) - { - case 17668: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 17669: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 17670: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 17671: - Switch08KPRG(data, PRGArea.AreaE000); - break; - case 17680: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 17681: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 17682: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 17683: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 17684: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 17685: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 17686: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 17687: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 17672: - case 17673: - case 17674: - case 17675: - case 17676: - case 17677: - case 17678: - case 17679: - break; - } - } - } +namespace MyNes.Core; + +[BoardInfo("FFE F8xxx", 17)] +internal class Mapper017 : FFE +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + switch (address) + { + case 17668: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 17669: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 17670: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 17671: + Switch08KPRG(data, PRGArea.AreaE000); + break; + case 17680: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 17681: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 17682: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 17683: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 17684: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 17685: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 17686: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 17687: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 17672: + case 17673: + case 17674: + case 17675: + case 17676: + case 17677: + case 17678: + case 17679: + break; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper018.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper018.cs index c65aeb4..d53f90c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper018.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper018.cs @@ -1,219 +1,218 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Jaleco SS8806", 18)] - internal class Mapper018 : Board - { - private int[] prg_reg; - - private int[] chr_reg; - - private int irqRelaod; - - private int irqCounter; - - private bool irqEnable; - - private int irqMask; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - prg_reg = new int[3]; - chr_reg = new int[8]; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF003) - { - case 32768: - prg_reg[0] = (prg_reg[0] & 0xF0) | (data & 0xF); - Switch08KPRG(prg_reg[0], PRGArea.Area8000); - break; - case 32769: - prg_reg[0] = (prg_reg[0] & 0xF) | ((data & 0xF) << 4); - Switch08KPRG(prg_reg[0], PRGArea.Area8000); - break; - case 32770: - prg_reg[1] = (prg_reg[1] & 0xF0) | (data & 0xF); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - break; - case 32771: - prg_reg[1] = (prg_reg[1] & 0xF) | ((data & 0xF) << 4); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - break; - case 36864: - prg_reg[2] = (prg_reg[2] & 0xF0) | (data & 0xF); - Switch08KPRG(prg_reg[2], PRGArea.AreaC000); - break; - case 36865: - prg_reg[2] = (prg_reg[2] & 0xF) | ((data & 0xF) << 4); - Switch08KPRG(prg_reg[2], PRGArea.AreaC000); - break; - case 40960: - chr_reg[0] = (chr_reg[0] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_reg[0], CHRArea.Area0000); - break; - case 40961: - chr_reg[0] = (chr_reg[0] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_reg[0], CHRArea.Area0000); - break; - case 40962: - chr_reg[1] = (chr_reg[1] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_reg[1], CHRArea.Area0400); - break; - case 40963: - chr_reg[1] = (chr_reg[1] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_reg[1], CHRArea.Area0400); - break; - case 45056: - chr_reg[2] = (chr_reg[2] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_reg[2], CHRArea.Area0800); - break; - case 45057: - chr_reg[2] = (chr_reg[2] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_reg[2], CHRArea.Area0800); - break; - case 45058: - chr_reg[3] = (chr_reg[3] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_reg[3], CHRArea.Area0C00); - break; - case 45059: - chr_reg[3] = (chr_reg[3] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_reg[3], CHRArea.Area0C00); - break; - case 49152: - chr_reg[4] = (chr_reg[4] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_reg[4], CHRArea.Area1000); - break; - case 49153: - chr_reg[4] = (chr_reg[4] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_reg[4], CHRArea.Area1000); - break; - case 49154: - chr_reg[5] = (chr_reg[5] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_reg[5], CHRArea.Area1400); - break; - case 49155: - chr_reg[5] = (chr_reg[5] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_reg[5], CHRArea.Area1400); - break; - case 53248: - chr_reg[6] = (chr_reg[6] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_reg[6], CHRArea.Area1800); - break; - case 53249: - chr_reg[6] = (chr_reg[6] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_reg[6], CHRArea.Area1800); - break; - case 53250: - chr_reg[7] = (chr_reg[7] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_reg[7], CHRArea.Area1C00); - break; - case 53251: - chr_reg[7] = (chr_reg[7] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_reg[7], CHRArea.Area1C00); - break; - case 57344: - irqRelaod = (irqRelaod & 0xFFF0) | (data & 0xF); - break; - case 57345: - irqRelaod = (irqRelaod & 0xFF0F) | ((data & 0xF) << 4); - break; - case 57346: - irqRelaod = (irqRelaod & 0xF0FF) | ((data & 0xF) << 8); - break; - case 57347: - irqRelaod = (irqRelaod & 0xFFF) | ((data & 0xF) << 12); - break; - case 61440: - irqCounter = irqRelaod; - NesEmu.IRQFlags &= -9; - break; - case 61441: - irqEnable = (data & 1) == 1; - if ((data & 8) == 8) - { - irqMask = 15; - } - else if ((data & 4) == 4) - { - irqMask = 255; - } - else if ((data & 2) == 2) - { - irqMask = 4095; - } - else - { - irqMask = 65535; - } - NesEmu.IRQFlags &= -9; - break; - case 61442: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - } - } - - internal override void OnCPUClock() - { - if (irqEnable && (irqCounter & irqMask) > 0 && (--irqCounter & irqMask) == 0) - { - irqEnable = false; - NesEmu.IRQFlags |= 8; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - for (int i = 0; i < prg_reg.Length; i++) - { - stream.Write(prg_reg[i]); - } - for (int j = 0; j < chr_reg.Length; j++) - { - stream.Write(chr_reg[j]); - } - stream.Write(irqRelaod); - stream.Write(irqCounter); - stream.Write(irqEnable); - stream.Write(irqMask); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - for (int i = 0; i < prg_reg.Length; i++) - { - prg_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < chr_reg.Length; j++) - { - chr_reg[j] = stream.ReadInt32(); - } - irqRelaod = stream.ReadInt32(); - irqCounter = stream.ReadInt32(); - irqEnable = stream.ReadBoolean(); - irqMask = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Jaleco SS8806", 18)] +internal class Mapper018 : Board +{ + private int[] prg_reg; + + private int[] chr_reg; + + private int irqRelaod; + + private int irqCounter; + + private bool irqEnable; + + private int irqMask; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + prg_reg = new int[3]; + chr_reg = new int[8]; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF003) + { + case 32768: + prg_reg[0] = (prg_reg[0] & 0xF0) | (data & 0xF); + Switch08KPRG(prg_reg[0], PRGArea.Area8000); + break; + case 32769: + prg_reg[0] = (prg_reg[0] & 0xF) | ((data & 0xF) << 4); + Switch08KPRG(prg_reg[0], PRGArea.Area8000); + break; + case 32770: + prg_reg[1] = (prg_reg[1] & 0xF0) | (data & 0xF); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + break; + case 32771: + prg_reg[1] = (prg_reg[1] & 0xF) | ((data & 0xF) << 4); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + break; + case 36864: + prg_reg[2] = (prg_reg[2] & 0xF0) | (data & 0xF); + Switch08KPRG(prg_reg[2], PRGArea.AreaC000); + break; + case 36865: + prg_reg[2] = (prg_reg[2] & 0xF) | ((data & 0xF) << 4); + Switch08KPRG(prg_reg[2], PRGArea.AreaC000); + break; + case 40960: + chr_reg[0] = (chr_reg[0] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_reg[0], CHRArea.Area0000); + break; + case 40961: + chr_reg[0] = (chr_reg[0] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_reg[0], CHRArea.Area0000); + break; + case 40962: + chr_reg[1] = (chr_reg[1] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_reg[1], CHRArea.Area0400); + break; + case 40963: + chr_reg[1] = (chr_reg[1] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_reg[1], CHRArea.Area0400); + break; + case 45056: + chr_reg[2] = (chr_reg[2] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_reg[2], CHRArea.Area0800); + break; + case 45057: + chr_reg[2] = (chr_reg[2] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_reg[2], CHRArea.Area0800); + break; + case 45058: + chr_reg[3] = (chr_reg[3] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_reg[3], CHRArea.Area0C00); + break; + case 45059: + chr_reg[3] = (chr_reg[3] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_reg[3], CHRArea.Area0C00); + break; + case 49152: + chr_reg[4] = (chr_reg[4] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_reg[4], CHRArea.Area1000); + break; + case 49153: + chr_reg[4] = (chr_reg[4] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_reg[4], CHRArea.Area1000); + break; + case 49154: + chr_reg[5] = (chr_reg[5] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_reg[5], CHRArea.Area1400); + break; + case 49155: + chr_reg[5] = (chr_reg[5] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_reg[5], CHRArea.Area1400); + break; + case 53248: + chr_reg[6] = (chr_reg[6] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_reg[6], CHRArea.Area1800); + break; + case 53249: + chr_reg[6] = (chr_reg[6] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_reg[6], CHRArea.Area1800); + break; + case 53250: + chr_reg[7] = (chr_reg[7] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_reg[7], CHRArea.Area1C00); + break; + case 53251: + chr_reg[7] = (chr_reg[7] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_reg[7], CHRArea.Area1C00); + break; + case 57344: + irqRelaod = (irqRelaod & 0xFFF0) | (data & 0xF); + break; + case 57345: + irqRelaod = (irqRelaod & 0xFF0F) | ((data & 0xF) << 4); + break; + case 57346: + irqRelaod = (irqRelaod & 0xF0FF) | ((data & 0xF) << 8); + break; + case 57347: + irqRelaod = (irqRelaod & 0xFFF) | ((data & 0xF) << 12); + break; + case 61440: + irqCounter = irqRelaod; + NesEmu.IRQFlags &= -9; + break; + case 61441: + irqEnable = (data & 1) == 1; + if ((data & 8) == 8) + { + irqMask = 15; + } + else if ((data & 4) == 4) + { + irqMask = 255; + } + else if ((data & 2) == 2) + { + irqMask = 4095; + } + else + { + irqMask = 65535; + } + NesEmu.IRQFlags &= -9; + break; + case 61442: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + } + } + + internal override void OnCPUClock() + { + if (irqEnable && (irqCounter & irqMask) > 0 && (--irqCounter & irqMask) == 0) + { + irqEnable = false; + NesEmu.IRQFlags |= 8; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + for (int i = 0; i < prg_reg.Length; i++) + { + stream.Write(prg_reg[i]); + } + for (int j = 0; j < chr_reg.Length; j++) + { + stream.Write(chr_reg[j]); + } + stream.Write(irqRelaod); + stream.Write(irqCounter); + stream.Write(irqEnable); + stream.Write(irqMask); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + for (int i = 0; i < prg_reg.Length; i++) + { + prg_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < chr_reg.Length; j++) + { + chr_reg[j] = stream.ReadInt32(); + } + irqRelaod = stream.ReadInt32(); + irqCounter = stream.ReadInt32(); + irqEnable = stream.ReadBoolean(); + irqMask = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper019.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper019.cs index 25d4163..9f71d5f 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper019.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper019.cs @@ -1,7 +1,6 @@ -namespace MyNes.Core -{ - [BoardInfo("Namcot 106", 19, 1, 256)] - internal class Mapper019 : Namcot106 - { - } +namespace MyNes.Core; + +[BoardInfo("Namcot 106", 19, 1, 256)] +internal class Mapper019 : Namcot106 +{ } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper021.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper021.cs index 5bd6e94..b50b9f1 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper021.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper021.cs @@ -1,254 +1,253 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC4", 21)] - internal class Mapper021 : Board - { - private bool prg_mode; - - private byte prg_reg0; - - private int[] chr_Reg; - - private int irq_reload; - - private int irq_counter; - - private int prescaler; - - private bool irq_mode_cycle; - - private bool irq_enable; - - private bool irq_enable_on_ak; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - prescaler = 341; - chr_Reg = new int[8]; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address) - { - case 32768: - case 32770: - case 32772: - case 32774: - case 32832: - case 32896: - case 32960: - prg_reg0 = data; - Switch08KPRG(prg_mode ? (PRG_ROM_08KB_Mask - 1) : (prg_reg0 & 0x1F), PRGArea.Area8000); - Switch08KPRG(prg_mode ? (prg_reg0 & 0x1F) : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); - break; - case 36864: - case 36866: - case 36928: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 36868: - case 36870: - case 36992: - case 37056: - prg_mode = (data & 2) == 2; - Switch08KPRG(prg_mode ? (PRG_ROM_08KB_Mask - 1) : (prg_reg0 & 0x1F), PRGArea.Area8000); - Switch08KPRG(prg_mode ? (prg_reg0 & 0x1F) : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); - break; - case 40960: - case 40962: - case 40964: - case 40966: - case 41024: - case 41088: - case 41152: - Switch08KPRG(data & 0x1F, PRGArea.AreaA000); - break; - case 45056: - chr_Reg[0] = (chr_Reg[0] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[0], CHRArea.Area0000); - break; - case 45058: - case 45120: - chr_Reg[0] = (chr_Reg[0] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[0], CHRArea.Area0000); - break; - case 45060: - case 45184: - chr_Reg[1] = (chr_Reg[1] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[1], CHRArea.Area0400); - break; - case 45062: - case 45248: - chr_Reg[1] = (chr_Reg[1] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[1], CHRArea.Area0400); - break; - case 49152: - chr_Reg[2] = (chr_Reg[2] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[2], CHRArea.Area0800); - break; - case 49154: - case 49216: - chr_Reg[2] = (chr_Reg[2] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[2], CHRArea.Area0800); - break; - case 49156: - case 49280: - chr_Reg[3] = (chr_Reg[3] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); - break; - case 49158: - case 49344: - chr_Reg[3] = (chr_Reg[3] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); - break; - case 53248: - chr_Reg[4] = (chr_Reg[4] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[4], CHRArea.Area1000); - break; - case 53250: - case 53312: - chr_Reg[4] = (chr_Reg[4] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[4], CHRArea.Area1000); - break; - case 53252: - case 53376: - chr_Reg[5] = (chr_Reg[5] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[5], CHRArea.Area1400); - break; - case 53254: - case 53440: - chr_Reg[5] = (chr_Reg[5] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[5], CHRArea.Area1400); - break; - case 57344: - chr_Reg[6] = (chr_Reg[6] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[6], CHRArea.Area1800); - break; - case 57346: - case 57408: - chr_Reg[6] = (chr_Reg[6] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[6], CHRArea.Area1800); - break; - case 57348: - case 57472: - chr_Reg[7] = (chr_Reg[7] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); - break; - case 57350: - case 57536: - chr_Reg[7] = (chr_Reg[7] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); - break; - case 61440: - irq_reload = (irq_reload & 0xF0) | (data & 0xF); - break; - case 61442: - case 61504: - irq_reload = (irq_reload & 0xF) | ((data & 0xF) << 4); - break; - case 61444: - case 61568: - irq_mode_cycle = (data & 4) == 4; - irq_enable = (data & 2) == 2; - irq_enable_on_ak = (data & 1) == 1; - if (irq_enable) - { - irq_counter = irq_reload; - prescaler = 341; - } - NesEmu.IRQFlags &= -9; - break; - case 61446: - case 61632: - NesEmu.IRQFlags &= -9; - irq_enable = irq_enable_on_ak; - break; - } - } - - internal override void OnCPUClock() - { - if (!irq_enable) - { - return; - } - if (!irq_mode_cycle) - { - if (prescaler > 0) - { - prescaler -= 3; - return; - } - prescaler = 341; - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - else - { - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(prg_mode); - stream.Write(prg_reg0); - for (int i = 0; i < chr_Reg.Length; i++) - { - stream.Write(chr_Reg[i]); - } - stream.Write(irq_reload); - stream.Write(irq_counter); - stream.Write(prescaler); - stream.Write(irq_mode_cycle); - stream.Write(irq_enable); - stream.Write(irq_enable_on_ak); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - prg_mode = stream.ReadBoolean(); - prg_reg0 = stream.ReadByte(); - for (int i = 0; i < chr_Reg.Length; i++) - { - chr_Reg[i] = stream.ReadInt32(); - } - irq_reload = stream.ReadInt32(); - irq_counter = stream.ReadInt32(); - prescaler = stream.ReadInt32(); - irq_mode_cycle = stream.ReadBoolean(); - irq_enable = stream.ReadBoolean(); - irq_enable_on_ak = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC4", 21)] +internal class Mapper021 : Board +{ + private bool prg_mode; + + private byte prg_reg0; + + private int[] chr_Reg; + + private int irq_reload; + + private int irq_counter; + + private int prescaler; + + private bool irq_mode_cycle; + + private bool irq_enable; + + private bool irq_enable_on_ak; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + prescaler = 341; + chr_Reg = new int[8]; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address) + { + case 32768: + case 32770: + case 32772: + case 32774: + case 32832: + case 32896: + case 32960: + prg_reg0 = data; + Switch08KPRG(prg_mode ? (PRG_ROM_08KB_Mask - 1) : (prg_reg0 & 0x1F), PRGArea.Area8000); + Switch08KPRG(prg_mode ? (prg_reg0 & 0x1F) : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); + break; + case 36864: + case 36866: + case 36928: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 36868: + case 36870: + case 36992: + case 37056: + prg_mode = (data & 2) == 2; + Switch08KPRG(prg_mode ? (PRG_ROM_08KB_Mask - 1) : (prg_reg0 & 0x1F), PRGArea.Area8000); + Switch08KPRG(prg_mode ? (prg_reg0 & 0x1F) : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); + break; + case 40960: + case 40962: + case 40964: + case 40966: + case 41024: + case 41088: + case 41152: + Switch08KPRG(data & 0x1F, PRGArea.AreaA000); + break; + case 45056: + chr_Reg[0] = (chr_Reg[0] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[0], CHRArea.Area0000); + break; + case 45058: + case 45120: + chr_Reg[0] = (chr_Reg[0] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[0], CHRArea.Area0000); + break; + case 45060: + case 45184: + chr_Reg[1] = (chr_Reg[1] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[1], CHRArea.Area0400); + break; + case 45062: + case 45248: + chr_Reg[1] = (chr_Reg[1] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[1], CHRArea.Area0400); + break; + case 49152: + chr_Reg[2] = (chr_Reg[2] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[2], CHRArea.Area0800); + break; + case 49154: + case 49216: + chr_Reg[2] = (chr_Reg[2] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[2], CHRArea.Area0800); + break; + case 49156: + case 49280: + chr_Reg[3] = (chr_Reg[3] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); + break; + case 49158: + case 49344: + chr_Reg[3] = (chr_Reg[3] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); + break; + case 53248: + chr_Reg[4] = (chr_Reg[4] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[4], CHRArea.Area1000); + break; + case 53250: + case 53312: + chr_Reg[4] = (chr_Reg[4] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[4], CHRArea.Area1000); + break; + case 53252: + case 53376: + chr_Reg[5] = (chr_Reg[5] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[5], CHRArea.Area1400); + break; + case 53254: + case 53440: + chr_Reg[5] = (chr_Reg[5] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[5], CHRArea.Area1400); + break; + case 57344: + chr_Reg[6] = (chr_Reg[6] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[6], CHRArea.Area1800); + break; + case 57346: + case 57408: + chr_Reg[6] = (chr_Reg[6] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[6], CHRArea.Area1800); + break; + case 57348: + case 57472: + chr_Reg[7] = (chr_Reg[7] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); + break; + case 57350: + case 57536: + chr_Reg[7] = (chr_Reg[7] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); + break; + case 61440: + irq_reload = (irq_reload & 0xF0) | (data & 0xF); + break; + case 61442: + case 61504: + irq_reload = (irq_reload & 0xF) | ((data & 0xF) << 4); + break; + case 61444: + case 61568: + irq_mode_cycle = (data & 4) == 4; + irq_enable = (data & 2) == 2; + irq_enable_on_ak = (data & 1) == 1; + if (irq_enable) + { + irq_counter = irq_reload; + prescaler = 341; + } + NesEmu.IRQFlags &= -9; + break; + case 61446: + case 61632: + NesEmu.IRQFlags &= -9; + irq_enable = irq_enable_on_ak; + break; + } + } + + internal override void OnCPUClock() + { + if (!irq_enable) + { + return; + } + if (!irq_mode_cycle) + { + if (prescaler > 0) + { + prescaler -= 3; + return; + } + prescaler = 341; + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + else + { + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(prg_mode); + stream.Write(prg_reg0); + for (int i = 0; i < chr_Reg.Length; i++) + { + stream.Write(chr_Reg[i]); + } + stream.Write(irq_reload); + stream.Write(irq_counter); + stream.Write(prescaler); + stream.Write(irq_mode_cycle); + stream.Write(irq_enable); + stream.Write(irq_enable_on_ak); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + prg_mode = stream.ReadBoolean(); + prg_reg0 = stream.ReadByte(); + for (int i = 0; i < chr_Reg.Length; i++) + { + chr_Reg[i] = stream.ReadInt32(); + } + irq_reload = stream.ReadInt32(); + irq_counter = stream.ReadInt32(); + prescaler = stream.ReadInt32(); + irq_mode_cycle = stream.ReadBoolean(); + irq_enable = stream.ReadBoolean(); + irq_enable_on_ak = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper022.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper022.cs index 29aa8b4..3c9920e 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper022.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper022.cs @@ -1,138 +1,137 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC2", 22)] - internal class Mapper022 : Board - { - private int[] chr_Reg; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - chr_Reg = new int[8]; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address) - { - case 32768: - case 32769: - case 32770: - case 32771: - Switch08KPRG(data & 0xF, PRGArea.Area8000); - break; - case 36864: - case 36865: - case 36866: - case 36867: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 40960: - case 40961: - case 40962: - case 40963: - Switch08KPRG(data & 0xF, PRGArea.AreaA000); - break; - case 45056: - chr_Reg[0] = (chr_Reg[0] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[0] >> 1, CHRArea.Area0000); - break; - case 45058: - chr_Reg[0] = (chr_Reg[0] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[0] >> 1, CHRArea.Area0000); - break; - case 45057: - chr_Reg[1] = (chr_Reg[1] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[1] >> 1, CHRArea.Area0400); - break; - case 45059: - chr_Reg[1] = (chr_Reg[1] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[1] >> 1, CHRArea.Area0400); - break; - case 49152: - chr_Reg[2] = (chr_Reg[2] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[2] >> 1, CHRArea.Area0800); - break; - case 49154: - chr_Reg[2] = (chr_Reg[2] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[2] >> 1, CHRArea.Area0800); - break; - case 49153: - chr_Reg[3] = (chr_Reg[3] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[3] >> 1, CHRArea.Area0C00); - break; - case 49155: - chr_Reg[3] = (chr_Reg[3] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[3] >> 1, CHRArea.Area0C00); - break; - case 53248: - chr_Reg[4] = (chr_Reg[4] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[4] >> 1, CHRArea.Area1000); - break; - case 53250: - chr_Reg[4] = (chr_Reg[4] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[4] >> 1, CHRArea.Area1000); - break; - case 53249: - chr_Reg[5] = (chr_Reg[5] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[5] >> 1, CHRArea.Area1400); - break; - case 53251: - chr_Reg[5] = (chr_Reg[5] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[5] >> 1, CHRArea.Area1400); - break; - case 57344: - chr_Reg[6] = (chr_Reg[6] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[6] >> 1, CHRArea.Area1800); - break; - case 57346: - chr_Reg[6] = (chr_Reg[6] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[6] >> 1, CHRArea.Area1800); - break; - case 57345: - chr_Reg[7] = (chr_Reg[7] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[7] >> 1, CHRArea.Area1C00); - break; - case 57347: - chr_Reg[7] = (chr_Reg[7] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[7] >> 1, CHRArea.Area1C00); - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - for (int i = 0; i < chr_Reg.Length; i++) - { - stream.Write(chr_Reg[i]); - } - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - for (int i = 0; i < chr_Reg.Length; i++) - { - chr_Reg[i] = stream.ReadInt32(); - } - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC2", 22)] +internal class Mapper022 : Board +{ + private int[] chr_Reg; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + chr_Reg = new int[8]; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address) + { + case 32768: + case 32769: + case 32770: + case 32771: + Switch08KPRG(data & 0xF, PRGArea.Area8000); + break; + case 36864: + case 36865: + case 36866: + case 36867: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 40960: + case 40961: + case 40962: + case 40963: + Switch08KPRG(data & 0xF, PRGArea.AreaA000); + break; + case 45056: + chr_Reg[0] = (chr_Reg[0] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[0] >> 1, CHRArea.Area0000); + break; + case 45058: + chr_Reg[0] = (chr_Reg[0] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[0] >> 1, CHRArea.Area0000); + break; + case 45057: + chr_Reg[1] = (chr_Reg[1] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[1] >> 1, CHRArea.Area0400); + break; + case 45059: + chr_Reg[1] = (chr_Reg[1] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[1] >> 1, CHRArea.Area0400); + break; + case 49152: + chr_Reg[2] = (chr_Reg[2] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[2] >> 1, CHRArea.Area0800); + break; + case 49154: + chr_Reg[2] = (chr_Reg[2] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[2] >> 1, CHRArea.Area0800); + break; + case 49153: + chr_Reg[3] = (chr_Reg[3] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[3] >> 1, CHRArea.Area0C00); + break; + case 49155: + chr_Reg[3] = (chr_Reg[3] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[3] >> 1, CHRArea.Area0C00); + break; + case 53248: + chr_Reg[4] = (chr_Reg[4] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[4] >> 1, CHRArea.Area1000); + break; + case 53250: + chr_Reg[4] = (chr_Reg[4] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[4] >> 1, CHRArea.Area1000); + break; + case 53249: + chr_Reg[5] = (chr_Reg[5] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[5] >> 1, CHRArea.Area1400); + break; + case 53251: + chr_Reg[5] = (chr_Reg[5] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[5] >> 1, CHRArea.Area1400); + break; + case 57344: + chr_Reg[6] = (chr_Reg[6] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[6] >> 1, CHRArea.Area1800); + break; + case 57346: + chr_Reg[6] = (chr_Reg[6] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[6] >> 1, CHRArea.Area1800); + break; + case 57345: + chr_Reg[7] = (chr_Reg[7] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[7] >> 1, CHRArea.Area1C00); + break; + case 57347: + chr_Reg[7] = (chr_Reg[7] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[7] >> 1, CHRArea.Area1C00); + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + for (int i = 0; i < chr_Reg.Length; i++) + { + stream.Write(chr_Reg[i]); + } + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + for (int i = 0; i < chr_Reg.Length; i++) + { + chr_Reg[i] = stream.ReadInt32(); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper023.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper023.cs index b540714..9b5dae6 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper023.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper023.cs @@ -1,163 +1,162 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC2", 23)] - internal class Mapper023 : Board - { - private int[] chr_Reg; - - private byte security; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - chr_Reg = new int[8]; - security = 0; - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - if (address == 24576) - { - security = (byte)(data & 1u); - } - } - - internal override void ReadSRM(ref ushort address, out byte data) - { - if (address == 24576) - { - data = security; - } - else - { - data = 0; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address) - { - case 32768: - case 32769: - case 32770: - case 32771: - Switch08KPRG(data & 0xF, PRGArea.Area8000); - break; - case 36864: - case 36865: - case 36866: - case 36867: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 40960: - case 40961: - case 40962: - case 40963: - Switch08KPRG(data & 0xF, PRGArea.AreaA000); - break; - case 45056: - chr_Reg[0] = (chr_Reg[0] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[0], CHRArea.Area0000); - break; - case 45057: - chr_Reg[0] = (chr_Reg[0] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[0], CHRArea.Area0000); - break; - case 45058: - chr_Reg[1] = (chr_Reg[1] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[1], CHRArea.Area0400); - break; - case 45059: - chr_Reg[1] = (chr_Reg[1] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[1], CHRArea.Area0400); - break; - case 49152: - chr_Reg[2] = (chr_Reg[2] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[2], CHRArea.Area0800); - break; - case 49153: - chr_Reg[2] = (chr_Reg[2] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[2], CHRArea.Area0800); - break; - case 49154: - chr_Reg[3] = (chr_Reg[3] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); - break; - case 49155: - chr_Reg[3] = (chr_Reg[3] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); - break; - case 53248: - chr_Reg[4] = (chr_Reg[4] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[4], CHRArea.Area1000); - break; - case 53249: - chr_Reg[4] = (chr_Reg[4] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[4], CHRArea.Area1000); - break; - case 53250: - chr_Reg[5] = (chr_Reg[5] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[5], CHRArea.Area1400); - break; - case 53251: - chr_Reg[5] = (chr_Reg[5] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[5], CHRArea.Area1400); - break; - case 57344: - chr_Reg[6] = (chr_Reg[6] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[6], CHRArea.Area1800); - break; - case 57345: - chr_Reg[6] = (chr_Reg[6] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[6], CHRArea.Area1800); - break; - case 57346: - chr_Reg[7] = (chr_Reg[7] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); - break; - case 57347: - chr_Reg[7] = (chr_Reg[7] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - for (int i = 0; i < chr_Reg.Length; i++) - { - stream.Write(chr_Reg[i]); - } - stream.Write(security); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - for (int i = 0; i < chr_Reg.Length; i++) - { - chr_Reg[i] = stream.ReadInt32(); - } - security = stream.ReadByte(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC2", 23)] +internal class Mapper023 : Board +{ + private int[] chr_Reg; + + private byte security; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + chr_Reg = new int[8]; + security = 0; + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + if (address == 24576) + { + security = (byte)(data & 1u); + } + } + + internal override void ReadSRM(ref ushort address, out byte data) + { + if (address == 24576) + { + data = security; + } + else + { + data = 0; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address) + { + case 32768: + case 32769: + case 32770: + case 32771: + Switch08KPRG(data & 0xF, PRGArea.Area8000); + break; + case 36864: + case 36865: + case 36866: + case 36867: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 40960: + case 40961: + case 40962: + case 40963: + Switch08KPRG(data & 0xF, PRGArea.AreaA000); + break; + case 45056: + chr_Reg[0] = (chr_Reg[0] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[0], CHRArea.Area0000); + break; + case 45057: + chr_Reg[0] = (chr_Reg[0] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[0], CHRArea.Area0000); + break; + case 45058: + chr_Reg[1] = (chr_Reg[1] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[1], CHRArea.Area0400); + break; + case 45059: + chr_Reg[1] = (chr_Reg[1] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[1], CHRArea.Area0400); + break; + case 49152: + chr_Reg[2] = (chr_Reg[2] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[2], CHRArea.Area0800); + break; + case 49153: + chr_Reg[2] = (chr_Reg[2] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[2], CHRArea.Area0800); + break; + case 49154: + chr_Reg[3] = (chr_Reg[3] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); + break; + case 49155: + chr_Reg[3] = (chr_Reg[3] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); + break; + case 53248: + chr_Reg[4] = (chr_Reg[4] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[4], CHRArea.Area1000); + break; + case 53249: + chr_Reg[4] = (chr_Reg[4] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[4], CHRArea.Area1000); + break; + case 53250: + chr_Reg[5] = (chr_Reg[5] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[5], CHRArea.Area1400); + break; + case 53251: + chr_Reg[5] = (chr_Reg[5] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[5], CHRArea.Area1400); + break; + case 57344: + chr_Reg[6] = (chr_Reg[6] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[6], CHRArea.Area1800); + break; + case 57345: + chr_Reg[6] = (chr_Reg[6] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[6], CHRArea.Area1800); + break; + case 57346: + chr_Reg[7] = (chr_Reg[7] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); + break; + case 57347: + chr_Reg[7] = (chr_Reg[7] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + for (int i = 0; i < chr_Reg.Length; i++) + { + stream.Write(chr_Reg[i]); + } + stream.Write(security); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + for (int i = 0; i < chr_Reg.Length; i++) + { + chr_Reg[i] = stream.ReadInt32(); + } + security = stream.ReadByte(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper024.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper024.cs index 29315b7..030f283 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper024.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper024.cs @@ -1,245 +1,244 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC6", 24)] - [WithExternalSound] - internal class Mapper024 : Board - { - private int irq_reload; - - private int irq_counter; - - private int prescaler; - - private bool irq_mode_cycle; - - private bool irq_enable; - - private bool irq_enable_on_ak; - - private VRC6Pulse snd_1; - - private VRC6Pulse snd_2; - - private VRC6Sawtooth snd_3; - - private double[] audio_pulse_table; - - private double[] audio_tnd_table; - - internal override void Initialize(IRom rom) - { - base.Initialize(rom); - snd_1 = new VRC6Pulse(); - snd_2 = new VRC6Pulse(); - snd_3 = new VRC6Sawtooth(); - audio_pulse_table = new double[32]; - for (int i = 0; i < 32; i++) - { - audio_pulse_table[i] = 95.52 / (8128.0 / (double)i + 100.0); - } - audio_tnd_table = new double[204]; - for (int j = 0; j < 204; j++) - { - audio_tnd_table[j] = 163.67 / (24329.0 / (double)j + 100.0); - } - } - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - APUApplyChannelsSettings(); - snd_1.HardReset(); - snd_2.HardReset(); - snd_3.HardReset(); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address) - { - case 32768: - case 32769: - case 32770: - case 32771: - Switch16KPRG(data, PRGArea.Area8000); - break; - case 36864: - snd_1.Write0(ref data); - break; - case 36865: - snd_1.Write1(ref data); - break; - case 36866: - snd_1.Write2(ref data); - break; - case 40960: - snd_2.Write0(ref data); - break; - case 40961: - snd_2.Write1(ref data); - break; - case 40962: - snd_2.Write2(ref data); - break; - case 45056: - snd_3.Write0(ref data); - break; - case 45057: - snd_3.Write1(ref data); - break; - case 45058: - snd_3.Write2(ref data); - break; - case 45059: - switch ((data & 0xC) >> 2) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 49152: - case 49153: - case 49154: - case 49155: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 53248: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 53249: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 53250: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 53251: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 57344: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 57345: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 57346: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 57347: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 61440: - irq_reload = data; - break; - case 61441: - irq_mode_cycle = (data & 4) == 4; - irq_enable = (data & 2) == 2; - irq_enable_on_ak = (data & 1) == 1; - if (irq_enable) - { - irq_counter = irq_reload; - prescaler = 341; - } - NesEmu.IRQFlags &= -9; - break; - case 61442: - NesEmu.IRQFlags &= -9; - irq_enable = irq_enable_on_ak; - break; - } - } - - internal override void OnCPUClock() - { - if (!irq_enable) - { - return; - } - if (!irq_mode_cycle) - { - if (prescaler > 0) - { - prescaler -= 3; - return; - } - prescaler = 341; - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - else - { - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - } - - internal override void OnAPUClockSingle() - { - base.OnAPUClockSingle(); - snd_1.ClockSingle(); - snd_2.ClockSingle(); - snd_3.ClockSingle(); - } - - internal override void APUApplyChannelsSettings() - { - base.APUApplyChannelsSettings(); - snd_1.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SQ1; - snd_2.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SQ2; - snd_3.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SAW; - } - - internal override double APUGetSample() - { - return audio_pulse_table[snd_1.output + snd_2.output] + audio_tnd_table[snd_3.output]; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_reload); - stream.Write(irq_counter); - stream.Write(prescaler); - stream.Write(irq_mode_cycle); - stream.Write(irq_enable); - stream.Write(irq_enable_on_ak); - snd_1.SaveState(ref stream); - snd_2.SaveState(ref stream); - snd_3.SaveState(ref stream); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_reload = stream.ReadInt32(); - irq_counter = stream.ReadInt32(); - prescaler = stream.ReadInt32(); - irq_mode_cycle = stream.ReadBoolean(); - irq_enable = stream.ReadBoolean(); - irq_enable_on_ak = stream.ReadBoolean(); - snd_1.LoadState(ref stream); - snd_2.LoadState(ref stream); - snd_3.LoadState(ref stream); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC6", 24)] +[WithExternalSound] +internal class Mapper024 : Board +{ + private int irq_reload; + + private int irq_counter; + + private int prescaler; + + private bool irq_mode_cycle; + + private bool irq_enable; + + private bool irq_enable_on_ak; + + private VRC6Pulse snd_1; + + private VRC6Pulse snd_2; + + private VRC6Sawtooth snd_3; + + private double[] audio_pulse_table; + + private double[] audio_tnd_table; + + internal override void Initialize(IRom rom) + { + base.Initialize(rom); + snd_1 = new VRC6Pulse(); + snd_2 = new VRC6Pulse(); + snd_3 = new VRC6Sawtooth(); + audio_pulse_table = new double[32]; + for (int i = 0; i < 32; i++) + { + audio_pulse_table[i] = 95.52 / (8128.0 / (double)i + 100.0); + } + audio_tnd_table = new double[204]; + for (int j = 0; j < 204; j++) + { + audio_tnd_table[j] = 163.67 / (24329.0 / (double)j + 100.0); + } + } + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + APUApplyChannelsSettings(); + snd_1.HardReset(); + snd_2.HardReset(); + snd_3.HardReset(); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address) + { + case 32768: + case 32769: + case 32770: + case 32771: + Switch16KPRG(data, PRGArea.Area8000); + break; + case 36864: + snd_1.Write0(ref data); + break; + case 36865: + snd_1.Write1(ref data); + break; + case 36866: + snd_1.Write2(ref data); + break; + case 40960: + snd_2.Write0(ref data); + break; + case 40961: + snd_2.Write1(ref data); + break; + case 40962: + snd_2.Write2(ref data); + break; + case 45056: + snd_3.Write0(ref data); + break; + case 45057: + snd_3.Write1(ref data); + break; + case 45058: + snd_3.Write2(ref data); + break; + case 45059: + switch ((data & 0xC) >> 2) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 49152: + case 49153: + case 49154: + case 49155: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 53248: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 53249: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 53250: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 53251: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 57344: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 57345: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 57346: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 57347: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 61440: + irq_reload = data; + break; + case 61441: + irq_mode_cycle = (data & 4) == 4; + irq_enable = (data & 2) == 2; + irq_enable_on_ak = (data & 1) == 1; + if (irq_enable) + { + irq_counter = irq_reload; + prescaler = 341; + } + NesEmu.IRQFlags &= -9; + break; + case 61442: + NesEmu.IRQFlags &= -9; + irq_enable = irq_enable_on_ak; + break; + } + } + + internal override void OnCPUClock() + { + if (!irq_enable) + { + return; + } + if (!irq_mode_cycle) + { + if (prescaler > 0) + { + prescaler -= 3; + return; + } + prescaler = 341; + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + else + { + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + } + + internal override void OnAPUClockSingle() + { + base.OnAPUClockSingle(); + snd_1.ClockSingle(); + snd_2.ClockSingle(); + snd_3.ClockSingle(); + } + + internal override void APUApplyChannelsSettings() + { + base.APUApplyChannelsSettings(); + snd_1.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SQ1; + snd_2.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SQ2; + snd_3.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SAW; + } + + internal override double APUGetSample() + { + return audio_pulse_table[snd_1.output + snd_2.output] + audio_tnd_table[snd_3.output]; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_reload); + stream.Write(irq_counter); + stream.Write(prescaler); + stream.Write(irq_mode_cycle); + stream.Write(irq_enable); + stream.Write(irq_enable_on_ak); + snd_1.SaveState(ref stream); + snd_2.SaveState(ref stream); + snd_3.SaveState(ref stream); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_reload = stream.ReadInt32(); + irq_counter = stream.ReadInt32(); + prescaler = stream.ReadInt32(); + irq_mode_cycle = stream.ReadBoolean(); + irq_enable = stream.ReadBoolean(); + irq_enable_on_ak = stream.ReadBoolean(); + snd_1.LoadState(ref stream); + snd_2.LoadState(ref stream); + snd_3.LoadState(ref stream); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper025.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper025.cs index 9583013..66b9c05 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper025.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper025.cs @@ -1,254 +1,253 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC4", 25)] - internal class Mapper025 : Board - { - private bool prg_mode; - - private byte prg_reg0; - - private int[] chr_Reg; - - private int irq_reload; - - private int irq_counter; - - private int prescaler; - - private bool irq_mode_cycle; - - private bool irq_enable; - - private bool irq_enable_on_ak; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - prescaler = 341; - chr_Reg = new int[8]; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address) - { - case 32768: - case 32769: - case 32770: - case 32771: - case 32772: - case 32776: - case 32780: - prg_reg0 = data; - Switch08KPRG(prg_mode ? (PRG_ROM_08KB_Mask - 1) : (prg_reg0 & 0x1F), PRGArea.Area8000); - Switch08KPRG(prg_mode ? (prg_reg0 & 0x1F) : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); - break; - case 36864: - case 36866: - case 36872: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 36865: - case 36867: - case 36868: - case 36876: - prg_mode = (data & 2) == 2; - Switch08KPRG(prg_mode ? (PRG_ROM_08KB_Mask - 1) : (prg_reg0 & 0x1F), PRGArea.Area8000); - Switch08KPRG(prg_mode ? (prg_reg0 & 0x1F) : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); - break; - case 40960: - case 40961: - case 40962: - case 40963: - case 40964: - case 40968: - case 40972: - Switch08KPRG(data & 0x1F, PRGArea.AreaA000); - break; - case 45056: - chr_Reg[0] = (chr_Reg[0] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[0], CHRArea.Area0000); - break; - case 45058: - case 45064: - chr_Reg[0] = (chr_Reg[0] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[0], CHRArea.Area0000); - break; - case 45057: - case 45060: - chr_Reg[1] = (chr_Reg[1] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[1], CHRArea.Area0400); - break; - case 45059: - case 45068: - chr_Reg[1] = (chr_Reg[1] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[1], CHRArea.Area0400); - break; - case 49152: - chr_Reg[2] = (chr_Reg[2] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[2], CHRArea.Area0800); - break; - case 49154: - case 49160: - chr_Reg[2] = (chr_Reg[2] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[2], CHRArea.Area0800); - break; - case 49153: - case 49156: - chr_Reg[3] = (chr_Reg[3] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); - break; - case 49155: - case 49164: - chr_Reg[3] = (chr_Reg[3] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); - break; - case 53248: - chr_Reg[4] = (chr_Reg[4] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[4], CHRArea.Area1000); - break; - case 53250: - case 53256: - chr_Reg[4] = (chr_Reg[4] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[4], CHRArea.Area1000); - break; - case 53249: - case 53252: - chr_Reg[5] = (chr_Reg[5] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[5], CHRArea.Area1400); - break; - case 53251: - case 53260: - chr_Reg[5] = (chr_Reg[5] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[5], CHRArea.Area1400); - break; - case 57344: - chr_Reg[6] = (chr_Reg[6] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[6], CHRArea.Area1800); - break; - case 57346: - case 57352: - chr_Reg[6] = (chr_Reg[6] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[6], CHRArea.Area1800); - break; - case 57345: - case 57348: - chr_Reg[7] = (chr_Reg[7] & 0xF0) | (data & 0xF); - Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); - break; - case 57347: - case 57356: - chr_Reg[7] = (chr_Reg[7] & 0xF) | ((data & 0xF) << 4); - Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); - break; - case 61440: - irq_reload = (irq_reload & 0xF0) | (data & 0xF); - break; - case 61442: - case 61448: - irq_reload = (irq_reload & 0xF) | ((data & 0xF) << 4); - break; - case 61441: - case 61444: - irq_mode_cycle = (data & 4) == 4; - irq_enable = (data & 2) == 2; - irq_enable_on_ak = (data & 1) == 1; - if (irq_enable) - { - irq_counter = irq_reload; - prescaler = 341; - } - NesEmu.IRQFlags &= -9; - break; - case 61443: - case 61452: - NesEmu.IRQFlags &= -9; - irq_enable = irq_enable_on_ak; - break; - } - } - - internal override void OnCPUClock() - { - if (!irq_enable) - { - return; - } - if (!irq_mode_cycle) - { - if (prescaler > 0) - { - prescaler -= 3; - return; - } - prescaler = 341; - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - else - { - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(prg_mode); - stream.Write(prg_reg0); - for (int i = 0; i < chr_Reg.Length; i++) - { - stream.Write(chr_Reg[i]); - } - stream.Write(irq_reload); - stream.Write(irq_counter); - stream.Write(prescaler); - stream.Write(irq_mode_cycle); - stream.Write(irq_enable); - stream.Write(irq_enable_on_ak); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - prg_mode = stream.ReadBoolean(); - prg_reg0 = stream.ReadByte(); - for (int i = 0; i < chr_Reg.Length; i++) - { - chr_Reg[i] = stream.ReadInt32(); - } - irq_reload = stream.ReadInt32(); - irq_counter = stream.ReadInt32(); - prescaler = stream.ReadInt32(); - irq_mode_cycle = stream.ReadBoolean(); - irq_enable = stream.ReadBoolean(); - irq_enable_on_ak = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC4", 25)] +internal class Mapper025 : Board +{ + private bool prg_mode; + + private byte prg_reg0; + + private int[] chr_Reg; + + private int irq_reload; + + private int irq_counter; + + private int prescaler; + + private bool irq_mode_cycle; + + private bool irq_enable; + + private bool irq_enable_on_ak; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + prescaler = 341; + chr_Reg = new int[8]; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address) + { + case 32768: + case 32769: + case 32770: + case 32771: + case 32772: + case 32776: + case 32780: + prg_reg0 = data; + Switch08KPRG(prg_mode ? (PRG_ROM_08KB_Mask - 1) : (prg_reg0 & 0x1F), PRGArea.Area8000); + Switch08KPRG(prg_mode ? (prg_reg0 & 0x1F) : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); + break; + case 36864: + case 36866: + case 36872: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 36865: + case 36867: + case 36868: + case 36876: + prg_mode = (data & 2) == 2; + Switch08KPRG(prg_mode ? (PRG_ROM_08KB_Mask - 1) : (prg_reg0 & 0x1F), PRGArea.Area8000); + Switch08KPRG(prg_mode ? (prg_reg0 & 0x1F) : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); + break; + case 40960: + case 40961: + case 40962: + case 40963: + case 40964: + case 40968: + case 40972: + Switch08KPRG(data & 0x1F, PRGArea.AreaA000); + break; + case 45056: + chr_Reg[0] = (chr_Reg[0] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[0], CHRArea.Area0000); + break; + case 45058: + case 45064: + chr_Reg[0] = (chr_Reg[0] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[0], CHRArea.Area0000); + break; + case 45057: + case 45060: + chr_Reg[1] = (chr_Reg[1] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[1], CHRArea.Area0400); + break; + case 45059: + case 45068: + chr_Reg[1] = (chr_Reg[1] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[1], CHRArea.Area0400); + break; + case 49152: + chr_Reg[2] = (chr_Reg[2] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[2], CHRArea.Area0800); + break; + case 49154: + case 49160: + chr_Reg[2] = (chr_Reg[2] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[2], CHRArea.Area0800); + break; + case 49153: + case 49156: + chr_Reg[3] = (chr_Reg[3] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); + break; + case 49155: + case 49164: + chr_Reg[3] = (chr_Reg[3] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[3], CHRArea.Area0C00); + break; + case 53248: + chr_Reg[4] = (chr_Reg[4] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[4], CHRArea.Area1000); + break; + case 53250: + case 53256: + chr_Reg[4] = (chr_Reg[4] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[4], CHRArea.Area1000); + break; + case 53249: + case 53252: + chr_Reg[5] = (chr_Reg[5] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[5], CHRArea.Area1400); + break; + case 53251: + case 53260: + chr_Reg[5] = (chr_Reg[5] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[5], CHRArea.Area1400); + break; + case 57344: + chr_Reg[6] = (chr_Reg[6] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[6], CHRArea.Area1800); + break; + case 57346: + case 57352: + chr_Reg[6] = (chr_Reg[6] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[6], CHRArea.Area1800); + break; + case 57345: + case 57348: + chr_Reg[7] = (chr_Reg[7] & 0xF0) | (data & 0xF); + Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); + break; + case 57347: + case 57356: + chr_Reg[7] = (chr_Reg[7] & 0xF) | ((data & 0xF) << 4); + Switch01KCHR(chr_Reg[7], CHRArea.Area1C00); + break; + case 61440: + irq_reload = (irq_reload & 0xF0) | (data & 0xF); + break; + case 61442: + case 61448: + irq_reload = (irq_reload & 0xF) | ((data & 0xF) << 4); + break; + case 61441: + case 61444: + irq_mode_cycle = (data & 4) == 4; + irq_enable = (data & 2) == 2; + irq_enable_on_ak = (data & 1) == 1; + if (irq_enable) + { + irq_counter = irq_reload; + prescaler = 341; + } + NesEmu.IRQFlags &= -9; + break; + case 61443: + case 61452: + NesEmu.IRQFlags &= -9; + irq_enable = irq_enable_on_ak; + break; + } + } + + internal override void OnCPUClock() + { + if (!irq_enable) + { + return; + } + if (!irq_mode_cycle) + { + if (prescaler > 0) + { + prescaler -= 3; + return; + } + prescaler = 341; + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + else + { + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(prg_mode); + stream.Write(prg_reg0); + for (int i = 0; i < chr_Reg.Length; i++) + { + stream.Write(chr_Reg[i]); + } + stream.Write(irq_reload); + stream.Write(irq_counter); + stream.Write(prescaler); + stream.Write(irq_mode_cycle); + stream.Write(irq_enable); + stream.Write(irq_enable_on_ak); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + prg_mode = stream.ReadBoolean(); + prg_reg0 = stream.ReadByte(); + for (int i = 0; i < chr_Reg.Length; i++) + { + chr_Reg[i] = stream.ReadInt32(); + } + irq_reload = stream.ReadInt32(); + irq_counter = stream.ReadInt32(); + prescaler = stream.ReadInt32(); + irq_mode_cycle = stream.ReadBoolean(); + irq_enable = stream.ReadBoolean(); + irq_enable_on_ak = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper026.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper026.cs index 72c4bbc..04afc91 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper026.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper026.cs @@ -1,245 +1,244 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC6", 26)] - [WithExternalSound] - internal class Mapper026 : Board - { - private int irq_reload; - - private int irq_counter; - - private int prescaler; - - private bool irq_mode_cycle; - - private bool irq_enable; - - private bool irq_enable_on_ak; - - private VRC6Pulse snd_1; - - private VRC6Pulse snd_2; - - private VRC6Sawtooth snd_3; - - private double[] audio_pulse_table; - - private double[] audio_tnd_table; - - internal override void Initialize(IRom rom) - { - base.Initialize(rom); - snd_1 = new VRC6Pulse(); - snd_2 = new VRC6Pulse(); - snd_3 = new VRC6Sawtooth(); - audio_pulse_table = new double[32]; - for (int i = 0; i < 32; i++) - { - audio_pulse_table[i] = 95.52 / (8128.0 / (double)i + 100.0); - } - audio_tnd_table = new double[204]; - for (int j = 0; j < 204; j++) - { - audio_tnd_table[j] = 163.67 / (24329.0 / (double)j + 100.0); - } - } - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - APUApplyChannelsSettings(); - snd_1.HardReset(); - snd_2.HardReset(); - snd_3.HardReset(); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address) - { - case 32768: - case 32769: - case 32770: - case 32771: - Switch16KPRG(data, PRGArea.Area8000); - break; - case 36864: - snd_1.Write0(ref data); - break; - case 36866: - snd_1.Write1(ref data); - break; - case 36865: - snd_1.Write2(ref data); - break; - case 40960: - snd_2.Write0(ref data); - break; - case 40962: - snd_2.Write1(ref data); - break; - case 40961: - snd_2.Write2(ref data); - break; - case 45056: - snd_3.Write0(ref data); - break; - case 45058: - snd_3.Write1(ref data); - break; - case 45057: - snd_3.Write2(ref data); - break; - case 45059: - switch ((data & 0xC) >> 2) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 49152: - case 49153: - case 49154: - case 49155: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 53248: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 53250: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 53249: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 53251: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 57344: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 57346: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 57345: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 57347: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 61440: - irq_reload = data; - break; - case 61442: - irq_mode_cycle = (data & 4) == 4; - irq_enable = (data & 2) == 2; - irq_enable_on_ak = (data & 1) == 1; - if (irq_enable) - { - irq_counter = irq_reload; - prescaler = 341; - } - NesEmu.IRQFlags &= -9; - break; - case 61441: - NesEmu.IRQFlags &= -9; - irq_enable = irq_enable_on_ak; - break; - } - } - - internal override void OnCPUClock() - { - if (!irq_enable) - { - return; - } - if (!irq_mode_cycle) - { - if (prescaler > 0) - { - prescaler -= 3; - return; - } - prescaler = 341; - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - else - { - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - } - - internal override void OnAPUClockSingle() - { - base.OnAPUClockSingle(); - snd_1.ClockSingle(); - snd_2.ClockSingle(); - snd_3.ClockSingle(); - } - - internal override void APUApplyChannelsSettings() - { - base.APUApplyChannelsSettings(); - snd_1.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SQ1; - snd_2.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SQ2; - snd_3.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SAW; - } - - internal override double APUGetSample() - { - return audio_pulse_table[snd_1.output + snd_2.output] + audio_tnd_table[snd_3.output]; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_reload); - stream.Write(irq_counter); - stream.Write(prescaler); - stream.Write(irq_mode_cycle); - stream.Write(irq_enable); - stream.Write(irq_enable_on_ak); - snd_1.SaveState(ref stream); - snd_2.SaveState(ref stream); - snd_3.SaveState(ref stream); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_reload = stream.ReadInt32(); - irq_counter = stream.ReadInt32(); - prescaler = stream.ReadInt32(); - irq_mode_cycle = stream.ReadBoolean(); - irq_enable = stream.ReadBoolean(); - irq_enable_on_ak = stream.ReadBoolean(); - snd_1.LoadState(ref stream); - snd_2.LoadState(ref stream); - snd_3.LoadState(ref stream); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC6", 26)] +[WithExternalSound] +internal class Mapper026 : Board +{ + private int irq_reload; + + private int irq_counter; + + private int prescaler; + + private bool irq_mode_cycle; + + private bool irq_enable; + + private bool irq_enable_on_ak; + + private VRC6Pulse snd_1; + + private VRC6Pulse snd_2; + + private VRC6Sawtooth snd_3; + + private double[] audio_pulse_table; + + private double[] audio_tnd_table; + + internal override void Initialize(IRom rom) + { + base.Initialize(rom); + snd_1 = new VRC6Pulse(); + snd_2 = new VRC6Pulse(); + snd_3 = new VRC6Sawtooth(); + audio_pulse_table = new double[32]; + for (int i = 0; i < 32; i++) + { + audio_pulse_table[i] = 95.52 / (8128.0 / (double)i + 100.0); + } + audio_tnd_table = new double[204]; + for (int j = 0; j < 204; j++) + { + audio_tnd_table[j] = 163.67 / (24329.0 / (double)j + 100.0); + } + } + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + APUApplyChannelsSettings(); + snd_1.HardReset(); + snd_2.HardReset(); + snd_3.HardReset(); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address) + { + case 32768: + case 32769: + case 32770: + case 32771: + Switch16KPRG(data, PRGArea.Area8000); + break; + case 36864: + snd_1.Write0(ref data); + break; + case 36866: + snd_1.Write1(ref data); + break; + case 36865: + snd_1.Write2(ref data); + break; + case 40960: + snd_2.Write0(ref data); + break; + case 40962: + snd_2.Write1(ref data); + break; + case 40961: + snd_2.Write2(ref data); + break; + case 45056: + snd_3.Write0(ref data); + break; + case 45058: + snd_3.Write1(ref data); + break; + case 45057: + snd_3.Write2(ref data); + break; + case 45059: + switch ((data & 0xC) >> 2) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 49152: + case 49153: + case 49154: + case 49155: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 53248: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 53250: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 53249: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 53251: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 57344: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 57346: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 57345: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 57347: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 61440: + irq_reload = data; + break; + case 61442: + irq_mode_cycle = (data & 4) == 4; + irq_enable = (data & 2) == 2; + irq_enable_on_ak = (data & 1) == 1; + if (irq_enable) + { + irq_counter = irq_reload; + prescaler = 341; + } + NesEmu.IRQFlags &= -9; + break; + case 61441: + NesEmu.IRQFlags &= -9; + irq_enable = irq_enable_on_ak; + break; + } + } + + internal override void OnCPUClock() + { + if (!irq_enable) + { + return; + } + if (!irq_mode_cycle) + { + if (prescaler > 0) + { + prescaler -= 3; + return; + } + prescaler = 341; + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + else + { + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + } + + internal override void OnAPUClockSingle() + { + base.OnAPUClockSingle(); + snd_1.ClockSingle(); + snd_2.ClockSingle(); + snd_3.ClockSingle(); + } + + internal override void APUApplyChannelsSettings() + { + base.APUApplyChannelsSettings(); + snd_1.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SQ1; + snd_2.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SQ2; + snd_3.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_VRC6_SAW; + } + + internal override double APUGetSample() + { + return audio_pulse_table[snd_1.output + snd_2.output] + audio_tnd_table[snd_3.output]; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_reload); + stream.Write(irq_counter); + stream.Write(prescaler); + stream.Write(irq_mode_cycle); + stream.Write(irq_enable); + stream.Write(irq_enable_on_ak); + snd_1.SaveState(ref stream); + snd_2.SaveState(ref stream); + snd_3.SaveState(ref stream); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_reload = stream.ReadInt32(); + irq_counter = stream.ReadInt32(); + prescaler = stream.ReadInt32(); + irq_mode_cycle = stream.ReadBoolean(); + irq_enable = stream.ReadBoolean(); + irq_enable_on_ak = stream.ReadBoolean(); + snd_1.LoadState(ref stream); + snd_2.LoadState(ref stream); + snd_3.LoadState(ref stream); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper032.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper032.cs index eb5d7e7..2870936 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper032.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper032.cs @@ -1,109 +1,108 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Irem G-101", 32)] - internal class Mapper032 : Board - { - private bool prg_mode; - - private byte prg_reg0; - - private bool enable_mirroring_switch; - - internal override void HardReset() - { - base.HardReset(); - enable_mirroring_switch = true; - if (SHA1 == "7E4180432726A433C46BA2206D9E13B32761C11E") - { - enable_mirroring_switch = false; - Switch01KNMTFromMirroring(Mirroring.OneScA); - } - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF007) - { - case 32768: - case 32769: - case 32770: - case 32771: - case 32772: - case 32773: - case 32774: - case 32775: - prg_reg0 = data; - Switch08KPRG((!prg_mode) ? prg_reg0 : 0, PRGArea.Area8000); - Switch08KPRG(prg_mode ? prg_reg0 : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); - break; - case 36864: - case 36865: - case 36866: - case 36867: - case 36868: - case 36869: - case 36870: - case 36871: - prg_mode = (data & 2) == 2; - Switch08KPRG((!prg_mode) ? prg_reg0 : 0, PRGArea.Area8000); - Switch08KPRG(prg_mode ? prg_reg0 : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); - if (enable_mirroring_switch) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40960: - case 40961: - case 40962: - case 40963: - case 40964: - case 40965: - case 40966: - case 40967: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 45056: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 45057: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 45058: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 45059: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 45060: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 45061: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 45062: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 45063: - Switch01KCHR(data, CHRArea.Area1C00); - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(prg_mode); - stream.Write(prg_reg0); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - prg_mode = stream.ReadBoolean(); - prg_reg0 = stream.ReadByte(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Irem G-101", 32)] +internal class Mapper032 : Board +{ + private bool prg_mode; + + private byte prg_reg0; + + private bool enable_mirroring_switch; + + internal override void HardReset() + { + base.HardReset(); + enable_mirroring_switch = true; + if (SHA1 == "7E4180432726A433C46BA2206D9E13B32761C11E") + { + enable_mirroring_switch = false; + Switch01KNMTFromMirroring(Mirroring.OneScA); + } + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF007) + { + case 32768: + case 32769: + case 32770: + case 32771: + case 32772: + case 32773: + case 32774: + case 32775: + prg_reg0 = data; + Switch08KPRG((!prg_mode) ? prg_reg0 : 0, PRGArea.Area8000); + Switch08KPRG(prg_mode ? prg_reg0 : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); + break; + case 36864: + case 36865: + case 36866: + case 36867: + case 36868: + case 36869: + case 36870: + case 36871: + prg_mode = (data & 2) == 2; + Switch08KPRG((!prg_mode) ? prg_reg0 : 0, PRGArea.Area8000); + Switch08KPRG(prg_mode ? prg_reg0 : (PRG_ROM_08KB_Mask - 1), PRGArea.AreaC000); + if (enable_mirroring_switch) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40960: + case 40961: + case 40962: + case 40963: + case 40964: + case 40965: + case 40966: + case 40967: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 45056: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 45057: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 45058: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 45059: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 45060: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 45061: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 45062: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 45063: + Switch01KCHR(data, CHRArea.Area1C00); + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(prg_mode); + stream.Write(prg_reg0); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + prg_mode = stream.ReadBoolean(); + prg_reg0 = stream.ReadByte(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper033.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper033.cs index b1c91fd..40f1c58 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper033.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper033.cs @@ -1,177 +1,176 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Taito TC0190/TC0350", 33)] - [HassIssues] - internal class Mapper033 : Board - { - private bool MODE; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override string Issues => MNInterfaceLanguage.IssueMapper33; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - MODE = true; - if (IsGameFoundOnDB) - { - foreach (string chip in base.Chips) - { - if (chip.Contains("TC0190")) - { - MODE = false; - ppuA12TogglesOnRaisingEdge = true; - enabled_ppuA12ToggleTimer = true; - break; - } - } - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - mmc3_alt_behavior = false; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if (!MODE) - { - switch (address & 0xE003) - { - case 32768: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 32769: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 32770: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 32771: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 40960: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 40961: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 40962: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 40963: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 49152: - irq_reload = (byte)(data ^ 0xFFu); - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 49154: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 49155: - irq_enabled = true; - break; - case 57344: - Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); - break; - } - } - else - { - switch (address & 0xA003) - { - case 32768: - Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); - Switch08KPRG(data & 0x3F, PRGArea.Area8000); - break; - case 32769: - Switch08KPRG(data & 0x3F, PRGArea.AreaA000); - break; - case 32770: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 32771: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 40960: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 40961: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 40962: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 40963: - Switch01KCHR(data, CHRArea.Area1C00); - break; - } - } - } - - internal override void OnPPUA12RaisingEdge() - { - if (!MODE) - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Taito TC0190/TC0350", 33)] +[HassIssues] +internal class Mapper033 : Board +{ + private bool MODE; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override string Issues => MNInterfaceLanguage.IssueMapper33; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + MODE = true; + if (IsGameFoundOnDB) + { + foreach (string chip in base.Chips) + { + if (chip.Contains("TC0190")) + { + MODE = false; + ppuA12TogglesOnRaisingEdge = true; + enabled_ppuA12ToggleTimer = true; + break; + } + } + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + mmc3_alt_behavior = false; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if (!MODE) + { + switch (address & 0xE003) + { + case 32768: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 32769: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 32770: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 32771: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 40960: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 40961: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 40962: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 40963: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 49152: + irq_reload = (byte)(data ^ 0xFFu); + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 49154: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 49155: + irq_enabled = true; + break; + case 57344: + Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); + break; + } + } + else + { + switch (address & 0xA003) + { + case 32768: + Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); + Switch08KPRG(data & 0x3F, PRGArea.Area8000); + break; + case 32769: + Switch08KPRG(data & 0x3F, PRGArea.AreaA000); + break; + case 32770: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 32771: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 40960: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 40961: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 40962: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 40963: + Switch01KCHR(data, CHRArea.Area1C00); + break; + } + } + } + + internal override void OnPPUA12RaisingEdge() + { + if (!MODE) + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper034.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper034.cs index 646157e..6421e4d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper034.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper034.cs @@ -1,50 +1,49 @@ -namespace MyNes.Core -{ - [BoardInfo("BxROM/NINA-001", 34)] - internal class Mapper034 : Board - { - private bool BxROM; - - private byte writeData; - - internal override void HardReset() - { - base.HardReset(); - BxROM = true; - if (base.BoardType.Contains("NINA")) - { - BxROM = false; - } - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - base.WriteSRM(ref address, ref data); - if (!BxROM) - { - switch (address) - { - case 32765: - Switch32KPRG(data, PRGArea.Area8000); - break; - case 32766: - Switch04KCHR(data, CHRArea.Area0000); - break; - case 32767: - Switch04KCHR(data, CHRArea.Area1000); - break; - } - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if (BxROM) - { - ReadPRG(ref address, out writeData); - writeData &= data; - Switch32KPRG(writeData, PRGArea.Area8000); - } - } - } +namespace MyNes.Core; + +[BoardInfo("BxROM/NINA-001", 34)] +internal class Mapper034 : Board +{ + private bool BxROM; + + private byte writeData; + + internal override void HardReset() + { + base.HardReset(); + BxROM = true; + if (base.BoardType.Contains("NINA")) + { + BxROM = false; + } + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + base.WriteSRM(ref address, ref data); + if (!BxROM) + { + switch (address) + { + case 32765: + Switch32KPRG(data, PRGArea.Area8000); + break; + case 32766: + Switch04KCHR(data, CHRArea.Area0000); + break; + case 32767: + Switch04KCHR(data, CHRArea.Area1000); + break; + } + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if (BxROM) + { + ReadPRG(ref address, out writeData); + writeData &= data; + Switch32KPRG(writeData, PRGArea.Area8000); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper041.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper041.cs index 31d1ad4..65e89e9 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper041.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper041.cs @@ -1,58 +1,57 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Caltron 6-in-1", 41)] - internal class Mapper041 : Board - { - private bool enableReg = false; - - private int vromReg = 0; - - internal override void HardReset() - { - base.HardReset(); - vromReg = 0; - enableReg = true; - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - if (address <= 26623) - { - Switch32KPRG(address & 7, PRGArea.Area8000); - enableReg = (address & 4) == 4; - vromReg = (vromReg & 3) | ((address >> 1) & 0xC); - Switch08KCHR(vromReg); - Switch01KNMTFromMirroring(((address & 0x20) == 32) ? Mirroring.Horz : Mirroring.Vert); - } - else - { - base.WriteSRM(ref address, ref data); - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if (enableReg) - { - vromReg = (vromReg & 0xC) | (data & 3); - Switch08KCHR(vromReg); - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(enableReg); - stream.Write(vromReg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - enableReg = stream.ReadBoolean(); - vromReg = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Caltron 6-in-1", 41)] +internal class Mapper041 : Board +{ + private bool enableReg; + + private int vromReg; + + internal override void HardReset() + { + base.HardReset(); + vromReg = 0; + enableReg = true; + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + if (address <= 26623) + { + Switch32KPRG(address & 7, PRGArea.Area8000); + enableReg = (address & 4) == 4; + vromReg = (vromReg & 3) | ((address >> 1) & 0xC); + Switch08KCHR(vromReg); + Switch01KNMTFromMirroring(((address & 0x20) == 32) ? Mirroring.Horz : Mirroring.Vert); + } + else + { + base.WriteSRM(ref address, ref data); + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if (enableReg) + { + vromReg = (vromReg & 0xC) | (data & 3); + Switch08KCHR(vromReg); + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(enableReg); + stream.Write(vromReg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + enableReg = stream.ReadBoolean(); + vromReg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper042.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper042.cs index bf1f406..1d2f26b 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper042.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper042.cs @@ -1,94 +1,93 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Mario Baby", 42)] - internal class Mapper042 : Board - { - private int SRAM_PRG_Page = 0; - - private bool irqEnable = false; - - private int irqCounter = 0; - - internal override void HardReset() - { - base.HardReset(); - Switch32KPRG(PRG_ROM_32KB_Mask, PRGArea.Area8000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if (address == 32768) - { - Switch08KCHR(data); - return; - } - if (address == 61440) - { - SRAM_PRG_Page = data << 13; - return; - } - switch (address & 0xE003) - { - case 57344: - Switch08KPRG(data, PRGArea.Area6000); - break; - case 57345: - if ((data & 8) == 8) - { - Switch01KNMTFromMirroring(Mirroring.Horz); - } - else - { - Switch01KNMTFromMirroring(Mirroring.Vert); - } - break; - case 57346: - irqEnable = (data & 2) == 2; - if (!irqEnable) - { - irqCounter = 0; - } - NesEmu.IRQFlags &= -9; - break; - } - } - - internal override void OnCPUClock() - { - if (!irqEnable) - { - return; - } - int num = irqCounter++; - if ((irqCounter & 0x6000) != (num & 0x6000)) - { - if ((irqCounter & 0x6000) == 24576) - { - NesEmu.IRQFlags |= 8; - } - else - { - NesEmu.IRQFlags &= -9; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(SRAM_PRG_Page); - stream.Write(irqEnable); - stream.Write(irqCounter); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - SRAM_PRG_Page = stream.ReadInt32(); - irqEnable = stream.ReadBoolean(); - irqCounter = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Mario Baby", 42)] +internal class Mapper042 : Board +{ + private int SRAM_PRG_Page; + + private bool irqEnable; + + private int irqCounter; + + internal override void HardReset() + { + base.HardReset(); + Switch32KPRG(PRG_ROM_32KB_Mask, PRGArea.Area8000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if (address == 32768) + { + Switch08KCHR(data); + return; + } + if (address == 61440) + { + SRAM_PRG_Page = data << 13; + return; + } + switch (address & 0xE003) + { + case 57344: + Switch08KPRG(data, PRGArea.Area6000); + break; + case 57345: + if ((data & 8) == 8) + { + Switch01KNMTFromMirroring(Mirroring.Horz); + } + else + { + Switch01KNMTFromMirroring(Mirroring.Vert); + } + break; + case 57346: + irqEnable = (data & 2) == 2; + if (!irqEnable) + { + irqCounter = 0; + } + NesEmu.IRQFlags &= -9; + break; + } + } + + internal override void OnCPUClock() + { + if (!irqEnable) + { + return; + } + int num = irqCounter++; + if ((irqCounter & 0x6000) != (num & 0x6000)) + { + if ((irqCounter & 0x6000) == 24576) + { + NesEmu.IRQFlags |= 8; + } + else + { + NesEmu.IRQFlags &= -9; + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(SRAM_PRG_Page); + stream.Write(irqEnable); + stream.Write(irqCounter); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + SRAM_PRG_Page = stream.ReadInt32(); + irqEnable = stream.ReadBoolean(); + irqCounter = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper044.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper044.cs index 01a6f5e..fc29ee6 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper044.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper044.cs @@ -1,235 +1,234 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("7-in-1 MMC3 Port A001h", 44, true, true)] - [HassIssues] - internal class Mapper044 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int block; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - private int prg_and; - - private int prg_or; - - private int chr_and; - - private int chr_or; - - internal override string Issues => MNInterfaceLanguage.IssueMapper44; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_and = 15; - prg_or = 0; - chr_and = 127; - chr_or = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - block = data & 7; - prg_and = ((block > 5) ? 31 : 15); - prg_or = ((block < 5) ? (block << 4) : 96); - chr_and = ((block > 5) ? 255 : 127); - chr_or = ((block < 5) ? (block << 7) : 768); - SetupPRG(); - SetupCHR(); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); - } - else - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); - Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); - Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); - Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - stream.Write(block); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(prg_and); - stream.Write(prg_or); - stream.Write(chr_and); - stream.Write(chr_or); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - block = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - prg_and = stream.ReadInt32(); - prg_or = stream.ReadInt32(); - chr_and = stream.ReadInt32(); - chr_or = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("7-in-1 MMC3 Port A001h", 44, true, true)] +[HassIssues] +internal class Mapper044 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int block; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + private int prg_and; + + private int prg_or; + + private int chr_and; + + private int chr_or; + + internal override string Issues => MNInterfaceLanguage.IssueMapper44; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_and = 15; + prg_or = 0; + chr_and = 127; + chr_or = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + block = data & 7; + prg_and = ((block > 5) ? 31 : 15); + prg_or = ((block < 5) ? (block << 4) : 96); + chr_and = ((block > 5) ? 255 : 127); + chr_or = ((block < 5) ? (block << 7) : 768); + SetupPRG(); + SetupCHR(); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); + } + else + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); + Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); + Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); + Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + stream.Write(block); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(prg_and); + stream.Write(prg_or); + stream.Write(chr_and); + stream.Write(chr_or); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + block = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + prg_and = stream.ReadInt32(); + prg_or = stream.ReadInt32(); + chr_and = stream.ReadInt32(); + chr_or = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper045.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper045.cs index dd83b69..6f4300c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper045.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper045.cs @@ -1,294 +1,293 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("X-in-1 MMC3 Port 6000hx4", 45, true, true)] - internal class Mapper045 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - private bool locked; - - private int regCounter; - - private int prg_and; - - private int prg_or; - - private int chr_and; - - private int chr_or; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_and = 63; - prg_or = 0; - chr_and = 4095; - chr_or = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - locked = false; - regCounter = 0; - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - if (locked) - { - base.WriteSRM(ref address, ref data); - return; - } - switch (regCounter) - { - case 0: - chr_or = (chr_or & 0xFF00) | data; - SetupCHR(); - break; - case 1: - prg_or = data; - SetupPRG(); - break; - case 2: - if ((data & 8) == 8) - { - chr_and = (1 << (data & 7) + 1) - 1; - } - else - { - chr_and = ((data <= 0) ? (-1) : 0); - } - chr_or = (chr_or & 0xFF) | ((data & 0xF0) << 4); - SetupCHR(); - break; - case 3: - locked = (data & 0x40) == 64; - prg_and = (data & 0x3F) ^ 0x3F; - SetupPRG(); - break; - } - regCounter++; - if (regCounter > 3) - { - regCounter = 0; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); - } - else - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); - Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); - Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); - Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(prg_and); - stream.Write(prg_or); - stream.Write(chr_and); - stream.Write(chr_or); - stream.Write(locked); - stream.Write(regCounter); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - prg_and = stream.ReadInt32(); - prg_or = stream.ReadInt32(); - chr_and = stream.ReadInt32(); - chr_or = stream.ReadInt32(); - locked = stream.ReadBoolean(); - regCounter = stream.ReadInt32(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("X-in-1 MMC3 Port 6000hx4", 45, true, true)] +internal class Mapper045 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + private bool locked; + + private int regCounter; + + private int prg_and; + + private int prg_or; + + private int chr_and; + + private int chr_or; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_and = 63; + prg_or = 0; + chr_and = 4095; + chr_or = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + locked = false; + regCounter = 0; + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + if (locked) + { + base.WriteSRM(ref address, ref data); + return; + } + switch (regCounter) + { + case 0: + chr_or = (chr_or & 0xFF00) | data; + SetupCHR(); + break; + case 1: + prg_or = data; + SetupPRG(); + break; + case 2: + if ((data & 8) == 8) + { + chr_and = (1 << (data & 7) + 1) - 1; + } + else + { + chr_and = ((data <= 0) ? (-1) : 0); + } + chr_or = (chr_or & 0xFF) | ((data & 0xF0) << 4); + SetupCHR(); + break; + case 3: + locked = (data & 0x40) == 64; + prg_and = (data & 0x3F) ^ 0x3F; + SetupPRG(); + break; + } + regCounter++; + if (regCounter > 3) + { + regCounter = 0; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); + } + else + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); + Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); + Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); + Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(prg_and); + stream.Write(prg_or); + stream.Write(chr_and); + stream.Write(chr_or); + stream.Write(locked); + stream.Write(regCounter); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + prg_and = stream.ReadInt32(); + prg_or = stream.ReadInt32(); + chr_and = stream.ReadInt32(); + chr_or = stream.ReadInt32(); + locked = stream.ReadBoolean(); + regCounter = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper046.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper046.cs index 3afdda6..fee5029 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper046.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper046.cs @@ -1,42 +1,41 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("15-in-1 Color Dreams", 46)] - internal class Mapper046 : Board - { - private int prg_reg; - - private int chr_reg; - - internal override void WriteSRM(ref ushort address, ref byte data) - { - prg_reg = (prg_reg & 1) | ((data << 1) & 0x1E); - chr_reg = (chr_reg & 7) | ((data >> 1) & 0x78); - Switch08KCHR(chr_reg); - Switch32KPRG(prg_reg, PRGArea.Area8000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - prg_reg = (data & 1) | (prg_reg & 0x1E); - chr_reg = ((data >> 4) & 7) | (chr_reg & 0x78); - Switch08KCHR(chr_reg); - Switch32KPRG(prg_reg, PRGArea.Area8000); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(prg_reg); - stream.Write(chr_reg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - prg_reg = stream.ReadInt32(); - chr_reg = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("15-in-1 Color Dreams", 46)] +internal class Mapper046 : Board +{ + private int prg_reg; + + private int chr_reg; + + internal override void WriteSRM(ref ushort address, ref byte data) + { + prg_reg = (prg_reg & 1) | ((data << 1) & 0x1E); + chr_reg = (chr_reg & 7) | ((data >> 1) & 0x78); + Switch08KCHR(chr_reg); + Switch32KPRG(prg_reg, PRGArea.Area8000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + prg_reg = (data & 1) | (prg_reg & 0x1E); + chr_reg = ((data >> 4) & 7) | (chr_reg & 0x78); + Switch08KCHR(chr_reg); + Switch32KPRG(prg_reg, PRGArea.Area8000); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(prg_reg); + stream.Write(chr_reg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + prg_reg = stream.ReadInt32(); + chr_reg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper047.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper047.cs index e81fbfb..4d46fd2 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper047.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper047.cs @@ -1,258 +1,257 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("2-in-1 MMC3 Port 6000h", 47, true, true)] - internal class Mapper047 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - private int block; - - private int prg_and; - - private int prg_or; - - private int chr_and; - - private int chr_or; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_and = 15; - prg_or = 0; - chr_and = 127; - chr_or = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - if (PRG_RAM_ENABLED[PRG_AREA_BLK_INDEX[0]] && PRG_RAM_WRITABLE[PRG_AREA_BLK_INDEX[0]]) - { - block = data & 1; - prg_or = block << 4; - chr_or = block << 7; - SetupCHR(); - SetupPRG(); - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); - } - else - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); - Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); - Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); - Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - stream.Write(block); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(prg_and); - stream.Write(prg_or); - stream.Write(chr_and); - stream.Write(chr_or); - stream.Write(irq_enabled); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - block = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - prg_and = stream.ReadInt32(); - prg_or = stream.ReadInt32(); - chr_and = stream.ReadInt32(); - chr_or = stream.ReadInt32(); - irq_enabled = stream.ReadBoolean(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("2-in-1 MMC3 Port 6000h", 47, true, true)] +internal class Mapper047 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + private int block; + + private int prg_and; + + private int prg_or; + + private int chr_and; + + private int chr_or; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_and = 15; + prg_or = 0; + chr_and = 127; + chr_or = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + if (PRG_RAM_ENABLED[PRG_AREA_BLK_INDEX[0]] && PRG_RAM_WRITABLE[PRG_AREA_BLK_INDEX[0]]) + { + block = data & 1; + prg_or = block << 4; + chr_or = block << 7; + SetupCHR(); + SetupPRG(); + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); + } + else + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); + Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); + Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); + Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + stream.Write(block); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(prg_and); + stream.Write(prg_or); + stream.Write(chr_and); + stream.Write(chr_or); + stream.Write(irq_enabled); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + block = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + prg_and = stream.ReadInt32(); + prg_or = stream.ReadInt32(); + chr_and = stream.ReadInt32(); + chr_or = stream.ReadInt32(); + irq_enabled = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper048.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper048.cs index 943b319..0eb5b5a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper048.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper048.cs @@ -1,172 +1,171 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Taito TC0190/TC0350", 48, true, true)] - internal class Mapper048 : Board - { - private bool MODE; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - MODE = false; - if (IsGameFoundOnDB) - { - foreach (string chip in base.Chips) - { - if (chip.Contains("TC0350")) - { - MODE = true; - break; - } - } - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - mmc3_alt_behavior = false; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if (!MODE) - { - switch (address & 0xE003) - { - case 32768: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 32769: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 32770: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 32771: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 40960: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 40961: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 40962: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 40963: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 49152: - irq_reload = (byte)(data ^ 0xFFu); - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 49154: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 49155: - irq_enabled = true; - break; - case 57344: - Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); - break; - } - } - else - { - switch (address & 0xA003) - { - case 32768: - Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); - Switch08KPRG(data & 0x3F, PRGArea.Area8000); - break; - case 32769: - Switch08KPRG(data & 0x3F, PRGArea.AreaA000); - break; - case 32770: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 32771: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 40960: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 40961: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 40962: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 40963: - Switch01KCHR(data, CHRArea.Area1C00); - break; - } - } - } - - internal override void OnPPUA12RaisingEdge() - { - if (!MODE) - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Taito TC0190/TC0350", 48, true, true)] +internal class Mapper048 : Board +{ + private bool MODE; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + MODE = false; + if (IsGameFoundOnDB) + { + foreach (string chip in base.Chips) + { + if (chip.Contains("TC0350")) + { + MODE = true; + break; + } + } + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + mmc3_alt_behavior = false; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if (!MODE) + { + switch (address & 0xE003) + { + case 32768: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 32769: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 32770: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 32771: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 40960: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 40961: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 40962: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 40963: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 49152: + irq_reload = (byte)(data ^ 0xFFu); + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 49154: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 49155: + irq_enabled = true; + break; + case 57344: + Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); + break; + } + } + else + { + switch (address & 0xA003) + { + case 32768: + Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Horz : Mirroring.Vert); + Switch08KPRG(data & 0x3F, PRGArea.Area8000); + break; + case 32769: + Switch08KPRG(data & 0x3F, PRGArea.AreaA000); + break; + case 32770: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 32771: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 40960: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 40961: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 40962: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 40963: + Switch01KCHR(data, CHRArea.Area1C00); + break; + } + } + } + + internal override void OnPPUA12RaisingEdge() + { + if (!MODE) + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper049.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper049.cs index caf34f5..8fb7b7d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper049.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper049.cs @@ -1,272 +1,271 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("4-in-1 MMC3 Port 6xxxh", 49, true, true)] - internal class Mapper049 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - private bool prg_32Mode; - - private int prg_32Page; - - private int prg_and; - - private int prg_or; - - private int chr_and; - - private int chr_or; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - prg_32Mode = false; - prg_32Page = 0; - address_8001 = 0; - prg_and = 15; - prg_or = 0; - chr_and = 127; - chr_or = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - if (PRG_RAM_ENABLED[PRG_AREA_BLK_INDEX[0]] && PRG_RAM_WRITABLE[PRG_AREA_BLK_INDEX[0]]) - { - prg_32Mode = (data & 1) == 1; - prg_or = (data >> 2) & 0x30; - chr_or = (data & 0xC0) << 1; - prg_32Page = (data >> 4) & 3; - SetupCHR(); - SetupPRG(); - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); - } - else - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - if (prg_32Mode) - { - Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); - Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); - Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); - Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); - } - else - { - Switch32KPRG(prg_32Page, PRGArea.Area8000); - } - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(prg_and); - stream.Write(prg_or); - stream.Write(chr_and); - stream.Write(chr_or); - stream.Write(prg_32Mode); - stream.Write(prg_32Page); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - prg_and = stream.ReadInt32(); - prg_or = stream.ReadInt32(); - chr_and = stream.ReadInt32(); - chr_or = stream.ReadInt32(); - prg_32Mode = stream.ReadBoolean(); - prg_32Page = stream.ReadInt32(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("4-in-1 MMC3 Port 6xxxh", 49, true, true)] +internal class Mapper049 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + private bool prg_32Mode; + + private int prg_32Page; + + private int prg_and; + + private int prg_or; + + private int chr_and; + + private int chr_or; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + prg_32Mode = false; + prg_32Page = 0; + address_8001 = 0; + prg_and = 15; + prg_or = 0; + chr_and = 127; + chr_or = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + if (PRG_RAM_ENABLED[PRG_AREA_BLK_INDEX[0]] && PRG_RAM_WRITABLE[PRG_AREA_BLK_INDEX[0]]) + { + prg_32Mode = (data & 1) == 1; + prg_or = (data >> 2) & 0x30; + chr_or = (data & 0xC0) << 1; + prg_32Page = (data >> 4) & 3; + SetupCHR(); + SetupPRG(); + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); + } + else + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + if (prg_32Mode) + { + Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); + Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); + Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); + Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); + } + else + { + Switch32KPRG(prg_32Page, PRGArea.Area8000); + } + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(prg_and); + stream.Write(prg_or); + stream.Write(chr_and); + stream.Write(chr_or); + stream.Write(prg_32Mode); + stream.Write(prg_32Page); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + prg_and = stream.ReadInt32(); + prg_or = stream.ReadInt32(); + chr_and = stream.ReadInt32(); + chr_or = stream.ReadInt32(); + prg_32Mode = stream.ReadBoolean(); + prg_32Page = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper050.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper050.cs index 637f772..d32fe19 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper050.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper050.cs @@ -1,71 +1,70 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("FDS-Port - Alt. Levels", 50)] - internal class Mapper050 : Board - { - private int prg_page; - - private int irq_counter; - - private bool irq_enabled; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(15, PRGArea.Area6000); - Switch08KPRG(8, PRGArea.Area8000); - Switch08KPRG(9, PRGArea.AreaA000); - Switch08KPRG(11, PRGArea.AreaE000); - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - switch (address & 0x4120) - { - case 16416: - prg_page = (data & 8) | ((data & 1) << 2) | ((data >> 1) & 3); - Switch08KPRG(prg_page, PRGArea.AreaC000); - break; - case 16672: - irq_enabled = (data & 1) == 1; - if (!irq_enabled) - { - irq_counter = 0; - NesEmu.IRQFlags &= -9; - } - break; - } - } - - internal override void OnCPUClock() - { - if (irq_enabled) - { - irq_counter++; - if (irq_counter == 4096) - { - NesEmu.IRQFlags |= 8; - irq_counter = 0; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(prg_page); - stream.Write(irq_counter); - stream.Write(irq_enabled); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - prg_page = stream.ReadInt32(); - irq_counter = stream.ReadInt32(); - irq_enabled = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("FDS-Port - Alt. Levels", 50)] +internal class Mapper050 : Board +{ + private int prg_page; + + private int irq_counter; + + private bool irq_enabled; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(15, PRGArea.Area6000); + Switch08KPRG(8, PRGArea.Area8000); + Switch08KPRG(9, PRGArea.AreaA000); + Switch08KPRG(11, PRGArea.AreaE000); + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + switch (address & 0x4120) + { + case 16416: + prg_page = (data & 8) | ((data & 1) << 2) | ((data >> 1) & 3); + Switch08KPRG(prg_page, PRGArea.AreaC000); + break; + case 16672: + irq_enabled = (data & 1) == 1; + if (!irq_enabled) + { + irq_counter = 0; + NesEmu.IRQFlags &= -9; + } + break; + } + } + + internal override void OnCPUClock() + { + if (irq_enabled) + { + irq_counter++; + if (irq_counter == 4096) + { + NesEmu.IRQFlags |= 8; + irq_counter = 0; + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(prg_page); + stream.Write(irq_counter); + stream.Write(irq_enabled); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + prg_page = stream.ReadInt32(); + irq_counter = stream.ReadInt32(); + irq_enabled = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper051.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper051.cs index e769f4d..b02e9b0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper051.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper051.cs @@ -1,79 +1,78 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("11-in-1", 51)] - internal class Mapper051 : Board - { - private int bank = 0; - - private int mode = 1; - - private int offset; - - internal override void HardReset() - { - base.HardReset(); - bank = 0; - mode = 1; - offset = 0; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE000) - { - case 32768: - case 57344: - bank = data & 0xF; - UpdateBanks(); - break; - case 49152: - bank = data & 0xF; - mode = ((data >> 3) & 2) | (mode & 1); - UpdateBanks(); - break; - } - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - mode = ((data >> 3) & 2) | ((data >> 1) & 1); - UpdateBanks(); - } - - private void UpdateBanks() - { - offset = 0; - if ((mode & 1) == 1) - { - Switch32KPRG(bank, PRGArea.Area8000); - offset = 35; - } - else - { - Switch08KPRG((bank << 1) | (mode >> 1), PRGArea.Area8000); - Switch08KPRG((bank << 1) | 7, PRGArea.Area8000); - offset = 47; - } - Switch08KPRG(offset | (bank << 2), PRGArea.Area6000); - Switch01KNMTFromMirroring((mode == 3) ? Mirroring.Horz : Mirroring.Vert); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(bank); - stream.Write(mode); - stream.Write(offset); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - bank = stream.ReadInt32(); - mode = stream.ReadInt32(); - offset = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("11-in-1", 51)] +internal class Mapper051 : Board +{ + private int bank; + + private int mode = 1; + + private int offset; + + internal override void HardReset() + { + base.HardReset(); + bank = 0; + mode = 1; + offset = 0; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE000) + { + case 32768: + case 57344: + bank = data & 0xF; + UpdateBanks(); + break; + case 49152: + bank = data & 0xF; + mode = ((data >> 3) & 2) | (mode & 1); + UpdateBanks(); + break; + } + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + mode = ((data >> 3) & 2) | ((data >> 1) & 1); + UpdateBanks(); + } + + private void UpdateBanks() + { + offset = 0; + if ((mode & 1) == 1) + { + Switch32KPRG(bank, PRGArea.Area8000); + offset = 35; + } + else + { + Switch08KPRG((bank << 1) | (mode >> 1), PRGArea.Area8000); + Switch08KPRG((bank << 1) | 7, PRGArea.Area8000); + offset = 47; + } + Switch08KPRG(offset | (bank << 2), PRGArea.Area6000); + Switch01KNMTFromMirroring((mode == 3) ? Mirroring.Horz : Mirroring.Vert); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(bank); + stream.Write(mode); + stream.Write(offset); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + bank = stream.ReadInt32(); + mode = stream.ReadInt32(); + offset = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper052.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper052.cs index de14867..7f5d250 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper052.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper052.cs @@ -1,273 +1,272 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("7-in-1 MMC3 Port 6800h with SRAM", 52, true, true)] - internal class Mapper052 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - private int prg_and; - - private int prg_or; - - private int chr_and; - - private int chr_or; - - private bool locked; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - locked = false; - address_8001 = 0; - prg_and = 31; - prg_or = 0; - chr_and = 255; - chr_or = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void SoftReset() - { - HardReset(); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - if (!locked) - { - if (PRG_RAM_ENABLED[PRG_AREA_BLK_INDEX[0]] && PRG_RAM_WRITABLE[PRG_AREA_BLK_INDEX[0]]) - { - locked = true; - prg_and = ((data << 1) & 0x10) ^ 0x1F; - prg_or = ((data & 6) | ((data >> 3) & data & 1)) << 4; - chr_and = ((data & 0x40) << 1) ^ 0xFF; - chr_or = (((data >> 3) & 4) | ((data >> 1) & 2) | ((data >> 6) & (data >> 4) & 1)) << 7; - SetupCHR(); - SetupPRG(); - } - } - else - { - base.WriteSRM(ref address, ref data); - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); - } - else - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); - Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); - Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); - Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(prg_and); - stream.Write(prg_or); - stream.Write(chr_and); - stream.Write(chr_or); - stream.Write(locked); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - prg_and = stream.ReadInt32(); - prg_or = stream.ReadInt32(); - chr_and = stream.ReadInt32(); - chr_or = stream.ReadInt32(); - locked = stream.ReadBoolean(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("7-in-1 MMC3 Port 6800h with SRAM", 52, true, true)] +internal class Mapper052 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + private int prg_and; + + private int prg_or; + + private int chr_and; + + private int chr_or; + + private bool locked; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + locked = false; + address_8001 = 0; + prg_and = 31; + prg_or = 0; + chr_and = 255; + chr_or = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void SoftReset() + { + HardReset(); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + if (!locked) + { + if (PRG_RAM_ENABLED[PRG_AREA_BLK_INDEX[0]] && PRG_RAM_WRITABLE[PRG_AREA_BLK_INDEX[0]]) + { + locked = true; + prg_and = ((data << 1) & 0x10) ^ 0x1F; + prg_or = ((data & 6) | ((data >> 3) & data & 1)) << 4; + chr_and = ((data & 0x40) << 1) ^ 0xFF; + chr_or = (((data >> 3) & 4) | ((data >> 1) & 2) | ((data >> 6) & (data >> 4) & 1)) << 7; + SetupCHR(); + SetupPRG(); + } + } + else + { + base.WriteSRM(ref address, ref data); + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); + } + else + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); + Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); + Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); + Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(prg_and); + stream.Write(prg_or); + stream.Write(chr_and); + stream.Write(chr_or); + stream.Write(locked); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + prg_and = stream.ReadInt32(); + prg_or = stream.ReadInt32(); + chr_and = stream.ReadInt32(); + chr_or = stream.ReadInt32(); + locked = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper053.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper053.cs index 191b40d..8ea105d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper053.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper053.cs @@ -1,58 +1,57 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 53)] - [HassIssues] - internal class Mapper053 : Board - { - private byte[] regs = new byte[2]; - - private bool epromFirst; - - internal override string Issues => MNInterfaceLanguage.IssueMapper53; - - internal override void HardReset() - { - base.HardReset(); - regs = new byte[2]; - epromFirst = true; - Switch08KPRG(0, PRGArea.Area6000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - regs[1] = data; - UpdatePrg(); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - regs[0] = data; - UpdatePrg(); - Switch01KNMTFromMirroring(((data & 0x20) == 32) ? Mirroring.Horz : Mirroring.Vert); - } - - private void UpdatePrg() - { - int num = (regs[0] << 3) & 0x78; - Switch08KPRG(((num << 1) | 0xF) + (epromFirst ? 4 : 0), PRGArea.Area6000); - Switch16KPRG(((regs[0] & 0x10) == 16) ? ((num | (regs[1] & 7)) + (epromFirst ? 2 : 0)) : ((!epromFirst) ? 128 : 0), PRGArea.Area8000); - Switch16KPRG(((regs[0] & 0x10) == 16) ? ((num | 7) + (epromFirst ? 2 : 0)) : (epromFirst ? 1 : 129), PRGArea.AreaC000); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(regs); - stream.Write(epromFirst); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - stream.Read(regs, 0, 2); - epromFirst = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 53)] +[HassIssues] +internal class Mapper053 : Board +{ + private byte[] regs = new byte[2]; + + private bool epromFirst; + + internal override string Issues => MNInterfaceLanguage.IssueMapper53; + + internal override void HardReset() + { + base.HardReset(); + regs = new byte[2]; + epromFirst = true; + Switch08KPRG(0, PRGArea.Area6000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + regs[1] = data; + UpdatePrg(); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + regs[0] = data; + UpdatePrg(); + Switch01KNMTFromMirroring(((data & 0x20) == 32) ? Mirroring.Horz : Mirroring.Vert); + } + + private void UpdatePrg() + { + int num = (regs[0] << 3) & 0x78; + Switch08KPRG(((num << 1) | 0xF) + (epromFirst ? 4 : 0), PRGArea.Area6000); + Switch16KPRG(((regs[0] & 0x10) == 16) ? ((num | (regs[1] & 7)) + (epromFirst ? 2 : 0)) : ((!epromFirst) ? 128 : 0), PRGArea.Area8000); + Switch16KPRG(((regs[0] & 0x10) == 16) ? ((num | 7) + (epromFirst ? 2 : 0)) : (epromFirst ? 1 : 129), PRGArea.AreaC000); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(regs); + stream.Write(epromFirst); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + stream.Read(regs, 0, 2); + epromFirst = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper056.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper056.cs index 559e256..fd3d6f4 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper056.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper056.cs @@ -1,97 +1,96 @@ -namespace MyNes.Core -{ - [BoardInfo("Pirate SMB3", 56)] - internal class Mapper056 : Board - { - private int irqCounter = 0; - - private int irqLatch = 0; - - private bool irqEnabled = false; - - private int irqControl = 0; - - private int switchControl = 0; - - internal override string Issues => MNInterfaceLanguage.IssueMapper56; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - irqLatch = 0; - irqCounter = 0; - irqControl = 0; - irqEnabled = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if (address < 61440) - { - switch (address & 0xE000) - { - case 32768: - irqLatch = (irqLatch & 0xFFF0) | (data & 0xF); - break; - case 36864: - irqLatch = (irqLatch & 0xFF0F) | ((data & 0xF) << 4); - break; - case 40960: - irqLatch = (irqLatch & 0xF0FF) | ((data & 0xF) << 8); - break; - case 45056: - irqLatch = (irqLatch & 0xFFF) | ((data & 0xF) << 12); - break; - case 49152: - irqControl = data & 5; - irqEnabled = (data & 2) == 2; - if (irqEnabled) - { - irqCounter = irqLatch; - } - NesEmu.IRQFlags &= -9; - break; - case 53248: - irqEnabled = (irqControl & 1) == 1; - NesEmu.IRQFlags &= -9; - break; - case 57344: - switchControl = data; - break; - } - return; - } - int num = (switchControl & 0xF) - 1; - if (num < 3) - { - Switch08KPRG((data & 0xF) | (PRG_AREA_BLK_INDEX[(num >> 13) + 1] & 0x10), (PRGArea)num); - } - switch (address & 0xC00) - { - case 0: - address &= 3; - if (address < 3) - { - Switch08KPRG((data & 0xF) | (PRG_AREA_BLK_INDEX[(num >> 13) + 1] & 0x10), (PRGArea)address); - } - break; - case 2048: - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Vert : Mirroring.Horz); - break; - case 3072: - Switch01KCHR(data, (CHRArea)(address & 7u)); - break; - } - } - - internal override void OnCPUClock() - { - if (irqEnabled && irqCounter++ == 65535) - { - irqCounter = irqLatch; - NesEmu.IRQFlags |= 8; - } - } - } +namespace MyNes.Core; + +[BoardInfo("Pirate SMB3", 56)] +internal class Mapper056 : Board +{ + private int irqCounter; + + private int irqLatch; + + private bool irqEnabled; + + private int irqControl; + + private int switchControl; + + internal override string Issues => MNInterfaceLanguage.IssueMapper56; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + irqLatch = 0; + irqCounter = 0; + irqControl = 0; + irqEnabled = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if (address < 61440) + { + switch (address & 0xE000) + { + case 32768: + irqLatch = (irqLatch & 0xFFF0) | (data & 0xF); + break; + case 36864: + irqLatch = (irqLatch & 0xFF0F) | ((data & 0xF) << 4); + break; + case 40960: + irqLatch = (irqLatch & 0xF0FF) | ((data & 0xF) << 8); + break; + case 45056: + irqLatch = (irqLatch & 0xFFF) | ((data & 0xF) << 12); + break; + case 49152: + irqControl = data & 5; + irqEnabled = (data & 2) == 2; + if (irqEnabled) + { + irqCounter = irqLatch; + } + NesEmu.IRQFlags &= -9; + break; + case 53248: + irqEnabled = (irqControl & 1) == 1; + NesEmu.IRQFlags &= -9; + break; + case 57344: + switchControl = data; + break; + } + return; + } + int num = (switchControl & 0xF) - 1; + if (num < 3) + { + Switch08KPRG((data & 0xF) | (PRG_AREA_BLK_INDEX[(num >> 13) + 1] & 0x10), (PRGArea)num); + } + switch (address & 0xC00) + { + case 0: + address &= 3; + if (address < 3) + { + Switch08KPRG((data & 0xF) | (PRG_AREA_BLK_INDEX[(num >> 13) + 1] & 0x10), (PRGArea)address); + } + break; + case 2048: + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Vert : Mirroring.Horz); + break; + case 3072: + Switch01KCHR(data, (CHRArea)(address & 7u)); + break; + } + } + + internal override void OnCPUClock() + { + if (irqEnabled && irqCounter++ == 65535) + { + irqCounter = irqLatch; + NesEmu.IRQFlags |= 8; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper057.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper057.cs index 26fe2e0..44dcc8d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper057.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper057.cs @@ -1,55 +1,54 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("6-in-1 (SuperGK)", 57)] - internal class Mapper057 : Board - { - private int chr_aaa; - - private int chr_bbb; - - private int chr_hhh; - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0x8800) - { - case 32768: - chr_aaa = data & 7; - chr_hhh = (data & 0x40) >> 3; - break; - case 34816: - chr_bbb = data & 7; - if ((data & 0x10) == 16) - { - Switch32KPRG((data & 0xE0) >> 6, PRGArea.Area8000); - } - else - { - Switch16KPRG((data & 0xE0) >> 5, PRGArea.Area8000); - Switch16KPRG((data & 0xE0) >> 5, PRGArea.AreaC000); - } - Switch01KNMTFromMirroring(((data & 8) == 8) ? Mirroring.Horz : Mirroring.Vert); - break; - } - Switch08KCHR(chr_hhh | (chr_aaa | chr_bbb)); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(chr_aaa); - stream.Write(chr_bbb); - stream.Write(chr_hhh); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - chr_aaa = stream.ReadInt32(); - chr_bbb = stream.ReadInt32(); - chr_hhh = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("6-in-1 (SuperGK)", 57)] +internal class Mapper057 : Board +{ + private int chr_aaa; + + private int chr_bbb; + + private int chr_hhh; + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0x8800) + { + case 32768: + chr_aaa = data & 7; + chr_hhh = (data & 0x40) >> 3; + break; + case 34816: + chr_bbb = data & 7; + if ((data & 0x10) == 16) + { + Switch32KPRG((data & 0xE0) >> 6, PRGArea.Area8000); + } + else + { + Switch16KPRG((data & 0xE0) >> 5, PRGArea.Area8000); + Switch16KPRG((data & 0xE0) >> 5, PRGArea.AreaC000); + } + Switch01KNMTFromMirroring(((data & 8) == 8) ? Mirroring.Horz : Mirroring.Vert); + break; + } + Switch08KCHR(chr_hhh | (chr_aaa | chr_bbb)); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(chr_aaa); + stream.Write(chr_bbb); + stream.Write(chr_hhh); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + chr_aaa = stream.ReadInt32(); + chr_bbb = stream.ReadInt32(); + chr_hhh = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper058.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper058.cs index 1cc600e..404b6a8 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper058.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper058.cs @@ -1,24 +1,23 @@ -namespace MyNes.Core -{ - [BoardInfo("68-in-1 (Game Star)", 58)] - [HassIssues] - internal class Mapper058 : Board - { - internal override string Issues => MNInterfaceLanguage.IssueMapper58; - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR((address >> 3) & 7); - if ((address & 0x40) == 0) - { - Switch32KPRG((address & 7) >> 1, PRGArea.Area8000); - } - else - { - Switch16KPRG(address & 7, PRGArea.Area8000); - Switch16KPRG(address & 7, PRGArea.AreaC000); - } - Switch01KNMTFromMirroring(((address & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); - } - } +namespace MyNes.Core; + +[BoardInfo("68-in-1 (Game Star)", 58)] +[HassIssues] +internal class Mapper058 : Board +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper58; + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR((address >> 3) & 7); + if ((address & 0x40) == 0) + { + Switch32KPRG((address & 7) >> 1, PRGArea.Area8000); + } + else + { + Switch16KPRG(address & 7, PRGArea.Area8000); + Switch16KPRG(address & 7, PRGArea.AreaC000); + } + Switch01KNMTFromMirroring(((address & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper060.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper060.cs index 2ab0e2c..07bcae0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper060.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper060.cs @@ -1,67 +1,66 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 60)] - [HassIssues] - internal class Mapper060 : Board - { - private int latch = 0; - - private byte menu = 0; - - internal override string Issues => MNInterfaceLanguage.IssueMapper60; - - internal override void HardReset() - { - base.HardReset(); - latch = 0; - menu = 0; - } - - internal override void SoftReset() - { - base.SoftReset(); - latch = 0; - menu = (byte)((uint)(menu + 1) & 3u); - Switch08KCHR(menu); - Switch16KPRG(menu, PRGArea.Area8000); - Switch16KPRG(menu, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - latch = address & 0x100; - Switch01KNMTFromMirroring(((address & 8) == 8) ? Mirroring.Horz : Mirroring.Vert); - Switch16KPRG((address >> 4) & ~((~address >> 7) & 1), PRGArea.Area8000); - Switch16KPRG((address >> 4) | ((~address >> 7) & 1), PRGArea.AreaC000); - Switch08KCHR(address); - } - - internal override void ReadPRG(ref ushort address, out byte data) - { - if (latch == 0) - { - base.ReadPRG(ref address, out data); - } - else - { - data = menu; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(latch); - stream.Write(menu); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - latch = stream.ReadInt32(); - menu = stream.ReadByte(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 60)] +[HassIssues] +internal class Mapper060 : Board +{ + private int latch; + + private byte menu; + + internal override string Issues => MNInterfaceLanguage.IssueMapper60; + + internal override void HardReset() + { + base.HardReset(); + latch = 0; + menu = 0; + } + + internal override void SoftReset() + { + base.SoftReset(); + latch = 0; + menu = (byte)((uint)(menu + 1) & 3u); + Switch08KCHR(menu); + Switch16KPRG(menu, PRGArea.Area8000); + Switch16KPRG(menu, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + latch = address & 0x100; + Switch01KNMTFromMirroring(((address & 8) == 8) ? Mirroring.Horz : Mirroring.Vert); + Switch16KPRG((address >> 4) & ~((~address >> 7) & 1), PRGArea.Area8000); + Switch16KPRG((address >> 4) | ((~address >> 7) & 1), PRGArea.AreaC000); + Switch08KCHR(address); + } + + internal override void ReadPRG(ref ushort address, out byte data) + { + if (latch == 0) + { + base.ReadPRG(ref address, out data); + } + else + { + data = menu; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(latch); + stream.Write(menu); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + latch = stream.ReadInt32(); + menu = stream.ReadByte(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper061.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper061.cs index 8d65c61..f380745 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper061.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper061.cs @@ -1,20 +1,19 @@ -namespace MyNes.Core -{ - [BoardInfo("20-in-1", 61)] - internal class Mapper061 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - if ((address & 0x10) == 0) - { - Switch32KPRG(address & 0xF, PRGArea.Area8000); - } - else - { - Switch16KPRG(((address & 0xF) << 1) | ((address & 0x20) >> 5), PRGArea.Area8000); - Switch16KPRG(((address & 0xF) << 1) | ((address & 0x20) >> 5), PRGArea.AreaC000); - } - Switch01KNMTFromMirroring(((address & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); - } - } +namespace MyNes.Core; + +[BoardInfo("20-in-1", 61)] +internal class Mapper061 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + if ((address & 0x10) == 0) + { + Switch32KPRG(address & 0xF, PRGArea.Area8000); + } + else + { + Switch16KPRG(((address & 0xF) << 1) | ((address & 0x20) >> 5), PRGArea.Area8000); + Switch16KPRG(((address & 0xF) << 1) | ((address & 0x20) >> 5), PRGArea.AreaC000); + } + Switch01KNMTFromMirroring(((address & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper062.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper062.cs index caf9ad9..2344b1c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper062.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper062.cs @@ -1,24 +1,23 @@ -namespace MyNes.Core -{ - [BoardInfo("Super 700-in-1", 62)] - internal class Mapper062 : Board - { - private int prg_page; - - internal override void WritePRG(ref ushort address, ref byte data) - { - prg_page = ((address & 0x3F00) >> 8) | (address & 0x40); - Switch08KCHR(((address & 0x1F) << 2) | (data & 3)); - if ((address & 0x20) == 32) - { - Switch16KPRG(prg_page, PRGArea.Area8000); - Switch16KPRG(prg_page, PRGArea.AreaC000); - } - else - { - Switch32KPRG(prg_page >> 1, PRGArea.Area8000); - } - Switch01KNMTFromMirroring(((address & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); - } - } +namespace MyNes.Core; + +[BoardInfo("Super 700-in-1", 62)] +internal class Mapper062 : Board +{ + private int prg_page; + + internal override void WritePRG(ref ushort address, ref byte data) + { + prg_page = ((address & 0x3F00) >> 8) | (address & 0x40); + Switch08KCHR(((address & 0x1F) << 2) | (data & 3)); + if ((address & 0x20) == 32) + { + Switch16KPRG(prg_page, PRGArea.Area8000); + Switch16KPRG(prg_page, PRGArea.AreaC000); + } + else + { + Switch32KPRG(prg_page >> 1, PRGArea.Area8000); + } + Switch01KNMTFromMirroring(((address & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper064.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper064.cs index eec8d92..85240f0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper064.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper064.cs @@ -1,258 +1,257 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Tengen RAMBO-1", 64, true, true)] - internal class Mapper064 : Board - { - private bool flag_c; - - private bool flag_p; - - private bool flag_k; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private byte irq_reload; - - private bool irq_mode; - - private bool irq_clear; - - private int irq_prescaler; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = (flag_k = false)); - address_8001 = 0; - prg_reg = new int[3]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = 2; - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - SetupPRG(); - chr_reg = new int[8]; - for (int i = 0; i < 8; i++) - { - chr_reg[i] = i; - } - SetupCHR(); - irq_enabled = false; - irq_counter = 0; - irq_prescaler = 0; - irq_mode = false; - irq_reload = byte.MaxValue; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 0xF; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - flag_k = (data & 0x20) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data; - SetupPRG(); - break; - case 8: - chr_reg[6] = data; - SetupCHR(); - break; - case 9: - chr_reg[7] = data; - SetupCHR(); - break; - case 15: - prg_reg[2] = data; - SetupPRG(); - break; - case 10: - case 11: - case 12: - case 13: - case 14: - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 49152: - irq_reload = data; - break; - case 49153: - irq_mode = (data & 1) == 1; - irq_clear = true; - irq_prescaler = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - if (!flag_k) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - } - else - { - Switch01KCHR(chr_reg[0], CHRArea.Area0000); - Switch01KCHR(chr_reg[6], CHRArea.Area0400); - Switch01KCHR(chr_reg[1], CHRArea.Area0800); - Switch01KCHR(chr_reg[7], CHRArea.Area0C00); - } - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - if (!flag_k) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - } - else - { - Switch01KCHR(chr_reg[0], CHRArea.Area1000); - Switch01KCHR(chr_reg[6], CHRArea.Area1400); - Switch01KCHR(chr_reg[1], CHRArea.Area1800); - Switch01KCHR(chr_reg[7], CHRArea.Area1C00); - } - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[(!flag_p) ? 1u : 0u], PRGArea.AreaA000); - Switch08KPRG(prg_reg[flag_p ? 1 : 2], PRGArea.AreaC000); - } - - internal override void OnPPUA12RaisingEdge() - { - ClockIRQ(); - } - - internal override void OnCPUClock() - { - if (irq_mode) - { - irq_prescaler++; - if (irq_prescaler == 4) - { - irq_prescaler = 0; - ClockIRQ(); - } - } - } - - private void ClockIRQ() - { - if (irq_clear) - { - irq_counter = (byte)(irq_reload + 1); - irq_clear = false; - } - else if (irq_counter == 0) - { - irq_counter = irq_reload; - } - else if (--irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(irq_prescaler); - stream.Write(irq_mode); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - irq_prescaler = stream.ReadInt32(); - irq_mode = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Tengen RAMBO-1", 64, true, true)] +internal class Mapper064 : Board +{ + private bool flag_c; + + private bool flag_p; + + private bool flag_k; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private byte irq_reload; + + private bool irq_mode; + + private bool irq_clear; + + private int irq_prescaler; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = (flag_k = false)); + address_8001 = 0; + prg_reg = new int[3]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = 2; + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + SetupPRG(); + chr_reg = new int[8]; + for (int i = 0; i < 8; i++) + { + chr_reg[i] = i; + } + SetupCHR(); + irq_enabled = false; + irq_counter = 0; + irq_prescaler = 0; + irq_mode = false; + irq_reload = byte.MaxValue; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 0xF; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + flag_k = (data & 0x20) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data; + SetupPRG(); + break; + case 8: + chr_reg[6] = data; + SetupCHR(); + break; + case 9: + chr_reg[7] = data; + SetupCHR(); + break; + case 15: + prg_reg[2] = data; + SetupPRG(); + break; + case 10: + case 11: + case 12: + case 13: + case 14: + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 49152: + irq_reload = data; + break; + case 49153: + irq_mode = (data & 1) == 1; + irq_clear = true; + irq_prescaler = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + if (!flag_k) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + } + else + { + Switch01KCHR(chr_reg[0], CHRArea.Area0000); + Switch01KCHR(chr_reg[6], CHRArea.Area0400); + Switch01KCHR(chr_reg[1], CHRArea.Area0800); + Switch01KCHR(chr_reg[7], CHRArea.Area0C00); + } + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + if (!flag_k) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + } + else + { + Switch01KCHR(chr_reg[0], CHRArea.Area1000); + Switch01KCHR(chr_reg[6], CHRArea.Area1400); + Switch01KCHR(chr_reg[1], CHRArea.Area1800); + Switch01KCHR(chr_reg[7], CHRArea.Area1C00); + } + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[(!flag_p) ? 1u : 0u], PRGArea.AreaA000); + Switch08KPRG(prg_reg[flag_p ? 1 : 2], PRGArea.AreaC000); + } + + internal override void OnPPUA12RaisingEdge() + { + ClockIRQ(); + } + + internal override void OnCPUClock() + { + if (irq_mode) + { + irq_prescaler++; + if (irq_prescaler == 4) + { + irq_prescaler = 0; + ClockIRQ(); + } + } + } + + private void ClockIRQ() + { + if (irq_clear) + { + irq_counter = (byte)(irq_reload + 1); + irq_clear = false; + } + else if (irq_counter == 0) + { + irq_counter = irq_reload; + } + else if (--irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(irq_prescaler); + stream.Write(irq_mode); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + irq_prescaler = stream.ReadInt32(); + irq_mode = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper065.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper065.cs index 7b4f006..0460b0a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper065.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper065.cs @@ -1,94 +1,93 @@ -namespace MyNes.Core -{ - [BoardInfo("Irem H-3001", 65)] - internal class Mapper065 : Board - { - private bool irq_enable; - - private int irq_reload; - - private int irq_counter; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(0, PRGArea.Area8000); - Switch08KPRG(1, PRGArea.AreaA000); - Switch08KPRG(254, PRGArea.AreaC000); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address) - { - case 32768: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 36865: - Switch01KNMTFromMirroring(((data & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); - break; - case 36867: - irq_enable = (data & 0x80) == 128; - NesEmu.IRQFlags &= -9; - break; - case 36868: - irq_counter = irq_reload; - NesEmu.IRQFlags &= -9; - break; - case 36869: - irq_reload = (irq_reload & 0xFF) | (data << 8); - break; - case 36870: - irq_reload = (irq_reload & 0xFF00) | data; - break; - case 40960: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 49152: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 45056: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 45057: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 45058: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 45059: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 45060: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 45061: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 45062: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 45063: - Switch01KCHR(data, CHRArea.Area1C00); - break; - } - } - - internal override void OnCPUClock() - { - if (irq_enable) - { - if (irq_counter > 0) - { - irq_counter--; - } - else if (irq_counter == 0) - { - irq_counter = -1; - NesEmu.IRQFlags |= 8; - } - } - } - } +namespace MyNes.Core; + +[BoardInfo("Irem H-3001", 65)] +internal class Mapper065 : Board +{ + private bool irq_enable; + + private int irq_reload; + + private int irq_counter; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(0, PRGArea.Area8000); + Switch08KPRG(1, PRGArea.AreaA000); + Switch08KPRG(254, PRGArea.AreaC000); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address) + { + case 32768: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 36865: + Switch01KNMTFromMirroring(((data & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); + break; + case 36867: + irq_enable = (data & 0x80) == 128; + NesEmu.IRQFlags &= -9; + break; + case 36868: + irq_counter = irq_reload; + NesEmu.IRQFlags &= -9; + break; + case 36869: + irq_reload = (irq_reload & 0xFF) | (data << 8); + break; + case 36870: + irq_reload = (irq_reload & 0xFF00) | data; + break; + case 40960: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 49152: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 45056: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 45057: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 45058: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 45059: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 45060: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 45061: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 45062: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 45063: + Switch01KCHR(data, CHRArea.Area1C00); + break; + } + } + + internal override void OnCPUClock() + { + if (irq_enable) + { + if (irq_counter > 0) + { + irq_counter--; + } + else if (irq_counter == 0) + { + irq_counter = -1; + NesEmu.IRQFlags |= 8; + } + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper066.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper066.cs index 40784a7..d6b01c0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper066.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper066.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("GxROM", 66)] - internal class Mapper066 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch32KPRG((data >> 4) & 3, PRGArea.Area8000); - Switch08KCHR(data & 3); - } - } +namespace MyNes.Core; + +[BoardInfo("GxROM", 66)] +internal class Mapper066 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch32KPRG((data >> 4) & 3, PRGArea.Area8000); + Switch08KCHR(data & 3); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper067.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper067.cs index bebc000..30d1342 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper067.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper067.cs @@ -1,108 +1,107 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Sunsoft 3", 67)] - internal class Mapper067 : Board - { - private bool irq_enabled; - - private int irq_counter; - - private bool odd; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - irq_enabled = false; - irq_counter = 65535; - odd = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF800) - { - case 34816: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 38912: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 43008: - Switch02KCHR(data, CHRArea.Area1000); - break; - case 47104: - Switch02KCHR(data, CHRArea.Area1800); - break; - case 51200: - if (!odd) - { - irq_counter = (irq_counter & 0xFF) | (data << 8); - } - else - { - irq_counter = (irq_counter & 0xFF00) | data; - } - odd = !odd; - break; - case 55296: - irq_enabled = (data & 0x10) == 16; - odd = false; - NesEmu.IRQFlags &= -9; - break; - case 59392: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 63488: - Switch16KPRG(data, PRGArea.Area8000); - break; - } - } - - internal override void OnCPUClock() - { - if (irq_enabled) - { - irq_counter--; - if (irq_counter == 0) - { - irq_counter = 65535; - NesEmu.IRQFlags |= 8; - irq_enabled = false; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(odd); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadInt32(); - odd = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Sunsoft 3", 67)] +internal class Mapper067 : Board +{ + private bool irq_enabled; + + private int irq_counter; + + private bool odd; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + irq_enabled = false; + irq_counter = 65535; + odd = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF800) + { + case 34816: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 38912: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 43008: + Switch02KCHR(data, CHRArea.Area1000); + break; + case 47104: + Switch02KCHR(data, CHRArea.Area1800); + break; + case 51200: + if (!odd) + { + irq_counter = (irq_counter & 0xFF) | (data << 8); + } + else + { + irq_counter = (irq_counter & 0xFF00) | data; + } + odd = !odd; + break; + case 55296: + irq_enabled = (data & 0x10) == 16; + odd = false; + NesEmu.IRQFlags &= -9; + break; + case 59392: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 63488: + Switch16KPRG(data, PRGArea.Area8000); + break; + } + } + + internal override void OnCPUClock() + { + if (irq_enabled) + { + irq_counter--; + if (irq_counter == 0) + { + irq_counter = 65535; + NesEmu.IRQFlags |= 8; + irq_enabled = false; + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(odd); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadInt32(); + odd = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper068.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper068.cs index 7aed440..674b543 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper068.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper068.cs @@ -1,112 +1,111 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Sunsoft 4", 68)] - internal class Mapper068 : Board - { - private bool flag_r; - - private bool flag_m; - - private int nt_reg0; - - private int nt_reg1; - - private int temp; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF000) - { - case 32768: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 36864: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 40960: - Switch02KCHR(data, CHRArea.Area1000); - break; - case 45056: - Switch02KCHR(data, CHRArea.Area1800); - break; - case 49152: - nt_reg0 = (data & 0x7F) | 0x80; - break; - case 53248: - nt_reg1 = (data & 0x7F) | 0x80; - break; - case 57344: - flag_r = (data & 0x10) == 16; - flag_m = (data & 1) == 1; - Switch01KNMTFromMirroring(flag_m ? Mirroring.Horz : Mirroring.Vert); - break; - case 61440: - Switch16KPRG(data, PRGArea.Area8000); - break; - } - } - - internal override void ReadNMT(ref ushort address, out byte data) - { - if (!flag_r) - { - data = NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF]; - return; - } - switch ((address >> 10) & 3) - { - case 0: - data = CHR_ROM[nt_reg0][address & 0x3FF]; - break; - case 1: - data = CHR_ROM[flag_m ? nt_reg0 : nt_reg1][address & 0x3FF]; - break; - case 2: - data = CHR_ROM[flag_m ? nt_reg1 : nt_reg0][address & 0x3FF]; - break; - case 3: - data = CHR_ROM[nt_reg1][address & 0x3FF]; - break; - default: - data = 0; - break; - } - } - - internal override void WriteNMT(ref ushort address, ref byte data) - { - if (!flag_r) - { - base.WriteNMT(ref address, ref data); - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_r); - stream.Write(flag_m); - stream.Write(nt_reg0); - stream.Write(nt_reg1); - stream.Write(temp); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_r = stream.ReadBoolean(); - flag_m = stream.ReadBoolean(); - nt_reg0 = stream.ReadInt32(); - nt_reg1 = stream.ReadInt32(); - temp = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Sunsoft 4", 68)] +internal class Mapper068 : Board +{ + private bool flag_r; + + private bool flag_m; + + private int nt_reg0; + + private int nt_reg1; + + private int temp; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF000) + { + case 32768: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 36864: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 40960: + Switch02KCHR(data, CHRArea.Area1000); + break; + case 45056: + Switch02KCHR(data, CHRArea.Area1800); + break; + case 49152: + nt_reg0 = (data & 0x7F) | 0x80; + break; + case 53248: + nt_reg1 = (data & 0x7F) | 0x80; + break; + case 57344: + flag_r = (data & 0x10) == 16; + flag_m = (data & 1) == 1; + Switch01KNMTFromMirroring(flag_m ? Mirroring.Horz : Mirroring.Vert); + break; + case 61440: + Switch16KPRG(data, PRGArea.Area8000); + break; + } + } + + internal override void ReadNMT(ref ushort address, out byte data) + { + if (!flag_r) + { + data = NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF]; + return; + } + switch ((address >> 10) & 3) + { + case 0: + data = CHR_ROM[nt_reg0][address & 0x3FF]; + break; + case 1: + data = CHR_ROM[flag_m ? nt_reg0 : nt_reg1][address & 0x3FF]; + break; + case 2: + data = CHR_ROM[flag_m ? nt_reg1 : nt_reg0][address & 0x3FF]; + break; + case 3: + data = CHR_ROM[nt_reg1][address & 0x3FF]; + break; + default: + data = 0; + break; + } + } + + internal override void WriteNMT(ref ushort address, ref byte data) + { + if (!flag_r) + { + base.WriteNMT(ref address, ref data); + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_r); + stream.Write(flag_m); + stream.Write(nt_reg0); + stream.Write(nt_reg1); + stream.Write(temp); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_r = stream.ReadBoolean(); + flag_m = stream.ReadBoolean(); + nt_reg0 = stream.ReadInt32(); + nt_reg1 = stream.ReadInt32(); + temp = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper069.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper069.cs index 521b451..a0a9be5 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper069.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper069.cs @@ -1,259 +1,258 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("FME-7/Sunsoft 5B", 69)] - [WithExternalSound] - internal class Mapper069 : Board - { - private int address_A000; - - private int address_E000; - - private int irq_counter; - - private bool irq_count_enabled; - - private bool irq_trigger_enabled; - - private Sunsoft5BChnl snd_1; - - private Sunsoft5BChnl snd_2; - - private Sunsoft5BChnl snd_3; - - private double[] audio_pulse_table; - - private double[] audio_tnd_table; - - internal override void Initialize(IRom rom) - { - base.Initialize(rom); - snd_1 = new Sunsoft5BChnl(); - snd_2 = new Sunsoft5BChnl(); - snd_3 = new Sunsoft5BChnl(); - audio_pulse_table = new double[32]; - for (int i = 0; i < 32; i++) - { - audio_pulse_table[i] = 95.52 / (8128.0 / (double)i + 100.0); - } - audio_tnd_table = new double[204]; - for (int j = 0; j < 204; j++) - { - audio_tnd_table[j] = 163.67 / (24329.0 / (double)j + 100.0); - } - } - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - address_A000 = 0; - irq_counter = 65535; - irq_count_enabled = false; - irq_trigger_enabled = false; - APUApplyChannelsSettings(); - snd_1.HardReset(); - snd_2.HardReset(); - snd_3.HardReset(); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE000) - { - case 32768: - address_A000 = data & 0xF; - break; - case 40960: - switch (address_A000) - { - case 0: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 1: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 2: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 3: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 4: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 5: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 6: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 7: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 8: - TogglePRGRAMEnable((data & 0x80) == 128); - if ((data & 0x40u) != 0) - { - Toggle08KPRG_RAM(ram: true, PRGArea.Area6000); - Switch08KPRG(data & 0x3F & PRG_RAM_08KB_Mask, PRGArea.Area6000); - } - else - { - Toggle08KPRG_RAM(ram: false, PRGArea.Area6000); - Switch08KPRG(data & 0x3F, PRGArea.Area6000); - } - break; - case 9: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 10: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 11: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 12: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 13: - irq_count_enabled = (data & 0x80) == 128; - irq_trigger_enabled = (data & 1) == 1; - if (!irq_trigger_enabled) - { - NesEmu.IRQFlags &= -9; - } - break; - case 14: - irq_counter = (irq_counter & 0xFF00) | data; - break; - case 15: - irq_counter = (irq_counter & 0xFF) | (data << 8); - break; - } - break; - case 49152: - address_E000 = data & 0xF; - break; - case 57344: - switch (address_E000) - { - case 0: - snd_1.Write0(ref data); - break; - case 1: - snd_1.Write1(ref data); - break; - case 2: - snd_2.Write0(ref data); - break; - case 3: - snd_2.Write1(ref data); - break; - case 4: - snd_3.Write0(ref data); - break; - case 5: - snd_3.Write1(ref data); - break; - case 7: - snd_1.Enabled = (data & 1) == 0; - snd_2.Enabled = (data & 2) == 0; - snd_3.Enabled = (data & 4) == 0; - break; - case 8: - snd_1.Volume = (byte)(data & 0xFu); - break; - case 9: - snd_2.Volume = (byte)(data & 0xFu); - break; - case 10: - snd_3.Volume = (byte)(data & 0xFu); - break; - case 6: - break; - } - break; - } - } - - internal override void OnCPUClock() - { - if (!irq_count_enabled) - { - return; - } - irq_counter--; - if (irq_counter <= 0) - { - irq_counter = 65535; - if (irq_trigger_enabled) - { - NesEmu.IRQFlags |= 8; - } - } - } - - internal override double APUGetSample() - { - return audio_pulse_table[snd_1.output + snd_2.output] + audio_tnd_table[snd_3.output]; - } - - internal override void OnAPUClockSingle() - { - base.OnAPUClockSingle(); - snd_1.ClockSingle(); - snd_2.ClockSingle(); - snd_3.ClockSingle(); - } - - internal override void APUApplyChannelsSettings() - { - base.APUApplyChannelsSettings(); - snd_1.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SUN1; - snd_2.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SUN2; - snd_3.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SUN3; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(address_A000); - stream.Write(address_E000); - stream.Write(irq_counter); - stream.Write(irq_count_enabled); - stream.Write(irq_trigger_enabled); - snd_1.SaveState(ref stream); - snd_2.SaveState(ref stream); - snd_3.SaveState(ref stream); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - address_A000 = stream.ReadInt32(); - address_E000 = stream.ReadInt32(); - irq_counter = stream.ReadInt32(); - irq_count_enabled = stream.ReadBoolean(); - irq_trigger_enabled = stream.ReadBoolean(); - snd_1.LoadState(ref stream); - snd_2.LoadState(ref stream); - snd_3.LoadState(ref stream); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("FME-7/Sunsoft 5B", 69)] +[WithExternalSound] +internal class Mapper069 : Board +{ + private int address_A000; + + private int address_E000; + + private int irq_counter; + + private bool irq_count_enabled; + + private bool irq_trigger_enabled; + + private Sunsoft5BChnl snd_1; + + private Sunsoft5BChnl snd_2; + + private Sunsoft5BChnl snd_3; + + private double[] audio_pulse_table; + + private double[] audio_tnd_table; + + internal override void Initialize(IRom rom) + { + base.Initialize(rom); + snd_1 = new Sunsoft5BChnl(); + snd_2 = new Sunsoft5BChnl(); + snd_3 = new Sunsoft5BChnl(); + audio_pulse_table = new double[32]; + for (int i = 0; i < 32; i++) + { + audio_pulse_table[i] = 95.52 / (8128.0 / (double)i + 100.0); + } + audio_tnd_table = new double[204]; + for (int j = 0; j < 204; j++) + { + audio_tnd_table[j] = 163.67 / (24329.0 / (double)j + 100.0); + } + } + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + address_A000 = 0; + irq_counter = 65535; + irq_count_enabled = false; + irq_trigger_enabled = false; + APUApplyChannelsSettings(); + snd_1.HardReset(); + snd_2.HardReset(); + snd_3.HardReset(); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE000) + { + case 32768: + address_A000 = data & 0xF; + break; + case 40960: + switch (address_A000) + { + case 0: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 1: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 2: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 3: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 4: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 5: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 6: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 7: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 8: + TogglePRGRAMEnable((data & 0x80) == 128); + if ((data & 0x40u) != 0) + { + Toggle08KPRG_RAM(ram: true, PRGArea.Area6000); + Switch08KPRG(data & 0x3F & PRG_RAM_08KB_Mask, PRGArea.Area6000); + } + else + { + Toggle08KPRG_RAM(ram: false, PRGArea.Area6000); + Switch08KPRG(data & 0x3F, PRGArea.Area6000); + } + break; + case 9: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 10: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 11: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 12: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 13: + irq_count_enabled = (data & 0x80) == 128; + irq_trigger_enabled = (data & 1) == 1; + if (!irq_trigger_enabled) + { + NesEmu.IRQFlags &= -9; + } + break; + case 14: + irq_counter = (irq_counter & 0xFF00) | data; + break; + case 15: + irq_counter = (irq_counter & 0xFF) | (data << 8); + break; + } + break; + case 49152: + address_E000 = data & 0xF; + break; + case 57344: + switch (address_E000) + { + case 0: + snd_1.Write0(ref data); + break; + case 1: + snd_1.Write1(ref data); + break; + case 2: + snd_2.Write0(ref data); + break; + case 3: + snd_2.Write1(ref data); + break; + case 4: + snd_3.Write0(ref data); + break; + case 5: + snd_3.Write1(ref data); + break; + case 7: + snd_1.Enabled = (data & 1) == 0; + snd_2.Enabled = (data & 2) == 0; + snd_3.Enabled = (data & 4) == 0; + break; + case 8: + snd_1.Volume = (byte)(data & 0xFu); + break; + case 9: + snd_2.Volume = (byte)(data & 0xFu); + break; + case 10: + snd_3.Volume = (byte)(data & 0xFu); + break; + case 6: + break; + } + break; + } + } + + internal override void OnCPUClock() + { + if (!irq_count_enabled) + { + return; + } + irq_counter--; + if (irq_counter <= 0) + { + irq_counter = 65535; + if (irq_trigger_enabled) + { + NesEmu.IRQFlags |= 8; + } + } + } + + internal override double APUGetSample() + { + return audio_pulse_table[snd_1.output + snd_2.output] + audio_tnd_table[snd_3.output]; + } + + internal override void OnAPUClockSingle() + { + base.OnAPUClockSingle(); + snd_1.ClockSingle(); + snd_2.ClockSingle(); + snd_3.ClockSingle(); + } + + internal override void APUApplyChannelsSettings() + { + base.APUApplyChannelsSettings(); + snd_1.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SUN1; + snd_2.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SUN2; + snd_3.Outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SUN3; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(address_A000); + stream.Write(address_E000); + stream.Write(irq_counter); + stream.Write(irq_count_enabled); + stream.Write(irq_trigger_enabled); + snd_1.SaveState(ref stream); + snd_2.SaveState(ref stream); + snd_3.SaveState(ref stream); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + address_A000 = stream.ReadInt32(); + address_E000 = stream.ReadInt32(); + irq_counter = stream.ReadInt32(); + irq_count_enabled = stream.ReadBoolean(); + irq_trigger_enabled = stream.ReadBoolean(); + snd_1.LoadState(ref stream); + snd_2.LoadState(ref stream); + snd_3.LoadState(ref stream); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper070.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper070.cs index 41cb3df..6d42512 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper070.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper070.cs @@ -1,18 +1,17 @@ -namespace MyNes.Core -{ - [BoardInfo("Bandai", 70)] - internal class Mapper070 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch16KPRG((data >> 4) & 0xF, PRGArea.Area8000); - Switch08KCHR(data & 0xF); - } - } +namespace MyNes.Core; + +[BoardInfo("Bandai", 70)] +internal class Mapper070 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch16KPRG((data >> 4) & 0xF, PRGArea.Area8000); + Switch08KCHR(data & 0xF); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper071.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper071.cs index 2427cc1..93a6e09 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper071.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper071.cs @@ -1,30 +1,29 @@ -namespace MyNes.Core -{ - [BoardInfo("Camerica", 71)] - internal class Mapper071 : Board - { - private bool fireHawk; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - fireHawk = SHA1.ToUpper() == "334781C830F135CF30A33E392D8AAA4AFDC223F9"; - } - - internal override void WritePRG(ref ushort addr, ref byte val) - { - if (addr < 40960) - { - if (fireHawk) - { - Switch01KNMTFromMirroring(((val & 0x10) == 16) ? Mirroring.OneScB : Mirroring.OneScA); - } - } - else if (addr >= 49152) - { - Switch16KPRG(val, PRGArea.Area8000); - } - } - } +namespace MyNes.Core; + +[BoardInfo("Camerica", 71)] +internal class Mapper071 : Board +{ + private bool fireHawk; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + fireHawk = SHA1.ToUpper() == "334781C830F135CF30A33E392D8AAA4AFDC223F9"; + } + + internal override void WritePRG(ref ushort addr, ref byte val) + { + if (addr < 40960) + { + if (fireHawk) + { + Switch01KNMTFromMirroring(((val & 0x10) == 16) ? Mirroring.OneScB : Mirroring.OneScA); + } + } + else if (addr >= 49152) + { + Switch16KPRG(val, PRGArea.Area8000); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper072.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper072.cs index 4870d6c..2eabeb4 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper072.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper072.cs @@ -1,53 +1,52 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Jaleco Early Mapper 0", 72)] - internal class Mapper072 : Board - { - private byte writeData; - - private int chr_reg; - - private int prg_reg; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - writeData = 0; - chr_reg = (prg_reg = 0); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch ((data >> 6) & 3) - { - case 0: - Switch08KCHR(chr_reg); - Switch16KPRG(prg_reg, PRGArea.Area8000); - break; - case 1: - chr_reg = data & 0xF; - break; - case 2: - prg_reg = data & 0xF; - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(chr_reg); - stream.Write(prg_reg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - chr_reg = stream.ReadInt32(); - prg_reg = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Jaleco Early Mapper 0", 72)] +internal class Mapper072 : Board +{ + private byte writeData; + + private int chr_reg; + + private int prg_reg; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + writeData = 0; + chr_reg = (prg_reg = 0); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch ((data >> 6) & 3) + { + case 0: + Switch08KCHR(chr_reg); + Switch16KPRG(prg_reg, PRGArea.Area8000); + break; + case 1: + chr_reg = data & 0xF; + break; + case 2: + prg_reg = data & 0xF; + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(chr_reg); + stream.Write(prg_reg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + chr_reg = stream.ReadInt32(); + prg_reg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper073.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper073.cs index 3d004c6..2c19828 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper073.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper073.cs @@ -1,111 +1,110 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC3", 73)] - internal class Mapper073 : Board - { - private bool irq_mode_8; - - private bool irq_enable; - - private bool irq_enable_on_ak; - - private int irq_reload; - - private int irq_counter; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - irq_mode_8 = false; - irq_enable = false; - irq_enable_on_ak = false; - irq_reload = 0; - irq_counter = 0; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF000) - { - case 32768: - irq_reload = (irq_reload & 0xFFF0) | (data & 0xF); - break; - case 36864: - irq_reload = (irq_reload & 0xFF0F) | ((data & 0xF) << 4); - break; - case 40960: - irq_reload = (irq_reload & 0xF0FF) | ((data & 0xF) << 8); - break; - case 45056: - irq_reload = (irq_reload & 0xFFF) | ((data & 0xF) << 12); - break; - case 49152: - irq_mode_8 = (data & 4) == 4; - irq_enable = (data & 2) == 2; - irq_enable_on_ak = (data & 1) == 1; - if (irq_enable) - { - irq_counter = irq_reload; - } - NesEmu.IRQFlags &= -9; - break; - case 53248: - irq_enable = irq_enable_on_ak; - NesEmu.IRQFlags &= -9; - break; - case 61440: - Switch16KPRG(data & 0xF, PRGArea.Area8000); - break; - } - } - - internal override void OnCPUClock() - { - if (!irq_enable) - { - return; - } - if (irq_mode_8) - { - irq_counter = (irq_counter & 0xFF00) | (byte)((irq_counter & 0xFF) + 1); - if ((byte)(irq_counter & 0xFF) == byte.MaxValue) - { - NesEmu.IRQFlags |= 8; - irq_counter = (irq_counter & 0xFF00) | (irq_reload & 0xFF); - } - } - else - { - irq_counter++; - if (irq_counter == 65535) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_mode_8); - stream.Write(irq_enable); - stream.Write(irq_enable_on_ak); - stream.Write(irq_reload); - stream.Write(irq_counter); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_mode_8 = stream.ReadBoolean(); - irq_enable = stream.ReadBoolean(); - irq_enable_on_ak = stream.ReadBoolean(); - irq_reload = stream.ReadInt32(); - irq_counter = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC3", 73)] +internal class Mapper073 : Board +{ + private bool irq_mode_8; + + private bool irq_enable; + + private bool irq_enable_on_ak; + + private int irq_reload; + + private int irq_counter; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + irq_mode_8 = false; + irq_enable = false; + irq_enable_on_ak = false; + irq_reload = 0; + irq_counter = 0; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF000) + { + case 32768: + irq_reload = (irq_reload & 0xFFF0) | (data & 0xF); + break; + case 36864: + irq_reload = (irq_reload & 0xFF0F) | ((data & 0xF) << 4); + break; + case 40960: + irq_reload = (irq_reload & 0xF0FF) | ((data & 0xF) << 8); + break; + case 45056: + irq_reload = (irq_reload & 0xFFF) | ((data & 0xF) << 12); + break; + case 49152: + irq_mode_8 = (data & 4) == 4; + irq_enable = (data & 2) == 2; + irq_enable_on_ak = (data & 1) == 1; + if (irq_enable) + { + irq_counter = irq_reload; + } + NesEmu.IRQFlags &= -9; + break; + case 53248: + irq_enable = irq_enable_on_ak; + NesEmu.IRQFlags &= -9; + break; + case 61440: + Switch16KPRG(data & 0xF, PRGArea.Area8000); + break; + } + } + + internal override void OnCPUClock() + { + if (!irq_enable) + { + return; + } + if (irq_mode_8) + { + irq_counter = (irq_counter & 0xFF00) | (byte)((irq_counter & 0xFF) + 1); + if ((byte)(irq_counter & 0xFF) == byte.MaxValue) + { + NesEmu.IRQFlags |= 8; + irq_counter = (irq_counter & 0xFF00) | (irq_reload & 0xFF); + } + } + else + { + irq_counter++; + if (irq_counter == 65535) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_mode_8); + stream.Write(irq_enable); + stream.Write(irq_enable_on_ak); + stream.Write(irq_reload); + stream.Write(irq_counter); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_mode_8 = stream.ReadBoolean(); + irq_enable = stream.ReadBoolean(); + irq_enable_on_ak = stream.ReadBoolean(); + irq_reload = stream.ReadInt32(); + irq_counter = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper074.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper074.cs index 8795f90..2e466aa 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper074.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper074.cs @@ -1,234 +1,233 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Pirate MMC3 variant", 74, true, true)] - internal class Mapper074 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Toggle02KCHR_RAM(chr_reg[0] != 8 && chr_reg[0] != 9, CHRArea.Area0000); - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Toggle02KCHR_RAM(chr_reg[1] != 8 && chr_reg[1] != 9, CHRArea.Area0800); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Toggle02KCHR_RAM(chr_reg[2] != 8 && chr_reg[2] != 9, CHRArea.Area1000); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Toggle02KCHR_RAM(chr_reg[3] != 8 && chr_reg[3] != 9, CHRArea.Area1400); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Toggle02KCHR_RAM(chr_reg[4] != 8 && chr_reg[4] != 9, CHRArea.Area1800); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Toggle02KCHR_RAM(chr_reg[5] != 8 && chr_reg[5] != 9, CHRArea.Area1C00); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Toggle02KCHR_RAM(chr_reg[0] != 8 && chr_reg[0] != 9, CHRArea.Area1000); - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Toggle02KCHR_RAM(chr_reg[1] != 8 && chr_reg[1] != 9, CHRArea.Area1800); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Toggle02KCHR_RAM(chr_reg[2] != 8 && chr_reg[2] != 9, CHRArea.Area0000); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Toggle02KCHR_RAM(chr_reg[3] != 8 && chr_reg[3] != 9, CHRArea.Area0400); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Toggle02KCHR_RAM(chr_reg[4] != 8 && chr_reg[4] != 9, CHRArea.Area0800); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Toggle02KCHR_RAM(chr_reg[5] != 8 && chr_reg[5] != 9, CHRArea.Area0C00); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Pirate MMC3 variant", 74, true, true)] +internal class Mapper074 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Toggle02KCHR_RAM(chr_reg[0] != 8 && chr_reg[0] != 9, CHRArea.Area0000); + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Toggle02KCHR_RAM(chr_reg[1] != 8 && chr_reg[1] != 9, CHRArea.Area0800); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Toggle02KCHR_RAM(chr_reg[2] != 8 && chr_reg[2] != 9, CHRArea.Area1000); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Toggle02KCHR_RAM(chr_reg[3] != 8 && chr_reg[3] != 9, CHRArea.Area1400); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Toggle02KCHR_RAM(chr_reg[4] != 8 && chr_reg[4] != 9, CHRArea.Area1800); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Toggle02KCHR_RAM(chr_reg[5] != 8 && chr_reg[5] != 9, CHRArea.Area1C00); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Toggle02KCHR_RAM(chr_reg[0] != 8 && chr_reg[0] != 9, CHRArea.Area1000); + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Toggle02KCHR_RAM(chr_reg[1] != 8 && chr_reg[1] != 9, CHRArea.Area1800); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Toggle02KCHR_RAM(chr_reg[2] != 8 && chr_reg[2] != 9, CHRArea.Area0000); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Toggle02KCHR_RAM(chr_reg[3] != 8 && chr_reg[3] != 9, CHRArea.Area0400); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Toggle02KCHR_RAM(chr_reg[4] != 8 && chr_reg[4] != 9, CHRArea.Area0800); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Toggle02KCHR_RAM(chr_reg[5] != 8 && chr_reg[5] != 9, CHRArea.Area0C00); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper075.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper075.cs index 6604ceb..117cd4c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper075.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper075.cs @@ -1,63 +1,62 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC1", 75)] - internal class Mapper075 : Board - { - private int chr0_reg; - - private int chr1_reg; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF000) - { - case 32768: - Switch08KPRG(data & 0xF, PRGArea.Area8000); - break; - case 40960: - Switch08KPRG(data & 0xF, PRGArea.AreaA000); - break; - case 49152: - Switch08KPRG(data & 0xF, PRGArea.AreaC000); - break; - case 36864: - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - chr0_reg = (chr0_reg & 0xF) | ((data & 2) << 3); - Switch04KCHR(chr0_reg, CHRArea.Area0000); - chr1_reg = (chr1_reg & 0xF) | ((data & 4) << 2); - Switch04KCHR(chr1_reg, CHRArea.Area1000); - break; - case 57344: - chr0_reg = (chr0_reg & 0x10) | (data & 0xF); - Switch04KCHR(chr0_reg, CHRArea.Area0000); - break; - case 61440: - chr1_reg = (chr1_reg & 0x10) | (data & 0xF); - Switch04KCHR(chr1_reg, CHRArea.Area1000); - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(chr0_reg); - stream.Write(chr1_reg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - chr0_reg = stream.ReadInt32(); - chr1_reg = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC1", 75)] +internal class Mapper075 : Board +{ + private int chr0_reg; + + private int chr1_reg; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF000) + { + case 32768: + Switch08KPRG(data & 0xF, PRGArea.Area8000); + break; + case 40960: + Switch08KPRG(data & 0xF, PRGArea.AreaA000); + break; + case 49152: + Switch08KPRG(data & 0xF, PRGArea.AreaC000); + break; + case 36864: + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + chr0_reg = (chr0_reg & 0xF) | ((data & 2) << 3); + Switch04KCHR(chr0_reg, CHRArea.Area0000); + chr1_reg = (chr1_reg & 0xF) | ((data & 4) << 2); + Switch04KCHR(chr1_reg, CHRArea.Area1000); + break; + case 57344: + chr0_reg = (chr0_reg & 0x10) | (data & 0xF); + Switch04KCHR(chr0_reg, CHRArea.Area0000); + break; + case 61440: + chr1_reg = (chr1_reg & 0x10) | (data & 0xF); + Switch04KCHR(chr1_reg, CHRArea.Area1000); + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(chr0_reg); + stream.Write(chr1_reg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + chr0_reg = stream.ReadInt32(); + chr1_reg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper076.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper076.cs index 690dfff..3395463 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper076.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper076.cs @@ -1,77 +1,76 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Namco 109", 76)] - internal class Mapper076 : Board - { - private int address_8001; - - private bool prg_a; - - private byte prg_reg; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask - 1, PRGArea.AreaC000); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - address_8001 = 0; - prg_a = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - prg_a = (data & 0x40) == 64; - Switch08KPRG(prg_reg, prg_a ? PRGArea.AreaC000 : PRGArea.Area8000); - break; - case 32769: - switch (address_8001) - { - case 2: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 3: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 4: - Switch02KCHR(data, CHRArea.Area1000); - break; - case 5: - Switch02KCHR(data, CHRArea.Area1800); - break; - case 6: - Switch08KPRG(prg_reg = data, prg_a ? PRGArea.AreaC000 : PRGArea.Area8000); - break; - case 7: - Switch08KPRG(data, PRGArea.AreaA000); - break; - } - break; - case 40960: - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(address_8001); - stream.Write(prg_a); - stream.Write(prg_reg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - address_8001 = stream.ReadInt32(); - prg_a = stream.ReadBoolean(); - prg_reg = stream.ReadByte(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Namco 109", 76)] +internal class Mapper076 : Board +{ + private int address_8001; + + private bool prg_a; + + private byte prg_reg; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask - 1, PRGArea.AreaC000); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + address_8001 = 0; + prg_a = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + prg_a = (data & 0x40) == 64; + Switch08KPRG(prg_reg, prg_a ? PRGArea.AreaC000 : PRGArea.Area8000); + break; + case 32769: + switch (address_8001) + { + case 2: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 3: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 4: + Switch02KCHR(data, CHRArea.Area1000); + break; + case 5: + Switch02KCHR(data, CHRArea.Area1800); + break; + case 6: + Switch08KPRG(prg_reg = data, prg_a ? PRGArea.AreaC000 : PRGArea.Area8000); + break; + case 7: + Switch08KPRG(data, PRGArea.AreaA000); + break; + } + break; + case 40960: + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(address_8001); + stream.Write(prg_a); + stream.Write(prg_reg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + address_8001 = stream.ReadInt32(); + prg_a = stream.ReadBoolean(); + prg_reg = stream.ReadByte(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper077.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper077.cs index 7922a49..d5ac051 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper077.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper077.cs @@ -1,23 +1,22 @@ -namespace MyNes.Core -{ - [BoardInfo("Irem", 77)] - internal class Mapper077 : Board - { - internal override void HardReset() - { - base.HardReset(); - Toggle02KCHR_RAM(ram: true, CHRArea.Area0800); - Switch02KCHR(0, CHRArea.Area0800); - Toggle02KCHR_RAM(ram: true, CHRArea.Area1000); - Switch02KCHR(1, CHRArea.Area1000); - Toggle02KCHR_RAM(ram: true, CHRArea.Area1800); - Switch02KCHR(2, CHRArea.Area1800); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch02KCHR((data >> 4) & 0xF, CHRArea.Area0000); - Switch32KPRG(data & 0xF, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("Irem", 77)] +internal class Mapper077 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Toggle02KCHR_RAM(ram: true, CHRArea.Area0800); + Switch02KCHR(0, CHRArea.Area0800); + Toggle02KCHR_RAM(ram: true, CHRArea.Area1000); + Switch02KCHR(1, CHRArea.Area1000); + Toggle02KCHR_RAM(ram: true, CHRArea.Area1800); + Switch02KCHR(2, CHRArea.Area1800); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch02KCHR((data >> 4) & 0xF, CHRArea.Area0000); + Switch32KPRG(data & 0xF, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper078.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper078.cs index 4d21f8a..790c9b8 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper078.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper078.cs @@ -1,33 +1,32 @@ -namespace MyNes.Core -{ - [BoardInfo("Irem 74HC161/32", 78)] - internal class Mapper078 : Board - { - private bool mirroring_mode_single; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - mirroring_mode_single = false; - if (base.BoardType == "JALECO-JF-16") - { - mirroring_mode_single = true; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR((data >> 4) & 0xF); - Switch16KPRG(data & 7, PRGArea.Area8000); - if (mirroring_mode_single) - { - Switch01KNMTFromMirroring(((data & 8) == 8) ? Mirroring.OneScB : Mirroring.OneScA); - } - else - { - Switch01KNMTFromMirroring(((data & 8) == 8) ? Mirroring.Vert : Mirroring.Horz); - } - } - } +namespace MyNes.Core; + +[BoardInfo("Irem 74HC161/32", 78)] +internal class Mapper078 : Board +{ + private bool mirroring_mode_single; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + mirroring_mode_single = false; + if (base.BoardType == "JALECO-JF-16") + { + mirroring_mode_single = true; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR((data >> 4) & 0xF); + Switch16KPRG(data & 7, PRGArea.Area8000); + if (mirroring_mode_single) + { + Switch01KNMTFromMirroring(((data & 8) == 8) ? Mirroring.OneScB : Mirroring.OneScA); + } + else + { + Switch01KNMTFromMirroring(((data & 8) == 8) ? Mirroring.Vert : Mirroring.Horz); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper079.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper079.cs index 3fcf817..643d411 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper079.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper079.cs @@ -1,15 +1,14 @@ -namespace MyNes.Core -{ - [BoardInfo("AVE Nina-3", 79)] - internal class Mapper079 : Board - { - internal override void WriteEX(ref ushort address, ref byte data) - { - if ((address ^ 0x4100) == 0) - { - Switch32KPRG((data >> 3) & 7, PRGArea.Area8000); - Switch08KCHR((data & 7) | ((data >> 3) & 8)); - } - } - } +namespace MyNes.Core; + +[BoardInfo("AVE Nina-3", 79)] +internal class Mapper079 : Board +{ + internal override void WriteEX(ref ushort address, ref byte data) + { + if ((address ^ 0x4100) == 0) + { + Switch32KPRG((data >> 3) & 7, PRGArea.Area8000); + Switch08KCHR((data & 7) | ((data >> 3) & 8)); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper080.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper080.cs index d161be2..ea6a70b 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper080.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper080.cs @@ -1,56 +1,55 @@ -namespace MyNes.Core -{ - [BoardInfo("Taito X-005", 80)] - internal class Mapper080 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - switch (address) - { - case 32496: - Switch02KCHR(data >> 1, CHRArea.Area0000); - break; - case 32497: - Switch02KCHR(data >> 1, CHRArea.Area0800); - break; - case 32498: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 32499: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 32500: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 32501: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 32502: - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Vert : Mirroring.Horz); - break; - case 32506: - case 32507: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 32508: - case 32509: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 32510: - case 32511: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 32503: - case 32504: - case 32505: - break; - } - } - } +namespace MyNes.Core; + +[BoardInfo("Taito X-005", 80)] +internal class Mapper080 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + switch (address) + { + case 32496: + Switch02KCHR(data >> 1, CHRArea.Area0000); + break; + case 32497: + Switch02KCHR(data >> 1, CHRArea.Area0800); + break; + case 32498: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 32499: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 32500: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 32501: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 32502: + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Vert : Mirroring.Horz); + break; + case 32506: + case 32507: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 32508: + case 32509: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 32510: + case 32511: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 32503: + case 32504: + case 32505: + break; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper082.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper082.cs index 22500ff..43d7675 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper082.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper082.cs @@ -1,70 +1,69 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Taito X1-17 ", 82)] - internal class Mapper082 : Board - { - private bool chr_mode; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - switch (address) - { - case 32496: - Switch02KCHR(data >> 1, chr_mode ? CHRArea.Area1000 : CHRArea.Area0000); - break; - case 32497: - Switch02KCHR(data >> 1, chr_mode ? CHRArea.Area1800 : CHRArea.Area0800); - break; - case 32498: - Switch01KCHR(data, (!chr_mode) ? CHRArea.Area1000 : CHRArea.Area0000); - break; - case 32499: - Switch01KCHR(data, chr_mode ? CHRArea.Area0400 : CHRArea.Area1400); - break; - case 32500: - Switch01KCHR(data, chr_mode ? CHRArea.Area0800 : CHRArea.Area1800); - break; - case 32501: - Switch01KCHR(data, chr_mode ? CHRArea.Area0C00 : CHRArea.Area1C00); - break; - case 32502: - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Vert : Mirroring.Horz); - chr_mode = (data & 2) == 2; - break; - case 32506: - Switch08KPRG(data >> 2, PRGArea.Area8000); - break; - case 32507: - Switch08KPRG(data >> 2, PRGArea.AreaA000); - break; - case 32508: - Switch08KPRG(data >> 2, PRGArea.AreaC000); - break; - case 32503: - case 32504: - case 32505: - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(chr_mode); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - chr_mode = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Taito X1-17 ", 82)] +internal class Mapper082 : Board +{ + private bool chr_mode; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + switch (address) + { + case 32496: + Switch02KCHR(data >> 1, chr_mode ? CHRArea.Area1000 : CHRArea.Area0000); + break; + case 32497: + Switch02KCHR(data >> 1, chr_mode ? CHRArea.Area1800 : CHRArea.Area0800); + break; + case 32498: + Switch01KCHR(data, (!chr_mode) ? CHRArea.Area1000 : CHRArea.Area0000); + break; + case 32499: + Switch01KCHR(data, chr_mode ? CHRArea.Area0400 : CHRArea.Area1400); + break; + case 32500: + Switch01KCHR(data, chr_mode ? CHRArea.Area0800 : CHRArea.Area1800); + break; + case 32501: + Switch01KCHR(data, chr_mode ? CHRArea.Area0C00 : CHRArea.Area1C00); + break; + case 32502: + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Vert : Mirroring.Horz); + chr_mode = (data & 2) == 2; + break; + case 32506: + Switch08KPRG(data >> 2, PRGArea.Area8000); + break; + case 32507: + Switch08KPRG(data >> 2, PRGArea.AreaA000); + break; + case 32508: + Switch08KPRG(data >> 2, PRGArea.AreaC000); + break; + case 32503: + case 32504: + case 32505: + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(chr_mode); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + chr_mode = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper085.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper085.cs index e6e682d..03c43a9 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper085.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper085.cs @@ -1,171 +1,170 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("VRC7", 85)] - [HassIssues] - internal class Mapper085 : Board - { - private int irq_reload; - - private int irq_counter; - - private int prescaler; - - private bool irq_mode_cycle; - - private bool irq_enable; - - private bool irq_enable_on_ak; - - internal override string Issues => MNInterfaceLanguage.IssueMapper85; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - irq_reload = 0; - prescaler = 341; - irq_counter = 0; - irq_mode_cycle = false; - irq_enable = false; - irq_enable_on_ak = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address) - { - case 32768: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 32776: - case 32784: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 36864: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 40960: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 40968: - case 40976: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 45056: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 45064: - case 45072: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 49152: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 49160: - case 49168: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 53248: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 53256: - case 53264: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 57344: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 57352: - case 57360: - irq_reload = data; - break; - case 61440: - irq_mode_cycle = (data & 4) == 4; - irq_enable = (data & 2) == 2; - irq_enable_on_ak = (data & 1) == 1; - if (irq_enable) - { - irq_counter = irq_reload; - prescaler = 341; - } - NesEmu.IRQFlags &= -9; - break; - case 61448: - case 61456: - NesEmu.IRQFlags &= -9; - irq_enable = irq_enable_on_ak; - break; - } - } - - internal override void OnCPUClock() - { - if (!irq_enable) - { - return; - } - if (!irq_mode_cycle) - { - if (prescaler > 0) - { - prescaler -= 3; - return; - } - prescaler = 341; - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - else - { - irq_counter++; - if (irq_counter == 255) - { - NesEmu.IRQFlags |= 8; - irq_counter = irq_reload; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(prescaler); - stream.Write(irq_counter); - stream.Write(irq_mode_cycle); - stream.Write(irq_reload); - stream.Write(irq_enable); - stream.Write(irq_enable_on_ak); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - prescaler = stream.ReadInt32(); - irq_counter = stream.ReadInt32(); - irq_mode_cycle = stream.ReadBoolean(); - irq_reload = stream.ReadInt32(); - irq_enable = stream.ReadBoolean(); - irq_enable_on_ak = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("VRC7", 85)] +[HassIssues] +internal class Mapper085 : Board +{ + private int irq_reload; + + private int irq_counter; + + private int prescaler; + + private bool irq_mode_cycle; + + private bool irq_enable; + + private bool irq_enable_on_ak; + + internal override string Issues => MNInterfaceLanguage.IssueMapper85; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + irq_reload = 0; + prescaler = 341; + irq_counter = 0; + irq_mode_cycle = false; + irq_enable = false; + irq_enable_on_ak = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address) + { + case 32768: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 32776: + case 32784: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 36864: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 40960: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 40968: + case 40976: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 45056: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 45064: + case 45072: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 49152: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 49160: + case 49168: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 53248: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 53256: + case 53264: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 57344: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 57352: + case 57360: + irq_reload = data; + break; + case 61440: + irq_mode_cycle = (data & 4) == 4; + irq_enable = (data & 2) == 2; + irq_enable_on_ak = (data & 1) == 1; + if (irq_enable) + { + irq_counter = irq_reload; + prescaler = 341; + } + NesEmu.IRQFlags &= -9; + break; + case 61448: + case 61456: + NesEmu.IRQFlags &= -9; + irq_enable = irq_enable_on_ak; + break; + } + } + + internal override void OnCPUClock() + { + if (!irq_enable) + { + return; + } + if (!irq_mode_cycle) + { + if (prescaler > 0) + { + prescaler -= 3; + return; + } + prescaler = 341; + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + else + { + irq_counter++; + if (irq_counter == 255) + { + NesEmu.IRQFlags |= 8; + irq_counter = irq_reload; + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(prescaler); + stream.Write(irq_counter); + stream.Write(irq_mode_cycle); + stream.Write(irq_reload); + stream.Write(irq_enable); + stream.Write(irq_enable_on_ak); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + prescaler = stream.ReadInt32(); + irq_counter = stream.ReadInt32(); + irq_mode_cycle = stream.ReadBoolean(); + irq_reload = stream.ReadInt32(); + irq_enable = stream.ReadBoolean(); + irq_enable_on_ak = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper086.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper086.cs index 410ea5f..8076423 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper086.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper086.cs @@ -1,15 +1,14 @@ -namespace MyNes.Core -{ - [BoardInfo("Jaleco Early Mapper 2", 86)] - internal class Mapper086 : Board - { - internal override void WriteSRM(ref ushort address, ref byte data) - { - if (address < 28672) - { - Switch32KPRG((data >> 4) & 3, PRGArea.Area8000); - Switch08KCHR((data & 7) | ((data >> 4) & 4)); - } - } - } +namespace MyNes.Core; + +[BoardInfo("Jaleco Early Mapper 2", 86)] +internal class Mapper086 : Board +{ + internal override void WriteSRM(ref ushort address, ref byte data) + { + if (address < 28672) + { + Switch32KPRG((data >> 4) & 3, PRGArea.Area8000); + Switch08KCHR((data & 7) | ((data >> 4) & 4)); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper087.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper087.cs index 7764a7d..e5105bf 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper087.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper087.cs @@ -1,11 +1,10 @@ -namespace MyNes.Core -{ - [BoardInfo("Jaleco/Konami", 87)] - internal class Mapper087 : Board - { - internal override void WriteSRM(ref ushort address, ref byte data) - { - Switch08KCHR(((data & 2) >> 1) | ((data & 1) << 1)); - } - } +namespace MyNes.Core; + +[BoardInfo("Jaleco/Konami", 87)] +internal class Mapper087 : Board +{ + internal override void WriteSRM(ref ushort address, ref byte data) + { + Switch08KCHR(((data & 2) >> 1) | ((data & 1) << 1)); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper088.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper088.cs index 31cdc9b..8e14db7 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper088.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper088.cs @@ -1,67 +1,66 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Namco 118", 88)] - internal class Mapper088 : Board - { - private int address_8001; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0x8001) - { - case 32768: - address_8001 = data & 7; - break; - case 32769: - switch (address_8001) - { - case 0: - Switch02KCHR((data & 0x3F) >> 1, CHRArea.Area0000); - break; - case 1: - Switch02KCHR((data & 0x3F) >> 1, CHRArea.Area0800); - break; - case 2: - Switch01KCHR(data | 0x40, CHRArea.Area1000); - break; - case 3: - Switch01KCHR(data | 0x40, CHRArea.Area1400); - break; - case 4: - Switch01KCHR(data | 0x40, CHRArea.Area1800); - break; - case 5: - Switch01KCHR(data | 0x40, CHRArea.Area1C00); - break; - case 6: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 7: - Switch08KPRG(data, PRGArea.AreaA000); - break; - } - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(address_8001); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - address_8001 = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Namco 118", 88)] +internal class Mapper088 : Board +{ + private int address_8001; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0x8001) + { + case 32768: + address_8001 = data & 7; + break; + case 32769: + switch (address_8001) + { + case 0: + Switch02KCHR((data & 0x3F) >> 1, CHRArea.Area0000); + break; + case 1: + Switch02KCHR((data & 0x3F) >> 1, CHRArea.Area0800); + break; + case 2: + Switch01KCHR(data | 0x40, CHRArea.Area1000); + break; + case 3: + Switch01KCHR(data | 0x40, CHRArea.Area1400); + break; + case 4: + Switch01KCHR(data | 0x40, CHRArea.Area1800); + break; + case 5: + Switch01KCHR(data | 0x40, CHRArea.Area1C00); + break; + case 6: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 7: + Switch08KPRG(data, PRGArea.AreaA000); + break; + } + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(address_8001); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + address_8001 = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper089.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper089.cs index 17eae88..7695540 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper089.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper089.cs @@ -1,19 +1,18 @@ -namespace MyNes.Core -{ - [BoardInfo("Sunsoft Early", 89)] - internal class Mapper089 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR((data & 7) | ((data >> 4) & 8)); - Switch16KPRG((data >> 4) & 7, PRGArea.Area8000); - Switch01KNMTFromMirroring(((data & 8) == 8) ? Mirroring.OneScB : Mirroring.OneScA); - } - } +namespace MyNes.Core; + +[BoardInfo("Sunsoft Early", 89)] +internal class Mapper089 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR((data & 7) | ((data >> 4) & 8)); + Switch16KPRG((data >> 4) & 7, PRGArea.Area8000); + Switch01KNMTFromMirroring(((data & 8) == 8) ? Mirroring.OneScB : Mirroring.OneScA); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper090.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper090.cs index dbc7371..57977c0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper090.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper090.cs @@ -1,634 +1,633 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Pirate MMC5-style", 90)] - [HassIssues] - internal class Mapper090 : Board - { - protected bool MAPPER90MODE; - - private int[] prg_reg; - - private int[] chr_reg; - - private int[] nt_reg; - - private int prg_mode; - - private int chr_mode; - - private bool chr_block_mode; - - private int chr_block; - - private bool chr_m; - - private bool flag_s; - - private int irqCounter = 0; - - private bool IrqEnable = false; - - private bool irqCountDownMode = false; - - private bool irqCountUpMode = false; - - private bool irqFunkyMode = false; - - private bool irqPrescalerSize = false; - - private int irqSource = 0; - - private int irqPrescaler = 0; - - private int irqPrescalerXOR = 0; - - private byte irqFunkyModeReg = 0; - - private byte Dipswitch; - - private byte multiplication_a; - - private byte multiplication_b; - - private ushort multiplication; - - private byte RAM5803; - - private bool nt_advanced_enable; - - private bool nt_rom_only; - - private int nt_ram_select; - - internal override string Issues => MNInterfaceLanguage.IssueMapper90; - - internal override void HardReset() - { - base.HardReset(); - MAPPER90MODE = true; - prg_reg = new int[4]; - chr_reg = new int[8]; - nt_reg = new int[4]; - prg_mode = (chr_mode = 0); - for (int i = 0; i < 4; i++) - { - prg_reg[i] = i; - nt_reg[i] = i; - } - for (int j = 0; j < 8; j++) - { - chr_reg[j] = j; - } - SetupPRG(); - SetupCHR(); - Dipswitch = 0; - irqCounter = 0; - IrqEnable = false; - irqCountDownMode = false; - irqCountUpMode = false; - irqFunkyMode = false; - irqPrescalerSize = false; - irqSource = 0; - irqPrescaler = 0; - irqPrescalerXOR = 0; - irqFunkyModeReg = 0; - RAM5803 = 0; - flag_s = false; - multiplication_a = 0; - multiplication_b = 0; - multiplication = 0; - } - - internal override void SoftReset() - { - base.SoftReset(); - if (Dipswitch == 0) - { - Dipswitch = byte.MaxValue; - } - else - { - Dipswitch = 0; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF007) - { - case 32768: - case 32769: - case 32770: - case 32771: - case 32772: - case 32773: - case 32774: - case 32775: - prg_reg[address & 3] = data & 0x7F; - SetupPRG(); - break; - case 36864: - case 36865: - case 36866: - case 36867: - case 36868: - case 36869: - case 36870: - case 36871: - chr_reg[address & 7] = (chr_reg[address & 7] & 0xFF00) | data; - SetupCHR(); - break; - case 40960: - case 40961: - case 40962: - case 40963: - case 40964: - case 40965: - case 40966: - case 40967: - chr_reg[address & 7] = (chr_reg[address & 7] & 0xFF) | (data << 8); - SetupCHR(); - break; - case 45056: - case 45057: - case 45058: - case 45059: - nt_reg[address & 3] = (nt_reg[address & 3] & 0xFF00) | data; - break; - case 45060: - case 45061: - case 45062: - case 45063: - nt_reg[address & 3] = (nt_reg[address & 3] & 0xFF) | (data << 8); - break; - case 49152: - IrqEnable = (data & 1) == 1; - if (!IrqEnable) - { - NesEmu.IRQFlags &= -9; - } - break; - case 49153: - irqCountDownMode = (data & 0x80) == 128; - irqCountUpMode = (data & 0x40) == 64; - irqFunkyMode = (data & 8) == 8; - irqPrescalerSize = (data & 4) == 4; - irqSource = data & 3; - break; - case 49154: - IrqEnable = false; - NesEmu.IRQFlags &= -9; - break; - case 49155: - IrqEnable = true; - break; - case 49156: - irqPrescaler = data ^ irqPrescalerXOR; - break; - case 49157: - irqCounter = data ^ irqPrescalerXOR; - break; - case 49158: - irqPrescalerXOR = data; - break; - case 49159: - irqFunkyModeReg = data; - break; - case 53248: - flag_s = (data & 0x80) == 128; - prg_mode = data & 7; - chr_mode = (data >> 3) & 3; - nt_advanced_enable = (data & 0x20) == 32; - nt_rom_only = (data & 0x40) == 64; - SetupPRG(); - SetupCHR(); - break; - case 53249: - switch (data & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 53250: - nt_ram_select = data & 0x80; - break; - case 53251: - chr_m = (data & 0x80) == 128; - chr_block_mode = (data & 0x20) == 32; - chr_block = (data & 0x1F) << 8; - SetupCHR(); - break; - } - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - } - - internal override void ReadSRM(ref ushort address, out byte data) - { - if (flag_s) - { - base.ReadSRM(ref address, out data); - } - else - { - data = 0; - } - } - - internal override void ReadEX(ref ushort address, out byte data) - { - switch (address) - { - case 20480: - data = Dipswitch; - break; - case 22528: - data = (byte)(multiplication & 0xFFu); - break; - case 22529: - data = (byte)((multiplication & 0xFF00) >> 8); - break; - case 22531: - data = RAM5803; - break; - default: - data = 0; - break; - } - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - switch (address) - { - case 22528: - multiplication_a = data; - multiplication = (ushort)(multiplication_a * multiplication_b); - break; - case 22529: - multiplication_b = data; - multiplication = (ushort)(multiplication_a * multiplication_b); - break; - case 22531: - RAM5803 = data; - break; - case 22530: - break; - } - } - - internal override void ReadNMT(ref ushort address, out byte data) - { - if (MAPPER90MODE) - { - data = NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF]; - } - if (!nt_advanced_enable) - { - data = NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF]; - } - else if (nt_rom_only) - { - data = CHR_ROM[nt_reg[(address >> 10) & 3]][address & 0x3FF]; - } - else if ((nt_reg[(address >> 10) & 3] & 0x80) != nt_ram_select) - { - data = CHR_ROM[nt_reg[(address >> 10) & 3]][address & 0x3FF]; - } - else - { - data = NMT_RAM[nt_reg[(address >> 10) & 3] & 1][address & 0x3FF]; - } - } - - internal override void WriteNMT(ref ushort address, ref byte data) - { - if (MAPPER90MODE) - { - NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF] = data; - } - else if (!nt_advanced_enable) - { - NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF] = data; - } - else if (!nt_rom_only && (nt_reg[(address >> 10) & 3] & 0x80) == nt_ram_select) - { - NMT_RAM[nt_reg[(address >> 10) & 3] & 1][address & 0x3FF] = data; - } - } - - private void SetupPRG() - { - switch (prg_mode) - { - case 0: - Switch08KPRG(prg_reg[3] * 4 + 3, PRGArea.Area6000); - Switch32KPRG(PRG_ROM_32KB_Mask, PRGArea.Area8000); - break; - case 1: - Switch08KPRG(prg_reg[3] * 2 + 1, PRGArea.Area6000); - Switch16KPRG(prg_reg[1], PRGArea.Area8000); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - break; - case 2: - Switch08KPRG(prg_reg[3], PRGArea.Area6000); - Switch08KPRG(prg_reg[0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[2], PRGArea.AreaC000); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - break; - case 3: - Switch08KPRG(ReverseByte(prg_reg[3]), PRGArea.Area6000); - Switch08KPRG(ReverseByte(prg_reg[0]), PRGArea.Area8000); - Switch08KPRG(ReverseByte(prg_reg[1]), PRGArea.AreaA000); - Switch08KPRG(ReverseByte(prg_reg[2]), PRGArea.AreaC000); - Switch08KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaE000); - break; - case 4: - Switch08KPRG(prg_reg[3] * 4 + 3, PRGArea.Area6000); - Switch32KPRG(prg_reg[3], PRGArea.Area8000); - break; - case 5: - Switch08KPRG(prg_reg[3] * 2 + 1, PRGArea.Area6000); - Switch16KPRG(prg_reg[1], PRGArea.Area8000); - Switch16KPRG(prg_reg[3], PRGArea.AreaC000); - break; - case 6: - Switch08KPRG(prg_reg[3], PRGArea.Area6000); - Switch08KPRG(prg_reg[0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[2], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - break; - case 7: - Switch08KPRG(ReverseByte(prg_reg[3]), PRGArea.Area6000); - Switch08KPRG(ReverseByte(prg_reg[0]), PRGArea.Area8000); - Switch08KPRG(ReverseByte(prg_reg[1]), PRGArea.AreaA000); - Switch08KPRG(ReverseByte(prg_reg[2]), PRGArea.AreaC000); - Switch08KPRG(ReverseByte(prg_reg[3]), PRGArea.AreaE000); - break; - } - } - - private void SetupCHR() - { - switch (chr_mode) - { - case 0: - if (chr_block_mode) - { - Switch08KCHR(chr_reg[0]); - } - else - { - Switch08KCHR((chr_reg[0] & 0xFF) | chr_block); - } - break; - case 1: - if (chr_block_mode) - { - Switch04KCHR(chr_reg[0], CHRArea.Area0000); - Switch04KCHR(chr_reg[4], CHRArea.Area1000); - } - else - { - Switch04KCHR((chr_reg[0] & 0xFF) | chr_block, CHRArea.Area0000); - Switch04KCHR((chr_reg[4] & 0xFF) | chr_block, CHRArea.Area1000); - } - break; - case 2: - if (chr_block_mode) - { - Switch02KCHR(chr_reg[0], CHRArea.Area0000); - Switch02KCHR(chr_m ? chr_reg[0] : chr_reg[2], CHRArea.Area0800); - Switch02KCHR(chr_reg[4], CHRArea.Area1000); - Switch02KCHR(chr_reg[6], CHRArea.Area1800); - } - else - { - Switch02KCHR((chr_reg[0] & 0xFF) | chr_block, CHRArea.Area0000); - Switch02KCHR(((chr_m ? chr_reg[0] : chr_reg[2]) & 0xFF) | chr_block, CHRArea.Area0800); - Switch02KCHR((chr_reg[4] & 0xFF) | chr_block, CHRArea.Area1000); - Switch02KCHR((chr_reg[6] & 0xFF) | chr_block, CHRArea.Area1800); - } - break; - case 3: - if (chr_block_mode) - { - Switch01KCHR(chr_reg[0], CHRArea.Area0000); - Switch01KCHR(chr_reg[1], CHRArea.Area0400); - Switch01KCHR(chr_m ? chr_reg[0] : chr_reg[2], CHRArea.Area0800); - Switch01KCHR(chr_m ? chr_reg[1] : chr_reg[3], CHRArea.Area0C00); - Switch01KCHR(chr_reg[4], CHRArea.Area1000); - Switch01KCHR(chr_reg[5], CHRArea.Area1400); - Switch01KCHR(chr_reg[6], CHRArea.Area1800); - Switch01KCHR(chr_reg[7], CHRArea.Area1C00); - } - else - { - Switch01KCHR((chr_reg[0] & 0xFF) | chr_block, CHRArea.Area0000); - Switch01KCHR((chr_reg[1] & 0xFF) | chr_block, CHRArea.Area0400); - Switch01KCHR(((chr_m ? chr_reg[0] : chr_reg[2]) & 0xFF) | chr_block, CHRArea.Area0800); - Switch01KCHR(((chr_m ? chr_reg[1] : chr_reg[3]) & 0xFF) | chr_block, CHRArea.Area0C00); - Switch01KCHR((chr_reg[4] & 0xFF) | chr_block, CHRArea.Area1000); - Switch01KCHR((chr_reg[5] & 0xFF) | chr_block, CHRArea.Area1400); - Switch01KCHR((chr_reg[6] & 0xFF) | chr_block, CHRArea.Area1800); - Switch01KCHR((chr_reg[7] & 0xFF) | chr_block, CHRArea.Area1C00); - } - break; - } - } - - private byte ReverseByte(int value) - { - return (byte)((uint)(((value & 0x40) >> 6) | ((value & 0x20) >> 4) | ((value & 0x10) >> 2)) | ((uint)value & 8u) | (uint)((value & 4) << 2) | (uint)((value & 2) << 4) | (uint)((value & 1) << 6)); - } - - internal override void OnCPUClock() - { - if (irqSource != 0) - { - return; - } - if (irqPrescalerSize) - { - irqPrescaler = (irqPrescaler & 0xF8) | (((irqPrescaler & 7) + 1) & 7); - if ((irqPrescaler & 7) == 7) - { - ClockIRQCounter(); - } - } - else - { - irqPrescaler++; - if (irqPrescaler == 255) - { - ClockIRQCounter(); - } - } - } - - internal override void OnPPUAddressUpdate(ref ushort address) - { - if (irqSource != 1) - { - return; - } - old_vram_address = new_vram_address; - new_vram_address = address & 0x1000; - if (old_vram_address >= new_vram_address) - { - return; - } - if (irqPrescalerSize) - { - irqPrescaler = (irqPrescaler & 0xF8) | (((irqPrescaler & 7) + 1) & 7); - if ((irqPrescaler & 7) == 7) - { - ClockIRQCounter(); - } - } - else - { - irqPrescaler++; - if (irqPrescaler == 255) - { - ClockIRQCounter(); - } - } - } - - private void ClockIRQCounter() - { - if (irqCountDownMode && irqCountUpMode) - { - return; - } - if (irqCountDownMode) - { - irqCounter--; - if (irqCounter == 0) - { - irqCounter = 255; - if (IrqEnable) - { - NesEmu.IRQFlags |= 8; - } - } - } - else - { - if (!irqCountUpMode) - { - return; - } - irqCounter++; - if (irqCounter == 255) - { - irqCounter = 0; - if (IrqEnable) - { - NesEmu.IRQFlags |= 8; - } - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - for (int i = 0; i < prg_reg.Length; i++) - { - stream.Write(prg_reg[i]); - } - for (int j = 0; j < chr_reg.Length; j++) - { - stream.Write(chr_reg[j]); - } - for (int k = 0; k < nt_reg.Length; k++) - { - stream.Write(nt_reg[k]); - } - stream.Write(prg_mode); - stream.Write(chr_mode); - stream.Write(chr_block_mode); - stream.Write(chr_block); - stream.Write(chr_m); - stream.Write(flag_s); - stream.Write(irqCounter); - stream.Write(IrqEnable); - stream.Write(irqCountDownMode); - stream.Write(irqCountUpMode); - stream.Write(irqFunkyMode); - stream.Write(irqPrescalerSize); - stream.Write(irqSource); - stream.Write(irqPrescaler); - stream.Write(irqPrescalerXOR); - stream.Write(irqFunkyModeReg); - stream.Write(Dipswitch); - stream.Write(multiplication_a); - stream.Write(multiplication_b); - stream.Write(multiplication); - stream.Write(RAM5803); - stream.Write(nt_advanced_enable); - stream.Write(nt_rom_only); - stream.Write(nt_ram_select); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - for (int i = 0; i < prg_reg.Length; i++) - { - prg_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < chr_reg.Length; j++) - { - chr_reg[j] = stream.ReadInt32(); - } - for (int k = 0; k < nt_reg.Length; k++) - { - nt_reg[k] = stream.ReadInt32(); - } - prg_mode = stream.ReadInt32(); - chr_mode = stream.ReadInt32(); - chr_block_mode = stream.ReadBoolean(); - chr_block = stream.ReadInt32(); - chr_m = stream.ReadBoolean(); - flag_s = stream.ReadBoolean(); - irqCounter = stream.ReadInt32(); - IrqEnable = stream.ReadBoolean(); - irqCountDownMode = stream.ReadBoolean(); - irqCountUpMode = stream.ReadBoolean(); - irqFunkyMode = stream.ReadBoolean(); - irqPrescalerSize = stream.ReadBoolean(); - irqSource = stream.ReadInt32(); - irqPrescaler = stream.ReadInt32(); - irqPrescalerXOR = stream.ReadInt32(); - irqFunkyModeReg = stream.ReadByte(); - Dipswitch = stream.ReadByte(); - multiplication_a = stream.ReadByte(); - multiplication_b = stream.ReadByte(); - multiplication = stream.ReadUInt16(); - RAM5803 = stream.ReadByte(); - nt_advanced_enable = stream.ReadBoolean(); - nt_rom_only = stream.ReadBoolean(); - nt_ram_select = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Pirate MMC5-style", 90)] +[HassIssues] +internal class Mapper090 : Board +{ + protected bool MAPPER90MODE; + + private int[] prg_reg; + + private int[] chr_reg; + + private int[] nt_reg; + + private int prg_mode; + + private int chr_mode; + + private bool chr_block_mode; + + private int chr_block; + + private bool chr_m; + + private bool flag_s; + + private int irqCounter; + + private bool IrqEnable; + + private bool irqCountDownMode; + + private bool irqCountUpMode; + + private bool irqFunkyMode; + + private bool irqPrescalerSize; + + private int irqSource; + + private int irqPrescaler; + + private int irqPrescalerXOR; + + private byte irqFunkyModeReg; + + private byte Dipswitch; + + private byte multiplication_a; + + private byte multiplication_b; + + private ushort multiplication; + + private byte RAM5803; + + private bool nt_advanced_enable; + + private bool nt_rom_only; + + private int nt_ram_select; + + internal override string Issues => MNInterfaceLanguage.IssueMapper90; + + internal override void HardReset() + { + base.HardReset(); + MAPPER90MODE = true; + prg_reg = new int[4]; + chr_reg = new int[8]; + nt_reg = new int[4]; + prg_mode = (chr_mode = 0); + for (int i = 0; i < 4; i++) + { + prg_reg[i] = i; + nt_reg[i] = i; + } + for (int j = 0; j < 8; j++) + { + chr_reg[j] = j; + } + SetupPRG(); + SetupCHR(); + Dipswitch = 0; + irqCounter = 0; + IrqEnable = false; + irqCountDownMode = false; + irqCountUpMode = false; + irqFunkyMode = false; + irqPrescalerSize = false; + irqSource = 0; + irqPrescaler = 0; + irqPrescalerXOR = 0; + irqFunkyModeReg = 0; + RAM5803 = 0; + flag_s = false; + multiplication_a = 0; + multiplication_b = 0; + multiplication = 0; + } + + internal override void SoftReset() + { + base.SoftReset(); + if (Dipswitch == 0) + { + Dipswitch = byte.MaxValue; + } + else + { + Dipswitch = 0; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF007) + { + case 32768: + case 32769: + case 32770: + case 32771: + case 32772: + case 32773: + case 32774: + case 32775: + prg_reg[address & 3] = data & 0x7F; + SetupPRG(); + break; + case 36864: + case 36865: + case 36866: + case 36867: + case 36868: + case 36869: + case 36870: + case 36871: + chr_reg[address & 7] = (chr_reg[address & 7] & 0xFF00) | data; + SetupCHR(); + break; + case 40960: + case 40961: + case 40962: + case 40963: + case 40964: + case 40965: + case 40966: + case 40967: + chr_reg[address & 7] = (chr_reg[address & 7] & 0xFF) | (data << 8); + SetupCHR(); + break; + case 45056: + case 45057: + case 45058: + case 45059: + nt_reg[address & 3] = (nt_reg[address & 3] & 0xFF00) | data; + break; + case 45060: + case 45061: + case 45062: + case 45063: + nt_reg[address & 3] = (nt_reg[address & 3] & 0xFF) | (data << 8); + break; + case 49152: + IrqEnable = (data & 1) == 1; + if (!IrqEnable) + { + NesEmu.IRQFlags &= -9; + } + break; + case 49153: + irqCountDownMode = (data & 0x80) == 128; + irqCountUpMode = (data & 0x40) == 64; + irqFunkyMode = (data & 8) == 8; + irqPrescalerSize = (data & 4) == 4; + irqSource = data & 3; + break; + case 49154: + IrqEnable = false; + NesEmu.IRQFlags &= -9; + break; + case 49155: + IrqEnable = true; + break; + case 49156: + irqPrescaler = data ^ irqPrescalerXOR; + break; + case 49157: + irqCounter = data ^ irqPrescalerXOR; + break; + case 49158: + irqPrescalerXOR = data; + break; + case 49159: + irqFunkyModeReg = data; + break; + case 53248: + flag_s = (data & 0x80) == 128; + prg_mode = data & 7; + chr_mode = (data >> 3) & 3; + nt_advanced_enable = (data & 0x20) == 32; + nt_rom_only = (data & 0x40) == 64; + SetupPRG(); + SetupCHR(); + break; + case 53249: + switch (data & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 53250: + nt_ram_select = data & 0x80; + break; + case 53251: + chr_m = (data & 0x80) == 128; + chr_block_mode = (data & 0x20) == 32; + chr_block = (data & 0x1F) << 8; + SetupCHR(); + break; + } + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + } + + internal override void ReadSRM(ref ushort address, out byte data) + { + if (flag_s) + { + base.ReadSRM(ref address, out data); + } + else + { + data = 0; + } + } + + internal override void ReadEX(ref ushort address, out byte data) + { + switch (address) + { + case 20480: + data = Dipswitch; + break; + case 22528: + data = (byte)(multiplication & 0xFFu); + break; + case 22529: + data = (byte)((multiplication & 0xFF00) >> 8); + break; + case 22531: + data = RAM5803; + break; + default: + data = 0; + break; + } + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + switch (address) + { + case 22528: + multiplication_a = data; + multiplication = (ushort)(multiplication_a * multiplication_b); + break; + case 22529: + multiplication_b = data; + multiplication = (ushort)(multiplication_a * multiplication_b); + break; + case 22531: + RAM5803 = data; + break; + case 22530: + break; + } + } + + internal override void ReadNMT(ref ushort address, out byte data) + { + if (MAPPER90MODE) + { + data = NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF]; + } + if (!nt_advanced_enable) + { + data = NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF]; + } + else if (nt_rom_only) + { + data = CHR_ROM[nt_reg[(address >> 10) & 3]][address & 0x3FF]; + } + else if ((nt_reg[(address >> 10) & 3] & 0x80) != nt_ram_select) + { + data = CHR_ROM[nt_reg[(address >> 10) & 3]][address & 0x3FF]; + } + else + { + data = NMT_RAM[nt_reg[(address >> 10) & 3] & 1][address & 0x3FF]; + } + } + + internal override void WriteNMT(ref ushort address, ref byte data) + { + if (MAPPER90MODE) + { + NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF] = data; + } + else if (!nt_advanced_enable) + { + NMT_RAM[NMT_AREA_BLK_INDEX[(address >> 10) & 3]][address & 0x3FF] = data; + } + else if (!nt_rom_only && (nt_reg[(address >> 10) & 3] & 0x80) == nt_ram_select) + { + NMT_RAM[nt_reg[(address >> 10) & 3] & 1][address & 0x3FF] = data; + } + } + + private void SetupPRG() + { + switch (prg_mode) + { + case 0: + Switch08KPRG(prg_reg[3] * 4 + 3, PRGArea.Area6000); + Switch32KPRG(PRG_ROM_32KB_Mask, PRGArea.Area8000); + break; + case 1: + Switch08KPRG(prg_reg[3] * 2 + 1, PRGArea.Area6000); + Switch16KPRG(prg_reg[1], PRGArea.Area8000); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + break; + case 2: + Switch08KPRG(prg_reg[3], PRGArea.Area6000); + Switch08KPRG(prg_reg[0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[2], PRGArea.AreaC000); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + break; + case 3: + Switch08KPRG(ReverseByte(prg_reg[3]), PRGArea.Area6000); + Switch08KPRG(ReverseByte(prg_reg[0]), PRGArea.Area8000); + Switch08KPRG(ReverseByte(prg_reg[1]), PRGArea.AreaA000); + Switch08KPRG(ReverseByte(prg_reg[2]), PRGArea.AreaC000); + Switch08KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaE000); + break; + case 4: + Switch08KPRG(prg_reg[3] * 4 + 3, PRGArea.Area6000); + Switch32KPRG(prg_reg[3], PRGArea.Area8000); + break; + case 5: + Switch08KPRG(prg_reg[3] * 2 + 1, PRGArea.Area6000); + Switch16KPRG(prg_reg[1], PRGArea.Area8000); + Switch16KPRG(prg_reg[3], PRGArea.AreaC000); + break; + case 6: + Switch08KPRG(prg_reg[3], PRGArea.Area6000); + Switch08KPRG(prg_reg[0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[2], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + break; + case 7: + Switch08KPRG(ReverseByte(prg_reg[3]), PRGArea.Area6000); + Switch08KPRG(ReverseByte(prg_reg[0]), PRGArea.Area8000); + Switch08KPRG(ReverseByte(prg_reg[1]), PRGArea.AreaA000); + Switch08KPRG(ReverseByte(prg_reg[2]), PRGArea.AreaC000); + Switch08KPRG(ReverseByte(prg_reg[3]), PRGArea.AreaE000); + break; + } + } + + private void SetupCHR() + { + switch (chr_mode) + { + case 0: + if (chr_block_mode) + { + Switch08KCHR(chr_reg[0]); + } + else + { + Switch08KCHR((chr_reg[0] & 0xFF) | chr_block); + } + break; + case 1: + if (chr_block_mode) + { + Switch04KCHR(chr_reg[0], CHRArea.Area0000); + Switch04KCHR(chr_reg[4], CHRArea.Area1000); + } + else + { + Switch04KCHR((chr_reg[0] & 0xFF) | chr_block, CHRArea.Area0000); + Switch04KCHR((chr_reg[4] & 0xFF) | chr_block, CHRArea.Area1000); + } + break; + case 2: + if (chr_block_mode) + { + Switch02KCHR(chr_reg[0], CHRArea.Area0000); + Switch02KCHR(chr_m ? chr_reg[0] : chr_reg[2], CHRArea.Area0800); + Switch02KCHR(chr_reg[4], CHRArea.Area1000); + Switch02KCHR(chr_reg[6], CHRArea.Area1800); + } + else + { + Switch02KCHR((chr_reg[0] & 0xFF) | chr_block, CHRArea.Area0000); + Switch02KCHR(((chr_m ? chr_reg[0] : chr_reg[2]) & 0xFF) | chr_block, CHRArea.Area0800); + Switch02KCHR((chr_reg[4] & 0xFF) | chr_block, CHRArea.Area1000); + Switch02KCHR((chr_reg[6] & 0xFF) | chr_block, CHRArea.Area1800); + } + break; + case 3: + if (chr_block_mode) + { + Switch01KCHR(chr_reg[0], CHRArea.Area0000); + Switch01KCHR(chr_reg[1], CHRArea.Area0400); + Switch01KCHR(chr_m ? chr_reg[0] : chr_reg[2], CHRArea.Area0800); + Switch01KCHR(chr_m ? chr_reg[1] : chr_reg[3], CHRArea.Area0C00); + Switch01KCHR(chr_reg[4], CHRArea.Area1000); + Switch01KCHR(chr_reg[5], CHRArea.Area1400); + Switch01KCHR(chr_reg[6], CHRArea.Area1800); + Switch01KCHR(chr_reg[7], CHRArea.Area1C00); + } + else + { + Switch01KCHR((chr_reg[0] & 0xFF) | chr_block, CHRArea.Area0000); + Switch01KCHR((chr_reg[1] & 0xFF) | chr_block, CHRArea.Area0400); + Switch01KCHR(((chr_m ? chr_reg[0] : chr_reg[2]) & 0xFF) | chr_block, CHRArea.Area0800); + Switch01KCHR(((chr_m ? chr_reg[1] : chr_reg[3]) & 0xFF) | chr_block, CHRArea.Area0C00); + Switch01KCHR((chr_reg[4] & 0xFF) | chr_block, CHRArea.Area1000); + Switch01KCHR((chr_reg[5] & 0xFF) | chr_block, CHRArea.Area1400); + Switch01KCHR((chr_reg[6] & 0xFF) | chr_block, CHRArea.Area1800); + Switch01KCHR((chr_reg[7] & 0xFF) | chr_block, CHRArea.Area1C00); + } + break; + } + } + + private byte ReverseByte(int value) + { + return (byte)((uint)(((value & 0x40) >> 6) | ((value & 0x20) >> 4) | ((value & 0x10) >> 2)) | ((uint)value & 8u) | (uint)((value & 4) << 2) | (uint)((value & 2) << 4) | (uint)((value & 1) << 6)); + } + + internal override void OnCPUClock() + { + if (irqSource != 0) + { + return; + } + if (irqPrescalerSize) + { + irqPrescaler = (irqPrescaler & 0xF8) | (((irqPrescaler & 7) + 1) & 7); + if ((irqPrescaler & 7) == 7) + { + ClockIRQCounter(); + } + } + else + { + irqPrescaler++; + if (irqPrescaler == 255) + { + ClockIRQCounter(); + } + } + } + + internal override void OnPPUAddressUpdate(ref ushort address) + { + if (irqSource != 1) + { + return; + } + old_vram_address = new_vram_address; + new_vram_address = address & 0x1000; + if (old_vram_address >= new_vram_address) + { + return; + } + if (irqPrescalerSize) + { + irqPrescaler = (irqPrescaler & 0xF8) | (((irqPrescaler & 7) + 1) & 7); + if ((irqPrescaler & 7) == 7) + { + ClockIRQCounter(); + } + } + else + { + irqPrescaler++; + if (irqPrescaler == 255) + { + ClockIRQCounter(); + } + } + } + + private void ClockIRQCounter() + { + if (irqCountDownMode && irqCountUpMode) + { + return; + } + if (irqCountDownMode) + { + irqCounter--; + if (irqCounter == 0) + { + irqCounter = 255; + if (IrqEnable) + { + NesEmu.IRQFlags |= 8; + } + } + } + else + { + if (!irqCountUpMode) + { + return; + } + irqCounter++; + if (irqCounter == 255) + { + irqCounter = 0; + if (IrqEnable) + { + NesEmu.IRQFlags |= 8; + } + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + for (int i = 0; i < prg_reg.Length; i++) + { + stream.Write(prg_reg[i]); + } + for (int j = 0; j < chr_reg.Length; j++) + { + stream.Write(chr_reg[j]); + } + for (int k = 0; k < nt_reg.Length; k++) + { + stream.Write(nt_reg[k]); + } + stream.Write(prg_mode); + stream.Write(chr_mode); + stream.Write(chr_block_mode); + stream.Write(chr_block); + stream.Write(chr_m); + stream.Write(flag_s); + stream.Write(irqCounter); + stream.Write(IrqEnable); + stream.Write(irqCountDownMode); + stream.Write(irqCountUpMode); + stream.Write(irqFunkyMode); + stream.Write(irqPrescalerSize); + stream.Write(irqSource); + stream.Write(irqPrescaler); + stream.Write(irqPrescalerXOR); + stream.Write(irqFunkyModeReg); + stream.Write(Dipswitch); + stream.Write(multiplication_a); + stream.Write(multiplication_b); + stream.Write(multiplication); + stream.Write(RAM5803); + stream.Write(nt_advanced_enable); + stream.Write(nt_rom_only); + stream.Write(nt_ram_select); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + for (int i = 0; i < prg_reg.Length; i++) + { + prg_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < chr_reg.Length; j++) + { + chr_reg[j] = stream.ReadInt32(); + } + for (int k = 0; k < nt_reg.Length; k++) + { + nt_reg[k] = stream.ReadInt32(); + } + prg_mode = stream.ReadInt32(); + chr_mode = stream.ReadInt32(); + chr_block_mode = stream.ReadBoolean(); + chr_block = stream.ReadInt32(); + chr_m = stream.ReadBoolean(); + flag_s = stream.ReadBoolean(); + irqCounter = stream.ReadInt32(); + IrqEnable = stream.ReadBoolean(); + irqCountDownMode = stream.ReadBoolean(); + irqCountUpMode = stream.ReadBoolean(); + irqFunkyMode = stream.ReadBoolean(); + irqPrescalerSize = stream.ReadBoolean(); + irqSource = stream.ReadInt32(); + irqPrescaler = stream.ReadInt32(); + irqPrescalerXOR = stream.ReadInt32(); + irqFunkyModeReg = stream.ReadByte(); + Dipswitch = stream.ReadByte(); + multiplication_a = stream.ReadByte(); + multiplication_b = stream.ReadByte(); + multiplication = stream.ReadUInt16(); + RAM5803 = stream.ReadByte(); + nt_advanced_enable = stream.ReadBoolean(); + nt_rom_only = stream.ReadBoolean(); + nt_ram_select = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper091.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper091.cs index c3f994a..372bd69 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper091.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper091.cs @@ -1,96 +1,95 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("HK-SF3", 91, true, true)] - internal class Mapper091 : Board - { - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - switch (address & 0x7003) - { - case 24576: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 24577: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 24578: - Switch02KCHR(data, CHRArea.Area1000); - break; - case 24579: - Switch02KCHR(data, CHRArea.Area1800); - break; - case 28672: - Switch08KPRG(data & 0xF, PRGArea.Area8000); - break; - case 28673: - Switch08KPRG(data & 0xF, PRGArea.AreaA000); - break; - case 28674: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 28675: - irq_enabled = true; - irq_reload = 7; - irq_counter = 0; - break; - } - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("HK-SF3", 91, true, true)] +internal class Mapper091 : Board +{ + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + switch (address & 0x7003) + { + case 24576: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 24577: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 24578: + Switch02KCHR(data, CHRArea.Area1000); + break; + case 24579: + Switch02KCHR(data, CHRArea.Area1800); + break; + case 28672: + Switch08KPRG(data & 0xF, PRGArea.Area8000); + break; + case 28673: + Switch08KPRG(data & 0xF, PRGArea.AreaA000); + break; + case 28674: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 28675: + irq_enabled = true; + irq_reload = 7; + irq_counter = 0; + break; + } + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper092.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper092.cs index fd8f9a7..7009b8d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper092.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper092.cs @@ -1,50 +1,49 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Jaleco Early Mapper 1", 92)] - internal class Mapper092 : Board - { - private int chr_reg; - - private int prg_reg; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(0, PRGArea.Area8000); - chr_reg = (prg_reg = 0); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch ((data >> 6) & 3) - { - case 0: - Switch08KCHR(chr_reg); - Switch16KPRG(prg_reg, PRGArea.AreaC000); - break; - case 1: - chr_reg = data & 0xF; - break; - case 2: - prg_reg = data & 0xF; - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(chr_reg); - stream.Write(prg_reg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - chr_reg = stream.ReadInt32(); - prg_reg = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Jaleco Early Mapper 1", 92)] +internal class Mapper092 : Board +{ + private int chr_reg; + + private int prg_reg; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(0, PRGArea.Area8000); + chr_reg = (prg_reg = 0); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch ((data >> 6) & 3) + { + case 0: + Switch08KCHR(chr_reg); + Switch16KPRG(prg_reg, PRGArea.AreaC000); + break; + case 1: + chr_reg = data & 0xF; + break; + case 2: + prg_reg = data & 0xF; + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(chr_reg); + stream.Write(prg_reg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + chr_reg = stream.ReadInt32(); + prg_reg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper093.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper093.cs index bc67e0b..149c2c2 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper093.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper093.cs @@ -1,18 +1,17 @@ -namespace MyNes.Core -{ - [BoardInfo("74161/32", 93)] - internal class Mapper093 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch16KPRG((data >> 4) & 0xF, PRGArea.Area8000); - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - } +namespace MyNes.Core; + +[BoardInfo("74161/32", 93)] +internal class Mapper093 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch16KPRG((data >> 4) & 0xF, PRGArea.Area8000); + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper094.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper094.cs index 40a5810..54eb7a2 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper094.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper094.cs @@ -1,17 +1,16 @@ -namespace MyNes.Core -{ - [BoardInfo("74161/32", 94)] - internal class Mapper094 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch16KPRG((data >> 2) & 7, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("74161/32", 94)] +internal class Mapper094 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch16KPRG((data >> 2) & 7, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper095.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper095.cs index 2b704fd..6e2e92d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper095.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper095.cs @@ -1,265 +1,264 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Namcot MMC3-Style", 95, true, true)] - internal class Mapper095 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void ReadNMT(ref ushort address, out byte value) - { - if (flag_c) - { - value = NMT_RAM[(chr_reg[((address >> 10) & 3) + 2] & 0x20) >> 5][address & 0x3FF]; - return; - } - switch ((address >> 10) & 3) - { - case 0: - case 1: - value = NMT_RAM[(chr_reg[0] & 0x20) >> 5][address & 0x3FF]; - break; - case 2: - case 3: - value = NMT_RAM[(chr_reg[1] & 0x20) >> 5][address & 0x3FF]; - break; - default: - value = 0; - break; - } - } - - internal override void WriteNMT(ref ushort address, ref byte data) - { - if (flag_c) - { - NMT_RAM[(chr_reg[((address >> 10) & 3) + 2] & 0x20) >> 5][address & 0x3FF] = data; - return; - } - switch ((address >> 10) & 3) - { - case 0: - case 1: - NMT_RAM[(chr_reg[0] & 0x20) >> 5][address & 0x3FF] = data; - break; - case 2: - case 3: - NMT_RAM[(chr_reg[1] & 0x20) >> 5][address & 0x3FF] = data; - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Namcot MMC3-Style", 95, true, true)] +internal class Mapper095 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void ReadNMT(ref ushort address, out byte value) + { + if (flag_c) + { + value = NMT_RAM[(chr_reg[((address >> 10) & 3) + 2] & 0x20) >> 5][address & 0x3FF]; + return; + } + switch ((address >> 10) & 3) + { + case 0: + case 1: + value = NMT_RAM[(chr_reg[0] & 0x20) >> 5][address & 0x3FF]; + break; + case 2: + case 3: + value = NMT_RAM[(chr_reg[1] & 0x20) >> 5][address & 0x3FF]; + break; + default: + value = 0; + break; + } + } + + internal override void WriteNMT(ref ushort address, ref byte data) + { + if (flag_c) + { + NMT_RAM[(chr_reg[((address >> 10) & 3) + 2] & 0x20) >> 5][address & 0x3FF] = data; + return; + } + switch ((address >> 10) & 3) + { + case 0: + case 1: + NMT_RAM[(chr_reg[0] & 0x20) >> 5][address & 0x3FF] = data; + break; + case 2: + case 3: + NMT_RAM[(chr_reg[1] & 0x20) >> 5][address & 0x3FF] = data; + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper096.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper096.cs index 0fd1f2f..dc30da4 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper096.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper096.cs @@ -1,46 +1,45 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("74161/32", 96, 1, 32)] - internal class Mapper096 : Board - { - private int flag_c; - - internal override string Issues => MNInterfaceLanguage.IssueMapper96; - - internal override void HardReset() - { - base.HardReset(); - flag_c = 0; - Switch04KCHR(3, CHRArea.Area1000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch32KPRG(data & 3, PRGArea.Area8000); - flag_c = (((data & 4) == 4) ? 1 : 0); - Switch04KCHR(3, CHRArea.Area1000); - } - - internal override void OnPPUAddressUpdate(ref ushort address) - { - if ((address & 0x3FF) < 960 && (address & 0x1000) == 0) - { - Switch04KCHR(((address & 0x300) >> 8) | flag_c, CHRArea.Area0000); - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("74161/32", 96, 1, 32)] +internal class Mapper096 : Board +{ + private int flag_c; + + internal override string Issues => MNInterfaceLanguage.IssueMapper96; + + internal override void HardReset() + { + base.HardReset(); + flag_c = 0; + Switch04KCHR(3, CHRArea.Area1000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch32KPRG(data & 3, PRGArea.Area8000); + flag_c = (((data & 4) == 4) ? 1 : 0); + Switch04KCHR(3, CHRArea.Area1000); + } + + internal override void OnPPUAddressUpdate(ref ushort address) + { + if ((address & 0x3FF) < 960 && (address & 0x1000) == 0) + { + Switch04KCHR(((address & 0x300) >> 8) | flag_c, CHRArea.Area0000); + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper097.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper097.cs index e83e731..e3c4403 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper097.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper097.cs @@ -1,32 +1,31 @@ -namespace MyNes.Core -{ - [BoardInfo("Irem - PRG HI", 97)] - internal class Mapper097 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.Area8000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch16KPRG(data & 0xF, PRGArea.AreaC000); - switch ((address >> 6) & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - } - } +namespace MyNes.Core; + +[BoardInfo("Irem - PRG HI", 97)] +internal class Mapper097 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.Area8000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch16KPRG(data & 0xF, PRGArea.AreaC000); + switch ((address >> 6) & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper105.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper105.cs index ea34631..7229299 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper105.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper105.cs @@ -1,200 +1,199 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("NES-EVENT", 105)] - [HassIssues] - internal class Mapper105 : Board - { - private int DipSwitchNumber; - - private byte[] reg = new byte[4]; - - private byte shift = 0; - - private byte buffer = 0; - - private bool flag_p; - - private bool flag_s; - - private bool flag_o; - - private int reg_a; - - private int reg_b; - - private bool irq_control; - - private bool initialized; - - private int irq_counter; - - private int dipswitches; - - internal override string Issues => MNInterfaceLanguage.IssueMapper105; - - internal override void HardReset() - { - base.HardReset(); - TogglePRGRAMEnable(enable: true); - reg = new byte[4]; - reg[0] = 12; - flag_s = (flag_p = true); - reg[1] = (reg[2] = (reg[3] = 0)); - buffer = 0; - shift = 0; - initialized = false; - DipSwitchNumber = 0; - dipswitches = 0x20000000 | (DipSwitchNumber << 22); - } - - internal override void SoftReset() - { - DipSwitchNumber = (DipSwitchNumber + 1) & 0xF; - dipswitches = 0x20000000 | (DipSwitchNumber << 22); - } - - internal override void WritePRG(ref ushort address, ref byte value) - { - if ((value & 0x80) == 128) - { - reg[0] |= 12; - flag_s = (flag_p = true); - shift = (buffer = 0); - return; - } - if ((value & 1) == 1) - { - buffer |= (byte)(1 << (int)shift); - } - if (++shift < 5) - { - return; - } - address = (ushort)((address & 0x7FFF) >> 13); - reg[address] = buffer; - shift = (buffer = 0); - switch (address) - { - case 0: - flag_p = (reg[0] & 8) != 0; - flag_s = (reg[0] & 4) != 0; - UpdatePRG(); - switch (reg[0] & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.OneScA); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - } - break; - case 1: - irq_control = (reg[1] & 0x10) == 16; - if (irq_control) - { - initialized = true; - irq_counter = 0; - NesEmu.IRQFlags &= -9; - } - else - { - Switch32KPRG(0, PRGArea.Area8000); - } - flag_o = (reg[1] & 8) == 8; - reg_a = (reg[1] >> 1) & 3; - UpdatePRG(); - break; - case 3: - TogglePRGRAMEnable((reg[3] & 0x10) == 0); - reg_b = reg[3] & 0xF; - UpdatePRG(); - break; - case 2: - break; - } - } - - private void UpdatePRG() - { - if (initialized) - { - if (!flag_o) - { - Switch32KPRG(reg_a, PRGArea.Area8000); - } - else if (!flag_p) - { - Switch32KPRG((reg_b >> 1) + 4, PRGArea.Area8000); - } - else if (!flag_s) - { - Switch16KPRG(8, PRGArea.Area8000); - Switch16KPRG(reg_b + 8, PRGArea.AreaC000); - } - else - { - Switch16KPRG(reg_b + 8, PRGArea.Area8000); - Switch16KPRG(15, PRGArea.AreaC000); - } - } - } - - internal override void OnCPUClock() - { - if (!irq_control) - { - irq_counter++; - if (irq_counter == dipswitches) - { - irq_counter = 0; - NesEmu.IRQFlags |= 8; - } - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(DipSwitchNumber); - stream.Write(reg); - stream.Write(shift); - stream.Write(buffer); - stream.Write(flag_p); - stream.Write(flag_s); - stream.Write(flag_o); - stream.Write(reg_a); - stream.Write(reg_b); - stream.Write(irq_control); - stream.Write(initialized); - stream.Write(irq_counter); - stream.Write(dipswitches); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - DipSwitchNumber = stream.ReadInt32(); - stream.Read(reg, 0, reg.Length); - shift = stream.ReadByte(); - buffer = stream.ReadByte(); - flag_p = stream.ReadBoolean(); - flag_s = stream.ReadBoolean(); - flag_o = stream.ReadBoolean(); - reg_a = stream.ReadInt32(); - reg_b = stream.ReadInt32(); - irq_control = stream.ReadBoolean(); - initialized = stream.ReadBoolean(); - irq_counter = stream.ReadInt32(); - dipswitches = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("NES-EVENT", 105)] +[HassIssues] +internal class Mapper105 : Board +{ + private int DipSwitchNumber; + + private byte[] reg = new byte[4]; + + private byte shift; + + private byte buffer; + + private bool flag_p; + + private bool flag_s; + + private bool flag_o; + + private int reg_a; + + private int reg_b; + + private bool irq_control; + + private bool initialized; + + private int irq_counter; + + private int dipswitches; + + internal override string Issues => MNInterfaceLanguage.IssueMapper105; + + internal override void HardReset() + { + base.HardReset(); + TogglePRGRAMEnable(enable: true); + reg = new byte[4]; + reg[0] = 12; + flag_s = (flag_p = true); + reg[1] = (reg[2] = (reg[3] = 0)); + buffer = 0; + shift = 0; + initialized = false; + DipSwitchNumber = 0; + dipswitches = 0x20000000 | (DipSwitchNumber << 22); + } + + internal override void SoftReset() + { + DipSwitchNumber = (DipSwitchNumber + 1) & 0xF; + dipswitches = 0x20000000 | (DipSwitchNumber << 22); + } + + internal override void WritePRG(ref ushort address, ref byte value) + { + if ((value & 0x80) == 128) + { + reg[0] |= 12; + flag_s = (flag_p = true); + shift = (buffer = 0); + return; + } + if ((value & 1) == 1) + { + buffer |= (byte)(1 << (int)shift); + } + if (++shift < 5) + { + return; + } + address = (ushort)((address & 0x7FFF) >> 13); + reg[address] = buffer; + shift = (buffer = 0); + switch (address) + { + case 0: + flag_p = (reg[0] & 8) != 0; + flag_s = (reg[0] & 4) != 0; + UpdatePRG(); + switch (reg[0] & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.OneScA); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + } + break; + case 1: + irq_control = (reg[1] & 0x10) == 16; + if (irq_control) + { + initialized = true; + irq_counter = 0; + NesEmu.IRQFlags &= -9; + } + else + { + Switch32KPRG(0, PRGArea.Area8000); + } + flag_o = (reg[1] & 8) == 8; + reg_a = (reg[1] >> 1) & 3; + UpdatePRG(); + break; + case 3: + TogglePRGRAMEnable((reg[3] & 0x10) == 0); + reg_b = reg[3] & 0xF; + UpdatePRG(); + break; + case 2: + break; + } + } + + private void UpdatePRG() + { + if (initialized) + { + if (!flag_o) + { + Switch32KPRG(reg_a, PRGArea.Area8000); + } + else if (!flag_p) + { + Switch32KPRG((reg_b >> 1) + 4, PRGArea.Area8000); + } + else if (!flag_s) + { + Switch16KPRG(8, PRGArea.Area8000); + Switch16KPRG(reg_b + 8, PRGArea.AreaC000); + } + else + { + Switch16KPRG(reg_b + 8, PRGArea.Area8000); + Switch16KPRG(15, PRGArea.AreaC000); + } + } + } + + internal override void OnCPUClock() + { + if (!irq_control) + { + irq_counter++; + if (irq_counter == dipswitches) + { + irq_counter = 0; + NesEmu.IRQFlags |= 8; + } + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(DipSwitchNumber); + stream.Write(reg); + stream.Write(shift); + stream.Write(buffer); + stream.Write(flag_p); + stream.Write(flag_s); + stream.Write(flag_o); + stream.Write(reg_a); + stream.Write(reg_b); + stream.Write(irq_control); + stream.Write(initialized); + stream.Write(irq_counter); + stream.Write(dipswitches); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + DipSwitchNumber = stream.ReadInt32(); + stream.Read(reg, 0, reg.Length); + shift = stream.ReadByte(); + buffer = stream.ReadByte(); + flag_p = stream.ReadBoolean(); + flag_s = stream.ReadBoolean(); + flag_o = stream.ReadBoolean(); + reg_a = stream.ReadInt32(); + reg_b = stream.ReadInt32(); + irq_control = stream.ReadBoolean(); + initialized = stream.ReadBoolean(); + irq_counter = stream.ReadInt32(); + dipswitches = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper107.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper107.cs index f5e332d..8db96b5 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper107.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper107.cs @@ -1,11 +1,10 @@ -namespace MyNes.Core -{ - internal class Mapper107 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch32KPRG(data >> 1, PRGArea.Area8000); - Switch08KCHR(data); - } - } +namespace MyNes.Core; + +internal class Mapper107 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch32KPRG(data >> 1, PRGArea.Area8000); + Switch08KCHR(data); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper112.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper112.cs index 1e04e7c..27de618 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper112.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper112.cs @@ -1,70 +1,69 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Asder", 112)] - internal class Mapper112 : Board - { - private int address_A000; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_A000 = data & 7; - break; - case 40960: - switch (address_A000) - { - case 0: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 1: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 2: - Switch02KCHR(data >> 1, CHRArea.Area0000); - break; - case 3: - Switch02KCHR(data >> 1, CHRArea.Area0800); - break; - case 4: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 5: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 6: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 7: - Switch01KCHR(data, CHRArea.Area1C00); - break; - } - break; - case 57344: - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(address_A000); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - address_A000 = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Asder", 112)] +internal class Mapper112 : Board +{ + private int address_A000; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_A000 = data & 7; + break; + case 40960: + switch (address_A000) + { + case 0: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 1: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 2: + Switch02KCHR(data >> 1, CHRArea.Area0000); + break; + case 3: + Switch02KCHR(data >> 1, CHRArea.Area0800); + break; + case 4: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 5: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 6: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 7: + Switch01KCHR(data, CHRArea.Area1C00); + break; + } + break; + case 57344: + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(address_A000); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + address_A000 = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper113.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper113.cs index d8517c2..2ae55d5 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper113.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper113.cs @@ -1,18 +1,15 @@ -namespace MyNes.Core -{ - [BoardInfo("Sachen/Hacker/Nina", 113)] - internal class Mapper113 : Board - { - internal override void WriteEX(ref ushort address, ref byte data) - { - int num = address & 0x4100; - int num2 = num; - if (num2 == 16640) - { - Switch08KCHR((data & 7) | ((data & 0x40) >> 3)); - Switch32KPRG((data >> 3) & 7, PRGArea.Area8000); - Switch01KNMTFromMirroring(((data & 0x80) == 128) ? Mirroring.Vert : Mirroring.Horz); - } - } - } +namespace MyNes.Core; + +[BoardInfo("Sachen/Hacker/Nina", 113)] +internal class Mapper113 : Board +{ + internal override void WriteEX(ref ushort address, ref byte data) + { + if ((address & 0x4100) == 16640) + { + Switch08KCHR((data & 7) | ((data & 0x40) >> 3)); + Switch32KPRG((data >> 3) & 7, PRGArea.Area8000); + Switch01KNMTFromMirroring(((data & 0x80) == 128) ? Mirroring.Vert : Mirroring.Horz); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper115.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper115.cs index 080e95f..c4f8d9a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper115.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper115.cs @@ -1,259 +1,258 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("MMC3 Cart Saint", 115, true, true)] - internal class Mapper115 : Board - { - private bool flag_c; - - private bool flag_p; - - private bool flag_o; - - private int chr_block; - - private int prg_secreg; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_o = (flag_c = (flag_p = false)); - address_8001 = 0; - chr_block = 0; - prg_secreg = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - switch (address & 0x6001) - { - case 24576: - flag_o = (data & 0x80) == 128; - prg_secreg = data & 0xF; - SetupPRG(); - break; - case 24577: - chr_block = (data & 1) << 8; - SetupCHR(); - break; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR((chr_reg[0] >> 1) | chr_block, CHRArea.Area0000); - Switch02KCHR((chr_reg[1] >> 1) | chr_block, CHRArea.Area0800); - Switch01KCHR(chr_reg[2] | chr_block, CHRArea.Area1000); - Switch01KCHR(chr_reg[3] | chr_block, CHRArea.Area1400); - Switch01KCHR(chr_reg[4] | chr_block, CHRArea.Area1800); - Switch01KCHR(chr_reg[5] | chr_block, CHRArea.Area1C00); - } - else - { - Switch02KCHR((chr_reg[0] >> 1) | chr_block, CHRArea.Area1000); - Switch02KCHR((chr_reg[1] >> 1) | chr_block, CHRArea.Area1800); - Switch01KCHR(chr_reg[2] | chr_block, CHRArea.Area0000); - Switch01KCHR(chr_reg[3] | chr_block, CHRArea.Area0400); - Switch01KCHR(chr_reg[4] | chr_block, CHRArea.Area0800); - Switch01KCHR(chr_reg[5] | chr_block, CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - if (!flag_o) - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - } - else - { - Switch16KPRG(prg_secreg, PRGArea.Area8000); - } - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(flag_o); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(chr_block); - stream.Write(prg_secreg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - flag_o = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - chr_block = stream.ReadInt32(); - prg_secreg = stream.ReadInt32(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("MMC3 Cart Saint", 115, true, true)] +internal class Mapper115 : Board +{ + private bool flag_c; + + private bool flag_p; + + private bool flag_o; + + private int chr_block; + + private int prg_secreg; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_o = (flag_c = (flag_p = false)); + address_8001 = 0; + chr_block = 0; + prg_secreg = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + switch (address & 0x6001) + { + case 24576: + flag_o = (data & 0x80) == 128; + prg_secreg = data & 0xF; + SetupPRG(); + break; + case 24577: + chr_block = (data & 1) << 8; + SetupCHR(); + break; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR((chr_reg[0] >> 1) | chr_block, CHRArea.Area0000); + Switch02KCHR((chr_reg[1] >> 1) | chr_block, CHRArea.Area0800); + Switch01KCHR(chr_reg[2] | chr_block, CHRArea.Area1000); + Switch01KCHR(chr_reg[3] | chr_block, CHRArea.Area1400); + Switch01KCHR(chr_reg[4] | chr_block, CHRArea.Area1800); + Switch01KCHR(chr_reg[5] | chr_block, CHRArea.Area1C00); + } + else + { + Switch02KCHR((chr_reg[0] >> 1) | chr_block, CHRArea.Area1000); + Switch02KCHR((chr_reg[1] >> 1) | chr_block, CHRArea.Area1800); + Switch01KCHR(chr_reg[2] | chr_block, CHRArea.Area0000); + Switch01KCHR(chr_reg[3] | chr_block, CHRArea.Area0400); + Switch01KCHR(chr_reg[4] | chr_block, CHRArea.Area0800); + Switch01KCHR(chr_reg[5] | chr_block, CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + if (!flag_o) + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + } + else + { + Switch16KPRG(prg_secreg, PRGArea.Area8000); + } + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(flag_o); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(chr_block); + stream.Write(prg_secreg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + flag_o = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + chr_block = stream.ReadInt32(); + prg_secreg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper118.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper118.cs index 236730f..c34c87e 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper118.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper118.cs @@ -1,263 +1,262 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("MMC3 TLSROM", 118, true, true)] - internal class Mapper118 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - internal override void ReadNMT(ref ushort address, out byte value) - { - switch ((address >> 10) & 3) - { - case 0: - value = NMT_RAM[(chr_reg[flag_c ? 2 : 0] >> 7) & 1][address & 0x3FF]; - break; - case 1: - value = NMT_RAM[(chr_reg[flag_c ? 3 : 0] >> 7) & 1][address & 0x3FF]; - break; - case 2: - value = NMT_RAM[(chr_reg[(!flag_c) ? 1 : 4] >> 7) & 1][address & 0x3FF]; - break; - case 3: - value = NMT_RAM[(chr_reg[(!flag_c) ? 1 : 5] >> 7) & 1][address & 0x3FF]; - break; - default: - value = 0; - break; - } - } - - internal override void WriteNMT(ref ushort address, ref byte data) - { - switch ((address >> 10) & 3) - { - case 0: - NMT_RAM[(chr_reg[flag_c ? 2 : 0] >> 7) & 1][address & 0x3FF] = data; - break; - case 1: - NMT_RAM[(chr_reg[flag_c ? 3 : 0] >> 7) & 1][address & 0x3FF] = data; - break; - case 2: - NMT_RAM[(chr_reg[(!flag_c) ? 1 : 4] >> 7) & 1][address & 0x3FF] = data; - break; - case 3: - NMT_RAM[(chr_reg[(!flag_c) ? 1 : 5] >> 7) & 1][address & 0x3FF] = data; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("MMC3 TLSROM", 118, true, true)] +internal class Mapper118 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + internal override void ReadNMT(ref ushort address, out byte value) + { + switch ((address >> 10) & 3) + { + case 0: + value = NMT_RAM[(chr_reg[flag_c ? 2 : 0] >> 7) & 1][address & 0x3FF]; + break; + case 1: + value = NMT_RAM[(chr_reg[flag_c ? 3 : 0] >> 7) & 1][address & 0x3FF]; + break; + case 2: + value = NMT_RAM[(chr_reg[(!flag_c) ? 1 : 4] >> 7) & 1][address & 0x3FF]; + break; + case 3: + value = NMT_RAM[(chr_reg[(!flag_c) ? 1 : 5] >> 7) & 1][address & 0x3FF]; + break; + default: + value = 0; + break; + } + } + + internal override void WriteNMT(ref ushort address, ref byte data) + { + switch ((address >> 10) & 3) + { + case 0: + NMT_RAM[(chr_reg[flag_c ? 2 : 0] >> 7) & 1][address & 0x3FF] = data; + break; + case 1: + NMT_RAM[(chr_reg[flag_c ? 3 : 0] >> 7) & 1][address & 0x3FF] = data; + break; + case 2: + NMT_RAM[(chr_reg[(!flag_c) ? 1 : 4] >> 7) & 1][address & 0x3FF] = data; + break; + case 3: + NMT_RAM[(chr_reg[(!flag_c) ? 1 : 5] >> 7) & 1][address & 0x3FF] = data; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper119.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper119.cs index 828cd56..d2ec94f 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper119.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper119.cs @@ -1,236 +1,235 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("TQROM", 119, 1, 8, true, true)] - internal class Mapper119 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override string Issues => MNInterfaceLanguage.IssueMapper119; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Toggle02KCHR_RAM((chr_reg[0] & 0x40) != 0, CHRArea.Area0000); - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Toggle02KCHR_RAM((chr_reg[1] & 0x40) != 0, CHRArea.Area0800); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Toggle02KCHR_RAM((chr_reg[2] & 0x40) != 0, CHRArea.Area1000); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Toggle02KCHR_RAM((chr_reg[3] & 0x40) != 0, CHRArea.Area1400); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Toggle02KCHR_RAM((chr_reg[4] & 0x40) != 0, CHRArea.Area1800); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Toggle02KCHR_RAM((chr_reg[5] & 0x40) != 0, CHRArea.Area1C00); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Toggle02KCHR_RAM((chr_reg[0] & 0x40) != 0, CHRArea.Area1000); - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Toggle02KCHR_RAM((chr_reg[1] & 0x40) != 0, CHRArea.Area1800); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Toggle02KCHR_RAM((chr_reg[2] & 0x40) != 0, CHRArea.Area0000); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Toggle02KCHR_RAM((chr_reg[3] & 0x40) != 0, CHRArea.Area0400); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Toggle02KCHR_RAM((chr_reg[4] & 0x40) != 0, CHRArea.Area0800); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Toggle02KCHR_RAM((chr_reg[5] & 0x40) != 0, CHRArea.Area0C00); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("TQROM", 119, 1, 8, true, true)] +internal class Mapper119 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override string Issues => MNInterfaceLanguage.IssueMapper119; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Toggle02KCHR_RAM((chr_reg[0] & 0x40) != 0, CHRArea.Area0000); + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Toggle02KCHR_RAM((chr_reg[1] & 0x40) != 0, CHRArea.Area0800); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Toggle02KCHR_RAM((chr_reg[2] & 0x40) != 0, CHRArea.Area1000); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Toggle02KCHR_RAM((chr_reg[3] & 0x40) != 0, CHRArea.Area1400); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Toggle02KCHR_RAM((chr_reg[4] & 0x40) != 0, CHRArea.Area1800); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Toggle02KCHR_RAM((chr_reg[5] & 0x40) != 0, CHRArea.Area1C00); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Toggle02KCHR_RAM((chr_reg[0] & 0x40) != 0, CHRArea.Area1000); + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Toggle02KCHR_RAM((chr_reg[1] & 0x40) != 0, CHRArea.Area1800); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Toggle02KCHR_RAM((chr_reg[2] & 0x40) != 0, CHRArea.Area0000); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Toggle02KCHR_RAM((chr_reg[3] & 0x40) != 0, CHRArea.Area0400); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Toggle02KCHR_RAM((chr_reg[4] & 0x40) != 0, CHRArea.Area0800); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Toggle02KCHR_RAM((chr_reg[5] & 0x40) != 0, CHRArea.Area0C00); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper133.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper133.cs index 8df37d7..a9ddb07 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper133.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper133.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("Sachen", 133)] - internal class Mapper133 : Board - { - internal override void WriteEX(ref ushort address, ref byte data) - { - Switch08KCHR(data & 3); - Switch32KPRG(data >> 2, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("Sachen", 133)] +internal class Mapper133 : Board +{ + internal override void WriteEX(ref ushort address, ref byte data) + { + Switch08KCHR(data & 3); + Switch32KPRG(data >> 2, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper140.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper140.cs index 49031e7..1c51176 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper140.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper140.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 140)] - internal class Mapper140 : Board - { - internal override void WriteSRM(ref ushort address, ref byte data) - { - Switch08KCHR(data & 0xF); - Switch32KPRG((data >> 4) & 3, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 140)] +internal class Mapper140 : Board +{ + internal override void WriteSRM(ref ushort address, ref byte data) + { + Switch08KCHR(data & 0xF); + Switch32KPRG((data >> 4) & 3, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper152.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper152.cs index 2fd20b0..7020d00 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper152.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper152.cs @@ -1,19 +1,18 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 152)] - internal class Mapper152 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(data & 0xF); - Switch16KPRG((data >> 4) & 7, PRGArea.Area8000); - Switch01KNMTFromMirroring(((data & 0x80) == 128) ? Mirroring.OneScB : Mirroring.OneScA); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 152)] +internal class Mapper152 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(data & 0xF); + Switch16KPRG((data >> 4) & 7, PRGArea.Area8000); + Switch01KNMTFromMirroring(((data & 0x80) == 128) ? Mirroring.OneScB : Mirroring.OneScA); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper154.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper154.cs index 34f0020..fa2357b 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper154.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper154.cs @@ -1,72 +1,71 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("NAMCOT-3453", 154)] - [HassIssues] - internal class Mapper154 : Board - { - private int address_8001; - - internal override string Issues => MNInterfaceLanguage.IssueMapper154; - - internal override void HardReset() - { - base.HardReset(); - address_8001 = 0; - Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0x8001) - { - case 32768: - address_8001 = data & 7; - Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.OneScB : Mirroring.OneScA); - break; - case 32769: - switch (address_8001) - { - case 0: - Switch02KCHR((data & 0x3F) >> 1, CHRArea.Area0000); - break; - case 1: - Switch02KCHR((data & 0x3F) >> 1, CHRArea.Area0800); - break; - case 2: - Switch01KCHR(data | 0x40, CHRArea.Area1000); - break; - case 3: - Switch01KCHR(data | 0x40, CHRArea.Area1400); - break; - case 4: - Switch01KCHR(data | 0x40, CHRArea.Area1800); - break; - case 5: - Switch01KCHR(data | 0x40, CHRArea.Area1C00); - break; - case 6: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 7: - Switch08KPRG(data, PRGArea.AreaA000); - break; - } - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(address_8001); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - address_8001 = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("NAMCOT-3453", 154)] +[HassIssues] +internal class Mapper154 : Board +{ + private int address_8001; + + internal override string Issues => MNInterfaceLanguage.IssueMapper154; + + internal override void HardReset() + { + base.HardReset(); + address_8001 = 0; + Switch16KPRG(PRG_ROM_16KB_Mask, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0x8001) + { + case 32768: + address_8001 = data & 7; + Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.OneScB : Mirroring.OneScA); + break; + case 32769: + switch (address_8001) + { + case 0: + Switch02KCHR((data & 0x3F) >> 1, CHRArea.Area0000); + break; + case 1: + Switch02KCHR((data & 0x3F) >> 1, CHRArea.Area0800); + break; + case 2: + Switch01KCHR(data | 0x40, CHRArea.Area1000); + break; + case 3: + Switch01KCHR(data | 0x40, CHRArea.Area1400); + break; + case 4: + Switch01KCHR(data | 0x40, CHRArea.Area1800); + break; + case 5: + Switch01KCHR(data | 0x40, CHRArea.Area1C00); + break; + case 6: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 7: + Switch08KPRG(data, PRGArea.AreaA000); + break; + } + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(address_8001); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + address_8001 = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper163.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper163.cs index 859cbad..e6ed396 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper163.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper163.cs @@ -1,109 +1,108 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 163)] - internal class Mapper163 : Board - { - internal byte prg_reg; - - internal byte security_reg; - - internal bool security_trigger; - - internal byte security_reg101; - - internal bool do_chr_ram; - - internal override void HardReset() - { - base.HardReset(); - security_reg101 = 1; - security_trigger = false; - do_chr_ram = true; - Switch32KPRG(15, PRGArea.Area8000); - Toggle08KCHR_RAM(ram: true); - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - if (address == 20737) - { - if (security_reg101 != 0 && data == 0) - { - security_trigger = true; - } - security_reg101 = data; - } - else - { - if (address < 20480) - { - return; - } - switch (address & 0x7300) - { - case 20480: - prg_reg = (byte)((prg_reg & 0xF0u) | (data & 0xFu)); - Switch32KPRG(prg_reg, PRGArea.Area8000); - do_chr_ram = (data & 0x80) != 0; - if (!do_chr_ram && NesEmu.ppu_clock_v < 128) - { - Switch08KCHR(0); - } - break; - case 20736: - if (data == 6) - { - Switch32KPRG(3, PRGArea.Area8000); - } - break; - case 20992: - prg_reg = (byte)((prg_reg & 0xFu) | (uint)((data & 0xF) << 4)); - Switch32KPRG(prg_reg, PRGArea.Area8000); - break; - case 21248: - security_reg = data; - break; - } - } - } - - internal override void ReadEX(ref ushort addr, out byte val) - { - val = 0; - if (addr < 20480) - { - return; - } - switch (addr & 0x1E14) - { - case 20736: - val = security_reg; - break; - case 21760: - if (security_trigger) - { - val = security_reg; - } - break; - } - } - - internal override void OnPPUScanlineTick() - { - base.OnPPUScanlineTick(); - if (do_chr_ram && NesEmu.IsRenderingOn()) - { - if (NesEmu.ppu_clock_v == 127) - { - Switch04KCHR(1, CHRArea.Area0000); - Switch04KCHR(1, CHRArea.Area1000); - } - if (NesEmu.ppu_clock_v == 237) - { - Switch04KCHR(0, CHRArea.Area0000); - Switch04KCHR(0, CHRArea.Area1000); - } - } - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 163)] +internal class Mapper163 : Board +{ + internal byte prg_reg; + + internal byte security_reg; + + internal bool security_trigger; + + internal byte security_reg101; + + internal bool do_chr_ram; + + internal override void HardReset() + { + base.HardReset(); + security_reg101 = 1; + security_trigger = false; + do_chr_ram = true; + Switch32KPRG(15, PRGArea.Area8000); + Toggle08KCHR_RAM(ram: true); + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + if (address == 20737) + { + if (security_reg101 != 0 && data == 0) + { + security_trigger = true; + } + security_reg101 = data; + } + else + { + if (address < 20480) + { + return; + } + switch (address & 0x7300) + { + case 20480: + prg_reg = (byte)((prg_reg & 0xF0u) | (data & 0xFu)); + Switch32KPRG(prg_reg, PRGArea.Area8000); + do_chr_ram = (data & 0x80) != 0; + if (!do_chr_ram && NesEmu.ppu_clock_v < 128) + { + Switch08KCHR(0); + } + break; + case 20736: + if (data == 6) + { + Switch32KPRG(3, PRGArea.Area8000); + } + break; + case 20992: + prg_reg = (byte)((prg_reg & 0xFu) | (uint)((data & 0xF) << 4)); + Switch32KPRG(prg_reg, PRGArea.Area8000); + break; + case 21248: + security_reg = data; + break; + } + } + } + + internal override void ReadEX(ref ushort addr, out byte val) + { + val = 0; + if (addr < 20480) + { + return; + } + switch (addr & 0x1E14) + { + case 20736: + val = security_reg; + break; + case 21760: + if (security_trigger) + { + val = security_reg; + } + break; + } + } + + internal override void OnPPUScanlineTick() + { + base.OnPPUScanlineTick(); + if (do_chr_ram && NesEmu.IsRenderingOn()) + { + if (NesEmu.ppu_clock_v == 127) + { + Switch04KCHR(1, CHRArea.Area0000); + Switch04KCHR(1, CHRArea.Area1000); + } + if (NesEmu.ppu_clock_v == 237) + { + Switch04KCHR(0, CHRArea.Area0000); + Switch04KCHR(0, CHRArea.Area1000); + } + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper164.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper164.cs index 9e86ed9..0d78025 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper164.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper164.cs @@ -1,35 +1,27 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 164)] - internal class Mapper164 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch32KPRG(255, PRGArea.Area8000); - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - if (address >= 20480) - { - int num = address & 0xF000; - int num2 = num; - if (num2 == 20480) - { - Switch32KPRG(data, PRGArea.Area8000); - } - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - int num = address & 0xF000; - int num2 = num; - if (num2 == 53248) - { - Switch32KPRG(data, PRGArea.Area8000); - } - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 164)] +internal class Mapper164 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch32KPRG(255, PRGArea.Area8000); + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + if (address >= 20480 && (address & 0xF000) == 20480) + { + Switch32KPRG(data, PRGArea.Area8000); + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if ((address & 0xF000) == 53248) + { + Switch32KPRG(data, PRGArea.Area8000); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper165.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper165.cs index 7c92875..463851f 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper165.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper165.cs @@ -1,253 +1,252 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 165, true, true)] - internal class Mapper165 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private byte latch_a = 254; - - private byte latch_b = 254; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - internal override void ReadCHR(ref ushort address, out byte data) - { - if ((address & 0x1FF0) == 4048 && latch_a != 253) - { - latch_a = 253; - Switch04KCHR(chr_reg[0] >> 2, CHRArea.Area0000); - } - else if ((address & 0x1FF0) == 4064 && latch_a != 254) - { - latch_a = 254; - Switch04KCHR(chr_reg[1] >> 2, CHRArea.Area0000); - } - else if ((address & 0x1FF0) == 8144 && latch_b != 253) - { - latch_b = 253; - Switch04KCHR(chr_reg[2] >> 2, CHRArea.Area1000); - } - else if ((address & 0x1FF0) == 8160 && latch_b != 254) - { - latch_b = 254; - Switch04KCHR(chr_reg[4] >> 2, CHRArea.Area1000); - } - base.ReadCHR(ref address, out data); - } - - private void SetupCHR() - { - if (latch_a == 253) - { - Switch04KCHR(chr_reg[0] >> 2, CHRArea.Area0000); - } - if (latch_a == 254) - { - Switch04KCHR(chr_reg[1] >> 2, CHRArea.Area0000); - } - if (latch_b == 253) - { - Switch04KCHR(chr_reg[2] >> 2, CHRArea.Area1000); - } - if (latch_b == 254) - { - Switch04KCHR(chr_reg[4] >> 2, CHRArea.Area1000); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(latch_a); - stream.Write(latch_b); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - latch_a = stream.ReadByte(); - latch_b = stream.ReadByte(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 165, true, true)] +internal class Mapper165 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private byte latch_a = 254; + + private byte latch_b = 254; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + internal override void ReadCHR(ref ushort address, out byte data) + { + if ((address & 0x1FF0) == 4048 && latch_a != 253) + { + latch_a = 253; + Switch04KCHR(chr_reg[0] >> 2, CHRArea.Area0000); + } + else if ((address & 0x1FF0) == 4064 && latch_a != 254) + { + latch_a = 254; + Switch04KCHR(chr_reg[1] >> 2, CHRArea.Area0000); + } + else if ((address & 0x1FF0) == 8144 && latch_b != 253) + { + latch_b = 253; + Switch04KCHR(chr_reg[2] >> 2, CHRArea.Area1000); + } + else if ((address & 0x1FF0) == 8160 && latch_b != 254) + { + latch_b = 254; + Switch04KCHR(chr_reg[4] >> 2, CHRArea.Area1000); + } + base.ReadCHR(ref address, out data); + } + + private void SetupCHR() + { + if (latch_a == 253) + { + Switch04KCHR(chr_reg[0] >> 2, CHRArea.Area0000); + } + if (latch_a == 254) + { + Switch04KCHR(chr_reg[1] >> 2, CHRArea.Area0000); + } + if (latch_b == 253) + { + Switch04KCHR(chr_reg[2] >> 2, CHRArea.Area1000); + } + if (latch_b == 254) + { + Switch04KCHR(chr_reg[4] >> 2, CHRArea.Area1000); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(latch_a); + stream.Write(latch_b); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + latch_a = stream.ReadByte(); + latch_b = stream.ReadByte(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper180.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper180.cs index 6ec511a..9e151ea 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper180.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper180.cs @@ -1,14 +1,13 @@ -namespace MyNes.Core -{ - [BoardInfo("Nihon Bussan", 180)] - [HassIssues] - internal class Mapper180 : Board - { - internal override string Issues => MNInterfaceLanguage.IssueMapper180; - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch16KPRG(data & 7, PRGArea.AreaC000); - } - } +namespace MyNes.Core; + +[BoardInfo("Nihon Bussan", 180)] +[HassIssues] +internal class Mapper180 : Board +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper180; + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch16KPRG(data & 7, PRGArea.AreaC000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper182.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper182.cs index 49c7fda..d351125 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper182.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper182.cs @@ -1,216 +1,226 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 182, true, true)] - internal class Mapper182 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - mmc3_alt_behavior = false; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32769: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40960: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 49152: - switch (address_8001) - { - case 0: - chr_reg[0] = data; - SetupCHR(); - break; - case 1: - chr_reg[3] = data; - SetupCHR(); - break; - case 2: - chr_reg[1] = data; - SetupCHR(); - break; - case 3: - chr_reg[5] = data; - SetupCHR(); - break; - case 4: - prg_reg[0] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - case 5: - prg_reg[1] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - case 6: - chr_reg[2] = data; - SetupCHR(); - break; - case 7: - chr_reg[4] = data; - SetupCHR(); - break; - } - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - irq_reload = data; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 182, true, true)] +internal class Mapper182 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + mmc3_alt_behavior = false; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + int num = address & 0xE001; + if (num <= 40961) + { + if (num <= 32769) + { + if (num != 32768 && num == 32769 && NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + } + else if (num != 40960) + { + _ = 40961; + } + else + { + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + } + return; + } + switch (num) + { + case 49152: + switch (address_8001) + { + case 0: + chr_reg[0] = data; + SetupCHR(); + break; + case 1: + chr_reg[3] = data; + SetupCHR(); + break; + case 2: + chr_reg[1] = data; + SetupCHR(); + break; + case 3: + chr_reg[5] = data; + SetupCHR(); + break; + case 4: + prg_reg[0] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + case 5: + prg_reg[1] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + case 6: + chr_reg[2] = data; + SetupCHR(); + break; + case 7: + chr_reg[4] = data; + SetupCHR(); + break; + } + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + irq_reload = data; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper184.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper184.cs index 943a192..25ae022 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper184.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper184.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("Sunsoft", 184)] - internal class Mapper184 : Board - { - internal override void WriteSRM(ref ushort address, ref byte data) - { - Switch04KCHR(data & 7, CHRArea.Area0000); - Switch04KCHR((data >> 4) & 7, CHRArea.Area1000); - } - } +namespace MyNes.Core; + +[BoardInfo("Sunsoft", 184)] +internal class Mapper184 : Board +{ + internal override void WriteSRM(ref ushort address, ref byte data) + { + Switch04KCHR(data & 7, CHRArea.Area0000); + Switch04KCHR((data >> 4) & 7, CHRArea.Area1000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper185.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper185.cs index 8a3f127..13fe8d7 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper185.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper185.cs @@ -1,45 +1,44 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 185)] - internal class Mapper185 : Board - { - private bool lockchr; - - internal override void HardReset() - { - base.HardReset(); - lockchr = false; - } - - internal override void ReadCHR(ref ushort address, out byte data) - { - if (!lockchr) - { - base.ReadCHR(ref address, out data); - } - else - { - data = byte.MaxValue; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - lockchr = (data & 0xF) == 0 || data == 19; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(lockchr); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - lockchr = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 185)] +internal class Mapper185 : Board +{ + private bool lockchr; + + internal override void HardReset() + { + base.HardReset(); + lockchr = false; + } + + internal override void ReadCHR(ref ushort address, out byte data) + { + if (!lockchr) + { + base.ReadCHR(ref address, out data); + } + else + { + data = byte.MaxValue; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + lockchr = (data & 0xF) == 0 || data == 19; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(lockchr); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + lockchr = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper189.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper189.cs index 4bd5d57..368e1b9 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper189.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper189.cs @@ -1,185 +1,183 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("MMC3 Variant", 189, true, true)] - internal class Mapper189 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = 0; - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - Switch32KPRG(((data & 0xF0) >> 4) | (data & 0xF), PRGArea.Area8000); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - Switch32KPRG(((data & 0xF0) >> 4) | (data & 0xF), PRGArea.Area8000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - break; - case 32769: - { - int num = address_8001; - int num2 = num; - if ((uint)num2 <= 5u) - { - chr_reg[address_8001] = data; - SetupCHR(); - } - break; - } - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - stream.Write(prg_reg); - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - prg_reg = stream.ReadInt32(); - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("MMC3 Variant", 189, true, true)] +internal class Mapper189 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = 0; + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + Switch32KPRG(((data & 0xF0) >> 4) | (data & 0xF), PRGArea.Area8000); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + Switch32KPRG(((data & 0xF0) >> 4) | (data & 0xF), PRGArea.Area8000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + break; + case 32769: + { + int num = address_8001; + if ((uint)num <= 5u) + { + chr_reg[address_8001] = data; + SetupCHR(); + } + break; + } + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + stream.Write(prg_reg); + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + prg_reg = stream.ReadInt32(); + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper191.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper191.cs index b7a7776..eeec6ce 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper191.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper191.cs @@ -1,212 +1,211 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Pirate MMC3 variant", 191, true, true)] - [HassIssues] - internal class Mapper191 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - internal override string Issues => MNInterfaceLanguage.IssueMapper191; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Toggle02KCHR_RAM((chr_reg[0] & 0x80) == 0, CHRArea.Area0000); - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Toggle02KCHR_RAM((chr_reg[1] & 0x80) == 0, CHRArea.Area0800); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Toggle02KCHR_RAM((chr_reg[2] & 0x80) == 0, CHRArea.Area1000); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Toggle02KCHR_RAM((chr_reg[3] & 0x80) == 0, CHRArea.Area1400); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Toggle02KCHR_RAM((chr_reg[4] & 0x80) == 0, CHRArea.Area1800); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Toggle02KCHR_RAM((chr_reg[5] & 0x80) == 0, CHRArea.Area1C00); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Toggle02KCHR_RAM((chr_reg[0] & 0x80) == 0, CHRArea.Area1000); - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Toggle02KCHR_RAM((chr_reg[1] & 0x80) == 0, CHRArea.Area1800); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Toggle02KCHR_RAM((chr_reg[2] & 0x80) == 0, CHRArea.Area0000); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Toggle02KCHR_RAM((chr_reg[3] & 0x80) == 0, CHRArea.Area0400); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Toggle02KCHR_RAM((chr_reg[4] & 0x80) == 0, CHRArea.Area0800); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Toggle02KCHR_RAM((chr_reg[5] & 0x80) == 0, CHRArea.Area0C00); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Pirate MMC3 variant", 191, true, true)] +[HassIssues] +internal class Mapper191 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + internal override string Issues => MNInterfaceLanguage.IssueMapper191; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Toggle02KCHR_RAM((chr_reg[0] & 0x80) == 0, CHRArea.Area0000); + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Toggle02KCHR_RAM((chr_reg[1] & 0x80) == 0, CHRArea.Area0800); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Toggle02KCHR_RAM((chr_reg[2] & 0x80) == 0, CHRArea.Area1000); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Toggle02KCHR_RAM((chr_reg[3] & 0x80) == 0, CHRArea.Area1400); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Toggle02KCHR_RAM((chr_reg[4] & 0x80) == 0, CHRArea.Area1800); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Toggle02KCHR_RAM((chr_reg[5] & 0x80) == 0, CHRArea.Area1C00); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Toggle02KCHR_RAM((chr_reg[0] & 0x80) == 0, CHRArea.Area1000); + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Toggle02KCHR_RAM((chr_reg[1] & 0x80) == 0, CHRArea.Area1800); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Toggle02KCHR_RAM((chr_reg[2] & 0x80) == 0, CHRArea.Area0000); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Toggle02KCHR_RAM((chr_reg[3] & 0x80) == 0, CHRArea.Area0400); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Toggle02KCHR_RAM((chr_reg[4] & 0x80) == 0, CHRArea.Area0800); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Toggle02KCHR_RAM((chr_reg[5] & 0x80) == 0, CHRArea.Area0C00); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper192.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper192.cs index f62dc4f..f988f81 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper192.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper192.cs @@ -1,225 +1,224 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Pirate MMC3 variant", 192, true, true)] - internal class Mapper192 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool isRam; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - isRam = chr_reg[0] >= 8 && chr_reg[0] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area0000); - Switch02KCHR(isRam ? (chr_reg[0] - 8 >> 1) : (chr_reg[0] >> 1), CHRArea.Area0000); - isRam = chr_reg[1] >= 8 && chr_reg[1] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area0000); - Switch02KCHR(isRam ? (chr_reg[1] - 8 >> 1) : (chr_reg[1] >> 1), CHRArea.Area0800); - isRam = chr_reg[2] >= 8 && chr_reg[2] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area1000); - Switch01KCHR(isRam ? (chr_reg[2] - 8) : chr_reg[2], CHRArea.Area1000); - isRam = chr_reg[3] >= 8 && chr_reg[3] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area1400); - Switch01KCHR(isRam ? (chr_reg[3] - 8) : chr_reg[3], CHRArea.Area1400); - isRam = chr_reg[4] >= 8 && chr_reg[4] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area1800); - Switch01KCHR(isRam ? (chr_reg[4] - 8) : chr_reg[4], CHRArea.Area1800); - isRam = chr_reg[5] >= 8 && chr_reg[5] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area1C00); - Switch01KCHR(isRam ? (chr_reg[5] - 8) : chr_reg[5], CHRArea.Area1C00); - } - else - { - isRam = chr_reg[0] >= 8 && chr_reg[0] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area1000); - Switch02KCHR(isRam ? (chr_reg[0] - 8 >> 1) : (chr_reg[0] >> 1), CHRArea.Area1000); - isRam = chr_reg[1] >= 8 && chr_reg[1] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area1800); - Switch02KCHR(isRam ? (chr_reg[1] - 8 >> 1) : (chr_reg[1] >> 1), CHRArea.Area1800); - isRam = chr_reg[2] >= 8 && chr_reg[2] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area0000); - Switch01KCHR(isRam ? (chr_reg[2] - 8) : chr_reg[2], CHRArea.Area0000); - isRam = chr_reg[3] >= 8 && chr_reg[3] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area0400); - Switch01KCHR(isRam ? (chr_reg[3] - 8) : chr_reg[3], CHRArea.Area0400); - isRam = chr_reg[4] >= 8 && chr_reg[4] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area0800); - Switch01KCHR(isRam ? (chr_reg[4] - 8) : chr_reg[4], CHRArea.Area0800); - isRam = chr_reg[5] >= 8 && chr_reg[5] <= 11; - Toggle02KCHR_RAM(isRam, CHRArea.Area0C00); - Switch01KCHR(isRam ? (chr_reg[5] - 8) : chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(isRam); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - isRam = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Pirate MMC3 variant", 192, true, true)] +internal class Mapper192 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool isRam; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + isRam = chr_reg[0] >= 8 && chr_reg[0] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area0000); + Switch02KCHR(isRam ? (chr_reg[0] - 8 >> 1) : (chr_reg[0] >> 1), CHRArea.Area0000); + isRam = chr_reg[1] >= 8 && chr_reg[1] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area0000); + Switch02KCHR(isRam ? (chr_reg[1] - 8 >> 1) : (chr_reg[1] >> 1), CHRArea.Area0800); + isRam = chr_reg[2] >= 8 && chr_reg[2] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area1000); + Switch01KCHR(isRam ? (chr_reg[2] - 8) : chr_reg[2], CHRArea.Area1000); + isRam = chr_reg[3] >= 8 && chr_reg[3] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area1400); + Switch01KCHR(isRam ? (chr_reg[3] - 8) : chr_reg[3], CHRArea.Area1400); + isRam = chr_reg[4] >= 8 && chr_reg[4] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area1800); + Switch01KCHR(isRam ? (chr_reg[4] - 8) : chr_reg[4], CHRArea.Area1800); + isRam = chr_reg[5] >= 8 && chr_reg[5] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area1C00); + Switch01KCHR(isRam ? (chr_reg[5] - 8) : chr_reg[5], CHRArea.Area1C00); + } + else + { + isRam = chr_reg[0] >= 8 && chr_reg[0] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area1000); + Switch02KCHR(isRam ? (chr_reg[0] - 8 >> 1) : (chr_reg[0] >> 1), CHRArea.Area1000); + isRam = chr_reg[1] >= 8 && chr_reg[1] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area1800); + Switch02KCHR(isRam ? (chr_reg[1] - 8 >> 1) : (chr_reg[1] >> 1), CHRArea.Area1800); + isRam = chr_reg[2] >= 8 && chr_reg[2] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area0000); + Switch01KCHR(isRam ? (chr_reg[2] - 8) : chr_reg[2], CHRArea.Area0000); + isRam = chr_reg[3] >= 8 && chr_reg[3] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area0400); + Switch01KCHR(isRam ? (chr_reg[3] - 8) : chr_reg[3], CHRArea.Area0400); + isRam = chr_reg[4] >= 8 && chr_reg[4] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area0800); + Switch01KCHR(isRam ? (chr_reg[4] - 8) : chr_reg[4], CHRArea.Area0800); + isRam = chr_reg[5] >= 8 && chr_reg[5] <= 11; + Toggle02KCHR_RAM(isRam, CHRArea.Area0C00); + Switch01KCHR(isRam ? (chr_reg[5] - 8) : chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(isRam); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + isRam = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper193.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper193.cs index 6e6f39b..9100d4a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper193.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper193.cs @@ -1,36 +1,35 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 193, 1, 32)] - [HassIssues] - internal class Mapper193 : Board - { - internal override string Issues => MNInterfaceLanguage.IssueMapper193; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask - 2, PRGArea.AreaA000); - Switch08KPRG(PRG_ROM_08KB_Mask - 1, PRGArea.AreaC000); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - switch (address & 0x6003) - { - case 24576: - Switch04KCHR(data >> 2, CHRArea.Area0000); - break; - case 24577: - Switch02KCHR(data >> 1, CHRArea.Area1000); - break; - case 24578: - Switch02KCHR(data >> 1, CHRArea.Area1800); - break; - case 24579: - Switch08KPRG(data, PRGArea.Area8000); - break; - } - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 193, 1, 32)] +[HassIssues] +internal class Mapper193 : Board +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper193; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask - 2, PRGArea.AreaA000); + Switch08KPRG(PRG_ROM_08KB_Mask - 1, PRGArea.AreaC000); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + switch (address & 0x6003) + { + case 24576: + Switch04KCHR(data >> 2, CHRArea.Area0000); + break; + case 24577: + Switch02KCHR(data >> 1, CHRArea.Area1000); + break; + case 24578: + Switch02KCHR(data >> 1, CHRArea.Area1800); + break; + case 24579: + Switch08KPRG(data, PRGArea.Area8000); + break; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper194.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper194.cs index 1f2a785..35c2bee 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper194.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper194.cs @@ -1,209 +1,208 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Pirate MMC3 variant", 194, true, true)] - internal class Mapper194 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Toggle02KCHR_RAM(chr_reg[0] > 1, CHRArea.Area0000); - Switch02KCHR((chr_reg[0] > 1) ? (chr_reg[0] - 1 >> 1) : (chr_reg[0] >> 1), CHRArea.Area0000); - Toggle02KCHR_RAM(chr_reg[1] > 1, CHRArea.Area0800); - Switch02KCHR((chr_reg[1] > 1) ? (chr_reg[1] - 1 >> 1) : (chr_reg[1] >> 1), CHRArea.Area0800); - Toggle02KCHR_RAM(chr_reg[2] > 1, CHRArea.Area1000); - Switch01KCHR((chr_reg[2] > 1) ? (chr_reg[2] - 1) : chr_reg[2], CHRArea.Area1000); - Toggle02KCHR_RAM(chr_reg[3] > 1, CHRArea.Area1400); - Switch01KCHR((chr_reg[3] > 1) ? (chr_reg[3] - 1) : chr_reg[3], CHRArea.Area1400); - Toggle02KCHR_RAM(chr_reg[4] > 1, CHRArea.Area1800); - Switch01KCHR((chr_reg[4] > 1) ? (chr_reg[4] - 1) : chr_reg[4], CHRArea.Area1800); - Toggle02KCHR_RAM(chr_reg[5] > 1, CHRArea.Area1C00); - Switch01KCHR((chr_reg[5] > 1) ? (chr_reg[5] - 1) : chr_reg[5], CHRArea.Area1C00); - } - else - { - Toggle02KCHR_RAM(chr_reg[0] > 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Toggle02KCHR_RAM(chr_reg[1] > 1, CHRArea.Area1800); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Toggle02KCHR_RAM(chr_reg[2] > 1, CHRArea.Area0000); - Switch01KCHR((chr_reg[2] > 1) ? (chr_reg[2] - 1) : chr_reg[2], CHRArea.Area0000); - Toggle02KCHR_RAM(chr_reg[3] > 1, CHRArea.Area0400); - Switch01KCHR((chr_reg[3] > 1) ? (chr_reg[3] - 1) : chr_reg[3], CHRArea.Area0400); - Toggle02KCHR_RAM(chr_reg[4] > 1, CHRArea.Area0800); - Switch01KCHR((chr_reg[4] > 1) ? (chr_reg[4] - 1) : chr_reg[4], CHRArea.Area0800); - Toggle02KCHR_RAM(chr_reg[5] > 1, CHRArea.Area0C00); - Switch01KCHR((chr_reg[5] > 1) ? (chr_reg[5] - 1) : chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Pirate MMC3 variant", 194, true, true)] +internal class Mapper194 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Toggle02KCHR_RAM(chr_reg[0] > 1, CHRArea.Area0000); + Switch02KCHR((chr_reg[0] > 1) ? (chr_reg[0] - 1 >> 1) : (chr_reg[0] >> 1), CHRArea.Area0000); + Toggle02KCHR_RAM(chr_reg[1] > 1, CHRArea.Area0800); + Switch02KCHR((chr_reg[1] > 1) ? (chr_reg[1] - 1 >> 1) : (chr_reg[1] >> 1), CHRArea.Area0800); + Toggle02KCHR_RAM(chr_reg[2] > 1, CHRArea.Area1000); + Switch01KCHR((chr_reg[2] > 1) ? (chr_reg[2] - 1) : chr_reg[2], CHRArea.Area1000); + Toggle02KCHR_RAM(chr_reg[3] > 1, CHRArea.Area1400); + Switch01KCHR((chr_reg[3] > 1) ? (chr_reg[3] - 1) : chr_reg[3], CHRArea.Area1400); + Toggle02KCHR_RAM(chr_reg[4] > 1, CHRArea.Area1800); + Switch01KCHR((chr_reg[4] > 1) ? (chr_reg[4] - 1) : chr_reg[4], CHRArea.Area1800); + Toggle02KCHR_RAM(chr_reg[5] > 1, CHRArea.Area1C00); + Switch01KCHR((chr_reg[5] > 1) ? (chr_reg[5] - 1) : chr_reg[5], CHRArea.Area1C00); + } + else + { + Toggle02KCHR_RAM(chr_reg[0] > 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Toggle02KCHR_RAM(chr_reg[1] > 1, CHRArea.Area1800); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Toggle02KCHR_RAM(chr_reg[2] > 1, CHRArea.Area0000); + Switch01KCHR((chr_reg[2] > 1) ? (chr_reg[2] - 1) : chr_reg[2], CHRArea.Area0000); + Toggle02KCHR_RAM(chr_reg[3] > 1, CHRArea.Area0400); + Switch01KCHR((chr_reg[3] > 1) ? (chr_reg[3] - 1) : chr_reg[3], CHRArea.Area0400); + Toggle02KCHR_RAM(chr_reg[4] > 1, CHRArea.Area0800); + Switch01KCHR((chr_reg[4] > 1) ? (chr_reg[4] - 1) : chr_reg[4], CHRArea.Area0800); + Toggle02KCHR_RAM(chr_reg[5] > 1, CHRArea.Area0C00); + Switch01KCHR((chr_reg[5] > 1) ? (chr_reg[5] - 1) : chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper200.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper200.cs index 4967f1b..1d5f5f6 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper200.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper200.cs @@ -1,14 +1,13 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 200)] - internal class Mapper200 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(address & 7); - Switch16KPRG(address & 7, PRGArea.Area8000); - Switch16KPRG(address & 7, PRGArea.AreaC000); - Switch01KNMTFromMirroring(((address & 8) == 8) ? Mirroring.Horz : Mirroring.Vert); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 200)] +internal class Mapper200 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(address & 7); + Switch16KPRG(address & 7, PRGArea.Area8000); + Switch16KPRG(address & 7, PRGArea.AreaC000); + Switch01KNMTFromMirroring(((address & 8) == 8) ? Mirroring.Horz : Mirroring.Vert); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper201.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper201.cs index a1aa22f..de809df 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper201.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper201.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 201)] - internal class Mapper201 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(address & 0xFF); - Switch32KPRG(address & 0xFF, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 201)] +internal class Mapper201 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(address & 0xFF); + Switch32KPRG(address & 0xFF, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper202.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper202.cs index dc485df..4c5dd26 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper202.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper202.cs @@ -1,22 +1,21 @@ -namespace MyNes.Core -{ - [BoardInfo("150-in-1", 202)] - [HassIssues] - internal class Mapper202 : Board - { - internal override string Issues => MNInterfaceLanguage.IssueMapper202; - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch01KNMTFromMirroring(((address & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - Switch08KCHR((address >> 1) & 7); - if ((address & 0xC) == 12) - { - Switch32KPRG(3, PRGArea.Area8000); - return; - } - Switch16KPRG((address >> 1) & 7, PRGArea.Area8000); - Switch16KPRG((address >> 1) & 7, PRGArea.AreaC000); - } - } +namespace MyNes.Core; + +[BoardInfo("150-in-1", 202)] +[HassIssues] +internal class Mapper202 : Board +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper202; + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch01KNMTFromMirroring(((address & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + Switch08KCHR((address >> 1) & 7); + if ((address & 0xC) == 12) + { + Switch32KPRG(3, PRGArea.Area8000); + return; + } + Switch16KPRG((address >> 1) & 7, PRGArea.Area8000); + Switch16KPRG((address >> 1) & 7, PRGArea.AreaC000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper203.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper203.cs index a1a2019..8575334 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper203.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper203.cs @@ -1,16 +1,15 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 203)] - [HassIssues] - internal class Mapper203 : Board - { - internal override string Issues => MNInterfaceLanguage.IssueMapper203; - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(data & 3); - Switch16KPRG(data & 0x3F, PRGArea.Area8000); - Switch16KPRG(data & 0x3F, PRGArea.AreaC000); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 203)] +[HassIssues] +internal class Mapper203 : Board +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper203; + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(data & 3); + Switch16KPRG(data & 0x3F, PRGArea.Area8000); + Switch16KPRG(data & 0x3F, PRGArea.AreaC000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper204.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper204.cs index bbff677..c742bdc 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper204.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper204.cs @@ -1,19 +1,18 @@ -namespace MyNes.Core -{ - [BoardInfo("64-in-1", 204)] - internal class Mapper204 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch01KNMTFromMirroring(((address & 0x10) == 16) ? Mirroring.Horz : Mirroring.Vert); - Switch08KCHR(address & 7); - if ((address & 6) == 6) - { - Switch32KPRG(3, PRGArea.Area8000); - return; - } - Switch16KPRG(address & 7, PRGArea.Area8000); - Switch16KPRG(address & 7, PRGArea.AreaC000); - } - } +namespace MyNes.Core; + +[BoardInfo("64-in-1", 204)] +internal class Mapper204 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch01KNMTFromMirroring(((address & 0x10) == 16) ? Mirroring.Horz : Mirroring.Vert); + Switch08KCHR(address & 7); + if ((address & 6) == 6) + { + Switch32KPRG(3, PRGArea.Area8000); + return; + } + Switch16KPRG(address & 7, PRGArea.Area8000); + Switch16KPRG(address & 7, PRGArea.AreaC000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper205.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper205.cs index efb548a..75ed8a9 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper205.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper205.cs @@ -1,275 +1,274 @@ -using System; -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 205, true, true)] - internal class Mapper205 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private int chr_or; - - private int chr_and; - - private int prg_or; - - private int prg_and; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_and = 31; - prg_or = 0; - chr_and = 255; - chr_or = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - if (IsGameFoundOnDB) - { - switch (GameCartInfo.chip_type[0].ToLower()) - { - case "mmc3a": - mmc3_alt_behavior = true; - Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); - break; - case "mmc3b": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); - break; - case "mmc3c": - mmc3_alt_behavior = false; - Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); - break; - } - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - switch (data & 3) - { - case 0: - prg_and = 31; - prg_or = 0; - chr_and = 255; - chr_or = 0; - break; - case 1: - prg_and = 31; - prg_or = 16; - chr_and = 255; - chr_or = 128; - break; - case 2: - prg_and = 15; - prg_or = 32; - chr_and = 127; - chr_or = 256; - break; - case 3: - prg_and = 15; - prg_or = 48; - chr_and = 127; - chr_or = 384; - break; - } - SetupCHR(); - SetupPRG(); - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); - } - else - { - Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); - Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); - Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); - Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); - Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); - Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); - Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); - Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); - Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(chr_or); - stream.Write(chr_and); - stream.Write(prg_or); - stream.Write(prg_and); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - chr_or = stream.ReadInt32(); - chr_and = stream.ReadInt32(); - prg_or = stream.ReadInt32(); - prg_and = stream.ReadInt32(); - } - } +using System; +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 205, true, true)] +internal class Mapper205 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private int chr_or; + + private int chr_and; + + private int prg_or; + + private int prg_and; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_and = 31; + prg_or = 0; + chr_and = 255; + chr_or = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + if (IsGameFoundOnDB) + { + switch (GameCartInfo.chip_type[0].ToLower()) + { + case "mmc3a": + mmc3_alt_behavior = true; + Console.WriteLine("Chip= MMC3 A, MMC3 IQR mode switched to RevA"); + break; + case "mmc3b": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 B, MMC3 IQR mode switched to RevB"); + break; + case "mmc3c": + mmc3_alt_behavior = false; + Console.WriteLine("Chip= MMC3 C, MMC3 IQR mode switched to RevB"); + break; + } + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + switch (data & 3) + { + case 0: + prg_and = 31; + prg_or = 0; + chr_and = 255; + chr_or = 0; + break; + case 1: + prg_and = 31; + prg_or = 16; + chr_and = 255; + chr_or = 128; + break; + case 2: + prg_and = 15; + prg_or = 32; + chr_and = 127; + chr_or = 256; + break; + case 3: + prg_and = 15; + prg_or = 48; + chr_and = 127; + chr_or = 384; + break; + } + SetupCHR(); + SetupPRG(); + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area0000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area0800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area1000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area1400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area1800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area1C00); + } + else + { + Switch02KCHR(((chr_reg[0] & chr_and) | chr_or) >> 1, CHRArea.Area1000); + Switch02KCHR(((chr_reg[1] & chr_and) | chr_or) >> 1, CHRArea.Area1800); + Switch01KCHR((chr_reg[2] & chr_and) | chr_or, CHRArea.Area0000); + Switch01KCHR((chr_reg[3] & chr_and) | chr_or, CHRArea.Area0400); + Switch01KCHR((chr_reg[4] & chr_and) | chr_or, CHRArea.Area0800); + Switch01KCHR((chr_reg[5] & chr_and) | chr_or, CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG((prg_reg[flag_p ? 2 : 0] & prg_and) | prg_or, PRGArea.Area8000); + Switch08KPRG((prg_reg[1] & prg_and) | prg_or, PRGArea.AreaA000); + Switch08KPRG((prg_reg[(!flag_p) ? 2 : 0] & prg_and) | prg_or, PRGArea.AreaC000); + Switch08KPRG((prg_reg[3] & prg_and) | prg_or, PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(chr_or); + stream.Write(chr_and); + stream.Write(prg_or); + stream.Write(prg_and); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + chr_or = stream.ReadInt32(); + chr_and = stream.ReadInt32(); + prg_or = stream.ReadInt32(); + prg_and = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper206.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper206.cs index d50894c..0951a0a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper206.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper206.cs @@ -1,131 +1,130 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 206)] - internal class Mapper206 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - SetupPRG(); - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - case 7: - prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; - SetupPRG(); - break; - } - break; - } - } - - private void SetupCHR() - { - if (!flag_c) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - - private void SetupPRG() - { - Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); - Switch08KPRG(prg_reg[1], PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); - Switch08KPRG(prg_reg[3], PRGArea.AreaE000); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 206)] +internal class Mapper206 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + SetupPRG(); + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + case 7: + prg_reg[address_8001 - 6] = data & PRG_ROM_08KB_Mask; + SetupPRG(); + break; + } + break; + } + } + + private void SetupCHR() + { + if (!flag_c) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + + private void SetupPRG() + { + Switch08KPRG(prg_reg[flag_p ? 2 : 0], PRGArea.Area8000); + Switch08KPRG(prg_reg[1], PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0], PRGArea.AreaC000); + Switch08KPRG(prg_reg[3], PRGArea.AreaE000); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper207.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper207.cs index 4f7778a..f7b262a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper207.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper207.cs @@ -1,112 +1,111 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 207)] - [HassIssues] - internal class Mapper207 : Board - { - private int mirroring0; - - private int mirroring1; - - internal override string Issues => MNInterfaceLanguage.IssueMapper207; - - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - switch (address) - { - case 32496: - Switch02KCHR(data & 0x3F, CHRArea.Area0000); - mirroring0 = (data >> 7) & 1; - break; - case 32497: - Switch02KCHR(data & 0x3F, CHRArea.Area0800); - mirroring1 = (data >> 7) & 1; - break; - case 32498: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 32499: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 32500: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 32501: - Switch01KCHR(data, CHRArea.Area1C00); - break; - case 32506: - case 32507: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 32508: - case 32509: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 32510: - case 32511: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 32502: - case 32503: - case 32504: - case 32505: - break; - } - } - - internal override void ReadNMT(ref ushort address, out byte data) - { - switch ((address >> 10) & 3) - { - case 0: - case 1: - data = NMT_RAM[mirroring0][address & 0x3FF]; - break; - case 2: - case 3: - data = NMT_RAM[mirroring1][address & 0x3FF]; - break; - default: - data = 0; - break; - } - } - - internal override void WriteNMT(ref ushort address, ref byte data) - { - switch ((address >> 10) & 3) - { - case 0: - case 1: - NMT_RAM[mirroring0][address & 0x3FF] = data; - break; - case 2: - case 3: - NMT_RAM[mirroring1][address & 0x3FF] = data; - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(mirroring0); - stream.Write(mirroring1); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - mirroring0 = stream.ReadInt32(); - mirroring1 = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 207)] +[HassIssues] +internal class Mapper207 : Board +{ + private int mirroring0; + + private int mirroring1; + + internal override string Issues => MNInterfaceLanguage.IssueMapper207; + + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + switch (address) + { + case 32496: + Switch02KCHR(data & 0x3F, CHRArea.Area0000); + mirroring0 = (data >> 7) & 1; + break; + case 32497: + Switch02KCHR(data & 0x3F, CHRArea.Area0800); + mirroring1 = (data >> 7) & 1; + break; + case 32498: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 32499: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 32500: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 32501: + Switch01KCHR(data, CHRArea.Area1C00); + break; + case 32506: + case 32507: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 32508: + case 32509: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 32510: + case 32511: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 32502: + case 32503: + case 32504: + case 32505: + break; + } + } + + internal override void ReadNMT(ref ushort address, out byte data) + { + switch ((address >> 10) & 3) + { + case 0: + case 1: + data = NMT_RAM[mirroring0][address & 0x3FF]; + break; + case 2: + case 3: + data = NMT_RAM[mirroring1][address & 0x3FF]; + break; + default: + data = 0; + break; + } + } + + internal override void WriteNMT(ref ushort address, ref byte data) + { + switch ((address >> 10) & 3) + { + case 0: + case 1: + NMT_RAM[mirroring0][address & 0x3FF] = data; + break; + case 2: + case 3: + NMT_RAM[mirroring1][address & 0x3FF] = data; + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(mirroring0); + stream.Write(mirroring1); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + mirroring0 = stream.ReadInt32(); + mirroring1 = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper209.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper209.cs index 5b4d75f..716c76c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper209.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper209.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("Pirate MMC5-style", 209)] - internal class Mapper209 : Mapper090 - { - internal override void HardReset() - { - MAPPER90MODE = false; - base.HardReset(); - } - } +namespace MyNes.Core; + +[BoardInfo("Pirate MMC5-style", 209)] +internal class Mapper209 : Mapper090 +{ + internal override void HardReset() + { + MAPPER90MODE = false; + base.HardReset(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper212.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper212.cs index 9b4f7fb..ed58480 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper212.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper212.cs @@ -1,19 +1,18 @@ -namespace MyNes.Core -{ - [BoardInfo("Super HIK 300-in-1 (1994)", 212)] - internal class Mapper212 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(address & 7); - Switch01KNMTFromMirroring(((address & 8) == 8) ? Mirroring.Horz : Mirroring.Vert); - if ((address & 0x4000) == 16384) - { - Switch32KPRG((address >> 1) & 3, PRGArea.Area8000); - return; - } - Switch16KPRG(address & 7, PRGArea.Area8000); - Switch16KPRG(address & 7, PRGArea.AreaC000); - } - } +namespace MyNes.Core; + +[BoardInfo("Super HIK 300-in-1 (1994)", 212)] +internal class Mapper212 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(address & 7); + Switch01KNMTFromMirroring(((address & 8) == 8) ? Mirroring.Horz : Mirroring.Vert); + if ((address & 0x4000) == 16384) + { + Switch32KPRG((address >> 1) & 3, PRGArea.Area8000); + return; + } + Switch16KPRG(address & 7, PRGArea.Area8000); + Switch16KPRG(address & 7, PRGArea.AreaC000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper213.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper213.cs index 781dc65..93a7012 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper213.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper213.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("9999999-in-1", 213)] - internal class Mapper213 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR((address >> 3) & 7); - Switch32KPRG((address >> 1) & 3, PRGArea.Area8000); - } - } +namespace MyNes.Core; + +[BoardInfo("9999999-in-1", 213)] +internal class Mapper213 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR((address >> 3) & 7); + Switch32KPRG((address >> 1) & 3, PRGArea.Area8000); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper214.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper214.cs index e45d15a..a90dbfa 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper214.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper214.cs @@ -1,13 +1,12 @@ -namespace MyNes.Core -{ - [BoardInfo("X-in-1", 214)] - internal class Mapper214 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch16KPRG(address >> 2, PRGArea.Area8000); - Switch16KPRG(address >> 2, PRGArea.AreaC000); - Switch08KCHR(address); - } - } +namespace MyNes.Core; + +[BoardInfo("X-in-1", 214)] +internal class Mapper214 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch16KPRG(address >> 2, PRGArea.Area8000); + Switch16KPRG(address >> 2, PRGArea.AreaC000); + Switch08KCHR(address); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper216.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper216.cs index edd16c2..a942dc0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper216.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper216.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 216)] - internal class Mapper216 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch32KPRG(address, PRGArea.Area8000); - Switch08KCHR(address >> 1); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 216)] +internal class Mapper216 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch32KPRG(address, PRGArea.Area8000); + Switch08KCHR(address >> 1); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper222.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper222.cs index c21c893..fd395cb 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper222.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper222.cs @@ -1,48 +1,47 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 222)] - internal class Mapper222 : Board - { - internal override string Issues => MNInterfaceLanguage.IssueMapper222; - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF003) - { - case 32768: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 36864: - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - break; - case 40960: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 45056: - Switch01KCHR(data, CHRArea.Area0000); - break; - case 45058: - Switch01KCHR(data, CHRArea.Area0400); - break; - case 49152: - Switch01KCHR(data, CHRArea.Area0800); - break; - case 49154: - Switch01KCHR(data, CHRArea.Area0C00); - break; - case 53248: - Switch01KCHR(data, CHRArea.Area1000); - break; - case 53250: - Switch01KCHR(data, CHRArea.Area1400); - break; - case 57344: - Switch01KCHR(data, CHRArea.Area1800); - break; - case 57346: - Switch01KCHR(data, CHRArea.Area1C00); - break; - } - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 222)] +internal class Mapper222 : Board +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper222; + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF003) + { + case 32768: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 36864: + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + break; + case 40960: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 45056: + Switch01KCHR(data, CHRArea.Area0000); + break; + case 45058: + Switch01KCHR(data, CHRArea.Area0400); + break; + case 49152: + Switch01KCHR(data, CHRArea.Area0800); + break; + case 49154: + Switch01KCHR(data, CHRArea.Area0C00); + break; + case 53248: + Switch01KCHR(data, CHRArea.Area1000); + break; + case 53250: + Switch01KCHR(data, CHRArea.Area1400); + break; + case 57344: + Switch01KCHR(data, CHRArea.Area1800); + break; + case 57346: + Switch01KCHR(data, CHRArea.Area1C00); + break; + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper225.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper225.cs index 29ab413..f290c25 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper225.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper225.cs @@ -1,63 +1,62 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 225)] - internal class Mapper225 : Board - { - private byte[] RAM; - - internal override void HardReset() - { - base.HardReset(); - RAM = new byte[4]; - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - if (address >= 22528) - { - RAM[address & 3] = (byte)(data & 0xFu); - } - } - - internal override void ReadEX(ref ushort address, out byte value) - { - if (address >= 22528) - { - value = RAM[address & 3]; - } - else - { - value = 0; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(address & 0x3F); - if ((address & 0x1000) == 4096) - { - Switch16KPRG((address >> 6) & 0x3F, PRGArea.Area8000); - Switch16KPRG((address >> 6) & 0x3F, PRGArea.AreaC000); - } - else - { - Switch32KPRG(((address >> 6) & 0x3F) >> 1, PRGArea.Area8000); - } - Switch01KNMTFromMirroring(((address & 0x2000) == 8192) ? Mirroring.Horz : Mirroring.Vert); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(RAM); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - stream.Read(RAM, 0, RAM.Length); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 225)] +internal class Mapper225 : Board +{ + private byte[] RAM; + + internal override void HardReset() + { + base.HardReset(); + RAM = new byte[4]; + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + if (address >= 22528) + { + RAM[address & 3] = (byte)(data & 0xFu); + } + } + + internal override void ReadEX(ref ushort address, out byte value) + { + if (address >= 22528) + { + value = RAM[address & 3]; + } + else + { + value = 0; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(address & 0x3F); + if ((address & 0x1000) == 4096) + { + Switch16KPRG((address >> 6) & 0x3F, PRGArea.Area8000); + Switch16KPRG((address >> 6) & 0x3F, PRGArea.AreaC000); + } + else + { + Switch32KPRG(((address >> 6) & 0x3F) >> 1, PRGArea.Area8000); + } + Switch01KNMTFromMirroring(((address & 0x2000) == 8192) ? Mirroring.Horz : Mirroring.Vert); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(RAM); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + stream.Read(RAM, 0, RAM.Length); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper226.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper226.cs index 3fe1ec4..75c3c30 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper226.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper226.cs @@ -1,66 +1,65 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 226)] - internal class Mapper226 : Board - { - private int prg_reg; - - private bool prg_mode; - - internal override void HardReset() - { - base.HardReset(); - prg_reg = 0; - prg_mode = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0x8001) - { - case 32768: - prg_reg = (data & 0x1F) | ((data & 0x80) >> 2) | (prg_reg & 0xC0); - prg_mode = (data & 0x20) == 32; - Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Vert : Mirroring.Horz); - if (prg_mode) - { - Switch16KPRG(prg_reg, PRGArea.Area8000); - Switch16KPRG(prg_reg, PRGArea.AreaC000); - } - else - { - Switch32KPRG(prg_reg >> 1, PRGArea.Area8000); - } - break; - case 32769: - prg_reg = ((data & 1) << 6) | (prg_reg & 0x3F); - if (prg_mode) - { - Switch16KPRG(prg_reg, PRGArea.Area8000); - Switch16KPRG(prg_reg, PRGArea.AreaC000); - } - else - { - Switch32KPRG(prg_reg >> 1, PRGArea.Area8000); - } - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(prg_reg); - stream.Write(prg_mode); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - prg_reg = stream.ReadInt32(); - prg_mode = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 226)] +internal class Mapper226 : Board +{ + private int prg_reg; + + private bool prg_mode; + + internal override void HardReset() + { + base.HardReset(); + prg_reg = 0; + prg_mode = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0x8001) + { + case 32768: + prg_reg = (data & 0x1F) | ((data & 0x80) >> 2) | (prg_reg & 0xC0); + prg_mode = (data & 0x20) == 32; + Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Vert : Mirroring.Horz); + if (prg_mode) + { + Switch16KPRG(prg_reg, PRGArea.Area8000); + Switch16KPRG(prg_reg, PRGArea.AreaC000); + } + else + { + Switch32KPRG(prg_reg >> 1, PRGArea.Area8000); + } + break; + case 32769: + prg_reg = ((data & 1) << 6) | (prg_reg & 0x3F); + if (prg_mode) + { + Switch16KPRG(prg_reg, PRGArea.Area8000); + Switch16KPRG(prg_reg, PRGArea.AreaC000); + } + else + { + Switch32KPRG(prg_reg >> 1, PRGArea.Area8000); + } + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(prg_reg); + stream.Write(prg_mode); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + prg_reg = stream.ReadInt32(); + prg_mode = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper227.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper227.cs index b838088..8197033 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper227.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper227.cs @@ -1,90 +1,89 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 227)] - internal class Mapper227 : Board - { - private bool flag_o; - - private bool flag_s; - - private bool flag_l; - - private int prg_reg; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(0, PRGArea.AreaC000); - flag_o = false; - flag_s = false; - flag_l = false; - prg_reg = 0; - ToggleCHRRAMWritableEnable(enable: true); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - flag_s = (address & 1) == 1; - flag_o = (address & 0x80) == 128; - flag_l = (address & 0x200) == 512; - prg_reg = ((address >> 2) & 0x1F) | ((address >> 3) & 0x20); - Switch01KNMTFromMirroring(((address & 2) == 2) ? Mirroring.Horz : Mirroring.Vert); - ToggleCHRRAMWritableEnable(!flag_o); - if (flag_o) - { - if (!flag_s) - { - Switch16KPRG(prg_reg, PRGArea.Area8000); - Switch16KPRG(prg_reg, PRGArea.AreaC000); - } - else - { - Switch32KPRG(prg_reg >> 1, PRGArea.Area8000); - } - } - else if (!flag_l) - { - if (!flag_s) - { - Switch16KPRG(prg_reg, PRGArea.Area8000); - Switch16KPRG(prg_reg & 0x38, PRGArea.AreaC000); - } - else - { - Switch16KPRG(prg_reg & 0x3E, PRGArea.Area8000); - Switch16KPRG(prg_reg & 0x38, PRGArea.AreaC000); - } - } - else if (!flag_s) - { - Switch16KPRG(prg_reg, PRGArea.Area8000); - Switch16KPRG(prg_reg | 7, PRGArea.AreaC000); - } - else - { - Switch16KPRG(prg_reg & 0x3E, PRGArea.Area8000); - Switch16KPRG(prg_reg | 7, PRGArea.AreaC000); - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_o); - stream.Write(flag_s); - stream.Write(flag_l); - stream.Write(prg_reg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_o = stream.ReadBoolean(); - flag_s = stream.ReadBoolean(); - flag_l = stream.ReadBoolean(); - prg_reg = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 227)] +internal class Mapper227 : Board +{ + private bool flag_o; + + private bool flag_s; + + private bool flag_l; + + private int prg_reg; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(0, PRGArea.AreaC000); + flag_o = false; + flag_s = false; + flag_l = false; + prg_reg = 0; + ToggleCHRRAMWritableEnable(enable: true); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + flag_s = (address & 1) == 1; + flag_o = (address & 0x80) == 128; + flag_l = (address & 0x200) == 512; + prg_reg = ((address >> 2) & 0x1F) | ((address >> 3) & 0x20); + Switch01KNMTFromMirroring(((address & 2) == 2) ? Mirroring.Horz : Mirroring.Vert); + ToggleCHRRAMWritableEnable(!flag_o); + if (flag_o) + { + if (!flag_s) + { + Switch16KPRG(prg_reg, PRGArea.Area8000); + Switch16KPRG(prg_reg, PRGArea.AreaC000); + } + else + { + Switch32KPRG(prg_reg >> 1, PRGArea.Area8000); + } + } + else if (!flag_l) + { + if (!flag_s) + { + Switch16KPRG(prg_reg, PRGArea.Area8000); + Switch16KPRG(prg_reg & 0x38, PRGArea.AreaC000); + } + else + { + Switch16KPRG(prg_reg & 0x3E, PRGArea.Area8000); + Switch16KPRG(prg_reg & 0x38, PRGArea.AreaC000); + } + } + else if (!flag_s) + { + Switch16KPRG(prg_reg, PRGArea.Area8000); + Switch16KPRG(prg_reg | 7, PRGArea.AreaC000); + } + else + { + Switch16KPRG(prg_reg & 0x3E, PRGArea.Area8000); + Switch16KPRG(prg_reg | 7, PRGArea.AreaC000); + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_o); + stream.Write(flag_s); + stream.Write(flag_l); + stream.Write(prg_reg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_o = stream.ReadBoolean(); + flag_s = stream.ReadBoolean(); + flag_l = stream.ReadBoolean(); + prg_reg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper228.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper228.cs index f5596d0..7e160d9 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper228.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper228.cs @@ -1,61 +1,60 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 228)] - [HassIssues] - internal class Mapper228 : Board - { - private byte[] RAM; - - private int bank; - - internal override string Issues => MNInterfaceLanguage.IssueMapper228; - - internal override void HardReset() - { - base.HardReset(); - RAM = new byte[4]; - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - RAM[address & 3] = (byte)(data & 0xFu); - } - - internal override void ReadEX(ref ushort address, out byte data) - { - data = RAM[address & 3]; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(((address & 0xF) << 2) | (data & 3)); - Switch01KNMTFromMirroring(((address & 0x2000) == 8192) ? Mirroring.Horz : Mirroring.Vert); - bank = ((address >> 7) & 0x1F) + ((address >> 7) & (address >> 8) & 0x10); - if ((address & 0x20) == 32) - { - Switch16KPRG((bank << 2) | ((address >> 5) & 2), PRGArea.Area8000); - Switch16KPRG((bank << 2) | ((address >> 5) & 2), PRGArea.AreaC000); - } - else - { - Switch32KPRG(bank, PRGArea.Area8000); - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(RAM); - stream.Write(bank); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - stream.Read(RAM, 0, RAM.Length); - bank = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 228)] +[HassIssues] +internal class Mapper228 : Board +{ + private byte[] RAM; + + private int bank; + + internal override string Issues => MNInterfaceLanguage.IssueMapper228; + + internal override void HardReset() + { + base.HardReset(); + RAM = new byte[4]; + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + RAM[address & 3] = (byte)(data & 0xFu); + } + + internal override void ReadEX(ref ushort address, out byte data) + { + data = RAM[address & 3]; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(((address & 0xF) << 2) | (data & 3)); + Switch01KNMTFromMirroring(((address & 0x2000) == 8192) ? Mirroring.Horz : Mirroring.Vert); + bank = ((address >> 7) & 0x1F) + ((address >> 7) & (address >> 8) & 0x10); + if ((address & 0x20) == 32) + { + Switch16KPRG((bank << 2) | ((address >> 5) & 2), PRGArea.Area8000); + Switch16KPRG((bank << 2) | ((address >> 5) & 2), PRGArea.AreaC000); + } + else + { + Switch32KPRG(bank, PRGArea.Area8000); + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(RAM); + stream.Write(bank); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + stream.Read(RAM, 0, RAM.Length); + bank = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper229.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper229.cs index 84ffd91..67ae850 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper229.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper229.cs @@ -1,17 +1,16 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 229)] - [HassIssues] - internal class Mapper229 : Board - { - internal override string Issues => MNInterfaceLanguage.IssueMapper229; - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch01KNMTFromMirroring(((address & 0x20) == 32) ? Mirroring.Horz : Mirroring.Vert); - Switch16KPRG(((address & 0x1E) == 30) ? (address & 0x1F) : 0, PRGArea.Area8000); - Switch16KPRG(((address & 0x1E) != 30) ? 1 : (address & 0x1F), PRGArea.AreaC000); - Switch08KCHR(address); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 229)] +[HassIssues] +internal class Mapper229 : Board +{ + internal override string Issues => MNInterfaceLanguage.IssueMapper229; + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch01KNMTFromMirroring(((address & 0x20) == 32) ? Mirroring.Horz : Mirroring.Vert); + Switch16KPRG(((address & 0x1E) == 30) ? (address & 0x1F) : 0, PRGArea.Area8000); + Switch16KPRG(((address & 0x1E) != 30) ? 1 : (address & 0x1F), PRGArea.AreaC000); + Switch08KCHR(address); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper230.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper230.cs index 879ff31..ef491d0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper230.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper230.cs @@ -1,58 +1,57 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 230)] - [HassIssues] - internal class Mapper230 : Board - { - private bool contraMode = false; - - internal override string Issues => MNInterfaceLanguage.IssueMapper230; - - internal override void HardReset() - { - base.HardReset(); - contraMode = true; - Switch16KPRG(0, PRGArea.Area8000); - Switch16KPRG(7, PRGArea.AreaC000); - } - - internal override void SoftReset() - { - base.SoftReset(); - contraMode = !contraMode; - if (contraMode) - { - Switch16KPRG(0, PRGArea.Area8000); - Switch16KPRG(7, PRGArea.AreaC000); - Switch01KNMTFromMirroring(Mirroring.Vert); - } - else - { - Switch08KCHR(0); - Switch16KPRG(8, PRGArea.Area8000); - Switch16KPRG(39, PRGArea.AreaC000); - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if (contraMode) - { - Switch16KPRG(data & 7, PRGArea.Area8000); - Switch16KPRG(7, PRGArea.AreaC000); - Switch01KNMTFromMirroring(Mirroring.Vert); - return; - } - Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Vert : Mirroring.Horz); - if ((data & 0x20) == 32) - { - Switch16KPRG((data & 0x1F) + 8, PRGArea.Area8000); - Switch16KPRG((data & 0x1F) + 8, PRGArea.AreaC000); - } - else - { - Switch32KPRG(((data & 0x1F) >> 1) + 4, PRGArea.Area8000); - } - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 230)] +[HassIssues] +internal class Mapper230 : Board +{ + private bool contraMode; + + internal override string Issues => MNInterfaceLanguage.IssueMapper230; + + internal override void HardReset() + { + base.HardReset(); + contraMode = true; + Switch16KPRG(0, PRGArea.Area8000); + Switch16KPRG(7, PRGArea.AreaC000); + } + + internal override void SoftReset() + { + base.SoftReset(); + contraMode = !contraMode; + if (contraMode) + { + Switch16KPRG(0, PRGArea.Area8000); + Switch16KPRG(7, PRGArea.AreaC000); + Switch01KNMTFromMirroring(Mirroring.Vert); + } + else + { + Switch08KCHR(0); + Switch16KPRG(8, PRGArea.Area8000); + Switch16KPRG(39, PRGArea.AreaC000); + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if (contraMode) + { + Switch16KPRG(data & 7, PRGArea.Area8000); + Switch16KPRG(7, PRGArea.AreaC000); + Switch01KNMTFromMirroring(Mirroring.Vert); + return; + } + Switch01KNMTFromMirroring(((data & 0x40) == 64) ? Mirroring.Vert : Mirroring.Horz); + if ((data & 0x20) == 32) + { + Switch16KPRG((data & 0x1F) + 8, PRGArea.Area8000); + Switch16KPRG((data & 0x1F) + 8, PRGArea.AreaC000); + } + else + { + Switch32KPRG(((data & 0x1F) >> 1) + 4, PRGArea.Area8000); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper231.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper231.cs index 9874345..9dd5a48 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper231.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper231.cs @@ -1,13 +1,12 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 231)] - internal class Mapper231 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch16KPRG(address & 0x1E, PRGArea.Area8000); - Switch16KPRG((address & 0x1E) | ((address >> 5) & 1), PRGArea.AreaC000); - Switch01KNMTFromMirroring(((address & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 231)] +internal class Mapper231 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch16KPRG(address & 0x1E, PRGArea.Area8000); + Switch16KPRG((address & 0x1E) | ((address >> 5) & 1), PRGArea.AreaC000); + Switch01KNMTFromMirroring(((address & 0x80) == 128) ? Mirroring.Horz : Mirroring.Vert); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper232.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper232.cs index 4d48bf4..9f739d8 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper232.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper232.cs @@ -1,42 +1,41 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 232)] - internal class Mapper232 : Board - { - private int prg_reg; - - internal override void HardReset() - { - base.HardReset(); - Switch16KPRG(3, PRGArea.AreaC000); - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - if (address < 49152) - { - prg_reg = ((data & 0x18) >> 1) | (prg_reg & 3); - } - else - { - prg_reg = (prg_reg & 0xC) | (data & 3); - } - Switch16KPRG(prg_reg, PRGArea.Area8000); - Switch16KPRG(3 | (prg_reg & 0xC), PRGArea.AreaC000); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(prg_reg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - prg_reg = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 232)] +internal class Mapper232 : Board +{ + private int prg_reg; + + internal override void HardReset() + { + base.HardReset(); + Switch16KPRG(3, PRGArea.AreaC000); + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + if (address < 49152) + { + prg_reg = ((data & 0x18) >> 1) | (prg_reg & 3); + } + else + { + prg_reg = (prg_reg & 0xC) | (data & 3); + } + Switch16KPRG(prg_reg, PRGArea.Area8000); + Switch16KPRG(3 | (prg_reg & 0xC), PRGArea.AreaC000); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(prg_reg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + prg_reg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper233.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper233.cs index 7e55904..7f44eab 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper233.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper233.cs @@ -1,68 +1,67 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 233)] - internal class Mapper233 : Board - { - private int title = 0; - - private int bank; - - internal override void HardReset() - { - base.HardReset(); - bank = (title = 0); - } - - internal override void SoftReset() - { - base.SoftReset(); - bank = 0; - title ^= 32; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - bank = data & 0x1F; - if ((data & 0x20) == 32) - { - Switch16KPRG(title | bank, PRGArea.Area8000); - Switch16KPRG(title | bank, PRGArea.AreaC000); - } - else - { - Switch32KPRG((title >> 1) | (bank >> 1), PRGArea.Area8000); - } - switch ((data >> 6) & 3) - { - case 0: - Switch01KNMT(128); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 2: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(title); - stream.Write(bank); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - title = stream.ReadInt32(); - bank = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 233)] +internal class Mapper233 : Board +{ + private int title; + + private int bank; + + internal override void HardReset() + { + base.HardReset(); + bank = (title = 0); + } + + internal override void SoftReset() + { + base.SoftReset(); + bank = 0; + title ^= 32; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + bank = data & 0x1F; + if ((data & 0x20) == 32) + { + Switch16KPRG(title | bank, PRGArea.Area8000); + Switch16KPRG(title | bank, PRGArea.AreaC000); + } + else + { + Switch32KPRG((title >> 1) | (bank >> 1), PRGArea.Area8000); + } + switch ((data >> 6) & 3) + { + case 0: + Switch01KNMT(128); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 2: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(title); + stream.Write(bank); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + title = stream.ReadInt32(); + bank = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper240.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper240.cs index 1891222..dea3ced 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper240.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper240.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 240)] - internal class Mapper240 : Board - { - internal override void WriteEX(ref ushort address, ref byte data) - { - Switch32KPRG((data >> 4) & 0xF, PRGArea.Area8000); - Switch08KCHR(data & 0xF); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 240)] +internal class Mapper240 : Board +{ + internal override void WriteEX(ref ushort address, ref byte data) + { + Switch32KPRG((data >> 4) & 0xF, PRGArea.Area8000); + Switch08KCHR(data & 0xF); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper242.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper242.cs index f305de5..0855ccb 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper242.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper242.cs @@ -1,12 +1,11 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 242)] - internal class Mapper242 : Board - { - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch32KPRG((address >> 3) & 0xF, PRGArea.Area8000); - Switch01KNMTFromMirroring(((address & 2) == 2) ? Mirroring.Horz : Mirroring.Vert); - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 242)] +internal class Mapper242 : Board +{ + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch32KPRG((address >> 3) & 0xF, PRGArea.Area8000); + Switch01KNMTFromMirroring(((address & 2) == 2) ? Mirroring.Horz : Mirroring.Vert); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper243.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper243.cs index 3943327..113f959 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper243.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper243.cs @@ -1,88 +1,87 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Sachen Poker", 243)] - [HassIssues] - internal class Mapper243 : Board - { - private int addr; - - private int chr_reg; - - internal override string Issues => MNInterfaceLanguage.IssueMapper243; - - internal override void HardReset() - { - base.HardReset(); - addr = (chr_reg = 0); - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - if (address >= 20480 || address < 16416) - { - return; - } - switch (address & 0x4101) - { - case 16640: - addr = data & 7; - break; - case 16641: - switch (addr) - { - case 2: - chr_reg = ((data << 3) & 8) | (chr_reg & 7); - Switch08KCHR(chr_reg); - break; - case 4: - chr_reg = (data & 1) | (chr_reg & 0xE); - Switch08KCHR(chr_reg); - break; - case 5: - Switch32KPRG(data & 7, PRGArea.Area8000); - break; - case 6: - chr_reg = ((data & 3) << 1) | (chr_reg & 9); - Switch08KCHR(chr_reg); - break; - case 7: - switch ((data >> 1) & 3) - { - case 0: - Switch01KNMTFromMirroring(Mirroring.Horz); - break; - case 1: - Switch01KNMTFromMirroring(Mirroring.Vert); - break; - case 2: - Switch01KNMT(14); - break; - case 3: - Switch01KNMTFromMirroring(Mirroring.OneScB); - break; - } - break; - case 3: - break; - } - break; - } - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(addr); - stream.Write(chr_reg); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - addr = stream.ReadInt32(); - chr_reg = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Sachen Poker", 243)] +[HassIssues] +internal class Mapper243 : Board +{ + private int addr; + + private int chr_reg; + + internal override string Issues => MNInterfaceLanguage.IssueMapper243; + + internal override void HardReset() + { + base.HardReset(); + addr = (chr_reg = 0); + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + if (address >= 20480 || address < 16416) + { + return; + } + switch (address & 0x4101) + { + case 16640: + addr = data & 7; + break; + case 16641: + switch (addr) + { + case 2: + chr_reg = ((data << 3) & 8) | (chr_reg & 7); + Switch08KCHR(chr_reg); + break; + case 4: + chr_reg = (data & 1) | (chr_reg & 0xE); + Switch08KCHR(chr_reg); + break; + case 5: + Switch32KPRG(data & 7, PRGArea.Area8000); + break; + case 6: + chr_reg = ((data & 3) << 1) | (chr_reg & 9); + Switch08KCHR(chr_reg); + break; + case 7: + switch ((data >> 1) & 3) + { + case 0: + Switch01KNMTFromMirroring(Mirroring.Horz); + break; + case 1: + Switch01KNMTFromMirroring(Mirroring.Vert); + break; + case 2: + Switch01KNMT(14); + break; + case 3: + Switch01KNMTFromMirroring(Mirroring.OneScB); + break; + } + break; + case 3: + break; + } + break; + } + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(addr); + stream.Write(chr_reg); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + addr = stream.ReadInt32(); + chr_reg = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper245.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper245.cs index 4d48c1e..b9bce60 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper245.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper245.cs @@ -1,229 +1,228 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("C&E", 245, true, true)] - [HassIssues] - internal class Mapper245 : Board - { - private bool flag_c; - - private bool flag_p; - - private int address_8001; - - private int[] chr_reg; - - private int[] prg_reg; - - private int prg_or; - - private bool irq_enabled; - - private byte irq_counter; - - private int old_irq_counter; - - private byte irq_reload; - - private bool irq_clear; - - private bool mmc3_alt_behavior; - - internal override string Issues => MNInterfaceLanguage.IssueMapper245; - - internal override void HardReset() - { - base.HardReset(); - flag_c = (flag_p = false); - address_8001 = 0; - prg_reg = new int[4]; - prg_or = 0; - prg_reg[0] = 0; - prg_reg[1] = 1; - prg_reg[2] = PRG_ROM_08KB_Mask - 1; - prg_reg[3] = PRG_ROM_08KB_Mask; - chr_reg = new int[6]; - for (int i = 0; i < 6; i++) - { - chr_reg[i] = 0; - } - SetupPRG(); - SetupCHR(); - irq_enabled = false; - irq_counter = 0; - irq_reload = byte.MaxValue; - old_irq_counter = 0; - irq_clear = false; - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xE001) - { - case 32768: - address_8001 = data & 7; - flag_c = (data & 0x80) != 0; - flag_p = (data & 0x40) != 0; - SetupCHR(); - SetupPRG(); - break; - case 32769: - switch (address_8001) - { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - chr_reg[address_8001] = data; - SetupCHR(); - break; - case 6: - prg_reg[0] = data & 0x3F; - SetupPRG(); - break; - case 7: - prg_reg[1] = data & 0x3F; - SetupPRG(); - break; - } - break; - case 40960: - if (NMT_DEFAULT_MIRROR != Mirroring.Full) - { - Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); - } - break; - case 40961: - TogglePRGRAMEnable((data & 0x80) != 0); - TogglePRGRAMWritableEnable((data & 0x40) == 0); - break; - case 49152: - irq_reload = data; - break; - case 49153: - if (mmc3_alt_behavior) - { - irq_clear = true; - } - irq_counter = 0; - break; - case 57344: - irq_enabled = false; - NesEmu.IRQFlags &= -9; - break; - case 57345: - irq_enabled = true; - break; - } - } - - private void SetupCHR() - { - if (CHR_ROM_01KB_Count > 0) - { - if (!flag_c) - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); - Switch01KCHR(chr_reg[2], CHRArea.Area1000); - Switch01KCHR(chr_reg[3], CHRArea.Area1400); - Switch01KCHR(chr_reg[4], CHRArea.Area1800); - Switch01KCHR(chr_reg[5], CHRArea.Area1C00); - } - else - { - Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); - Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); - Switch01KCHR(chr_reg[2], CHRArea.Area0000); - Switch01KCHR(chr_reg[3], CHRArea.Area0400); - Switch01KCHR(chr_reg[4], CHRArea.Area0800); - Switch01KCHR(chr_reg[5], CHRArea.Area0C00); - } - } - else if (!flag_c) - { - Switch04KCHR(0, CHRArea.Area0000); - Switch04KCHR(1, CHRArea.Area1000); - } - else - { - Switch04KCHR(1, CHRArea.Area0000); - Switch04KCHR(0, CHRArea.Area1000); - } - } - - private void SetupPRG() - { - prg_or = (chr_reg[0] & 2) << 5; - Switch08KPRG(prg_reg[flag_p ? 2 : 0] | prg_or, PRGArea.Area8000); - Switch08KPRG(prg_reg[1] | prg_or, PRGArea.AreaA000); - Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0] | prg_or, PRGArea.AreaC000); - Switch08KPRG(prg_reg[3] | prg_or, PRGArea.AreaE000); - } - - internal override void OnPPUA12RaisingEdge() - { - old_irq_counter = irq_counter; - if (irq_counter == 0 || irq_clear) - { - irq_counter = irq_reload; - } - else - { - irq_counter--; - } - if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) - { - NesEmu.IRQFlags |= 8; - } - irq_clear = false; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(flag_c); - stream.Write(flag_p); - stream.Write(address_8001); - for (int i = 0; i < chr_reg.Length; i++) - { - stream.Write(chr_reg[i]); - } - for (int j = 0; j < prg_reg.Length; j++) - { - stream.Write(prg_reg[j]); - } - stream.Write(irq_enabled); - stream.Write(irq_counter); - stream.Write(old_irq_counter); - stream.Write(irq_reload); - stream.Write(irq_clear); - stream.Write(prg_or); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - flag_c = stream.ReadBoolean(); - flag_p = stream.ReadBoolean(); - address_8001 = stream.ReadInt32(); - for (int i = 0; i < chr_reg.Length; i++) - { - chr_reg[i] = stream.ReadInt32(); - } - for (int j = 0; j < prg_reg.Length; j++) - { - prg_reg[j] = stream.ReadInt32(); - } - irq_enabled = stream.ReadBoolean(); - irq_counter = stream.ReadByte(); - old_irq_counter = stream.ReadInt32(); - irq_reload = stream.ReadByte(); - irq_clear = stream.ReadBoolean(); - prg_or = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("C&E", 245, true, true)] +[HassIssues] +internal class Mapper245 : Board +{ + private bool flag_c; + + private bool flag_p; + + private int address_8001; + + private int[] chr_reg; + + private int[] prg_reg; + + private int prg_or; + + private bool irq_enabled; + + private byte irq_counter; + + private int old_irq_counter; + + private byte irq_reload; + + private bool irq_clear; + + private bool mmc3_alt_behavior; + + internal override string Issues => MNInterfaceLanguage.IssueMapper245; + + internal override void HardReset() + { + base.HardReset(); + flag_c = (flag_p = false); + address_8001 = 0; + prg_reg = new int[4]; + prg_or = 0; + prg_reg[0] = 0; + prg_reg[1] = 1; + prg_reg[2] = PRG_ROM_08KB_Mask - 1; + prg_reg[3] = PRG_ROM_08KB_Mask; + chr_reg = new int[6]; + for (int i = 0; i < 6; i++) + { + chr_reg[i] = 0; + } + SetupPRG(); + SetupCHR(); + irq_enabled = false; + irq_counter = 0; + irq_reload = byte.MaxValue; + old_irq_counter = 0; + irq_clear = false; + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xE001) + { + case 32768: + address_8001 = data & 7; + flag_c = (data & 0x80) != 0; + flag_p = (data & 0x40) != 0; + SetupCHR(); + SetupPRG(); + break; + case 32769: + switch (address_8001) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + chr_reg[address_8001] = data; + SetupCHR(); + break; + case 6: + prg_reg[0] = data & 0x3F; + SetupPRG(); + break; + case 7: + prg_reg[1] = data & 0x3F; + SetupPRG(); + break; + } + break; + case 40960: + if (NMT_DEFAULT_MIRROR != Mirroring.Full) + { + Switch01KNMTFromMirroring(((data & 1) == 1) ? Mirroring.Horz : Mirroring.Vert); + } + break; + case 40961: + TogglePRGRAMEnable((data & 0x80) != 0); + TogglePRGRAMWritableEnable((data & 0x40) == 0); + break; + case 49152: + irq_reload = data; + break; + case 49153: + if (mmc3_alt_behavior) + { + irq_clear = true; + } + irq_counter = 0; + break; + case 57344: + irq_enabled = false; + NesEmu.IRQFlags &= -9; + break; + case 57345: + irq_enabled = true; + break; + } + } + + private void SetupCHR() + { + if (CHR_ROM_01KB_Count > 0) + { + if (!flag_c) + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area0000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area0800); + Switch01KCHR(chr_reg[2], CHRArea.Area1000); + Switch01KCHR(chr_reg[3], CHRArea.Area1400); + Switch01KCHR(chr_reg[4], CHRArea.Area1800); + Switch01KCHR(chr_reg[5], CHRArea.Area1C00); + } + else + { + Switch02KCHR(chr_reg[0] >> 1, CHRArea.Area1000); + Switch02KCHR(chr_reg[1] >> 1, CHRArea.Area1800); + Switch01KCHR(chr_reg[2], CHRArea.Area0000); + Switch01KCHR(chr_reg[3], CHRArea.Area0400); + Switch01KCHR(chr_reg[4], CHRArea.Area0800); + Switch01KCHR(chr_reg[5], CHRArea.Area0C00); + } + } + else if (!flag_c) + { + Switch04KCHR(0, CHRArea.Area0000); + Switch04KCHR(1, CHRArea.Area1000); + } + else + { + Switch04KCHR(1, CHRArea.Area0000); + Switch04KCHR(0, CHRArea.Area1000); + } + } + + private void SetupPRG() + { + prg_or = (chr_reg[0] & 2) << 5; + Switch08KPRG(prg_reg[flag_p ? 2 : 0] | prg_or, PRGArea.Area8000); + Switch08KPRG(prg_reg[1] | prg_or, PRGArea.AreaA000); + Switch08KPRG(prg_reg[(!flag_p) ? 2 : 0] | prg_or, PRGArea.AreaC000); + Switch08KPRG(prg_reg[3] | prg_or, PRGArea.AreaE000); + } + + internal override void OnPPUA12RaisingEdge() + { + old_irq_counter = irq_counter; + if (irq_counter == 0 || irq_clear) + { + irq_counter = irq_reload; + } + else + { + irq_counter--; + } + if ((!mmc3_alt_behavior || old_irq_counter != 0 || irq_clear) && irq_counter == 0 && irq_enabled) + { + NesEmu.IRQFlags |= 8; + } + irq_clear = false; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(flag_c); + stream.Write(flag_p); + stream.Write(address_8001); + for (int i = 0; i < chr_reg.Length; i++) + { + stream.Write(chr_reg[i]); + } + for (int j = 0; j < prg_reg.Length; j++) + { + stream.Write(prg_reg[j]); + } + stream.Write(irq_enabled); + stream.Write(irq_counter); + stream.Write(old_irq_counter); + stream.Write(irq_reload); + stream.Write(irq_clear); + stream.Write(prg_or); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + flag_c = stream.ReadBoolean(); + flag_p = stream.ReadBoolean(); + address_8001 = stream.ReadInt32(); + for (int i = 0; i < chr_reg.Length; i++) + { + chr_reg[i] = stream.ReadInt32(); + } + for (int j = 0; j < prg_reg.Length; j++) + { + prg_reg[j] = stream.ReadInt32(); + } + irq_enabled = stream.ReadBoolean(); + irq_counter = stream.ReadByte(); + old_irq_counter = stream.ReadInt32(); + irq_reload = stream.ReadByte(); + irq_clear = stream.ReadBoolean(); + prg_or = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper246.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper246.cs index 71991ab..d138a3f 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper246.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper246.cs @@ -1,50 +1,49 @@ -namespace MyNes.Core -{ - [BoardInfo("Unknown", 246)] - internal class Mapper246 : Board - { - internal override void HardReset() - { - base.HardReset(); - Switch08KPRG(255, PRGArea.AreaE000); - } - - internal override void WriteSRM(ref ushort address, ref byte data) - { - if (address < 26624) - { - switch (address) - { - case 24576: - Switch08KPRG(data, PRGArea.Area8000); - break; - case 24577: - Switch08KPRG(data, PRGArea.AreaA000); - break; - case 24578: - Switch08KPRG(data, PRGArea.AreaC000); - break; - case 24579: - Switch08KPRG(data, PRGArea.AreaE000); - break; - case 24580: - Switch02KCHR(data, CHRArea.Area0000); - break; - case 24581: - Switch02KCHR(data, CHRArea.Area0800); - break; - case 24582: - Switch02KCHR(data, CHRArea.Area1000); - break; - case 24583: - Switch02KCHR(data, CHRArea.Area1800); - break; - } - } - else - { - base.WriteSRM(ref address, ref data); - } - } - } +namespace MyNes.Core; + +[BoardInfo("Unknown", 246)] +internal class Mapper246 : Board +{ + internal override void HardReset() + { + base.HardReset(); + Switch08KPRG(255, PRGArea.AreaE000); + } + + internal override void WriteSRM(ref ushort address, ref byte data) + { + if (address < 26624) + { + switch (address) + { + case 24576: + Switch08KPRG(data, PRGArea.Area8000); + break; + case 24577: + Switch08KPRG(data, PRGArea.AreaA000); + break; + case 24578: + Switch08KPRG(data, PRGArea.AreaC000); + break; + case 24579: + Switch08KPRG(data, PRGArea.AreaE000); + break; + case 24580: + Switch02KCHR(data, CHRArea.Area0000); + break; + case 24581: + Switch02KCHR(data, CHRArea.Area0800); + break; + case 24582: + Switch02KCHR(data, CHRArea.Area1000); + break; + case 24583: + Switch02KCHR(data, CHRArea.Area1800); + break; + } + } + else + { + base.WriteSRM(ref address, ref data); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper255.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper255.cs index b54016c..03059c7 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper255.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mapper255.cs @@ -1,66 +1,65 @@ -using System.IO; - -namespace MyNes.Core -{ - [BoardInfo("Unknown", 255)] - [HassIssues] - internal class Mapper255 : Board - { - private byte[] RAM; - - internal override string Issues => MNInterfaceLanguage.IssueMapper255; - - internal override void HardReset() - { - base.HardReset(); - RAM = new byte[4]; - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - if (address >= 22528) - { - RAM[address & 3] = (byte)(data & 0xFu); - } - } - - internal override void ReadEX(ref ushort address, out byte data) - { - if (address >= 22528) - { - data = RAM[address & 3]; - } - else - { - data = 0; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - Switch08KCHR(address & 0x3F); - if ((address & 0x1000) == 4096) - { - Switch16KPRG((address >> 6) & 0x3F, PRGArea.Area8000); - Switch16KPRG((address >> 6) & 0x3F, PRGArea.AreaC000); - } - else - { - Switch32KPRG(((address >> 6) & 0x3F) >> 1, PRGArea.Area8000); - } - Switch01KNMTFromMirroring(((address & 0x2000) == 8192) ? Mirroring.Horz : Mirroring.Vert); - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(RAM); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - stream.Read(RAM, 0, RAM.Length); - } - } +using System.IO; + +namespace MyNes.Core; + +[BoardInfo("Unknown", 255)] +[HassIssues] +internal class Mapper255 : Board +{ + private byte[] RAM; + + internal override string Issues => MNInterfaceLanguage.IssueMapper255; + + internal override void HardReset() + { + base.HardReset(); + RAM = new byte[4]; + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + if (address >= 22528) + { + RAM[address & 3] = (byte)(data & 0xFu); + } + } + + internal override void ReadEX(ref ushort address, out byte data) + { + if (address >= 22528) + { + data = RAM[address & 3]; + } + else + { + data = 0; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + Switch08KCHR(address & 0x3F); + if ((address & 0x1000) == 4096) + { + Switch16KPRG((address >> 6) & 0x3F, PRGArea.Area8000); + Switch16KPRG((address >> 6) & 0x3F, PRGArea.AreaC000); + } + else + { + Switch32KPRG(((address >> 6) & 0x3F) >> 1, PRGArea.Area8000); + } + Switch01KNMTFromMirroring(((address & 0x2000) == 8192) ? Mirroring.Horz : Mirroring.Vert); + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(RAM); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + stream.Read(RAM, 0, RAM.Length); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/MemReadAccess.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/MemReadAccess.cs index 6f199bc..00d047a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/MemReadAccess.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/MemReadAccess.cs @@ -1,4 +1,3 @@ -namespace MyNes.Core -{ - internal delegate void MemReadAccess(ref ushort addr, out byte value); -} +namespace MyNes.Core; + +internal delegate void MemReadAccess(ref ushort addr, out byte value); diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/MemWriteAccess.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/MemWriteAccess.cs index e63e2dc..35e591c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/MemWriteAccess.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/MemWriteAccess.cs @@ -1,4 +1,3 @@ -namespace MyNes.Core -{ - internal delegate void MemWriteAccess(ref ushort addr, ref byte value); -} +namespace MyNes.Core; + +internal delegate void MemWriteAccess(ref ushort addr, ref byte value); diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mirroring.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mirroring.cs index d637bea..6a08f0f 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Mirroring.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Mirroring.cs @@ -1,11 +1,10 @@ -namespace MyNes.Core -{ - public enum Mirroring : byte - { - Horz = 80, - Vert = 68, - OneScA = 0, - OneScB = 85, - Full = 228 - } +namespace MyNes.Core; + +public enum Mirroring : byte +{ + Horz = 80, + Vert = 68, + OneScA = 0, + OneScB = 85, + Full = 228 } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/MyNesMain.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/MyNesMain.cs index 4a2c4bf..4c21ee3 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/MyNesMain.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/MyNesMain.cs @@ -1,339 +1,336 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; - -namespace MyNes.Core -{ - public class MyNesMain - { - public static EmuSettings EmuSettings { get; private set; } - - public static RendererSettings RendererSettings { get; private set; } - - public static string AppPath { get; private set; } - - public static string WorkingFolder { get; private set; } - - internal static List Boards { get; private set; } - - public static List VideoProviders { get; private set; } - - public static List AudioProviders { get; private set; } - - public static IVideoProvider VideoProvider { get; private set; } - - public static IAudioProvider AudioProvider { get; private set; } - - public static WaveRecorder WaveRecorder { get; private set; } - - public static void Initialize(bool setupRenderers) - { - Tracer.WriteLine("Initializing My Nes Core ...."); - AppPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]); - if (AppPath == "") - { - AppPath = Path.GetFullPath(".\\"); - } - WorkingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "MyNes"); - Directory.CreateDirectory(WorkingFolder); - Tracer.WriteLine("Loading emu settings ..."); - EmuSettings = new EmuSettings(Path.Combine(WorkingFolder, "emusettings.ini")); - EmuSettings.LoadSettings(); - Tracer.WriteLine("Emu settings loaded successfully."); - Tracer.WriteLine("Loading renderer settings ..."); - RendererSettings = new RendererSettings(Path.Combine(WorkingFolder, "renderersettings.ini")); - RendererSettings.LoadSettings(); - Tracer.WriteLine("Renderer settings loaded successfully."); - Tracer.WriteLine("Locating boards and providers ..."); - WaveRecorder = new WaveRecorder(); - Boards = new List(); - VideoProviders = new List(); - AudioProviders = new List(); - string[] files = Directory.GetFiles(Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]), "*", SearchOption.AllDirectories); - string[] array = files; - foreach (string text in array) - { - try - { - if (!(Path.GetExtension(text).ToLower() == ".exe") && !(Path.GetExtension(text).ToLower() == ".dll")) - { - continue; - } - Tracer.WriteLine("Reading assembly: " + text); - Assembly assembly = Assembly.LoadFile(text); - if (!(assembly != null)) - { - continue; - } - Type[] types = assembly.GetTypes(); - Type[] array2 = types; - foreach (Type type in array2) - { - if (type.IsSubclassOf(typeof(Board)) && !type.IsAbstract) - { - Board board = Activator.CreateInstance(type) as Board; - Boards.Add(board); - Tracer.WriteLine("Board added: " + board.Name + " [ Mapper " + board.MapperNumber + "]"); - } - else if (type.GetInterface("MyNes.Core.IVideoProvider") != null) - { - IVideoProvider videoProvider = Activator.CreateInstance(type) as IVideoProvider; - VideoProviders.Add(videoProvider); - Tracer.WriteLine("Video provider added: " + videoProvider.Name + " [" + videoProvider.ID + "]"); - } - else if (type.GetInterface("MyNes.Core.IAudioProvider") != null) - { - IAudioProvider audioProvider = Activator.CreateInstance(type) as IAudioProvider; - AudioProviders.Add(audioProvider); - Tracer.WriteLine("Audio provider added: " + audioProvider.Name + " [" + audioProvider.ID + "]"); - } - } - } - catch (Exception ex) - { - Tracer.WriteLine("ERROR: " + ex.ToString()); - } - } - Tracer.WriteInformation("Done."); - Tracer.WriteInformation("Total of " + Boards.Count + " board found."); - Tracer.WriteInformation("Total of " + VideoProviders.Count + " video provider found."); - Tracer.WriteInformation("Total of " + AudioProviders.Count + " audio provider found."); - if (setupRenderers) - { - SetVideoProvider(); - SetAudioProvider(); - SetRenderingMethods(); - } - NesEmu.Initialize(); - } - - public static void Shutdown() - { - if (NesEmu.ON) - { - NesEmu.ShutDown(); - } - if (VideoProvider != null) - { - VideoProvider.ShutDown(); - } - if (AudioProvider != null) - { - AudioProvider.ShutDown(); - } - Tracer.WriteLine("Saving settings ..."); - EmuSettings.SaveSettings(); - RendererSettings.SaveSettings(); - Tracer.WriteLine("Settings saved successfully."); - Tracer.WriteLine("Exiting My Nes."); - } - - internal static bool IsBoardExist(int mapper) - { - foreach (Board board in Boards) - { - if (board.MapperNumber == mapper) - { - return true; - } - } - return false; - } - - internal static Board GetBoard(int mapper) - { - foreach (Board board in Boards) - { - if (board.MapperNumber == mapper) - { - return board; - } - } - return null; - } - - public static void MakeWorkingFolder() - { - WorkingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "MyNes"); - Directory.CreateDirectory(WorkingFolder); - } - - public static BoardInfoObject[] GetBoardsList(bool includeUnsupportedMappers) - { - List list = new List(); - if (includeUnsupportedMappers) - { - for (int i = 0; i < 256; i++) - { - bool flag = false; - foreach (Board board in Boards) - { - if (board.MapperNumber == i) - { - BoardInfoObject boardInfoObject = new BoardInfoObject(); - boardInfoObject.Name = board.Name; - boardInfoObject.MapperNumber = board.MapperNumber; - boardInfoObject.IsSupported = true; - boardInfoObject.HasIssues = board.HasIssues; - boardInfoObject.Issues = board.Issues; - list.Add(boardInfoObject); - flag = true; - break; - } - } - if (!flag) - { - BoardInfoObject boardInfoObject2 = new BoardInfoObject(); - boardInfoObject2.Name = "N/A"; - boardInfoObject2.MapperNumber = i; - boardInfoObject2.IsSupported = false; - boardInfoObject2.HasIssues = false; - boardInfoObject2.Issues = ""; - list.Add(boardInfoObject2); - } - } - } - else - { - foreach (Board board2 in Boards) - { - if (board2.MapperNumber >= 0) - { - BoardInfoObject boardInfoObject3 = new BoardInfoObject(); - boardInfoObject3.Name = board2.Name; - boardInfoObject3.MapperNumber = board2.MapperNumber; - boardInfoObject3.IsSupported = true; - boardInfoObject3.HasIssues = board2.HasIssues; - boardInfoObject3.Issues = board2.Issues; - list.Add(boardInfoObject3); - } - } - } - return list.ToArray(); - } - - public static IVideoProvider GetVideoProvider(string id) - { - foreach (IVideoProvider videoProvider in VideoProviders) - { - if (videoProvider.ID == id) - { - return videoProvider; - } - } - return null; - } - - public static IAudioProvider GetAudioProvider(string id) - { - foreach (IAudioProvider audioProvider in AudioProviders) - { - if (audioProvider.ID == id) - { - return audioProvider; - } - } - return null; - } - - public static void SetVideoProvider() - { - Tracer.WriteLine("Looking for the video provider that set in the settings..."); - VideoProvider = GetVideoProvider(RendererSettings.Video_ProviderID); - if (VideoProvider == null) - { - Tracer.WriteError("ERROR: cannot find the video provider that set in the settings"); - Tracer.WriteWarning("Deciding video provider"); - if (VideoProviders.Count > 0) - { - RendererSettings.Video_ProviderID = VideoProviders[0].ID; - VideoProvider = VideoProviders[0]; - if (VideoProvider != null) - { - Tracer.WriteInformation("Video provider set to " + VideoProvider.Name + " [" + VideoProvider.ID + "]"); - VideoProvider.Initialize(); - } - else - { - Tracer.WriteError("ERROR: cannot set video provider."); - } - } - else - { - Tracer.WriteError("ERROR: cannot set video provider, no video providers located."); - } - } - else - { - Tracer.WriteInformation("Video provider set to " + VideoProvider.Name + " [" + VideoProvider.ID + "]"); - VideoProvider.Initialize(); - } - } - - public static void SetAudioProvider() - { - Tracer.WriteLine("Looking for the audio provider that set in the settings..."); - AudioProvider = GetAudioProvider(RendererSettings.Audio_ProviderID); - if (AudioProvider == null) - { - Tracer.WriteError("ERROR: cannot find the audio provider that set in the settings"); - Tracer.WriteWarning("Deciding audio provider"); - if (AudioProviders.Count > 0) - { - RendererSettings.Audio_ProviderID = AudioProviders[0].ID; - AudioProvider = AudioProviders[0]; - if (AudioProvider != null) - { - Tracer.WriteInformation("Audio provider set to " + AudioProvider.Name + " [" + AudioProvider.ID + "]"); - AudioProvider.Initialize(); - } - else - { - Tracer.WriteError("ERROR: cannot set audio provider."); - } - } - else - { - Tracer.WriteError("ERROR: cannot set audio provider, no audio providers located."); - } - } - else - { - Tracer.WriteInformation("Audio provider set to " + AudioProvider.Name + " [" + AudioProvider.ID + "]"); - AudioProvider.Initialize(); - } - } - - public static void SetRenderingMethods() - { - if (VideoProvider != null && AudioProvider != null) - { - NesEmu.SetupRenderingMethods(VideoProvider.SubmitFrame, AudioProvider.SubmitSamples, AudioProvider.TogglePause, AudioProvider.GetIsPlaying); - } - else - { - Tracer.WriteError("ERROR: unable to setup rendering methods, one (or both) of the providers is not set (video and/or audio provider)"); - } - } - - public static void RecordWave() - { - if (NesEmu.ON && NesEmu.SoundEnabled) - { - string text = Path.Combine(EmuSettings.WavesFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath) + ".wav"); - int num = 0; - while (File.Exists(text)) - { - text = Path.Combine(EmuSettings.WavesFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath) + "_" + num + ".wav"); - num++; - } - WaveRecorder.Record(text, 1, 16, RendererSettings.Audio_Frequency); - } - else if (VideoProvider != null) - { - VideoProvider.WriteErrorNotification("Cannot record sound when the emu is off/sound is not enabled.", instant: false); - } - } - } +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; + +namespace MyNes.Core; + +public class MyNesMain +{ + public static EmuSettings EmuSettings { get; private set; } + + public static RendererSettings RendererSettings { get; private set; } + + public static string AppPath { get; private set; } + + public static string WorkingFolder { get; private set; } + + internal static List Boards { get; private set; } + + public static List VideoProviders { get; private set; } + + public static List AudioProviders { get; private set; } + + public static IVideoProvider VideoProvider { get; private set; } + + public static IAudioProvider AudioProvider { get; private set; } + + public static WaveRecorder WaveRecorder { get; private set; } + + public static void Initialize(bool setupRenderers) + { + Tracer.WriteLine("Initializing My Nes Core ...."); + AppPath = Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]); + if (AppPath == "") + { + AppPath = Path.GetFullPath(".\\"); + } + WorkingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "MyNes"); + Directory.CreateDirectory(WorkingFolder); + Tracer.WriteLine("Loading emu settings ..."); + EmuSettings = new EmuSettings(Path.Combine(WorkingFolder, "emusettings.ini")); + EmuSettings.LoadSettings(); + Tracer.WriteLine("Emu settings loaded successfully."); + Tracer.WriteLine("Loading renderer settings ..."); + RendererSettings = new RendererSettings(Path.Combine(WorkingFolder, "renderersettings.ini")); + RendererSettings.LoadSettings(); + Tracer.WriteLine("Renderer settings loaded successfully."); + Tracer.WriteLine("Locating boards and providers ..."); + WaveRecorder = new WaveRecorder(); + Boards = new List(); + VideoProviders = new List(); + AudioProviders = new List(); + string[] files = Directory.GetFiles(Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]), "*", SearchOption.AllDirectories); + foreach (string text in files) + { + try + { + if (!(Path.GetExtension(text).ToLower() == ".exe") && !(Path.GetExtension(text).ToLower() == ".dll")) + { + continue; + } + Tracer.WriteLine("Reading assembly: " + text); + Assembly assembly = Assembly.LoadFile(text); + if (!(assembly != null)) + { + continue; + } + Type[] types = assembly.GetTypes(); + foreach (Type type in types) + { + if (type.IsSubclassOf(typeof(Board)) && !type.IsAbstract) + { + Board board = Activator.CreateInstance(type) as Board; + Boards.Add(board); + Tracer.WriteLine("Board added: " + board.Name + " [ Mapper " + board.MapperNumber + "]"); + } + else if (type.GetInterface("MyNes.Core.IVideoProvider") != null) + { + IVideoProvider videoProvider = Activator.CreateInstance(type) as IVideoProvider; + VideoProviders.Add(videoProvider); + Tracer.WriteLine("Video provider added: " + videoProvider.Name + " [" + videoProvider.ID + "]"); + } + else if (type.GetInterface("MyNes.Core.IAudioProvider") != null) + { + IAudioProvider audioProvider = Activator.CreateInstance(type) as IAudioProvider; + AudioProviders.Add(audioProvider); + Tracer.WriteLine("Audio provider added: " + audioProvider.Name + " [" + audioProvider.ID + "]"); + } + } + } + catch (Exception ex) + { + Tracer.WriteLine("ERROR: " + ex.ToString()); + } + } + Tracer.WriteInformation("Done."); + Tracer.WriteInformation("Total of " + Boards.Count + " board found."); + Tracer.WriteInformation("Total of " + VideoProviders.Count + " video provider found."); + Tracer.WriteInformation("Total of " + AudioProviders.Count + " audio provider found."); + if (setupRenderers) + { + SetVideoProvider(); + SetAudioProvider(); + SetRenderingMethods(); + } + NesEmu.Initialize(); + } + + public static void Shutdown() + { + if (NesEmu.ON) + { + NesEmu.ShutDown(); + } + if (VideoProvider != null) + { + VideoProvider.ShutDown(); + } + if (AudioProvider != null) + { + AudioProvider.ShutDown(); + } + Tracer.WriteLine("Saving settings ..."); + EmuSettings.SaveSettings(); + RendererSettings.SaveSettings(); + Tracer.WriteLine("Settings saved successfully."); + Tracer.WriteLine("Exiting My Nes."); + } + + internal static bool IsBoardExist(int mapper) + { + foreach (Board board in Boards) + { + if (board.MapperNumber == mapper) + { + return true; + } + } + return false; + } + + internal static Board GetBoard(int mapper) + { + foreach (Board board in Boards) + { + if (board.MapperNumber == mapper) + { + return board; + } + } + return null; + } + + public static void MakeWorkingFolder() + { + WorkingFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "MyNes"); + Directory.CreateDirectory(WorkingFolder); + } + + public static BoardInfoObject[] GetBoardsList(bool includeUnsupportedMappers) + { + List list = new List(); + if (includeUnsupportedMappers) + { + for (int i = 0; i < 256; i++) + { + bool flag = false; + foreach (Board board in Boards) + { + if (board.MapperNumber == i) + { + BoardInfoObject boardInfoObject = new BoardInfoObject(); + boardInfoObject.Name = board.Name; + boardInfoObject.MapperNumber = board.MapperNumber; + boardInfoObject.IsSupported = true; + boardInfoObject.HasIssues = board.HasIssues; + boardInfoObject.Issues = board.Issues; + list.Add(boardInfoObject); + flag = true; + break; + } + } + if (!flag) + { + BoardInfoObject boardInfoObject2 = new BoardInfoObject(); + boardInfoObject2.Name = "N/A"; + boardInfoObject2.MapperNumber = i; + boardInfoObject2.IsSupported = false; + boardInfoObject2.HasIssues = false; + boardInfoObject2.Issues = ""; + list.Add(boardInfoObject2); + } + } + } + else + { + foreach (Board board2 in Boards) + { + if (board2.MapperNumber >= 0) + { + BoardInfoObject boardInfoObject3 = new BoardInfoObject(); + boardInfoObject3.Name = board2.Name; + boardInfoObject3.MapperNumber = board2.MapperNumber; + boardInfoObject3.IsSupported = true; + boardInfoObject3.HasIssues = board2.HasIssues; + boardInfoObject3.Issues = board2.Issues; + list.Add(boardInfoObject3); + } + } + } + return list.ToArray(); + } + + public static IVideoProvider GetVideoProvider(string id) + { + foreach (IVideoProvider videoProvider in VideoProviders) + { + if (videoProvider.ID == id) + { + return videoProvider; + } + } + return null; + } + + public static IAudioProvider GetAudioProvider(string id) + { + foreach (IAudioProvider audioProvider in AudioProviders) + { + if (audioProvider.ID == id) + { + return audioProvider; + } + } + return null; + } + + public static void SetVideoProvider() + { + Tracer.WriteLine("Looking for the video provider that set in the settings..."); + VideoProvider = GetVideoProvider(RendererSettings.Video_ProviderID); + if (VideoProvider == null) + { + Tracer.WriteError("ERROR: cannot find the video provider that set in the settings"); + Tracer.WriteWarning("Deciding video provider"); + if (VideoProviders.Count > 0) + { + RendererSettings.Video_ProviderID = VideoProviders[0].ID; + VideoProvider = VideoProviders[0]; + if (VideoProvider != null) + { + Tracer.WriteInformation("Video provider set to " + VideoProvider.Name + " [" + VideoProvider.ID + "]"); + VideoProvider.Initialize(); + } + else + { + Tracer.WriteError("ERROR: cannot set video provider."); + } + } + else + { + Tracer.WriteError("ERROR: cannot set video provider, no video providers located."); + } + } + else + { + Tracer.WriteInformation("Video provider set to " + VideoProvider.Name + " [" + VideoProvider.ID + "]"); + VideoProvider.Initialize(); + } + } + + public static void SetAudioProvider() + { + Tracer.WriteLine("Looking for the audio provider that set in the settings..."); + AudioProvider = GetAudioProvider(RendererSettings.Audio_ProviderID); + if (AudioProvider == null) + { + Tracer.WriteError("ERROR: cannot find the audio provider that set in the settings"); + Tracer.WriteWarning("Deciding audio provider"); + if (AudioProviders.Count > 0) + { + RendererSettings.Audio_ProviderID = AudioProviders[0].ID; + AudioProvider = AudioProviders[0]; + if (AudioProvider != null) + { + Tracer.WriteInformation("Audio provider set to " + AudioProvider.Name + " [" + AudioProvider.ID + "]"); + AudioProvider.Initialize(); + } + else + { + Tracer.WriteError("ERROR: cannot set audio provider."); + } + } + else + { + Tracer.WriteError("ERROR: cannot set audio provider, no audio providers located."); + } + } + else + { + Tracer.WriteInformation("Audio provider set to " + AudioProvider.Name + " [" + AudioProvider.ID + "]"); + AudioProvider.Initialize(); + } + } + + public static void SetRenderingMethods() + { + if (VideoProvider != null && AudioProvider != null) + { + NesEmu.SetupRenderingMethods(VideoProvider.SubmitFrame, AudioProvider.SubmitSamples, AudioProvider.TogglePause, AudioProvider.GetIsPlaying); + } + else + { + Tracer.WriteError("ERROR: unable to setup rendering methods, one (or both) of the providers is not set (video and/or audio provider)"); + } + } + + public static void RecordWave() + { + if (NesEmu.ON && NesEmu.SoundEnabled) + { + string text = Path.Combine(EmuSettings.WavesFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath) + ".wav"); + int num = 0; + while (File.Exists(text)) + { + text = Path.Combine(EmuSettings.WavesFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath) + "_" + num + ".wav"); + num++; + } + WaveRecorder.Record(text, 1, 16, RendererSettings.Audio_Frequency); + } + else if (VideoProvider != null) + { + VideoProvider.WriteErrorNotification("Cannot record sound when the emu is off/sound is not enabled.", instant: false); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/NTArea.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/NTArea.cs index 7635f4c..8028592 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/NTArea.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/NTArea.cs @@ -1,10 +1,9 @@ -namespace MyNes.Core -{ - internal enum NTArea : byte - { - Area2000NT0, - Area2400NT1, - Area2800NT2, - Area2C00NT3 - } +namespace MyNes.Core; + +internal enum NTArea : byte +{ + Area2000NT0, + Area2400NT1, + Area2800NT2, + Area2C00NT3 } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/NTSCPaletteGenerator.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/NTSCPaletteGenerator.cs new file mode 100644 index 0000000..c2e0a05 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/NTSCPaletteGenerator.cs @@ -0,0 +1,108 @@ +using System; + +namespace MyNes.Core; + +public class NTSCPaletteGenerator +{ + public const float default_saturation = 1.496f; + + public const float default_hue_tweak = 0f; + + public const float default_contrast = 1.016f; + + public const float default_brightness = 1.075f; + + public const float default_gamma = 1.975f; + + private const float black = 0.518f; + + private const float white = 1.962f; + + private const float attenuation = 0.746f; + + public static float saturation = 2f; + + public static float hue_tweak = 0f; + + public static float contrast = 1.4f; + + public static float brightness = 1.07f; + + public static float gamma = 2f; + + private static float[] levels = new float[8] { 0.35f, 0.518f, 0.962f, 1.55f, 1.094f, 1.506f, 1.962f, 1.962f }; + + private static int wave(int p, int color) + { + if ((color + p + 8) % 12 >= 6) + { + return 0; + } + return 1; + } + + private static float gammafix(float f, float gamma) + { + return (float)((f < 0f) ? 0.0 : Math.Pow(f, 2.2f / gamma)); + } + + private static int clamp(float v) + { + return (int)((v < 0f) ? 0f : ((v > 255f) ? 255f : v)); + } + + public static int MakeRGBcolor(int pixel) + { + int num = pixel & 0xF; + int num2 = ((num >= 14) ? 1 : ((pixel >> 4) & 3)); + float[] array = new float[2] + { + levels[num2 + ((num == 0) ? 4 : 0)], + levels[num2 + ((num <= 12) ? 4 : 0)] + }; + float num3 = 0f; + float num4 = 0f; + float num5 = 0f; + for (int i = 0; i < 12; i++) + { + float num6 = array[wave(i, num)]; + if ((((uint)pixel & 0x40u) != 0 && wave(i, 12) == 1) || (((uint)pixel & 0x80u) != 0 && wave(i, 4) == 1) || (((uint)pixel & 0x100u) != 0 && wave(i, 8) == 1)) + { + num6 *= 0.746f; + } + float num7 = (num6 - 0.518f) / 1.444f; + num7 = (num7 - 0.5f) * contrast + 0.5f; + num7 *= brightness / 12f; + num3 += num7; + num4 += (float)((double)num7 * Math.Cos(Math.PI / 6.0 * (double)((float)i + hue_tweak))); + num5 += (float)((double)num7 * Math.Sin(Math.PI / 6.0 * (double)((float)i + hue_tweak))); + } + num4 *= saturation; + num5 *= saturation; + return 65536 * clamp(255f * gammafix(num3 + 0.946882f * num4 + 0.623557f * num5, gamma)) + 256 * clamp(255f * gammafix(num3 - 245f / (328f * (float)Math.E) * num4 - 0.635691f * num5, gamma)) + clamp(255f * gammafix(num3 - 1.108545f * num4 + 1.709007f * num5, gamma)); + } + + public static int[] GeneratePalette() + { + int[] array = new int[512]; + for (int i = 0; i < 512; i++) + { + array[i] = MakeRGBcolor(i) | -16777216; + } + return array; + } + + public static int[] GeneratePaletteGBR() + { + int[] array = new int[512]; + for (int i = 0; i < 512; i++) + { + int num = MakeRGBcolor(i); + byte b = (byte)((num & 0xFF0000) >> 16); + byte b2 = (byte)((num & 0xFF00) >> 8); + byte b3 = (byte)((uint)num & 0xFFu); + array[i] = -16777216 | (b3 << 16) | (b2 << 8) | b; + } + return array; + } +} diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/NTSCPaletteGenerator.cs.meta b/AxibugEmuOnline.Client/Assets/MyNes.Core/NTSCPaletteGenerator.cs.meta new file mode 100644 index 0000000..e5cadd3 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/NTSCPaletteGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 29be0f25cd887b349ab47194ae46b123 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Namcot106.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Namcot106.cs index b5f0558..4dd7fd6 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Namcot106.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Namcot106.cs @@ -1,553 +1,552 @@ -using System.IO; - -namespace MyNes.Core -{ - [WithExternalSound] - internal abstract class Namcot106 : Board - { - private int irq_counter; - - private bool irq_enable; - - private bool disables_chr_ram_A; - - private bool disables_chr_ram_B; - - private bool enable_mirroring_switch; - - private bool enable_N106_sound; - - private int temp_nmt; - - private Namcot106Chnl[] sound_channels; - - private byte soundReg; - - public int enabledChannels; - - private int enabledChannels1; - - private int channelIndex; - - private byte temp_val; - - private byte temp_i; - - public byte[] EXRAM; - - private bool[] sound_channels_enable; - - private double soundOut; - - private int sound_out_div; - - internal override void HardReset() - { - base.HardReset(); - EXRAM = new byte[128]; - Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); - enable_mirroring_switch = (enable_N106_sound = base.MapperNumber == 19); - switch (SHA1.ToUpper()) - { - case "97E7E61EECB73CB1EA0C15AE51E65EA56301A685": - case "3D554F55411AB2DDD1A87E7583E643970DB784F3": - case "7FA51058307DB50825C2D3A3A98C0DA554BC3C92": - case "1C476C795CFC17E987C22FFD6F09BAF1396ED2C9": - enable_mirroring_switch = false; - enable_N106_sound = false; - break; - } - if (enable_N106_sound) - { - sound_channels = new Namcot106Chnl[8]; - sound_channels_enable = new bool[8]; - for (int i = 0; i < 8; i++) - { - sound_channels[i] = new Namcot106Chnl(this); - sound_channels[i].HardReset(); - } - soundReg = 0; - enabledChannels = 0; - channelIndex = 0; - APUApplyChannelsSettings(); - } - } - - internal override void WriteEX(ref ushort address, ref byte data) - { - switch (address & 0xF800) - { - case 18432: - if (soundReg >= 64) - { - switch (soundReg & 0x7F) - { - case 64: - sound_channels[0].WriteA(ref data); - break; - case 66: - sound_channels[0].WriteB(ref data); - break; - case 68: - sound_channels[0].WriteC(ref data); - break; - case 70: - sound_channels[0].WriteD(ref data); - break; - case 71: - sound_channels[0].WriteE(ref data); - break; - case 72: - sound_channels[1].WriteA(ref data); - break; - case 74: - sound_channels[1].WriteB(ref data); - break; - case 76: - sound_channels[1].WriteC(ref data); - break; - case 78: - sound_channels[1].WriteD(ref data); - break; - case 79: - sound_channels[1].WriteE(ref data); - break; - case 80: - sound_channels[2].WriteA(ref data); - break; - case 82: - sound_channels[2].WriteB(ref data); - break; - case 84: - sound_channels[2].WriteC(ref data); - break; - case 86: - sound_channels[2].WriteD(ref data); - break; - case 87: - sound_channels[2].WriteE(ref data); - break; - case 88: - sound_channels[3].WriteA(ref data); - break; - case 90: - sound_channels[3].WriteB(ref data); - break; - case 92: - sound_channels[3].WriteC(ref data); - break; - case 94: - sound_channels[3].WriteD(ref data); - break; - case 95: - sound_channels[3].WriteE(ref data); - break; - case 96: - sound_channels[4].WriteA(ref data); - break; - case 98: - sound_channels[4].WriteB(ref data); - break; - case 100: - sound_channels[4].WriteC(ref data); - break; - case 102: - sound_channels[4].WriteD(ref data); - break; - case 103: - sound_channels[4].WriteE(ref data); - break; - case 104: - sound_channels[5].WriteA(ref data); - break; - case 106: - sound_channels[5].WriteB(ref data); - break; - case 108: - sound_channels[5].WriteC(ref data); - break; - case 110: - sound_channels[5].WriteD(ref data); - break; - case 111: - sound_channels[5].WriteE(ref data); - break; - case 112: - sound_channels[6].WriteA(ref data); - break; - case 114: - sound_channels[6].WriteB(ref data); - break; - case 116: - sound_channels[6].WriteC(ref data); - break; - case 118: - sound_channels[6].WriteD(ref data); - break; - case 119: - sound_channels[6].WriteE(ref data); - break; - case 120: - sound_channels[7].WriteA(ref data); - break; - case 122: - sound_channels[7].WriteB(ref data); - break; - case 124: - sound_channels[7].WriteC(ref data); - break; - case 126: - sound_channels[7].WriteD(ref data); - break; - case 127: - sound_channels[7].WriteE(ref data); - enabledChannels = (data & 0x70) >> 4; - channelIndex = 0; - enabledChannels1 = enabledChannels + 1; - temp_i = 7; - while (temp_i >= 0 && enabledChannels1 > 0) - { - sound_channels[temp_i].Enabled = true; - enabledChannels1--; - temp_i--; - } - break; - } - } - EXRAM[soundReg & 0x7F] = data; - if ((soundReg & 0x80) == 128) - { - soundReg = (byte)(((uint)(soundReg + 1) & 0x7Fu) | 0x80u); - } - break; - case 20480: - NesEmu.IRQFlags &= -9; - irq_counter = (irq_counter & 0x7F00) | data; - break; - case 22528: - NesEmu.IRQFlags &= -9; - irq_counter = (irq_counter & 0xFF) | ((data & 0x7F) << 8); - irq_enable = (data & 0x80) == 128; - break; - } - } - - internal override void ReadEX(ref ushort address, out byte value) - { - switch (address & 0xF800) - { - case 18432: - value = EXRAM[soundReg & 0x7F]; - if ((soundReg & 0x80) == 128) - { - soundReg = (byte)(((uint)(soundReg + 1) & 0x7Fu) | 0x80u); - } - break; - case 20480: - NesEmu.IRQFlags &= -9; - value = (byte)((uint)irq_counter & 0xFFu); - break; - case 22528: - NesEmu.IRQFlags &= -9; - value = (byte)((irq_enable ? 128u : 0u) | (uint)((irq_counter & 0x7F00) >> 8)); - break; - default: - value = 0; - break; - } - } - - internal override void WritePRG(ref ushort address, ref byte data) - { - switch (address & 0xF800) - { - case 32768: - if (!disables_chr_ram_A) - { - Toggle01KCHR_RAM(data >= 224, CHRArea.Area0000); - Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area0000); - } - else - { - Toggle01KCHR_RAM(ram: false, CHRArea.Area0000); - Switch01KCHR(data, CHRArea.Area0000); - } - break; - case 34816: - if (!disables_chr_ram_A) - { - Toggle01KCHR_RAM(data >= 224, CHRArea.Area0400); - Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area0400); - } - else - { - Toggle01KCHR_RAM(ram: false, CHRArea.Area0400); - Switch01KCHR(data, CHRArea.Area0400); - } - break; - case 36864: - if (!disables_chr_ram_A) - { - Toggle01KCHR_RAM(data >= 224, CHRArea.Area0800); - Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area0800); - } - else - { - Toggle01KCHR_RAM(ram: false, CHRArea.Area0800); - Switch01KCHR(data, CHRArea.Area0800); - } - break; - case 38912: - if (!disables_chr_ram_A) - { - Toggle01KCHR_RAM(data >= 224, CHRArea.Area0C00); - Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area0C00); - } - else - { - Toggle01KCHR_RAM(ram: false, CHRArea.Area0C00); - Switch01KCHR(data, CHRArea.Area0C00); - } - break; - case 40960: - if (!disables_chr_ram_B) - { - Toggle01KCHR_RAM(data >= 224, CHRArea.Area1000); - Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area1000); - } - else - { - Toggle01KCHR_RAM(ram: false, CHRArea.Area1000); - Switch01KCHR(data, CHRArea.Area1000); - } - break; - case 43008: - if (!disables_chr_ram_B) - { - Toggle01KCHR_RAM(data >= 224, CHRArea.Area1400); - Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area1400); - } - else - { - Toggle01KCHR_RAM(ram: false, CHRArea.Area1400); - Switch01KCHR(data, CHRArea.Area1400); - } - break; - case 45056: - if (!disables_chr_ram_B) - { - Toggle01KCHR_RAM(data >= 224, CHRArea.Area1800); - Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area1800); - } - else - { - Toggle01KCHR_RAM(ram: false, CHRArea.Area1800); - Switch01KCHR(data, CHRArea.Area1800); - } - break; - case 47104: - if (!disables_chr_ram_B) - { - Toggle01KCHR_RAM(data >= 224, CHRArea.Area1C00); - Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area1C00); - } - else - { - Toggle01KCHR_RAM(ram: false, CHRArea.Area1C00); - Switch01KCHR(data, CHRArea.Area1C00); - } - break; - case 49152: - if (enable_mirroring_switch) - { - NMT_AREA_BLK_INDEX[0] = data; - } - break; - case 51200: - if (enable_mirroring_switch) - { - NMT_AREA_BLK_INDEX[1] = data; - } - break; - case 53248: - if (enable_mirroring_switch) - { - NMT_AREA_BLK_INDEX[2] = data; - } - break; - case 55296: - if (enable_mirroring_switch) - { - NMT_AREA_BLK_INDEX[3] = data; - } - break; - case 57344: - Switch08KPRG(data & 0x3F, PRGArea.Area8000); - break; - case 59392: - Switch08KPRG(data & 0x3F, PRGArea.AreaA000); - disables_chr_ram_A = (data & 0x40) == 64; - disables_chr_ram_B = (data & 0x80) == 128; - break; - case 61440: - Switch08KPRG(data & 0x3F, PRGArea.AreaC000); - break; - case 63488: - soundReg = data; - break; - } - } - - internal override void ReadNMT(ref ushort address, out byte data) - { - if (enable_mirroring_switch) - { - temp_nmt = NMT_AREA_BLK_INDEX[(address >> 10) & 3]; - if (temp_nmt >= 224) - { - data = NMT_RAM[(temp_nmt - 224) & 1][address & 0x3FF]; - } - else - { - data = CHR_ROM[temp_nmt][address & 0x3FF]; - } - } - else - { - base.ReadNMT(ref address, out data); - } - } - - internal override void WriteNMT(ref ushort address, ref byte data) - { - if (enable_mirroring_switch) - { - temp_nmt = NMT_AREA_BLK_INDEX[(address >> 10) & 3]; - if (temp_nmt >= 224) - { - NMT_RAM[(temp_nmt - 224) & 1][address & 0x3FF] = data; - } - } - else - { - base.WriteNMT(ref address, ref data); - } - } - - internal override void OnCPUClock() - { - if (irq_enable) - { - if (irq_counter == 32767) - { - NesEmu.IRQFlags |= 8; - irq_counter = 0; - } - else - { - irq_counter++; - } - } - } - - internal override void OnAPUClockSingle() - { - if (sound_channels != null) - { - for (int i = 0; i < sound_channels.Length; i++) - { - sound_channels[i].ClockSingle(); - } - } - } - - internal override double APUGetSample() - { - soundOut = 0.0; - sound_out_div = 0; - if (enabledChannels > 0) - { - for (int i = 0; i < sound_channels.Length; i++) - { - if (sound_channels[i].Enabled && sound_channels_enable[i]) - { - if (sound_channels[i].clocks > 0) - { - sound_channels[i].output = sound_channels[i].output_av / sound_channels[i].clocks; - } - sound_channels[i].clocks = (sound_channels[i].output_av = 0); - soundOut += sound_channels[i].output; - sound_out_div++; - } - } - soundOut = soundOut / 8.0 / 225.0; - } - return soundOut; - } - - internal override void APUApplyChannelsSettings() - { - base.APUApplyChannelsSettings(); - sound_channels_enable[0] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT1; - sound_channels_enable[1] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT2; - sound_channels_enable[2] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT3; - sound_channels_enable[3] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT4; - sound_channels_enable[4] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT5; - sound_channels_enable[5] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT6; - sound_channels_enable[6] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT7; - sound_channels_enable[7] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT8; - } - - internal override void WriteStateData(ref BinaryWriter stream) - { - base.WriteStateData(ref stream); - stream.Write(irq_counter); - stream.Write(irq_enable); - stream.Write(disables_chr_ram_A); - stream.Write(disables_chr_ram_B); - stream.Write(enable_mirroring_switch); - stream.Write(enable_N106_sound); - stream.Write(temp_nmt); - if (enable_N106_sound) - { - for (int i = 0; i < sound_channels.Length; i++) - { - sound_channels[i].SaveState(stream); - } - } - stream.Write(soundReg); - stream.Write(enabledChannels); - stream.Write(enabledChannels1); - stream.Write(channelIndex); - stream.Write(temp_val); - stream.Write(temp_i); - stream.Write(EXRAM); - } - - internal override void ReadStateData(ref BinaryReader stream) - { - base.ReadStateData(ref stream); - irq_counter = stream.ReadInt32(); - irq_enable = stream.ReadBoolean(); - disables_chr_ram_A = stream.ReadBoolean(); - disables_chr_ram_B = stream.ReadBoolean(); - enable_mirroring_switch = stream.ReadBoolean(); - enable_N106_sound = stream.ReadBoolean(); - temp_nmt = stream.ReadInt32(); - if (enable_N106_sound) - { - for (int i = 0; i < sound_channels.Length; i++) - { - sound_channels[i].LoadState(stream); - } - } - soundReg = stream.ReadByte(); - enabledChannels = stream.ReadInt32(); - enabledChannels1 = stream.ReadInt32(); - channelIndex = stream.ReadInt32(); - temp_val = stream.ReadByte(); - temp_i = stream.ReadByte(); - stream.Read(EXRAM, 0, EXRAM.Length); - } - } +using System.IO; + +namespace MyNes.Core; + +[WithExternalSound] +internal abstract class Namcot106 : Board +{ + private int irq_counter; + + private bool irq_enable; + + private bool disables_chr_ram_A; + + private bool disables_chr_ram_B; + + private bool enable_mirroring_switch; + + private bool enable_N106_sound; + + private int temp_nmt; + + private Namcot106Chnl[] sound_channels; + + private byte soundReg; + + public int enabledChannels; + + private int enabledChannels1; + + private int channelIndex; + + private byte temp_val; + + private byte temp_i; + + public byte[] EXRAM; + + private bool[] sound_channels_enable; + + private double soundOut; + + private int sound_out_div; + + internal override void HardReset() + { + base.HardReset(); + EXRAM = new byte[128]; + Switch08KPRG(PRG_ROM_08KB_Mask, PRGArea.AreaE000); + enable_mirroring_switch = (enable_N106_sound = base.MapperNumber == 19); + switch (SHA1.ToUpper()) + { + case "97E7E61EECB73CB1EA0C15AE51E65EA56301A685": + case "3D554F55411AB2DDD1A87E7583E643970DB784F3": + case "7FA51058307DB50825C2D3A3A98C0DA554BC3C92": + case "1C476C795CFC17E987C22FFD6F09BAF1396ED2C9": + enable_mirroring_switch = false; + enable_N106_sound = false; + break; + } + if (enable_N106_sound) + { + sound_channels = new Namcot106Chnl[8]; + sound_channels_enable = new bool[8]; + for (int i = 0; i < 8; i++) + { + sound_channels[i] = new Namcot106Chnl(this); + sound_channels[i].HardReset(); + } + soundReg = 0; + enabledChannels = 0; + channelIndex = 0; + APUApplyChannelsSettings(); + } + } + + internal override void WriteEX(ref ushort address, ref byte data) + { + switch (address & 0xF800) + { + case 18432: + if (soundReg >= 64) + { + switch (soundReg & 0x7F) + { + case 64: + sound_channels[0].WriteA(ref data); + break; + case 66: + sound_channels[0].WriteB(ref data); + break; + case 68: + sound_channels[0].WriteC(ref data); + break; + case 70: + sound_channels[0].WriteD(ref data); + break; + case 71: + sound_channels[0].WriteE(ref data); + break; + case 72: + sound_channels[1].WriteA(ref data); + break; + case 74: + sound_channels[1].WriteB(ref data); + break; + case 76: + sound_channels[1].WriteC(ref data); + break; + case 78: + sound_channels[1].WriteD(ref data); + break; + case 79: + sound_channels[1].WriteE(ref data); + break; + case 80: + sound_channels[2].WriteA(ref data); + break; + case 82: + sound_channels[2].WriteB(ref data); + break; + case 84: + sound_channels[2].WriteC(ref data); + break; + case 86: + sound_channels[2].WriteD(ref data); + break; + case 87: + sound_channels[2].WriteE(ref data); + break; + case 88: + sound_channels[3].WriteA(ref data); + break; + case 90: + sound_channels[3].WriteB(ref data); + break; + case 92: + sound_channels[3].WriteC(ref data); + break; + case 94: + sound_channels[3].WriteD(ref data); + break; + case 95: + sound_channels[3].WriteE(ref data); + break; + case 96: + sound_channels[4].WriteA(ref data); + break; + case 98: + sound_channels[4].WriteB(ref data); + break; + case 100: + sound_channels[4].WriteC(ref data); + break; + case 102: + sound_channels[4].WriteD(ref data); + break; + case 103: + sound_channels[4].WriteE(ref data); + break; + case 104: + sound_channels[5].WriteA(ref data); + break; + case 106: + sound_channels[5].WriteB(ref data); + break; + case 108: + sound_channels[5].WriteC(ref data); + break; + case 110: + sound_channels[5].WriteD(ref data); + break; + case 111: + sound_channels[5].WriteE(ref data); + break; + case 112: + sound_channels[6].WriteA(ref data); + break; + case 114: + sound_channels[6].WriteB(ref data); + break; + case 116: + sound_channels[6].WriteC(ref data); + break; + case 118: + sound_channels[6].WriteD(ref data); + break; + case 119: + sound_channels[6].WriteE(ref data); + break; + case 120: + sound_channels[7].WriteA(ref data); + break; + case 122: + sound_channels[7].WriteB(ref data); + break; + case 124: + sound_channels[7].WriteC(ref data); + break; + case 126: + sound_channels[7].WriteD(ref data); + break; + case 127: + sound_channels[7].WriteE(ref data); + enabledChannels = (data & 0x70) >> 4; + channelIndex = 0; + enabledChannels1 = enabledChannels + 1; + temp_i = 7; + while (temp_i >= 0 && enabledChannels1 > 0) + { + sound_channels[temp_i].Enabled = true; + enabledChannels1--; + temp_i--; + } + break; + } + } + EXRAM[soundReg & 0x7F] = data; + if ((soundReg & 0x80) == 128) + { + soundReg = (byte)(((uint)(soundReg + 1) & 0x7Fu) | 0x80u); + } + break; + case 20480: + NesEmu.IRQFlags &= -9; + irq_counter = (irq_counter & 0x7F00) | data; + break; + case 22528: + NesEmu.IRQFlags &= -9; + irq_counter = (irq_counter & 0xFF) | ((data & 0x7F) << 8); + irq_enable = (data & 0x80) == 128; + break; + } + } + + internal override void ReadEX(ref ushort address, out byte value) + { + switch (address & 0xF800) + { + case 18432: + value = EXRAM[soundReg & 0x7F]; + if ((soundReg & 0x80) == 128) + { + soundReg = (byte)(((uint)(soundReg + 1) & 0x7Fu) | 0x80u); + } + break; + case 20480: + NesEmu.IRQFlags &= -9; + value = (byte)((uint)irq_counter & 0xFFu); + break; + case 22528: + NesEmu.IRQFlags &= -9; + value = (byte)((irq_enable ? 128u : 0u) | (uint)((irq_counter & 0x7F00) >> 8)); + break; + default: + value = 0; + break; + } + } + + internal override void WritePRG(ref ushort address, ref byte data) + { + switch (address & 0xF800) + { + case 32768: + if (!disables_chr_ram_A) + { + Toggle01KCHR_RAM(data >= 224, CHRArea.Area0000); + Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area0000); + } + else + { + Toggle01KCHR_RAM(ram: false, CHRArea.Area0000); + Switch01KCHR(data, CHRArea.Area0000); + } + break; + case 34816: + if (!disables_chr_ram_A) + { + Toggle01KCHR_RAM(data >= 224, CHRArea.Area0400); + Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area0400); + } + else + { + Toggle01KCHR_RAM(ram: false, CHRArea.Area0400); + Switch01KCHR(data, CHRArea.Area0400); + } + break; + case 36864: + if (!disables_chr_ram_A) + { + Toggle01KCHR_RAM(data >= 224, CHRArea.Area0800); + Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area0800); + } + else + { + Toggle01KCHR_RAM(ram: false, CHRArea.Area0800); + Switch01KCHR(data, CHRArea.Area0800); + } + break; + case 38912: + if (!disables_chr_ram_A) + { + Toggle01KCHR_RAM(data >= 224, CHRArea.Area0C00); + Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area0C00); + } + else + { + Toggle01KCHR_RAM(ram: false, CHRArea.Area0C00); + Switch01KCHR(data, CHRArea.Area0C00); + } + break; + case 40960: + if (!disables_chr_ram_B) + { + Toggle01KCHR_RAM(data >= 224, CHRArea.Area1000); + Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area1000); + } + else + { + Toggle01KCHR_RAM(ram: false, CHRArea.Area1000); + Switch01KCHR(data, CHRArea.Area1000); + } + break; + case 43008: + if (!disables_chr_ram_B) + { + Toggle01KCHR_RAM(data >= 224, CHRArea.Area1400); + Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area1400); + } + else + { + Toggle01KCHR_RAM(ram: false, CHRArea.Area1400); + Switch01KCHR(data, CHRArea.Area1400); + } + break; + case 45056: + if (!disables_chr_ram_B) + { + Toggle01KCHR_RAM(data >= 224, CHRArea.Area1800); + Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area1800); + } + else + { + Toggle01KCHR_RAM(ram: false, CHRArea.Area1800); + Switch01KCHR(data, CHRArea.Area1800); + } + break; + case 47104: + if (!disables_chr_ram_B) + { + Toggle01KCHR_RAM(data >= 224, CHRArea.Area1C00); + Switch01KCHR((data >= 224) ? (data - 224) : data, CHRArea.Area1C00); + } + else + { + Toggle01KCHR_RAM(ram: false, CHRArea.Area1C00); + Switch01KCHR(data, CHRArea.Area1C00); + } + break; + case 49152: + if (enable_mirroring_switch) + { + NMT_AREA_BLK_INDEX[0] = data; + } + break; + case 51200: + if (enable_mirroring_switch) + { + NMT_AREA_BLK_INDEX[1] = data; + } + break; + case 53248: + if (enable_mirroring_switch) + { + NMT_AREA_BLK_INDEX[2] = data; + } + break; + case 55296: + if (enable_mirroring_switch) + { + NMT_AREA_BLK_INDEX[3] = data; + } + break; + case 57344: + Switch08KPRG(data & 0x3F, PRGArea.Area8000); + break; + case 59392: + Switch08KPRG(data & 0x3F, PRGArea.AreaA000); + disables_chr_ram_A = (data & 0x40) == 64; + disables_chr_ram_B = (data & 0x80) == 128; + break; + case 61440: + Switch08KPRG(data & 0x3F, PRGArea.AreaC000); + break; + case 63488: + soundReg = data; + break; + } + } + + internal override void ReadNMT(ref ushort address, out byte data) + { + if (enable_mirroring_switch) + { + temp_nmt = NMT_AREA_BLK_INDEX[(address >> 10) & 3]; + if (temp_nmt >= 224) + { + data = NMT_RAM[(temp_nmt - 224) & 1][address & 0x3FF]; + } + else + { + data = CHR_ROM[temp_nmt][address & 0x3FF]; + } + } + else + { + base.ReadNMT(ref address, out data); + } + } + + internal override void WriteNMT(ref ushort address, ref byte data) + { + if (enable_mirroring_switch) + { + temp_nmt = NMT_AREA_BLK_INDEX[(address >> 10) & 3]; + if (temp_nmt >= 224) + { + NMT_RAM[(temp_nmt - 224) & 1][address & 0x3FF] = data; + } + } + else + { + base.WriteNMT(ref address, ref data); + } + } + + internal override void OnCPUClock() + { + if (irq_enable) + { + if (irq_counter == 32767) + { + NesEmu.IRQFlags |= 8; + irq_counter = 0; + } + else + { + irq_counter++; + } + } + } + + internal override void OnAPUClockSingle() + { + if (sound_channels != null) + { + for (int i = 0; i < sound_channels.Length; i++) + { + sound_channels[i].ClockSingle(); + } + } + } + + internal override double APUGetSample() + { + soundOut = 0.0; + sound_out_div = 0; + if (enabledChannels > 0) + { + for (int i = 0; i < sound_channels.Length; i++) + { + if (sound_channels[i].Enabled && sound_channels_enable[i]) + { + if (sound_channels[i].clocks > 0) + { + sound_channels[i].output = sound_channels[i].output_av / sound_channels[i].clocks; + } + sound_channels[i].clocks = (sound_channels[i].output_av = 0); + soundOut += sound_channels[i].output; + sound_out_div++; + } + } + soundOut = soundOut / 8.0 / 225.0; + } + return soundOut; + } + + internal override void APUApplyChannelsSettings() + { + base.APUApplyChannelsSettings(); + sound_channels_enable[0] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT1; + sound_channels_enable[1] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT2; + sound_channels_enable[2] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT3; + sound_channels_enable[3] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT4; + sound_channels_enable[4] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT5; + sound_channels_enable[5] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT6; + sound_channels_enable[6] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT7; + sound_channels_enable[7] = MyNesMain.RendererSettings.Audio_ChannelEnabled_NMT8; + } + + internal override void WriteStateData(ref BinaryWriter stream) + { + base.WriteStateData(ref stream); + stream.Write(irq_counter); + stream.Write(irq_enable); + stream.Write(disables_chr_ram_A); + stream.Write(disables_chr_ram_B); + stream.Write(enable_mirroring_switch); + stream.Write(enable_N106_sound); + stream.Write(temp_nmt); + if (enable_N106_sound) + { + for (int i = 0; i < sound_channels.Length; i++) + { + sound_channels[i].SaveState(stream); + } + } + stream.Write(soundReg); + stream.Write(enabledChannels); + stream.Write(enabledChannels1); + stream.Write(channelIndex); + stream.Write(temp_val); + stream.Write(temp_i); + stream.Write(EXRAM); + } + + internal override void ReadStateData(ref BinaryReader stream) + { + base.ReadStateData(ref stream); + irq_counter = stream.ReadInt32(); + irq_enable = stream.ReadBoolean(); + disables_chr_ram_A = stream.ReadBoolean(); + disables_chr_ram_B = stream.ReadBoolean(); + enable_mirroring_switch = stream.ReadBoolean(); + enable_N106_sound = stream.ReadBoolean(); + temp_nmt = stream.ReadInt32(); + if (enable_N106_sound) + { + for (int i = 0; i < sound_channels.Length; i++) + { + sound_channels[i].LoadState(stream); + } + } + soundReg = stream.ReadByte(); + enabledChannels = stream.ReadInt32(); + enabledChannels1 = stream.ReadInt32(); + channelIndex = stream.ReadInt32(); + temp_val = stream.ReadByte(); + temp_i = stream.ReadByte(); + stream.Read(EXRAM, 0, EXRAM.Length); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Namcot106Chnl.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Namcot106Chnl.cs index ca27e69..594abac 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Namcot106Chnl.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Namcot106Chnl.cs @@ -1,157 +1,156 @@ -using System.IO; - -namespace MyNes.Core -{ - internal class Namcot106Chnl - { - private Namcot106 namcot; - - private int freqTimer; - - private int frequency; - - public int output; - - public int output_av; - - public int clocks; - - private int cycles; - - private int InstrumentLength; - - private byte InstrumentAddress; - - private int startPoint; - - private int endPoint; - - private int readPoint; - - public int volume; - - private bool freez; - - public bool Enabled { get; set; } - - public Namcot106Chnl(Namcot106 namcot) - { - this.namcot = namcot; - } - - public void HardReset() - { - } - - private void UpdateFrequency() - { - if (frequency > 0) - { - freqTimer = 983040 * (namcot.enabledChannels + 1) / frequency; - freez = false; - } - else - { - freez = true; - output_av = 0; - } - } - - private void UpdatePlaybackParameters() - { - startPoint = InstrumentAddress; - endPoint = InstrumentAddress + 4 * (8 - InstrumentLength); - readPoint = InstrumentAddress; - } - - public void WriteA(ref byte data) - { - frequency = (frequency & 0xFFFF00) | data; - UpdateFrequency(); - } - - public void WriteB(ref byte data) - { - frequency = (frequency & 0xFF00FF) | (data << 8); - UpdateFrequency(); - } - - public void WriteC(ref byte data) - { - frequency = (frequency & 0xFFFF) | ((data & 3) << 12); - InstrumentLength = (data >> 2) & 7; - UpdateFrequency(); - UpdatePlaybackParameters(); - } - - public void WriteD(ref byte data) - { - InstrumentAddress = data; - UpdatePlaybackParameters(); - } - - public void WriteE(ref byte data) - { - volume = data & 0xF; - } - - public void ClockSingle() - { - if (freez || --cycles > 0) - { - return; - } - cycles = freqTimer; - if (readPoint >= startPoint && readPoint <= endPoint) - { - if (Enabled && !freez) - { - if ((readPoint & 1) == 0) - { - output_av += (namcot.EXRAM[readPoint] & 0xF) * volume; - } - else - { - output_av += ((namcot.EXRAM[readPoint] >> 4) & 0xF) * volume; - } - } - readPoint++; - } - else - { - readPoint = startPoint; - } - clocks++; - } - - public void SaveState(BinaryWriter stream) - { - stream.Write(freqTimer); - stream.Write(frequency); - stream.Write(output); - stream.Write(cycles); - stream.Write(InstrumentLength); - stream.Write(InstrumentAddress); - stream.Write(startPoint); - stream.Write(endPoint); - stream.Write(readPoint); - stream.Write(volume); - stream.Write(freez); - } - - public void LoadState(BinaryReader stream) - { - freqTimer = stream.ReadInt32(); - frequency = stream.ReadInt32(); - output = stream.ReadByte(); - cycles = stream.ReadInt32(); - InstrumentLength = stream.ReadInt32(); - InstrumentAddress = stream.ReadByte(); - startPoint = stream.ReadInt32(); - endPoint = stream.ReadInt32(); - readPoint = stream.ReadInt32(); - volume = stream.ReadInt32(); - freez = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +internal class Namcot106Chnl +{ + private Namcot106 namcot; + + private int freqTimer; + + private int frequency; + + public int output; + + public int output_av; + + public int clocks; + + private int cycles; + + private int InstrumentLength; + + private byte InstrumentAddress; + + private int startPoint; + + private int endPoint; + + private int readPoint; + + public int volume; + + private bool freez; + + public bool Enabled { get; set; } + + public Namcot106Chnl(Namcot106 namcot) + { + this.namcot = namcot; + } + + public void HardReset() + { + } + + private void UpdateFrequency() + { + if (frequency > 0) + { + freqTimer = 983040 * (namcot.enabledChannels + 1) / frequency; + freez = false; + } + else + { + freez = true; + output_av = 0; + } + } + + private void UpdatePlaybackParameters() + { + startPoint = InstrumentAddress; + endPoint = InstrumentAddress + 4 * (8 - InstrumentLength); + readPoint = InstrumentAddress; + } + + public void WriteA(ref byte data) + { + frequency = (frequency & 0xFFFF00) | data; + UpdateFrequency(); + } + + public void WriteB(ref byte data) + { + frequency = (frequency & 0xFF00FF) | (data << 8); + UpdateFrequency(); + } + + public void WriteC(ref byte data) + { + frequency = (frequency & 0xFFFF) | ((data & 3) << 12); + InstrumentLength = (data >> 2) & 7; + UpdateFrequency(); + UpdatePlaybackParameters(); + } + + public void WriteD(ref byte data) + { + InstrumentAddress = data; + UpdatePlaybackParameters(); + } + + public void WriteE(ref byte data) + { + volume = data & 0xF; + } + + public void ClockSingle() + { + if (freez || --cycles > 0) + { + return; + } + cycles = freqTimer; + if (readPoint >= startPoint && readPoint <= endPoint) + { + if (Enabled && !freez) + { + if ((readPoint & 1) == 0) + { + output_av += (namcot.EXRAM[readPoint] & 0xF) * volume; + } + else + { + output_av += ((namcot.EXRAM[readPoint] >> 4) & 0xF) * volume; + } + } + readPoint++; + } + else + { + readPoint = startPoint; + } + clocks++; + } + + public void SaveState(BinaryWriter stream) + { + stream.Write(freqTimer); + stream.Write(frequency); + stream.Write(output); + stream.Write(cycles); + stream.Write(InstrumentLength); + stream.Write(InstrumentAddress); + stream.Write(startPoint); + stream.Write(endPoint); + stream.Write(readPoint); + stream.Write(volume); + stream.Write(freez); + } + + public void LoadState(BinaryReader stream) + { + freqTimer = stream.ReadInt32(); + frequency = stream.ReadInt32(); + output = stream.ReadByte(); + cycles = stream.ReadInt32(); + InstrumentLength = stream.ReadInt32(); + InstrumentAddress = stream.ReadByte(); + startPoint = stream.ReadInt32(); + endPoint = stream.ReadInt32(); + readPoint = stream.ReadInt32(); + volume = stream.ReadInt32(); + freez = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabase.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabase.cs index b9f109d..4d7e539 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabase.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabase.cs @@ -1,330 +1,329 @@ -using System.Collections.Generic; -using System.IO; -using System.Xml; - -namespace MyNes.Core -{ - public class NesCartDatabase - { - private static List _databaseRoms = new List(); - - public static string DBVersion = ""; - - public static string DBConformance = ""; - - public static string DBAgent = ""; - - public static string DBAuthor = ""; - - public static string DBTimeStamp = ""; - - public static bool Ready = false; - - public static List DatabaseRoms => _databaseRoms; - - public static void LoadDatabase(string fileName, out bool success) - { - success = false; - Ready = false; - if (!File.Exists(fileName)) - { - return; - } - _databaseRoms.Clear(); - Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); - XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); - xmlReaderSettings.DtdProcessing = DtdProcessing.Ignore; - xmlReaderSettings.IgnoreWhitespace = true; - XmlReader xmlReader = XmlReader.Create(stream, xmlReaderSettings); - NesCartDatabaseGameInfo nesCartDatabaseGameInfo = default(NesCartDatabaseGameInfo); - nesCartDatabaseGameInfo.Cartridges = new List(); - nesCartDatabaseGameInfo.Game_AltName = ""; - nesCartDatabaseGameInfo.Game_Catalog = ""; - nesCartDatabaseGameInfo.Game_Class = ""; - nesCartDatabaseGameInfo.Game_Developer = ""; - nesCartDatabaseGameInfo.Game_Name = ""; - nesCartDatabaseGameInfo.Game_Players = ""; - nesCartDatabaseGameInfo.Game_Publisher = ""; - nesCartDatabaseGameInfo.Game_Region = ""; - nesCartDatabaseGameInfo.Game_ReleaseDate = ""; - while (xmlReader.Read()) - { - if ((xmlReader.Name == "xml") & xmlReader.IsStartElement()) - { - if (xmlReader.MoveToAttribute("version")) - { - DBVersion = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("conformance")) - { - DBConformance = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("agent")) - { - DBAgent = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("author")) - { - DBAuthor = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("timestamp")) - { - DBTimeStamp = xmlReader.Value; - } - } - else - { - if (!((xmlReader.Name == "game") & xmlReader.IsStartElement())) - { - continue; - } - nesCartDatabaseGameInfo = default(NesCartDatabaseGameInfo); - if (xmlReader.MoveToAttribute("name")) - { - nesCartDatabaseGameInfo.Game_Name = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("altname")) - { - nesCartDatabaseGameInfo.Game_AltName = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("class")) - { - nesCartDatabaseGameInfo.Game_Class = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("catalog")) - { - nesCartDatabaseGameInfo.Game_Catalog = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("publisher")) - { - nesCartDatabaseGameInfo.Game_Publisher = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("developer")) - { - nesCartDatabaseGameInfo.Game_Developer = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("region")) - { - nesCartDatabaseGameInfo.Game_Region = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("players")) - { - nesCartDatabaseGameInfo.Game_Players = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("date")) - { - nesCartDatabaseGameInfo.Game_ReleaseDate = xmlReader.Value; - } - NesCartDatabaseCartridgeInfo nesCartDatabaseCartridgeInfo = new NesCartDatabaseCartridgeInfo(); - nesCartDatabaseCartridgeInfo.PAD_h = ""; - nesCartDatabaseCartridgeInfo.PAD_v = ""; - nesCartDatabaseCartridgeInfo.PRG_crc = ""; - nesCartDatabaseCartridgeInfo.PRG_name = ""; - nesCartDatabaseCartridgeInfo.PRG_sha1 = ""; - nesCartDatabaseCartridgeInfo.PRG_size = ""; - nesCartDatabaseCartridgeInfo.chip_type = new List(); - nesCartDatabaseCartridgeInfo.CHR_crc = ""; - nesCartDatabaseCartridgeInfo.CHR_name = ""; - nesCartDatabaseCartridgeInfo.CHR_sha1 = ""; - nesCartDatabaseCartridgeInfo.CHR_size = ""; - nesCartDatabaseCartridgeInfo.CIC_type = ""; - nesCartDatabaseCartridgeInfo.Board_Mapper = ""; - nesCartDatabaseCartridgeInfo.Board_Pcb = ""; - nesCartDatabaseCartridgeInfo.Board_Type = ""; - nesCartDatabaseCartridgeInfo.VRAM_sizes = new List(); - nesCartDatabaseCartridgeInfo.WRAMBanks = new List(); - while (xmlReader.Read()) - { - if ((xmlReader.Name == "game") & !xmlReader.IsStartElement()) - { - _databaseRoms.Add(nesCartDatabaseGameInfo); - break; - } - if ((xmlReader.Name == "cartridge") & xmlReader.IsStartElement()) - { - if (nesCartDatabaseGameInfo.Cartridges == null) - { - nesCartDatabaseGameInfo.Cartridges = new List(); - } - nesCartDatabaseCartridgeInfo = new NesCartDatabaseCartridgeInfo(); - nesCartDatabaseCartridgeInfo.PAD_h = ""; - nesCartDatabaseCartridgeInfo.PAD_v = ""; - nesCartDatabaseCartridgeInfo.PRG_crc = ""; - nesCartDatabaseCartridgeInfo.PRG_name = ""; - nesCartDatabaseCartridgeInfo.PRG_sha1 = ""; - nesCartDatabaseCartridgeInfo.PRG_size = ""; - nesCartDatabaseCartridgeInfo.chip_type = new List(); - nesCartDatabaseCartridgeInfo.CHR_crc = ""; - nesCartDatabaseCartridgeInfo.CHR_name = ""; - nesCartDatabaseCartridgeInfo.CHR_sha1 = ""; - nesCartDatabaseCartridgeInfo.CHR_size = ""; - nesCartDatabaseCartridgeInfo.CIC_type = ""; - nesCartDatabaseCartridgeInfo.Board_Mapper = ""; - nesCartDatabaseCartridgeInfo.Board_Pcb = ""; - nesCartDatabaseCartridgeInfo.Board_Type = ""; - nesCartDatabaseCartridgeInfo.VRAM_sizes = new List(); - nesCartDatabaseCartridgeInfo.WRAMBanks = new List(); - if (xmlReader.MoveToAttribute("system")) - { - nesCartDatabaseCartridgeInfo.System = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("crc")) - { - nesCartDatabaseCartridgeInfo.CRC = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("sha1")) - { - nesCartDatabaseCartridgeInfo.SHA1 = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("dump")) - { - nesCartDatabaseCartridgeInfo.Dump = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("dumper")) - { - nesCartDatabaseCartridgeInfo.Dumper = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("datedumped")) - { - nesCartDatabaseCartridgeInfo.DateDumped = xmlReader.Value; - } - } - else if ((xmlReader.Name == "cartridge") & !xmlReader.IsStartElement()) - { - nesCartDatabaseGameInfo.Cartridges.Add(nesCartDatabaseCartridgeInfo); - } - else if ((xmlReader.Name == "board") & xmlReader.IsStartElement()) - { - if (xmlReader.MoveToAttribute("type")) - { - nesCartDatabaseCartridgeInfo.Board_Type = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("pcb")) - { - nesCartDatabaseCartridgeInfo.Board_Pcb = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("mapper")) - { - nesCartDatabaseCartridgeInfo.Board_Mapper = xmlReader.Value; - } - } - else if ((xmlReader.Name == "prg") & xmlReader.IsStartElement()) - { - if (xmlReader.MoveToAttribute("name")) - { - nesCartDatabaseCartridgeInfo.PRG_name = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("size")) - { - nesCartDatabaseCartridgeInfo.PRG_size = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("crc")) - { - nesCartDatabaseCartridgeInfo.PRG_crc = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("sha1")) - { - nesCartDatabaseCartridgeInfo.PRG_sha1 = xmlReader.Value; - } - } - else if ((xmlReader.Name == "chr") & xmlReader.IsStartElement()) - { - if (xmlReader.MoveToAttribute("name")) - { - nesCartDatabaseCartridgeInfo.CHR_name = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("size")) - { - nesCartDatabaseCartridgeInfo.CHR_size = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("crc")) - { - nesCartDatabaseCartridgeInfo.CHR_crc = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("sha1")) - { - nesCartDatabaseCartridgeInfo.CHR_sha1 = xmlReader.Value; - } - } - else if ((xmlReader.Name == "vram") & xmlReader.IsStartElement()) - { - if (xmlReader.MoveToAttribute("size")) - { - nesCartDatabaseCartridgeInfo.VRAM_sizes.Add(xmlReader.Value); - } - } - else if ((xmlReader.Name == "wram") & xmlReader.IsStartElement()) - { - string sIZE = ""; - bool bATTERY = false; - int result = 0; - if (xmlReader.MoveToAttribute("size")) - { - sIZE = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("battery")) - { - bATTERY = xmlReader.Value == "1"; - } - if (xmlReader.MoveToAttribute("id")) - { - int.TryParse(xmlReader.Value, out result); - } - nesCartDatabaseCartridgeInfo.WRAMBanks.Add(new SRAMBankInfo(result, sIZE, bATTERY)); - } - else if ((xmlReader.Name == "chip") & xmlReader.IsStartElement()) - { - if (xmlReader.MoveToAttribute("type")) - { - if (nesCartDatabaseCartridgeInfo.chip_type == null) - { - nesCartDatabaseCartridgeInfo.chip_type = new List(); - } - nesCartDatabaseCartridgeInfo.chip_type.Add(xmlReader.Value); - } - } - else if ((xmlReader.Name == "cic") & xmlReader.IsStartElement()) - { - if (xmlReader.MoveToAttribute("type")) - { - nesCartDatabaseCartridgeInfo.CIC_type = xmlReader.Value; - } - } - else if ((xmlReader.Name == "pad") & xmlReader.IsStartElement()) - { - if (xmlReader.MoveToAttribute("h")) - { - nesCartDatabaseCartridgeInfo.PAD_h = xmlReader.Value; - } - if (xmlReader.MoveToAttribute("v")) - { - nesCartDatabaseCartridgeInfo.PAD_v = xmlReader.Value; - } - } - } - } - } - Ready = true; - success = true; - xmlReader.Close(); - stream.Close(); - } - - public static NesCartDatabaseGameInfo Find(string Cart_sha1, out bool found) - { - found = false; - foreach (NesCartDatabaseGameInfo databaseRom in _databaseRoms) - { - foreach (NesCartDatabaseCartridgeInfo cartridge in databaseRom.Cartridges) - { - if (cartridge.SHA1.ToLower() == Cart_sha1.ToLower()) - { - found = true; - return databaseRom; - } - } - } - return default(NesCartDatabaseGameInfo); - } - } +using System.Collections.Generic; +using System.IO; +using System.Xml; + +namespace MyNes.Core; + +public class NesCartDatabase +{ + private static List _databaseRoms = new List(); + + public static string DBVersion = ""; + + public static string DBConformance = ""; + + public static string DBAgent = ""; + + public static string DBAuthor = ""; + + public static string DBTimeStamp = ""; + + public static bool Ready = false; + + public static List DatabaseRoms => _databaseRoms; + + public static void LoadDatabase(string fileName, out bool success) + { + success = false; + Ready = false; + if (!File.Exists(fileName)) + { + return; + } + _databaseRoms.Clear(); + Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); + XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); + xmlReaderSettings.DtdProcessing = DtdProcessing.Ignore; + xmlReaderSettings.IgnoreWhitespace = true; + XmlReader xmlReader = XmlReader.Create(stream, xmlReaderSettings); + NesCartDatabaseGameInfo nesCartDatabaseGameInfo = default(NesCartDatabaseGameInfo); + nesCartDatabaseGameInfo.Cartridges = new List(); + nesCartDatabaseGameInfo.Game_AltName = ""; + nesCartDatabaseGameInfo.Game_Catalog = ""; + nesCartDatabaseGameInfo.Game_Class = ""; + nesCartDatabaseGameInfo.Game_Developer = ""; + nesCartDatabaseGameInfo.Game_Name = ""; + nesCartDatabaseGameInfo.Game_Players = ""; + nesCartDatabaseGameInfo.Game_Publisher = ""; + nesCartDatabaseGameInfo.Game_Region = ""; + nesCartDatabaseGameInfo.Game_ReleaseDate = ""; + while (xmlReader.Read()) + { + if ((xmlReader.Name == "xml") & xmlReader.IsStartElement()) + { + if (xmlReader.MoveToAttribute("version")) + { + DBVersion = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("conformance")) + { + DBConformance = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("agent")) + { + DBAgent = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("author")) + { + DBAuthor = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("timestamp")) + { + DBTimeStamp = xmlReader.Value; + } + } + else + { + if (!((xmlReader.Name == "game") & xmlReader.IsStartElement())) + { + continue; + } + nesCartDatabaseGameInfo = default(NesCartDatabaseGameInfo); + if (xmlReader.MoveToAttribute("name")) + { + nesCartDatabaseGameInfo.Game_Name = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("altname")) + { + nesCartDatabaseGameInfo.Game_AltName = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("class")) + { + nesCartDatabaseGameInfo.Game_Class = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("catalog")) + { + nesCartDatabaseGameInfo.Game_Catalog = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("publisher")) + { + nesCartDatabaseGameInfo.Game_Publisher = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("developer")) + { + nesCartDatabaseGameInfo.Game_Developer = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("region")) + { + nesCartDatabaseGameInfo.Game_Region = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("players")) + { + nesCartDatabaseGameInfo.Game_Players = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("date")) + { + nesCartDatabaseGameInfo.Game_ReleaseDate = xmlReader.Value; + } + NesCartDatabaseCartridgeInfo nesCartDatabaseCartridgeInfo = new NesCartDatabaseCartridgeInfo(); + nesCartDatabaseCartridgeInfo.PAD_h = ""; + nesCartDatabaseCartridgeInfo.PAD_v = ""; + nesCartDatabaseCartridgeInfo.PRG_crc = ""; + nesCartDatabaseCartridgeInfo.PRG_name = ""; + nesCartDatabaseCartridgeInfo.PRG_sha1 = ""; + nesCartDatabaseCartridgeInfo.PRG_size = ""; + nesCartDatabaseCartridgeInfo.chip_type = new List(); + nesCartDatabaseCartridgeInfo.CHR_crc = ""; + nesCartDatabaseCartridgeInfo.CHR_name = ""; + nesCartDatabaseCartridgeInfo.CHR_sha1 = ""; + nesCartDatabaseCartridgeInfo.CHR_size = ""; + nesCartDatabaseCartridgeInfo.CIC_type = ""; + nesCartDatabaseCartridgeInfo.Board_Mapper = ""; + nesCartDatabaseCartridgeInfo.Board_Pcb = ""; + nesCartDatabaseCartridgeInfo.Board_Type = ""; + nesCartDatabaseCartridgeInfo.VRAM_sizes = new List(); + nesCartDatabaseCartridgeInfo.WRAMBanks = new List(); + while (xmlReader.Read()) + { + if ((xmlReader.Name == "game") & !xmlReader.IsStartElement()) + { + _databaseRoms.Add(nesCartDatabaseGameInfo); + break; + } + if ((xmlReader.Name == "cartridge") & xmlReader.IsStartElement()) + { + if (nesCartDatabaseGameInfo.Cartridges == null) + { + nesCartDatabaseGameInfo.Cartridges = new List(); + } + nesCartDatabaseCartridgeInfo = new NesCartDatabaseCartridgeInfo(); + nesCartDatabaseCartridgeInfo.PAD_h = ""; + nesCartDatabaseCartridgeInfo.PAD_v = ""; + nesCartDatabaseCartridgeInfo.PRG_crc = ""; + nesCartDatabaseCartridgeInfo.PRG_name = ""; + nesCartDatabaseCartridgeInfo.PRG_sha1 = ""; + nesCartDatabaseCartridgeInfo.PRG_size = ""; + nesCartDatabaseCartridgeInfo.chip_type = new List(); + nesCartDatabaseCartridgeInfo.CHR_crc = ""; + nesCartDatabaseCartridgeInfo.CHR_name = ""; + nesCartDatabaseCartridgeInfo.CHR_sha1 = ""; + nesCartDatabaseCartridgeInfo.CHR_size = ""; + nesCartDatabaseCartridgeInfo.CIC_type = ""; + nesCartDatabaseCartridgeInfo.Board_Mapper = ""; + nesCartDatabaseCartridgeInfo.Board_Pcb = ""; + nesCartDatabaseCartridgeInfo.Board_Type = ""; + nesCartDatabaseCartridgeInfo.VRAM_sizes = new List(); + nesCartDatabaseCartridgeInfo.WRAMBanks = new List(); + if (xmlReader.MoveToAttribute("system")) + { + nesCartDatabaseCartridgeInfo.System = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("crc")) + { + nesCartDatabaseCartridgeInfo.CRC = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("sha1")) + { + nesCartDatabaseCartridgeInfo.SHA1 = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("dump")) + { + nesCartDatabaseCartridgeInfo.Dump = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("dumper")) + { + nesCartDatabaseCartridgeInfo.Dumper = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("datedumped")) + { + nesCartDatabaseCartridgeInfo.DateDumped = xmlReader.Value; + } + } + else if ((xmlReader.Name == "cartridge") & !xmlReader.IsStartElement()) + { + nesCartDatabaseGameInfo.Cartridges.Add(nesCartDatabaseCartridgeInfo); + } + else if ((xmlReader.Name == "board") & xmlReader.IsStartElement()) + { + if (xmlReader.MoveToAttribute("type")) + { + nesCartDatabaseCartridgeInfo.Board_Type = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("pcb")) + { + nesCartDatabaseCartridgeInfo.Board_Pcb = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("mapper")) + { + nesCartDatabaseCartridgeInfo.Board_Mapper = xmlReader.Value; + } + } + else if ((xmlReader.Name == "prg") & xmlReader.IsStartElement()) + { + if (xmlReader.MoveToAttribute("name")) + { + nesCartDatabaseCartridgeInfo.PRG_name = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("size")) + { + nesCartDatabaseCartridgeInfo.PRG_size = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("crc")) + { + nesCartDatabaseCartridgeInfo.PRG_crc = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("sha1")) + { + nesCartDatabaseCartridgeInfo.PRG_sha1 = xmlReader.Value; + } + } + else if ((xmlReader.Name == "chr") & xmlReader.IsStartElement()) + { + if (xmlReader.MoveToAttribute("name")) + { + nesCartDatabaseCartridgeInfo.CHR_name = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("size")) + { + nesCartDatabaseCartridgeInfo.CHR_size = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("crc")) + { + nesCartDatabaseCartridgeInfo.CHR_crc = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("sha1")) + { + nesCartDatabaseCartridgeInfo.CHR_sha1 = xmlReader.Value; + } + } + else if ((xmlReader.Name == "vram") & xmlReader.IsStartElement()) + { + if (xmlReader.MoveToAttribute("size")) + { + nesCartDatabaseCartridgeInfo.VRAM_sizes.Add(xmlReader.Value); + } + } + else if ((xmlReader.Name == "wram") & xmlReader.IsStartElement()) + { + string sIZE = ""; + bool bATTERY = false; + int result = 0; + if (xmlReader.MoveToAttribute("size")) + { + sIZE = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("battery")) + { + bATTERY = xmlReader.Value == "1"; + } + if (xmlReader.MoveToAttribute("id")) + { + int.TryParse(xmlReader.Value, out result); + } + nesCartDatabaseCartridgeInfo.WRAMBanks.Add(new SRAMBankInfo(result, sIZE, bATTERY)); + } + else if ((xmlReader.Name == "chip") & xmlReader.IsStartElement()) + { + if (xmlReader.MoveToAttribute("type")) + { + if (nesCartDatabaseCartridgeInfo.chip_type == null) + { + nesCartDatabaseCartridgeInfo.chip_type = new List(); + } + nesCartDatabaseCartridgeInfo.chip_type.Add(xmlReader.Value); + } + } + else if ((xmlReader.Name == "cic") & xmlReader.IsStartElement()) + { + if (xmlReader.MoveToAttribute("type")) + { + nesCartDatabaseCartridgeInfo.CIC_type = xmlReader.Value; + } + } + else if ((xmlReader.Name == "pad") & xmlReader.IsStartElement()) + { + if (xmlReader.MoveToAttribute("h")) + { + nesCartDatabaseCartridgeInfo.PAD_h = xmlReader.Value; + } + if (xmlReader.MoveToAttribute("v")) + { + nesCartDatabaseCartridgeInfo.PAD_v = xmlReader.Value; + } + } + } + } + } + Ready = true; + success = true; + xmlReader.Close(); + stream.Close(); + } + + public static NesCartDatabaseGameInfo Find(string Cart_sha1, out bool found) + { + found = false; + foreach (NesCartDatabaseGameInfo databaseRom in _databaseRoms) + { + foreach (NesCartDatabaseCartridgeInfo cartridge in databaseRom.Cartridges) + { + if (cartridge.SHA1.ToLower() == Cart_sha1.ToLower()) + { + found = true; + return databaseRom; + } + } + } + return default(NesCartDatabaseGameInfo); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabaseCartridgeInfo.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabaseCartridgeInfo.cs index 49dd6bd..82ecd93 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabaseCartridgeInfo.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabaseCartridgeInfo.cs @@ -1,53 +1,52 @@ -using System.Collections.Generic; - -namespace MyNes.Core -{ - public class NesCartDatabaseCartridgeInfo - { - public string System; - - public string CRC; - - public string SHA1; - - public string Dump; - - public string Dumper; - - public string DateDumped; - - public string Board_Type; - - public string Board_Pcb; - - public string Board_Mapper; - - public List VRAM_sizes; - - public List WRAMBanks; - - public string PRG_name; - - public string PRG_size; - - public string PRG_crc; - - public string PRG_sha1; - - public string CHR_name; - - public string CHR_size; - - public string CHR_crc; - - public string CHR_sha1; - - public List chip_type; - - public string CIC_type; - - public string PAD_h; - - public string PAD_v; - } +using System.Collections.Generic; + +namespace MyNes.Core; + +public class NesCartDatabaseCartridgeInfo +{ + public string System; + + public string CRC; + + public string SHA1; + + public string Dump; + + public string Dumper; + + public string DateDumped; + + public string Board_Type; + + public string Board_Pcb; + + public string Board_Mapper; + + public List VRAM_sizes; + + public List WRAMBanks; + + public string PRG_name; + + public string PRG_size; + + public string PRG_crc; + + public string PRG_sha1; + + public string CHR_name; + + public string CHR_size; + + public string CHR_crc; + + public string CHR_sha1; + + public List chip_type; + + public string CIC_type; + + public string PAD_h; + + public string PAD_v; } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabaseGameInfo.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabaseGameInfo.cs index 00f4376..c04c9b6 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabaseGameInfo.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesCartDatabaseGameInfo.cs @@ -1,29 +1,28 @@ -using System.Collections.Generic; - -namespace MyNes.Core -{ - public struct NesCartDatabaseGameInfo - { - public string Game_Name; - - public string Game_AltName; - - public string Game_Class; - - public string Game_Catalog; - - public string Game_Publisher; - - public string Game_Developer; - - public string Game_Region; - - public string Game_Players; - - public string Game_ReleaseDate; - - public List Cartridges; - - public static NesCartDatabaseGameInfo Empty => default(NesCartDatabaseGameInfo); - } +using System.Collections.Generic; + +namespace MyNes.Core; + +public struct NesCartDatabaseGameInfo +{ + public string Game_Name; + + public string Game_AltName; + + public string Game_Class; + + public string Game_Catalog; + + public string Game_Publisher; + + public string Game_Developer; + + public string Game_Region; + + public string Game_Players; + + public string Game_ReleaseDate; + + public List Cartridges; + + public static NesCartDatabaseGameInfo Empty => default(NesCartDatabaseGameInfo); } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesEmu.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesEmu.cs index d6bfc26..df2c565 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/NesEmu.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/NesEmu.cs @@ -1,5939 +1,5812 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Threading; -using System.Xml; - -namespace MyNes.Core -{ - public class NesEmu - { - [StructLayout(LayoutKind.Explicit)] - private struct CPURegister - { - [FieldOffset(0)] - internal byte l; - - [FieldOffset(1)] - internal byte h; - - [FieldOffset(0)] - internal ushort v; - } - - private enum RequestMode - { - None, - HardReset, - SoftReset, - LoadState, - SaveState, - TakeSnapshot - } - - private static int[][] dmc_freq_table = new int[3][] - { - new int[16] - { - 428, 380, 340, 320, 286, 254, 226, 214, 190, 160, - 142, 128, 106, 84, 72, 54 - }, - new int[16] - { - 398, 354, 316, 298, 276, 236, 210, 198, 176, 148, - 132, 118, 98, 78, 66, 50 - }, - new int[16] - { - 428, 380, 340, 320, 286, 254, 226, 214, 190, 160, - 142, 128, 106, 84, 72, 54 - } - }; - - private static int dmc_output_a; - - private static int dmc_output; - - private static int dmc_period_devider; - - private static bool dmc_irq_enabled; - - private static bool dmc_loop_flag; - - private static byte dmc_rate_index; - - private static ushort dmc_addr_refresh; - - private static int dmc_size_refresh; - - private static bool dmc_dmaEnabled; - - private static byte dmc_dmaByte; - - private static int dmc_dmaBits; - - private static bool dmc_bufferFull; - - private static byte dmc_dmaBuffer; - - private static int dmc_dmaSize; - - private static ushort dmc_dmaAddr; - - private static ushort[][] nos_freq_table = new ushort[3][] - { - new ushort[16] - { - 4, 8, 16, 32, 64, 96, 128, 160, 202, 254, - 380, 508, 762, 1016, 2034, 4068 - }, - new ushort[16] - { - 4, 7, 14, 30, 60, 88, 118, 148, 188, 236, - 354, 472, 708, 944, 1890, 3778 - }, - new ushort[16] - { - 4, 8, 16, 32, 64, 96, 128, 160, 202, 254, - 380, 508, 762, 1016, 2034, 4068 - } - }; - - private static bool nos_length_halt; - - private static bool nos_constant_volume_envelope; - - private static byte nos_volume_devider_period; - - private static ushort nos_timer; - - private static bool nos_mode; - - private static int nos_period_devider; - - private static bool nos_length_enabled; - - private static int nos_length_counter; - - private static bool nos_envelope_start_flag; - - private static byte nos_envelope_devider; - - private static byte nos_envelope_decay_level_counter; - - private static byte nos_envelope; - - private static int nos_output; - - private static int nos_shift_reg; - - private static int nos_feedback; - - private static bool nos_ignore_reload; - - private static byte[][] sq_duty_cycle_sequences = new byte[4][] - { - new byte[8] { 0, 0, 0, 0, 0, 0, 0, 1 }, - new byte[8] { 0, 0, 0, 0, 0, 0, 1, 1 }, - new byte[8] { 0, 0, 0, 0, 1, 1, 1, 1 }, - new byte[8] { 1, 1, 1, 1, 1, 1, 0, 0 } - }; - - private static byte[] sq_duration_table = new byte[32] - { - 10, 254, 20, 2, 40, 4, 80, 6, 160, 8, - 60, 10, 14, 12, 26, 14, 12, 16, 24, 18, - 48, 20, 96, 22, 192, 24, 72, 26, 16, 28, - 32, 30 - }; - - private static byte sq1_duty_cycle; - - private static bool sq1_length_halt; - - private static bool sq1_constant_volume_envelope; - - private static byte sq1_volume_devider_period; - - private static bool sq1_sweep_enable; - - private static byte sq1_sweep_devider_period; - - private static bool sq1_sweep_negate; - - private static byte sq1_sweep_shift_count; - - private static int sq1_timer; - - private static int sq1_period_devider; - - private static byte sq1_seqencer; - - private static bool sq1_length_enabled; - - private static int sq1_length_counter; - - private static bool sq1_envelope_start_flag; - - private static byte sq1_envelope_devider; - - private static byte sq1_envelope_decay_level_counter; - - private static byte sq1_envelope; - - private static int sq1_sweep_counter; - - private static bool sq1_sweep_reload; - - private static int sq1_sweep_change; - - private static bool sq1_valid_freq; - - private static int sq1_output; - - private static bool sq1_ignore_reload; - - private static byte[] trl_step_seq = new byte[32] - { - 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, - 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15 - }; - - private static bool trl_liner_control_flag; - - private static byte trl_liner_control_reload; - - private static ushort trl_timer; - - private static bool trl_length_enabled; - - private static byte trl_length_counter; - - private static bool trl_liner_control_reload_flag; - - private static byte trl_liner_counter; - - private static int trl_output; - - private static int trl_period_devider; - - private static int trl_step; - - private static bool trl_ignore_reload; - - private static byte apu_reg_io_db; - - private static byte apu_reg_io_addr; - - private static bool apu_reg_access_happened; - - private static bool apu_reg_access_w; - - private static Action[] apu_reg_update_func; - - private static Action[] apu_reg_read_func; - - private static Action[] apu_reg_write_func; - - private static Action apu_update_playback_func; - - private static bool apu_odd_cycle; - - private static bool apu_irq_enabled; - - private static bool apu_irq_flag; - - private static bool apu_irq_do_it; - - internal static bool apu_irq_delta_occur; - - private static bool apu_seq_mode; - - private static int apu_ferq_f; - - private static int apu_ferq_l; - - private static int apu_ferq_e; - - private static int apu_cycle_f; - - private static int apu_cycle_f_t; - - private static int apu_cycle_e; - - private static int apu_cycle_l; - - private static bool apu_odd_l; - - private static bool apu_check_irq; - - private static bool apu_do_env; - - private static bool apu_do_length; - - public static bool SoundEnabled; - - public static double audio_playback_amplitude = 1.5; - - public static int audio_playback_peek_limit = 124; - - private static bool audio_playback_dac_initialized; - - public static double cpu_speed; - - public static double cpu_clock_per_frame; - - internal static double apu_target_samples_count_per_frame; - - private static short[] audio_samples; - - private static int audio_w_pos; - - private static int audio_samples_added; - - internal static int audio_samples_count; - - private static int[][][][][] mix_table; - - private static double audio_x; - - private static double audio_y; - - private static double audio_y_av; - - private static double audio_y_timer; - - public static double audio_timer_ratio = 40.0; - - private static double audio_timer; - - private static SoundLowPassFilter audio_low_pass_filter_14K; - - private static SoundHighPassFilter audio_high_pass_filter_90; - - private static SoundHighPassFilter audio_high_pass_filter_440; - - private static SoundDCBlockerFilter audio_dc_blocker_filter; - - private static bool audio_sq1_outputable; - - private static bool audio_sq2_outputable; - - private static bool audio_nos_outputable; - - private static bool audio_trl_outputable; - - private static bool audio_dmc_outputable; - - private static bool audio_signal_outputed; - - private static bool apu_use_external_sound; - - private static CPURegister cpu_reg_pc; - - private static CPURegister cpu_reg_sp; - - private static CPURegister cpu_reg_ea; - - private static byte cpu_reg_a; - - private static byte cpu_reg_x; - - private static byte cpu_reg_y; - - private static bool cpu_flag_n; - - private static bool cpu_flag_v; - - private static bool cpu_flag_d; - - private static bool cpu_flag_i; - - private static bool cpu_flag_z; - - private static bool cpu_flag_c; - - private static byte cpu_m; - - private static byte cpu_opcode; - - private static byte cpu_byte_temp; - - private static int cpu_int_temp; - - private static int cpu_int_temp1; - - private static byte cpu_dummy; - - private static bool cpu_bool_tmp; - - private static CPURegister temp_add; - - private static bool CPU_IRQ_PIN; - - private static bool CPU_NMI_PIN; - - private static bool cpu_suspend_nmi; - - private static bool cpu_suspend_irq; - - private static Action[] cpu_addressings; - - private static Action[] cpu_instructions; - - private static int dma_DMCDMAWaitCycles; - - private static int dma_OAMDMAWaitCycles; - - private static bool dma_isOamDma; - - private static int dma_oamdma_i; - - private static bool dma_DMCOn; - - private static bool dma_OAMOn; - - private static bool dma_DMC_occurring; - - private static bool dma_OAM_occurring; - - private static int dma_OAMFinishCounter; - - private static ushort dma_Oamaddress; - - private static int dma_OAMCYCLE; - - private static byte dma_latch; - - private static byte dma_dummy; - - private static ushort reg_2004; - - internal static int IRQFlags = 0; - - private static bool PPU_NMI_Current; - - private static bool PPU_NMI_Old; - - private const int IRQ_APU = 1; - - internal const int IRQ_DMC = 2; - - internal const int IRQ_BOARD = 8; - - private static ushort InterruptVector; - - private static byte[] mem_wram; - - internal static Board mem_board; - - private static MemReadAccess[] mem_read_accesses; - - private static MemWriteAccess[] mem_write_accesses; - - private static bool BUS_RW; - - private static ushort BUS_ADDRESS; - - private static string SRAMFileName; - - public static string GMFileName; - - private static int PORT0; - - private static int PORT1; - - private static int inputStrobe; - - private static IJoypadConnecter joypad1; - - private static IJoypadConnecter joypad2; - - private static IJoypadConnecter joypad3; - - private static IJoypadConnecter joypad4; - - private static IShortcutsHandler shortucts; - - public static bool IsFourPlayers; - - private static byte[] reverseLookup = new byte[256] - { - 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, - 80, 208, 48, 176, 112, 240, 8, 136, 72, 200, - 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, - 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, - 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, - 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, - 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, - 98, 226, 18, 146, 82, 210, 50, 178, 114, 242, - 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, - 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, - 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, - 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, - 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, - 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, - 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, - 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, - 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, - 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, - 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, - 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, - 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, - 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, - 59, 187, 123, 251, 7, 135, 71, 199, 39, 167, - 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, - 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, - 95, 223, 63, 191, 127, 255 - }; - - private static Action[] ppu_v_clocks; - - private static Action[] ppu_h_clocks; - - private static Action[] ppu_bkg_fetches; - - private static Action[] ppu_spr_fetches; - - private static Action[] ppu_oam_phases; - - private static int[] ppu_bkg_pixels; - - private static int[] ppu_spr_pixels; - - private static int[] ppu_screen_pixels; - - private static int ppu_clock_h; - - internal static ushort ppu_clock_v; - - private static ushort ppu_clock_vblank_start; - - private static ushort ppu_clock_vblank_end; - - private static bool ppu_use_odd_cycle; - - private static bool ppu_use_odd_swap; - - private static bool ppu_odd_swap_done; - - private static bool ppu_is_nmi_time; - - private static bool ppu_frame_finished; - - private static byte[] ppu_oam_bank; - - private static byte[] ppu_oam_bank_secondary; - - private static byte[] ppu_palette_bank; - - private static byte ppu_reg_io_db; - - private static byte ppu_reg_io_addr; - - private static bool ppu_reg_access_happened; - - private static bool ppu_reg_access_w; - - private static Action[] ppu_reg_update_func; - - private static Action[] ppu_reg_read_func; - - private static byte ppu_reg_2000_vram_address_increament; - - private static ushort ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites; - - private static ushort ppu_reg_2000_background_pattern_table_address; - - internal static byte ppu_reg_2000_Sprite_size; - - private static bool ppu_reg_2000_VBI; - - private static bool ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen; - - private static bool ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen; - - private static bool ppu_reg_2001_show_background; - - private static bool ppu_reg_2001_show_sprites; - - private static bool ppu_reg_2001_grayscale; - - private static int ppu_reg_2001_emphasis; - - private static bool ppu_reg_2002_SpriteOverflow; - - private static bool ppu_reg_2002_Sprite0Hit; - - private static bool ppu_reg_2002_VblankStartedFlag; - - private static byte ppu_reg_2003_oam_addr; - - private static ushort ppu_vram_addr; - - private static byte ppu_vram_data; - - private static ushort ppu_vram_addr_temp; - - private static ushort ppu_vram_addr_access_temp; - - private static bool ppu_vram_flip_flop; - - private static byte ppu_vram_finex; - - private static ushort ppu_bkgfetch_nt_addr; - - private static byte ppu_bkgfetch_nt_data; - - private static ushort ppu_bkgfetch_at_addr; - - private static byte ppu_bkgfetch_at_data; - - private static ushort ppu_bkgfetch_lb_addr; - - private static byte ppu_bkgfetch_lb_data; - - private static ushort ppu_bkgfetch_hb_addr; - - private static byte ppu_bkgfetch_hb_data; - - private static int ppu_sprfetch_slot; - - private static byte ppu_sprfetch_y_data; - - private static byte ppu_sprfetch_t_data; - - private static byte ppu_sprfetch_at_data; - - private static byte ppu_sprfetch_x_data; - - private static ushort ppu_sprfetch_lb_addr; - - private static byte ppu_sprfetch_lb_data; - - private static ushort ppu_sprfetch_hb_addr; - - private static byte ppu_sprfetch_hb_data; - - internal static bool ppu_is_sprfetch; - - private static int ppu_bkg_render_i; - - private static int ppu_bkg_render_pos; - - private static int ppu_bkg_render_tmp_val; - - private static int ppu_bkg_current_pixel; - - private static int ppu_spr_current_pixel; - - private static int ppu_current_pixel; - - private static int ppu_render_x; - - private static int ppu_render_y; - - private static byte ppu_oamev_n; - - private static byte ppu_oamev_m; - - private static bool ppu_oamev_compare; - - private static byte ppu_oamev_slot; - - private static byte ppu_fetch_data; - - private static byte ppu_phase_index; - - private static bool ppu_sprite0_should_hit; - - private static int ppu_palette_temp__val; - - private static int ppu_color_temp__level; - - private static int ppu_color_temp__red; - - private static int ppu_color_temp__blue; - - private static int ppu_color_temp__green; - - private static bool ppu_color_temp__e_red; - - private static bool ppu_color_temp__e_blue; - - private static bool ppu_color_temp__e_green; - - private static byte[] ppu_color_temp_blue__sequence = new byte[16] - { - 7, 7, 6, 5, 4, 3, 2, 1, 2, 3, - 4, 5, 6, 0, 0, 0 - }; - - private static byte[] ppu_color_temp_red___sequence = new byte[16] - { - 7, 1, 2, 3, 4, 5, 6, 7, 6, 5, - 4, 3, 2, 0, 0, 0 - }; - - private static byte[] ppu_color_temp_green_sequence = new byte[16] - { - 7, 0, 0, 0, 1, 2, 3, 4, 5, 6, - 7, 6, 5, 0, 0, 0 - }; - - private static int ppu_temp_comparator; - - public static bool ON; - - public static bool PAUSED; - - public static bool isPaused; - - public static string CurrentFilePath; - - public static bool FrameLimiterEnabled; - - private static Thread mainThread; - - private static double fps_time_last; - - private static double fps_time_start; - - private static double fps_time_token; - - private static double fps_time_dead; - - private static double fps_time_period; - - private static double fps_time_frame_time; - - private static double emu_time_target_fps = 60.0; - - private static bool emu_frame_clocking_mode; - - private static bool emu_frame_done; - - private static bool render_initialized; - - private static RenderVideoFrame render_video; - - private static RenderAudioSamples render_audio; - - private static TogglePause render_audio_toggle_pause; - - private static GetIsPlaying render_audio_get_is_playing; - - private static bool render_audio_is_playing; - - public static EmuRegion Region; - - internal static Action EmuClockComponents; - - internal static int pal_add_cycle = 0; - - private static int SystemIndex; - - private static RequestMode emu_request_mode = RequestMode.None; - - public static bool FrameSkipEnabled; - - public static int FrameSkipInterval; - - private static int FrameSkipCounter; - - private static byte sq2_duty_cycle; - - private static bool sq2_length_halt; - - private static bool sq2_constant_volume_envelope; - - private static byte sq2_volume_devider_period; - - private static bool sq2_sweep_enable; - - private static byte sq2_sweep_devider_period; - - private static bool sq2_sweep_negate; - - private static byte sq2_sweep_shift_count; - - private static int sq2_timer; - - private static int sq2_period_devider; - - private static byte sq2_seqencer; - - private static bool sq2_length_enabled; - - private static int sq2_length_counter; - - private static bool sq2_envelope_start_flag; - - private static byte sq2_envelope_devider; - - private static byte sq2_envelope_decay_level_counter; - - private static byte sq2_envelope; - - private static int sq2_sweep_counter; - - private static bool sq2_sweep_reload; - - private static int sq2_sweep_change; - - private static bool sq2_valid_freq; - - private static int sq2_output; - - private static bool sq2_ignore_reload; - - private static byte register_p - { - get - { - return (byte)((cpu_flag_n ? 128u : 0u) | (cpu_flag_v ? 64u : 0u) | (cpu_flag_d ? 8u : 0u) | (cpu_flag_i ? 4u : 0u) | (cpu_flag_z ? 2u : 0u) | (cpu_flag_c ? 1u : 0u) | 0x20u); - } - set - { - cpu_flag_n = (value & 0x80) != 0; - cpu_flag_v = (value & 0x40) != 0; - cpu_flag_d = (value & 8) != 0; - cpu_flag_i = (value & 4) != 0; - cpu_flag_z = (value & 2) != 0; - cpu_flag_c = (value & 1) != 0; - } - } - - public static GameGenieCode[] GameGenieCodes - { - get - { - if (mem_board != null) - { - return mem_board.GameGenieCodes; - } - return null; - } - } - - public static bool IsGameGenieActive - { - get - { - if (mem_board != null) - { - return mem_board.IsGameGenieActive; - } - return false; - } - set - { - if (mem_board != null) - { - mem_board.IsGameGenieActive = value; - } - } - } - - public static bool IsGameFoundOnDB - { - get - { - if (mem_board != null) - { - return mem_board.IsGameFoundOnDB; - } - return false; - } - } - - public static NesCartDatabaseGameInfo GameInfo - { - get - { - if (mem_board != null) - { - return mem_board.GameInfo; - } - return NesCartDatabaseGameInfo.Empty; - } - } - - public static NesCartDatabaseCartridgeInfo GameCartInfo - { - get - { - if (mem_board != null) - { - return mem_board.GameCartInfo; - } - return new NesCartDatabaseCartridgeInfo(); - } - } - - public static string SHA1 => mem_board.SHA1; - - public static event EventHandler EmuShutdown; - - private static void DMCHardReset() - { - dmc_output_a = 0; - dmc_output = 0; - dmc_period_devider = 0; - dmc_loop_flag = false; - dmc_rate_index = 0; - dmc_irq_enabled = false; - dmc_dmaAddr = 49152; - dmc_addr_refresh = 49152; - dmc_size_refresh = 0; - dmc_dmaBits = 1; - dmc_dmaByte = 1; - dmc_period_devider = 0; - dmc_dmaEnabled = false; - dmc_bufferFull = false; - dmc_dmaSize = 0; - } - - private static void DMCSoftReset() - { - DMCHardReset(); - } - - private static void DMCClock() - { - dmc_period_devider--; - if (dmc_period_devider > 0) - { - return; - } - dmc_period_devider = dmc_freq_table[SystemIndex][dmc_rate_index]; - if (dmc_dmaEnabled) - { - if (((uint)dmc_dmaByte & (true ? 1u : 0u)) != 0) - { - if (dmc_output_a <= 125) - { - dmc_output_a += 2; - } - } - else if (dmc_output_a >= 2) - { - dmc_output_a -= 2; - } - dmc_dmaByte >>= 1; - } - dmc_dmaBits--; - if (dmc_dmaBits == 0) - { - dmc_dmaBits = 8; - if (dmc_bufferFull) - { - dmc_bufferFull = false; - dmc_dmaEnabled = true; - dmc_dmaByte = dmc_dmaBuffer; - if (dmc_dmaSize > 0) - { - AssertDMCDMA(); - } - } - else - { - dmc_dmaEnabled = false; - } - } - if (audio_dmc_outputable) - { - dmc_output = dmc_output_a; - } - audio_signal_outputed = true; - } - - private static void DMCDoDMA() - { - dmc_bufferFull = true; - Read(ref dmc_dmaAddr, out dmc_dmaBuffer); - if (dmc_dmaAddr == ushort.MaxValue) - { - dmc_dmaAddr = 32768; - } - else - { - dmc_dmaAddr++; - } - if (dmc_dmaSize > 0) - { - dmc_dmaSize--; - } - if (dmc_dmaSize == 0) - { - if (dmc_loop_flag) - { - dmc_dmaSize = dmc_size_refresh; - dmc_dmaAddr = dmc_addr_refresh; - } - else if (dmc_irq_enabled) - { - IRQFlags |= 2; - apu_irq_delta_occur = true; - } - } - } - - private static void APUOnRegister4010() - { - if (apu_reg_access_w) - { - dmc_irq_enabled = (apu_reg_io_db & 0x80) != 0; - dmc_loop_flag = (apu_reg_io_db & 0x40) != 0; - if (!dmc_irq_enabled) - { - apu_irq_delta_occur = false; - IRQFlags &= -3; - } - dmc_rate_index = (byte)(apu_reg_io_db & 0xFu); - } - } - - private static void APUOnRegister4011() - { - if (apu_reg_access_w) - { - dmc_output_a = (byte)(apu_reg_io_db & 0x7F); - } - } - - private static void APUOnRegister4012() - { - if (apu_reg_access_w) - { - dmc_addr_refresh = (ushort)((uint)(apu_reg_io_db << 6) | 0xC000u); - } - } - - private static void APUOnRegister4013() - { - if (apu_reg_access_w) - { - dmc_size_refresh = (apu_reg_io_db << 4) | 1; - } - } - - private static void DMCOn4015() - { - apu_irq_delta_occur = false; - IRQFlags &= -3; - } - - private static void DMCRead4015() - { - if (dmc_dmaSize > 0) - { - apu_reg_io_db = (byte)((apu_reg_io_db & 0xEFu) | 0x10u); - } - } - - private static void DMCWriteState(ref BinaryWriter bin) - { - bin.Write(dmc_output_a); - bin.Write(dmc_output); - bin.Write(dmc_period_devider); - bin.Write(dmc_irq_enabled); - bin.Write(dmc_loop_flag); - bin.Write(dmc_rate_index); - bin.Write(dmc_addr_refresh); - bin.Write(dmc_size_refresh); - bin.Write(dmc_dmaEnabled); - bin.Write(dmc_dmaByte); - bin.Write(dmc_dmaBits); - bin.Write(dmc_bufferFull); - bin.Write(dmc_dmaBuffer); - bin.Write(dmc_dmaSize); - bin.Write(dmc_dmaAddr); - } - - private static void DMCReadState(ref BinaryReader bin) - { - dmc_output_a = bin.ReadInt32(); - dmc_output = bin.ReadInt32(); - dmc_period_devider = bin.ReadInt32(); - dmc_irq_enabled = bin.ReadBoolean(); - dmc_loop_flag = bin.ReadBoolean(); - dmc_rate_index = bin.ReadByte(); - dmc_addr_refresh = bin.ReadUInt16(); - dmc_size_refresh = bin.ReadInt32(); - dmc_dmaEnabled = bin.ReadBoolean(); - dmc_dmaByte = bin.ReadByte(); - dmc_dmaBits = bin.ReadInt32(); - dmc_bufferFull = bin.ReadBoolean(); - dmc_dmaBuffer = bin.ReadByte(); - dmc_dmaSize = bin.ReadInt32(); - dmc_dmaAddr = bin.ReadUInt16(); - } - - private static void NOSHardReset() - { - nos_length_halt = false; - nos_constant_volume_envelope = false; - nos_volume_devider_period = 0; - nos_shift_reg = 1; - nos_timer = 0; - nos_mode = false; - nos_period_devider = 0; - nos_length_enabled = false; - nos_length_counter = 0; - nos_envelope_start_flag = false; - nos_envelope_devider = 0; - nos_envelope_decay_level_counter = 0; - nos_envelope = 0; - nos_output = 0; - nos_feedback = 0; - nos_ignore_reload = false; - } - - private static void NOSSoftReset() - { - NOSHardReset(); - } - - private static void NOSClock() - { - nos_period_devider--; - if (nos_period_devider > 0) - { - return; - } - nos_period_devider = nos_timer; - if (nos_mode) - { - nos_feedback = ((nos_shift_reg >> 6) & 1) ^ (nos_shift_reg & 1); - } - else - { - nos_feedback = ((nos_shift_reg >> 1) & 1) ^ (nos_shift_reg & 1); - } - nos_shift_reg >>= 1; - nos_shift_reg = (nos_shift_reg & 0x3FFF) | ((nos_feedback & 1) << 14); - if (nos_length_counter > 0 && (nos_shift_reg & 1) == 0) - { - if (audio_nos_outputable) - { - nos_output = nos_envelope; - } - } - else - { - nos_output = 0; - } - audio_signal_outputed = true; - } - - private static void NOSClockLength() - { - if (nos_length_counter > 0 && !nos_length_halt) - { - nos_length_counter--; - if (apu_reg_access_happened && apu_reg_io_addr == 15 && apu_reg_access_w) - { - nos_ignore_reload = true; - } - } - } - - private static void NOSClockEnvelope() - { - if (nos_envelope_start_flag) - { - nos_envelope_start_flag = false; - nos_envelope_decay_level_counter = 15; - nos_envelope_devider = (byte)(nos_volume_devider_period + 1); - } - else if (nos_envelope_devider > 0) - { - nos_envelope_devider--; - } - else - { - nos_envelope_devider = (byte)(nos_volume_devider_period + 1); - if (nos_envelope_decay_level_counter > 0) - { - nos_envelope_decay_level_counter--; - } - else if (nos_length_halt) - { - nos_envelope_decay_level_counter = 15; - } - } - nos_envelope = (nos_constant_volume_envelope ? nos_volume_devider_period : nos_envelope_decay_level_counter); - } - - private static void APUOnRegister400C() - { - if (apu_reg_access_w) - { - nos_volume_devider_period = (byte)(apu_reg_io_db & 0xFu); - nos_length_halt = (apu_reg_io_db & 0x20) != 0; - nos_constant_volume_envelope = (apu_reg_io_db & 0x10) != 0; - nos_envelope = (nos_constant_volume_envelope ? nos_volume_devider_period : nos_envelope_decay_level_counter); - } - } - - private static void APUOnRegister400D() - { - } - - private static void APUOnRegister400E() - { - if (apu_reg_access_w) - { - nos_timer = (ushort)(nos_freq_table[SystemIndex][apu_reg_io_db & 0xF] / 2); - nos_mode = (apu_reg_io_db & 0x80) == 128; - } - } - - private static void APUOnRegister400F() - { - if (apu_reg_access_w) - { - if (nos_length_enabled && !nos_ignore_reload) - { - nos_length_counter = sq_duration_table[apu_reg_io_db >> 3]; - } - if (nos_ignore_reload) - { - nos_ignore_reload = false; - } - nos_envelope_start_flag = true; - } - } - - private static void NOSOn4015() - { - nos_length_enabled = (apu_reg_io_db & 8) != 0; - if (!nos_length_enabled) - { - nos_length_counter = 0; - } - } - - private static void NOSRead4015() - { - if (nos_length_counter > 0) - { - apu_reg_io_db = (byte)((apu_reg_io_db & 0xF7u) | 8u); - } - } - - private static void NOSWriteState(ref BinaryWriter bin) - { - bin.Write(nos_length_halt); - bin.Write(nos_constant_volume_envelope); - bin.Write(nos_volume_devider_period); - bin.Write(nos_timer); - bin.Write(nos_mode); - bin.Write(nos_period_devider); - bin.Write(nos_length_enabled); - bin.Write(nos_length_counter); - bin.Write(nos_envelope_start_flag); - bin.Write(nos_envelope_devider); - bin.Write(nos_envelope_decay_level_counter); - bin.Write(nos_envelope); - bin.Write(nos_output); - bin.Write(nos_shift_reg); - bin.Write(nos_feedback); - bin.Write(nos_ignore_reload); - } - - private static void NOSReadState(ref BinaryReader bin) - { - nos_length_halt = bin.ReadBoolean(); - nos_constant_volume_envelope = bin.ReadBoolean(); - nos_volume_devider_period = bin.ReadByte(); - nos_timer = bin.ReadUInt16(); - nos_mode = bin.ReadBoolean(); - nos_period_devider = bin.ReadInt32(); - nos_length_enabled = bin.ReadBoolean(); - nos_length_counter = bin.ReadInt32(); - nos_envelope_start_flag = bin.ReadBoolean(); - nos_envelope_devider = bin.ReadByte(); - nos_envelope_decay_level_counter = bin.ReadByte(); - nos_envelope = bin.ReadByte(); - nos_output = bin.ReadInt32(); - nos_shift_reg = bin.ReadInt32(); - nos_feedback = bin.ReadInt32(); - nos_ignore_reload = bin.ReadBoolean(); - } - - private static void SQ1HardReset() - { - sq1_duty_cycle = 0; - sq1_length_halt = false; - sq1_constant_volume_envelope = false; - sq1_volume_devider_period = 0; - sq1_sweep_enable = false; - sq1_sweep_devider_period = 0; - sq1_sweep_negate = false; - sq1_sweep_shift_count = 0; - sq1_timer = 0; - sq1_period_devider = 0; - sq1_seqencer = 0; - sq1_length_enabled = false; - sq1_length_counter = 0; - sq1_envelope_start_flag = false; - sq1_envelope_devider = 0; - sq1_envelope_decay_level_counter = 0; - sq1_envelope = 0; - sq1_sweep_counter = 0; - sq1_sweep_reload = false; - sq1_sweep_change = 0; - sq1_valid_freq = false; - sq1_output = 0; - sq1_ignore_reload = false; - } - - private static void SQ1SoftReset() - { - SQ1HardReset(); - } - - private static void SQ1Clock() - { - sq1_period_devider--; - if (sq1_period_devider > 0) - { - return; - } - sq1_period_devider = sq1_timer + 1; - sq1_seqencer = (byte)((uint)(sq1_seqencer + 1) & 7u); - if (sq1_length_counter > 0 && sq1_valid_freq) - { - if (audio_sq1_outputable) - { - sq1_output = sq_duty_cycle_sequences[sq1_duty_cycle][sq1_seqencer] * sq1_envelope; - } - } - else - { - sq1_output = 0; - } - audio_signal_outputed = true; - } - - private static void SQ1ClockLength() - { - if (sq1_length_counter > 0 && !sq1_length_halt) - { - sq1_length_counter--; - if (apu_reg_access_happened && apu_reg_io_addr == 3 && apu_reg_access_w) - { - sq1_ignore_reload = true; - } - } - sq1_sweep_counter--; - if (sq1_sweep_counter == 0) - { - sq1_sweep_counter = sq1_sweep_devider_period + 1; - if (sq1_sweep_enable && sq1_sweep_shift_count > 0 && sq1_valid_freq) - { - sq1_sweep_change = sq1_timer >> (int)sq1_sweep_shift_count; - sq1_timer += (sq1_sweep_negate ? (~sq1_sweep_change) : sq1_sweep_change); - SQ1CalculateValidFreq(); - } - } - if (sq1_sweep_reload) - { - sq1_sweep_counter = sq1_sweep_devider_period + 1; - sq1_sweep_reload = false; - } - } - - private static void SQ1ClockEnvelope() - { - if (sq1_envelope_start_flag) - { - sq1_envelope_start_flag = false; - sq1_envelope_decay_level_counter = 15; - sq1_envelope_devider = (byte)(sq1_volume_devider_period + 1); - } - else if (sq1_envelope_devider > 0) - { - sq1_envelope_devider--; - } - else - { - sq1_envelope_devider = (byte)(sq1_volume_devider_period + 1); - if (sq1_envelope_decay_level_counter > 0) - { - sq1_envelope_decay_level_counter--; - } - else if (sq1_length_halt) - { - sq1_envelope_decay_level_counter = 15; - } - } - sq1_envelope = (sq1_constant_volume_envelope ? sq1_volume_devider_period : sq1_envelope_decay_level_counter); - } - - private static void APUOnRegister4000() - { - if (apu_reg_access_w) - { - sq1_duty_cycle = (byte)((apu_reg_io_db & 0xC0) >> 6); - sq1_volume_devider_period = (byte)(apu_reg_io_db & 0xFu); - sq1_length_halt = (apu_reg_io_db & 0x20) != 0; - sq1_constant_volume_envelope = (apu_reg_io_db & 0x10) != 0; - sq1_envelope = (sq1_constant_volume_envelope ? sq1_volume_devider_period : sq1_envelope_decay_level_counter); - } - } - - private static void APUOnRegister4001() - { - if (apu_reg_access_w) - { - sq1_sweep_enable = (apu_reg_io_db & 0x80) == 128; - sq1_sweep_devider_period = (byte)((uint)(apu_reg_io_db >> 4) & 7u); - sq1_sweep_negate = (apu_reg_io_db & 8) == 8; - sq1_sweep_shift_count = (byte)(apu_reg_io_db & 7u); - sq1_sweep_reload = true; - SQ1CalculateValidFreq(); - } - } - - private static void APUOnRegister4002() - { - if (apu_reg_access_w) - { - sq1_timer = (sq1_timer & 0xFF00) | apu_reg_io_db; - SQ1CalculateValidFreq(); - } - } - - private static void APUOnRegister4003() - { - if (apu_reg_access_w) - { - sq1_timer = (sq1_timer & 0xFF) | ((apu_reg_io_db & 7) << 8); - if (sq1_length_enabled && !sq1_ignore_reload) - { - sq1_length_counter = sq_duration_table[apu_reg_io_db >> 3]; - } - if (sq1_ignore_reload) - { - sq1_ignore_reload = false; - } - sq1_seqencer = 0; - sq1_envelope_start_flag = true; - SQ1CalculateValidFreq(); - } - } - - private static void SQ1On4015() - { - sq1_length_enabled = (apu_reg_io_db & 1) != 0; - if (!sq1_length_enabled) - { - sq1_length_counter = 0; - } - } - - private static void SQ1Read4015() - { - if (sq1_length_counter > 0) - { - apu_reg_io_db = (byte)((apu_reg_io_db & 0xFEu) | 1u); - } - } - - private static void SQ1CalculateValidFreq() - { - sq1_valid_freq = sq1_timer >= 8 && (sq1_sweep_negate || ((sq1_timer + (sq1_timer >> (int)sq1_sweep_shift_count)) & 0x800) == 0); - } - - private static void SQ1WriteState(ref BinaryWriter bin) - { - bin.Write(sq1_duty_cycle); - bin.Write(sq1_length_halt); - bin.Write(sq1_constant_volume_envelope); - bin.Write(sq1_volume_devider_period); - bin.Write(sq1_sweep_enable); - bin.Write(sq1_sweep_devider_period); - bin.Write(sq1_sweep_negate); - bin.Write(sq1_sweep_shift_count); - bin.Write(sq1_timer); - bin.Write(sq1_period_devider); - bin.Write(sq1_seqencer); - bin.Write(sq1_length_enabled); - bin.Write(sq1_length_counter); - bin.Write(sq1_envelope_start_flag); - bin.Write(sq1_envelope_devider); - bin.Write(sq1_envelope_decay_level_counter); - bin.Write(sq1_envelope); - bin.Write(sq1_sweep_counter); - bin.Write(sq1_sweep_reload); - bin.Write(sq1_sweep_change); - bin.Write(sq1_valid_freq); - bin.Write(sq1_output); - bin.Write(sq1_ignore_reload); - } - - private static void SQ1ReadState(ref BinaryReader bin) - { - sq1_duty_cycle = bin.ReadByte(); - sq1_length_halt = bin.ReadBoolean(); - sq1_constant_volume_envelope = bin.ReadBoolean(); - sq1_volume_devider_period = bin.ReadByte(); - sq1_sweep_enable = bin.ReadBoolean(); - sq1_sweep_devider_period = bin.ReadByte(); - sq1_sweep_negate = bin.ReadBoolean(); - sq1_sweep_shift_count = bin.ReadByte(); - sq1_timer = bin.ReadInt32(); - sq1_period_devider = bin.ReadInt32(); - sq1_seqencer = bin.ReadByte(); - sq1_length_enabled = bin.ReadBoolean(); - sq1_length_counter = bin.ReadInt32(); - sq1_envelope_start_flag = bin.ReadBoolean(); - sq1_envelope_devider = bin.ReadByte(); - sq1_envelope_decay_level_counter = bin.ReadByte(); - sq1_envelope = bin.ReadByte(); - sq1_sweep_counter = bin.ReadInt32(); - sq1_sweep_reload = bin.ReadBoolean(); - sq1_sweep_change = bin.ReadInt32(); - sq1_valid_freq = bin.ReadBoolean(); - sq1_output = bin.ReadInt32(); - sq1_ignore_reload = bin.ReadBoolean(); - } - - private static void TRLHardReset() - { - trl_liner_control_flag = false; - trl_liner_control_reload = 0; - trl_timer = 0; - trl_length_enabled = false; - trl_length_counter = 0; - trl_liner_control_reload_flag = false; - trl_liner_counter = 0; - trl_output = 0; - trl_period_devider = 0; - trl_step = 0; - trl_ignore_reload = false; - } - - private static void TRLSoftReset() - { - TRLHardReset(); - } - - private static void TRLClock() - { - trl_period_devider--; - if (trl_period_devider > 0) - { - return; - } - trl_period_devider = trl_timer + 1; - if (trl_length_counter > 0 && trl_liner_counter > 0 && trl_timer >= 4) - { - trl_step++; - trl_step &= 31; - if (audio_trl_outputable) - { - trl_output = trl_step_seq[trl_step]; - } - } - audio_signal_outputed = true; - } - - private static void TRLClockLength() - { - if (trl_length_counter > 0 && !trl_liner_control_flag) - { - trl_length_counter--; - if (apu_reg_access_happened && apu_reg_io_addr == 11 && apu_reg_access_w) - { - trl_ignore_reload = true; - } - } - } - - private static void TRLClockEnvelope() - { - if (trl_liner_control_reload_flag) - { - trl_liner_counter = trl_liner_control_reload; - } - else if (trl_liner_counter > 0) - { - trl_liner_counter--; - } - if (!trl_liner_control_flag) - { - trl_liner_control_reload_flag = false; - } - } - - private static void APUOnRegister4008() - { - if (apu_reg_access_w) - { - trl_liner_control_flag = (apu_reg_io_db & 0x80) == 128; - trl_liner_control_reload = (byte)(apu_reg_io_db & 0x7Fu); - } - } - - private static void APUOnRegister4009() - { - } - - private static void APUOnRegister400A() - { - if (apu_reg_access_w) - { - trl_timer = (ushort)((trl_timer & 0x7F00u) | apu_reg_io_db); - } - } - - private static void APUOnRegister400B() - { - if (apu_reg_access_w) - { - trl_timer = (ushort)((trl_timer & 0xFFu) | (uint)((apu_reg_io_db & 7) << 8)); - if (trl_length_enabled && !trl_ignore_reload) - { - trl_length_counter = sq_duration_table[apu_reg_io_db >> 3]; - } - if (trl_ignore_reload) - { - trl_ignore_reload = false; - } - trl_liner_control_reload_flag = true; - } - } - - private static void TRLOn4015() - { - trl_length_enabled = (apu_reg_io_db & 4) != 0; - if (!trl_length_enabled) - { - trl_length_counter = 0; - } - } - - private static void TRLRead4015() - { - if (trl_length_counter > 0) - { - apu_reg_io_db = (byte)((apu_reg_io_db & 0xFBu) | 4u); - } - } - - private static void TRLWriteState(ref BinaryWriter bin) - { - bin.Write(trl_liner_control_flag); - bin.Write(trl_liner_control_reload); - bin.Write(trl_timer); - bin.Write(trl_length_enabled); - bin.Write(trl_length_counter); - bin.Write(trl_liner_control_reload_flag); - bin.Write(trl_liner_counter); - bin.Write(trl_output); - bin.Write(trl_period_devider); - bin.Write(trl_step); - bin.Write(trl_ignore_reload); - } - - private static void TRLReadState(ref BinaryReader bin) - { - trl_liner_control_flag = bin.ReadBoolean(); - trl_liner_control_reload = bin.ReadByte(); - trl_timer = bin.ReadUInt16(); - trl_length_enabled = bin.ReadBoolean(); - trl_length_counter = bin.ReadByte(); - trl_liner_control_reload_flag = bin.ReadBoolean(); - trl_liner_counter = bin.ReadByte(); - trl_output = bin.ReadInt32(); - trl_period_devider = bin.ReadInt32(); - trl_step = bin.ReadInt32(); - trl_ignore_reload = bin.ReadBoolean(); - } - - private static void APUInitialize() - { - apu_reg_update_func = new Action[32]; - apu_reg_read_func = new Action[32]; - apu_reg_write_func = new Action[32]; - for (int i = 0; i < 32; i++) - { - apu_reg_update_func[i] = APUBlankAccess; - apu_reg_read_func[i] = APUBlankAccess; - apu_reg_write_func[i] = APUBlankAccess; - } - apu_reg_update_func[0] = APUOnRegister4000; - apu_reg_update_func[1] = APUOnRegister4001; - apu_reg_update_func[2] = APUOnRegister4002; - apu_reg_update_func[3] = APUOnRegister4003; - apu_reg_update_func[4] = APUOnRegister4004; - apu_reg_update_func[5] = APUOnRegister4005; - apu_reg_update_func[6] = APUOnRegister4006; - apu_reg_update_func[7] = APUOnRegister4007; - apu_reg_update_func[8] = APUOnRegister4008; - apu_reg_update_func[9] = APUOnRegister4009; - apu_reg_update_func[10] = APUOnRegister400A; - apu_reg_update_func[11] = APUOnRegister400B; - apu_reg_update_func[12] = APUOnRegister400C; - apu_reg_update_func[13] = APUOnRegister400D; - apu_reg_update_func[14] = APUOnRegister400E; - apu_reg_update_func[15] = APUOnRegister400F; - apu_reg_update_func[16] = APUOnRegister4010; - apu_reg_update_func[17] = APUOnRegister4011; - apu_reg_update_func[18] = APUOnRegister4012; - apu_reg_update_func[19] = APUOnRegister4013; - apu_reg_update_func[21] = APUOnRegister4015; - apu_reg_update_func[22] = APUOnRegister4016; - apu_reg_update_func[23] = APUOnRegister4017; - apu_reg_read_func[21] = APURead4015; - apu_reg_read_func[22] = APURead4016; - apu_reg_read_func[23] = APURead4017; - apu_reg_write_func[20] = APUWrite4014; - apu_reg_write_func[21] = APUWrite4015; - audio_low_pass_filter_14K = new SoundLowPassFilter(0.00815686); - audio_high_pass_filter_90 = new SoundHighPassFilter(0.999835); - audio_high_pass_filter_440 = new SoundHighPassFilter(0.996039); - audio_dc_blocker_filter = new SoundDCBlockerFilter(0.995); - apu_update_playback_func = APUUpdatePlaybackWithFilters; - } - - public static void ApplyAudioSettings(bool all = true) - { - SoundEnabled = MyNesMain.RendererSettings.Audio_SoundEnabled; - audio_sq1_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SQ1; - audio_sq2_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SQ2; - audio_nos_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_NOZ; - audio_trl_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_TRL; - audio_dmc_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_DMC; - if (apu_use_external_sound) - { - mem_board.APUApplyChannelsSettings(); - } - if (all) - { - CalculateAudioPlaybackValues(); - } - } - - private static void APUHardReset() - { - apu_reg_io_db = 0; - apu_reg_io_addr = 0; - apu_reg_access_happened = false; - apu_reg_access_w = false; - apu_seq_mode = false; - apu_odd_cycle = true; - apu_cycle_f_t = 0; - apu_cycle_e = 4; - apu_cycle_f = 4; - apu_cycle_l = 4; - apu_odd_l = false; - apu_check_irq = false; - apu_do_env = false; - apu_do_length = false; - switch (Region) - { - case EmuRegion.NTSC: - cpu_speed = 1789773.0; - cpu_clock_per_frame = 29780.5; - apu_ferq_f = 14914; - apu_ferq_e = 3728; - apu_ferq_l = 7456; - break; - case EmuRegion.PALB: - cpu_speed = 1662607.0; - cpu_clock_per_frame = 33247.5; - apu_ferq_f = 14914; - apu_ferq_e = 3728; - apu_ferq_l = 7456; - break; - case EmuRegion.DENDY: - cpu_speed = 1773448.0; - cpu_clock_per_frame = 35464.0; - apu_ferq_f = 14914; - apu_ferq_e = 3728; - apu_ferq_l = 7456; - break; - } - Tracer.WriteLine("NES: cpu speed = " + cpu_speed); - SQ1HardReset(); - SQ2HardReset(); - NOSHardReset(); - DMCHardReset(); - TRLHardReset(); - apu_irq_enabled = true; - apu_irq_flag = false; - reg_2004 = 8196; - CalculateAudioPlaybackValues(); - apu_use_external_sound = mem_board.enable_external_sound; - if (apu_use_external_sound) - { - Tracer.WriteInformation("External sound channels has been enabled on apu."); - } - } - - private static void APUSoftReset() - { - apu_reg_io_db = 0; - apu_reg_io_addr = 0; - apu_reg_access_happened = false; - apu_reg_access_w = false; - apu_seq_mode = false; - apu_odd_cycle = false; - apu_cycle_f_t = 0; - apu_cycle_e = 4; - apu_cycle_f = 4; - apu_cycle_l = 4; - apu_odd_l = false; - apu_check_irq = false; - apu_do_env = false; - apu_do_length = false; - apu_irq_enabled = true; - apu_irq_flag = false; - SQ1SoftReset(); - SQ2SoftReset(); - TRLSoftReset(); - NOSSoftReset(); - DMCSoftReset(); - } - - private static void APUIORead(ref ushort addr, out byte value) - { - if (addr >= 16416) - { - mem_board.ReadEX(ref addr, out value); - return; - } - apu_reg_io_addr = (byte)(addr & 0x1Fu); - apu_reg_access_happened = true; - apu_reg_access_w = false; - apu_reg_read_func[apu_reg_io_addr](); - value = apu_reg_io_db; - } - - private static void APUIOWrite(ref ushort addr, ref byte value) - { - if (addr >= 16416) - { - mem_board.WriteEX(ref addr, ref value); - return; - } - apu_reg_io_addr = (byte)(addr & 0x1Fu); - apu_reg_io_db = value; - apu_reg_access_w = true; - apu_reg_access_happened = true; - apu_reg_write_func[apu_reg_io_addr](); - } - - private static void APUBlankAccess() - { - } - - private static void APUWrite4014() - { - dma_Oamaddress = (ushort)(apu_reg_io_db << 8); - AssertOAMDMA(); - } - - private static void APUWrite4015() - { - if ((apu_reg_io_db & 0x10u) != 0) - { - if (dmc_dmaSize == 0) - { - dmc_dmaSize = dmc_size_refresh; - dmc_dmaAddr = dmc_addr_refresh; - } - } - else - { - dmc_dmaSize = 0; - } - if (!dmc_bufferFull && dmc_dmaSize > 0) - { - AssertDMCDMA(); - } - } - - private static void APUOnRegister4015() - { - if (apu_reg_access_w) - { - SQ1On4015(); - SQ2On4015(); - NOSOn4015(); - TRLOn4015(); - DMCOn4015(); - } - else - { - apu_irq_flag = false; - IRQFlags &= -2; - } - } - - private static void APUOnRegister4016() - { - if (!apu_reg_access_w) - { - return; - } - if (inputStrobe > (apu_reg_io_db & 1)) - { - if (IsFourPlayers) - { - PORT0 = (joypad3.GetData() << 8) | joypad1.GetData() | 0x1010000; - PORT1 = (joypad4.GetData() << 8) | joypad2.GetData() | 0x2020000; - } - else - { - PORT0 = joypad1.GetData() | 0x1010100; - PORT1 = joypad2.GetData() | 0x2020200; - } - } - inputStrobe = apu_reg_io_db & 1; - } - - private static void APUOnRegister4017() - { - if (apu_reg_access_w) - { - apu_seq_mode = (apu_reg_io_db & 0x80) != 0; - apu_irq_enabled = (apu_reg_io_db & 0x40) == 0; - apu_cycle_e = -1; - apu_cycle_l = -1; - apu_cycle_f = -1; - apu_odd_l = false; - apu_do_length = apu_seq_mode; - apu_do_env = apu_seq_mode; - apu_check_irq = false; - if (!apu_irq_enabled) - { - apu_irq_flag = false; - IRQFlags &= -2; - } - } - } - - private static void APURead4015() - { - apu_reg_io_db &= 32; - SQ1Read4015(); - SQ2Read4015(); - NOSRead4015(); - TRLRead4015(); - DMCRead4015(); - if (apu_irq_flag) - { - apu_reg_io_db = (byte)((apu_reg_io_db & 0xBFu) | 0x40u); - } - if (apu_irq_delta_occur) - { - apu_reg_io_db = (byte)((apu_reg_io_db & 0x7Fu) | 0x80u); - } - } - - private static void APURead4016() - { - apu_reg_io_db = (byte)((uint)PORT0 & 1u); - PORT0 >>= 1; - } - - private static void APURead4017() - { - apu_reg_io_db = (byte)((uint)PORT1 & 1u); - PORT1 >>= 1; - } - - private static void APUClock() - { - apu_odd_cycle = !apu_odd_cycle; - if (apu_do_env) - { - APUClockEnvelope(); - } - if (apu_do_length) - { - APUClockDuration(); - } - if (apu_odd_cycle) - { - apu_cycle_f++; - if (apu_cycle_f >= apu_ferq_f) - { - apu_cycle_f = -1; - apu_check_irq = true; - apu_cycle_f_t = 3; - } - apu_cycle_e++; - if (apu_cycle_e >= apu_ferq_e) - { - apu_cycle_e = -1; - if (apu_check_irq) - { - if (!apu_seq_mode) - { - apu_do_env = true; - } - else - { - apu_cycle_e = 4; - } - } - else - { - apu_do_env = true; - } - } - apu_cycle_l++; - if (apu_cycle_l >= apu_ferq_l) - { - apu_odd_l = !apu_odd_l; - apu_cycle_l = (apu_odd_l ? (-2) : (-1)); - if (apu_check_irq && apu_seq_mode) - { - apu_cycle_l = 3730; - apu_odd_l = true; - } - else - { - apu_do_length = true; - } - } - SQ1Clock(); - SQ2Clock(); - NOSClock(); - if (apu_use_external_sound) - { - mem_board.OnAPUClock(); - } - if (apu_reg_access_happened) - { - apu_reg_access_happened = false; - apu_reg_update_func[apu_reg_io_addr](); - } - } - TRLClock(); - DMCClock(); - if (apu_check_irq) - { - if (!apu_seq_mode) - { - APUCheckIRQ(); - } - apu_cycle_f_t--; - if (apu_cycle_f_t == 0) - { - apu_check_irq = false; - } - } - if (apu_use_external_sound) - { - mem_board.OnAPUClockSingle(); - } - apu_update_playback_func(); - } - - private static void APUClockDuration() - { - SQ1ClockLength(); - SQ2ClockLength(); - NOSClockLength(); - TRLClockLength(); - if (apu_use_external_sound) - { - mem_board.OnAPUClockDuration(); - } - apu_do_length = false; - } - - private static void APUClockEnvelope() - { - SQ1ClockEnvelope(); - SQ2ClockEnvelope(); - NOSClockEnvelope(); - TRLClockEnvelope(); - if (apu_use_external_sound) - { - mem_board.OnAPUClockEnvelope(); - } - apu_do_env = false; - } - - private static void APUCheckIRQ() - { - if (apu_irq_enabled) - { - apu_irq_flag = true; - } - if (apu_irq_flag) - { - IRQFlags |= 1; - } - } - - private static void CalculateAudioPlaybackValues() - { - apu_target_samples_count_per_frame = (double)MyNesMain.RendererSettings.Audio_Frequency / emu_time_target_fps; - audio_timer_ratio = cpu_clock_per_frame / apu_target_samples_count_per_frame; - cpu_speed = audio_timer_ratio * (double)MyNesMain.RendererSettings.Audio_Frequency; - audio_playback_peek_limit = MyNesMain.RendererSettings.Audio_InternalPeekLimit; - audio_samples_count = MyNesMain.RendererSettings.Audio_InternalSamplesCount; - audio_playback_amplitude = MyNesMain.RendererSettings.Audio_PlaybackAmplitude; - audio_samples = new short[audio_samples_count]; - audio_w_pos = 0; - audio_samples_added = 0; - audio_timer = 0.0; - audio_x = (audio_y = 0.0); - Tracer.WriteLine("AUDIO: frequency = " + MyNesMain.RendererSettings.Audio_Frequency); - Tracer.WriteLine("AUDIO: timer ratio = " + audio_timer_ratio); - Tracer.WriteLine("AUDIO: internal samples count = " + audio_samples_count); - Tracer.WriteLine("AUDIO: amplitude = " + audio_playback_amplitude); - double num = 0.0; - if (MyNesMain.RendererSettings.Audio_EnableFilters) - { - apu_update_playback_func = APUUpdatePlaybackWithFilters; - num = cpu_speed / 14000.0; - audio_low_pass_filter_14K = new SoundLowPassFilter(SoundLowPassFilter.GetK(num, 14000.0)); - num = cpu_speed / 90.0; - audio_high_pass_filter_90 = new SoundHighPassFilter(SoundHighPassFilter.GetK(num, 90.0)); - num = cpu_speed / 440.0; - audio_high_pass_filter_440 = new SoundHighPassFilter(SoundHighPassFilter.GetK(num, 440.0)); - } - else - { - apu_update_playback_func = APUUpdatePlaybackWithoutFilters; - } - InitializeDACTables(force_intitialize: false); - } - - public static void InitializeDACTables(bool force_intitialize) - { - if (audio_playback_dac_initialized && !force_intitialize) - { - return; - } - int[] array = new int[5]; - mix_table = new int[16][][][][]; - for (int i = 0; i < 16; i++) - { - mix_table[i] = new int[16][][][]; - for (int j = 0; j < 16; j++) - { - mix_table[i][j] = new int[16][][]; - for (int k = 0; k < 16; k++) - { - mix_table[i][j][k] = new int[16][]; - for (int l = 0; l < 16; l++) - { - mix_table[i][j][k][l] = new int[128]; - for (int m = 0; m < 128; m++) - { - if (MyNesMain.RendererSettings.Audio_UseDefaultMixer) - { - double num = 95.88 / (8128.0 / (double)(i + j) + 100.0); - double num2 = 159.79 / (1.0 / ((double)k / 8227.0 + (double)l / 12241.0 + (double)m / 22638.0) + 100.0); - mix_table[i][j][k][l][m] = (int)Math.Ceiling((num + num2) * audio_playback_amplitude); - continue; - } - GetPrec(i, 255, 2048, out array[0]); - GetPrec(j, 255, 2048, out array[1]); - GetPrec(l, 255, 2048, out array[2]); - GetPrec(k, 255, 2048, out array[3]); - GetPrec(m, 255, 2048, out array[4]); - array[4] /= 2; - int num3 = array[0] + array[1] + array[2] + array[3] + array[4]; - num3 /= 5; - mix_table[i][j][k][l][m] = num3; - } - } - } - } - } - audio_playback_dac_initialized = true; - } - - private static void APUUpdatePlaybackWithFilters() - { - if (!SoundEnabled) - { - return; - } - audio_x = mix_table[sq1_output][sq2_output][trl_output][nos_output][dmc_output]; - if (apu_use_external_sound) - { - audio_x = (audio_x + mem_board.APUGetSample() * audio_playback_amplitude) / 2.0; - } - audio_high_pass_filter_90.DoFiltering(audio_x, out audio_y); - audio_high_pass_filter_440.DoFiltering(audio_y, out audio_y); - audio_low_pass_filter_14K.DoFiltering(audio_y, out audio_y); - audio_y_av += audio_y; - audio_y_timer += 1.0; - audio_timer += 1.0; - if (!(audio_timer >= audio_timer_ratio)) - { - return; - } - if (audio_y_timer > 0.0) - { - audio_y = audio_y_av / audio_y_timer; - } - else - { - audio_y = 0.0; - } - audio_y_av = 0.0; - audio_y_timer = 0.0; - audio_timer -= audio_timer_ratio; - if (audio_w_pos < audio_samples_count) - { - if (audio_y > (double)audio_playback_peek_limit) - { - audio_y = audio_playback_peek_limit; - } - if (audio_y < (double)(-audio_playback_peek_limit)) - { - audio_y = -audio_playback_peek_limit; - } - audio_samples[audio_w_pos] = (short)audio_y; - if (MyNesMain.WaveRecorder.IsRecording) - { - MyNesMain.WaveRecorder.AddSample((short)audio_y); - } - audio_w_pos++; - audio_samples_added++; - } - audio_y = 0.0; - } - - private static void APUUpdatePlaybackWithoutFilters() - { - if (!SoundEnabled) - { - return; - } - audio_y = mix_table[sq1_output][sq2_output][trl_output][nos_output][dmc_output] / 2; - if (apu_use_external_sound) - { - audio_y = (audio_y + mem_board.APUGetSample() * audio_playback_amplitude) / 2.0; - } - audio_y_av += audio_y; - audio_y_timer += 1.0; - audio_timer += 1.0; - if (!(audio_timer >= audio_timer_ratio)) - { - return; - } - if (audio_y_timer > 0.0) - { - audio_y = audio_y_av / audio_y_timer; - } - else - { - audio_y = 0.0; - } - audio_y_av = 0.0; - audio_y_timer = 0.0; - audio_timer -= audio_timer_ratio; - if (audio_w_pos < audio_samples_count) - { - if (audio_y > (double)audio_playback_peek_limit) - { - audio_y = audio_playback_peek_limit; - } - if (audio_y < (double)(-audio_playback_peek_limit)) - { - audio_y = -audio_playback_peek_limit; - } - audio_samples[audio_w_pos] = (short)audio_y; - if (MyNesMain.WaveRecorder.IsRecording) - { - MyNesMain.WaveRecorder.AddSample((short)audio_y); - } - audio_w_pos++; - audio_samples_added++; - } - audio_y = 0.0; - } - - private static void GetPrec(int inVal, int inMax, int outMax, out int val) - { - val = outMax * inVal / inMax; - } - - private static void APUWriteState(ref BinaryWriter bin) - { - bin.Write(apu_reg_io_db); - bin.Write(apu_reg_io_addr); - bin.Write(apu_reg_access_happened); - bin.Write(apu_reg_access_w); - bin.Write(apu_odd_cycle); - bin.Write(apu_irq_enabled); - bin.Write(apu_irq_flag); - bin.Write(apu_irq_delta_occur); - bin.Write(apu_seq_mode); - bin.Write(apu_ferq_f); - bin.Write(apu_ferq_l); - bin.Write(apu_ferq_e); - bin.Write(apu_cycle_f); - bin.Write(apu_cycle_e); - bin.Write(apu_cycle_l); - bin.Write(apu_odd_l); - bin.Write(apu_cycle_f_t); - bin.Write(apu_check_irq); - bin.Write(apu_do_env); - bin.Write(apu_do_length); - SQ1WriteState(ref bin); - SQ2WriteState(ref bin); - NOSWriteState(ref bin); - TRLWriteState(ref bin); - DMCWriteState(ref bin); - } - - private static void APUReadState(ref BinaryReader bin) - { - apu_reg_io_db = bin.ReadByte(); - apu_reg_io_addr = bin.ReadByte(); - apu_reg_access_happened = bin.ReadBoolean(); - apu_reg_access_w = bin.ReadBoolean(); - apu_odd_cycle = bin.ReadBoolean(); - apu_irq_enabled = bin.ReadBoolean(); - apu_irq_flag = bin.ReadBoolean(); - apu_irq_delta_occur = bin.ReadBoolean(); - apu_seq_mode = bin.ReadBoolean(); - apu_ferq_f = bin.ReadInt32(); - apu_ferq_l = bin.ReadInt32(); - apu_ferq_e = bin.ReadInt32(); - apu_cycle_f = bin.ReadInt32(); - apu_cycle_e = bin.ReadInt32(); - apu_cycle_l = bin.ReadInt32(); - apu_odd_l = bin.ReadBoolean(); - apu_cycle_f_t = bin.ReadInt32(); - apu_check_irq = bin.ReadBoolean(); - apu_do_env = bin.ReadBoolean(); - apu_do_length = bin.ReadBoolean(); - SQ1ReadState(ref bin); - SQ2ReadState(ref bin); - NOSReadState(ref bin); - TRLReadState(ref bin); - DMCReadState(ref bin); - } - - private static byte register_pb() - { - return (byte)((cpu_flag_n ? 128u : 0u) | (cpu_flag_v ? 64u : 0u) | (cpu_flag_d ? 8u : 0u) | (cpu_flag_i ? 4u : 0u) | (cpu_flag_z ? 2u : 0u) | (cpu_flag_c ? 1u : 0u) | 0x30u); - } - - private static void CPUInitialize() - { - cpu_addressings = new Action[256] - { - Imp____, IndX_R_, ImA____, IndX_W_, Zpg_R__, Zpg_R__, Zpg_RW_, Zpg_W__, ImA____, Imm____, - ImA____, Imm____, Abs_R__, Abs_R__, Abs_RW_, Abs_W__, Imp____, IndY_R_, Imp____, IndY_W_, - ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, ImA____, AbsY_R_, ImA____, AbsY_W_, AbsX_R_, AbsX_R_, - AbsX_RW, AbsX_W_, Imp____, IndX_R_, ImA____, IndX_W_, Zpg_R__, Zpg_R__, Zpg_RW_, Zpg_W__, - ImA____, Imm____, ImA____, Imm____, Abs_R__, Abs_R__, Abs_RW_, Abs_W__, Imp____, IndY_R_, - Imp____, IndY_W_, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, ImA____, AbsY_R_, ImA____, AbsY_W_, - AbsX_R_, AbsX_R_, AbsX_RW, AbsX_W_, ImA____, IndX_R_, ImA____, IndX_W_, Zpg_R__, Zpg_R__, - Zpg_RW_, Zpg_W__, ImA____, Imm____, ImA____, Imm____, Abs_W__, Abs_R__, Abs_RW_, Abs_W__, - Imp____, IndY_R_, Imp____, IndY_W_, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, ImA____, AbsY_R_, - ImA____, AbsY_W_, AbsX_R_, AbsX_R_, AbsX_RW, AbsX_W_, ImA____, IndX_R_, ImA____, IndX_W_, - Zpg_R__, Zpg_R__, Zpg_RW_, Zpg_W__, ImA____, Imm____, ImA____, Imm____, Imp____, Abs_R__, - Abs_RW_, Abs_W__, Imp____, IndY_R_, Imp____, IndY_W_, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, - ImA____, AbsY_R_, ImA____, AbsY_W_, AbsX_R_, AbsX_R_, AbsX_RW, AbsX_W_, Imm____, IndX_W_, - Imm____, IndX_W_, Zpg_W__, Zpg_W__, Zpg_W__, Zpg_W__, ImA____, Imm____, ImA____, Imm____, - Abs_W__, Abs_W__, Abs_W__, Abs_W__, Imp____, IndY_W_, Imp____, IndY_W_, ZpgX_W_, ZpgX_W_, - ZpgY_W_, ZpgY_W_, ImA____, AbsY_W_, ImA____, AbsY_W_, Abs_W__, AbsX_W_, Abs_W__, AbsY_W_, - Imm____, IndX_R_, Imm____, IndX_R_, Zpg_R__, Zpg_R__, Zpg_R__, Zpg_R__, ImA____, Imm____, - ImA____, Imm____, Abs_R__, Abs_R__, Abs_R__, Abs_R__, Imp____, IndY_R_, Imp____, IndY_R_, - ZpgX_R_, ZpgX_R_, ZpgY_R_, ZpgY_R_, ImA____, AbsY_R_, ImA____, AbsY_R_, AbsX_R_, AbsX_R_, - AbsY_R_, AbsY_R_, Imm____, IndX_R_, Imm____, IndX_R_, Zpg_R__, Zpg_R__, Zpg_RW_, Zpg_R__, - ImA____, Imm____, ImA____, Imm____, Abs_R__, Abs_R__, Abs_RW_, Abs_R__, Imp____, IndY_R_, - Imp____, IndY_RW, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_RW, ImA____, AbsY_R_, ImA____, AbsY_RW, - AbsX_R_, AbsX_R_, AbsX_RW, AbsX_RW, Imm____, IndX_R_, Imm____, IndX_W_, Zpg_R__, Zpg_R__, - Zpg_RW_, Zpg_W__, ImA____, Imm____, ImA____, Imm____, Abs_R__, Abs_R__, Abs_RW_, Abs_W__, - Imp____, IndY_R_, Imp____, IndY_W_, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, ImA____, AbsY_R_, - ImA____, AbsY_W_, AbsX_R_, AbsX_R_, AbsX_RW, AbsX_W_ - }; - cpu_instructions = new Action[256] - { - BRK__, ORA__, NOP__, SLO__, NOP__, ORA__, ASL_M, SLO__, PHP__, ORA__, - ASL_A, ANC__, NOP__, ORA__, ASL_M, SLO__, BPL__, ORA__, NOP__, SLO__, - NOP__, ORA__, ASL_M, SLO__, CLC__, ORA__, NOP__, SLO__, NOP__, ORA__, - ASL_M, SLO__, JSR__, AND__, NOP__, RLA__, BIT__, AND__, ROL_M, RLA__, - PLP__, AND__, ROL_A, ANC__, BIT__, AND__, ROL_M, RLA__, BMI__, AND__, - NOP__, RLA__, NOP__, AND__, ROL_M, RLA__, SEC__, AND__, NOP__, RLA__, - NOP__, AND__, ROL_M, RLA__, RTI__, EOR__, NOP__, SRE__, NOP__, EOR__, - LSR_M, SRE__, PHA__, EOR__, LSR_A, ALR__, JMP__, EOR__, LSR_M, SRE__, - BVC__, EOR__, NOP__, SRE__, NOP__, EOR__, LSR_M, SRE__, CLI__, EOR__, - NOP__, SRE__, NOP__, EOR__, LSR_M, SRE__, RTS__, ADC__, NOP__, RRA__, - NOP__, ADC__, ROR_M, RRA__, PLA__, ADC__, ROR_A, ARR__, JMP_I, ADC__, - ROR_M, RRA__, BVS__, ADC__, NOP__, RRA__, NOP__, ADC__, ROR_M, RRA__, - SEI__, ADC__, NOP__, RRA__, NOP__, ADC__, ROR_M, RRA__, NOP__, STA__, - NOP__, SAX__, STY__, STA__, STX__, SAX__, DEY__, NOP__, TXA__, XAA__, - STY__, STA__, STX__, SAX__, BCC__, STA__, NOP__, AHX__, STY__, STA__, - STX__, SAX__, TYA__, STA__, TXS__, XAS__, SHY__, STA__, SHX__, AHX__, - LDY__, LDA__, LDX__, LAX__, LDY__, LDA__, LDX__, LAX__, TAY__, LDA__, - TAX__, LAX__, LDY__, LDA__, LDX__, LAX__, BCS__, LDA__, NOP__, LAX__, - LDY__, LDA__, LDX__, LAX__, CLV__, LDA__, TSX__, LAR__, LDY__, LDA__, - LDX__, LAX__, CPY__, CMP__, NOP__, DCP__, CPY__, CMP__, DEC__, DCP__, - INY__, CMP__, DEX__, AXS__, CPY__, CMP__, DEC__, DCP__, BNE__, CMP__, - NOP__, DCP__, NOP__, CMP__, DEC__, DCP__, CLD__, CMP__, NOP__, DCP__, - NOP__, CMP__, DEC__, DCP__, CPX__, SBC__, NOP__, ISC__, CPX__, SBC__, - INC__, ISC__, INX__, SBC__, NOP__, SBC__, CPX__, SBC__, INC__, ISC__, - BEQ__, SBC__, NOP__, ISC__, NOP__, SBC__, INC__, ISC__, SED__, SBC__, - NOP__, ISC__, NOP__, SBC__, INC__, ISC__ - }; - } - - private static void CPUClock() - { - Read(ref cpu_reg_pc.v, out cpu_opcode); - cpu_reg_pc.v++; - cpu_addressings[cpu_opcode](); - cpu_instructions[cpu_opcode](); - if (CPU_IRQ_PIN || CPU_NMI_PIN) - { - Read(ref cpu_reg_pc.v, out cpu_dummy); - Read(ref cpu_reg_pc.v, out cpu_dummy); - Interrupt(); - } - } - - private static void CPUHardReset() - { - cpu_reg_a = 0; - cpu_reg_x = 0; - cpu_reg_y = 0; - cpu_reg_sp.l = 253; - cpu_reg_sp.h = 1; - ushort addr = 65532; - mem_board.ReadPRG(ref addr, out cpu_reg_pc.l); - addr++; - mem_board.ReadPRG(ref addr, out cpu_reg_pc.h); - register_p = 0; - cpu_flag_i = true; - cpu_reg_ea.v = 0; - cpu_opcode = 0; - CPU_IRQ_PIN = false; - CPU_NMI_PIN = false; - cpu_suspend_nmi = false; - cpu_suspend_irq = false; - IRQFlags = 0; - } - - private static void CPUSoftReset() - { - cpu_flag_i = true; - cpu_reg_sp.v -= 3; - ushort addr = 65532; - Read(ref addr, out cpu_reg_pc.l); - addr++; - Read(ref addr, out cpu_reg_pc.h); - } - - private static void Imp____() - { - } - - private static void IndX_R_() - { - temp_add.h = 0; - Read(ref cpu_reg_pc.v, out temp_add.l); - cpu_reg_pc.v++; - Read(ref temp_add.v, out cpu_dummy); - temp_add.l += cpu_reg_x; - Read(ref temp_add.v, out cpu_reg_ea.l); - temp_add.l++; - Read(ref temp_add.v, out cpu_reg_ea.h); - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void IndX_W_() - { - temp_add.h = 0; - Read(ref cpu_reg_pc.v, out temp_add.l); - cpu_reg_pc.v++; - Read(ref temp_add.v, out cpu_dummy); - temp_add.l += cpu_reg_x; - Read(ref temp_add.v, out cpu_reg_ea.l); - temp_add.l++; - Read(ref temp_add.v, out cpu_reg_ea.h); - } - - private static void IndX_RW() - { - temp_add.h = 0; - Read(ref cpu_reg_pc.v, out temp_add.l); - cpu_reg_pc.v++; - Read(ref temp_add.v, out cpu_dummy); - temp_add.l += cpu_reg_x; - Read(ref temp_add.v, out cpu_reg_ea.l); - temp_add.l++; - Read(ref temp_add.v, out cpu_reg_ea.h); - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void IndY_R_() - { - temp_add.h = 0; - Read(ref cpu_reg_pc.v, out temp_add.l); - cpu_reg_pc.v++; - Read(ref temp_add.v, out cpu_reg_ea.l); - temp_add.l++; - Read(ref temp_add.v, out cpu_reg_ea.h); - cpu_reg_ea.l += cpu_reg_y; - Read(ref cpu_reg_ea.v, out cpu_m); - if (cpu_reg_ea.l < cpu_reg_y) - { - cpu_reg_ea.h++; - Read(ref cpu_reg_ea.v, out cpu_m); - } - } - - private static void IndY_W_() - { - temp_add.h = 0; - Read(ref cpu_reg_pc.v, out temp_add.l); - cpu_reg_pc.v++; - Read(ref temp_add.v, out cpu_reg_ea.l); - temp_add.l++; - Read(ref temp_add.v, out cpu_reg_ea.h); - cpu_reg_ea.l += cpu_reg_y; - Read(ref cpu_reg_ea.v, out cpu_m); - if (cpu_reg_ea.l < cpu_reg_y) - { - cpu_reg_ea.h++; - } - } - - private static void IndY_RW() - { - temp_add.h = 0; - Read(ref cpu_reg_pc.v, out temp_add.l); - cpu_reg_pc.v++; - Read(ref temp_add.v, out cpu_reg_ea.l); - temp_add.l++; - Read(ref temp_add.v, out cpu_reg_ea.h); - cpu_reg_ea.l += cpu_reg_y; - Read(ref cpu_reg_ea.v, out cpu_dummy); - if (cpu_reg_ea.l < cpu_reg_y) - { - cpu_reg_ea.h++; - } - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void Zpg_R__() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void Zpg_W__() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - } - - private static void Zpg_RW_() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void ZpgX_R_() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_dummy); - cpu_reg_ea.l += cpu_reg_x; - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void ZpgX_W_() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_dummy); - cpu_reg_ea.l += cpu_reg_x; - } - - private static void ZpgX_RW() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_dummy); - cpu_reg_ea.l += cpu_reg_x; - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void ZpgY_R_() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_dummy); - cpu_reg_ea.l += cpu_reg_y; - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void ZpgY_W_() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_dummy); - cpu_reg_ea.l += cpu_reg_y; - } - - private static void ZpgY_RW() - { - cpu_reg_ea.h = 0; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_dummy); - cpu_reg_ea.l += cpu_reg_y; - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void Imm____() - { - Read(ref cpu_reg_pc.v, out cpu_m); - cpu_reg_pc.v++; - } - - private static void ImA____() - { - Read(ref cpu_reg_pc.v, out cpu_dummy); - } - - private static void Abs_R__() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void Abs_W__() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - } - - private static void Abs_RW_() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void AbsX_R_() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - cpu_reg_ea.l += cpu_reg_x; - Read(ref cpu_reg_ea.v, out cpu_m); - if (cpu_reg_ea.l < cpu_reg_x) - { - cpu_reg_ea.h++; - Read(ref cpu_reg_ea.v, out cpu_m); - } - } - - private static void AbsX_W_() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - cpu_reg_ea.l += cpu_reg_x; - Read(ref cpu_reg_ea.v, out cpu_m); - if (cpu_reg_ea.l < cpu_reg_x) - { - cpu_reg_ea.h++; - } - } - - private static void AbsX_RW() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - cpu_reg_ea.l += cpu_reg_x; - Read(ref cpu_reg_ea.v, out cpu_dummy); - if (cpu_reg_ea.l < cpu_reg_x) - { - cpu_reg_ea.h++; - } - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void AbsY_R_() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - cpu_reg_ea.l += cpu_reg_y; - Read(ref cpu_reg_ea.v, out cpu_m); - if (cpu_reg_ea.l < cpu_reg_y) - { - cpu_reg_ea.h++; - Read(ref cpu_reg_ea.v, out cpu_m); - } - } - - private static void AbsY_W_() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - cpu_reg_ea.l += cpu_reg_y; - Read(ref cpu_reg_ea.v, out cpu_m); - if (cpu_reg_ea.l < cpu_reg_y) - { - cpu_reg_ea.h++; - } - } - - private static void AbsY_RW() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v++; - cpu_reg_ea.l += cpu_reg_y; - Read(ref cpu_reg_ea.v, out cpu_m); - if (cpu_reg_ea.l < cpu_reg_y) - { - cpu_reg_ea.h++; - } - Read(ref cpu_reg_ea.v, out cpu_m); - } - - private static void Interrupt() - { - Push(ref cpu_reg_pc.h); - Push(ref cpu_reg_pc.l); - cpu_dummy = ((cpu_opcode == 0) ? register_pb() : register_p); - Push(ref cpu_dummy); - temp_add.v = InterruptVector; - cpu_suspend_nmi = true; - cpu_flag_i = true; - CPU_NMI_PIN = false; - Read(ref temp_add.v, out cpu_reg_pc.l); - temp_add.v++; - Read(ref temp_add.v, out cpu_reg_pc.h); - cpu_suspend_nmi = false; - } - - private static void Branch(ref bool condition) - { - Read(ref cpu_reg_pc.v, out cpu_byte_temp); - cpu_reg_pc.v++; - if (!condition) - { - return; - } - cpu_suspend_irq = true; - Read(ref cpu_reg_pc.v, out cpu_dummy); - cpu_reg_pc.l += cpu_byte_temp; - cpu_suspend_irq = false; - if (cpu_byte_temp >= 128) - { - if (cpu_reg_pc.l >= cpu_byte_temp) - { - Read(ref cpu_reg_pc.v, out cpu_dummy); - cpu_reg_pc.h--; - } - } - else if (cpu_reg_pc.l < cpu_byte_temp) - { - Read(ref cpu_reg_pc.v, out cpu_dummy); - cpu_reg_pc.h++; - } - } - - private static void Push(ref byte val) - { - Write(ref cpu_reg_sp.v, ref val); - cpu_reg_sp.l--; - } - - private static void Pull(out byte val) - { - cpu_reg_sp.l++; - Read(ref cpu_reg_sp.v, out val); - } - - private static void ADC__() - { - cpu_int_temp = cpu_reg_a + cpu_m + (cpu_flag_c ? 1 : 0); - cpu_flag_v = ((cpu_int_temp ^ cpu_reg_a) & (cpu_int_temp ^ cpu_m) & 0x80) != 0; - cpu_flag_n = (cpu_int_temp & 0x80) != 0; - cpu_flag_z = (cpu_int_temp & 0xFF) == 0; - cpu_flag_c = cpu_int_temp >> 8 != 0; - cpu_reg_a = (byte)((uint)cpu_int_temp & 0xFFu); - } - - private static void AHX__() - { - cpu_byte_temp = (byte)((uint)(cpu_reg_a & cpu_reg_x) & 7u); - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - } - - private static void ALR__() - { - cpu_reg_a &= cpu_m; - cpu_flag_c = (cpu_reg_a & 1) != 0; - cpu_reg_a >>= 1; - cpu_flag_n = (cpu_reg_a & 0x80) != 0; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void ANC__() - { - cpu_reg_a &= cpu_m; - cpu_flag_n = (cpu_reg_a & 0x80) != 0; - cpu_flag_z = cpu_reg_a == 0; - cpu_flag_c = (cpu_reg_a & 0x80) != 0; - } - - private static void AND__() - { - cpu_reg_a &= cpu_m; - cpu_flag_n = (cpu_reg_a & 0x80) == 128; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void ARR__() - { - cpu_reg_a = (byte)((uint)((cpu_m & cpu_reg_a) >> 1) | (cpu_flag_c ? 128u : 0u)); - cpu_flag_z = (cpu_reg_a & 0xFF) == 0; - cpu_flag_n = (cpu_reg_a & 0x80) != 0; - cpu_flag_c = (cpu_reg_a & 0x40) != 0; - cpu_flag_v = (((cpu_reg_a << 1) ^ cpu_reg_a) & 0x40) != 0; - } - - private static void AXS__() - { - cpu_int_temp = (cpu_reg_a & cpu_reg_x) - cpu_m; - cpu_flag_n = (cpu_int_temp & 0x80) != 0; - cpu_flag_z = (cpu_int_temp & 0xFF) == 0; - cpu_flag_c = ~cpu_int_temp >> 8 != 0; - cpu_reg_x = (byte)((uint)cpu_int_temp & 0xFFu); - } - - private static void ASL_M() - { - cpu_flag_c = (cpu_m & 0x80) == 128; - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_m = (byte)((uint)(cpu_m << 1) & 0xFEu); - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_flag_n = (cpu_m & 0x80) == 128; - cpu_flag_z = cpu_m == 0; - } - - private static void ASL_A() - { - cpu_flag_c = (cpu_reg_a & 0x80) == 128; - cpu_reg_a = (byte)((uint)(cpu_reg_a << 1) & 0xFEu); - cpu_flag_n = (cpu_reg_a & 0x80) == 128; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void BCC__() - { - cpu_bool_tmp = !cpu_flag_c; - Branch(ref cpu_bool_tmp); - } - - private static void BCS__() - { - Branch(ref cpu_flag_c); - } - - private static void BEQ__() - { - Branch(ref cpu_flag_z); - } - - private static void BIT__() - { - cpu_flag_n = (cpu_m & 0x80) != 0; - cpu_flag_v = (cpu_m & 0x40) != 0; - cpu_flag_z = (cpu_m & cpu_reg_a) == 0; - } - - private static void BRK__() - { - Read(ref cpu_reg_pc.v, out cpu_dummy); - cpu_reg_pc.v++; - Interrupt(); - } - - private static void BPL__() - { - cpu_bool_tmp = !cpu_flag_n; - Branch(ref cpu_bool_tmp); - } - - private static void BNE__() - { - cpu_bool_tmp = !cpu_flag_z; - Branch(ref cpu_bool_tmp); - } - - private static void BMI__() - { - Branch(ref cpu_flag_n); - } - - private static void BVC__() - { - cpu_bool_tmp = !cpu_flag_v; - Branch(ref cpu_bool_tmp); - } - - private static void BVS__() - { - Branch(ref cpu_flag_v); - } - - private static void SED__() - { - cpu_flag_d = true; - } - - private static void CLC__() - { - cpu_flag_c = false; - } - - private static void CLD__() - { - cpu_flag_d = false; - } - - private static void CLV__() - { - cpu_flag_v = false; - } - - private static void CMP__() - { - cpu_int_temp = cpu_reg_a - cpu_m; - cpu_flag_n = (cpu_int_temp & 0x80) == 128; - cpu_flag_c = cpu_reg_a >= cpu_m; - cpu_flag_z = cpu_int_temp == 0; - } - - private static void CPX__() - { - cpu_int_temp = cpu_reg_x - cpu_m; - cpu_flag_n = (cpu_int_temp & 0x80) == 128; - cpu_flag_c = cpu_reg_x >= cpu_m; - cpu_flag_z = cpu_int_temp == 0; - } - - private static void CPY__() - { - cpu_int_temp = cpu_reg_y - cpu_m; - cpu_flag_n = (cpu_int_temp & 0x80) == 128; - cpu_flag_c = cpu_reg_y >= cpu_m; - cpu_flag_z = cpu_int_temp == 0; - } - - private static void CLI__() - { - cpu_flag_i = false; - } - - private static void DCP__() - { - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_m--; - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_int_temp = cpu_reg_a - cpu_m; - cpu_flag_n = (cpu_int_temp & 0x80) != 0; - cpu_flag_z = cpu_int_temp == 0; - cpu_flag_c = ~cpu_int_temp >> 8 != 0; - } - - private static void DEC__() - { - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_m--; - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_flag_n = (cpu_m & 0x80) == 128; - cpu_flag_z = cpu_m == 0; - } - - private static void DEY__() - { - cpu_reg_y--; - cpu_flag_z = cpu_reg_y == 0; - cpu_flag_n = (cpu_reg_y & 0x80) == 128; - } - - private static void DEX__() - { - cpu_reg_x--; - cpu_flag_z = cpu_reg_x == 0; - cpu_flag_n = (cpu_reg_x & 0x80) == 128; - } - - private static void EOR__() - { - cpu_reg_a ^= cpu_m; - cpu_flag_n = (cpu_reg_a & 0x80) == 128; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void INC__() - { - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_m++; - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_flag_n = (cpu_m & 0x80) == 128; - cpu_flag_z = cpu_m == 0; - } - - private static void INX__() - { - cpu_reg_x++; - cpu_flag_z = cpu_reg_x == 0; - cpu_flag_n = (cpu_reg_x & 0x80) == 128; - } - - private static void INY__() - { - cpu_reg_y++; - cpu_flag_n = (cpu_reg_y & 0x80) == 128; - cpu_flag_z = cpu_reg_y == 0; - } - - private static void ISC__() - { - Read(ref cpu_reg_ea.v, out cpu_byte_temp); - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_byte_temp++; - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_int_temp = cpu_byte_temp ^ 0xFF; - cpu_int_temp1 = cpu_reg_a + cpu_int_temp + (cpu_flag_c ? 1 : 0); - cpu_flag_n = (cpu_int_temp1 & 0x80) != 0; - cpu_flag_v = ((cpu_int_temp1 ^ cpu_reg_a) & (cpu_int_temp1 ^ cpu_int_temp) & 0x80) != 0; - cpu_flag_z = (cpu_int_temp1 & 0xFF) == 0; - cpu_flag_c = cpu_int_temp1 >> 8 != 0; - cpu_reg_a = (byte)((uint)cpu_int_temp1 & 0xFFu); - } - - private static void JMP__() - { - cpu_reg_pc.v = cpu_reg_ea.v; - } - - private static void JMP_I() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - Read(ref cpu_reg_ea.v, out cpu_reg_pc.l); - cpu_reg_ea.l++; - Read(ref cpu_reg_ea.v, out cpu_reg_pc.h); - } - - private static void JSR__() - { - Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); - cpu_reg_pc.v++; - Write(ref cpu_reg_sp.v, ref cpu_reg_ea.l); - Push(ref cpu_reg_pc.h); - Push(ref cpu_reg_pc.l); - Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); - cpu_reg_pc.v = cpu_reg_ea.v; - } - - private static void LAR__() - { - cpu_reg_sp.l &= cpu_m; - cpu_reg_a = cpu_reg_sp.l; - cpu_reg_x = cpu_reg_sp.l; - cpu_flag_n = (cpu_reg_sp.l & 0x80) != 0; - cpu_flag_z = (cpu_reg_sp.l & 0xFF) == 0; - } - - private static void LAX__() - { - cpu_reg_x = (cpu_reg_a = cpu_m); - cpu_flag_n = (cpu_reg_x & 0x80) != 0; - cpu_flag_z = (cpu_reg_x & 0xFF) == 0; - } - - private static void LDA__() - { - cpu_reg_a = cpu_m; - cpu_flag_n = (cpu_reg_a & 0x80) == 128; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void LDX__() - { - cpu_reg_x = cpu_m; - cpu_flag_n = (cpu_reg_x & 0x80) == 128; - cpu_flag_z = cpu_reg_x == 0; - } - - private static void LDY__() - { - cpu_reg_y = cpu_m; - cpu_flag_n = (cpu_reg_y & 0x80) == 128; - cpu_flag_z = cpu_reg_y == 0; - } - - private static void LSR_A() - { - cpu_flag_c = (cpu_reg_a & 1) == 1; - cpu_reg_a >>= 1; - cpu_flag_z = cpu_reg_a == 0; - cpu_flag_n = (cpu_reg_a & 0x80) != 0; - } - - private static void LSR_M() - { - cpu_flag_c = (cpu_m & 1) == 1; - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_m >>= 1; - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_flag_z = cpu_m == 0; - cpu_flag_n = (cpu_m & 0x80) != 0; - } - - private static void NOP__() - { - } - - private static void ORA__() - { - cpu_reg_a |= cpu_m; - cpu_flag_n = (cpu_reg_a & 0x80) == 128; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void PHA__() - { - Push(ref cpu_reg_a); - } - - private static void PHP__() - { - cpu_dummy = register_pb(); - Push(ref cpu_dummy); - } - - private static void PLA__() - { - Read(ref cpu_reg_sp.v, out cpu_dummy); - Pull(out cpu_reg_a); - cpu_flag_n = (cpu_reg_a & 0x80) == 128; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void PLP__() - { - Read(ref cpu_reg_sp.v, out cpu_dummy); - Pull(out cpu_dummy); - register_p = cpu_dummy; - } - - private static void RLA__() - { - Read(ref cpu_reg_ea.v, out cpu_byte_temp); - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_dummy = (byte)((uint)(cpu_byte_temp << 1) | (cpu_flag_c ? 1u : 0u)); - Write(ref cpu_reg_ea.v, ref cpu_dummy); - cpu_flag_n = (cpu_dummy & 0x80) != 0; - cpu_flag_z = (cpu_dummy & 0xFF) == 0; - cpu_flag_c = (cpu_byte_temp & 0x80) != 0; - cpu_reg_a &= cpu_dummy; - cpu_flag_n = (cpu_reg_a & 0x80) != 0; - cpu_flag_z = (cpu_reg_a & 0xFF) == 0; - } - - private static void ROL_A() - { - cpu_byte_temp = (byte)((uint)(cpu_reg_a << 1) | (cpu_flag_c ? 1u : 0u)); - cpu_flag_n = (cpu_byte_temp & 0x80) != 0; - cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; - cpu_flag_c = (cpu_reg_a & 0x80) != 0; - cpu_reg_a = cpu_byte_temp; - } - - private static void ROL_M() - { - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_byte_temp = (byte)((uint)(cpu_m << 1) | (cpu_flag_c ? 1u : 0u)); - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_flag_n = (cpu_byte_temp & 0x80) != 0; - cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; - cpu_flag_c = (cpu_m & 0x80) != 0; - } - - private static void ROR_A() - { - cpu_byte_temp = (byte)((uint)(cpu_reg_a >> 1) | (cpu_flag_c ? 128u : 0u)); - cpu_flag_n = (cpu_byte_temp & 0x80) != 0; - cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; - cpu_flag_c = (cpu_reg_a & 1) != 0; - cpu_reg_a = cpu_byte_temp; - } - - private static void ROR_M() - { - Write(ref cpu_reg_ea.v, ref cpu_m); - cpu_byte_temp = (byte)((uint)(cpu_m >> 1) | (cpu_flag_c ? 128u : 0u)); - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_flag_n = (cpu_byte_temp & 0x80) != 0; - cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; - cpu_flag_c = (cpu_m & 1) != 0; - } - - private static void RRA__() - { - Read(ref cpu_reg_ea.v, out cpu_byte_temp); - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_dummy = (byte)((uint)(cpu_byte_temp >> 1) | (cpu_flag_c ? 128u : 0u)); - Write(ref cpu_reg_ea.v, ref cpu_dummy); - cpu_flag_n = (cpu_dummy & 0x80) != 0; - cpu_flag_z = (cpu_dummy & 0xFF) == 0; - cpu_flag_c = (cpu_byte_temp & 1) != 0; - cpu_byte_temp = cpu_dummy; - cpu_int_temp = cpu_reg_a + cpu_byte_temp + (cpu_flag_c ? 1 : 0); - cpu_flag_n = (cpu_int_temp & 0x80) != 0; - cpu_flag_v = ((cpu_int_temp ^ cpu_reg_a) & (cpu_int_temp ^ cpu_byte_temp) & 0x80) != 0; - cpu_flag_z = (cpu_int_temp & 0xFF) == 0; - cpu_flag_c = cpu_int_temp >> 8 != 0; - cpu_reg_a = (byte)cpu_int_temp; - } - - private static void RTI__() - { - Read(ref cpu_reg_sp.v, out cpu_dummy); - Pull(out cpu_dummy); - register_p = cpu_dummy; - Pull(out cpu_reg_pc.l); - Pull(out cpu_reg_pc.h); - } - - private static void RTS__() - { - Read(ref cpu_reg_sp.v, out cpu_dummy); - Pull(out cpu_reg_pc.l); - Pull(out cpu_reg_pc.h); - cpu_reg_pc.v++; - Read(ref cpu_reg_pc.v, out cpu_dummy); - } - - private static void SAX__() - { - cpu_dummy = (byte)(cpu_reg_x & cpu_reg_a); - Write(ref cpu_reg_ea.v, ref cpu_dummy); - } - - private static void SBC__() - { - cpu_m ^= byte.MaxValue; - cpu_int_temp = cpu_reg_a + cpu_m + (cpu_flag_c ? 1 : 0); - cpu_flag_n = (cpu_int_temp & 0x80) != 0; - cpu_flag_v = ((cpu_int_temp ^ cpu_reg_a) & (cpu_int_temp ^ cpu_m) & 0x80) != 0; - cpu_flag_z = (cpu_int_temp & 0xFF) == 0; - cpu_flag_c = cpu_int_temp >> 8 != 0; - cpu_reg_a = (byte)cpu_int_temp; - } - - private static void SEC__() - { - cpu_flag_c = true; - } - - private static void SEI__() - { - cpu_flag_i = true; - } - - private static void SHX__() - { - cpu_byte_temp = (byte)(cpu_reg_x & (cpu_reg_ea.h + 1)); - Read(ref cpu_reg_ea.v, out cpu_dummy); - cpu_reg_ea.l += cpu_reg_y; - if (cpu_reg_ea.l < cpu_reg_y) - { - cpu_reg_ea.h = cpu_byte_temp; - } - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - } - - private static void SHY__() - { - cpu_byte_temp = (byte)(cpu_reg_y & (cpu_reg_ea.h + 1)); - Read(ref cpu_reg_ea.v, out cpu_dummy); - cpu_reg_ea.l += cpu_reg_x; - if (cpu_reg_ea.l < cpu_reg_x) - { - cpu_reg_ea.h = cpu_byte_temp; - } - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - } - - private static void SLO__() - { - Read(ref cpu_reg_ea.v, out cpu_byte_temp); - cpu_flag_c = (cpu_byte_temp & 0x80) != 0; - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_byte_temp <<= 1; - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_flag_n = (cpu_byte_temp & 0x80) != 0; - cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; - cpu_reg_a |= cpu_byte_temp; - cpu_flag_n = (cpu_reg_a & 0x80) != 0; - cpu_flag_z = (cpu_reg_a & 0xFF) == 0; - } - - private static void SRE__() - { - Read(ref cpu_reg_ea.v, out cpu_byte_temp); - cpu_flag_c = (cpu_byte_temp & 1) != 0; - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_byte_temp >>= 1; - Write(ref cpu_reg_ea.v, ref cpu_byte_temp); - cpu_flag_n = (cpu_byte_temp & 0x80) != 0; - cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; - cpu_reg_a ^= cpu_byte_temp; - cpu_flag_n = (cpu_reg_a & 0x80) != 0; - cpu_flag_z = (cpu_reg_a & 0xFF) == 0; - } - - private static void STA__() - { - Write(ref cpu_reg_ea.v, ref cpu_reg_a); - } - - private static void STX__() - { - Write(ref cpu_reg_ea.v, ref cpu_reg_x); - } - - private static void STY__() - { - Write(ref cpu_reg_ea.v, ref cpu_reg_y); - } - - private static void TAX__() - { - cpu_reg_x = cpu_reg_a; - cpu_flag_n = (cpu_reg_x & 0x80) == 128; - cpu_flag_z = cpu_reg_x == 0; - } - - private static void TAY__() - { - cpu_reg_y = cpu_reg_a; - cpu_flag_n = (cpu_reg_y & 0x80) == 128; - cpu_flag_z = cpu_reg_y == 0; - } - - private static void TSX__() - { - cpu_reg_x = cpu_reg_sp.l; - cpu_flag_n = (cpu_reg_x & 0x80) != 0; - cpu_flag_z = cpu_reg_x == 0; - } - - private static void TXA__() - { - cpu_reg_a = cpu_reg_x; - cpu_flag_n = (cpu_reg_a & 0x80) == 128; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void TXS__() - { - cpu_reg_sp.l = cpu_reg_x; - } - - private static void TYA__() - { - cpu_reg_a = cpu_reg_y; - cpu_flag_n = (cpu_reg_a & 0x80) == 128; - cpu_flag_z = cpu_reg_a == 0; - } - - private static void XAA__() - { - cpu_reg_a = (byte)(cpu_reg_x & cpu_m); - cpu_flag_n = (cpu_reg_a & 0x80) != 0; - cpu_flag_z = (cpu_reg_a & 0xFF) == 0; - } - - private static void XAS__() - { - cpu_reg_sp.l = (byte)(cpu_reg_a & cpu_reg_x); - Write(ref cpu_reg_ea.v, ref cpu_reg_sp.l); - } - - private static void CPUWriteState(ref BinaryWriter bin) - { - bin.Write(cpu_reg_pc.v); - bin.Write(cpu_reg_sp.v); - bin.Write(cpu_reg_ea.v); - bin.Write(cpu_reg_a); - bin.Write(cpu_reg_x); - bin.Write(cpu_reg_y); - bin.Write(cpu_flag_n); - bin.Write(cpu_flag_v); - bin.Write(cpu_flag_d); - bin.Write(cpu_flag_i); - bin.Write(cpu_flag_z); - bin.Write(cpu_flag_c); - bin.Write(cpu_m); - bin.Write(cpu_opcode); - bin.Write(cpu_byte_temp); - bin.Write(cpu_int_temp); - bin.Write(cpu_int_temp1); - bin.Write(cpu_dummy); - bin.Write(cpu_bool_tmp); - bin.Write(temp_add.v); - bin.Write(CPU_IRQ_PIN); - bin.Write(CPU_NMI_PIN); - bin.Write(cpu_suspend_nmi); - bin.Write(cpu_suspend_irq); - } - - private static void CPUReadState(ref BinaryReader bin) - { - cpu_reg_pc.v = bin.ReadUInt16(); - cpu_reg_sp.v = bin.ReadUInt16(); - cpu_reg_ea.v = bin.ReadUInt16(); - cpu_reg_a = bin.ReadByte(); - cpu_reg_x = bin.ReadByte(); - cpu_reg_y = bin.ReadByte(); - cpu_flag_n = bin.ReadBoolean(); - cpu_flag_v = bin.ReadBoolean(); - cpu_flag_d = bin.ReadBoolean(); - cpu_flag_i = bin.ReadBoolean(); - cpu_flag_z = bin.ReadBoolean(); - cpu_flag_c = bin.ReadBoolean(); - cpu_m = bin.ReadByte(); - cpu_opcode = bin.ReadByte(); - cpu_byte_temp = bin.ReadByte(); - cpu_int_temp = bin.ReadInt32(); - cpu_int_temp1 = bin.ReadInt32(); - cpu_dummy = bin.ReadByte(); - cpu_bool_tmp = bin.ReadBoolean(); - temp_add.v = bin.ReadUInt16(); - CPU_IRQ_PIN = bin.ReadBoolean(); - CPU_NMI_PIN = bin.ReadBoolean(); - cpu_suspend_nmi = bin.ReadBoolean(); - cpu_suspend_irq = bin.ReadBoolean(); - } - - private static void DMAHardReset() - { - dma_DMCDMAWaitCycles = 0; - dma_OAMDMAWaitCycles = 0; - dma_isOamDma = false; - dma_oamdma_i = 0; - dma_DMCOn = false; - dma_OAMOn = false; - dma_DMC_occurring = false; - dma_OAM_occurring = false; - dma_OAMFinishCounter = 0; - dma_Oamaddress = 0; - dma_OAMCYCLE = 0; - dma_latch = 0; - reg_2004 = 8196; - } - - private static void DMASoftReset() - { - dma_DMCDMAWaitCycles = 0; - dma_OAMDMAWaitCycles = 0; - dma_isOamDma = false; - dma_oamdma_i = 0; - dma_DMCOn = false; - dma_OAMOn = false; - dma_DMC_occurring = false; - dma_OAM_occurring = false; - dma_OAMFinishCounter = 0; - dma_Oamaddress = 0; - dma_OAMCYCLE = 0; - dma_latch = 0; - } - - internal static void AssertDMCDMA() - { - if (dma_OAM_occurring) - { - if (dma_OAMCYCLE < 508) - { - dma_DMCDMAWaitCycles = (BUS_RW ? 1 : 0); - } - else - { - dma_DMCDMAWaitCycles = 4 - (512 - dma_OAMCYCLE); - } - } - else - { - if (dma_DMC_occurring) - { - return; - } - dma_DMCDMAWaitCycles = (BUS_RW ? 3 : 2); - if (dma_OAMFinishCounter == 3) - { - dma_DMCDMAWaitCycles++; - } - } - dma_isOamDma = false; - dma_DMCOn = true; - } - - private static void AssertOAMDMA() - { - if (!dma_OAM_occurring) - { - dma_OAMDMAWaitCycles = (apu_odd_cycle ? 1 : 2); - dma_isOamDma = true; - dma_OAMOn = true; - } - } - - private static void DMAClock() - { - if (dma_OAMFinishCounter > 0) - { - dma_OAMFinishCounter--; - } - if (!BUS_RW) - { - if (dma_DMCDMAWaitCycles > 0) - { - dma_DMCDMAWaitCycles--; - } - if (dma_OAMDMAWaitCycles > 0) - { - dma_OAMDMAWaitCycles--; - } - return; - } - if (dma_DMCOn) - { - dma_DMC_occurring = true; - dma_DMCOn = false; - if (dma_DMCDMAWaitCycles > 0) - { - if (BUS_ADDRESS == 16406 || BUS_ADDRESS == 16407) - { - Read(ref BUS_ADDRESS, out dma_dummy); - dma_DMCDMAWaitCycles--; - while (dma_DMCDMAWaitCycles > 0) - { - EmuClockComponents(); - dma_DMCDMAWaitCycles--; - } - } - else - { - if (dma_DMCDMAWaitCycles > 0) - { - EmuClockComponents(); - dma_DMCDMAWaitCycles--; - } - while (dma_DMCDMAWaitCycles > 0) - { - Read(ref BUS_ADDRESS, out dma_dummy); - dma_DMCDMAWaitCycles--; - } - } - } - DMCDoDMA(); - dma_DMC_occurring = false; - } - if (!dma_OAMOn) - { - return; - } - dma_OAM_occurring = true; - dma_OAMOn = false; - if (dma_OAMDMAWaitCycles > 0) - { - if (BUS_ADDRESS == 16406 || BUS_ADDRESS == 16407) - { - Read(ref BUS_ADDRESS, out dma_dummy); - dma_OAMDMAWaitCycles--; - while (dma_OAMDMAWaitCycles > 0) - { - EmuClockComponents(); - dma_OAMDMAWaitCycles--; - } - } - else - { - if (dma_OAMDMAWaitCycles > 0) - { - EmuClockComponents(); - dma_OAMDMAWaitCycles--; - } - while (dma_OAMDMAWaitCycles > 0) - { - Read(ref BUS_ADDRESS, out dma_dummy); - dma_OAMDMAWaitCycles--; - } - } - } - dma_OAMCYCLE = 0; - for (dma_oamdma_i = 0; dma_oamdma_i < 256; dma_oamdma_i++) - { - Read(ref dma_Oamaddress, out dma_latch); - dma_OAMCYCLE++; - Write(ref reg_2004, ref dma_latch); - dma_OAMCYCLE++; - dma_Oamaddress = (ushort)(++dma_Oamaddress & 0xFFFFu); - } - dma_OAMCYCLE = 0; - dma_OAMFinishCounter = 5; - dma_OAM_occurring = false; - } - - private static void DMAWriteState(ref BinaryWriter bin) - { - bin.Write(dma_DMCDMAWaitCycles); - bin.Write(dma_OAMDMAWaitCycles); - bin.Write(dma_isOamDma); - bin.Write(dma_oamdma_i); - bin.Write(dma_DMCOn); - bin.Write(dma_OAMOn); - bin.Write(dma_DMC_occurring); - bin.Write(dma_OAM_occurring); - bin.Write(dma_OAMFinishCounter); - bin.Write(dma_Oamaddress); - bin.Write(dma_OAMCYCLE); - bin.Write(dma_latch); - bin.Write(dma_dummy); - } - - private static void DMAReadState(ref BinaryReader bin) - { - dma_DMCDMAWaitCycles = bin.ReadInt32(); - dma_OAMDMAWaitCycles = bin.ReadInt32(); - dma_isOamDma = bin.ReadBoolean(); - dma_oamdma_i = bin.ReadInt32(); - dma_DMCOn = bin.ReadBoolean(); - dma_OAMOn = bin.ReadBoolean(); - dma_DMC_occurring = bin.ReadBoolean(); - dma_OAM_occurring = bin.ReadBoolean(); - dma_OAMFinishCounter = bin.ReadInt32(); - dma_Oamaddress = bin.ReadUInt16(); - dma_OAMCYCLE = bin.ReadInt32(); - dma_latch = bin.ReadByte(); - dma_dummy = bin.ReadByte(); - } - - private static void PollInterruptStatus() - { - if (!cpu_suspend_nmi) - { - if (PPU_NMI_Current & !PPU_NMI_Old) - { - CPU_NMI_PIN = true; - } - PPU_NMI_Old = (PPU_NMI_Current = false); - } - if (!cpu_suspend_irq) - { - CPU_IRQ_PIN = !cpu_flag_i && IRQFlags != 0; - } - if (CPU_NMI_PIN) - { - InterruptVector = 65530; - } - else - { - InterruptVector = 65534; - } - } - - private static void InterruptsWriteState(ref BinaryWriter bin) - { - bin.Write(IRQFlags); - bin.Write(PPU_NMI_Current); - bin.Write(PPU_NMI_Old); - bin.Write(InterruptVector); - } - - private static void InterruptsReadState(ref BinaryReader bin) - { - IRQFlags = bin.ReadInt32(); - PPU_NMI_Current = bin.ReadBoolean(); - PPU_NMI_Old = bin.ReadBoolean(); - InterruptVector = bin.ReadUInt16(); - } - - public static void SetupGameGenie(bool IsGameGenieActive, GameGenieCode[] GameGenieCodes) - { - if (mem_board != null) - { - mem_board.SetupGameGenie(IsGameGenieActive, GameGenieCodes); - } - } - - private static void MEMInitialize(IRom rom) - { - Tracer.WriteLine("Looking for mapper # " + rom.MapperNumber + "...."); - if (MyNesMain.IsBoardExist(rom.MapperNumber)) - { - Tracer.WriteLine("Mapper # " + rom.MapperNumber + " located, assigning..."); - mem_board = MyNesMain.GetBoard(rom.MapperNumber); - Tracer.WriteInformation("Mapper # " + rom.MapperNumber + " assigned successfully."); - if (mem_board.HasIssues) - { - Tracer.WriteWarning(MNInterfaceLanguage.Mapper + " # " + mem_board.MapperNumber + " [" + mem_board.Name + "] " + MNInterfaceLanguage.Message_Error17); - MyNesMain.VideoProvider.WriteWarningNotification(MNInterfaceLanguage.Mapper + " # " + mem_board.MapperNumber + " [" + mem_board.Name + "] " + MNInterfaceLanguage.Message_Error17, instant: false); - } - } - else - { - Tracer.WriteError("Mapper # " + rom.MapperNumber + " IS NOT LOCATED, mapper is not supported or unable to find it."); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Mapper + " # " + rom.MapperNumber + " " + MNInterfaceLanguage.Message_Error14, instant: false); - mem_board = MyNesMain.GetBoard(0); - Tracer.WriteWarning("Mapper # 0 [NROM] will be used instead, assigned successfully."); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Mapper + " # 0 [NROM] " + MNInterfaceLanguage.Message_Error15, instant: false); - } - mem_read_accesses = new MemReadAccess[65536]; - mem_write_accesses = new MemWriteAccess[65536]; - MEMMap(MEMReadWRAM, new ushort[2] { 0, 4096 }); - MEMMap(MEMWriteWRAM, new ushort[2] { 0, 4096 }); - MEMMap(PPUIORead, new ushort[2] { 8192, 12288 }); - MEMMap(PPUIOWrite, new ushort[2] { 8192, 12288 }); - MEMMap(APUIORead, new ushort[1] { 16384 }); - MEMMap(APUIOWrite, new ushort[1] { 16384 }); - MEMMap(mem_board.ReadEX, new ushort[1] { 20480 }); - MEMMap(mem_board.WriteEX, new ushort[1] { 20480 }); - MEMMap(mem_board.ReadSRM, new ushort[2] { 24576, 28672 }); - MEMMap(mem_board.WriteSRM, new ushort[2] { 24576, 28672 }); - MEMMap(mem_board.ReadPRG, new ushort[8] { 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440 }); - MEMMap(mem_board.WritePRG, new ushort[8] { 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440 }); - mem_board.Initialize(rom); - mem_wram = new byte[2048]; - } - - private static void MEMHardReset() - { - mem_wram = new byte[2048]; - mem_wram[8] = 247; - mem_wram[9] = 239; - mem_wram[10] = 223; - mem_wram[15] = 191; - Tracer.WriteLine("Reading SRAM ..."); - SRAMFileName = Path.Combine(MyNesMain.EmuSettings.SRAMFolder, Path.GetFileNameWithoutExtension(CurrentFilePath) + ".srm"); - if (File.Exists(SRAMFileName)) - { - Stream stream = new FileStream(SRAMFileName, FileMode.Open, FileAccess.Read); - byte[] array = new byte[stream.Length]; - stream.Read(array, 0, array.Length); - stream.Flush(); - stream.Close(); - byte[] outData = new byte[0]; - ZlipWrapper.DecompressData(array, out outData); - mem_board.LoadSRAM(outData); - Tracer.WriteLine("SRAM read successfully."); - } - else - { - Tracer.WriteLine("SRAM file not found; rom has no SRAM or file not exist."); - } - ReloadGameGenieCodes(); - mem_board.HardReset(); - } - - public static void ReloadGameGenieCodes() - { - Tracer.WriteLine("Reading game genie codes (if available)...."); - GMFileName = Path.Combine(MyNesMain.EmuSettings.GameGenieFolder, Path.GetFileNameWithoutExtension(CurrentFilePath) + ".txt"); - mem_board.GameGenieCodes = new GameGenieCode[0]; - if (File.Exists(GMFileName)) - { - XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); - xmlReaderSettings.DtdProcessing = DtdProcessing.Ignore; - xmlReaderSettings.IgnoreWhitespace = true; - XmlReader xmlReader = XmlReader.Create(GMFileName, xmlReaderSettings); - xmlReader.Read(); - xmlReader.Read(); - if (xmlReader.Name != "MyNesGameGenieCodesList") - { - xmlReader.Close(); - return; - } - GameGenie gameGenie = new GameGenie(); - List list = new List(); - while (xmlReader.Read()) - { - if (xmlReader.Name == "Code") - { - GameGenieCode item = default(GameGenieCode); - item.Enabled = true; - xmlReader.MoveToAttribute("code"); - item.Name = xmlReader.Value.ToString(); - if (item.Name.Length == 6) - { - item.Address = gameGenie.GetGGAddress(gameGenie.GetCodeAsHEX(item.Name), 6) | 0x8000; - item.Value = gameGenie.GetGGValue(gameGenie.GetCodeAsHEX(item.Name), 6); - item.IsCompare = false; - } - else - { - item.Address = gameGenie.GetGGAddress(gameGenie.GetCodeAsHEX(item.Name), 8) | 0x8000; - item.Value = gameGenie.GetGGValue(gameGenie.GetCodeAsHEX(item.Name), 8); - item.Compare = gameGenie.GetGGCompareValue(gameGenie.GetCodeAsHEX(item.Name)); - item.IsCompare = true; - } - list.Add(item); - } - } - xmlReader.Close(); - if (list.Count > 0) - { - mem_board.GameGenieCodes = list.ToArray(); - Tracer.WriteInformation("Game Genie codes loaded successfully, total of " + list.Count); - } - else - { - Tracer.WriteError("There is no Game Genie code in the file to load."); - } - } - else - { - Tracer.WriteWarning("No Game Genie file found for this game."); - } - } - - private static void MEMMap(MemReadAccess readAccess, ushort[] addresses) - { - for (int i = 0; i < addresses.Length; i++) - { - mem_read_accesses[(addresses[i] & 0xF000) >> 12] = readAccess; - } - } - - private static void MEMMap(MemWriteAccess writeAccess, ushort[] addresses) - { - for (int i = 0; i < addresses.Length; i++) - { - mem_write_accesses[(addresses[i] & 0xF000) >> 12] = writeAccess; - } - } - - private static void MEMReadWRAM(ref ushort addr, out byte value) - { - value = mem_wram[addr & 0x7FF]; - } - - private static void MEMWriteWRAM(ref ushort addr, ref byte value) - { - mem_wram[addr & 0x7FF] = value; - } - - internal static void Read(ref ushort addr, out byte value) - { - BUS_RW = true; - BUS_ADDRESS = addr; - EmuClockComponents(); - mem_read_accesses[(addr & 0xF000) >> 12](ref addr, out value); - } - - private static void Write(ref ushort addr, ref byte value) - { - BUS_RW = false; - BUS_ADDRESS = addr; - EmuClockComponents(); - mem_write_accesses[(addr & 0xF000) >> 12](ref addr, ref value); - } - - internal static void SaveSRAM() - { - if (mem_board != null && MyNesMain.EmuSettings.SaveSRAMAtEmuShutdown && mem_board.SRAMSaveRequired) - { - Tracer.WriteLine("Saving SRAM ..."); - byte[] outData = new byte[0]; - ZlipWrapper.CompressData(mem_board.GetSRAMBuffer(), out outData); - Stream stream = new FileStream(SRAMFileName, FileMode.Create, FileAccess.Write); - stream.Write(outData, 0, outData.Length); - stream.Flush(); - stream.Close(); - Tracer.WriteLine("SRAM saved successfully."); - } - } - - private static void MEMWriteState(ref BinaryWriter bin) - { - mem_board.WriteStateData(ref bin); - bin.Write(mem_wram); - bin.Write(BUS_RW); - bin.Write(BUS_ADDRESS); - } - - private static void MEMReadState(ref BinaryReader bin) - { - mem_board.ReadStateData(ref bin); - bin.Read(mem_wram, 0, mem_wram.Length); - BUS_RW = bin.ReadBoolean(); - BUS_ADDRESS = bin.ReadUInt16(); - } - - private static void PORTSInitialize() - { - if (joypad1 == null) - { - joypad1 = new BlankJoypad(); - } - if (joypad2 == null) - { - joypad2 = new BlankJoypad(); - } - if (joypad3 == null) - { - joypad3 = new BlankJoypad(); - } - if (joypad4 == null) - { - joypad4 = new BlankJoypad(); - } - if (shortucts == null) - { - shortucts = new BlankShortuctsHandler(); - } - } - - public static void SetupShortcutsHandler(IShortcutsHandler hh) - { - shortucts = hh; - } - - public static void SetupControllers(IJoypadConnecter joy1, IJoypadConnecter joy2, IJoypadConnecter joy3, IJoypadConnecter joy4) - { - joypad1 = joy1; - joypad2 = joy2; - joypad3 = joy3; - joypad4 = joy4; - } - - public static void SetupVSUnisystemDIP(IVSUnisystemDIPConnecter uni) - { - } - - public static void SetupControllersP1(IJoypadConnecter joy) - { - joypad1 = joy; - } - - public static void SetupControllersP2(IJoypadConnecter joy) - { - joypad2 = joy; - } - - public static void SetupControllersP3(IJoypadConnecter joy) - { - joypad3 = joy; - } - - public static void SetupControllersP4(IJoypadConnecter joy) - { - joypad4 = joy; - } - - public static void DestroyJoypads() - { - if (joypad1 == null) - { - joypad1 = new BlankJoypad(); - } - else - { - joypad1.Destroy(); - } - if (joypad2 == null) - { - joypad2 = new BlankJoypad(); - } - else - { - joypad1.Destroy(); - } - if (joypad3 == null) - { - joypad3 = new BlankJoypad(); - } - else - { - joypad1.Destroy(); - } - if (joypad4 == null) - { - joypad4 = new BlankJoypad(); - } - else - { - joypad1.Destroy(); - } - } - - private static void PORTWriteState(ref BinaryWriter bin) - { - bin.Write(PORT0); - bin.Write(PORT1); - bin.Write(inputStrobe); - } - - private static void PORTReadState(ref BinaryReader bin) - { - PORT0 = bin.ReadInt32(); - PORT1 = bin.ReadInt32(); - inputStrobe = bin.ReadInt32(); - } - - private static void PPUInitialize() - { - ppu_reg_update_func = new Action[8] { PPUOnRegister2000, PPUOnRegister2001, PPUOnRegister2002, PPUOnRegister2003, PPUOnRegister2004, PPUOnRegister2005, PPUOnRegister2006, PPUOnRegister2007 }; - ppu_reg_read_func = new Action[8] { PPURead2000, PPURead2001, PPURead2002, PPURead2003, PPURead2004, PPURead2005, PPURead2006, PPURead2007 }; - ppu_bkg_fetches = new Action[8] { PPUBKFetch0, PPUBKFetch1, PPUBKFetch2, PPUBKFetch3, PPUBKFetch4, PPUBKFetch5, PPUBKFetch6, PPUBKFetch7 }; - ppu_spr_fetches = new Action[8] { PPUBKFetch0, PPUBKFetch1, PPUBKFetch2, PPUBKFetch3, PPUSPRFetch0, PPUSPRFetch1, PPUSPRFetch2, PPUSPRFetch3 }; - ppu_oam_phases = new Action[9] { PPUOamPhase0, PPUOamPhase1, PPUOamPhase2, PPUOamPhase3, PPUOamPhase4, PPUOamPhase5, PPUOamPhase6, PPUOamPhase7, PPUOamPhase8 }; - ppu_h_clocks = new Action[341]; - ppu_h_clocks[0] = PPUHClock_000_Idle; - for (int i = 1; i < 257; i++) - { - ppu_h_clocks[i] = PPUHClock_1_256_BKGClocks; - } - for (int j = 257; j < 321; j++) - { - ppu_h_clocks[j] = PPUHClock_257_320_SPRClocks; - } - for (int k = 321; k < 337; k++) - { - ppu_h_clocks[k] = PPUHClock_321_336_DUMClocks; - } - for (int l = 337; l < 341; l++) - { - ppu_h_clocks[l] = PPUHClock_337_340_DUMClocks; - } - ppu_v_clocks = new Action[320]; - for (int m = 0; m < 240; m++) - { - ppu_v_clocks[m] = PPUScanlineRender; - } - ppu_v_clocks[240] = PPUScanlineVBLANK; - ppu_oam_bank = new byte[256]; - ppu_oam_bank_secondary = new byte[32]; - ppu_palette_bank = new byte[32]; - ppu_bkg_pixels = new int[512]; - ppu_spr_pixels = new int[512]; - ppu_screen_pixels = new int[61440]; - } - - private static void PPUHardReset() - { - ppu_reg_2001_grayscale = false; - switch (Region) - { - case EmuRegion.NTSC: - ppu_clock_vblank_start = 241; - ppu_clock_vblank_end = 261; - ppu_use_odd_cycle = true; - break; - case EmuRegion.PALB: - ppu_clock_vblank_start = 241; - ppu_clock_vblank_end = 311; - ppu_use_odd_cycle = false; - break; - case EmuRegion.DENDY: - { - ppu_clock_vblank_start = 291; - ppu_clock_vblank_end = 311; - for (int i = 241; i <= 290; i++) - { - ppu_v_clocks[i] = PPUScanlineVBLANK; - } - ppu_use_odd_cycle = false; - break; - } - } - ppu_v_clocks[ppu_clock_vblank_start] = PPUScanlineVBLANKStart; - for (int j = ppu_clock_vblank_start + 1; j <= ppu_clock_vblank_end - 1; j++) - { - ppu_v_clocks[j] = PPUScanlineVBLANK; - } - ppu_v_clocks[ppu_clock_vblank_end] = PPUScanlineVBLANKEnd; - ppu_oam_bank = new byte[256]; - ppu_oam_bank_secondary = new byte[32]; - PPUOamReset(); - ppu_palette_bank = new byte[32] - { - 9, 1, 0, 1, 0, 2, 2, 13, 8, 16, - 8, 36, 0, 0, 4, 44, 9, 1, 52, 3, - 0, 4, 0, 20, 8, 58, 0, 2, 0, 32, - 44, 8 - }; - ppu_reg_io_db = 0; - ppu_reg_io_addr = 0; - ppu_reg_access_happened = false; - ppu_reg_access_w = false; - ppu_reg_2000_vram_address_increament = 1; - ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites = 0; - ppu_reg_2000_background_pattern_table_address = 0; - ppu_reg_2000_Sprite_size = 0; - ppu_reg_2000_VBI = false; - ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen = false; - ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen = false; - ppu_reg_2001_show_background = false; - ppu_reg_2001_show_sprites = false; - ppu_reg_2001_grayscale = false; - ppu_reg_2001_emphasis = 0; - ppu_reg_2002_SpriteOverflow = false; - ppu_reg_2002_Sprite0Hit = false; - ppu_reg_2002_VblankStartedFlag = false; - ppu_reg_2003_oam_addr = 0; - ppu_is_sprfetch = false; - ppu_use_odd_swap = false; - ppu_clock_h = 0; - ppu_clock_v = 0; - } - - private static void PPUClock() - { - mem_board.OnPPUClock(); - ppu_v_clocks[ppu_clock_v](); - ppu_clock_h++; - if (ppu_clock_h >= 341) - { - mem_board.OnPPUScanlineTick(); - if (ppu_clock_v == ppu_clock_vblank_end) - { - ppu_clock_v = 0; - } - else - { - ppu_clock_v++; - } - ppu_clock_h = 0; - } - if (ppu_reg_access_happened) - { - ppu_reg_access_happened = false; - ppu_reg_update_func[ppu_reg_io_addr](); - } - } - - public static int GetPixel(int x, int y) - { - return ppu_screen_pixels[y * 256 + x]; - } - - private static void PPUScanlineRender() - { - ppu_h_clocks[ppu_clock_h](); - } - - private static void PPUScanlineVBLANKStart() - { - ppu_is_nmi_time = (ppu_clock_h >= 1) & (ppu_clock_h <= 3); - if (ppu_is_nmi_time) - { - if (ppu_clock_h == 1) - { - ppu_reg_2002_VblankStartedFlag = true; - ppu_frame_finished = true; - } - PPU_NMI_Current = ppu_reg_2002_VblankStartedFlag & ppu_reg_2000_VBI; - } - } - - private static void PPUScanlineVBLANKEnd() - { - ppu_is_nmi_time = (ppu_clock_h >= 1) & (ppu_clock_h <= 3); - if (ppu_clock_h == 1) - { - ppu_reg_2002_Sprite0Hit = false; - ppu_reg_2002_VblankStartedFlag = false; - ppu_reg_2002_SpriteOverflow = false; - } - PPUScanlineRender(); - if (ppu_use_odd_cycle && ppu_clock_h == 339) - { - ppu_use_odd_swap = !ppu_use_odd_swap; - if (!ppu_use_odd_swap & (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites)) - { - ppu_odd_swap_done = true; - ppu_clock_h++; - } - } - } - - private static void PPUScanlineVBLANK() - { - } - - private static void PPUHClock_000_Idle() - { - if (ppu_odd_swap_done) - { - ppu_bkg_fetches[1](); - ppu_odd_swap_done = false; - } - } - - private static void PPUHClock_1_256_BKGClocks() - { - if (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites) - { - if (ppu_clock_v != ppu_clock_vblank_end) - { - if (ppu_clock_h > 0 && ppu_clock_h < 65) - { - ppu_oam_bank_secondary[(ppu_clock_h - 1) & 0x1F] = byte.MaxValue; - } - else - { - if (ppu_clock_h == 65) - { - PPUOamReset(); - } - if (((ppu_clock_h - 1) & 1) == 0) - { - PPUOamEvFetch(); - } - else - { - ppu_oam_phases[ppu_phase_index](); - } - if (ppu_clock_h == 256) - { - PPUOamClear(); - } - } - } - ppu_bkg_fetches[(ppu_clock_h - 1) & 7](); - if (ppu_clock_v < 240) - { - RenderPixel(); - } - } - else if (ppu_clock_v < 240) - { - ppu_screen_pixels[ppu_clock_h - 1 + ppu_clock_v * 256] = MakeRGBColor(ppu_vram_addr); - } - } - - private static void PPUHClock_257_320_SPRClocks() - { - if (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites) - { - ppu_spr_fetches[(ppu_clock_h - 1) & 7](); - if (ppu_clock_h == 257) - { - ppu_vram_addr = (ushort)((ppu_vram_addr & 0x7BE0u) | (ppu_vram_addr_temp & 0x41Fu)); - } - if (ppu_clock_v == ppu_clock_vblank_end && ppu_clock_h >= 280 && ppu_clock_h <= 304) - { - ppu_vram_addr = (ushort)((ppu_vram_addr & 0x41Fu) | (ppu_vram_addr_temp & 0x7BE0u)); - } - } - } - - private static void PPUHClock_321_336_DUMClocks() - { - if (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites) - { - ppu_bkg_fetches[(ppu_clock_h - 1) & 7](); - } - } - - private static void PPUHClock_337_340_DUMClocks() - { - if (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites) - { - ppu_bkg_fetches[(ppu_clock_h - 1) & 1](); - } - } - - private static void PPUBKFetch0() - { - ppu_bkgfetch_nt_addr = (ushort)(0x2000u | (ppu_vram_addr & 0xFFFu)); - mem_board.OnPPUAddressUpdate(ref ppu_bkgfetch_nt_addr); - } - - private static void PPUBKFetch1() - { - mem_board.ReadNMT(ref ppu_bkgfetch_nt_addr, out ppu_bkgfetch_nt_data); - } - - private static void PPUBKFetch2() - { - ppu_bkgfetch_at_addr = (ushort)(0x23C0u | (ppu_vram_addr & 0xC00u) | ((uint)(ppu_vram_addr >> 4) & 0x38u) | ((uint)(ppu_vram_addr >> 2) & 7u)); - mem_board.OnPPUAddressUpdate(ref ppu_bkgfetch_at_addr); - } - - private static void PPUBKFetch3() - { - mem_board.ReadNMT(ref ppu_bkgfetch_at_addr, out ppu_bkgfetch_at_data); - ppu_bkgfetch_at_data = (byte)(ppu_bkgfetch_at_data >> (((ppu_vram_addr >> 4) & 4) | (ppu_vram_addr & 2))); - } - - private static void PPUBKFetch4() - { - ppu_bkgfetch_lb_addr = (ushort)((uint)(ppu_reg_2000_background_pattern_table_address | (ppu_bkgfetch_nt_data << 4)) | ((uint)(ppu_vram_addr >> 12) & 7u)); - mem_board.OnPPUAddressUpdate(ref ppu_bkgfetch_lb_addr); - } - - private static void PPUBKFetch5() - { - mem_board.ReadCHR(ref ppu_bkgfetch_lb_addr, out ppu_bkgfetch_lb_data); - } - - private static void PPUBKFetch6() - { - ppu_bkgfetch_hb_addr = (ushort)((uint)(ppu_reg_2000_background_pattern_table_address | (ppu_bkgfetch_nt_data << 4)) | 8u | ((uint)(ppu_vram_addr >> 12) & 7u)); - mem_board.OnPPUAddressUpdate(ref ppu_bkgfetch_hb_addr); - } - - private static void PPUBKFetch7() - { - mem_board.ReadCHR(ref ppu_bkgfetch_hb_addr, out ppu_bkgfetch_hb_data); - ppu_bkg_render_pos = ppu_clock_h + 8; - ppu_bkg_render_pos %= 336; - if (ppu_clock_h == 256) - { - if ((ppu_vram_addr & 0x7000) != 28672) - { - ppu_vram_addr += 4096; - } - else - { - ppu_vram_addr ^= 28672; - switch (ppu_vram_addr & 0x3E0) - { - case 928: - ppu_vram_addr ^= 2976; - break; - case 992: - ppu_vram_addr ^= 992; - break; - default: - ppu_vram_addr += 32; - break; - } - } - } - else if ((ppu_vram_addr & 0x1F) == 31) - { - ppu_vram_addr ^= 1055; - } - else - { - ppu_vram_addr++; - } - for (ppu_bkg_render_i = 0; ppu_bkg_render_i < 8; ppu_bkg_render_i++) - { - ppu_bkg_render_tmp_val = ((ppu_bkgfetch_at_data << 2) & 0xC) | ((ppu_bkgfetch_lb_data >> 7) & 1) | ((ppu_bkgfetch_hb_data >> 6) & 2); - ppu_bkg_pixels[ppu_bkg_render_i + ppu_bkg_render_pos] = ppu_bkg_render_tmp_val; - ppu_bkgfetch_lb_data <<= 1; - ppu_bkgfetch_hb_data <<= 1; - } - } - - private static void PPUSPRFetch0() - { - ppu_sprfetch_slot = (ppu_clock_h - 1 >> 3) & 7; - ppu_sprfetch_slot = 7 - ppu_sprfetch_slot; - ppu_sprfetch_y_data = ppu_oam_bank_secondary[ppu_sprfetch_slot * 4]; - ppu_sprfetch_t_data = ppu_oam_bank_secondary[ppu_sprfetch_slot * 4 + 1]; - ppu_sprfetch_at_data = ppu_oam_bank_secondary[ppu_sprfetch_slot * 4 + 2]; - ppu_sprfetch_x_data = ppu_oam_bank_secondary[ppu_sprfetch_slot * 4 + 3]; - ppu_temp_comparator = (ppu_clock_v - ppu_sprfetch_y_data) ^ (((ppu_sprfetch_at_data & 0x80u) != 0) ? 15 : 0); - if (ppu_reg_2000_Sprite_size == 16) - { - ppu_sprfetch_lb_addr = (ushort)(((uint)(ppu_sprfetch_t_data << 12) & 0x1000u) | ((uint)(ppu_sprfetch_t_data << 4) & 0xFE0u) | ((uint)(ppu_temp_comparator << 1) & 0x10u) | ((uint)ppu_temp_comparator & 7u)); - } - else - { - ppu_sprfetch_lb_addr = (ushort)((uint)(ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites | (ppu_sprfetch_t_data << 4)) | ((uint)ppu_temp_comparator & 7u)); - } - mem_board.OnPPUAddressUpdate(ref ppu_sprfetch_lb_addr); - } - - private static void PPUSPRFetch1() - { - ppu_is_sprfetch = true; - mem_board.ReadCHR(ref ppu_sprfetch_lb_addr, out ppu_sprfetch_lb_data); - ppu_is_sprfetch = false; - if ((ppu_sprfetch_at_data & 0x40u) != 0) - { - ppu_sprfetch_lb_data = reverseLookup[ppu_sprfetch_lb_data]; - } - } - - private static void PPUSPRFetch2() - { - ppu_sprfetch_hb_addr = (ushort)(ppu_sprfetch_lb_addr | 8u); - mem_board.OnPPUAddressUpdate(ref ppu_sprfetch_hb_addr); - } - - private static void PPUSPRFetch3() - { - ppu_is_sprfetch = true; - mem_board.ReadCHR(ref ppu_sprfetch_hb_addr, out ppu_sprfetch_hb_data); - ppu_is_sprfetch = false; - if ((ppu_sprfetch_at_data & 0x40u) != 0) - { - ppu_sprfetch_hb_data = reverseLookup[ppu_sprfetch_hb_data]; - } - if (ppu_sprfetch_x_data == byte.MaxValue) - { - return; - } - for (ppu_bkg_render_i = 0; ppu_bkg_render_i < 8; ppu_bkg_render_i++) - { - if (ppu_sprfetch_x_data < byte.MaxValue) - { - ppu_bkg_render_tmp_val = ((ppu_sprfetch_at_data << 2) & 0xC) | ((ppu_sprfetch_lb_data >> 7) & 1) | ((ppu_sprfetch_hb_data >> 6) & 2); - if (((uint)ppu_bkg_render_tmp_val & 3u) != 0) - { - ppu_spr_pixels[ppu_sprfetch_x_data] = ppu_bkg_render_tmp_val; - if (ppu_sprfetch_slot == 0 && ppu_sprite0_should_hit) - { - ppu_spr_pixels[ppu_sprfetch_x_data] |= 16384; - } - if ((ppu_sprfetch_at_data & 0x20) == 0) - { - ppu_spr_pixels[ppu_sprfetch_x_data] |= 32768; - } - } - ppu_sprfetch_lb_data <<= 1; - ppu_sprfetch_hb_data <<= 1; - ppu_sprfetch_x_data++; - } - } - } - - private static void PPUOamReset() - { - ppu_oamev_n = 0; - ppu_oamev_m = 0; - ppu_oamev_slot = 0; - ppu_phase_index = 0; - ppu_sprite0_should_hit = false; - } - - private static void PPUOamClear() - { - for (int i = 0; i < ppu_spr_pixels.Length; i++) - { - ppu_spr_pixels[i] = 0; - } - } - - private static void PPUOamEvFetch() - { - ppu_fetch_data = ppu_oam_bank[ppu_oamev_n * 4 + ppu_oamev_m]; - } - - private static void PPUOamPhase0() - { - ppu_oamev_compare = ppu_clock_v >= ppu_fetch_data && ppu_clock_v < ppu_fetch_data + ppu_reg_2000_Sprite_size; - if (ppu_oamev_compare) - { - ppu_oam_bank_secondary[ppu_oamev_slot * 4] = ppu_fetch_data; - ppu_oamev_m = 1; - ppu_phase_index++; - if (ppu_oamev_n == 0) - { - ppu_sprite0_should_hit = true; - } - } - else - { - ppu_oamev_m = 0; - ppu_oamev_n++; - if (ppu_oamev_n == 64) - { - ppu_oamev_n = 0; - ppu_phase_index = 8; - } - } - } - - private static void PPUOamPhase1() - { - ppu_oam_bank_secondary[ppu_oamev_slot * 4 + ppu_oamev_m] = ppu_fetch_data; - ppu_oamev_m = 2; - ppu_phase_index++; - } - - private static void PPUOamPhase2() - { - ppu_oam_bank_secondary[ppu_oamev_slot * 4 + ppu_oamev_m] = ppu_fetch_data; - ppu_oamev_m = 3; - ppu_phase_index++; - } - - private static void PPUOamPhase3() - { - ppu_oam_bank_secondary[ppu_oamev_slot * 4 + ppu_oamev_m] = ppu_fetch_data; - ppu_oamev_m = 0; - ppu_oamev_n++; - ppu_oamev_slot++; - if (ppu_oamev_n == 64) - { - ppu_oamev_n = 0; - ppu_phase_index = 8; - } - else if (ppu_oamev_slot < 8) - { - ppu_phase_index = 0; - } - else if (ppu_oamev_slot == 8) - { - ppu_phase_index = 4; - } - } - - private static void PPUOamPhase4() - { - ppu_oamev_compare = ppu_clock_v >= ppu_fetch_data && ppu_clock_v < ppu_fetch_data + ppu_reg_2000_Sprite_size; - if (ppu_oamev_compare) - { - ppu_oamev_m = 1; - ppu_phase_index++; - ppu_reg_2002_SpriteOverflow = true; - return; - } - ppu_oamev_m++; - if (ppu_oamev_m == 4) - { - ppu_oamev_m = 0; - } - ppu_oamev_n++; - if (ppu_oamev_n == 64) - { - ppu_oamev_n = 0; - ppu_phase_index = 8; - } - else - { - ppu_phase_index = 4; - } - } - - private static void PPUOamPhase5() - { - ppu_oamev_m = 2; - ppu_phase_index++; - } - - private static void PPUOamPhase6() - { - ppu_oamev_m = 3; - ppu_phase_index++; - } - - private static void PPUOamPhase7() - { - ppu_oamev_m = 0; - ppu_oamev_n++; - if (ppu_oamev_n == 64) - { - ppu_oamev_n = 0; - } - ppu_phase_index = 8; - } - - private static void PPUOamPhase8() - { - ppu_oamev_n++; - if (ppu_oamev_n >= 64) - { - ppu_oamev_n = 0; - } - } - - private static void RenderPixel() - { - if (ppu_clock_v == ppu_clock_vblank_end) - { - return; - } - ppu_render_x = ppu_clock_h - 1; - ppu_render_y = ppu_clock_v * 256; - if (ppu_render_x < 8) - { - if (ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen) - { - ppu_bkg_current_pixel = 0x3F00 | ppu_bkg_pixels[ppu_render_x + ppu_vram_finex]; - } - else - { - ppu_bkg_current_pixel = 16128; - } - if (ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen) - { - ppu_spr_current_pixel = 0x3F10 | ppu_spr_pixels[ppu_render_x]; - } - else - { - ppu_spr_current_pixel = 16144; - } - } - else - { - if (!ppu_reg_2001_show_background) - { - ppu_bkg_current_pixel = 16128; - } - else - { - ppu_bkg_current_pixel = 0x3F00 | ppu_bkg_pixels[ppu_render_x + ppu_vram_finex]; - } - if (!ppu_reg_2001_show_sprites || ppu_clock_v == 0) - { - ppu_spr_current_pixel = 16144; - } - else - { - ppu_spr_current_pixel = 0x3F10 | ppu_spr_pixels[ppu_render_x]; - } - } - ppu_current_pixel = 0; - if (((uint)ppu_spr_current_pixel & 0x8000u) != 0) - { - ppu_current_pixel = ppu_spr_current_pixel; - } - else - { - ppu_current_pixel = ppu_bkg_current_pixel; - } - if ((ppu_bkg_current_pixel & 3) == 0) - { - ppu_current_pixel = ppu_spr_current_pixel; - } - else if ((ppu_spr_current_pixel & 3) == 0) - { - ppu_current_pixel = ppu_bkg_current_pixel; - } - else if (((uint)ppu_spr_pixels[ppu_render_x] & 0x4000u) != 0) - { - ppu_reg_2002_Sprite0Hit = true; - } - ppu_screen_pixels[ppu_render_x + ppu_render_y] = MakeRGBColor(ppu_current_pixel); - } - - private static int MakeRGBColor(int pixel) - { - pixel = ((pixel < 16128) ? 15 : ((((uint)ppu_current_pixel & 3u) != 0) ? ppu_palette_bank[pixel & 0x1F] : ppu_palette_bank[pixel & 0xC])); - ppu_palette_temp__val = pixel & 0xF; - ppu_color_temp__level = (pixel & 0x30) << 2; - if (ppu_reg_2001_grayscale) - { - ppu_palette_temp__val = 0; - } - ppu_color_temp__blue = (ppu_color_temp_blue__sequence[ppu_palette_temp__val] << 3) | ppu_color_temp__level; - ppu_color_temp__red = (ppu_color_temp_red___sequence[ppu_palette_temp__val] << 3) | ppu_color_temp__level; - ppu_color_temp__green = (ppu_color_temp_green_sequence[ppu_palette_temp__val] << 3) | ppu_color_temp__level; - if (SystemIndex == 0) - { - ppu_color_temp__e_red = (ppu_reg_2001_emphasis & 1) != 0; - } - else - { - ppu_color_temp__e_green = (ppu_reg_2001_emphasis & 1) != 0; - } - if (SystemIndex == 0) - { - ppu_color_temp__e_green = (ppu_reg_2001_emphasis & 2) != 0; - } - else - { - ppu_color_temp__e_red = (ppu_reg_2001_emphasis & 2) != 0; - } - ppu_color_temp__e_blue = (ppu_reg_2001_emphasis & 4) != 0; - if (ppu_color_temp__e_blue) - { - ppu_color_temp__blue |= 7; - } - if (ppu_color_temp__e_red) - { - ppu_color_temp__red |= 7; - } - if (ppu_color_temp__e_green) - { - ppu_color_temp__green |= 7; - } - return (ppu_color_temp__red << 16) | (ppu_color_temp__green << 8) | ppu_color_temp__blue; - } - - private static void PPUIORead(ref ushort addr, out byte value) - { - ppu_reg_io_addr = (byte)(addr & 7u); - ppu_reg_access_happened = true; - ppu_reg_access_w = false; - ppu_reg_read_func[ppu_reg_io_addr](); - value = ppu_reg_io_db; - } - - private static void PPUIOWrite(ref ushort addr, ref byte value) - { - ppu_reg_io_addr = (byte)(addr & 7u); - ppu_reg_io_db = value; - ppu_reg_access_w = true; - ppu_reg_access_happened = true; - } - - private static void PPUOnRegister2000() - { - if (ppu_reg_access_w) - { - ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0x73FFu) | (uint)((ppu_reg_io_db & 3) << 10)); - if ((ppu_reg_io_db & 4u) != 0) - { - ppu_reg_2000_vram_address_increament = 32; - } - else - { - ppu_reg_2000_vram_address_increament = 1; - } - if ((ppu_reg_io_db & 8u) != 0) - { - ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites = 4096; - } - else - { - ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites = 0; - } - if ((ppu_reg_io_db & 0x10u) != 0) - { - ppu_reg_2000_background_pattern_table_address = 4096; - } - else - { - ppu_reg_2000_background_pattern_table_address = 0; - } - if ((ppu_reg_io_db & 0x20u) != 0) - { - ppu_reg_2000_Sprite_size = 16; - } - else - { - ppu_reg_2000_Sprite_size = 8; - } - if (!ppu_reg_2000_VBI && (ppu_reg_io_db & 0x80u) != 0 && ppu_reg_2002_VblankStartedFlag) - { - PPU_NMI_Current = true; - } - ppu_reg_2000_VBI = (ppu_reg_io_db & 0x80) != 0; - if (!ppu_reg_2000_VBI && ppu_is_nmi_time) - { - PPU_NMI_Current = false; - } - } - } - - private static void PPUOnRegister2001() - { - if (ppu_reg_access_w) - { - ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen = (ppu_reg_io_db & 2) != 0; - ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen = (ppu_reg_io_db & 4) != 0; - ppu_reg_2001_show_background = (ppu_reg_io_db & 8) != 0; - ppu_reg_2001_show_sprites = (ppu_reg_io_db & 0x10) != 0; - ppu_reg_2001_grayscale = (ppu_reg_io_db & 1) != 0; - ppu_reg_2001_emphasis = (ppu_reg_io_db & 0xE0) >> 5; - } - } - - private static void PPUOnRegister2002() - { - if (!ppu_reg_access_w) - { - ppu_vram_flip_flop = false; - ppu_reg_2002_VblankStartedFlag = false; - if (ppu_clock_v == ppu_clock_vblank_start) - { - PPU_NMI_Current = ppu_reg_2002_VblankStartedFlag & ppu_reg_2000_VBI; - } - } - } - - private static void PPUOnRegister2003() - { - if (ppu_reg_access_w) - { - ppu_reg_2003_oam_addr = ppu_reg_io_db; - } - } - - private static void PPUOnRegister2004() - { - if (ppu_reg_access_w) - { - if (ppu_clock_v < 240 && IsRenderingOn()) - { - ppu_reg_io_db = byte.MaxValue; - } - if ((ppu_reg_2003_oam_addr & 3) == 2) - { - ppu_reg_io_db &= 227; - } - ppu_oam_bank[ppu_reg_2003_oam_addr] = ppu_reg_io_db; - ppu_reg_2003_oam_addr = (byte)((uint)(ppu_reg_2003_oam_addr + 1) & 0xFFu); - } - } - - private static void PPUOnRegister2005() - { - if (ppu_reg_access_w) - { - if (!ppu_vram_flip_flop) - { - ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0x7FE0u) | (uint)((ppu_reg_io_db & 0xF8) >> 3)); - ppu_vram_finex = (byte)(ppu_reg_io_db & 7u); - } - else - { - ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0xC1Fu) | (uint)((ppu_reg_io_db & 7) << 12) | (uint)((ppu_reg_io_db & 0xF8) << 2)); - } - ppu_vram_flip_flop = !ppu_vram_flip_flop; - } - } - - private static void PPUOnRegister2006() - { - if (ppu_reg_access_w) - { - if (!ppu_vram_flip_flop) - { - ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0xFFu) | (uint)((ppu_reg_io_db & 0x3F) << 8)); - } - else - { - ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0x7F00u) | ppu_reg_io_db); - ppu_vram_addr = ppu_vram_addr_temp; - mem_board.OnPPUAddressUpdate(ref ppu_vram_addr); - } - ppu_vram_flip_flop = !ppu_vram_flip_flop; - } - } - - private static void PPUOnRegister2007() - { - if (ppu_reg_access_w) - { - ppu_vram_addr_access_temp = (ushort)(ppu_vram_addr & 0x3FFFu); - if (ppu_vram_addr_access_temp < 8192) - { - mem_board.WriteCHR(ref ppu_vram_addr_access_temp, ref ppu_reg_io_db); - } - else if (ppu_vram_addr_access_temp < 16128) - { - mem_board.WriteNMT(ref ppu_vram_addr_access_temp, ref ppu_reg_io_db); - } - else if ((ppu_vram_addr_access_temp & 3u) != 0) - { - ppu_palette_bank[ppu_vram_addr_access_temp & 0x1F] = ppu_reg_io_db; - } - else - { - ppu_palette_bank[ppu_vram_addr_access_temp & 0xC] = ppu_reg_io_db; - } - } - else - { - if ((ppu_vram_addr & 0x3F00) == 16128) - { - ppu_vram_addr_access_temp = (ushort)(ppu_vram_addr & 0x2FFFu); - } - else - { - ppu_vram_addr_access_temp = (ushort)(ppu_vram_addr & 0x3FFFu); - } - if (ppu_vram_addr_access_temp < 8192) - { - mem_board.ReadCHR(ref ppu_vram_addr_access_temp, out ppu_vram_data); - } - else if (ppu_vram_addr_access_temp < 16128) - { - mem_board.ReadNMT(ref ppu_vram_addr_access_temp, out ppu_vram_data); - } - } - ppu_vram_addr = (ushort)((uint)(ppu_vram_addr + ppu_reg_2000_vram_address_increament) & 0x7FFFu); - mem_board.OnPPUAddressUpdate(ref ppu_vram_addr); - } - - private static void PPURead2000() - { - } - - private static void PPURead2001() - { - } - - private static void PPURead2002() - { - ppu_reg_io_db = (byte)((ppu_reg_io_db & 0xDFu) | (ppu_reg_2002_SpriteOverflow ? 32u : 0u)); - ppu_reg_io_db = (byte)((ppu_reg_io_db & 0xBFu) | (ppu_reg_2002_Sprite0Hit ? 64u : 0u)); - ppu_reg_io_db = (byte)((ppu_reg_io_db & 0x7Fu) | (ppu_reg_2002_VblankStartedFlag ? 128u : 0u)); - } - - private static void PPURead2003() - { - } - - private static void PPURead2004() - { - ppu_reg_io_db = ppu_oam_bank[ppu_reg_2003_oam_addr]; - if (ppu_clock_v < 240 && IsRenderingOn()) - { - if (ppu_clock_h < 64) - { - ppu_reg_io_db = byte.MaxValue; - } - else if (ppu_clock_h < 192) - { - ppu_reg_io_db = ppu_oam_bank[(ppu_clock_h - 64 << 1) & 0xFC]; - } - else if (ppu_clock_h < 256) - { - ppu_reg_io_db = (((ppu_clock_h & 1) == 1) ? ppu_oam_bank[252] : ppu_oam_bank[(ppu_clock_h - 192 << 1) & 0xFC]); - } - else if (ppu_clock_h < 320) - { - ppu_reg_io_db = byte.MaxValue; - } - else - { - ppu_reg_io_db = ppu_oam_bank[0]; - } - } - } - - private static void PPURead2005() - { - } - - private static void PPURead2006() - { - } - - private static void PPURead2007() - { - ppu_vram_addr_access_temp = (ushort)(ppu_vram_addr & 0x3FFFu); - if (ppu_vram_addr_access_temp < 16128) - { - ppu_reg_io_db = ppu_vram_data; - } - else if ((ppu_vram_addr_access_temp & 3u) != 0) - { - ppu_reg_io_db = ppu_palette_bank[ppu_vram_addr_access_temp & 0x1F]; - } - else - { - ppu_reg_io_db = ppu_palette_bank[ppu_vram_addr_access_temp & 0xC]; - } - } - - internal static bool IsRenderingOn() - { - return ppu_reg_2001_show_background || ppu_reg_2001_show_sprites; - } - - internal static bool IsInRender() - { - return ppu_clock_v < 240 || ppu_clock_v == ppu_clock_vblank_end; - } - - private static void PPUWriteState(ref BinaryWriter bin) - { - bin.Write(ppu_clock_h); - bin.Write(ppu_clock_v); - bin.Write(ppu_clock_vblank_start); - bin.Write(ppu_clock_vblank_end); - bin.Write(ppu_use_odd_cycle); - bin.Write(ppu_use_odd_swap); - bin.Write(ppu_is_nmi_time); - bin.Write(ppu_frame_finished); - bin.Write(ppu_oam_bank); - bin.Write(ppu_oam_bank_secondary); - bin.Write(ppu_palette_bank); - bin.Write(ppu_reg_io_db); - bin.Write(ppu_reg_io_addr); - bin.Write(ppu_reg_access_happened); - bin.Write(ppu_reg_access_w); - bin.Write(ppu_reg_2000_vram_address_increament); - bin.Write(ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites); - bin.Write(ppu_reg_2000_background_pattern_table_address); - bin.Write(ppu_reg_2000_Sprite_size); - bin.Write(ppu_reg_2000_VBI); - bin.Write(ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen); - bin.Write(ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen); - bin.Write(ppu_reg_2001_show_background); - bin.Write(ppu_reg_2001_show_sprites); - bin.Write(ppu_reg_2001_grayscale ? 1 : 0); - bin.Write(ppu_reg_2001_emphasis); - bin.Write(ppu_reg_2002_SpriteOverflow); - bin.Write(ppu_reg_2002_Sprite0Hit); - bin.Write(ppu_reg_2002_VblankStartedFlag); - bin.Write(ppu_reg_2003_oam_addr); - bin.Write(ppu_vram_addr); - bin.Write(ppu_vram_data); - bin.Write(ppu_vram_addr_temp); - bin.Write(ppu_vram_addr_access_temp); - bin.Write(ppu_vram_flip_flop); - bin.Write(ppu_vram_finex); - bin.Write(ppu_bkgfetch_nt_addr); - bin.Write(ppu_bkgfetch_nt_data); - bin.Write(ppu_bkgfetch_at_addr); - bin.Write(ppu_bkgfetch_at_data); - bin.Write(ppu_bkgfetch_lb_addr); - bin.Write(ppu_bkgfetch_lb_data); - bin.Write(ppu_bkgfetch_hb_addr); - bin.Write(ppu_bkgfetch_hb_data); - bin.Write(ppu_sprfetch_slot); - bin.Write(ppu_sprfetch_y_data); - bin.Write(ppu_sprfetch_t_data); - bin.Write(ppu_sprfetch_at_data); - bin.Write(ppu_sprfetch_x_data); - bin.Write(ppu_sprfetch_lb_addr); - bin.Write(ppu_sprfetch_lb_data); - bin.Write(ppu_sprfetch_hb_addr); - bin.Write(ppu_sprfetch_hb_data); - bin.Write(ppu_bkg_render_i); - bin.Write(ppu_bkg_render_pos); - bin.Write(ppu_bkg_render_tmp_val); - bin.Write(ppu_bkg_current_pixel); - bin.Write(ppu_spr_current_pixel); - bin.Write(ppu_current_pixel); - bin.Write(ppu_render_x); - bin.Write(0); - bin.Write(ppu_oamev_n); - bin.Write(ppu_oamev_m); - bin.Write(ppu_oamev_compare); - bin.Write(ppu_oamev_slot); - bin.Write(ppu_fetch_data); - bin.Write(ppu_phase_index); - bin.Write(ppu_sprite0_should_hit); - } - - private static void PPUReadState(ref BinaryReader bin) - { - ppu_clock_h = bin.ReadInt32(); - ppu_clock_v = bin.ReadUInt16(); - ppu_clock_vblank_start = bin.ReadUInt16(); - ppu_clock_vblank_end = bin.ReadUInt16(); - ppu_use_odd_cycle = bin.ReadBoolean(); - ppu_use_odd_swap = bin.ReadBoolean(); - ppu_is_nmi_time = bin.ReadBoolean(); - ppu_frame_finished = bin.ReadBoolean(); - bin.Read(ppu_oam_bank, 0, ppu_oam_bank.Length); - bin.Read(ppu_oam_bank_secondary, 0, ppu_oam_bank_secondary.Length); - bin.Read(ppu_palette_bank, 0, ppu_palette_bank.Length); - ppu_reg_io_db = bin.ReadByte(); - ppu_reg_io_addr = bin.ReadByte(); - ppu_reg_access_happened = bin.ReadBoolean(); - ppu_reg_access_w = bin.ReadBoolean(); - ppu_reg_2000_vram_address_increament = bin.ReadByte(); - ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites = bin.ReadUInt16(); - ppu_reg_2000_background_pattern_table_address = bin.ReadUInt16(); - ppu_reg_2000_Sprite_size = bin.ReadByte(); - ppu_reg_2000_VBI = bin.ReadBoolean(); - ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen = bin.ReadBoolean(); - ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen = bin.ReadBoolean(); - ppu_reg_2001_show_background = bin.ReadBoolean(); - ppu_reg_2001_show_sprites = bin.ReadBoolean(); - ppu_reg_2001_grayscale = bin.ReadInt32() == 1; - ppu_reg_2001_emphasis = bin.ReadInt32(); - ppu_reg_2002_SpriteOverflow = bin.ReadBoolean(); - ppu_reg_2002_Sprite0Hit = bin.ReadBoolean(); - ppu_reg_2002_VblankStartedFlag = bin.ReadBoolean(); - ppu_reg_2003_oam_addr = bin.ReadByte(); - ppu_vram_addr = bin.ReadUInt16(); - ppu_vram_data = bin.ReadByte(); - ppu_vram_addr_temp = bin.ReadUInt16(); - ppu_vram_addr_access_temp = bin.ReadUInt16(); - ppu_vram_flip_flop = bin.ReadBoolean(); - ppu_vram_finex = bin.ReadByte(); - ppu_bkgfetch_nt_addr = bin.ReadUInt16(); - ppu_bkgfetch_nt_data = bin.ReadByte(); - ppu_bkgfetch_at_addr = bin.ReadUInt16(); - ppu_bkgfetch_at_data = bin.ReadByte(); - ppu_bkgfetch_lb_addr = bin.ReadUInt16(); - ppu_bkgfetch_lb_data = bin.ReadByte(); - ppu_bkgfetch_hb_addr = bin.ReadUInt16(); - ppu_bkgfetch_hb_data = bin.ReadByte(); - ppu_sprfetch_slot = bin.ReadInt32(); - ppu_sprfetch_y_data = bin.ReadByte(); - ppu_sprfetch_t_data = bin.ReadByte(); - ppu_sprfetch_at_data = bin.ReadByte(); - ppu_sprfetch_x_data = bin.ReadByte(); - ppu_sprfetch_lb_addr = bin.ReadUInt16(); - ppu_sprfetch_lb_data = bin.ReadByte(); - ppu_sprfetch_hb_addr = bin.ReadUInt16(); - ppu_sprfetch_hb_data = bin.ReadByte(); - ppu_bkg_render_i = bin.ReadInt32(); - ppu_bkg_render_pos = bin.ReadInt32(); - ppu_bkg_render_tmp_val = bin.ReadInt32(); - ppu_bkg_current_pixel = bin.ReadInt32(); - ppu_spr_current_pixel = bin.ReadInt32(); - ppu_current_pixel = bin.ReadInt32(); - ppu_render_x = bin.ReadInt32(); - bin.ReadInt32(); - ppu_oamev_n = bin.ReadByte(); - ppu_oamev_m = bin.ReadByte(); - ppu_oamev_compare = bin.ReadBoolean(); - ppu_oamev_slot = bin.ReadByte(); - ppu_fetch_data = bin.ReadByte(); - ppu_phase_index = bin.ReadByte(); - ppu_sprite0_should_hit = bin.ReadBoolean(); - } - - internal static void CheckGame(string fileName, out bool valid) - { - string text = Path.GetExtension(fileName).ToLower(); - string text2 = text; - if (text2 == ".nes") - { - Tracer.WriteLine("Checking INES header ..."); - INes nes = new INes(); - nes.Load(fileName, loadDumps: false); - valid = nes.IsValid; - Tracer.WriteLine("INES header is valid."); - } - else - { - Tracer.WriteWarning("File format is not supported. Format: " + Path.GetExtension(fileName)); - valid = false; - } - } - - internal static void Initialize() - { - Tracer.WriteLine("Loading database file ..."); - string text = Path.Combine(MyNesMain.AppPath, "database.xml"); - if (File.Exists(text)) - { - bool success = false; - NesCartDatabase.LoadDatabase(text, out success); - if (success) - { - Tracer.WriteInformation("Nes Cart database file loaded successfully."); - } - else - { - Tracer.WriteError("Error loading Nes Cart database file."); - } - } - else - { - Tracer.WriteWarning("Nes Cart database file cannot be located at " + text); - } - EmuClockComponents = EmuClockComponentsNTSC; - FrameLimiterEnabled = true; - CPUInitialize(); - PPUInitialize(); - APUInitialize(); - PORTSInitialize(); - } - - internal static void SetupRenderingMethods(RenderVideoFrame renderVideo, RenderAudioSamples renderAudio, TogglePause renderTogglePause, GetIsPlaying renderGetIsPlaying) - { - render_initialized = false; - render_video = renderVideo; - render_audio = renderAudio; - render_audio_toggle_pause = renderTogglePause; - render_audio_get_is_playing = renderGetIsPlaying; - render_initialized = render_video != null && render_audio != null && render_audio_toggle_pause != null && render_audio_get_is_playing != null; - if (render_initialized) - { - Tracer.WriteInformation("Renderer methods initialized successfully."); - return; - } - Tracer.WriteError("ERROR RENDERER INITIALIZING !!"); - Tracer.WriteError("Faild to initialize the renderers methods. Please use the method 'SetupRenderingMethods' to initialize the renderers methods before you can run the emulation."); - } - - public static void LoadGame(string fileName, out bool success) - { - if (!render_initialized) - { - Tracer.WriteError("NO RENDERER INITIALIZED !! EMU CANNOT BE INTIALIZED WITHOUT A RENDERER !!"); - Tracer.WriteError("Please use the method 'SetupRenderingMethods' to initialize the renderers methods before you can run the emulation."); - success = false; - return; - } - string text = Path.GetExtension(fileName).ToLower(); - string text2 = text; - if (text2 == ".nes") - { - Tracer.WriteLine("Checking INES header ..."); - INes nes = new INes(); - nes.Load(fileName, loadDumps: true); - if (nes.IsValid) - { - emu_request_mode = RequestMode.None; - CurrentFilePath = fileName; - if (ON) - { - ShutDown(); - } - Tracer.WriteLine("INES header is valid, loading game ..."); - MEMInitialize(nes); - ApplyRegionSetting(); - ApplyAudioSettings(); - ApplyFrameSkipSettings(); - PORTSInitialize(); - hardReset(); - Tracer.WriteLine("EMU is ready."); - success = true; - emu_frame_clocking_mode = !MyNesMain.RendererSettings.UseEmuThread; - ON = true; - PAUSED = false; - isPaused = false; - FrameLimiterEnabled = true; - if (MyNesMain.RendererSettings.UseEmuThread) - { - Tracer.WriteLine("Running in a thread ... using custom frame limiter."); - mainThread = new Thread(EmuClock); - mainThread.Start(); - } - MyNesMain.VideoProvider.SignalToggle(started: true); - MyNesMain.AudioProvider.SignalToggle(started: true); - } - else - { - success = false; - } - } - else - { - success = false; - } - } - - public static void HardReset() - { - PAUSED = true; - emu_request_mode = RequestMode.HardReset; - } - - private static void hardReset() - { - if (MyNesMain.WaveRecorder.IsRecording) - { - MyNesMain.WaveRecorder.Stop(); - } - render_audio_toggle_pause(paused: true); - switch (Region) - { - case EmuRegion.NTSC: - emu_time_target_fps = 60.0988; - break; - case EmuRegion.PALB: - case EmuRegion.DENDY: - emu_time_target_fps = 50.0; - break; - } - fps_time_period = 1.0 / emu_time_target_fps; - MEMHardReset(); - CPUHardReset(); - PPUHardReset(); - APUHardReset(); - DMAHardReset(); - render_audio_toggle_pause(paused: false); - MyNesMain.VideoProvider.WriteWarningNotification(MNInterfaceLanguage.Message_HardReset, instant: false); - } - - public static void SoftReset() - { - PAUSED = true; - emu_request_mode = RequestMode.SoftReset; - } - - private static void softReset() - { - CPUSoftReset(); - APUSoftReset(); - MyNesMain.VideoProvider.WriteWarningNotification(MNInterfaceLanguage.Message_SoftReset, instant: false); - } - - public static void SaveState() - { - PAUSED = true; - emu_request_mode = RequestMode.SaveState; - } - - public static void LoadState() - { - PAUSED = true; - emu_request_mode = RequestMode.LoadState; - } - - internal static void TakeSnapshot() - { - PAUSED = true; - emu_request_mode = RequestMode.TakeSnapshot; - } - - public static void ShutDown() - { - MyNesMain.VideoProvider.SignalToggle(started: false); - MyNesMain.AudioProvider.SignalToggle(started: false); - if (MyNesMain.WaveRecorder.IsRecording) - { - MyNesMain.WaveRecorder.Stop(); - } - render_audio_get_is_playing(out render_audio_is_playing); - if (render_audio_is_playing) - { - render_audio_toggle_pause(paused: true); - } - Tracer.WriteLine("Shutting down the emulation core..."); - ON = false; - if (mainThread != null) - { - Tracer.WriteLine("Aborting thread .."); - while (mainThread.IsAlive) - { - } - mainThread.Abort(); - mainThread = null; - } - SaveSRAM(); - Tracer.WriteInformation("Emulation core shutdown successfully."); - NesEmu.EmuShutdown?.Invoke(null, new EventArgs()); - } - - public static void EMUClockFrame() - { - if (PAUSED) - { - render_audio_get_is_playing(out render_audio_is_playing); - if (render_audio_is_playing) - { - render_audio_toggle_pause(paused: true); - } - shortucts.Update(); - switch (emu_request_mode) - { - case RequestMode.HardReset: - hardReset(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - case RequestMode.SoftReset: - softReset(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - case RequestMode.SaveState: - StateHandler.SaveState(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - case RequestMode.LoadState: - StateHandler.LoadState(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - case RequestMode.TakeSnapshot: - MyNesMain.VideoProvider.TakeSnapshot(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - } - isPaused = true; - return; - } - emu_frame_done = false; - while (!ppu_frame_finished && ON) - { - CPUClock(); - } - if (!FrameSkipEnabled) - { - render_video(ref ppu_screen_pixels); - } - else - { - FrameSkipCounter++; - if (FrameSkipCounter >= FrameSkipInterval) - { - render_video(ref ppu_screen_pixels); - FrameSkipCounter = 0; - } - } - isPaused = false; - ppu_frame_finished = false; - emu_frame_done = true; - joypad1.Update(); - joypad2.Update(); - if (IsFourPlayers) - { - joypad3.Update(); - joypad4.Update(); - } - shortucts.Update(); - if (SoundEnabled) - { - render_audio_get_is_playing(out render_audio_is_playing); - if (!render_audio_is_playing) - { - render_audio_toggle_pause(paused: false); - } - render_audio(ref audio_samples, ref audio_samples_added); - audio_w_pos = 0; - audio_samples_added = 0; - audio_timer = 0.0; - } - fps_time_token = GetTime() - fps_time_start; - fps_time_last = GetTime(); - fps_time_frame_time = fps_time_last - fps_time_start; - fps_time_start = GetTime(); - } - - public static void EMUClockSamples(int samples_required, out int audio_added_samples) - { - int num = audio_samples_added; - while (samples_required > 0 && audio_w_pos < audio_samples_count) - { - CPUClock(); - if (audio_samples_added - num >= 1) - { - samples_required--; - } - num = audio_samples_added; - } - audio_added_samples = audio_samples_added; - } - - private static void EmuClock() - { - while (ON) - { - if (!PAUSED) - { - CPUClock(); - if (ppu_frame_finished) - { - FrameFinished(); - } - continue; - } - render_audio_get_is_playing(out render_audio_is_playing); - if (render_audio_is_playing) - { - render_audio_toggle_pause(paused: true); - } - Thread.Sleep(100); - shortucts.Update(); - switch (emu_request_mode) - { - case RequestMode.HardReset: - hardReset(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - case RequestMode.SoftReset: - softReset(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - case RequestMode.SaveState: - StateHandler.SaveState(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - case RequestMode.LoadState: - StateHandler.LoadState(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - case RequestMode.TakeSnapshot: - MyNesMain.VideoProvider.TakeSnapshot(); - PAUSED = false; - emu_request_mode = RequestMode.None; - break; - } - isPaused = true; - } - } - - internal static void EmuClockComponentsNTSC() - { - PPUClock(); - PollInterruptStatus(); - PPUClock(); - PPUClock(); - APUClock(); - DMAClock(); - mem_board.OnCPUClock(); - } - - internal static void EmuClockComponentsPALB() - { - PPUClock(); - PollInterruptStatus(); - PPUClock(); - PPUClock(); - pal_add_cycle++; - if (pal_add_cycle == 5) - { - pal_add_cycle = 0; - PPUClock(); - } - APUClock(); - DMAClock(); - mem_board.OnCPUClock(); - } - - internal static void ApplyFrameSkipSettings() - { - FrameSkipEnabled = MyNesMain.RendererSettings.FrameSkipEnabled; - FrameSkipInterval = MyNesMain.RendererSettings.FrameSkipInterval; - } - - private static void FrameFinished() - { - if (!FrameSkipEnabled) - { - render_video(ref ppu_screen_pixels); - } - else - { - FrameSkipCounter++; - if (FrameSkipCounter >= FrameSkipInterval) - { - render_video(ref ppu_screen_pixels); - FrameSkipCounter = 0; - } - } - isPaused = false; - ppu_frame_finished = false; - emu_frame_done = true; - joypad1.Update(); - joypad2.Update(); - if (IsFourPlayers) - { - joypad3.Update(); - joypad4.Update(); - } - shortucts.Update(); - if (SoundEnabled) - { - render_audio_get_is_playing(out render_audio_is_playing); - if (!render_audio_is_playing) - { - render_audio_toggle_pause(paused: false); - } - render_audio(ref audio_samples, ref audio_samples_added); - audio_w_pos = 0; - audio_samples_added = 0; - audio_timer = 0.0; - } - fps_time_token = GetTime() - fps_time_start; - if (FrameLimiterEnabled) - { - if (fps_time_token > 0.0) - { - fps_time_dead = fps_time_period - fps_time_token; - if (fps_time_dead > 0.0) - { - Thread.Sleep((int)Math.Floor(fps_time_dead * 1000.0)); - fps_time_dead = GetTime() - fps_time_start; - while (fps_time_period - fps_time_dead > 0.0) - { - fps_time_dead = GetTime() - fps_time_start; - } - } - } - fps_time_last = GetTime(); - fps_time_frame_time = fps_time_last - fps_time_start; - } - fps_time_start = GetTime(); - } - - private static double GetTime() - { - return (double)Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency; - } - - public static void GetSpeedValues(out double frame_time, out double immediate_frame_time) - { - frame_time = fps_time_token; - immediate_frame_time = fps_time_frame_time; - } - - public static void SetFramePeriod(ref double period) - { - fps_time_period = period; - } - - public static void GetTargetFPS(out double fps) - { - fps = emu_time_target_fps; - } - - public static void ApplyRegionSetting() - { - switch ((RegionSetting)MyNesMain.EmuSettings.RegionSetting) - { - case RegionSetting.AUTO: - { - Tracer.WriteLine("REGION = AUTO"); - Region = EmuRegion.NTSC; - EmuClockComponents = EmuClockComponentsNTSC; - bool flag = false; - if (mem_board != null && mem_board.IsGameFoundOnDB) - { - Tracer.WriteLine("REGION SELECTION IS FROM DATABASE !!"); - if (mem_board.GameCartInfo.System.ToUpper().Contains("PAL")) - { - Region = EmuRegion.PALB; - EmuClockComponents = EmuClockComponentsPALB; - flag = true; - } - else if (mem_board.GameCartInfo.System.ToUpper().Contains("DENDY")) - { - Region = EmuRegion.DENDY; - EmuClockComponents = EmuClockComponentsNTSC; - flag = true; - } - else - { - Region = EmuRegion.NTSC; - EmuClockComponents = EmuClockComponentsNTSC; - flag = true; - } - } - if (!flag && CurrentFilePath.Contains("(E)")) - { - Region = EmuRegion.PALB; - EmuClockComponents = EmuClockComponentsPALB; - } - Tracer.WriteLine("REGION SELECTED: " + Region); - break; - } - case RegionSetting.ForceNTSC: - Tracer.WriteLine("REGION: FORCE NTSC"); - Region = EmuRegion.NTSC; - EmuClockComponents = EmuClockComponentsNTSC; - break; - case RegionSetting.ForcePALB: - Tracer.WriteLine("REGION: FORCE PALB"); - Region = EmuRegion.PALB; - EmuClockComponents = EmuClockComponentsPALB; - break; - case RegionSetting.ForceDENDY: - Tracer.WriteLine("REGION: FORCE DENDY"); - Region = EmuRegion.DENDY; - EmuClockComponents = EmuClockComponentsNTSC; - break; - } - SystemIndex = (int)Region; - } - - internal static void WriteStateData(ref BinaryWriter bin) - { - APUWriteState(ref bin); - CPUWriteState(ref bin); - DMAWriteState(ref bin); - InterruptsWriteState(ref bin); - MEMWriteState(ref bin); - PORTWriteState(ref bin); - PPUWriteState(ref bin); - } - - internal static void ReadStateData(ref BinaryReader bin) - { - APUReadState(ref bin); - CPUReadState(ref bin); - DMAReadState(ref bin); - InterruptsReadState(ref bin); - MEMReadState(ref bin); - PORTReadState(ref bin); - PPUReadState(ref bin); - } - - private static void SQ2HardReset() - { - sq2_duty_cycle = 0; - sq2_length_halt = false; - sq2_constant_volume_envelope = false; - sq2_volume_devider_period = 0; - sq2_sweep_enable = false; - sq2_sweep_devider_period = 0; - sq2_sweep_negate = false; - sq2_sweep_shift_count = 0; - sq2_timer = 0; - sq2_period_devider = 0; - sq2_seqencer = 0; - sq2_length_enabled = false; - sq2_length_counter = 0; - sq2_envelope_start_flag = false; - sq2_envelope_devider = 0; - sq2_envelope_decay_level_counter = 0; - sq2_envelope = 0; - sq2_sweep_counter = 0; - sq2_sweep_reload = false; - sq2_sweep_change = 0; - sq2_valid_freq = false; - sq2_output = 0; - sq2_ignore_reload = false; - } - - private static void SQ2SoftReset() - { - SQ2HardReset(); - } - - private static void SQ2Clock() - { - sq2_period_devider--; - if (sq2_period_devider > 0) - { - return; - } - sq2_period_devider = sq2_timer + 1; - sq2_seqencer = (byte)((uint)(sq2_seqencer + 1) & 7u); - if (sq2_length_counter > 0 && sq2_valid_freq) - { - if (audio_sq2_outputable) - { - sq2_output = sq_duty_cycle_sequences[sq2_duty_cycle][sq2_seqencer] * sq2_envelope; - } - } - else - { - sq2_output = 0; - } - audio_signal_outputed = true; - } - - private static void SQ2ClockLength() - { - if (sq2_length_counter > 0 && !sq2_length_halt) - { - sq2_length_counter--; - if (apu_reg_access_happened && apu_reg_io_addr == 7 && apu_reg_access_w) - { - sq2_ignore_reload = true; - } - } - sq2_sweep_counter--; - if (sq2_sweep_counter == 0) - { - sq2_sweep_counter = sq2_sweep_devider_period + 1; - if (sq2_sweep_enable && sq2_sweep_shift_count > 0 && sq2_valid_freq) - { - sq2_sweep_change = sq2_timer >> (int)sq2_sweep_shift_count; - sq2_timer += (sq2_sweep_negate ? (-sq2_sweep_change) : sq2_sweep_change); - SQ2CalculateValidFreq(); - } - } - else if (sq2_sweep_reload) - { - sq2_sweep_counter = sq2_sweep_devider_period + 1; - sq2_sweep_reload = false; - } - } - - private static void SQ2ClockEnvelope() - { - if (sq2_envelope_start_flag) - { - sq2_envelope_start_flag = false; - sq2_envelope_decay_level_counter = 15; - sq2_envelope_devider = (byte)(sq2_volume_devider_period + 1); - } - else if (sq2_envelope_devider > 0) - { - sq2_envelope_devider--; - } - else - { - sq2_envelope_devider = (byte)(sq2_volume_devider_period + 1); - if (sq2_envelope_decay_level_counter > 0) - { - sq2_envelope_decay_level_counter--; - } - else if (sq2_length_halt) - { - sq2_envelope_decay_level_counter = 15; - } - } - sq2_envelope = (sq2_constant_volume_envelope ? sq2_volume_devider_period : sq2_envelope_decay_level_counter); - } - - private static void APUOnRegister4004() - { - if (apu_reg_access_w) - { - sq2_duty_cycle = (byte)((apu_reg_io_db & 0xC0) >> 6); - sq2_volume_devider_period = (byte)(apu_reg_io_db & 0xFu); - sq2_length_halt = (apu_reg_io_db & 0x20) != 0; - sq2_constant_volume_envelope = (apu_reg_io_db & 0x10) != 0; - sq2_envelope = (sq2_constant_volume_envelope ? sq2_volume_devider_period : sq2_envelope_decay_level_counter); - } - } - - private static void APUOnRegister4005() - { - if (apu_reg_access_w) - { - sq2_sweep_enable = (apu_reg_io_db & 0x80) == 128; - sq2_sweep_devider_period = (byte)((uint)(apu_reg_io_db >> 4) & 7u); - sq2_sweep_negate = (apu_reg_io_db & 8) == 8; - sq2_sweep_shift_count = (byte)(apu_reg_io_db & 7u); - sq2_sweep_reload = true; - SQ2CalculateValidFreq(); - } - } - - private static void APUOnRegister4006() - { - if (apu_reg_access_w) - { - sq2_timer = (sq2_timer & 0xFF00) | apu_reg_io_db; - SQ2CalculateValidFreq(); - } - } - - private static void APUOnRegister4007() - { - if (apu_reg_access_w) - { - sq2_timer = (sq2_timer & 0xFF) | ((apu_reg_io_db & 7) << 8); - if (sq2_length_enabled && !sq2_ignore_reload) - { - sq2_length_counter = sq_duration_table[apu_reg_io_db >> 3]; - } - if (sq2_ignore_reload) - { - sq2_ignore_reload = false; - } - sq2_seqencer = 0; - sq2_envelope_start_flag = true; - SQ2CalculateValidFreq(); - } - } - - private static void SQ2On4015() - { - sq2_length_enabled = (apu_reg_io_db & 2) != 0; - if (!sq2_length_enabled) - { - sq2_length_counter = 0; - } - } - - private static void SQ2Read4015() - { - if (sq2_length_counter > 0) - { - apu_reg_io_db = (byte)((apu_reg_io_db & 0xFDu) | 2u); - } - } - - private static void SQ2CalculateValidFreq() - { - sq2_valid_freq = sq2_timer >= 8 && (sq2_sweep_negate || ((sq2_timer + (sq2_timer >> (int)sq2_sweep_shift_count)) & 0x800) == 0); - } - - private static void SQ2WriteState(ref BinaryWriter bin) - { - bin.Write(sq2_duty_cycle); - bin.Write(sq2_length_halt); - bin.Write(sq2_constant_volume_envelope); - bin.Write(sq2_volume_devider_period); - bin.Write(sq2_sweep_enable); - bin.Write(sq2_sweep_devider_period); - bin.Write(sq2_sweep_negate); - bin.Write(sq2_sweep_shift_count); - bin.Write(sq2_timer); - bin.Write(sq2_period_devider); - bin.Write(sq2_seqencer); - bin.Write(sq2_length_enabled); - bin.Write(sq2_length_counter); - bin.Write(sq2_envelope_start_flag); - bin.Write(sq2_envelope_devider); - bin.Write(sq2_envelope_decay_level_counter); - bin.Write(sq2_envelope); - bin.Write(sq2_sweep_counter); - bin.Write(sq2_sweep_reload); - bin.Write(sq2_sweep_change); - bin.Write(sq2_valid_freq); - bin.Write(sq2_output); - bin.Write(sq2_ignore_reload); - } - - private static void SQ2ReadState(ref BinaryReader bin) - { - sq2_duty_cycle = bin.ReadByte(); - sq2_length_halt = bin.ReadBoolean(); - sq2_constant_volume_envelope = bin.ReadBoolean(); - sq2_volume_devider_period = bin.ReadByte(); - sq2_sweep_enable = bin.ReadBoolean(); - sq2_sweep_devider_period = bin.ReadByte(); - sq2_sweep_negate = bin.ReadBoolean(); - sq2_sweep_shift_count = bin.ReadByte(); - sq2_timer = bin.ReadInt32(); - sq2_period_devider = bin.ReadInt32(); - sq2_seqencer = bin.ReadByte(); - sq2_length_enabled = bin.ReadBoolean(); - sq2_length_counter = bin.ReadInt32(); - sq2_envelope_start_flag = bin.ReadBoolean(); - sq2_envelope_devider = bin.ReadByte(); - sq2_envelope_decay_level_counter = bin.ReadByte(); - sq2_envelope = bin.ReadByte(); - sq2_sweep_counter = bin.ReadInt32(); - sq2_sweep_reload = bin.ReadBoolean(); - sq2_sweep_change = bin.ReadInt32(); - sq2_valid_freq = bin.ReadBoolean(); - sq2_output = bin.ReadInt32(); - sq2_ignore_reload = bin.ReadBoolean(); - } - } +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Xml; + +namespace MyNes.Core; + +public class NesEmu +{ + [StructLayout(LayoutKind.Explicit)] + private struct CPURegister + { + [FieldOffset(0)] + internal byte l; + + [FieldOffset(1)] + internal byte h; + + [FieldOffset(0)] + internal ushort v; + } + + private enum RequestMode + { + None, + HardReset, + SoftReset, + LoadState, + SaveState, + TakeSnapshot + } + + private static int[][] dmc_freq_table = new int[3][] + { + new int[16] + { + 428, 380, 340, 320, 286, 254, 226, 214, 190, 160, + 142, 128, 106, 84, 72, 54 + }, + new int[16] + { + 398, 354, 316, 298, 276, 236, 210, 198, 176, 148, + 132, 118, 98, 78, 66, 50 + }, + new int[16] + { + 428, 380, 340, 320, 286, 254, 226, 214, 190, 160, + 142, 128, 106, 84, 72, 54 + } + }; + + private static int dmc_output_a; + + private static int dmc_output; + + private static int dmc_period_devider; + + private static bool dmc_irq_enabled; + + private static bool dmc_loop_flag; + + private static byte dmc_rate_index; + + private static ushort dmc_addr_refresh; + + private static int dmc_size_refresh; + + private static bool dmc_dmaEnabled; + + private static byte dmc_dmaByte; + + private static int dmc_dmaBits; + + private static bool dmc_bufferFull; + + private static byte dmc_dmaBuffer; + + private static int dmc_dmaSize; + + private static ushort dmc_dmaAddr; + + private static ushort[][] nos_freq_table = new ushort[3][] + { + new ushort[16] + { + 4, 8, 16, 32, 64, 96, 128, 160, 202, 254, + 380, 508, 762, 1016, 2034, 4068 + }, + new ushort[16] + { + 4, 7, 14, 30, 60, 88, 118, 148, 188, 236, + 354, 472, 708, 944, 1890, 3778 + }, + new ushort[16] + { + 4, 8, 16, 32, 64, 96, 128, 160, 202, 254, + 380, 508, 762, 1016, 2034, 4068 + } + }; + + private static bool nos_length_halt; + + private static bool nos_constant_volume_envelope; + + private static byte nos_volume_devider_period; + + private static ushort nos_timer; + + private static bool nos_mode; + + private static int nos_period_devider; + + private static bool nos_length_enabled; + + private static int nos_length_counter; + + private static bool nos_envelope_start_flag; + + private static byte nos_envelope_devider; + + private static byte nos_envelope_decay_level_counter; + + private static byte nos_envelope; + + private static int nos_output; + + private static int nos_shift_reg; + + private static int nos_feedback; + + private static bool nos_ignore_reload; + + private static byte[][] sq_duty_cycle_sequences = new byte[4][] + { + new byte[8] { 0, 0, 0, 0, 0, 0, 0, 1 }, + new byte[8] { 0, 0, 0, 0, 0, 0, 1, 1 }, + new byte[8] { 0, 0, 0, 0, 1, 1, 1, 1 }, + new byte[8] { 1, 1, 1, 1, 1, 1, 0, 0 } + }; + + private static byte[] sq_duration_table = new byte[32] + { + 10, 254, 20, 2, 40, 4, 80, 6, 160, 8, + 60, 10, 14, 12, 26, 14, 12, 16, 24, 18, + 48, 20, 96, 22, 192, 24, 72, 26, 16, 28, + 32, 30 + }; + + private static byte sq1_duty_cycle; + + private static bool sq1_length_halt; + + private static bool sq1_constant_volume_envelope; + + private static byte sq1_volume_devider_period; + + private static bool sq1_sweep_enable; + + private static byte sq1_sweep_devider_period; + + private static bool sq1_sweep_negate; + + private static byte sq1_sweep_shift_count; + + private static int sq1_timer; + + private static int sq1_period_devider; + + private static byte sq1_seqencer; + + private static bool sq1_length_enabled; + + private static int sq1_length_counter; + + private static bool sq1_envelope_start_flag; + + private static byte sq1_envelope_devider; + + private static byte sq1_envelope_decay_level_counter; + + private static byte sq1_envelope; + + private static int sq1_sweep_counter; + + private static bool sq1_sweep_reload; + + private static int sq1_sweep_change; + + private static bool sq1_valid_freq; + + private static int sq1_output; + + private static bool sq1_ignore_reload; + + private static byte[] trl_step_seq = new byte[32] + { + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, + 5, 4, 3, 2, 1, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15 + }; + + private static bool trl_liner_control_flag; + + private static byte trl_liner_control_reload; + + private static ushort trl_timer; + + private static bool trl_length_enabled; + + private static byte trl_length_counter; + + private static bool trl_liner_control_reload_flag; + + private static byte trl_liner_counter; + + private static int trl_output; + + private static int trl_period_devider; + + private static int trl_step; + + private static bool trl_ignore_reload; + + private static byte apu_reg_io_db; + + private static byte apu_reg_io_addr; + + private static bool apu_reg_access_happened; + + private static bool apu_reg_access_w; + + private static Action[] apu_reg_update_func; + + private static Action[] apu_reg_read_func; + + private static Action[] apu_reg_write_func; + + private static Action apu_update_playback_func; + + private static bool apu_odd_cycle; + + private static bool apu_irq_enabled; + + private static bool apu_irq_flag; + + private static bool apu_irq_do_it; + + internal static bool apu_irq_delta_occur; + + private static bool apu_seq_mode; + + private static int apu_ferq_f; + + private static int apu_ferq_l; + + private static int apu_ferq_e; + + private static int apu_cycle_f; + + private static int apu_cycle_f_t; + + private static int apu_cycle_e; + + private static int apu_cycle_l; + + private static bool apu_odd_l; + + private static bool apu_check_irq; + + private static bool apu_do_env; + + private static bool apu_do_length; + + public static bool SoundEnabled; + + public static double audio_playback_amplitude = 1.5; + + public static int audio_playback_peek_limit = 124; + + private static bool audio_playback_dac_initialized; + + public static int cpu_speed; + + private static short[] audio_samples; + + private static int audio_w_pos; + + private static int audio_samples_added; + + internal static int audio_samples_count; + + private static int[][][][][] mix_table; + + private static double audio_x; + + private static double audio_y; + + private static double audio_y_av; + + private static double audio_y_timer; + + public static double audio_timer_ratio = 40.0; + + private static double audio_timer; + + private static SoundLowPassFilter audio_low_pass_filter_14K; + + private static SoundHighPassFilter audio_high_pass_filter_90; + + private static SoundHighPassFilter audio_high_pass_filter_440; + + private static SoundDCBlockerFilter audio_dc_blocker_filter; + + private static bool audio_sq1_outputable; + + private static bool audio_sq2_outputable; + + private static bool audio_nos_outputable; + + private static bool audio_trl_outputable; + + private static bool audio_dmc_outputable; + + private static bool audio_signal_outputed; + + private static bool apu_use_external_sound; + + private static CPURegister cpu_reg_pc; + + private static CPURegister cpu_reg_sp; + + private static CPURegister cpu_reg_ea; + + private static byte cpu_reg_a; + + private static byte cpu_reg_x; + + private static byte cpu_reg_y; + + private static bool cpu_flag_n; + + private static bool cpu_flag_v; + + private static bool cpu_flag_d; + + private static bool cpu_flag_i; + + private static bool cpu_flag_z; + + private static bool cpu_flag_c; + + private static byte cpu_m; + + private static byte cpu_opcode; + + private static byte cpu_byte_temp; + + private static int cpu_int_temp; + + private static int cpu_int_temp1; + + private static byte cpu_dummy; + + private static bool cpu_bool_tmp; + + private static CPURegister temp_add; + + private static bool CPU_IRQ_PIN; + + private static bool CPU_NMI_PIN; + + private static bool cpu_suspend_nmi; + + private static bool cpu_suspend_irq; + + private static Action[] cpu_addressings; + + private static Action[] cpu_instructions; + + private static int dma_DMCDMAWaitCycles; + + private static int dma_OAMDMAWaitCycles; + + private static bool dma_isOamDma; + + private static int dma_oamdma_i; + + private static bool dma_DMCOn; + + private static bool dma_OAMOn; + + private static bool dma_DMC_occurring; + + private static bool dma_OAM_occurring; + + private static int dma_OAMFinishCounter; + + private static ushort dma_Oamaddress; + + private static int dma_OAMCYCLE; + + private static byte dma_latch; + + private static byte dma_dummy; + + private static ushort reg_2004; + + internal static int IRQFlags = 0; + + private static bool PPU_NMI_Current; + + private static bool PPU_NMI_Old; + + private const int IRQ_APU = 1; + + internal const int IRQ_DMC = 2; + + internal const int IRQ_BOARD = 8; + + private static ushort InterruptVector; + + private static byte[] mem_wram; + + internal static Board mem_board; + + private static MemReadAccess[] mem_read_accesses; + + private static MemWriteAccess[] mem_write_accesses; + + private static bool BUS_RW; + + private static ushort BUS_ADDRESS; + + private static string SRAMFileName; + + public static string GMFileName; + + private static int PORT0; + + private static int PORT1; + + private static int inputStrobe; + + private static IJoypadConnecter joypad1; + + private static IJoypadConnecter joypad2; + + private static IJoypadConnecter joypad3; + + private static IJoypadConnecter joypad4; + + private static IShortcutsHandler shortucts; + + public static bool IsFourPlayers; + + private static byte[] reverseLookup = new byte[256] + { + 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, + 80, 208, 48, 176, 112, 240, 8, 136, 72, 200, + 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, + 120, 248, 4, 132, 68, 196, 36, 164, 100, 228, + 20, 148, 84, 212, 52, 180, 116, 244, 12, 140, + 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, + 60, 188, 124, 252, 2, 130, 66, 194, 34, 162, + 98, 226, 18, 146, 82, 210, 50, 178, 114, 242, + 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, + 90, 218, 58, 186, 122, 250, 6, 134, 70, 198, + 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, + 118, 246, 14, 142, 78, 206, 46, 174, 110, 238, + 30, 158, 94, 222, 62, 190, 126, 254, 1, 129, + 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, + 49, 177, 113, 241, 9, 137, 73, 201, 41, 169, + 105, 233, 25, 153, 89, 217, 57, 185, 121, 249, + 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, + 85, 213, 53, 181, 117, 245, 13, 141, 77, 205, + 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, + 125, 253, 3, 131, 67, 195, 35, 163, 99, 227, + 19, 147, 83, 211, 51, 179, 115, 243, 11, 139, + 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, + 59, 187, 123, 251, 7, 135, 71, 199, 39, 167, + 103, 231, 23, 151, 87, 215, 55, 183, 119, 247, + 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, + 95, 223, 63, 191, 127, 255 + }; + + private static Action[] ppu_v_clocks; + + private static Action[] ppu_h_clocks; + + private static Action[] ppu_bkg_fetches; + + private static Action[] ppu_spr_fetches; + + private static Action[] ppu_oam_phases; + + private static int[] ppu_bkg_pixels; + + private static int[] ppu_spr_pixels; + + private static int[] ppu_screen_pixels; + + private static int[] ppu_palette; + + private static int ppu_clock_h; + + internal static ushort ppu_clock_v; + + private static ushort ppu_clock_vblank_start; + + private static ushort ppu_clock_vblank_end; + + private static bool ppu_use_odd_cycle; + + private static bool ppu_use_odd_swap; + + private static bool ppu_odd_swap_done; + + private static bool ppu_is_nmi_time; + + private static bool ppu_frame_finished; + + private static byte[] ppu_oam_bank; + + private static byte[] ppu_oam_bank_secondary; + + private static byte[] ppu_palette_bank; + + private static byte ppu_reg_io_db; + + private static byte ppu_reg_io_addr; + + private static bool ppu_reg_access_happened; + + private static bool ppu_reg_access_w; + + private static Action[] ppu_reg_update_func; + + private static Action[] ppu_reg_read_func; + + private static byte ppu_reg_2000_vram_address_increament; + + private static ushort ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites; + + private static ushort ppu_reg_2000_background_pattern_table_address; + + internal static byte ppu_reg_2000_Sprite_size; + + private static bool ppu_reg_2000_VBI; + + private static bool ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen; + + private static bool ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen; + + private static bool ppu_reg_2001_show_background; + + private static bool ppu_reg_2001_show_sprites; + + private static int ppu_reg_2001_grayscale; + + private static int ppu_reg_2001_emphasis; + + private static bool ppu_reg_2002_SpriteOverflow; + + private static bool ppu_reg_2002_Sprite0Hit; + + private static bool ppu_reg_2002_VblankStartedFlag; + + private static byte ppu_reg_2003_oam_addr; + + private static ushort ppu_vram_addr; + + private static byte ppu_vram_data; + + private static ushort ppu_vram_addr_temp; + + private static ushort ppu_vram_addr_access_temp; + + private static bool ppu_vram_flip_flop; + + private static byte ppu_vram_finex; + + private static ushort ppu_bkgfetch_nt_addr; + + private static byte ppu_bkgfetch_nt_data; + + private static ushort ppu_bkgfetch_at_addr; + + private static byte ppu_bkgfetch_at_data; + + private static ushort ppu_bkgfetch_lb_addr; + + private static byte ppu_bkgfetch_lb_data; + + private static ushort ppu_bkgfetch_hb_addr; + + private static byte ppu_bkgfetch_hb_data; + + private static int ppu_sprfetch_slot; + + private static byte ppu_sprfetch_y_data; + + private static byte ppu_sprfetch_t_data; + + private static byte ppu_sprfetch_at_data; + + private static byte ppu_sprfetch_x_data; + + private static ushort ppu_sprfetch_lb_addr; + + private static byte ppu_sprfetch_lb_data; + + private static ushort ppu_sprfetch_hb_addr; + + private static byte ppu_sprfetch_hb_data; + + internal static bool ppu_is_sprfetch; + + private static int ppu_bkg_render_i; + + private static int ppu_bkg_render_pos; + + private static int ppu_bkg_render_tmp_val; + + private static int ppu_bkg_current_pixel; + + private static int ppu_spr_current_pixel; + + private static int ppu_current_pixel; + + private static int ppu_render_x; + + private static int ppu_render_y; + + private static byte ppu_oamev_n; + + private static byte ppu_oamev_m; + + private static bool ppu_oamev_compare; + + private static byte ppu_oamev_slot; + + private static byte ppu_fetch_data; + + private static byte ppu_phase_index; + + private static bool ppu_sprite0_should_hit; + + private static int ppu_temp_comparator; + + public static bool ON; + + public static bool PAUSED; + + public static bool isPaused; + + public static string CurrentFilePath; + + public static bool FrameLimiterEnabled; + + private static Thread mainThread; + + private static double fps_time_last; + + private static double fps_time_start; + + private static double fps_time_token; + + private static double fps_time_dead; + + private static double fps_time_period; + + private static double fps_time_frame_time; + + private static double emu_time_target_fps = 60.0; + + private static bool emu_frame_clocking_mode; + + private static bool emu_frame_done; + + private static bool render_initialized; + + private static RenderVideoFrame render_video; + + private static RenderAudioSamples render_audio; + + private static TogglePause render_audio_toggle_pause; + + private static GetIsPlaying render_audio_get_is_playing; + + private static bool render_audio_is_playing; + + public static EmuRegion Region; + + private static int SystemIndex; + + private static RequestMode emu_request_mode = RequestMode.None; + + public static bool FrameSkipEnabled; + + public static int FrameSkipInterval; + + private static int FrameSkipCounter; + + private static byte sq2_duty_cycle; + + private static bool sq2_length_halt; + + private static bool sq2_constant_volume_envelope; + + private static byte sq2_volume_devider_period; + + private static bool sq2_sweep_enable; + + private static byte sq2_sweep_devider_period; + + private static bool sq2_sweep_negate; + + private static byte sq2_sweep_shift_count; + + private static int sq2_timer; + + private static int sq2_period_devider; + + private static byte sq2_seqencer; + + private static bool sq2_length_enabled; + + private static int sq2_length_counter; + + private static bool sq2_envelope_start_flag; + + private static byte sq2_envelope_devider; + + private static byte sq2_envelope_decay_level_counter; + + private static byte sq2_envelope; + + private static int sq2_sweep_counter; + + private static bool sq2_sweep_reload; + + private static int sq2_sweep_change; + + private static bool sq2_valid_freq; + + private static int sq2_output; + + private static bool sq2_ignore_reload; + + private static byte register_p + { + get + { + return (byte)((cpu_flag_n ? 128u : 0u) | (cpu_flag_v ? 64u : 0u) | (cpu_flag_d ? 8u : 0u) | (cpu_flag_i ? 4u : 0u) | (cpu_flag_z ? 2u : 0u) | (cpu_flag_c ? 1u : 0u) | 0x20u); + } + set + { + cpu_flag_n = (value & 0x80) != 0; + cpu_flag_v = (value & 0x40) != 0; + cpu_flag_d = (value & 8) != 0; + cpu_flag_i = (value & 4) != 0; + cpu_flag_z = (value & 2) != 0; + cpu_flag_c = (value & 1) != 0; + } + } + + public static GameGenieCode[] GameGenieCodes + { + get + { + if (mem_board != null) + { + return mem_board.GameGenieCodes; + } + return null; + } + } + + public static bool IsGameGenieActive + { + get + { + if (mem_board != null) + { + return mem_board.IsGameGenieActive; + } + return false; + } + set + { + if (mem_board != null) + { + mem_board.IsGameGenieActive = value; + } + } + } + + public static bool IsGameFoundOnDB + { + get + { + if (mem_board != null) + { + return mem_board.IsGameFoundOnDB; + } + return false; + } + } + + public static NesCartDatabaseGameInfo GameInfo + { + get + { + if (mem_board != null) + { + return mem_board.GameInfo; + } + return NesCartDatabaseGameInfo.Empty; + } + } + + public static NesCartDatabaseCartridgeInfo GameCartInfo + { + get + { + if (mem_board != null) + { + return mem_board.GameCartInfo; + } + return new NesCartDatabaseCartridgeInfo(); + } + } + + public static string SHA1 => mem_board.SHA1; + + public static event EventHandler EmuShutdown; + + private static void DMCHardReset() + { + dmc_output_a = 0; + dmc_output = 0; + dmc_period_devider = 0; + dmc_loop_flag = false; + dmc_rate_index = 0; + dmc_irq_enabled = false; + dmc_dmaAddr = 49152; + dmc_addr_refresh = 49152; + dmc_size_refresh = 0; + dmc_dmaBits = 1; + dmc_dmaByte = 1; + dmc_period_devider = 0; + dmc_dmaEnabled = false; + dmc_bufferFull = false; + dmc_dmaSize = 0; + } + + private static void DMCSoftReset() + { + DMCHardReset(); + } + + private static void DMCClock() + { + dmc_period_devider--; + if (dmc_period_devider > 0) + { + return; + } + dmc_period_devider = dmc_freq_table[SystemIndex][dmc_rate_index]; + if (dmc_dmaEnabled) + { + if (((uint)dmc_dmaByte & (true ? 1u : 0u)) != 0) + { + if (dmc_output_a <= 125) + { + dmc_output_a += 2; + } + } + else if (dmc_output_a >= 2) + { + dmc_output_a -= 2; + } + dmc_dmaByte >>= 1; + } + dmc_dmaBits--; + if (dmc_dmaBits == 0) + { + dmc_dmaBits = 8; + if (dmc_bufferFull) + { + dmc_bufferFull = false; + dmc_dmaEnabled = true; + dmc_dmaByte = dmc_dmaBuffer; + if (dmc_dmaSize > 0) + { + AssertDMCDMA(); + } + } + else + { + dmc_dmaEnabled = false; + } + } + if (audio_dmc_outputable) + { + dmc_output = dmc_output_a; + } + audio_signal_outputed = true; + } + + private static void DMCDoDMA() + { + dmc_bufferFull = true; + Read(ref dmc_dmaAddr, out dmc_dmaBuffer); + if (dmc_dmaAddr == ushort.MaxValue) + { + dmc_dmaAddr = 32768; + } + else + { + dmc_dmaAddr++; + } + if (dmc_dmaSize > 0) + { + dmc_dmaSize--; + } + if (dmc_dmaSize == 0) + { + if (dmc_loop_flag) + { + dmc_dmaSize = dmc_size_refresh; + dmc_dmaAddr = dmc_addr_refresh; + } + else if (dmc_irq_enabled) + { + IRQFlags |= 2; + apu_irq_delta_occur = true; + } + } + } + + private static void APUOnRegister4010() + { + if (apu_reg_access_w) + { + dmc_irq_enabled = (apu_reg_io_db & 0x80) != 0; + dmc_loop_flag = (apu_reg_io_db & 0x40) != 0; + if (!dmc_irq_enabled) + { + apu_irq_delta_occur = false; + IRQFlags &= -3; + } + dmc_rate_index = (byte)(apu_reg_io_db & 0xFu); + } + } + + private static void APUOnRegister4011() + { + if (apu_reg_access_w) + { + dmc_output_a = (byte)(apu_reg_io_db & 0x7F); + } + } + + private static void APUOnRegister4012() + { + if (apu_reg_access_w) + { + dmc_addr_refresh = (ushort)((uint)(apu_reg_io_db << 6) | 0xC000u); + } + } + + private static void APUOnRegister4013() + { + if (apu_reg_access_w) + { + dmc_size_refresh = (apu_reg_io_db << 4) | 1; + } + } + + private static void DMCOn4015() + { + apu_irq_delta_occur = false; + IRQFlags &= -3; + } + + private static void DMCRead4015() + { + if (dmc_dmaSize > 0) + { + apu_reg_io_db = (byte)((apu_reg_io_db & 0xEFu) | 0x10u); + } + } + + private static void DMCWriteState(ref BinaryWriter bin) + { + bin.Write(dmc_output_a); + bin.Write(dmc_output); + bin.Write(dmc_period_devider); + bin.Write(dmc_irq_enabled); + bin.Write(dmc_loop_flag); + bin.Write(dmc_rate_index); + bin.Write(dmc_addr_refresh); + bin.Write(dmc_size_refresh); + bin.Write(dmc_dmaEnabled); + bin.Write(dmc_dmaByte); + bin.Write(dmc_dmaBits); + bin.Write(dmc_bufferFull); + bin.Write(dmc_dmaBuffer); + bin.Write(dmc_dmaSize); + bin.Write(dmc_dmaAddr); + } + + private static void DMCReadState(ref BinaryReader bin) + { + dmc_output_a = bin.ReadInt32(); + dmc_output = bin.ReadInt32(); + dmc_period_devider = bin.ReadInt32(); + dmc_irq_enabled = bin.ReadBoolean(); + dmc_loop_flag = bin.ReadBoolean(); + dmc_rate_index = bin.ReadByte(); + dmc_addr_refresh = bin.ReadUInt16(); + dmc_size_refresh = bin.ReadInt32(); + dmc_dmaEnabled = bin.ReadBoolean(); + dmc_dmaByte = bin.ReadByte(); + dmc_dmaBits = bin.ReadInt32(); + dmc_bufferFull = bin.ReadBoolean(); + dmc_dmaBuffer = bin.ReadByte(); + dmc_dmaSize = bin.ReadInt32(); + dmc_dmaAddr = bin.ReadUInt16(); + } + + private static void NOSHardReset() + { + nos_length_halt = false; + nos_constant_volume_envelope = false; + nos_volume_devider_period = 0; + nos_shift_reg = 1; + nos_timer = 0; + nos_mode = false; + nos_period_devider = 0; + nos_length_enabled = false; + nos_length_counter = 0; + nos_envelope_start_flag = false; + nos_envelope_devider = 0; + nos_envelope_decay_level_counter = 0; + nos_envelope = 0; + nos_output = 0; + nos_feedback = 0; + nos_ignore_reload = false; + } + + private static void NOSSoftReset() + { + NOSHardReset(); + } + + private static void NOSClock() + { + nos_period_devider--; + if (nos_period_devider > 0) + { + return; + } + nos_period_devider = nos_timer; + if (nos_mode) + { + nos_feedback = ((nos_shift_reg >> 6) & 1) ^ (nos_shift_reg & 1); + } + else + { + nos_feedback = ((nos_shift_reg >> 1) & 1) ^ (nos_shift_reg & 1); + } + nos_shift_reg >>= 1; + nos_shift_reg = (nos_shift_reg & 0x3FFF) | ((nos_feedback & 1) << 14); + if (nos_length_counter > 0 && (nos_shift_reg & 1) == 0) + { + if (audio_nos_outputable) + { + nos_output = nos_envelope; + } + } + else + { + nos_output = 0; + } + audio_signal_outputed = true; + } + + private static void NOSClockLength() + { + if (nos_length_counter > 0 && !nos_length_halt) + { + nos_length_counter--; + if (apu_reg_access_happened && apu_reg_io_addr == 15 && apu_reg_access_w) + { + nos_ignore_reload = true; + } + } + } + + private static void NOSClockEnvelope() + { + if (nos_envelope_start_flag) + { + nos_envelope_start_flag = false; + nos_envelope_decay_level_counter = 15; + nos_envelope_devider = (byte)(nos_volume_devider_period + 1); + } + else if (nos_envelope_devider > 0) + { + nos_envelope_devider--; + } + else + { + nos_envelope_devider = (byte)(nos_volume_devider_period + 1); + if (nos_envelope_decay_level_counter > 0) + { + nos_envelope_decay_level_counter--; + } + else if (nos_length_halt) + { + nos_envelope_decay_level_counter = 15; + } + } + nos_envelope = (nos_constant_volume_envelope ? nos_volume_devider_period : nos_envelope_decay_level_counter); + } + + private static void APUOnRegister400C() + { + if (apu_reg_access_w) + { + nos_volume_devider_period = (byte)(apu_reg_io_db & 0xFu); + nos_length_halt = (apu_reg_io_db & 0x20) != 0; + nos_constant_volume_envelope = (apu_reg_io_db & 0x10) != 0; + nos_envelope = (nos_constant_volume_envelope ? nos_volume_devider_period : nos_envelope_decay_level_counter); + } + } + + private static void APUOnRegister400D() + { + } + + private static void APUOnRegister400E() + { + if (apu_reg_access_w) + { + nos_timer = (ushort)(nos_freq_table[SystemIndex][apu_reg_io_db & 0xF] / 2); + nos_mode = (apu_reg_io_db & 0x80) == 128; + } + } + + private static void APUOnRegister400F() + { + if (apu_reg_access_w) + { + if (nos_length_enabled && !nos_ignore_reload) + { + nos_length_counter = sq_duration_table[apu_reg_io_db >> 3]; + } + if (nos_ignore_reload) + { + nos_ignore_reload = false; + } + nos_envelope_start_flag = true; + } + } + + private static void NOSOn4015() + { + nos_length_enabled = (apu_reg_io_db & 8) != 0; + if (!nos_length_enabled) + { + nos_length_counter = 0; + } + } + + private static void NOSRead4015() + { + if (nos_length_counter > 0) + { + apu_reg_io_db = (byte)((apu_reg_io_db & 0xF7u) | 8u); + } + } + + private static void NOSWriteState(ref BinaryWriter bin) + { + bin.Write(nos_length_halt); + bin.Write(nos_constant_volume_envelope); + bin.Write(nos_volume_devider_period); + bin.Write(nos_timer); + bin.Write(nos_mode); + bin.Write(nos_period_devider); + bin.Write(nos_length_enabled); + bin.Write(nos_length_counter); + bin.Write(nos_envelope_start_flag); + bin.Write(nos_envelope_devider); + bin.Write(nos_envelope_decay_level_counter); + bin.Write(nos_envelope); + bin.Write(nos_output); + bin.Write(nos_shift_reg); + bin.Write(nos_feedback); + bin.Write(nos_ignore_reload); + } + + private static void NOSReadState(ref BinaryReader bin) + { + nos_length_halt = bin.ReadBoolean(); + nos_constant_volume_envelope = bin.ReadBoolean(); + nos_volume_devider_period = bin.ReadByte(); + nos_timer = bin.ReadUInt16(); + nos_mode = bin.ReadBoolean(); + nos_period_devider = bin.ReadInt32(); + nos_length_enabled = bin.ReadBoolean(); + nos_length_counter = bin.ReadInt32(); + nos_envelope_start_flag = bin.ReadBoolean(); + nos_envelope_devider = bin.ReadByte(); + nos_envelope_decay_level_counter = bin.ReadByte(); + nos_envelope = bin.ReadByte(); + nos_output = bin.ReadInt32(); + nos_shift_reg = bin.ReadInt32(); + nos_feedback = bin.ReadInt32(); + nos_ignore_reload = bin.ReadBoolean(); + } + + private static void SQ1HardReset() + { + sq1_duty_cycle = 0; + sq1_length_halt = false; + sq1_constant_volume_envelope = false; + sq1_volume_devider_period = 0; + sq1_sweep_enable = false; + sq1_sweep_devider_period = 0; + sq1_sweep_negate = false; + sq1_sweep_shift_count = 0; + sq1_timer = 0; + sq1_period_devider = 0; + sq1_seqencer = 0; + sq1_length_enabled = false; + sq1_length_counter = 0; + sq1_envelope_start_flag = false; + sq1_envelope_devider = 0; + sq1_envelope_decay_level_counter = 0; + sq1_envelope = 0; + sq1_sweep_counter = 0; + sq1_sweep_reload = false; + sq1_sweep_change = 0; + sq1_valid_freq = false; + sq1_output = 0; + sq1_ignore_reload = false; + } + + private static void SQ1SoftReset() + { + SQ1HardReset(); + } + + private static void SQ1Clock() + { + sq1_period_devider--; + if (sq1_period_devider > 0) + { + return; + } + sq1_period_devider = sq1_timer + 1; + sq1_seqencer = (byte)((uint)(sq1_seqencer + 1) & 7u); + if (sq1_length_counter > 0 && sq1_valid_freq) + { + if (audio_sq1_outputable) + { + sq1_output = sq_duty_cycle_sequences[sq1_duty_cycle][sq1_seqencer] * sq1_envelope; + } + } + else + { + sq1_output = 0; + } + audio_signal_outputed = true; + } + + private static void SQ1ClockLength() + { + if (sq1_length_counter > 0 && !sq1_length_halt) + { + sq1_length_counter--; + if (apu_reg_access_happened && apu_reg_io_addr == 3 && apu_reg_access_w) + { + sq1_ignore_reload = true; + } + } + sq1_sweep_counter--; + if (sq1_sweep_counter == 0) + { + sq1_sweep_counter = sq1_sweep_devider_period + 1; + if (sq1_sweep_enable && sq1_sweep_shift_count > 0 && sq1_valid_freq) + { + sq1_sweep_change = sq1_timer >> (int)sq1_sweep_shift_count; + sq1_timer += (sq1_sweep_negate ? (~sq1_sweep_change) : sq1_sweep_change); + SQ1CalculateValidFreq(); + } + } + if (sq1_sweep_reload) + { + sq1_sweep_counter = sq1_sweep_devider_period + 1; + sq1_sweep_reload = false; + } + } + + private static void SQ1ClockEnvelope() + { + if (sq1_envelope_start_flag) + { + sq1_envelope_start_flag = false; + sq1_envelope_decay_level_counter = 15; + sq1_envelope_devider = (byte)(sq1_volume_devider_period + 1); + } + else if (sq1_envelope_devider > 0) + { + sq1_envelope_devider--; + } + else + { + sq1_envelope_devider = (byte)(sq1_volume_devider_period + 1); + if (sq1_envelope_decay_level_counter > 0) + { + sq1_envelope_decay_level_counter--; + } + else if (sq1_length_halt) + { + sq1_envelope_decay_level_counter = 15; + } + } + sq1_envelope = (sq1_constant_volume_envelope ? sq1_volume_devider_period : sq1_envelope_decay_level_counter); + } + + private static void APUOnRegister4000() + { + if (apu_reg_access_w) + { + sq1_duty_cycle = (byte)((apu_reg_io_db & 0xC0) >> 6); + sq1_volume_devider_period = (byte)(apu_reg_io_db & 0xFu); + sq1_length_halt = (apu_reg_io_db & 0x20) != 0; + sq1_constant_volume_envelope = (apu_reg_io_db & 0x10) != 0; + sq1_envelope = (sq1_constant_volume_envelope ? sq1_volume_devider_period : sq1_envelope_decay_level_counter); + } + } + + private static void APUOnRegister4001() + { + if (apu_reg_access_w) + { + sq1_sweep_enable = (apu_reg_io_db & 0x80) == 128; + sq1_sweep_devider_period = (byte)((uint)(apu_reg_io_db >> 4) & 7u); + sq1_sweep_negate = (apu_reg_io_db & 8) == 8; + sq1_sweep_shift_count = (byte)(apu_reg_io_db & 7u); + sq1_sweep_reload = true; + SQ1CalculateValidFreq(); + } + } + + private static void APUOnRegister4002() + { + if (apu_reg_access_w) + { + sq1_timer = (sq1_timer & 0xFF00) | apu_reg_io_db; + SQ1CalculateValidFreq(); + } + } + + private static void APUOnRegister4003() + { + if (apu_reg_access_w) + { + sq1_timer = (sq1_timer & 0xFF) | ((apu_reg_io_db & 7) << 8); + if (sq1_length_enabled && !sq1_ignore_reload) + { + sq1_length_counter = sq_duration_table[apu_reg_io_db >> 3]; + } + if (sq1_ignore_reload) + { + sq1_ignore_reload = false; + } + sq1_seqencer = 0; + sq1_envelope_start_flag = true; + SQ1CalculateValidFreq(); + } + } + + private static void SQ1On4015() + { + sq1_length_enabled = (apu_reg_io_db & 1) != 0; + if (!sq1_length_enabled) + { + sq1_length_counter = 0; + } + } + + private static void SQ1Read4015() + { + if (sq1_length_counter > 0) + { + apu_reg_io_db = (byte)((apu_reg_io_db & 0xFEu) | 1u); + } + } + + private static void SQ1CalculateValidFreq() + { + sq1_valid_freq = sq1_timer >= 8 && (sq1_sweep_negate || ((sq1_timer + (sq1_timer >> (int)sq1_sweep_shift_count)) & 0x800) == 0); + } + + private static void SQ1WriteState(ref BinaryWriter bin) + { + bin.Write(sq1_duty_cycle); + bin.Write(sq1_length_halt); + bin.Write(sq1_constant_volume_envelope); + bin.Write(sq1_volume_devider_period); + bin.Write(sq1_sweep_enable); + bin.Write(sq1_sweep_devider_period); + bin.Write(sq1_sweep_negate); + bin.Write(sq1_sweep_shift_count); + bin.Write(sq1_timer); + bin.Write(sq1_period_devider); + bin.Write(sq1_seqencer); + bin.Write(sq1_length_enabled); + bin.Write(sq1_length_counter); + bin.Write(sq1_envelope_start_flag); + bin.Write(sq1_envelope_devider); + bin.Write(sq1_envelope_decay_level_counter); + bin.Write(sq1_envelope); + bin.Write(sq1_sweep_counter); + bin.Write(sq1_sweep_reload); + bin.Write(sq1_sweep_change); + bin.Write(sq1_valid_freq); + bin.Write(sq1_output); + bin.Write(sq1_ignore_reload); + } + + private static void SQ1ReadState(ref BinaryReader bin) + { + sq1_duty_cycle = bin.ReadByte(); + sq1_length_halt = bin.ReadBoolean(); + sq1_constant_volume_envelope = bin.ReadBoolean(); + sq1_volume_devider_period = bin.ReadByte(); + sq1_sweep_enable = bin.ReadBoolean(); + sq1_sweep_devider_period = bin.ReadByte(); + sq1_sweep_negate = bin.ReadBoolean(); + sq1_sweep_shift_count = bin.ReadByte(); + sq1_timer = bin.ReadInt32(); + sq1_period_devider = bin.ReadInt32(); + sq1_seqencer = bin.ReadByte(); + sq1_length_enabled = bin.ReadBoolean(); + sq1_length_counter = bin.ReadInt32(); + sq1_envelope_start_flag = bin.ReadBoolean(); + sq1_envelope_devider = bin.ReadByte(); + sq1_envelope_decay_level_counter = bin.ReadByte(); + sq1_envelope = bin.ReadByte(); + sq1_sweep_counter = bin.ReadInt32(); + sq1_sweep_reload = bin.ReadBoolean(); + sq1_sweep_change = bin.ReadInt32(); + sq1_valid_freq = bin.ReadBoolean(); + sq1_output = bin.ReadInt32(); + sq1_ignore_reload = bin.ReadBoolean(); + } + + private static void TRLHardReset() + { + trl_liner_control_flag = false; + trl_liner_control_reload = 0; + trl_timer = 0; + trl_length_enabled = false; + trl_length_counter = 0; + trl_liner_control_reload_flag = false; + trl_liner_counter = 0; + trl_output = 0; + trl_period_devider = 0; + trl_step = 0; + trl_ignore_reload = false; + } + + private static void TRLSoftReset() + { + TRLHardReset(); + } + + private static void TRLClock() + { + trl_period_devider--; + if (trl_period_devider > 0) + { + return; + } + trl_period_devider = trl_timer + 1; + if (trl_length_counter > 0 && trl_liner_counter > 0 && trl_timer >= 4) + { + trl_step++; + trl_step &= 31; + if (audio_trl_outputable) + { + trl_output = trl_step_seq[trl_step]; + } + } + audio_signal_outputed = true; + } + + private static void TRLClockLength() + { + if (trl_length_counter > 0 && !trl_liner_control_flag) + { + trl_length_counter--; + if (apu_reg_access_happened && apu_reg_io_addr == 11 && apu_reg_access_w) + { + trl_ignore_reload = true; + } + } + } + + private static void TRLClockEnvelope() + { + if (trl_liner_control_reload_flag) + { + trl_liner_counter = trl_liner_control_reload; + } + else if (trl_liner_counter > 0) + { + trl_liner_counter--; + } + if (!trl_liner_control_flag) + { + trl_liner_control_reload_flag = false; + } + } + + private static void APUOnRegister4008() + { + if (apu_reg_access_w) + { + trl_liner_control_flag = (apu_reg_io_db & 0x80) == 128; + trl_liner_control_reload = (byte)(apu_reg_io_db & 0x7Fu); + } + } + + private static void APUOnRegister4009() + { + } + + private static void APUOnRegister400A() + { + if (apu_reg_access_w) + { + trl_timer = (ushort)((trl_timer & 0x7F00u) | apu_reg_io_db); + } + } + + private static void APUOnRegister400B() + { + if (apu_reg_access_w) + { + trl_timer = (ushort)((trl_timer & 0xFFu) | (uint)((apu_reg_io_db & 7) << 8)); + if (trl_length_enabled && !trl_ignore_reload) + { + trl_length_counter = sq_duration_table[apu_reg_io_db >> 3]; + } + if (trl_ignore_reload) + { + trl_ignore_reload = false; + } + trl_liner_control_reload_flag = true; + } + } + + private static void TRLOn4015() + { + trl_length_enabled = (apu_reg_io_db & 4) != 0; + if (!trl_length_enabled) + { + trl_length_counter = 0; + } + } + + private static void TRLRead4015() + { + if (trl_length_counter > 0) + { + apu_reg_io_db = (byte)((apu_reg_io_db & 0xFBu) | 4u); + } + } + + private static void TRLWriteState(ref BinaryWriter bin) + { + bin.Write(trl_liner_control_flag); + bin.Write(trl_liner_control_reload); + bin.Write(trl_timer); + bin.Write(trl_length_enabled); + bin.Write(trl_length_counter); + bin.Write(trl_liner_control_reload_flag); + bin.Write(trl_liner_counter); + bin.Write(trl_output); + bin.Write(trl_period_devider); + bin.Write(trl_step); + bin.Write(trl_ignore_reload); + } + + private static void TRLReadState(ref BinaryReader bin) + { + trl_liner_control_flag = bin.ReadBoolean(); + trl_liner_control_reload = bin.ReadByte(); + trl_timer = bin.ReadUInt16(); + trl_length_enabled = bin.ReadBoolean(); + trl_length_counter = bin.ReadByte(); + trl_liner_control_reload_flag = bin.ReadBoolean(); + trl_liner_counter = bin.ReadByte(); + trl_output = bin.ReadInt32(); + trl_period_devider = bin.ReadInt32(); + trl_step = bin.ReadInt32(); + trl_ignore_reload = bin.ReadBoolean(); + } + + private static void APUInitialize() + { + apu_reg_update_func = new Action[32]; + apu_reg_read_func = new Action[32]; + apu_reg_write_func = new Action[32]; + for (int i = 0; i < 32; i++) + { + apu_reg_update_func[i] = APUBlankAccess; + apu_reg_read_func[i] = APUBlankAccess; + apu_reg_write_func[i] = APUBlankAccess; + } + apu_reg_update_func[0] = APUOnRegister4000; + apu_reg_update_func[1] = APUOnRegister4001; + apu_reg_update_func[2] = APUOnRegister4002; + apu_reg_update_func[3] = APUOnRegister4003; + apu_reg_update_func[4] = APUOnRegister4004; + apu_reg_update_func[5] = APUOnRegister4005; + apu_reg_update_func[6] = APUOnRegister4006; + apu_reg_update_func[7] = APUOnRegister4007; + apu_reg_update_func[8] = APUOnRegister4008; + apu_reg_update_func[9] = APUOnRegister4009; + apu_reg_update_func[10] = APUOnRegister400A; + apu_reg_update_func[11] = APUOnRegister400B; + apu_reg_update_func[12] = APUOnRegister400C; + apu_reg_update_func[13] = APUOnRegister400D; + apu_reg_update_func[14] = APUOnRegister400E; + apu_reg_update_func[15] = APUOnRegister400F; + apu_reg_update_func[16] = APUOnRegister4010; + apu_reg_update_func[17] = APUOnRegister4011; + apu_reg_update_func[18] = APUOnRegister4012; + apu_reg_update_func[19] = APUOnRegister4013; + apu_reg_update_func[21] = APUOnRegister4015; + apu_reg_update_func[22] = APUOnRegister4016; + apu_reg_update_func[23] = APUOnRegister4017; + apu_reg_read_func[21] = APURead4015; + apu_reg_read_func[22] = APURead4016; + apu_reg_read_func[23] = APURead4017; + apu_reg_write_func[20] = APUWrite4014; + apu_reg_write_func[21] = APUWrite4015; + audio_low_pass_filter_14K = new SoundLowPassFilter(0.00815686); + audio_high_pass_filter_90 = new SoundHighPassFilter(0.999835); + audio_high_pass_filter_440 = new SoundHighPassFilter(0.996039); + audio_dc_blocker_filter = new SoundDCBlockerFilter(0.995); + apu_update_playback_func = APUUpdatePlaybackWithFilters; + } + + public static void ApplyAudioSettings(bool all = true) + { + SoundEnabled = MyNesMain.RendererSettings.Audio_SoundEnabled; + audio_sq1_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SQ1; + audio_sq2_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_SQ2; + audio_nos_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_NOZ; + audio_trl_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_TRL; + audio_dmc_outputable = MyNesMain.RendererSettings.Audio_ChannelEnabled_DMC; + if (apu_use_external_sound) + { + mem_board.APUApplyChannelsSettings(); + } + if (all) + { + CalculateAudioPlaybackValues(); + } + } + + private static void APUHardReset() + { + apu_reg_io_db = 0; + apu_reg_io_addr = 0; + apu_reg_access_happened = false; + apu_reg_access_w = false; + apu_seq_mode = false; + apu_odd_cycle = true; + apu_cycle_f_t = 0; + apu_cycle_e = 4; + apu_cycle_f = 4; + apu_cycle_l = 4; + apu_odd_l = false; + apu_check_irq = false; + apu_do_env = false; + apu_do_length = false; + switch (Region) + { + case EmuRegion.NTSC: + cpu_speed = 1789773; + apu_ferq_f = 14914; + apu_ferq_e = 3728; + apu_ferq_l = 7456; + break; + case EmuRegion.PALB: + cpu_speed = 1662607; + apu_ferq_f = 14914; + apu_ferq_e = 3728; + apu_ferq_l = 7456; + break; + case EmuRegion.DENDY: + cpu_speed = 1773448; + apu_ferq_f = 14914; + apu_ferq_e = 3728; + apu_ferq_l = 7456; + break; + } + Tracer.WriteLine("NES: cpu speed = " + cpu_speed); + SQ1HardReset(); + SQ2HardReset(); + NOSHardReset(); + DMCHardReset(); + TRLHardReset(); + apu_irq_enabled = true; + apu_irq_flag = false; + reg_2004 = 8196; + CalculateAudioPlaybackValues(); + apu_use_external_sound = mem_board.enable_external_sound; + if (apu_use_external_sound) + { + Tracer.WriteInformation("External sound channels has been enabled on apu."); + } + } + + private static void APUSoftReset() + { + apu_reg_io_db = 0; + apu_reg_io_addr = 0; + apu_reg_access_happened = false; + apu_reg_access_w = false; + apu_seq_mode = false; + apu_odd_cycle = false; + apu_cycle_f_t = 0; + apu_cycle_e = 4; + apu_cycle_f = 4; + apu_cycle_l = 4; + apu_odd_l = false; + apu_check_irq = false; + apu_do_env = false; + apu_do_length = false; + apu_irq_enabled = true; + apu_irq_flag = false; + SQ1SoftReset(); + SQ2SoftReset(); + TRLSoftReset(); + NOSSoftReset(); + DMCSoftReset(); + } + + private static void APUIORead(ref ushort addr, out byte value) + { + if (addr >= 16416) + { + mem_board.ReadEX(ref addr, out value); + return; + } + apu_reg_io_addr = (byte)(addr & 0x1Fu); + apu_reg_access_happened = true; + apu_reg_access_w = false; + apu_reg_read_func[apu_reg_io_addr](); + value = apu_reg_io_db; + } + + private static void APUIOWrite(ref ushort addr, ref byte value) + { + if (addr >= 16416) + { + mem_board.WriteEX(ref addr, ref value); + return; + } + apu_reg_io_addr = (byte)(addr & 0x1Fu); + apu_reg_io_db = value; + apu_reg_access_w = true; + apu_reg_access_happened = true; + apu_reg_write_func[apu_reg_io_addr](); + } + + private static void APUBlankAccess() + { + } + + private static void APUWrite4014() + { + dma_Oamaddress = (ushort)(apu_reg_io_db << 8); + AssertOAMDMA(); + } + + private static void APUWrite4015() + { + if ((apu_reg_io_db & 0x10u) != 0) + { + if (dmc_dmaSize == 0) + { + dmc_dmaSize = dmc_size_refresh; + dmc_dmaAddr = dmc_addr_refresh; + } + } + else + { + dmc_dmaSize = 0; + } + if (!dmc_bufferFull && dmc_dmaSize > 0) + { + AssertDMCDMA(); + } + } + + private static void APUOnRegister4015() + { + if (apu_reg_access_w) + { + SQ1On4015(); + SQ2On4015(); + NOSOn4015(); + TRLOn4015(); + DMCOn4015(); + } + else + { + apu_irq_flag = false; + IRQFlags &= -2; + } + } + + private static void APUOnRegister4016() + { + if (!apu_reg_access_w) + { + return; + } + if (inputStrobe > (apu_reg_io_db & 1)) + { + if (IsFourPlayers) + { + PORT0 = (joypad3.GetData() << 8) | joypad1.GetData() | 0x1010000; + PORT1 = (joypad4.GetData() << 8) | joypad2.GetData() | 0x2020000; + } + else + { + PORT0 = joypad1.GetData() | 0x1010100; + PORT1 = joypad2.GetData() | 0x2020200; + } + } + inputStrobe = apu_reg_io_db & 1; + } + + private static void APUOnRegister4017() + { + if (apu_reg_access_w) + { + apu_seq_mode = (apu_reg_io_db & 0x80) != 0; + apu_irq_enabled = (apu_reg_io_db & 0x40) == 0; + apu_cycle_e = -1; + apu_cycle_l = -1; + apu_cycle_f = -1; + apu_odd_l = false; + apu_do_length = apu_seq_mode; + apu_do_env = apu_seq_mode; + apu_check_irq = false; + if (!apu_irq_enabled) + { + apu_irq_flag = false; + IRQFlags &= -2; + } + } + } + + private static void APURead4015() + { + apu_reg_io_db &= 32; + SQ1Read4015(); + SQ2Read4015(); + NOSRead4015(); + TRLRead4015(); + DMCRead4015(); + if (apu_irq_flag) + { + apu_reg_io_db = (byte)((apu_reg_io_db & 0xBFu) | 0x40u); + } + if (apu_irq_delta_occur) + { + apu_reg_io_db = (byte)((apu_reg_io_db & 0x7Fu) | 0x80u); + } + } + + private static void APURead4016() + { + apu_reg_io_db = (byte)((uint)PORT0 & 1u); + PORT0 >>= 1; + } + + private static void APURead4017() + { + apu_reg_io_db = (byte)((uint)PORT1 & 1u); + PORT1 >>= 1; + } + + private static void APUClock() + { + apu_odd_cycle = !apu_odd_cycle; + if (apu_do_env) + { + APUClockEnvelope(); + } + if (apu_do_length) + { + APUClockDuration(); + } + if (apu_odd_cycle) + { + apu_cycle_f++; + if (apu_cycle_f >= apu_ferq_f) + { + apu_cycle_f = -1; + apu_check_irq = true; + apu_cycle_f_t = 3; + } + apu_cycle_e++; + if (apu_cycle_e >= apu_ferq_e) + { + apu_cycle_e = -1; + if (apu_check_irq) + { + if (!apu_seq_mode) + { + apu_do_env = true; + } + else + { + apu_cycle_e = 4; + } + } + else + { + apu_do_env = true; + } + } + apu_cycle_l++; + if (apu_cycle_l >= apu_ferq_l) + { + apu_odd_l = !apu_odd_l; + apu_cycle_l = (apu_odd_l ? (-2) : (-1)); + if (apu_check_irq && apu_seq_mode) + { + apu_cycle_l = 3730; + apu_odd_l = true; + } + else + { + apu_do_length = true; + } + } + SQ1Clock(); + SQ2Clock(); + NOSClock(); + if (apu_use_external_sound) + { + mem_board.OnAPUClock(); + } + if (apu_reg_access_happened) + { + apu_reg_access_happened = false; + apu_reg_update_func[apu_reg_io_addr](); + } + } + TRLClock(); + DMCClock(); + if (apu_check_irq) + { + if (!apu_seq_mode) + { + APUCheckIRQ(); + } + apu_cycle_f_t--; + if (apu_cycle_f_t == 0) + { + apu_check_irq = false; + } + } + if (apu_use_external_sound) + { + mem_board.OnAPUClockSingle(); + } + apu_update_playback_func(); + } + + private static void APUClockDuration() + { + SQ1ClockLength(); + SQ2ClockLength(); + NOSClockLength(); + TRLClockLength(); + if (apu_use_external_sound) + { + mem_board.OnAPUClockDuration(); + } + apu_do_length = false; + } + + private static void APUClockEnvelope() + { + SQ1ClockEnvelope(); + SQ2ClockEnvelope(); + NOSClockEnvelope(); + TRLClockEnvelope(); + if (apu_use_external_sound) + { + mem_board.OnAPUClockEnvelope(); + } + apu_do_env = false; + } + + private static void APUCheckIRQ() + { + if (apu_irq_enabled) + { + apu_irq_flag = true; + } + if (apu_irq_flag) + { + IRQFlags |= 1; + } + } + + private static void CalculateAudioPlaybackValues() + { + audio_timer_ratio = (double)cpu_speed / (double)MyNesMain.RendererSettings.Audio_Frequency; + audio_playback_peek_limit = MyNesMain.RendererSettings.Audio_InternalPeekLimit; + audio_samples_count = MyNesMain.RendererSettings.Audio_InternalSamplesCount; + audio_playback_amplitude = MyNesMain.RendererSettings.Audio_PlaybackAmplitude; + audio_samples = new short[audio_samples_count]; + audio_w_pos = 0; + audio_samples_added = 0; + audio_timer = 0.0; + audio_x = (audio_y = 0.0); + Tracer.WriteLine("AUDIO: frequency = " + MyNesMain.RendererSettings.Audio_Frequency); + Tracer.WriteLine("AUDIO: timer ratio = " + audio_timer_ratio); + Tracer.WriteLine("AUDIO: internal samples count = " + audio_samples_count); + Tracer.WriteLine("AUDIO: amplitude = " + audio_playback_amplitude); + if (MyNesMain.RendererSettings.Audio_EnableFilters) + { + apu_update_playback_func = APUUpdatePlaybackWithFilters; + audio_low_pass_filter_14K = new SoundLowPassFilter(SoundLowPassFilter.GetK((double)cpu_speed / 14000.0, 14000.0)); + audio_high_pass_filter_90 = new SoundHighPassFilter(SoundHighPassFilter.GetK((double)cpu_speed / 90.0, 90.0)); + audio_high_pass_filter_440 = new SoundHighPassFilter(SoundHighPassFilter.GetK((double)cpu_speed / 440.0, 440.0)); + } + else + { + apu_update_playback_func = APUUpdatePlaybackWithoutFilters; + } + InitializeDACTables(force_intitialize: false); + } + + public static void InitializeDACTables(bool force_intitialize) + { + if (audio_playback_dac_initialized && !force_intitialize) + { + return; + } + int[] array = new int[5]; + mix_table = new int[16][][][][]; + for (int i = 0; i < 16; i++) + { + mix_table[i] = new int[16][][][]; + for (int j = 0; j < 16; j++) + { + mix_table[i][j] = new int[16][][]; + for (int k = 0; k < 16; k++) + { + mix_table[i][j][k] = new int[16][]; + for (int l = 0; l < 16; l++) + { + mix_table[i][j][k][l] = new int[128]; + for (int m = 0; m < 128; m++) + { + if (MyNesMain.RendererSettings.Audio_UseDefaultMixer) + { + double num = 95.88 / (8128.0 / (double)(i + j) + 100.0); + double num2 = 159.79 / (1.0 / ((double)k / 8227.0 + (double)l / 12241.0 + (double)m / 22638.0) + 100.0); + mix_table[i][j][k][l][m] = (int)Math.Ceiling((num + num2) * audio_playback_amplitude); + continue; + } + GetPrec(i, 255, 2048, out array[0]); + GetPrec(j, 255, 2048, out array[1]); + GetPrec(l, 255, 2048, out array[2]); + GetPrec(k, 255, 2048, out array[3]); + GetPrec(m, 255, 2048, out array[4]); + array[4] /= 2; + int num3 = array[0] + array[1] + array[2] + array[3] + array[4]; + num3 /= 5; + mix_table[i][j][k][l][m] = num3; + } + } + } + } + } + audio_playback_dac_initialized = true; + } + + private static void APUUpdatePlaybackWithFilters() + { + if (!SoundEnabled) + { + return; + } + audio_x = mix_table[sq1_output][sq2_output][trl_output][nos_output][dmc_output]; + if (apu_use_external_sound) + { + audio_x = (audio_x + mem_board.APUGetSample() * audio_playback_amplitude) / 2.0; + } + audio_high_pass_filter_90.DoFiltering(audio_x, out audio_y); + audio_high_pass_filter_440.DoFiltering(audio_y, out audio_y); + audio_low_pass_filter_14K.DoFiltering(audio_y, out audio_y); + audio_y_av += audio_y; + audio_y_timer += 1.0; + audio_timer += 1.0; + if (!(audio_timer >= audio_timer_ratio)) + { + return; + } + if (audio_y_timer > 0.0) + { + audio_y = audio_y_av / audio_y_timer; + } + else + { + audio_y = 0.0; + } + audio_y_av = 0.0; + audio_y_timer = 0.0; + audio_timer -= audio_timer_ratio; + if (audio_w_pos < audio_samples_count) + { + if (audio_y > (double)audio_playback_peek_limit) + { + audio_y = audio_playback_peek_limit; + } + if (audio_y < (double)(-audio_playback_peek_limit)) + { + audio_y = -audio_playback_peek_limit; + } + audio_samples[audio_w_pos] = (short)audio_y; + if (MyNesMain.WaveRecorder.IsRecording) + { + MyNesMain.WaveRecorder.AddSample((short)audio_y); + } + audio_w_pos++; + audio_samples_added++; + } + audio_y = 0.0; + } + + private static void APUUpdatePlaybackWithoutFilters() + { + if (!SoundEnabled) + { + return; + } + audio_y = mix_table[sq1_output][sq2_output][trl_output][nos_output][dmc_output] / 2; + if (apu_use_external_sound) + { + audio_y = (audio_y + mem_board.APUGetSample() * audio_playback_amplitude) / 2.0; + } + audio_y_av += audio_y; + audio_y_timer += 1.0; + audio_timer += 1.0; + if (!(audio_timer >= audio_timer_ratio)) + { + return; + } + if (audio_y_timer > 0.0) + { + audio_y = audio_y_av / audio_y_timer; + } + else + { + audio_y = 0.0; + } + audio_y_av = 0.0; + audio_y_timer = 0.0; + audio_timer -= audio_timer_ratio; + if (audio_w_pos < audio_samples_count) + { + if (audio_y > (double)audio_playback_peek_limit) + { + audio_y = audio_playback_peek_limit; + } + if (audio_y < (double)(-audio_playback_peek_limit)) + { + audio_y = -audio_playback_peek_limit; + } + audio_samples[audio_w_pos] = (short)audio_y; + if (MyNesMain.WaveRecorder.IsRecording) + { + MyNesMain.WaveRecorder.AddSample((short)audio_y); + } + audio_w_pos++; + audio_samples_added++; + } + audio_y = 0.0; + } + + private static void GetPrec(int inVal, int inMax, int outMax, out int val) + { + val = outMax * inVal / inMax; + } + + private static void APUWriteState(ref BinaryWriter bin) + { + bin.Write(apu_reg_io_db); + bin.Write(apu_reg_io_addr); + bin.Write(apu_reg_access_happened); + bin.Write(apu_reg_access_w); + bin.Write(apu_odd_cycle); + bin.Write(apu_irq_enabled); + bin.Write(apu_irq_flag); + bin.Write(apu_irq_delta_occur); + bin.Write(apu_seq_mode); + bin.Write(apu_ferq_f); + bin.Write(apu_ferq_l); + bin.Write(apu_ferq_e); + bin.Write(apu_cycle_f); + bin.Write(apu_cycle_e); + bin.Write(apu_cycle_l); + bin.Write(apu_odd_l); + bin.Write(apu_cycle_f_t); + bin.Write(apu_check_irq); + bin.Write(apu_do_env); + bin.Write(apu_do_length); + SQ1WriteState(ref bin); + SQ2WriteState(ref bin); + NOSWriteState(ref bin); + TRLWriteState(ref bin); + DMCWriteState(ref bin); + } + + private static void APUReadState(ref BinaryReader bin) + { + apu_reg_io_db = bin.ReadByte(); + apu_reg_io_addr = bin.ReadByte(); + apu_reg_access_happened = bin.ReadBoolean(); + apu_reg_access_w = bin.ReadBoolean(); + apu_odd_cycle = bin.ReadBoolean(); + apu_irq_enabled = bin.ReadBoolean(); + apu_irq_flag = bin.ReadBoolean(); + apu_irq_delta_occur = bin.ReadBoolean(); + apu_seq_mode = bin.ReadBoolean(); + apu_ferq_f = bin.ReadInt32(); + apu_ferq_l = bin.ReadInt32(); + apu_ferq_e = bin.ReadInt32(); + apu_cycle_f = bin.ReadInt32(); + apu_cycle_e = bin.ReadInt32(); + apu_cycle_l = bin.ReadInt32(); + apu_odd_l = bin.ReadBoolean(); + apu_cycle_f_t = bin.ReadInt32(); + apu_check_irq = bin.ReadBoolean(); + apu_do_env = bin.ReadBoolean(); + apu_do_length = bin.ReadBoolean(); + SQ1ReadState(ref bin); + SQ2ReadState(ref bin); + NOSReadState(ref bin); + TRLReadState(ref bin); + DMCReadState(ref bin); + } + + private static byte register_pb() + { + return (byte)((cpu_flag_n ? 128u : 0u) | (cpu_flag_v ? 64u : 0u) | (cpu_flag_d ? 8u : 0u) | (cpu_flag_i ? 4u : 0u) | (cpu_flag_z ? 2u : 0u) | (cpu_flag_c ? 1u : 0u) | 0x30u); + } + + private static void CPUInitialize() + { + cpu_addressings = new Action[256] + { + Imp____, IndX_R_, ImA____, IndX_W_, Zpg_R__, Zpg_R__, Zpg_RW_, Zpg_W__, ImA____, Imm____, + ImA____, Imm____, Abs_R__, Abs_R__, Abs_RW_, Abs_W__, Imp____, IndY_R_, Imp____, IndY_W_, + ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, ImA____, AbsY_R_, ImA____, AbsY_W_, AbsX_R_, AbsX_R_, + AbsX_RW, AbsX_W_, Imp____, IndX_R_, ImA____, IndX_W_, Zpg_R__, Zpg_R__, Zpg_RW_, Zpg_W__, + ImA____, Imm____, ImA____, Imm____, Abs_R__, Abs_R__, Abs_RW_, Abs_W__, Imp____, IndY_R_, + Imp____, IndY_W_, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, ImA____, AbsY_R_, ImA____, AbsY_W_, + AbsX_R_, AbsX_R_, AbsX_RW, AbsX_W_, ImA____, IndX_R_, ImA____, IndX_W_, Zpg_R__, Zpg_R__, + Zpg_RW_, Zpg_W__, ImA____, Imm____, ImA____, Imm____, Abs_W__, Abs_R__, Abs_RW_, Abs_W__, + Imp____, IndY_R_, Imp____, IndY_W_, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, ImA____, AbsY_R_, + ImA____, AbsY_W_, AbsX_R_, AbsX_R_, AbsX_RW, AbsX_W_, ImA____, IndX_R_, ImA____, IndX_W_, + Zpg_R__, Zpg_R__, Zpg_RW_, Zpg_W__, ImA____, Imm____, ImA____, Imm____, Imp____, Abs_R__, + Abs_RW_, Abs_W__, Imp____, IndY_R_, Imp____, IndY_W_, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, + ImA____, AbsY_R_, ImA____, AbsY_W_, AbsX_R_, AbsX_R_, AbsX_RW, AbsX_W_, Imm____, IndX_W_, + Imm____, IndX_W_, Zpg_W__, Zpg_W__, Zpg_W__, Zpg_W__, ImA____, Imm____, ImA____, Imm____, + Abs_W__, Abs_W__, Abs_W__, Abs_W__, Imp____, IndY_W_, Imp____, IndY_W_, ZpgX_W_, ZpgX_W_, + ZpgY_W_, ZpgY_W_, ImA____, AbsY_W_, ImA____, AbsY_W_, Abs_W__, AbsX_W_, Abs_W__, AbsY_W_, + Imm____, IndX_R_, Imm____, IndX_R_, Zpg_R__, Zpg_R__, Zpg_R__, Zpg_R__, ImA____, Imm____, + ImA____, Imm____, Abs_R__, Abs_R__, Abs_R__, Abs_R__, Imp____, IndY_R_, Imp____, IndY_R_, + ZpgX_R_, ZpgX_R_, ZpgY_R_, ZpgY_R_, ImA____, AbsY_R_, ImA____, AbsY_R_, AbsX_R_, AbsX_R_, + AbsY_R_, AbsY_R_, Imm____, IndX_R_, Imm____, IndX_R_, Zpg_R__, Zpg_R__, Zpg_RW_, Zpg_R__, + ImA____, Imm____, ImA____, Imm____, Abs_R__, Abs_R__, Abs_RW_, Abs_R__, Imp____, IndY_R_, + Imp____, IndY_RW, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_RW, ImA____, AbsY_R_, ImA____, AbsY_RW, + AbsX_R_, AbsX_R_, AbsX_RW, AbsX_RW, Imm____, IndX_R_, Imm____, IndX_W_, Zpg_R__, Zpg_R__, + Zpg_RW_, Zpg_W__, ImA____, Imm____, ImA____, Imm____, Abs_R__, Abs_R__, Abs_RW_, Abs_W__, + Imp____, IndY_R_, Imp____, IndY_W_, ZpgX_R_, ZpgX_R_, ZpgX_RW, ZpgX_W_, ImA____, AbsY_R_, + ImA____, AbsY_W_, AbsX_R_, AbsX_R_, AbsX_RW, AbsX_W_ + }; + cpu_instructions = new Action[256] + { + BRK__, ORA__, NOP__, SLO__, NOP__, ORA__, ASL_M, SLO__, PHP__, ORA__, + ASL_A, ANC__, NOP__, ORA__, ASL_M, SLO__, BPL__, ORA__, NOP__, SLO__, + NOP__, ORA__, ASL_M, SLO__, CLC__, ORA__, NOP__, SLO__, NOP__, ORA__, + ASL_M, SLO__, JSR__, AND__, NOP__, RLA__, BIT__, AND__, ROL_M, RLA__, + PLP__, AND__, ROL_A, ANC__, BIT__, AND__, ROL_M, RLA__, BMI__, AND__, + NOP__, RLA__, NOP__, AND__, ROL_M, RLA__, SEC__, AND__, NOP__, RLA__, + NOP__, AND__, ROL_M, RLA__, RTI__, EOR__, NOP__, SRE__, NOP__, EOR__, + LSR_M, SRE__, PHA__, EOR__, LSR_A, ALR__, JMP__, EOR__, LSR_M, SRE__, + BVC__, EOR__, NOP__, SRE__, NOP__, EOR__, LSR_M, SRE__, CLI__, EOR__, + NOP__, SRE__, NOP__, EOR__, LSR_M, SRE__, RTS__, ADC__, NOP__, RRA__, + NOP__, ADC__, ROR_M, RRA__, PLA__, ADC__, ROR_A, ARR__, JMP_I, ADC__, + ROR_M, RRA__, BVS__, ADC__, NOP__, RRA__, NOP__, ADC__, ROR_M, RRA__, + SEI__, ADC__, NOP__, RRA__, NOP__, ADC__, ROR_M, RRA__, NOP__, STA__, + NOP__, SAX__, STY__, STA__, STX__, SAX__, DEY__, NOP__, TXA__, XAA__, + STY__, STA__, STX__, SAX__, BCC__, STA__, NOP__, AHX__, STY__, STA__, + STX__, SAX__, TYA__, STA__, TXS__, XAS__, SHY__, STA__, SHX__, AHX__, + LDY__, LDA__, LDX__, LAX__, LDY__, LDA__, LDX__, LAX__, TAY__, LDA__, + TAX__, LAX__, LDY__, LDA__, LDX__, LAX__, BCS__, LDA__, NOP__, LAX__, + LDY__, LDA__, LDX__, LAX__, CLV__, LDA__, TSX__, LAR__, LDY__, LDA__, + LDX__, LAX__, CPY__, CMP__, NOP__, DCP__, CPY__, CMP__, DEC__, DCP__, + INY__, CMP__, DEX__, AXS__, CPY__, CMP__, DEC__, DCP__, BNE__, CMP__, + NOP__, DCP__, NOP__, CMP__, DEC__, DCP__, CLD__, CMP__, NOP__, DCP__, + NOP__, CMP__, DEC__, DCP__, CPX__, SBC__, NOP__, ISC__, CPX__, SBC__, + INC__, ISC__, INX__, SBC__, NOP__, SBC__, CPX__, SBC__, INC__, ISC__, + BEQ__, SBC__, NOP__, ISC__, NOP__, SBC__, INC__, ISC__, SED__, SBC__, + NOP__, ISC__, NOP__, SBC__, INC__, ISC__ + }; + } + + private static void CPUClock() + { + Read(ref cpu_reg_pc.v, out cpu_opcode); + cpu_reg_pc.v++; + cpu_addressings[cpu_opcode](); + cpu_instructions[cpu_opcode](); + if (CPU_IRQ_PIN || CPU_NMI_PIN) + { + Read(ref cpu_reg_pc.v, out cpu_dummy); + Read(ref cpu_reg_pc.v, out cpu_dummy); + Interrupt(); + } + } + + private static void CPUHardReset() + { + cpu_reg_a = 0; + cpu_reg_x = 0; + cpu_reg_y = 0; + cpu_reg_sp.l = 253; + cpu_reg_sp.h = 1; + ushort addr = 65532; + mem_board.ReadPRG(ref addr, out cpu_reg_pc.l); + addr++; + mem_board.ReadPRG(ref addr, out cpu_reg_pc.h); + register_p = 0; + cpu_flag_i = true; + cpu_reg_ea.v = 0; + cpu_opcode = 0; + CPU_IRQ_PIN = false; + CPU_NMI_PIN = false; + cpu_suspend_nmi = false; + cpu_suspend_irq = false; + IRQFlags = 0; + } + + private static void CPUSoftReset() + { + cpu_flag_i = true; + cpu_reg_sp.v -= 3; + ushort addr = 65532; + Read(ref addr, out cpu_reg_pc.l); + addr++; + Read(ref addr, out cpu_reg_pc.h); + } + + private static void Imp____() + { + } + + private static void IndX_R_() + { + temp_add.h = 0; + Read(ref cpu_reg_pc.v, out temp_add.l); + cpu_reg_pc.v++; + Read(ref temp_add.v, out cpu_dummy); + temp_add.l += cpu_reg_x; + Read(ref temp_add.v, out cpu_reg_ea.l); + temp_add.l++; + Read(ref temp_add.v, out cpu_reg_ea.h); + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void IndX_W_() + { + temp_add.h = 0; + Read(ref cpu_reg_pc.v, out temp_add.l); + cpu_reg_pc.v++; + Read(ref temp_add.v, out cpu_dummy); + temp_add.l += cpu_reg_x; + Read(ref temp_add.v, out cpu_reg_ea.l); + temp_add.l++; + Read(ref temp_add.v, out cpu_reg_ea.h); + } + + private static void IndX_RW() + { + temp_add.h = 0; + Read(ref cpu_reg_pc.v, out temp_add.l); + cpu_reg_pc.v++; + Read(ref temp_add.v, out cpu_dummy); + temp_add.l += cpu_reg_x; + Read(ref temp_add.v, out cpu_reg_ea.l); + temp_add.l++; + Read(ref temp_add.v, out cpu_reg_ea.h); + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void IndY_R_() + { + temp_add.h = 0; + Read(ref cpu_reg_pc.v, out temp_add.l); + cpu_reg_pc.v++; + Read(ref temp_add.v, out cpu_reg_ea.l); + temp_add.l++; + Read(ref temp_add.v, out cpu_reg_ea.h); + cpu_reg_ea.l += cpu_reg_y; + Read(ref cpu_reg_ea.v, out cpu_m); + if (cpu_reg_ea.l < cpu_reg_y) + { + cpu_reg_ea.h++; + Read(ref cpu_reg_ea.v, out cpu_m); + } + } + + private static void IndY_W_() + { + temp_add.h = 0; + Read(ref cpu_reg_pc.v, out temp_add.l); + cpu_reg_pc.v++; + Read(ref temp_add.v, out cpu_reg_ea.l); + temp_add.l++; + Read(ref temp_add.v, out cpu_reg_ea.h); + cpu_reg_ea.l += cpu_reg_y; + Read(ref cpu_reg_ea.v, out cpu_m); + if (cpu_reg_ea.l < cpu_reg_y) + { + cpu_reg_ea.h++; + } + } + + private static void IndY_RW() + { + temp_add.h = 0; + Read(ref cpu_reg_pc.v, out temp_add.l); + cpu_reg_pc.v++; + Read(ref temp_add.v, out cpu_reg_ea.l); + temp_add.l++; + Read(ref temp_add.v, out cpu_reg_ea.h); + cpu_reg_ea.l += cpu_reg_y; + Read(ref cpu_reg_ea.v, out cpu_dummy); + if (cpu_reg_ea.l < cpu_reg_y) + { + cpu_reg_ea.h++; + } + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void Zpg_R__() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void Zpg_W__() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + } + + private static void Zpg_RW_() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void ZpgX_R_() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_dummy); + cpu_reg_ea.l += cpu_reg_x; + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void ZpgX_W_() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_dummy); + cpu_reg_ea.l += cpu_reg_x; + } + + private static void ZpgX_RW() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_dummy); + cpu_reg_ea.l += cpu_reg_x; + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void ZpgY_R_() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_dummy); + cpu_reg_ea.l += cpu_reg_y; + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void ZpgY_W_() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_dummy); + cpu_reg_ea.l += cpu_reg_y; + } + + private static void ZpgY_RW() + { + cpu_reg_ea.h = 0; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_dummy); + cpu_reg_ea.l += cpu_reg_y; + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void Imm____() + { + Read(ref cpu_reg_pc.v, out cpu_m); + cpu_reg_pc.v++; + } + + private static void ImA____() + { + Read(ref cpu_reg_pc.v, out cpu_dummy); + } + + private static void Abs_R__() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void Abs_W__() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + } + + private static void Abs_RW_() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void AbsX_R_() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + cpu_reg_ea.l += cpu_reg_x; + Read(ref cpu_reg_ea.v, out cpu_m); + if (cpu_reg_ea.l < cpu_reg_x) + { + cpu_reg_ea.h++; + Read(ref cpu_reg_ea.v, out cpu_m); + } + } + + private static void AbsX_W_() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + cpu_reg_ea.l += cpu_reg_x; + Read(ref cpu_reg_ea.v, out cpu_m); + if (cpu_reg_ea.l < cpu_reg_x) + { + cpu_reg_ea.h++; + } + } + + private static void AbsX_RW() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + cpu_reg_ea.l += cpu_reg_x; + Read(ref cpu_reg_ea.v, out cpu_dummy); + if (cpu_reg_ea.l < cpu_reg_x) + { + cpu_reg_ea.h++; + } + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void AbsY_R_() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + cpu_reg_ea.l += cpu_reg_y; + Read(ref cpu_reg_ea.v, out cpu_m); + if (cpu_reg_ea.l < cpu_reg_y) + { + cpu_reg_ea.h++; + Read(ref cpu_reg_ea.v, out cpu_m); + } + } + + private static void AbsY_W_() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + cpu_reg_ea.l += cpu_reg_y; + Read(ref cpu_reg_ea.v, out cpu_m); + if (cpu_reg_ea.l < cpu_reg_y) + { + cpu_reg_ea.h++; + } + } + + private static void AbsY_RW() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v++; + cpu_reg_ea.l += cpu_reg_y; + Read(ref cpu_reg_ea.v, out cpu_m); + if (cpu_reg_ea.l < cpu_reg_y) + { + cpu_reg_ea.h++; + } + Read(ref cpu_reg_ea.v, out cpu_m); + } + + private static void Interrupt() + { + Push(ref cpu_reg_pc.h); + Push(ref cpu_reg_pc.l); + cpu_dummy = ((cpu_opcode == 0) ? register_pb() : register_p); + Push(ref cpu_dummy); + temp_add.v = InterruptVector; + cpu_suspend_nmi = true; + cpu_flag_i = true; + CPU_NMI_PIN = false; + Read(ref temp_add.v, out cpu_reg_pc.l); + temp_add.v++; + Read(ref temp_add.v, out cpu_reg_pc.h); + cpu_suspend_nmi = false; + } + + private static void Branch(ref bool condition) + { + Read(ref cpu_reg_pc.v, out cpu_byte_temp); + cpu_reg_pc.v++; + if (!condition) + { + return; + } + cpu_suspend_irq = true; + Read(ref cpu_reg_pc.v, out cpu_dummy); + cpu_reg_pc.l += cpu_byte_temp; + cpu_suspend_irq = false; + if (cpu_byte_temp >= 128) + { + if (cpu_reg_pc.l >= cpu_byte_temp) + { + Read(ref cpu_reg_pc.v, out cpu_dummy); + cpu_reg_pc.h--; + } + } + else if (cpu_reg_pc.l < cpu_byte_temp) + { + Read(ref cpu_reg_pc.v, out cpu_dummy); + cpu_reg_pc.h++; + } + } + + private static void Push(ref byte val) + { + Write(ref cpu_reg_sp.v, ref val); + cpu_reg_sp.l--; + } + + private static void Pull(out byte val) + { + cpu_reg_sp.l++; + Read(ref cpu_reg_sp.v, out val); + } + + private static void ADC__() + { + cpu_int_temp = cpu_reg_a + cpu_m + (cpu_flag_c ? 1 : 0); + cpu_flag_v = ((cpu_int_temp ^ cpu_reg_a) & (cpu_int_temp ^ cpu_m) & 0x80) != 0; + cpu_flag_n = (cpu_int_temp & 0x80) != 0; + cpu_flag_z = (cpu_int_temp & 0xFF) == 0; + cpu_flag_c = cpu_int_temp >> 8 != 0; + cpu_reg_a = (byte)((uint)cpu_int_temp & 0xFFu); + } + + private static void AHX__() + { + cpu_byte_temp = (byte)((uint)(cpu_reg_a & cpu_reg_x) & 7u); + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + } + + private static void ALR__() + { + cpu_reg_a &= cpu_m; + cpu_flag_c = (cpu_reg_a & 1) != 0; + cpu_reg_a >>= 1; + cpu_flag_n = (cpu_reg_a & 0x80) != 0; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void ANC__() + { + cpu_reg_a &= cpu_m; + cpu_flag_n = (cpu_reg_a & 0x80) != 0; + cpu_flag_z = cpu_reg_a == 0; + cpu_flag_c = (cpu_reg_a & 0x80) != 0; + } + + private static void AND__() + { + cpu_reg_a &= cpu_m; + cpu_flag_n = (cpu_reg_a & 0x80) == 128; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void ARR__() + { + cpu_reg_a = (byte)((uint)((cpu_m & cpu_reg_a) >> 1) | (cpu_flag_c ? 128u : 0u)); + cpu_flag_z = (cpu_reg_a & 0xFF) == 0; + cpu_flag_n = (cpu_reg_a & 0x80) != 0; + cpu_flag_c = (cpu_reg_a & 0x40) != 0; + cpu_flag_v = (((cpu_reg_a << 1) ^ cpu_reg_a) & 0x40) != 0; + } + + private static void AXS__() + { + cpu_int_temp = (cpu_reg_a & cpu_reg_x) - cpu_m; + cpu_flag_n = (cpu_int_temp & 0x80) != 0; + cpu_flag_z = (cpu_int_temp & 0xFF) == 0; + cpu_flag_c = ~cpu_int_temp >> 8 != 0; + cpu_reg_x = (byte)((uint)cpu_int_temp & 0xFFu); + } + + private static void ASL_M() + { + cpu_flag_c = (cpu_m & 0x80) == 128; + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_m = (byte)((uint)(cpu_m << 1) & 0xFEu); + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_flag_n = (cpu_m & 0x80) == 128; + cpu_flag_z = cpu_m == 0; + } + + private static void ASL_A() + { + cpu_flag_c = (cpu_reg_a & 0x80) == 128; + cpu_reg_a = (byte)((uint)(cpu_reg_a << 1) & 0xFEu); + cpu_flag_n = (cpu_reg_a & 0x80) == 128; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void BCC__() + { + cpu_bool_tmp = !cpu_flag_c; + Branch(ref cpu_bool_tmp); + } + + private static void BCS__() + { + Branch(ref cpu_flag_c); + } + + private static void BEQ__() + { + Branch(ref cpu_flag_z); + } + + private static void BIT__() + { + cpu_flag_n = (cpu_m & 0x80) != 0; + cpu_flag_v = (cpu_m & 0x40) != 0; + cpu_flag_z = (cpu_m & cpu_reg_a) == 0; + } + + private static void BRK__() + { + Read(ref cpu_reg_pc.v, out cpu_dummy); + cpu_reg_pc.v++; + Interrupt(); + } + + private static void BPL__() + { + cpu_bool_tmp = !cpu_flag_n; + Branch(ref cpu_bool_tmp); + } + + private static void BNE__() + { + cpu_bool_tmp = !cpu_flag_z; + Branch(ref cpu_bool_tmp); + } + + private static void BMI__() + { + Branch(ref cpu_flag_n); + } + + private static void BVC__() + { + cpu_bool_tmp = !cpu_flag_v; + Branch(ref cpu_bool_tmp); + } + + private static void BVS__() + { + Branch(ref cpu_flag_v); + } + + private static void SED__() + { + cpu_flag_d = true; + } + + private static void CLC__() + { + cpu_flag_c = false; + } + + private static void CLD__() + { + cpu_flag_d = false; + } + + private static void CLV__() + { + cpu_flag_v = false; + } + + private static void CMP__() + { + cpu_int_temp = cpu_reg_a - cpu_m; + cpu_flag_n = (cpu_int_temp & 0x80) == 128; + cpu_flag_c = cpu_reg_a >= cpu_m; + cpu_flag_z = cpu_int_temp == 0; + } + + private static void CPX__() + { + cpu_int_temp = cpu_reg_x - cpu_m; + cpu_flag_n = (cpu_int_temp & 0x80) == 128; + cpu_flag_c = cpu_reg_x >= cpu_m; + cpu_flag_z = cpu_int_temp == 0; + } + + private static void CPY__() + { + cpu_int_temp = cpu_reg_y - cpu_m; + cpu_flag_n = (cpu_int_temp & 0x80) == 128; + cpu_flag_c = cpu_reg_y >= cpu_m; + cpu_flag_z = cpu_int_temp == 0; + } + + private static void CLI__() + { + cpu_flag_i = false; + } + + private static void DCP__() + { + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_m--; + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_int_temp = cpu_reg_a - cpu_m; + cpu_flag_n = (cpu_int_temp & 0x80) != 0; + cpu_flag_z = cpu_int_temp == 0; + cpu_flag_c = ~cpu_int_temp >> 8 != 0; + } + + private static void DEC__() + { + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_m--; + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_flag_n = (cpu_m & 0x80) == 128; + cpu_flag_z = cpu_m == 0; + } + + private static void DEY__() + { + cpu_reg_y--; + cpu_flag_z = cpu_reg_y == 0; + cpu_flag_n = (cpu_reg_y & 0x80) == 128; + } + + private static void DEX__() + { + cpu_reg_x--; + cpu_flag_z = cpu_reg_x == 0; + cpu_flag_n = (cpu_reg_x & 0x80) == 128; + } + + private static void EOR__() + { + cpu_reg_a ^= cpu_m; + cpu_flag_n = (cpu_reg_a & 0x80) == 128; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void INC__() + { + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_m++; + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_flag_n = (cpu_m & 0x80) == 128; + cpu_flag_z = cpu_m == 0; + } + + private static void INX__() + { + cpu_reg_x++; + cpu_flag_z = cpu_reg_x == 0; + cpu_flag_n = (cpu_reg_x & 0x80) == 128; + } + + private static void INY__() + { + cpu_reg_y++; + cpu_flag_n = (cpu_reg_y & 0x80) == 128; + cpu_flag_z = cpu_reg_y == 0; + } + + private static void ISC__() + { + Read(ref cpu_reg_ea.v, out cpu_byte_temp); + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_byte_temp++; + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_int_temp = cpu_byte_temp ^ 0xFF; + cpu_int_temp1 = cpu_reg_a + cpu_int_temp + (cpu_flag_c ? 1 : 0); + cpu_flag_n = (cpu_int_temp1 & 0x80) != 0; + cpu_flag_v = ((cpu_int_temp1 ^ cpu_reg_a) & (cpu_int_temp1 ^ cpu_int_temp) & 0x80) != 0; + cpu_flag_z = (cpu_int_temp1 & 0xFF) == 0; + cpu_flag_c = cpu_int_temp1 >> 8 != 0; + cpu_reg_a = (byte)((uint)cpu_int_temp1 & 0xFFu); + } + + private static void JMP__() + { + cpu_reg_pc.v = cpu_reg_ea.v; + } + + private static void JMP_I() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + Read(ref cpu_reg_ea.v, out cpu_reg_pc.l); + cpu_reg_ea.l++; + Read(ref cpu_reg_ea.v, out cpu_reg_pc.h); + } + + private static void JSR__() + { + Read(ref cpu_reg_pc.v, out cpu_reg_ea.l); + cpu_reg_pc.v++; + Write(ref cpu_reg_sp.v, ref cpu_reg_ea.l); + Push(ref cpu_reg_pc.h); + Push(ref cpu_reg_pc.l); + Read(ref cpu_reg_pc.v, out cpu_reg_ea.h); + cpu_reg_pc.v = cpu_reg_ea.v; + } + + private static void LAR__() + { + cpu_reg_sp.l &= cpu_m; + cpu_reg_a = cpu_reg_sp.l; + cpu_reg_x = cpu_reg_sp.l; + cpu_flag_n = (cpu_reg_sp.l & 0x80) != 0; + cpu_flag_z = (cpu_reg_sp.l & 0xFF) == 0; + } + + private static void LAX__() + { + cpu_reg_x = (cpu_reg_a = cpu_m); + cpu_flag_n = (cpu_reg_x & 0x80) != 0; + cpu_flag_z = (cpu_reg_x & 0xFF) == 0; + } + + private static void LDA__() + { + cpu_reg_a = cpu_m; + cpu_flag_n = (cpu_reg_a & 0x80) == 128; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void LDX__() + { + cpu_reg_x = cpu_m; + cpu_flag_n = (cpu_reg_x & 0x80) == 128; + cpu_flag_z = cpu_reg_x == 0; + } + + private static void LDY__() + { + cpu_reg_y = cpu_m; + cpu_flag_n = (cpu_reg_y & 0x80) == 128; + cpu_flag_z = cpu_reg_y == 0; + } + + private static void LSR_A() + { + cpu_flag_c = (cpu_reg_a & 1) == 1; + cpu_reg_a >>= 1; + cpu_flag_z = cpu_reg_a == 0; + cpu_flag_n = (cpu_reg_a & 0x80) != 0; + } + + private static void LSR_M() + { + cpu_flag_c = (cpu_m & 1) == 1; + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_m >>= 1; + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_flag_z = cpu_m == 0; + cpu_flag_n = (cpu_m & 0x80) != 0; + } + + private static void NOP__() + { + } + + private static void ORA__() + { + cpu_reg_a |= cpu_m; + cpu_flag_n = (cpu_reg_a & 0x80) == 128; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void PHA__() + { + Push(ref cpu_reg_a); + } + + private static void PHP__() + { + cpu_dummy = register_pb(); + Push(ref cpu_dummy); + } + + private static void PLA__() + { + Read(ref cpu_reg_sp.v, out cpu_dummy); + Pull(out cpu_reg_a); + cpu_flag_n = (cpu_reg_a & 0x80) == 128; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void PLP__() + { + Read(ref cpu_reg_sp.v, out cpu_dummy); + Pull(out cpu_dummy); + register_p = cpu_dummy; + } + + private static void RLA__() + { + Read(ref cpu_reg_ea.v, out cpu_byte_temp); + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_dummy = (byte)((uint)(cpu_byte_temp << 1) | (cpu_flag_c ? 1u : 0u)); + Write(ref cpu_reg_ea.v, ref cpu_dummy); + cpu_flag_n = (cpu_dummy & 0x80) != 0; + cpu_flag_z = (cpu_dummy & 0xFF) == 0; + cpu_flag_c = (cpu_byte_temp & 0x80) != 0; + cpu_reg_a &= cpu_dummy; + cpu_flag_n = (cpu_reg_a & 0x80) != 0; + cpu_flag_z = (cpu_reg_a & 0xFF) == 0; + } + + private static void ROL_A() + { + cpu_byte_temp = (byte)((uint)(cpu_reg_a << 1) | (cpu_flag_c ? 1u : 0u)); + cpu_flag_n = (cpu_byte_temp & 0x80) != 0; + cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; + cpu_flag_c = (cpu_reg_a & 0x80) != 0; + cpu_reg_a = cpu_byte_temp; + } + + private static void ROL_M() + { + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_byte_temp = (byte)((uint)(cpu_m << 1) | (cpu_flag_c ? 1u : 0u)); + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_flag_n = (cpu_byte_temp & 0x80) != 0; + cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; + cpu_flag_c = (cpu_m & 0x80) != 0; + } + + private static void ROR_A() + { + cpu_byte_temp = (byte)((uint)(cpu_reg_a >> 1) | (cpu_flag_c ? 128u : 0u)); + cpu_flag_n = (cpu_byte_temp & 0x80) != 0; + cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; + cpu_flag_c = (cpu_reg_a & 1) != 0; + cpu_reg_a = cpu_byte_temp; + } + + private static void ROR_M() + { + Write(ref cpu_reg_ea.v, ref cpu_m); + cpu_byte_temp = (byte)((uint)(cpu_m >> 1) | (cpu_flag_c ? 128u : 0u)); + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_flag_n = (cpu_byte_temp & 0x80) != 0; + cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; + cpu_flag_c = (cpu_m & 1) != 0; + } + + private static void RRA__() + { + Read(ref cpu_reg_ea.v, out cpu_byte_temp); + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_dummy = (byte)((uint)(cpu_byte_temp >> 1) | (cpu_flag_c ? 128u : 0u)); + Write(ref cpu_reg_ea.v, ref cpu_dummy); + cpu_flag_n = (cpu_dummy & 0x80) != 0; + cpu_flag_z = (cpu_dummy & 0xFF) == 0; + cpu_flag_c = (cpu_byte_temp & 1) != 0; + cpu_byte_temp = cpu_dummy; + cpu_int_temp = cpu_reg_a + cpu_byte_temp + (cpu_flag_c ? 1 : 0); + cpu_flag_n = (cpu_int_temp & 0x80) != 0; + cpu_flag_v = ((cpu_int_temp ^ cpu_reg_a) & (cpu_int_temp ^ cpu_byte_temp) & 0x80) != 0; + cpu_flag_z = (cpu_int_temp & 0xFF) == 0; + cpu_flag_c = cpu_int_temp >> 8 != 0; + cpu_reg_a = (byte)cpu_int_temp; + } + + private static void RTI__() + { + Read(ref cpu_reg_sp.v, out cpu_dummy); + Pull(out cpu_dummy); + register_p = cpu_dummy; + Pull(out cpu_reg_pc.l); + Pull(out cpu_reg_pc.h); + } + + private static void RTS__() + { + Read(ref cpu_reg_sp.v, out cpu_dummy); + Pull(out cpu_reg_pc.l); + Pull(out cpu_reg_pc.h); + cpu_reg_pc.v++; + Read(ref cpu_reg_pc.v, out cpu_dummy); + } + + private static void SAX__() + { + cpu_dummy = (byte)(cpu_reg_x & cpu_reg_a); + Write(ref cpu_reg_ea.v, ref cpu_dummy); + } + + private static void SBC__() + { + cpu_m ^= byte.MaxValue; + cpu_int_temp = cpu_reg_a + cpu_m + (cpu_flag_c ? 1 : 0); + cpu_flag_n = (cpu_int_temp & 0x80) != 0; + cpu_flag_v = ((cpu_int_temp ^ cpu_reg_a) & (cpu_int_temp ^ cpu_m) & 0x80) != 0; + cpu_flag_z = (cpu_int_temp & 0xFF) == 0; + cpu_flag_c = cpu_int_temp >> 8 != 0; + cpu_reg_a = (byte)cpu_int_temp; + } + + private static void SEC__() + { + cpu_flag_c = true; + } + + private static void SEI__() + { + cpu_flag_i = true; + } + + private static void SHX__() + { + cpu_byte_temp = (byte)(cpu_reg_x & (cpu_reg_ea.h + 1)); + Read(ref cpu_reg_ea.v, out cpu_dummy); + cpu_reg_ea.l += cpu_reg_y; + if (cpu_reg_ea.l < cpu_reg_y) + { + cpu_reg_ea.h = cpu_byte_temp; + } + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + } + + private static void SHY__() + { + cpu_byte_temp = (byte)(cpu_reg_y & (cpu_reg_ea.h + 1)); + Read(ref cpu_reg_ea.v, out cpu_dummy); + cpu_reg_ea.l += cpu_reg_x; + if (cpu_reg_ea.l < cpu_reg_x) + { + cpu_reg_ea.h = cpu_byte_temp; + } + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + } + + private static void SLO__() + { + Read(ref cpu_reg_ea.v, out cpu_byte_temp); + cpu_flag_c = (cpu_byte_temp & 0x80) != 0; + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_byte_temp <<= 1; + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_flag_n = (cpu_byte_temp & 0x80) != 0; + cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; + cpu_reg_a |= cpu_byte_temp; + cpu_flag_n = (cpu_reg_a & 0x80) != 0; + cpu_flag_z = (cpu_reg_a & 0xFF) == 0; + } + + private static void SRE__() + { + Read(ref cpu_reg_ea.v, out cpu_byte_temp); + cpu_flag_c = (cpu_byte_temp & 1) != 0; + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_byte_temp >>= 1; + Write(ref cpu_reg_ea.v, ref cpu_byte_temp); + cpu_flag_n = (cpu_byte_temp & 0x80) != 0; + cpu_flag_z = (cpu_byte_temp & 0xFF) == 0; + cpu_reg_a ^= cpu_byte_temp; + cpu_flag_n = (cpu_reg_a & 0x80) != 0; + cpu_flag_z = (cpu_reg_a & 0xFF) == 0; + } + + private static void STA__() + { + Write(ref cpu_reg_ea.v, ref cpu_reg_a); + } + + private static void STX__() + { + Write(ref cpu_reg_ea.v, ref cpu_reg_x); + } + + private static void STY__() + { + Write(ref cpu_reg_ea.v, ref cpu_reg_y); + } + + private static void TAX__() + { + cpu_reg_x = cpu_reg_a; + cpu_flag_n = (cpu_reg_x & 0x80) == 128; + cpu_flag_z = cpu_reg_x == 0; + } + + private static void TAY__() + { + cpu_reg_y = cpu_reg_a; + cpu_flag_n = (cpu_reg_y & 0x80) == 128; + cpu_flag_z = cpu_reg_y == 0; + } + + private static void TSX__() + { + cpu_reg_x = cpu_reg_sp.l; + cpu_flag_n = (cpu_reg_x & 0x80) != 0; + cpu_flag_z = cpu_reg_x == 0; + } + + private static void TXA__() + { + cpu_reg_a = cpu_reg_x; + cpu_flag_n = (cpu_reg_a & 0x80) == 128; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void TXS__() + { + cpu_reg_sp.l = cpu_reg_x; + } + + private static void TYA__() + { + cpu_reg_a = cpu_reg_y; + cpu_flag_n = (cpu_reg_a & 0x80) == 128; + cpu_flag_z = cpu_reg_a == 0; + } + + private static void XAA__() + { + cpu_reg_a = (byte)(cpu_reg_x & cpu_m); + cpu_flag_n = (cpu_reg_a & 0x80) != 0; + cpu_flag_z = (cpu_reg_a & 0xFF) == 0; + } + + private static void XAS__() + { + cpu_reg_sp.l = (byte)(cpu_reg_a & cpu_reg_x); + Write(ref cpu_reg_ea.v, ref cpu_reg_sp.l); + } + + private static void CPUWriteState(ref BinaryWriter bin) + { + bin.Write(cpu_reg_pc.v); + bin.Write(cpu_reg_sp.v); + bin.Write(cpu_reg_ea.v); + bin.Write(cpu_reg_a); + bin.Write(cpu_reg_x); + bin.Write(cpu_reg_y); + bin.Write(cpu_flag_n); + bin.Write(cpu_flag_v); + bin.Write(cpu_flag_d); + bin.Write(cpu_flag_i); + bin.Write(cpu_flag_z); + bin.Write(cpu_flag_c); + bin.Write(cpu_m); + bin.Write(cpu_opcode); + bin.Write(cpu_byte_temp); + bin.Write(cpu_int_temp); + bin.Write(cpu_int_temp1); + bin.Write(cpu_dummy); + bin.Write(cpu_bool_tmp); + bin.Write(temp_add.v); + bin.Write(CPU_IRQ_PIN); + bin.Write(CPU_NMI_PIN); + bin.Write(cpu_suspend_nmi); + bin.Write(cpu_suspend_irq); + } + + private static void CPUReadState(ref BinaryReader bin) + { + cpu_reg_pc.v = bin.ReadUInt16(); + cpu_reg_sp.v = bin.ReadUInt16(); + cpu_reg_ea.v = bin.ReadUInt16(); + cpu_reg_a = bin.ReadByte(); + cpu_reg_x = bin.ReadByte(); + cpu_reg_y = bin.ReadByte(); + cpu_flag_n = bin.ReadBoolean(); + cpu_flag_v = bin.ReadBoolean(); + cpu_flag_d = bin.ReadBoolean(); + cpu_flag_i = bin.ReadBoolean(); + cpu_flag_z = bin.ReadBoolean(); + cpu_flag_c = bin.ReadBoolean(); + cpu_m = bin.ReadByte(); + cpu_opcode = bin.ReadByte(); + cpu_byte_temp = bin.ReadByte(); + cpu_int_temp = bin.ReadInt32(); + cpu_int_temp1 = bin.ReadInt32(); + cpu_dummy = bin.ReadByte(); + cpu_bool_tmp = bin.ReadBoolean(); + temp_add.v = bin.ReadUInt16(); + CPU_IRQ_PIN = bin.ReadBoolean(); + CPU_NMI_PIN = bin.ReadBoolean(); + cpu_suspend_nmi = bin.ReadBoolean(); + cpu_suspend_irq = bin.ReadBoolean(); + } + + private static void DMAHardReset() + { + dma_DMCDMAWaitCycles = 0; + dma_OAMDMAWaitCycles = 0; + dma_isOamDma = false; + dma_oamdma_i = 0; + dma_DMCOn = false; + dma_OAMOn = false; + dma_DMC_occurring = false; + dma_OAM_occurring = false; + dma_OAMFinishCounter = 0; + dma_Oamaddress = 0; + dma_OAMCYCLE = 0; + dma_latch = 0; + reg_2004 = 8196; + } + + private static void DMASoftReset() + { + dma_DMCDMAWaitCycles = 0; + dma_OAMDMAWaitCycles = 0; + dma_isOamDma = false; + dma_oamdma_i = 0; + dma_DMCOn = false; + dma_OAMOn = false; + dma_DMC_occurring = false; + dma_OAM_occurring = false; + dma_OAMFinishCounter = 0; + dma_Oamaddress = 0; + dma_OAMCYCLE = 0; + dma_latch = 0; + } + + internal static void AssertDMCDMA() + { + if (dma_OAM_occurring) + { + if (dma_OAMCYCLE < 508) + { + dma_DMCDMAWaitCycles = (BUS_RW ? 1 : 0); + } + else + { + dma_DMCDMAWaitCycles = 4 - (512 - dma_OAMCYCLE); + } + } + else + { + if (dma_DMC_occurring) + { + return; + } + dma_DMCDMAWaitCycles = (BUS_RW ? 3 : 2); + if (dma_OAMFinishCounter == 3) + { + dma_DMCDMAWaitCycles++; + } + } + dma_isOamDma = false; + dma_DMCOn = true; + } + + private static void AssertOAMDMA() + { + if (!dma_OAM_occurring) + { + dma_OAMDMAWaitCycles = (apu_odd_cycle ? 1 : 2); + dma_isOamDma = true; + dma_OAMOn = true; + } + } + + private static void DMAClock() + { + if (dma_OAMFinishCounter > 0) + { + dma_OAMFinishCounter--; + } + if (!BUS_RW) + { + if (dma_DMCDMAWaitCycles > 0) + { + dma_DMCDMAWaitCycles--; + } + if (dma_OAMDMAWaitCycles > 0) + { + dma_OAMDMAWaitCycles--; + } + return; + } + if (dma_DMCOn) + { + dma_DMC_occurring = true; + dma_DMCOn = false; + if (dma_DMCDMAWaitCycles > 0) + { + if (BUS_ADDRESS == 16406 || BUS_ADDRESS == 16407) + { + Read(ref BUS_ADDRESS, out dma_dummy); + dma_DMCDMAWaitCycles--; + while (dma_DMCDMAWaitCycles > 0) + { + EmuClockComponents(); + dma_DMCDMAWaitCycles--; + } + } + else + { + if (dma_DMCDMAWaitCycles > 0) + { + EmuClockComponents(); + dma_DMCDMAWaitCycles--; + } + while (dma_DMCDMAWaitCycles > 0) + { + Read(ref BUS_ADDRESS, out dma_dummy); + dma_DMCDMAWaitCycles--; + } + } + } + DMCDoDMA(); + dma_DMC_occurring = false; + } + if (!dma_OAMOn) + { + return; + } + dma_OAM_occurring = true; + dma_OAMOn = false; + if (dma_OAMDMAWaitCycles > 0) + { + if (BUS_ADDRESS == 16406 || BUS_ADDRESS == 16407) + { + Read(ref BUS_ADDRESS, out dma_dummy); + dma_OAMDMAWaitCycles--; + while (dma_OAMDMAWaitCycles > 0) + { + EmuClockComponents(); + dma_OAMDMAWaitCycles--; + } + } + else + { + if (dma_OAMDMAWaitCycles > 0) + { + EmuClockComponents(); + dma_OAMDMAWaitCycles--; + } + while (dma_OAMDMAWaitCycles > 0) + { + Read(ref BUS_ADDRESS, out dma_dummy); + dma_OAMDMAWaitCycles--; + } + } + } + dma_OAMCYCLE = 0; + for (dma_oamdma_i = 0; dma_oamdma_i < 256; dma_oamdma_i++) + { + Read(ref dma_Oamaddress, out dma_latch); + dma_OAMCYCLE++; + Write(ref reg_2004, ref dma_latch); + dma_OAMCYCLE++; + dma_Oamaddress = (ushort)(++dma_Oamaddress & 0xFFFFu); + } + dma_OAMCYCLE = 0; + dma_OAMFinishCounter = 5; + dma_OAM_occurring = false; + } + + private static void DMAWriteState(ref BinaryWriter bin) + { + bin.Write(dma_DMCDMAWaitCycles); + bin.Write(dma_OAMDMAWaitCycles); + bin.Write(dma_isOamDma); + bin.Write(dma_oamdma_i); + bin.Write(dma_DMCOn); + bin.Write(dma_OAMOn); + bin.Write(dma_DMC_occurring); + bin.Write(dma_OAM_occurring); + bin.Write(dma_OAMFinishCounter); + bin.Write(dma_Oamaddress); + bin.Write(dma_OAMCYCLE); + bin.Write(dma_latch); + bin.Write(dma_dummy); + } + + private static void DMAReadState(ref BinaryReader bin) + { + dma_DMCDMAWaitCycles = bin.ReadInt32(); + dma_OAMDMAWaitCycles = bin.ReadInt32(); + dma_isOamDma = bin.ReadBoolean(); + dma_oamdma_i = bin.ReadInt32(); + dma_DMCOn = bin.ReadBoolean(); + dma_OAMOn = bin.ReadBoolean(); + dma_DMC_occurring = bin.ReadBoolean(); + dma_OAM_occurring = bin.ReadBoolean(); + dma_OAMFinishCounter = bin.ReadInt32(); + dma_Oamaddress = bin.ReadUInt16(); + dma_OAMCYCLE = bin.ReadInt32(); + dma_latch = bin.ReadByte(); + dma_dummy = bin.ReadByte(); + } + + private static void PollInterruptStatus() + { + if (!cpu_suspend_nmi) + { + if (PPU_NMI_Current & !PPU_NMI_Old) + { + CPU_NMI_PIN = true; + } + PPU_NMI_Old = (PPU_NMI_Current = false); + } + if (!cpu_suspend_irq) + { + CPU_IRQ_PIN = !cpu_flag_i && IRQFlags != 0; + } + if (CPU_NMI_PIN) + { + InterruptVector = 65530; + } + else + { + InterruptVector = 65534; + } + } + + private static void InterruptsWriteState(ref BinaryWriter bin) + { + bin.Write(IRQFlags); + bin.Write(PPU_NMI_Current); + bin.Write(PPU_NMI_Old); + bin.Write(InterruptVector); + } + + private static void InterruptsReadState(ref BinaryReader bin) + { + IRQFlags = bin.ReadInt32(); + PPU_NMI_Current = bin.ReadBoolean(); + PPU_NMI_Old = bin.ReadBoolean(); + InterruptVector = bin.ReadUInt16(); + } + + public static void SetupGameGenie(bool IsGameGenieActive, GameGenieCode[] GameGenieCodes) + { + if (mem_board != null) + { + mem_board.SetupGameGenie(IsGameGenieActive, GameGenieCodes); + } + } + + private static void MEMInitialize(IRom rom) + { + Tracer.WriteLine("Looking for mapper # " + rom.MapperNumber + "...."); + if (MyNesMain.IsBoardExist(rom.MapperNumber)) + { + Tracer.WriteLine("Mapper # " + rom.MapperNumber + " located, assigning..."); + mem_board = MyNesMain.GetBoard(rom.MapperNumber); + Tracer.WriteInformation("Mapper # " + rom.MapperNumber + " assigned successfully."); + if (mem_board.HasIssues) + { + Tracer.WriteWarning(MNInterfaceLanguage.Mapper + " # " + mem_board.MapperNumber + " [" + mem_board.Name + "] " + MNInterfaceLanguage.Message_Error17); + MyNesMain.VideoProvider.WriteWarningNotification(MNInterfaceLanguage.Mapper + " # " + mem_board.MapperNumber + " [" + mem_board.Name + "] " + MNInterfaceLanguage.Message_Error17, instant: false); + } + } + else + { + Tracer.WriteError("Mapper # " + rom.MapperNumber + " IS NOT LOCATED, mapper is not supported or unable to find it."); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Mapper + " # " + rom.MapperNumber + " " + MNInterfaceLanguage.Message_Error14, instant: false); + mem_board = MyNesMain.GetBoard(0); + Tracer.WriteWarning("Mapper # 0 [NROM] will be used instead, assigned successfully."); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Mapper + " # 0 [NROM] " + MNInterfaceLanguage.Message_Error15, instant: false); + } + mem_read_accesses = new MemReadAccess[65536]; + mem_write_accesses = new MemWriteAccess[65536]; + MEMMap(MEMReadWRAM, new ushort[2] { 0, 4096 }); + MEMMap(MEMWriteWRAM, new ushort[2] { 0, 4096 }); + MEMMap(PPUIORead, new ushort[2] { 8192, 12288 }); + MEMMap(PPUIOWrite, new ushort[2] { 8192, 12288 }); + MEMMap(APUIORead, new ushort[1] { 16384 }); + MEMMap(APUIOWrite, new ushort[1] { 16384 }); + MEMMap(mem_board.ReadEX, new ushort[1] { 20480 }); + MEMMap(mem_board.WriteEX, new ushort[1] { 20480 }); + MEMMap(mem_board.ReadSRM, new ushort[2] { 24576, 28672 }); + MEMMap(mem_board.WriteSRM, new ushort[2] { 24576, 28672 }); + MEMMap(mem_board.ReadPRG, new ushort[8] { 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440 }); + MEMMap(mem_board.WritePRG, new ushort[8] { 32768, 36864, 40960, 45056, 49152, 53248, 57344, 61440 }); + mem_board.Initialize(rom); + mem_wram = new byte[2048]; + } + + private static void MEMHardReset() + { + mem_wram = new byte[2048]; + mem_wram[8] = 247; + mem_wram[9] = 239; + mem_wram[10] = 223; + mem_wram[15] = 191; + Tracer.WriteLine("Reading SRAM ..."); + SRAMFileName = Path.Combine(MyNesMain.EmuSettings.SRAMFolder, Path.GetFileNameWithoutExtension(CurrentFilePath) + ".srm"); + if (File.Exists(SRAMFileName)) + { + FileStream fileStream = new FileStream(SRAMFileName, FileMode.Open, FileAccess.Read); + byte[] array = new byte[fileStream.Length]; + fileStream.Read(array, 0, array.Length); + fileStream.Flush(); + fileStream.Close(); + byte[] outData = new byte[0]; + ZlipWrapper.DecompressData(array, out outData); + mem_board.LoadSRAM(outData); + Tracer.WriteLine("SRAM read successfully."); + } + else + { + Tracer.WriteLine("SRAM file not found; rom has no SRAM or file not exist."); + } + ReloadGameGenieCodes(); + mem_board.HardReset(); + } + + public static void ReloadGameGenieCodes() + { + Tracer.WriteLine("Reading game genie codes (if available)...."); + GMFileName = Path.Combine(MyNesMain.EmuSettings.GameGenieFolder, Path.GetFileNameWithoutExtension(CurrentFilePath) + ".txt"); + mem_board.GameGenieCodes = new GameGenieCode[0]; + if (File.Exists(GMFileName)) + { + XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); + xmlReaderSettings.DtdProcessing = DtdProcessing.Ignore; + xmlReaderSettings.IgnoreWhitespace = true; + XmlReader xmlReader = XmlReader.Create(GMFileName, xmlReaderSettings); + xmlReader.Read(); + xmlReader.Read(); + if (xmlReader.Name != "MyNesGameGenieCodesList") + { + xmlReader.Close(); + return; + } + GameGenie gameGenie = new GameGenie(); + List list = new List(); + while (xmlReader.Read()) + { + if (xmlReader.Name == "Code") + { + GameGenieCode item = default(GameGenieCode); + item.Enabled = true; + xmlReader.MoveToAttribute("code"); + item.Name = xmlReader.Value.ToString(); + if (item.Name.Length == 6) + { + item.Address = gameGenie.GetGGAddress(gameGenie.GetCodeAsHEX(item.Name), 6) | 0x8000; + item.Value = gameGenie.GetGGValue(gameGenie.GetCodeAsHEX(item.Name), 6); + item.IsCompare = false; + } + else + { + item.Address = gameGenie.GetGGAddress(gameGenie.GetCodeAsHEX(item.Name), 8) | 0x8000; + item.Value = gameGenie.GetGGValue(gameGenie.GetCodeAsHEX(item.Name), 8); + item.Compare = gameGenie.GetGGCompareValue(gameGenie.GetCodeAsHEX(item.Name)); + item.IsCompare = true; + } + list.Add(item); + } + } + xmlReader.Close(); + if (list.Count > 0) + { + mem_board.GameGenieCodes = list.ToArray(); + Tracer.WriteInformation("Game Genie codes loaded successfully, total of " + list.Count); + } + else + { + Tracer.WriteError("There is no Game Genie code in the file to load."); + } + } + else + { + Tracer.WriteWarning("No Game Genie file found for this game."); + } + } + + private static void MEMMap(MemReadAccess readAccess, ushort[] addresses) + { + for (int i = 0; i < addresses.Length; i++) + { + mem_read_accesses[(addresses[i] & 0xF000) >> 12] = readAccess; + } + } + + private static void MEMMap(MemWriteAccess writeAccess, ushort[] addresses) + { + for (int i = 0; i < addresses.Length; i++) + { + mem_write_accesses[(addresses[i] & 0xF000) >> 12] = writeAccess; + } + } + + private static void MEMReadWRAM(ref ushort addr, out byte value) + { + value = mem_wram[addr & 0x7FF]; + } + + private static void MEMWriteWRAM(ref ushort addr, ref byte value) + { + mem_wram[addr & 0x7FF] = value; + } + + internal static void Read(ref ushort addr, out byte value) + { + BUS_RW = true; + BUS_ADDRESS = addr; + EmuClockComponents(); + mem_read_accesses[(addr & 0xF000) >> 12](ref addr, out value); + } + + private static void Write(ref ushort addr, ref byte value) + { + BUS_RW = false; + BUS_ADDRESS = addr; + EmuClockComponents(); + mem_write_accesses[(addr & 0xF000) >> 12](ref addr, ref value); + } + + internal static void SaveSRAM() + { + if (mem_board != null && MyNesMain.EmuSettings.SaveSRAMAtEmuShutdown && mem_board.SRAMSaveRequired) + { + Tracer.WriteLine("Saving SRAM ..."); + byte[] outData = new byte[0]; + ZlipWrapper.CompressData(mem_board.GetSRAMBuffer(), out outData); + FileStream fileStream = new FileStream(SRAMFileName, FileMode.Create, FileAccess.Write); + fileStream.Write(outData, 0, outData.Length); + fileStream.Flush(); + fileStream.Close(); + Tracer.WriteLine("SRAM saved successfully."); + } + } + + private static void MEMWriteState(ref BinaryWriter bin) + { + mem_board.WriteStateData(ref bin); + bin.Write(mem_wram); + bin.Write(BUS_RW); + bin.Write(BUS_ADDRESS); + } + + private static void MEMReadState(ref BinaryReader bin) + { + mem_board.ReadStateData(ref bin); + bin.Read(mem_wram, 0, mem_wram.Length); + BUS_RW = bin.ReadBoolean(); + BUS_ADDRESS = bin.ReadUInt16(); + } + + private static void PORTSInitialize() + { + if (joypad1 == null) + { + joypad1 = new BlankJoypad(); + } + if (joypad2 == null) + { + joypad2 = new BlankJoypad(); + } + if (joypad3 == null) + { + joypad3 = new BlankJoypad(); + } + if (joypad4 == null) + { + joypad4 = new BlankJoypad(); + } + if (shortucts == null) + { + shortucts = new BlankShortuctsHandler(); + } + } + + public static void SetupShortcutsHandler(IShortcutsHandler hh) + { + shortucts = hh; + } + + public static void SetupControllers(IJoypadConnecter joy1, IJoypadConnecter joy2, IJoypadConnecter joy3, IJoypadConnecter joy4) + { + joypad1 = joy1; + joypad2 = joy2; + joypad3 = joy3; + joypad4 = joy4; + } + + public static void SetupVSUnisystemDIP(IVSUnisystemDIPConnecter uni) + { + } + + public static void SetupControllersP1(IJoypadConnecter joy) + { + joypad1 = joy; + } + + public static void SetupControllersP2(IJoypadConnecter joy) + { + joypad2 = joy; + } + + public static void SetupControllersP3(IJoypadConnecter joy) + { + joypad3 = joy; + } + + public static void SetupControllersP4(IJoypadConnecter joy) + { + joypad4 = joy; + } + + public static void DestroyJoypads() + { + if (joypad1 == null) + { + joypad1 = new BlankJoypad(); + } + else + { + joypad1.Destroy(); + } + if (joypad2 == null) + { + joypad2 = new BlankJoypad(); + } + else + { + joypad1.Destroy(); + } + if (joypad3 == null) + { + joypad3 = new BlankJoypad(); + } + else + { + joypad1.Destroy(); + } + if (joypad4 == null) + { + joypad4 = new BlankJoypad(); + } + else + { + joypad1.Destroy(); + } + } + + private static void PORTWriteState(ref BinaryWriter bin) + { + bin.Write(PORT0); + bin.Write(PORT1); + bin.Write(inputStrobe); + } + + private static void PORTReadState(ref BinaryReader bin) + { + PORT0 = bin.ReadInt32(); + PORT1 = bin.ReadInt32(); + inputStrobe = bin.ReadInt32(); + } + + public static void SetupPalette(int[] pal) + { + ppu_palette = pal; + } + + private static void PPUInitialize() + { + ppu_reg_update_func = new Action[8] { PPUOnRegister2000, PPUOnRegister2001, PPUOnRegister2002, PPUOnRegister2003, PPUOnRegister2004, PPUOnRegister2005, PPUOnRegister2006, PPUOnRegister2007 }; + ppu_reg_read_func = new Action[8] { PPURead2000, PPURead2001, PPURead2002, PPURead2003, PPURead2004, PPURead2005, PPURead2006, PPURead2007 }; + ppu_bkg_fetches = new Action[8] { PPUBKFetch0, PPUBKFetch1, PPUBKFetch2, PPUBKFetch3, PPUBKFetch4, PPUBKFetch5, PPUBKFetch6, PPUBKFetch7 }; + ppu_spr_fetches = new Action[8] { PPUBKFetch0, PPUBKFetch1, PPUBKFetch2, PPUBKFetch3, PPUSPRFetch0, PPUSPRFetch1, PPUSPRFetch2, PPUSPRFetch3 }; + ppu_oam_phases = new Action[9] { PPUOamPhase0, PPUOamPhase1, PPUOamPhase2, PPUOamPhase3, PPUOamPhase4, PPUOamPhase5, PPUOamPhase6, PPUOamPhase7, PPUOamPhase8 }; + ppu_h_clocks = new Action[341]; + ppu_h_clocks[0] = PPUHClock_000_Idle; + for (int i = 1; i < 257; i++) + { + ppu_h_clocks[i] = PPUHClock_1_256_BKGClocks; + } + for (int j = 257; j < 321; j++) + { + ppu_h_clocks[j] = PPUHClock_257_320_SPRClocks; + } + for (int k = 321; k < 337; k++) + { + ppu_h_clocks[k] = PPUHClock_321_336_DUMClocks; + } + for (int l = 337; l < 341; l++) + { + ppu_h_clocks[l] = PPUHClock_337_340_DUMClocks; + } + ppu_v_clocks = new Action[320]; + for (int m = 0; m < 240; m++) + { + ppu_v_clocks[m] = PPUScanlineRender; + } + ppu_v_clocks[240] = PPUScanlineVBLANK; + ppu_oam_bank = new byte[256]; + ppu_oam_bank_secondary = new byte[32]; + ppu_palette_bank = new byte[32]; + ppu_bkg_pixels = new int[512]; + ppu_spr_pixels = new int[512]; + ppu_screen_pixels = new int[61440]; + ppu_palette = NTSCPaletteGenerator.GeneratePalette(); + } + + private static void PPUHardReset() + { + ppu_reg_2001_grayscale = 243; + switch (Region) + { + case EmuRegion.NTSC: + ppu_clock_vblank_start = 241; + ppu_clock_vblank_end = 261; + ppu_use_odd_cycle = true; + break; + case EmuRegion.PALB: + ppu_clock_vblank_start = 241; + ppu_clock_vblank_end = 311; + ppu_use_odd_cycle = false; + break; + case EmuRegion.DENDY: + { + ppu_clock_vblank_start = 291; + ppu_clock_vblank_end = 311; + for (int i = 241; i <= 290; i++) + { + ppu_v_clocks[i] = PPUScanlineVBLANK; + } + ppu_use_odd_cycle = false; + break; + } + } + ppu_v_clocks[ppu_clock_vblank_start] = PPUScanlineVBLANKStart; + for (int j = ppu_clock_vblank_start + 1; j <= ppu_clock_vblank_end - 1; j++) + { + ppu_v_clocks[j] = PPUScanlineVBLANK; + } + ppu_v_clocks[ppu_clock_vblank_end] = PPUScanlineVBLANKEnd; + ppu_oam_bank = new byte[256]; + ppu_oam_bank_secondary = new byte[32]; + PPUOamReset(); + ppu_palette_bank = new byte[32] + { + 9, 1, 0, 1, 0, 2, 2, 13, 8, 16, + 8, 36, 0, 0, 4, 44, 9, 1, 52, 3, + 0, 4, 0, 20, 8, 58, 0, 2, 0, 32, + 44, 8 + }; + ppu_reg_io_db = 0; + ppu_reg_io_addr = 0; + ppu_reg_access_happened = false; + ppu_reg_access_w = false; + ppu_reg_2000_vram_address_increament = 1; + ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites = 0; + ppu_reg_2000_background_pattern_table_address = 0; + ppu_reg_2000_Sprite_size = 0; + ppu_reg_2000_VBI = false; + ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen = false; + ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen = false; + ppu_reg_2001_show_background = false; + ppu_reg_2001_show_sprites = false; + ppu_reg_2001_grayscale = 63; + ppu_reg_2001_emphasis = 0; + ppu_reg_2002_SpriteOverflow = false; + ppu_reg_2002_Sprite0Hit = false; + ppu_reg_2002_VblankStartedFlag = false; + ppu_reg_2003_oam_addr = 0; + ppu_is_sprfetch = false; + ppu_use_odd_swap = false; + ppu_clock_h = 0; + ppu_clock_v = 0; + } + + private static void PPUClock() + { + mem_board.OnPPUClock(); + ppu_v_clocks[ppu_clock_v](); + ppu_clock_h++; + if (ppu_clock_h >= 341) + { + mem_board.OnPPUScanlineTick(); + if (ppu_clock_v == ppu_clock_vblank_end) + { + ppu_clock_v = 0; + ppu_frame_finished = true; + } + else + { + ppu_clock_v++; + } + ppu_clock_h -= 341; + } + if (ppu_reg_access_happened) + { + ppu_reg_access_happened = false; + ppu_reg_update_func[ppu_reg_io_addr](); + } + } + + public static int GetPixel(int x, int y) + { + return ppu_screen_pixels[y * 256 + x]; + } + + private static void PPUScanlineRender() + { + ppu_h_clocks[ppu_clock_h](); + } + + private static void PPUScanlineVBLANKStart() + { + ppu_is_nmi_time = (ppu_clock_h >= 1) & (ppu_clock_h <= 3); + if (ppu_is_nmi_time) + { + if (ppu_clock_h == 1) + { + ppu_reg_2002_VblankStartedFlag = true; + } + PPU_NMI_Current = ppu_reg_2002_VblankStartedFlag & ppu_reg_2000_VBI; + } + } + + private static void PPUScanlineVBLANKEnd() + { + ppu_is_nmi_time = (ppu_clock_h >= 1) & (ppu_clock_h <= 3); + if (ppu_clock_h == 1) + { + ppu_reg_2002_Sprite0Hit = false; + ppu_reg_2002_VblankStartedFlag = false; + ppu_reg_2002_SpriteOverflow = false; + } + PPUScanlineRender(); + if (ppu_use_odd_cycle && ppu_clock_h == 339) + { + ppu_use_odd_swap = !ppu_use_odd_swap; + if (!ppu_use_odd_swap & (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites)) + { + ppu_odd_swap_done = true; + ppu_clock_h++; + } + } + } + + private static void PPUScanlineVBLANK() + { + } + + private static void PPUHClock_000_Idle() + { + if (ppu_odd_swap_done) + { + ppu_bkg_fetches[1](); + ppu_odd_swap_done = false; + } + } + + private static void PPUHClock_1_256_BKGClocks() + { + if (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites) + { + if (ppu_clock_v != ppu_clock_vblank_end) + { + if (ppu_clock_h > 0 && ppu_clock_h < 65) + { + ppu_oam_bank_secondary[(ppu_clock_h - 1) & 0x1F] = byte.MaxValue; + } + else + { + if (ppu_clock_h == 65) + { + PPUOamReset(); + } + if (((ppu_clock_h - 1) & 1) == 0) + { + PPUOamEvFetch(); + } + else + { + ppu_oam_phases[ppu_phase_index](); + } + if (ppu_clock_h == 256) + { + PPUOamClear(); + } + } + } + ppu_bkg_fetches[(ppu_clock_h - 1) & 7](); + if (ppu_clock_v < 240) + { + RenderPixel(); + } + } + else + { + if (ppu_clock_v >= 240) + { + return; + } + if ((ppu_vram_addr & 0x3F00) == 16128) + { + if ((ppu_vram_addr & 3) == 0) + { + ppu_screen_pixels[ppu_clock_h - 1 + ppu_clock_v * 256] = ppu_palette[(ppu_palette_bank[ppu_vram_addr & 0xC] & ppu_reg_2001_grayscale) | ppu_reg_2001_emphasis]; + } + else + { + ppu_screen_pixels[ppu_clock_h - 1 + ppu_clock_v * 256] = ppu_palette[(ppu_palette_bank[ppu_vram_addr & 0x1F] & ppu_reg_2001_grayscale) | ppu_reg_2001_emphasis]; + } + } + else + { + ppu_screen_pixels[ppu_clock_h - 1 + ppu_clock_v * 256] = ppu_palette[(ppu_palette_bank[0] & ppu_reg_2001_grayscale) | ppu_reg_2001_emphasis]; + } + } + } + + private static void PPUHClock_257_320_SPRClocks() + { + if (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites) + { + ppu_spr_fetches[(ppu_clock_h - 1) & 7](); + if (ppu_clock_h == 257) + { + ppu_vram_addr = (ushort)((ppu_vram_addr & 0x7BE0u) | (ppu_vram_addr_temp & 0x41Fu)); + } + if (ppu_clock_v == ppu_clock_vblank_end && ppu_clock_h >= 280 && ppu_clock_h <= 304) + { + ppu_vram_addr = (ushort)((ppu_vram_addr & 0x41Fu) | (ppu_vram_addr_temp & 0x7BE0u)); + } + } + } + + private static void PPUHClock_321_336_DUMClocks() + { + if (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites) + { + ppu_bkg_fetches[(ppu_clock_h - 1) & 7](); + } + } + + private static void PPUHClock_337_340_DUMClocks() + { + if (ppu_reg_2001_show_background || ppu_reg_2001_show_sprites) + { + ppu_bkg_fetches[(ppu_clock_h - 1) & 1](); + } + } + + private static void PPUBKFetch0() + { + ppu_bkgfetch_nt_addr = (ushort)(0x2000u | (ppu_vram_addr & 0xFFFu)); + mem_board.OnPPUAddressUpdate(ref ppu_bkgfetch_nt_addr); + } + + private static void PPUBKFetch1() + { + mem_board.ReadNMT(ref ppu_bkgfetch_nt_addr, out ppu_bkgfetch_nt_data); + } + + private static void PPUBKFetch2() + { + ppu_bkgfetch_at_addr = (ushort)(0x23C0u | (ppu_vram_addr & 0xC00u) | ((uint)(ppu_vram_addr >> 4) & 0x38u) | ((uint)(ppu_vram_addr >> 2) & 7u)); + mem_board.OnPPUAddressUpdate(ref ppu_bkgfetch_at_addr); + } + + private static void PPUBKFetch3() + { + mem_board.ReadNMT(ref ppu_bkgfetch_at_addr, out ppu_bkgfetch_at_data); + ppu_bkgfetch_at_data = (byte)(ppu_bkgfetch_at_data >> (((ppu_vram_addr >> 4) & 4) | (ppu_vram_addr & 2))); + } + + private static void PPUBKFetch4() + { + ppu_bkgfetch_lb_addr = (ushort)((uint)(ppu_reg_2000_background_pattern_table_address | (ppu_bkgfetch_nt_data << 4)) | ((uint)(ppu_vram_addr >> 12) & 7u)); + mem_board.OnPPUAddressUpdate(ref ppu_bkgfetch_lb_addr); + } + + private static void PPUBKFetch5() + { + mem_board.ReadCHR(ref ppu_bkgfetch_lb_addr, out ppu_bkgfetch_lb_data); + } + + private static void PPUBKFetch6() + { + ppu_bkgfetch_hb_addr = (ushort)((uint)(ppu_reg_2000_background_pattern_table_address | (ppu_bkgfetch_nt_data << 4)) | 8u | ((uint)(ppu_vram_addr >> 12) & 7u)); + mem_board.OnPPUAddressUpdate(ref ppu_bkgfetch_hb_addr); + } + + private static void PPUBKFetch7() + { + mem_board.ReadCHR(ref ppu_bkgfetch_hb_addr, out ppu_bkgfetch_hb_data); + ppu_bkg_render_pos = ppu_clock_h + 8; + ppu_bkg_render_pos %= 336; + if (ppu_clock_h == 256) + { + if ((ppu_vram_addr & 0x7000) != 28672) + { + ppu_vram_addr += 4096; + } + else + { + ppu_vram_addr ^= 28672; + switch (ppu_vram_addr & 0x3E0) + { + case 928: + ppu_vram_addr ^= 2976; + break; + case 992: + ppu_vram_addr ^= 992; + break; + default: + ppu_vram_addr += 32; + break; + } + } + } + else if ((ppu_vram_addr & 0x1F) == 31) + { + ppu_vram_addr ^= 1055; + } + else + { + ppu_vram_addr++; + } + for (ppu_bkg_render_i = 0; ppu_bkg_render_i < 8; ppu_bkg_render_i++) + { + ppu_bkg_render_tmp_val = ((ppu_bkgfetch_at_data << 2) & 0xC) | ((ppu_bkgfetch_lb_data >> 7) & 1) | ((ppu_bkgfetch_hb_data >> 6) & 2); + ppu_bkg_pixels[ppu_bkg_render_i + ppu_bkg_render_pos] = ppu_bkg_render_tmp_val; + ppu_bkgfetch_lb_data <<= 1; + ppu_bkgfetch_hb_data <<= 1; + } + } + + private static void PPUSPRFetch0() + { + ppu_sprfetch_slot = (ppu_clock_h - 1 >> 3) & 7; + ppu_sprfetch_slot = 7 - ppu_sprfetch_slot; + ppu_sprfetch_y_data = ppu_oam_bank_secondary[ppu_sprfetch_slot * 4]; + ppu_sprfetch_t_data = ppu_oam_bank_secondary[ppu_sprfetch_slot * 4 + 1]; + ppu_sprfetch_at_data = ppu_oam_bank_secondary[ppu_sprfetch_slot * 4 + 2]; + ppu_sprfetch_x_data = ppu_oam_bank_secondary[ppu_sprfetch_slot * 4 + 3]; + ppu_temp_comparator = (ppu_clock_v - ppu_sprfetch_y_data) ^ (((ppu_sprfetch_at_data & 0x80u) != 0) ? 15 : 0); + if (ppu_reg_2000_Sprite_size == 16) + { + ppu_sprfetch_lb_addr = (ushort)(((uint)(ppu_sprfetch_t_data << 12) & 0x1000u) | ((uint)(ppu_sprfetch_t_data << 4) & 0xFE0u) | ((uint)(ppu_temp_comparator << 1) & 0x10u) | ((uint)ppu_temp_comparator & 7u)); + } + else + { + ppu_sprfetch_lb_addr = (ushort)((uint)(ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites | (ppu_sprfetch_t_data << 4)) | ((uint)ppu_temp_comparator & 7u)); + } + mem_board.OnPPUAddressUpdate(ref ppu_sprfetch_lb_addr); + } + + private static void PPUSPRFetch1() + { + ppu_is_sprfetch = true; + mem_board.ReadCHR(ref ppu_sprfetch_lb_addr, out ppu_sprfetch_lb_data); + ppu_is_sprfetch = false; + if ((ppu_sprfetch_at_data & 0x40u) != 0) + { + ppu_sprfetch_lb_data = reverseLookup[ppu_sprfetch_lb_data]; + } + } + + private static void PPUSPRFetch2() + { + ppu_sprfetch_hb_addr = (ushort)(ppu_sprfetch_lb_addr | 8u); + mem_board.OnPPUAddressUpdate(ref ppu_sprfetch_hb_addr); + } + + private static void PPUSPRFetch3() + { + ppu_is_sprfetch = true; + mem_board.ReadCHR(ref ppu_sprfetch_hb_addr, out ppu_sprfetch_hb_data); + ppu_is_sprfetch = false; + if ((ppu_sprfetch_at_data & 0x40u) != 0) + { + ppu_sprfetch_hb_data = reverseLookup[ppu_sprfetch_hb_data]; + } + if (ppu_sprfetch_x_data == byte.MaxValue) + { + return; + } + for (ppu_bkg_render_i = 0; ppu_bkg_render_i < 8; ppu_bkg_render_i++) + { + if (ppu_sprfetch_x_data < byte.MaxValue) + { + ppu_bkg_render_tmp_val = ((ppu_sprfetch_at_data << 2) & 0xC) | ((ppu_sprfetch_lb_data >> 7) & 1) | ((ppu_sprfetch_hb_data >> 6) & 2); + if (((uint)ppu_bkg_render_tmp_val & 3u) != 0) + { + ppu_spr_pixels[ppu_sprfetch_x_data] = ppu_bkg_render_tmp_val; + if (ppu_sprfetch_slot == 0 && ppu_sprite0_should_hit) + { + ppu_spr_pixels[ppu_sprfetch_x_data] |= 16384; + } + if ((ppu_sprfetch_at_data & 0x20) == 0) + { + ppu_spr_pixels[ppu_sprfetch_x_data] |= 32768; + } + } + ppu_sprfetch_lb_data <<= 1; + ppu_sprfetch_hb_data <<= 1; + ppu_sprfetch_x_data++; + } + } + } + + private static void PPUOamReset() + { + ppu_oamev_n = 0; + ppu_oamev_m = 0; + ppu_oamev_slot = 0; + ppu_phase_index = 0; + ppu_sprite0_should_hit = false; + } + + private static void PPUOamClear() + { + for (int i = 0; i < ppu_spr_pixels.Length; i++) + { + ppu_spr_pixels[i] = 0; + } + } + + private static void PPUOamEvFetch() + { + ppu_fetch_data = ppu_oam_bank[ppu_oamev_n * 4 + ppu_oamev_m]; + } + + private static void PPUOamPhase0() + { + ppu_oamev_compare = ppu_clock_v >= ppu_fetch_data && ppu_clock_v < ppu_fetch_data + ppu_reg_2000_Sprite_size; + if (ppu_oamev_compare) + { + ppu_oam_bank_secondary[ppu_oamev_slot * 4] = ppu_fetch_data; + ppu_oamev_m = 1; + ppu_phase_index++; + if (ppu_oamev_n == 0) + { + ppu_sprite0_should_hit = true; + } + } + else + { + ppu_oamev_m = 0; + ppu_oamev_n++; + if (ppu_oamev_n == 64) + { + ppu_oamev_n = 0; + ppu_phase_index = 8; + } + } + } + + private static void PPUOamPhase1() + { + ppu_oam_bank_secondary[ppu_oamev_slot * 4 + ppu_oamev_m] = ppu_fetch_data; + ppu_oamev_m = 2; + ppu_phase_index++; + } + + private static void PPUOamPhase2() + { + ppu_oam_bank_secondary[ppu_oamev_slot * 4 + ppu_oamev_m] = ppu_fetch_data; + ppu_oamev_m = 3; + ppu_phase_index++; + } + + private static void PPUOamPhase3() + { + ppu_oam_bank_secondary[ppu_oamev_slot * 4 + ppu_oamev_m] = ppu_fetch_data; + ppu_oamev_m = 0; + ppu_oamev_n++; + ppu_oamev_slot++; + if (ppu_oamev_n == 64) + { + ppu_oamev_n = 0; + ppu_phase_index = 8; + } + else if (ppu_oamev_slot < 8) + { + ppu_phase_index = 0; + } + else if (ppu_oamev_slot == 8) + { + ppu_phase_index = 4; + } + } + + private static void PPUOamPhase4() + { + ppu_oamev_compare = ppu_clock_v >= ppu_fetch_data && ppu_clock_v < ppu_fetch_data + ppu_reg_2000_Sprite_size; + if (ppu_oamev_compare) + { + ppu_oamev_m = 1; + ppu_phase_index++; + ppu_reg_2002_SpriteOverflow = true; + return; + } + ppu_oamev_m++; + if (ppu_oamev_m == 4) + { + ppu_oamev_m = 0; + } + ppu_oamev_n++; + if (ppu_oamev_n == 64) + { + ppu_oamev_n = 0; + ppu_phase_index = 8; + } + else + { + ppu_phase_index = 4; + } + } + + private static void PPUOamPhase5() + { + ppu_oamev_m = 2; + ppu_phase_index++; + } + + private static void PPUOamPhase6() + { + ppu_oamev_m = 3; + ppu_phase_index++; + } + + private static void PPUOamPhase7() + { + ppu_oamev_m = 0; + ppu_oamev_n++; + if (ppu_oamev_n == 64) + { + ppu_oamev_n = 0; + } + ppu_phase_index = 8; + } + + private static void PPUOamPhase8() + { + ppu_oamev_n++; + if (ppu_oamev_n >= 64) + { + ppu_oamev_n = 0; + } + } + + private static void RenderPixel() + { + if (ppu_clock_v == ppu_clock_vblank_end) + { + return; + } + ppu_render_x = ppu_clock_h - 1; + ppu_render_y = ppu_clock_v * 256; + if (ppu_render_x < 8) + { + if (ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen) + { + ppu_bkg_current_pixel = 0x3F00 | ppu_bkg_pixels[ppu_render_x + ppu_vram_finex]; + } + else + { + ppu_bkg_current_pixel = 16128; + } + if (ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen) + { + ppu_spr_current_pixel = 0x3F10 | ppu_spr_pixels[ppu_render_x]; + } + else + { + ppu_spr_current_pixel = 16144; + } + } + else + { + if (!ppu_reg_2001_show_background) + { + ppu_bkg_current_pixel = 16128; + } + else + { + ppu_bkg_current_pixel = 0x3F00 | ppu_bkg_pixels[ppu_render_x + ppu_vram_finex]; + } + if (!ppu_reg_2001_show_sprites || ppu_clock_v == 0) + { + ppu_spr_current_pixel = 16144; + } + else + { + ppu_spr_current_pixel = 0x3F10 | ppu_spr_pixels[ppu_render_x]; + } + } + ppu_current_pixel = 0; + if (((uint)ppu_spr_current_pixel & 0x8000u) != 0) + { + ppu_current_pixel = ppu_spr_current_pixel; + } + else + { + ppu_current_pixel = ppu_bkg_current_pixel; + } + if ((ppu_bkg_current_pixel & 3) == 0) + { + ppu_current_pixel = ppu_spr_current_pixel; + } + else if ((ppu_spr_current_pixel & 3) == 0) + { + ppu_current_pixel = ppu_bkg_current_pixel; + } + else if (((uint)ppu_spr_pixels[ppu_render_x] & 0x4000u) != 0) + { + ppu_reg_2002_Sprite0Hit = true; + } + if ((ppu_current_pixel & 3) == 0) + { + ppu_screen_pixels[ppu_render_x + ppu_render_y] = ppu_palette[(ppu_palette_bank[ppu_current_pixel & 0xC] & ppu_reg_2001_grayscale) | ppu_reg_2001_emphasis]; + } + else + { + ppu_screen_pixels[ppu_render_x + ppu_render_y] = ppu_palette[(ppu_palette_bank[ppu_current_pixel & 0x1F] & ppu_reg_2001_grayscale) | ppu_reg_2001_emphasis]; + } + } + + private static void PPUIORead(ref ushort addr, out byte value) + { + ppu_reg_io_addr = (byte)(addr & 7u); + ppu_reg_access_happened = true; + ppu_reg_access_w = false; + ppu_reg_read_func[ppu_reg_io_addr](); + value = ppu_reg_io_db; + } + + private static void PPUIOWrite(ref ushort addr, ref byte value) + { + ppu_reg_io_addr = (byte)(addr & 7u); + ppu_reg_io_db = value; + ppu_reg_access_w = true; + ppu_reg_access_happened = true; + } + + private static void PPUOnRegister2000() + { + if (ppu_reg_access_w) + { + ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0x73FFu) | (uint)((ppu_reg_io_db & 3) << 10)); + if ((ppu_reg_io_db & 4u) != 0) + { + ppu_reg_2000_vram_address_increament = 32; + } + else + { + ppu_reg_2000_vram_address_increament = 1; + } + if ((ppu_reg_io_db & 8u) != 0) + { + ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites = 4096; + } + else + { + ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites = 0; + } + if ((ppu_reg_io_db & 0x10u) != 0) + { + ppu_reg_2000_background_pattern_table_address = 4096; + } + else + { + ppu_reg_2000_background_pattern_table_address = 0; + } + if ((ppu_reg_io_db & 0x20u) != 0) + { + ppu_reg_2000_Sprite_size = 16; + } + else + { + ppu_reg_2000_Sprite_size = 8; + } + if (!ppu_reg_2000_VBI && (ppu_reg_io_db & 0x80u) != 0 && ppu_reg_2002_VblankStartedFlag) + { + PPU_NMI_Current = true; + } + ppu_reg_2000_VBI = (ppu_reg_io_db & 0x80) != 0; + if (!ppu_reg_2000_VBI && ppu_is_nmi_time) + { + PPU_NMI_Current = false; + } + } + } + + private static void PPUOnRegister2001() + { + if (ppu_reg_access_w) + { + ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen = (ppu_reg_io_db & 2) != 0; + ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen = (ppu_reg_io_db & 4) != 0; + ppu_reg_2001_show_background = (ppu_reg_io_db & 8) != 0; + ppu_reg_2001_show_sprites = (ppu_reg_io_db & 0x10) != 0; + ppu_reg_2001_grayscale = ((((uint)ppu_reg_io_db & (true ? 1u : 0u)) != 0) ? 48 : 63); + ppu_reg_2001_emphasis = (ppu_reg_io_db & 0xE0) << 1; + } + } + + private static void PPUOnRegister2002() + { + if (!ppu_reg_access_w) + { + ppu_vram_flip_flop = false; + ppu_reg_2002_VblankStartedFlag = false; + if (ppu_clock_v == ppu_clock_vblank_start) + { + PPU_NMI_Current = ppu_reg_2002_VblankStartedFlag & ppu_reg_2000_VBI; + } + } + } + + private static void PPUOnRegister2003() + { + if (ppu_reg_access_w) + { + ppu_reg_2003_oam_addr = ppu_reg_io_db; + } + } + + private static void PPUOnRegister2004() + { + if (ppu_reg_access_w) + { + if (ppu_clock_v < 240 && IsRenderingOn()) + { + ppu_reg_io_db = byte.MaxValue; + } + if ((ppu_reg_2003_oam_addr & 3) == 2) + { + ppu_reg_io_db &= 227; + } + ppu_oam_bank[ppu_reg_2003_oam_addr] = ppu_reg_io_db; + ppu_reg_2003_oam_addr = (byte)((uint)(ppu_reg_2003_oam_addr + 1) & 0xFFu); + } + } + + private static void PPUOnRegister2005() + { + if (ppu_reg_access_w) + { + if (!ppu_vram_flip_flop) + { + ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0x7FE0u) | (uint)((ppu_reg_io_db & 0xF8) >> 3)); + ppu_vram_finex = (byte)(ppu_reg_io_db & 7u); + } + else + { + ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0xC1Fu) | (uint)((ppu_reg_io_db & 7) << 12) | (uint)((ppu_reg_io_db & 0xF8) << 2)); + } + ppu_vram_flip_flop = !ppu_vram_flip_flop; + } + } + + private static void PPUOnRegister2006() + { + if (ppu_reg_access_w) + { + if (!ppu_vram_flip_flop) + { + ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0xFFu) | (uint)((ppu_reg_io_db & 0x3F) << 8)); + } + else + { + ppu_vram_addr_temp = (ushort)((ppu_vram_addr_temp & 0x7F00u) | ppu_reg_io_db); + ppu_vram_addr = ppu_vram_addr_temp; + mem_board.OnPPUAddressUpdate(ref ppu_vram_addr); + } + ppu_vram_flip_flop = !ppu_vram_flip_flop; + } + } + + private static void PPUOnRegister2007() + { + if (ppu_reg_access_w) + { + ppu_vram_addr_access_temp = (ushort)(ppu_vram_addr & 0x3FFFu); + if (ppu_vram_addr_access_temp < 8192) + { + mem_board.WriteCHR(ref ppu_vram_addr_access_temp, ref ppu_reg_io_db); + } + else if (ppu_vram_addr_access_temp < 16128) + { + mem_board.WriteNMT(ref ppu_vram_addr_access_temp, ref ppu_reg_io_db); + } + else if ((ppu_vram_addr_access_temp & 3u) != 0) + { + ppu_palette_bank[ppu_vram_addr_access_temp & 0x1F] = ppu_reg_io_db; + } + else + { + ppu_palette_bank[ppu_vram_addr_access_temp & 0xC] = ppu_reg_io_db; + } + } + else + { + if ((ppu_vram_addr & 0x3F00) == 16128) + { + ppu_vram_addr_access_temp = (ushort)(ppu_vram_addr & 0x2FFFu); + } + else + { + ppu_vram_addr_access_temp = (ushort)(ppu_vram_addr & 0x3FFFu); + } + if (ppu_vram_addr_access_temp < 8192) + { + mem_board.ReadCHR(ref ppu_vram_addr_access_temp, out ppu_vram_data); + } + else if (ppu_vram_addr_access_temp < 16128) + { + mem_board.ReadNMT(ref ppu_vram_addr_access_temp, out ppu_vram_data); + } + } + ppu_vram_addr = (ushort)((uint)(ppu_vram_addr + ppu_reg_2000_vram_address_increament) & 0x7FFFu); + mem_board.OnPPUAddressUpdate(ref ppu_vram_addr); + } + + private static void PPURead2000() + { + } + + private static void PPURead2001() + { + } + + private static void PPURead2002() + { + ppu_reg_io_db = (byte)((ppu_reg_io_db & 0xDFu) | (ppu_reg_2002_SpriteOverflow ? 32u : 0u)); + ppu_reg_io_db = (byte)((ppu_reg_io_db & 0xBFu) | (ppu_reg_2002_Sprite0Hit ? 64u : 0u)); + ppu_reg_io_db = (byte)((ppu_reg_io_db & 0x7Fu) | (ppu_reg_2002_VblankStartedFlag ? 128u : 0u)); + } + + private static void PPURead2003() + { + } + + private static void PPURead2004() + { + ppu_reg_io_db = ppu_oam_bank[ppu_reg_2003_oam_addr]; + if (ppu_clock_v < 240 && IsRenderingOn()) + { + if (ppu_clock_h < 64) + { + ppu_reg_io_db = byte.MaxValue; + } + else if (ppu_clock_h < 192) + { + ppu_reg_io_db = ppu_oam_bank[(ppu_clock_h - 64 << 1) & 0xFC]; + } + else if (ppu_clock_h < 256) + { + ppu_reg_io_db = (((ppu_clock_h & 1) == 1) ? ppu_oam_bank[252] : ppu_oam_bank[(ppu_clock_h - 192 << 1) & 0xFC]); + } + else if (ppu_clock_h < 320) + { + ppu_reg_io_db = byte.MaxValue; + } + else + { + ppu_reg_io_db = ppu_oam_bank[0]; + } + } + } + + private static void PPURead2005() + { + } + + private static void PPURead2006() + { + } + + private static void PPURead2007() + { + ppu_vram_addr_access_temp = (ushort)(ppu_vram_addr & 0x3FFFu); + if (ppu_vram_addr_access_temp < 16128) + { + ppu_reg_io_db = ppu_vram_data; + } + else if ((ppu_vram_addr_access_temp & 3u) != 0) + { + ppu_reg_io_db = ppu_palette_bank[ppu_vram_addr_access_temp & 0x1F]; + } + else + { + ppu_reg_io_db = ppu_palette_bank[ppu_vram_addr_access_temp & 0xC]; + } + } + + internal static bool IsRenderingOn() + { + if (!ppu_reg_2001_show_background) + { + return ppu_reg_2001_show_sprites; + } + return true; + } + + internal static bool IsInRender() + { + if (ppu_clock_v >= 240) + { + return ppu_clock_v == ppu_clock_vblank_end; + } + return true; + } + + private static void PPUWriteState(ref BinaryWriter bin) + { + bin.Write(ppu_clock_h); + bin.Write(ppu_clock_v); + bin.Write(ppu_clock_vblank_start); + bin.Write(ppu_clock_vblank_end); + bin.Write(ppu_use_odd_cycle); + bin.Write(ppu_use_odd_swap); + bin.Write(ppu_is_nmi_time); + bin.Write(ppu_frame_finished); + bin.Write(ppu_oam_bank); + bin.Write(ppu_oam_bank_secondary); + bin.Write(ppu_palette_bank); + bin.Write(ppu_reg_io_db); + bin.Write(ppu_reg_io_addr); + bin.Write(ppu_reg_access_happened); + bin.Write(ppu_reg_access_w); + bin.Write(ppu_reg_2000_vram_address_increament); + bin.Write(ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites); + bin.Write(ppu_reg_2000_background_pattern_table_address); + bin.Write(ppu_reg_2000_Sprite_size); + bin.Write(ppu_reg_2000_VBI); + bin.Write(ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen); + bin.Write(ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen); + bin.Write(ppu_reg_2001_show_background); + bin.Write(ppu_reg_2001_show_sprites); + bin.Write(ppu_reg_2001_grayscale); + bin.Write(ppu_reg_2001_emphasis); + bin.Write(ppu_reg_2002_SpriteOverflow); + bin.Write(ppu_reg_2002_Sprite0Hit); + bin.Write(ppu_reg_2002_VblankStartedFlag); + bin.Write(ppu_reg_2003_oam_addr); + bin.Write(ppu_vram_addr); + bin.Write(ppu_vram_data); + bin.Write(ppu_vram_addr_temp); + bin.Write(ppu_vram_addr_access_temp); + bin.Write(ppu_vram_flip_flop); + bin.Write(ppu_vram_finex); + bin.Write(ppu_bkgfetch_nt_addr); + bin.Write(ppu_bkgfetch_nt_data); + bin.Write(ppu_bkgfetch_at_addr); + bin.Write(ppu_bkgfetch_at_data); + bin.Write(ppu_bkgfetch_lb_addr); + bin.Write(ppu_bkgfetch_lb_data); + bin.Write(ppu_bkgfetch_hb_addr); + bin.Write(ppu_bkgfetch_hb_data); + bin.Write(ppu_sprfetch_slot); + bin.Write(ppu_sprfetch_y_data); + bin.Write(ppu_sprfetch_t_data); + bin.Write(ppu_sprfetch_at_data); + bin.Write(ppu_sprfetch_x_data); + bin.Write(ppu_sprfetch_lb_addr); + bin.Write(ppu_sprfetch_lb_data); + bin.Write(ppu_sprfetch_hb_addr); + bin.Write(ppu_sprfetch_hb_data); + bin.Write(ppu_bkg_render_i); + bin.Write(ppu_bkg_render_pos); + bin.Write(ppu_bkg_render_tmp_val); + bin.Write(ppu_bkg_current_pixel); + bin.Write(ppu_spr_current_pixel); + bin.Write(ppu_current_pixel); + bin.Write(ppu_render_x); + bin.Write(0); + bin.Write(ppu_oamev_n); + bin.Write(ppu_oamev_m); + bin.Write(ppu_oamev_compare); + bin.Write(ppu_oamev_slot); + bin.Write(ppu_fetch_data); + bin.Write(ppu_phase_index); + bin.Write(ppu_sprite0_should_hit); + } + + private static void PPUReadState(ref BinaryReader bin) + { + ppu_clock_h = bin.ReadInt32(); + ppu_clock_v = bin.ReadUInt16(); + ppu_clock_vblank_start = bin.ReadUInt16(); + ppu_clock_vblank_end = bin.ReadUInt16(); + ppu_use_odd_cycle = bin.ReadBoolean(); + ppu_use_odd_swap = bin.ReadBoolean(); + ppu_is_nmi_time = bin.ReadBoolean(); + ppu_frame_finished = bin.ReadBoolean(); + bin.Read(ppu_oam_bank, 0, ppu_oam_bank.Length); + bin.Read(ppu_oam_bank_secondary, 0, ppu_oam_bank_secondary.Length); + bin.Read(ppu_palette_bank, 0, ppu_palette_bank.Length); + ppu_reg_io_db = bin.ReadByte(); + ppu_reg_io_addr = bin.ReadByte(); + ppu_reg_access_happened = bin.ReadBoolean(); + ppu_reg_access_w = bin.ReadBoolean(); + ppu_reg_2000_vram_address_increament = bin.ReadByte(); + ppu_reg_2000_sprite_pattern_table_address_for_8x8_sprites = bin.ReadUInt16(); + ppu_reg_2000_background_pattern_table_address = bin.ReadUInt16(); + ppu_reg_2000_Sprite_size = bin.ReadByte(); + ppu_reg_2000_VBI = bin.ReadBoolean(); + ppu_reg_2001_show_background_in_leftmost_8_pixels_of_screen = bin.ReadBoolean(); + ppu_reg_2001_show_sprites_in_leftmost_8_pixels_of_screen = bin.ReadBoolean(); + ppu_reg_2001_show_background = bin.ReadBoolean(); + ppu_reg_2001_show_sprites = bin.ReadBoolean(); + ppu_reg_2001_grayscale = bin.ReadInt32(); + ppu_reg_2001_emphasis = bin.ReadInt32(); + ppu_reg_2002_SpriteOverflow = bin.ReadBoolean(); + ppu_reg_2002_Sprite0Hit = bin.ReadBoolean(); + ppu_reg_2002_VblankStartedFlag = bin.ReadBoolean(); + ppu_reg_2003_oam_addr = bin.ReadByte(); + ppu_vram_addr = bin.ReadUInt16(); + ppu_vram_data = bin.ReadByte(); + ppu_vram_addr_temp = bin.ReadUInt16(); + ppu_vram_addr_access_temp = bin.ReadUInt16(); + ppu_vram_flip_flop = bin.ReadBoolean(); + ppu_vram_finex = bin.ReadByte(); + ppu_bkgfetch_nt_addr = bin.ReadUInt16(); + ppu_bkgfetch_nt_data = bin.ReadByte(); + ppu_bkgfetch_at_addr = bin.ReadUInt16(); + ppu_bkgfetch_at_data = bin.ReadByte(); + ppu_bkgfetch_lb_addr = bin.ReadUInt16(); + ppu_bkgfetch_lb_data = bin.ReadByte(); + ppu_bkgfetch_hb_addr = bin.ReadUInt16(); + ppu_bkgfetch_hb_data = bin.ReadByte(); + ppu_sprfetch_slot = bin.ReadInt32(); + ppu_sprfetch_y_data = bin.ReadByte(); + ppu_sprfetch_t_data = bin.ReadByte(); + ppu_sprfetch_at_data = bin.ReadByte(); + ppu_sprfetch_x_data = bin.ReadByte(); + ppu_sprfetch_lb_addr = bin.ReadUInt16(); + ppu_sprfetch_lb_data = bin.ReadByte(); + ppu_sprfetch_hb_addr = bin.ReadUInt16(); + ppu_sprfetch_hb_data = bin.ReadByte(); + ppu_bkg_render_i = bin.ReadInt32(); + ppu_bkg_render_pos = bin.ReadInt32(); + ppu_bkg_render_tmp_val = bin.ReadInt32(); + ppu_bkg_current_pixel = bin.ReadInt32(); + ppu_spr_current_pixel = bin.ReadInt32(); + ppu_current_pixel = bin.ReadInt32(); + ppu_render_x = bin.ReadInt32(); + bin.ReadInt32(); + ppu_oamev_n = bin.ReadByte(); + ppu_oamev_m = bin.ReadByte(); + ppu_oamev_compare = bin.ReadBoolean(); + ppu_oamev_slot = bin.ReadByte(); + ppu_fetch_data = bin.ReadByte(); + ppu_phase_index = bin.ReadByte(); + ppu_sprite0_should_hit = bin.ReadBoolean(); + } + + internal static void CheckGame(string fileName, out bool valid) + { + string text = Path.GetExtension(fileName).ToLower(); + if (text != null && text == ".nes") + { + Tracer.WriteLine("Checking INES header ..."); + INes nes = new INes(); + nes.Load(fileName, loadDumps: false); + valid = nes.IsValid; + Tracer.WriteLine("INES header is valid."); + } + else + { + Tracer.WriteWarning("File format is not supported. Format: " + Path.GetExtension(fileName)); + valid = false; + } + } + + internal static void Initialize() + { + Tracer.WriteLine("Loading database file ..."); + string text = Path.Combine(MyNesMain.AppPath, "database.xml"); + if (File.Exists(text)) + { + bool success = false; + NesCartDatabase.LoadDatabase(text, out success); + if (success) + { + Tracer.WriteInformation("Nes Cart database file loaded successfully."); + } + else + { + Tracer.WriteError("Error loading Nes Cart database file."); + } + } + else + { + Tracer.WriteWarning("Nes Cart database file cannot be located at " + text); + } + FrameLimiterEnabled = true; + CPUInitialize(); + PPUInitialize(); + APUInitialize(); + PORTSInitialize(); + } + + internal static void SetupRenderingMethods(RenderVideoFrame renderVideo, RenderAudioSamples renderAudio, TogglePause renderTogglePause, GetIsPlaying renderGetIsPlaying) + { + render_initialized = false; + render_video = renderVideo; + render_audio = renderAudio; + render_audio_toggle_pause = renderTogglePause; + render_audio_get_is_playing = renderGetIsPlaying; + render_initialized = render_video != null && render_audio != null && render_audio_toggle_pause != null && render_audio_get_is_playing != null; + if (render_initialized) + { + Tracer.WriteInformation("Renderer methods initialized successfully."); + return; + } + Tracer.WriteError("ERROR RENDERER INITIALIZING !!"); + Tracer.WriteError("Faild to initialize the renderers methods. Please use the method 'SetupRenderingMethods' to initialize the renderers methods before you can run the emulation."); + } + + public static void LoadGame(string fileName, out bool success, bool useThread) + { + if (!render_initialized) + { + Tracer.WriteError("NO RENDERER INITIALIZED !! EMU CANNOT BE INTIALIZED WITHOUT A RENDERER !!"); + Tracer.WriteError("Please use the method 'SetupRenderingMethods' to initialize the renderers methods before you can run the emulation."); + success = false; + return; + } + string text = Path.GetExtension(fileName).ToLower(); + if (text != null && text == ".nes") + { + Tracer.WriteLine("Checking INES header ..."); + INes nes = new INes(); + nes.Load(fileName, loadDumps: true); + if (nes.IsValid) + { + emu_request_mode = RequestMode.None; + CurrentFilePath = fileName; + if (ON) + { + ShutDown(); + } + Tracer.WriteLine("INES header is valid, loading game ..."); + ApplyRegionSetting(); + MEMInitialize(nes); + ApplyAudioSettings(); + ApplyFrameSkipSettings(); + ApplyPaletteSetting(); + PORTSInitialize(); + hardReset(); + Tracer.WriteLine("EMU is ready."); + success = true; + emu_frame_clocking_mode = !useThread; + ON = true; + PAUSED = false; + if (useThread) + { + Tracer.WriteLine("Running in a thread ... using custom frame limiter."); + FrameLimiterEnabled = true; + mainThread = new Thread(EmuClock); + mainThread.Start(); + } + MyNesMain.VideoProvider.SignalToggle(started: true); + MyNesMain.AudioProvider.SignalToggle(started: true); + } + else + { + success = false; + } + } + else + { + success = false; + } + } + + public static void HardReset() + { + PAUSED = true; + emu_request_mode = RequestMode.HardReset; + } + + private static void hardReset() + { + if (MyNesMain.WaveRecorder.IsRecording) + { + MyNesMain.WaveRecorder.Stop(); + } + render_audio_toggle_pause(paused: true); + switch (Region) + { + case EmuRegion.NTSC: + emu_time_target_fps = 60.0988; + break; + case EmuRegion.PALB: + case EmuRegion.DENDY: + emu_time_target_fps = 50.0; + break; + } + fps_time_period = 1.0 / emu_time_target_fps; + MEMHardReset(); + CPUHardReset(); + PPUHardReset(); + APUHardReset(); + DMAHardReset(); + render_audio_toggle_pause(paused: false); + MyNesMain.VideoProvider.WriteWarningNotification(MNInterfaceLanguage.Message_HardReset, instant: false); + } + + public static void SoftReset() + { + PAUSED = true; + emu_request_mode = RequestMode.SoftReset; + } + + private static void softReset() + { + CPUSoftReset(); + APUSoftReset(); + MyNesMain.VideoProvider.WriteWarningNotification(MNInterfaceLanguage.Message_SoftReset, instant: false); + } + + public static void SaveState() + { + PAUSED = true; + emu_request_mode = RequestMode.SaveState; + } + + public static void LoadState() + { + PAUSED = true; + emu_request_mode = RequestMode.LoadState; + } + + internal static void TakeSnapshot() + { + PAUSED = true; + emu_request_mode = RequestMode.TakeSnapshot; + } + + public static void ShutDown() + { + MyNesMain.VideoProvider.SignalToggle(started: false); + MyNesMain.AudioProvider.SignalToggle(started: false); + if (MyNesMain.WaveRecorder.IsRecording) + { + MyNesMain.WaveRecorder.Stop(); + } + render_audio_get_is_playing(out render_audio_is_playing); + if (render_audio_is_playing) + { + render_audio_toggle_pause(paused: true); + } + Tracer.WriteLine("Shutting down the emulation core..."); + ON = false; + if (mainThread != null) + { + Tracer.WriteLine("Aborting thread .."); + while (mainThread.IsAlive) + { + } + mainThread.Abort(); + mainThread = null; + } + SaveSRAM(); + Tracer.WriteInformation("Emulation core shutdown successfully."); + NesEmu.EmuShutdown?.Invoke(null, new EventArgs()); + } + + internal static void EMUClockFrame() + { + emu_frame_done = false; + while (!emu_frame_done && ON) + { + if (!PAUSED) + { + CPUClock(); + } + else + { + Thread.Sleep(100); + } + } + } + + private static void EmuClock() + { + while (ON) + { + if (!PAUSED) + { + CPUClock(); + if (ppu_frame_finished) + { + FrameFinished(); + } + continue; + } + render_audio_get_is_playing(out render_audio_is_playing); + if (render_audio_is_playing) + { + render_audio_toggle_pause(paused: true); + } + Thread.Sleep(100); + shortucts.Update(); + switch (emu_request_mode) + { + case RequestMode.HardReset: + hardReset(); + PAUSED = false; + emu_request_mode = RequestMode.None; + break; + case RequestMode.SoftReset: + softReset(); + PAUSED = false; + emu_request_mode = RequestMode.None; + break; + case RequestMode.SaveState: + StateHandler.SaveState(); + PAUSED = false; + emu_request_mode = RequestMode.None; + break; + case RequestMode.LoadState: + StateHandler.LoadState(); + PAUSED = false; + emu_request_mode = RequestMode.None; + break; + case RequestMode.TakeSnapshot: + MyNesMain.VideoProvider.TakeSnapshot(); + PAUSED = false; + emu_request_mode = RequestMode.None; + break; + } + isPaused = true; + } + } + + internal static void EmuClockComponents() + { + PPUClock(); + PollInterruptStatus(); + PPUClock(); + PPUClock(); + APUClock(); + DMAClock(); + mem_board.OnCPUClock(); + } + + internal static void ApplyFrameSkipSettings() + { + FrameSkipEnabled = MyNesMain.RendererSettings.FrameSkipEnabled; + FrameSkipInterval = MyNesMain.RendererSettings.FrameSkipInterval; + } + + private static void FrameFinished() + { + if (!FrameSkipEnabled) + { + render_video(ref ppu_screen_pixels); + } + else + { + FrameSkipCounter++; + if (FrameSkipCounter >= FrameSkipInterval) + { + render_video(ref ppu_screen_pixels); + FrameSkipCounter = 0; + } + } + isPaused = false; + ppu_frame_finished = false; + emu_frame_done = true; + joypad1.Update(); + joypad2.Update(); + if (IsFourPlayers) + { + joypad3.Update(); + joypad4.Update(); + } + shortucts.Update(); + if (SoundEnabled) + { + render_audio_get_is_playing(out render_audio_is_playing); + if (!render_audio_is_playing) + { + render_audio_toggle_pause(paused: false); + } + render_audio(ref audio_samples, ref audio_samples_added); + audio_w_pos = 0; + audio_samples_added = 0; + audio_timer = 0.0; + } + fps_time_token = GetTime() - fps_time_start; + if (FrameLimiterEnabled) + { + if (fps_time_token > 0.0) + { + fps_time_dead = fps_time_period - fps_time_token; + if (fps_time_dead > 0.0) + { + Thread.Sleep((int)Math.Floor(fps_time_dead * 1000.0)); + fps_time_dead = GetTime() - fps_time_start; + while (fps_time_period - fps_time_dead > 0.0) + { + fps_time_dead = GetTime() - fps_time_start; + } + } + } + fps_time_last = GetTime(); + fps_time_frame_time = fps_time_last - fps_time_start; + } + fps_time_start = GetTime(); + } + + private static double GetTime() + { + return (double)Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency; + } + + public static void GetSpeedValues(out double frame_time, out double immediate_frame_time) + { + frame_time = fps_time_token; + immediate_frame_time = fps_time_frame_time; + } + + public static void SetFramePeriod(ref double period) + { + fps_time_period = period; + } + + public static void ApplyRegionSetting() + { + switch ((RegionSetting)MyNesMain.EmuSettings.RegionSetting) + { + case RegionSetting.AUTO: + Tracer.WriteLine("REGION = AUTO"); + Region = EmuRegion.NTSC; + if (CurrentFilePath.Contains("(E)")) + { + Region = EmuRegion.PALB; + } + Tracer.WriteLine("REGION SELECTED: " + Region); + break; + case RegionSetting.ForceNTSC: + Tracer.WriteLine("REGION: FORCE NTSC"); + Region = EmuRegion.NTSC; + break; + case RegionSetting.ForcePALB: + Tracer.WriteLine("REGION: FORCE PALB"); + Region = EmuRegion.PALB; + break; + case RegionSetting.ForceDENDY: + Tracer.WriteLine("REGION: FORCE DENDY"); + Region = EmuRegion.DENDY; + break; + } + SystemIndex = (int)Region; + } + + public static void ApplyPaletteSetting() + { + Tracer.WriteLine("Loading palette generators values from settings..."); + NTSCPaletteGenerator.brightness = MyNesMain.RendererSettings.Palette_NTSC_brightness; + NTSCPaletteGenerator.contrast = MyNesMain.RendererSettings.Palette_NTSC_contrast; + NTSCPaletteGenerator.gamma = MyNesMain.RendererSettings.Palette_NTSC_gamma; + NTSCPaletteGenerator.hue_tweak = MyNesMain.RendererSettings.Palette_NTSC_hue_tweak; + NTSCPaletteGenerator.saturation = MyNesMain.RendererSettings.Palette_NTSC_saturation; + PALBPaletteGenerator.brightness = MyNesMain.RendererSettings.Palette_PALB_brightness; + PALBPaletteGenerator.contrast = MyNesMain.RendererSettings.Palette_PALB_contrast; + PALBPaletteGenerator.gamma = MyNesMain.RendererSettings.Palette_PALB_gamma; + PALBPaletteGenerator.hue_tweak = MyNesMain.RendererSettings.Palette_PALB_hue_tweak; + PALBPaletteGenerator.saturation = MyNesMain.RendererSettings.Palette_PALB_saturation; + Tracer.WriteLine("Setting up palette ...."); + switch ((PaletteSelectSetting)MyNesMain.RendererSettings.Palette_PaletteSetting) + { + case PaletteSelectSetting.AUTO: + Tracer.WriteLine("Palette set to auto detect depending on region."); + switch (Region) + { + case EmuRegion.NTSC: + SetupPalette(NTSCPaletteGenerator.GeneratePalette()); + Tracer.WriteLine("Region is NTSC, Palette set from NTSC generator."); + break; + case EmuRegion.PALB: + case EmuRegion.DENDY: + SetupPalette(PALBPaletteGenerator.GeneratePalette()); + Tracer.WriteLine("Region is PALB/DENDY, Palette set from PALB generator."); + break; + } + break; + case PaletteSelectSetting.ForceNTSC: + Tracer.WriteLine("Palette set to always use NTSC palette generator."); + SetupPalette(NTSCPaletteGenerator.GeneratePalette()); + Tracer.WriteLine("Palette set from NTSC generator."); + break; + case PaletteSelectSetting.ForcePALB: + Tracer.WriteLine("Palette set to always use PALB palette generator."); + SetupPalette(NTSCPaletteGenerator.GeneratePalette()); + Tracer.WriteLine("Palette set from PALB generator."); + break; + case PaletteSelectSetting.File: + { + Tracer.WriteLine("Palette set to load from file."); + string fullPath = Path.GetFullPath(MyNesMain.RendererSettings.Palette_CurrentPaletteFilePath); + if (File.Exists(fullPath)) + { + PaletteFileWrapper.LoadFile(fullPath, out var palette); + SetupPalette(palette); + Tracer.WriteLine("Palette set from file: " + fullPath); + break; + } + Tracer.WriteError("Palette file: " + fullPath + " is not exist. Setting up palette from generators."); + switch (Region) + { + case EmuRegion.NTSC: + SetupPalette(NTSCPaletteGenerator.GeneratePalette()); + Tracer.WriteLine("Region is NTSC, Palette set from NTSC generator."); + break; + case EmuRegion.PALB: + case EmuRegion.DENDY: + SetupPalette(PALBPaletteGenerator.GeneratePalette()); + Tracer.WriteLine("Region is PALB/DENDY, Palette set from PALB generator."); + break; + } + break; + } + } + } + + internal static void WriteStateData(ref BinaryWriter bin) + { + APUWriteState(ref bin); + CPUWriteState(ref bin); + DMAWriteState(ref bin); + InterruptsWriteState(ref bin); + MEMWriteState(ref bin); + PORTWriteState(ref bin); + PPUWriteState(ref bin); + } + + internal static void ReadStateData(ref BinaryReader bin) + { + APUReadState(ref bin); + CPUReadState(ref bin); + DMAReadState(ref bin); + InterruptsReadState(ref bin); + MEMReadState(ref bin); + PORTReadState(ref bin); + PPUReadState(ref bin); + } + + private static void SQ2HardReset() + { + sq2_duty_cycle = 0; + sq2_length_halt = false; + sq2_constant_volume_envelope = false; + sq2_volume_devider_period = 0; + sq2_sweep_enable = false; + sq2_sweep_devider_period = 0; + sq2_sweep_negate = false; + sq2_sweep_shift_count = 0; + sq2_timer = 0; + sq2_period_devider = 0; + sq2_seqencer = 0; + sq2_length_enabled = false; + sq2_length_counter = 0; + sq2_envelope_start_flag = false; + sq2_envelope_devider = 0; + sq2_envelope_decay_level_counter = 0; + sq2_envelope = 0; + sq2_sweep_counter = 0; + sq2_sweep_reload = false; + sq2_sweep_change = 0; + sq2_valid_freq = false; + sq2_output = 0; + sq2_ignore_reload = false; + } + + private static void SQ2SoftReset() + { + SQ2HardReset(); + } + + private static void SQ2Clock() + { + sq2_period_devider--; + if (sq2_period_devider > 0) + { + return; + } + sq2_period_devider = sq2_timer + 1; + sq2_seqencer = (byte)((uint)(sq2_seqencer + 1) & 7u); + if (sq2_length_counter > 0 && sq2_valid_freq) + { + if (audio_sq2_outputable) + { + sq2_output = sq_duty_cycle_sequences[sq2_duty_cycle][sq2_seqencer] * sq2_envelope; + } + } + else + { + sq2_output = 0; + } + audio_signal_outputed = true; + } + + private static void SQ2ClockLength() + { + if (sq2_length_counter > 0 && !sq2_length_halt) + { + sq2_length_counter--; + if (apu_reg_access_happened && apu_reg_io_addr == 7 && apu_reg_access_w) + { + sq2_ignore_reload = true; + } + } + sq2_sweep_counter--; + if (sq2_sweep_counter == 0) + { + sq2_sweep_counter = sq2_sweep_devider_period + 1; + if (sq2_sweep_enable && sq2_sweep_shift_count > 0 && sq2_valid_freq) + { + sq2_sweep_change = sq2_timer >> (int)sq2_sweep_shift_count; + sq2_timer += (sq2_sweep_negate ? (-sq2_sweep_change) : sq2_sweep_change); + SQ2CalculateValidFreq(); + } + } + else if (sq2_sweep_reload) + { + sq2_sweep_counter = sq2_sweep_devider_period + 1; + sq2_sweep_reload = false; + } + } + + private static void SQ2ClockEnvelope() + { + if (sq2_envelope_start_flag) + { + sq2_envelope_start_flag = false; + sq2_envelope_decay_level_counter = 15; + sq2_envelope_devider = (byte)(sq2_volume_devider_period + 1); + } + else if (sq2_envelope_devider > 0) + { + sq2_envelope_devider--; + } + else + { + sq2_envelope_devider = (byte)(sq2_volume_devider_period + 1); + if (sq2_envelope_decay_level_counter > 0) + { + sq2_envelope_decay_level_counter--; + } + else if (sq2_length_halt) + { + sq2_envelope_decay_level_counter = 15; + } + } + sq2_envelope = (sq2_constant_volume_envelope ? sq2_volume_devider_period : sq2_envelope_decay_level_counter); + } + + private static void APUOnRegister4004() + { + if (apu_reg_access_w) + { + sq2_duty_cycle = (byte)((apu_reg_io_db & 0xC0) >> 6); + sq2_volume_devider_period = (byte)(apu_reg_io_db & 0xFu); + sq2_length_halt = (apu_reg_io_db & 0x20) != 0; + sq2_constant_volume_envelope = (apu_reg_io_db & 0x10) != 0; + sq2_envelope = (sq2_constant_volume_envelope ? sq2_volume_devider_period : sq2_envelope_decay_level_counter); + } + } + + private static void APUOnRegister4005() + { + if (apu_reg_access_w) + { + sq2_sweep_enable = (apu_reg_io_db & 0x80) == 128; + sq2_sweep_devider_period = (byte)((uint)(apu_reg_io_db >> 4) & 7u); + sq2_sweep_negate = (apu_reg_io_db & 8) == 8; + sq2_sweep_shift_count = (byte)(apu_reg_io_db & 7u); + sq2_sweep_reload = true; + SQ2CalculateValidFreq(); + } + } + + private static void APUOnRegister4006() + { + if (apu_reg_access_w) + { + sq2_timer = (sq2_timer & 0xFF00) | apu_reg_io_db; + SQ2CalculateValidFreq(); + } + } + + private static void APUOnRegister4007() + { + if (apu_reg_access_w) + { + sq2_timer = (sq2_timer & 0xFF) | ((apu_reg_io_db & 7) << 8); + if (sq2_length_enabled && !sq2_ignore_reload) + { + sq2_length_counter = sq_duration_table[apu_reg_io_db >> 3]; + } + if (sq2_ignore_reload) + { + sq2_ignore_reload = false; + } + sq2_seqencer = 0; + sq2_envelope_start_flag = true; + SQ2CalculateValidFreq(); + } + } + + private static void SQ2On4015() + { + sq2_length_enabled = (apu_reg_io_db & 2) != 0; + if (!sq2_length_enabled) + { + sq2_length_counter = 0; + } + } + + private static void SQ2Read4015() + { + if (sq2_length_counter > 0) + { + apu_reg_io_db = (byte)((apu_reg_io_db & 0xFDu) | 2u); + } + } + + private static void SQ2CalculateValidFreq() + { + sq2_valid_freq = sq2_timer >= 8 && (sq2_sweep_negate || ((sq2_timer + (sq2_timer >> (int)sq2_sweep_shift_count)) & 0x800) == 0); + } + + private static void SQ2WriteState(ref BinaryWriter bin) + { + bin.Write(sq2_duty_cycle); + bin.Write(sq2_length_halt); + bin.Write(sq2_constant_volume_envelope); + bin.Write(sq2_volume_devider_period); + bin.Write(sq2_sweep_enable); + bin.Write(sq2_sweep_devider_period); + bin.Write(sq2_sweep_negate); + bin.Write(sq2_sweep_shift_count); + bin.Write(sq2_timer); + bin.Write(sq2_period_devider); + bin.Write(sq2_seqencer); + bin.Write(sq2_length_enabled); + bin.Write(sq2_length_counter); + bin.Write(sq2_envelope_start_flag); + bin.Write(sq2_envelope_devider); + bin.Write(sq2_envelope_decay_level_counter); + bin.Write(sq2_envelope); + bin.Write(sq2_sweep_counter); + bin.Write(sq2_sweep_reload); + bin.Write(sq2_sweep_change); + bin.Write(sq2_valid_freq); + bin.Write(sq2_output); + bin.Write(sq2_ignore_reload); + } + + private static void SQ2ReadState(ref BinaryReader bin) + { + sq2_duty_cycle = bin.ReadByte(); + sq2_length_halt = bin.ReadBoolean(); + sq2_constant_volume_envelope = bin.ReadBoolean(); + sq2_volume_devider_period = bin.ReadByte(); + sq2_sweep_enable = bin.ReadBoolean(); + sq2_sweep_devider_period = bin.ReadByte(); + sq2_sweep_negate = bin.ReadBoolean(); + sq2_sweep_shift_count = bin.ReadByte(); + sq2_timer = bin.ReadInt32(); + sq2_period_devider = bin.ReadInt32(); + sq2_seqencer = bin.ReadByte(); + sq2_length_enabled = bin.ReadBoolean(); + sq2_length_counter = bin.ReadInt32(); + sq2_envelope_start_flag = bin.ReadBoolean(); + sq2_envelope_devider = bin.ReadByte(); + sq2_envelope_decay_level_counter = bin.ReadByte(); + sq2_envelope = bin.ReadByte(); + sq2_sweep_counter = bin.ReadInt32(); + sq2_sweep_reload = bin.ReadBoolean(); + sq2_sweep_change = bin.ReadInt32(); + sq2_valid_freq = bin.ReadBoolean(); + sq2_output = bin.ReadInt32(); + sq2_ignore_reload = bin.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/PALBPaletteGenerator.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/PALBPaletteGenerator.cs new file mode 100644 index 0000000..e07903c --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/PALBPaletteGenerator.cs @@ -0,0 +1,108 @@ +using System; + +namespace MyNes.Core; + +public class PALBPaletteGenerator +{ + public const float default_saturation = 1.496f; + + public const float default_hue_tweak = 0f; + + public const float default_contrast = 1.016f; + + public const float default_brightness = 1.075f; + + public const float default_gamma = 1.975f; + + private const float black = 0.518f; + + private const float white = 1.962f; + + private const float attenuation = 0.746f; + + public static float saturation = 2f; + + public static float hue_tweak = 0f; + + public static float contrast = 1.4f; + + public static float brightness = 1.07f; + + public static float gamma = 2f; + + private static float[] levels = new float[8] { 0.35f, 0.518f, 0.962f, 1.55f, 1.094f, 1.506f, 1.962f, 1.962f }; + + private static int wave(int p, int color) + { + if ((color + p + 8) % 12 >= 6) + { + return 0; + } + return 1; + } + + private static float gammafix(float f, float gamma) + { + return (float)((f < 0f) ? 0.0 : Math.Pow(f, 2.2f / gamma)); + } + + private static int clamp(float v) + { + return (int)((v < 0f) ? 0f : ((v > 255f) ? 255f : v)); + } + + public static int MakeRGBcolor(int pixel) + { + int num = pixel & 0xF; + int num2 = ((num >= 14) ? 1 : ((pixel >> 4) & 3)); + float[] array = new float[2] + { + levels[num2 + ((num == 0) ? 4 : 0)], + levels[num2 + ((num <= 12) ? 4 : 0)] + }; + float num3 = 0f; + float num4 = 0f; + float num5 = 0f; + for (int i = 0; i < 12; i++) + { + float num6 = array[wave(i, num)]; + if ((((uint)pixel & 0x40u) != 0 && wave(i, 12) == 1) || (((uint)pixel & 0x80u) != 0 && wave(i, 4) == 1) || (((uint)pixel & 0x100u) != 0 && wave(i, 8) == 1)) + { + num6 *= 0.746f; + } + float num7 = (num6 - 0.518f) / 1.444f; + num7 = (num7 - 0.5f) * contrast + 0.5f; + num7 *= brightness / 12f; + num3 += num7; + num4 += (float)((double)num7 * Math.Cos(Math.PI / 6.0 * (double)((float)i + 0.5f + hue_tweak))); + num5 += (float)((double)num7 * Math.Sin(Math.PI / 6.0 * (double)((float)i + 0.5f + hue_tweak))); + } + num4 *= saturation; + num5 *= saturation; + return 65536 * clamp(255f * gammafix(num3 + 0.946882f * num4 + 0.623557f * num5, gamma)) + 256 * clamp(255f * gammafix(num3 - 245f / (328f * (float)Math.E) * num4 - 0.635691f * num5, gamma)) + clamp(255f * gammafix(num3 - 1.108545f * num4 + 1.709007f * num5, gamma)); + } + + public static int[] GeneratePalette() + { + int[] array = new int[512]; + for (int i = 0; i < 512; i++) + { + array[i] = MakeRGBcolor(i) | -16777216; + } + return array; + } + + public static int[] GeneratePaletteGBR() + { + int[] array = new int[512]; + for (int i = 0; i < 512; i++) + { + int num = MakeRGBcolor(i); + byte b = (byte)((num & 0xFF0000) >> 16); + byte b2 = (byte)((num & 0xFF00) >> 8); + byte b3 = (byte)((uint)num & 0xFFu); + array[i] = -16777216 | (b3 << 16) | (b2 << 8) | b; + } + return array; + } +} diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/PALBPaletteGenerator.cs.meta b/AxibugEmuOnline.Client/Assets/MyNes.Core/PALBPaletteGenerator.cs.meta new file mode 100644 index 0000000..ff8e34b --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/PALBPaletteGenerator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3a50696d24d84244db471bd77c8e8ace +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/PRGArea.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/PRGArea.cs index a578275..f6040d0 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/PRGArea.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/PRGArea.cs @@ -1,18 +1,17 @@ -namespace MyNes.Core -{ - internal enum PRGArea : byte - { - Area4000 = 4, - Area5000, - Area6000, - Area7000, - Area8000, - Area9000, - AreaA000, - AreaB000, - AreaC000, - AreaD000, - AreaE000, - AreaF000 - } +namespace MyNes.Core; + +internal enum PRGArea : byte +{ + Area4000 = 4, + Area5000, + Area6000, + Area7000, + Area8000, + Area9000, + AreaA000, + AreaB000, + AreaC000, + AreaD000, + AreaE000, + AreaF000 } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteFileWrapper.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteFileWrapper.cs new file mode 100644 index 0000000..618a924 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteFileWrapper.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using System.IO; + +namespace MyNes.Core; + +public class PaletteFileWrapper +{ + public static bool LoadFile(string file, out int[] palette) + { + Stream stream = new FileStream(file, FileMode.Open, FileAccess.Read); + if (stream.Length == 192 || stream.Length == 1536) + { + int[] array = new int[512]; + byte[] array2 = new byte[stream.Length]; + stream.Read(array2, 0, array2.Length); + int num = 0; + for (int i = 0; i < 512; i++) + { + byte b = array2[num]; + num++; + if (num == array2.Length) + { + num = 0; + } + byte b2 = array2[num]; + num++; + if (num == array2.Length) + { + num = 0; + } + byte b3 = array2[num]; + num++; + if (num == array2.Length) + { + num = 0; + } + array[i] = -16777216 | (b << 16) | (b2 << 8) | b3; + } + stream.Close(); + palette = array; + return true; + } + palette = null; + return false; + } + + public static void SaveFile(string file, int[] palette) + { + Stream stream = new FileStream(file, FileMode.Create, FileAccess.Write); + List list = new List(); + foreach (int num in palette) + { + list.Add((byte)((uint)(num >> 16) & 0xFFu)); + list.Add((byte)((uint)(num >> 8) & 0xFFu)); + list.Add((byte)((uint)num & 0xFFu)); + } + stream.Write(list.ToArray(), 0, list.Count); + stream.Close(); + } +} diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteFileWrapper.cs.meta b/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteFileWrapper.cs.meta new file mode 100644 index 0000000..5006743 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteFileWrapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f15f9fdbee4f6704ebf4de045e49573c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteSelectSetting.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteSelectSetting.cs index 2895847..b47404a 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteSelectSetting.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/PaletteSelectSetting.cs @@ -1,10 +1,9 @@ -namespace MyNes.Core -{ - public enum PaletteSelectSetting - { - AUTO, - ForceNTSC, - ForcePALB, - File - } +namespace MyNes.Core; + +public enum PaletteSelectSetting +{ + AUTO, + ForceNTSC, + ForcePALB, + File } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/RegionSetting.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/RegionSetting.cs index 3c07fdc..ebae4c3 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/RegionSetting.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/RegionSetting.cs @@ -1,10 +1,9 @@ -namespace MyNes.Core -{ - public enum RegionSetting - { - AUTO, - ForceNTSC, - ForcePALB, - ForceDENDY - } +namespace MyNes.Core; + +public enum RegionSetting +{ + AUTO, + ForceNTSC, + ForcePALB, + ForceDENDY } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/RenderAudioSamples.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/RenderAudioSamples.cs index 6992b3b..0c587a3 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/RenderAudioSamples.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/RenderAudioSamples.cs @@ -1,4 +1,3 @@ -namespace MyNes.Core -{ - internal delegate void RenderAudioSamples(ref short[] buffer, ref int samples_added); -} +namespace MyNes.Core; + +internal delegate void RenderAudioSamples(ref short[] buffer, ref int samples_added); diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/RenderVideoFrame.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/RenderVideoFrame.cs index 82dbc3d..7456cd8 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/RenderVideoFrame.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/RenderVideoFrame.cs @@ -1,4 +1,3 @@ -namespace MyNes.Core -{ - internal delegate void RenderVideoFrame(ref int[] buffer); -} +namespace MyNes.Core; + +internal delegate void RenderVideoFrame(ref int[] buffer); diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/RendererSettings.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/RendererSettings.cs index 3e6e213..81c1326 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/RendererSettings.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/RendererSettings.cs @@ -1,106 +1,135 @@ -namespace MyNes.Core -{ - public class RendererSettings : ISettings - { - public string Video_ProviderID = ""; - - public bool Vid_AutoStretch = true; - - public bool Vid_Res_Upscale = true; - - public int Vid_Res_W = 640; - - public int Vid_Res_H = 480; - - public int Vid_StretchMultiply = 2; - - public bool Vid_KeepAspectRatio = true; - - public bool Vid_ShowFPS = false; - - public bool Vid_Fullscreen = false; - - public bool Vid_HardwareVertexProcessing = false; - - public bool Vid_VSync = false; - - public bool Vid_ShowNotifications = true; - - public int Vid_Filter = 1; - - public bool FrameSkipEnabled = false; - - public int FrameSkipInterval = 2; - - public bool UseEmuThread = true; - - public string Audio_ProviderID = ""; - - public bool Audio_EnableFilters = true; - - public int Audio_Volume = 100; - - public bool Audio_SoundEnabled = true; - - public int Audio_Frequency = 44100; - - public int Audio_InternalSamplesCount = 4096; - - public int Audio_InternalPeekLimit = 124; - - public int Audio_PlaybackAmplitude = 200; - - public int Audio_PlaybackBufferSizeInKB = 8; - - public bool Audio_UseDefaultMixer = true; - - public bool Audio_ChannelEnabled_SQ1 = true; - - public bool Audio_ChannelEnabled_SQ2 = true; - - public bool Audio_ChannelEnabled_NOZ = true; - - public bool Audio_ChannelEnabled_TRL = true; - - public bool Audio_ChannelEnabled_DMC = true; - - public bool Audio_ChannelEnabled_MMC5_SQ1 = true; - - public bool Audio_ChannelEnabled_MMC5_SQ2 = true; - - public bool Audio_ChannelEnabled_MMC5_PCM = true; - - public bool Audio_ChannelEnabled_VRC6_SQ1 = true; - - public bool Audio_ChannelEnabled_VRC6_SQ2 = true; - - public bool Audio_ChannelEnabled_VRC6_SAW = true; - - public bool Audio_ChannelEnabled_SUN1 = true; - - public bool Audio_ChannelEnabled_SUN2 = true; - - public bool Audio_ChannelEnabled_SUN3 = true; - - public bool Audio_ChannelEnabled_NMT1 = true; - - public bool Audio_ChannelEnabled_NMT2 = true; - - public bool Audio_ChannelEnabled_NMT3 = true; - - public bool Audio_ChannelEnabled_NMT4 = true; - - public bool Audio_ChannelEnabled_NMT5 = true; - - public bool Audio_ChannelEnabled_NMT6 = true; - - public bool Audio_ChannelEnabled_NMT7 = true; - - public bool Audio_ChannelEnabled_NMT8 = true; - - public RendererSettings(string path) - : base(path) - { - } - } +using System.IO; + +namespace MyNes.Core; + +public class RendererSettings : ISettings +{ + public string Video_ProviderID = ""; + + public bool Vid_AutoStretch = true; + + public int Vid_StretchMultiply = 3; + + public bool Vid_KeepAspectRatio; + + public bool Vid_ShowFPS; + + public bool Vid_HideLines = true; + + public bool Vid_Fullscreen; + + public bool Vid_HardwareVertexProcessing; + + public bool Vid_VSync; + + public bool Vid_ShowNotifications = true; + + public int Vid_Filter = 1; + + public bool FrameSkipEnabled; + + public int FrameSkipInterval = 2; + + public string Audio_ProviderID = ""; + + public bool Audio_EnableFilters = true; + + public int Audio_Volume = 100; + + public bool Audio_SoundEnabled = true; + + public int Audio_Frequency = 48000; + + public int Audio_InternalSamplesCount = 1024; + + public int Audio_InternalPeekLimit = 124; + + public int Audio_PlaybackAmplitude = 200; + + public int Audio_PlaybackBufferSizeInKB = 16; + + public bool Audio_UseDefaultMixer; + + public bool Audio_ChannelEnabled_SQ1 = true; + + public bool Audio_ChannelEnabled_SQ2 = true; + + public bool Audio_ChannelEnabled_NOZ = true; + + public bool Audio_ChannelEnabled_TRL = true; + + public bool Audio_ChannelEnabled_DMC = true; + + public bool Audio_ChannelEnabled_MMC5_SQ1 = true; + + public bool Audio_ChannelEnabled_MMC5_SQ2 = true; + + public bool Audio_ChannelEnabled_MMC5_PCM = true; + + public bool Audio_ChannelEnabled_VRC6_SQ1 = true; + + public bool Audio_ChannelEnabled_VRC6_SQ2 = true; + + public bool Audio_ChannelEnabled_VRC6_SAW = true; + + public bool Audio_ChannelEnabled_SUN1 = true; + + public bool Audio_ChannelEnabled_SUN2 = true; + + public bool Audio_ChannelEnabled_SUN3 = true; + + public bool Audio_ChannelEnabled_NMT1 = true; + + public bool Audio_ChannelEnabled_NMT2 = true; + + public bool Audio_ChannelEnabled_NMT3 = true; + + public bool Audio_ChannelEnabled_NMT4 = true; + + public bool Audio_ChannelEnabled_NMT5 = true; + + public bool Audio_ChannelEnabled_NMT6 = true; + + public bool Audio_ChannelEnabled_NMT7 = true; + + public bool Audio_ChannelEnabled_NMT8 = true; + + public int Palette_PaletteSetting; + + public string Palette_CurrentPaletteFilePath = "default_ntsc.pal"; + + public float Palette_NTSC_brightness = 1.075f; + + public float Palette_NTSC_contrast = 1.016f; + + public float Palette_NTSC_gamma = 1.975f; + + public float Palette_NTSC_hue_tweak; + + public float Palette_NTSC_saturation = 1.496f; + + public float Palette_PALB_brightness = 1.075f; + + public float Palette_PALB_contrast = 1.016f; + + public float Palette_PALB_gamma = 1.975f; + + public float Palette_PALB_hue_tweak; + + public float Palette_PALB_saturation = 1.496f; + + public RendererSettings(string path) + : base(path) + { + } + + public override void LoadSettings() + { + base.LoadSettings(); + if (Palette_CurrentPaletteFilePath == "default_ntsc.pal" || Palette_CurrentPaletteFilePath == "" || !File.Exists(Palette_CurrentPaletteFilePath)) + { + Palette_CurrentPaletteFilePath = Path.Combine(MyNesMain.AppPath, "Palettes"); + Palette_CurrentPaletteFilePath = Path.Combine(Palette_CurrentPaletteFilePath, "default_ntsc.pal"); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/SRAMBankInfo.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/SRAMBankInfo.cs index 80c644e..de29488 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/SRAMBankInfo.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/SRAMBankInfo.cs @@ -1,22 +1,21 @@ -namespace MyNes.Core -{ - public struct SRAMBankInfo - { - public int id; - - public string SIZE; - - public bool BATTERY; - - public SRAMBankInfo(int id, string SIZE, bool BATTERY) - { - this.SIZE = SIZE; - if (SIZE == "0kb") - { - SIZE = "8kb"; - } - this.BATTERY = BATTERY; - this.id = id; - } - } +namespace MyNes.Core; + +public struct SRAMBankInfo +{ + public int id; + + public string SIZE; + + public bool BATTERY; + + public SRAMBankInfo(int id, string SIZE, bool BATTERY) + { + this.SIZE = SIZE; + if (SIZE == "0kb") + { + SIZE = "8kb"; + } + this.BATTERY = BATTERY; + this.id = id; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundDCBlockerFilter.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundDCBlockerFilter.cs index 9e2fd28..32f0735 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundDCBlockerFilter.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundDCBlockerFilter.cs @@ -1,33 +1,32 @@ -namespace MyNes.Core -{ - internal class SoundDCBlockerFilter - { - private double R; - - private double y; - - private double y_1; - - private double x; - - private double x_1; - - public SoundDCBlockerFilter(double R) - { - this.R = R; - } - - public void Reset() - { - y = (y_1 = (x = (x_1 = 0.0))); - } - - public void DoFiltering(double sample, out double filtered) - { - x = sample; - filtered = (y = x - x_1 + R * y_1); - x_1 = x; - y_1 = y; - } - } +namespace MyNes.Core; + +internal class SoundDCBlockerFilter +{ + private double R; + + private double y; + + private double y_1; + + private double x; + + private double x_1; + + public SoundDCBlockerFilter(double R) + { + this.R = R; + } + + public void Reset() + { + y = (y_1 = (x = (x_1 = 0.0))); + } + + public void DoFiltering(double sample, out double filtered) + { + x = sample; + filtered = (y = x - x_1 + R * y_1); + x_1 = x; + y_1 = y; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundHighPassFilter.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundHighPassFilter.cs index 8102bb6..04502da 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundHighPassFilter.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundHighPassFilter.cs @@ -1,36 +1,35 @@ -using System; - -namespace MyNes.Core -{ - internal class SoundHighPassFilter - { - private double K; - - private double y_1; - - private double x_1; - - public SoundHighPassFilter(double k) - { - K = k; - } - - public void Reset() - { - y_1 = (x_1 = 0.0); - } - - public void DoFiltering(double sample, out double filtered) - { - filtered = K * y_1 + K * (sample - x_1); - x_1 = sample; - y_1 = filtered; - } - - public static double GetK(double dt, double fc) - { - double num = Math.PI * 2.0 * dt * fc; - return num / (num + 1.0); - } - } +using System; + +namespace MyNes.Core; + +internal class SoundHighPassFilter +{ + private double K; + + private double y_1; + + private double x_1; + + public SoundHighPassFilter(double k) + { + K = k; + } + + public void Reset() + { + y_1 = (x_1 = 0.0); + } + + public void DoFiltering(double sample, out double filtered) + { + filtered = K * y_1 + K * (sample - x_1); + x_1 = sample; + y_1 = filtered; + } + + public static double GetK(double dt, double fc) + { + double num = Math.PI * 2.0 * dt * fc; + return num / (num + 1.0); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundLowPassFilter.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundLowPassFilter.cs index 5a39d40..77bf2a3 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundLowPassFilter.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/SoundLowPassFilter.cs @@ -1,45 +1,44 @@ -using System; - -namespace MyNes.Core -{ - internal class SoundLowPassFilter - { - private double K; - - private double K_1; - - private double y; - - private double y_1; - - private double x; - - private double x_1; - - public SoundLowPassFilter(double k) - { - K = k; - K_1 = 1.0 - k; - } - - public void Reset(double k) - { - y = (y_1 = (x = (x_1 = 0.0))); - K = k; - K_1 = 1.0 - k; - } - - public void DoFiltering(double sample, out double filtered) - { - filtered = K * sample + K_1 * y_1; - x_1 = sample; - y_1 = filtered; - } - - public static double GetK(double dt, double fc) - { - double num = Math.PI * 2.0 * dt * fc; - return num / (num + 1.0); - } - } +using System; + +namespace MyNes.Core; + +internal class SoundLowPassFilter +{ + private double K; + + private double K_1; + + private double y; + + private double y_1; + + private double x; + + private double x_1; + + public SoundLowPassFilter(double k) + { + K = k; + K_1 = 1.0 - k; + } + + public void Reset(double k) + { + y = (y_1 = (x = (x_1 = 0.0))); + K = k; + K_1 = 1.0 - k; + } + + public void DoFiltering(double sample, out double filtered) + { + filtered = K * sample + K_1 * y_1; + x_1 = sample; + y_1 = filtered; + } + + public static double GetK(double dt, double fc) + { + double num = Math.PI * 2.0 * dt * fc; + return num / (num + 1.0); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/StateHandler.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/StateHandler.cs index 656a200..5f73a19 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/StateHandler.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/StateHandler.cs @@ -1,197 +1,193 @@ -using System; -using System.IO; -using System.Text; - -namespace MyNes.Core -{ - public class StateHandler - { - public static int Slot = 0; - - internal static string StateFolder = "States"; - - private const byte state_version = 7; - - private static bool IsSavingState = false; - - private static bool IsLoadingState = false; - - public static void SaveState(string fileName, bool saveImage) - { - if (!NesEmu.ON) - { - Tracer.WriteError("Can't save state, emu is off."); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error1, instant: false); - return; - } - if (!File.Exists(NesEmu.CurrentFilePath)) - { - Tracer.WriteError("Can't save state, no rom file is loaded."); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error2, instant: false); - return; - } - if (IsLoadingState) - { - Tracer.WriteError("Can't save state while loading a state !"); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error3, instant: false); - return; - } - if (IsSavingState) - { - Tracer.WriteError("Already saving state !!"); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error4, instant: false); - return; - } - IsSavingState = true; - Stream output = new MemoryStream(); - BinaryWriter bin = new BinaryWriter(output); - bin.Write(Encoding.ASCII.GetBytes("MNS")); - bin.Write((byte)7); - for (int i = 0; i < NesEmu.SHA1.Length; i += 2) - { - string value = NesEmu.SHA1.Substring(i, 2).ToUpper(); - bin.Write(Convert.ToByte(value, 16)); - } - NesEmu.WriteStateData(ref bin); - byte[] outData = new byte[0]; - ZlipWrapper.CompressData(((MemoryStream)bin.BaseStream).GetBuffer(), out outData); - Stream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write); - stream.Write(outData, 0, outData.Length); - MyNesMain.VideoProvider.TakeSnapshotAs(fileName.Replace(".mns", ".jpg"), ".jpg"); - bin.Flush(); - bin.Close(); - stream.Flush(); - stream.Close(); - IsSavingState = false; - Tracer.WriteInformation("State saved at slot " + Slot); - MyNesMain.VideoProvider.WriteInfoNotification(MNInterfaceLanguage.Message_Info1 + " " + Slot, instant: false); - } - - public static void SaveState(int Slot) - { - if (StateFolder == "States") - { - StateFolder = Path.Combine(MyNesMain.WorkingFolder, "States"); - } - Directory.CreateDirectory(StateFolder); - string fileName = Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + Slot + ".mns"; - SaveState(fileName, saveImage: false); - } - - public static void SaveState() - { - SaveState(Slot); - } - - public static void LoadState() - { - LoadState(Slot); - } - - public static void LoadState(string fileName) - { - if (!NesEmu.ON) - { - Tracer.WriteError("Can't load state, emu is off."); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error5, instant: false); - return; - } - if (!File.Exists(NesEmu.CurrentFilePath)) - { - Tracer.WriteError("Can't load state, no rom file is loaded."); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error6, instant: false); - return; - } - if (IsSavingState) - { - Tracer.WriteError("Can't load state while saving a state !"); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error7, instant: false); - return; - } - if (IsLoadingState) - { - Tracer.WriteError("Already loading state !!"); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error8, instant: false); - return; - } - if (!File.Exists(fileName)) - { - Tracer.WriteError("No state found in slot " + Slot); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error9 + " " + Slot, instant: false); - return; - } - IsLoadingState = true; - Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read); - byte[] array = new byte[stream.Length]; - byte[] outData = new byte[0]; - stream.Read(array, 0, array.Length); - stream.Close(); - ZlipWrapper.DecompressData(array, out outData); - BinaryReader bin = new BinaryReader(new MemoryStream(outData)); - byte[] array2 = new byte[3]; - bin.Read(array2, 0, array2.Length); - if (Encoding.ASCII.GetString(array2) != "MNS") - { - Tracer.WriteError("Unable load state at slot " + Slot + "; Not My Nes State File !"); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error11, instant: false); - IsLoadingState = false; - return; - } - if (bin.ReadByte() != 7) - { - Tracer.WriteError("Unable load state at slot " + Slot + "; Not compatible state file version !"); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error12, instant: false); - IsLoadingState = false; - return; - } - string text = ""; - for (int i = 0; i < NesEmu.SHA1.Length; i += 2) - { - text += bin.ReadByte().ToString("X2"); - } - if (text.ToLower() != NesEmu.SHA1.ToLower()) - { - Tracer.WriteError("Unable load state at slot " + Slot + "; This state file is not for this game; not same SHA1 !"); - MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error13, instant: false); - IsLoadingState = false; - } - else - { - NesEmu.ReadStateData(ref bin); - bin.Close(); - IsLoadingState = false; - Tracer.WriteInformation("State loaded from slot " + Slot); - MyNesMain.VideoProvider.WriteInfoNotification(MNInterfaceLanguage.Message_Info2 + " " + Slot, instant: false); - } - } - - public static void LoadState(int Slot) - { - if (StateFolder == "States") - { - StateFolder = Path.Combine(MyNesMain.WorkingFolder, "States"); - } - Directory.CreateDirectory(StateFolder); - string fileName = Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + Slot + ".mns"; - LoadState(fileName); - } - - public static string GetStateFile(int slot) - { - if (File.Exists(NesEmu.CurrentFilePath)) - { - return Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + slot + ".mns"; - } - return ""; - } - - public static string GetStateImageFile(int slot) - { - if (File.Exists(NesEmu.CurrentFilePath)) - { - return Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + slot + ".jpg"; - } - return ""; - } - } +using System; +using System.IO; +using System.Text; + +namespace MyNes.Core; + +public class StateHandler +{ + public static int Slot = 0; + + internal static string StateFolder = "States"; + + private const byte state_version = 7; + + private static bool IsSavingState = false; + + private static bool IsLoadingState = false; + + public static void SaveState(string fileName, bool saveImage) + { + if (!NesEmu.ON) + { + Tracer.WriteError("Can't save state, emu is off."); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error1, instant: false); + return; + } + if (!File.Exists(NesEmu.CurrentFilePath)) + { + Tracer.WriteError("Can't save state, no rom file is loaded."); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error2, instant: false); + return; + } + if (IsLoadingState) + { + Tracer.WriteError("Can't save state while loading a state !"); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error3, instant: false); + return; + } + if (IsSavingState) + { + Tracer.WriteError("Already saving state !!"); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error4, instant: false); + return; + } + IsSavingState = true; + BinaryWriter bin = new BinaryWriter(new MemoryStream()); + bin.Write(Encoding.ASCII.GetBytes("MNS")); + bin.Write((byte)7); + for (int i = 0; i < NesEmu.SHA1.Length; i += 2) + { + string value = NesEmu.SHA1.Substring(i, 2).ToUpper(); + bin.Write(Convert.ToByte(value, 16)); + } + NesEmu.WriteStateData(ref bin); + byte[] outData = new byte[0]; + ZlipWrapper.CompressData(((MemoryStream)bin.BaseStream).GetBuffer(), out outData); + FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write); + fileStream.Write(outData, 0, outData.Length); + MyNesMain.VideoProvider.TakeSnapshotAs(fileName.Replace(".mns", ".jpg"), ".jpg"); + bin.Flush(); + bin.Close(); + fileStream.Flush(); + fileStream.Close(); + IsSavingState = false; + Tracer.WriteInformation("State saved at slot " + Slot); + MyNesMain.VideoProvider.WriteInfoNotification(MNInterfaceLanguage.Message_Info1 + " " + Slot, instant: false); + } + + public static void SaveState(int Slot) + { + if (StateFolder == "States") + { + StateFolder = Path.Combine(MyNesMain.WorkingFolder, "States"); + } + Directory.CreateDirectory(StateFolder); + SaveState(Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + Slot + ".mns", saveImage: false); + } + + public static void SaveState() + { + SaveState(Slot); + } + + public static void LoadState() + { + LoadState(Slot); + } + + public static void LoadState(string fileName) + { + if (!NesEmu.ON) + { + Tracer.WriteError("Can't load state, emu is off."); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error5, instant: false); + return; + } + if (!File.Exists(NesEmu.CurrentFilePath)) + { + Tracer.WriteError("Can't load state, no rom file is loaded."); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error6, instant: false); + return; + } + if (IsSavingState) + { + Tracer.WriteError("Can't load state while saving a state !"); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error7, instant: false); + return; + } + if (IsLoadingState) + { + Tracer.WriteError("Already loading state !!"); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error8, instant: false); + return; + } + if (!File.Exists(fileName)) + { + Tracer.WriteError("No state found in slot " + Slot); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error9 + " " + Slot, instant: false); + return; + } + IsLoadingState = true; + FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); + byte[] array = new byte[fileStream.Length]; + byte[] outData = new byte[0]; + fileStream.Read(array, 0, array.Length); + fileStream.Close(); + ZlipWrapper.DecompressData(array, out outData); + BinaryReader bin = new BinaryReader(new MemoryStream(outData)); + byte[] array2 = new byte[3]; + bin.Read(array2, 0, array2.Length); + if (Encoding.ASCII.GetString(array2) != "MNS") + { + Tracer.WriteError("Unable load state at slot " + Slot + "; Not My Nes State File !"); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error11, instant: false); + IsLoadingState = false; + return; + } + if (bin.ReadByte() != 7) + { + Tracer.WriteError("Unable load state at slot " + Slot + "; Not compatible state file version !"); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error12, instant: false); + IsLoadingState = false; + return; + } + string text = ""; + for (int i = 0; i < NesEmu.SHA1.Length; i += 2) + { + text += bin.ReadByte().ToString("X2"); + } + if (text.ToLower() != NesEmu.SHA1.ToLower()) + { + Tracer.WriteError("Unable load state at slot " + Slot + "; This state file is not for this game; not same SHA1 !"); + MyNesMain.VideoProvider.WriteErrorNotification(MNInterfaceLanguage.Message_Error10 + " " + Slot + "; " + MNInterfaceLanguage.Message_Error13, instant: false); + IsLoadingState = false; + } + else + { + NesEmu.ReadStateData(ref bin); + bin.Close(); + IsLoadingState = false; + Tracer.WriteInformation("State loaded from slot " + Slot); + MyNesMain.VideoProvider.WriteInfoNotification(MNInterfaceLanguage.Message_Info2 + " " + Slot, instant: false); + } + } + + public static void LoadState(int Slot) + { + if (StateFolder == "States") + { + StateFolder = Path.Combine(MyNesMain.WorkingFolder, "States"); + } + Directory.CreateDirectory(StateFolder); + LoadState(Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + Slot + ".mns"); + } + + public static string GetStateFile(int slot) + { + if (File.Exists(NesEmu.CurrentFilePath)) + { + return Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + slot + ".mns"; + } + return ""; + } + + public static string GetStateImageFile(int slot) + { + if (File.Exists(NesEmu.CurrentFilePath)) + { + return Path.Combine(StateFolder, Path.GetFileNameWithoutExtension(NesEmu.CurrentFilePath)) + "_" + slot + ".jpg"; + } + return ""; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Sunsoft5BChnl.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Sunsoft5BChnl.cs index 1f269db..8b28e91 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Sunsoft5BChnl.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Sunsoft5BChnl.cs @@ -1,95 +1,94 @@ -using System.IO; - -namespace MyNes.Core -{ - internal class Sunsoft5BChnl - { - internal bool Enabled; - - internal byte Volume; - - private int dutyStep = 0; - - private int freqTimer; - - private int frequency; - - private int cycles; - - internal int output; - - internal bool Outputable; - - internal void HardReset() - { - } - - internal void SoftReset() - { - } - - internal void Write0(ref byte data) - { - frequency = (frequency & 0xF00) | data; - freqTimer = (frequency + 1) * 2; - } - - internal void Write1(ref byte data) - { - frequency = (frequency & 0xFF) | ((data & 0xF) << 8); - freqTimer = (frequency + 1) * 2; - } - - internal void ClockSingle() - { - if (--cycles > 0) - { - return; - } - cycles = freqTimer; - dutyStep = (dutyStep + 1) & 0x1F; - if (dutyStep <= 15) - { - if (Enabled) - { - if (Outputable) - { - output = Volume; - } - else - { - output = 0; - } - } - else - { - output = 0; - } - } - else - { - output = 0; - } - } - - internal void SaveState(ref BinaryWriter stream) - { - stream.Write(Enabled); - stream.Write(Volume); - stream.Write(dutyStep); - stream.Write(freqTimer); - stream.Write(frequency); - stream.Write(cycles); - } - - internal void LoadState(ref BinaryReader stream) - { - Enabled = stream.ReadBoolean(); - Volume = stream.ReadByte(); - dutyStep = stream.ReadInt32(); - freqTimer = stream.ReadInt32(); - frequency = stream.ReadInt32(); - cycles = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +internal class Sunsoft5BChnl +{ + internal bool Enabled; + + internal byte Volume; + + private int dutyStep; + + private int freqTimer; + + private int frequency; + + private int cycles; + + internal int output; + + internal bool Outputable; + + internal void HardReset() + { + } + + internal void SoftReset() + { + } + + internal void Write0(ref byte data) + { + frequency = (frequency & 0xF00) | data; + freqTimer = (frequency + 1) * 2; + } + + internal void Write1(ref byte data) + { + frequency = (frequency & 0xFF) | ((data & 0xF) << 8); + freqTimer = (frequency + 1) * 2; + } + + internal void ClockSingle() + { + if (--cycles > 0) + { + return; + } + cycles = freqTimer; + dutyStep = (dutyStep + 1) & 0x1F; + if (dutyStep <= 15) + { + if (Enabled) + { + if (Outputable) + { + output = Volume; + } + else + { + output = 0; + } + } + else + { + output = 0; + } + } + else + { + output = 0; + } + } + + internal void SaveState(ref BinaryWriter stream) + { + stream.Write(Enabled); + stream.Write(Volume); + stream.Write(dutyStep); + stream.Write(freqTimer); + stream.Write(frequency); + stream.Write(cycles); + } + + internal void LoadState(ref BinaryReader stream) + { + Enabled = stream.ReadBoolean(); + Volume = stream.ReadByte(); + dutyStep = stream.ReadInt32(); + freqTimer = stream.ReadInt32(); + frequency = stream.ReadInt32(); + cycles = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/TogglePause.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/TogglePause.cs index b10ad38..0e71d90 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/TogglePause.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/TogglePause.cs @@ -1,4 +1,3 @@ -namespace MyNes.Core -{ - internal delegate void TogglePause(bool paused); -} +namespace MyNes.Core; + +internal delegate void TogglePause(bool paused); diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/Tracer.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/Tracer.cs index 1d13039..f1cf94e 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/Tracer.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/Tracer.cs @@ -1,59 +1,64 @@ -using System; - -namespace MyNes.Core -{ - public sealed class Tracer - { - public static event EventHandler EventRaised; - - public static void WriteLine(string message) - { - Tracer.EventRaised?.Invoke(null, new TracerEventArgs(message, TracerStatus.Normal)); - } - - public static void WriteLine(string message, string category) - { - Tracer.EventRaised?.Invoke(null, new TracerEventArgs($"{category}: {message}", TracerStatus.Normal)); - } - - public static void WriteLine(string message, TracerStatus status) - { - Tracer.EventRaised?.Invoke(null, new TracerEventArgs(message, status)); - } - - public static void WriteLine(string message, string category, TracerStatus status) - { - Tracer.EventRaised?.Invoke(null, new TracerEventArgs($"{category}: {message}", status)); - } - - public static void WriteError(string message) - { - WriteLine(message, TracerStatus.Error); - } - - public static void WriteError(string message, string category) - { - WriteLine(message, category, TracerStatus.Error); - } - - public static void WriteWarning(string message) - { - WriteLine(message, TracerStatus.Warning); - } - - public static void WriteWarning(string message, string category) - { - WriteLine(message, category, TracerStatus.Warning); - } - - public static void WriteInformation(string message) - { - WriteLine(message, TracerStatus.Infromation); - } - - public static void WriteInformation(string message, string category) - { - WriteLine(message, category, TracerStatus.Infromation); - } - } +#define TRACE +using System; +using System.Diagnostics; + +namespace MyNes.Core; + +public sealed class Tracer +{ + public static event EventHandler EventRaised; + + public static void WriteLine(string message) + { + Tracer.EventRaised?.Invoke(null, new TracerEventArgs(message, TracerStatus.Normal)); + Trace.WriteLine(message); + } + + public static void WriteLine(string message, string category) + { + Tracer.EventRaised?.Invoke(null, new TracerEventArgs($"{category}: {message}", TracerStatus.Normal)); + Trace.WriteLine($"{category}: {message}"); + } + + public static void WriteLine(string message, TracerStatus status) + { + Tracer.EventRaised?.Invoke(null, new TracerEventArgs(message, status)); + Trace.WriteLine(message); + } + + public static void WriteLine(string message, string category, TracerStatus status) + { + Tracer.EventRaised?.Invoke(null, new TracerEventArgs($"{category}: {message}", status)); + Trace.WriteLine($"{category}: {message}"); + } + + public static void WriteError(string message) + { + WriteLine(message, TracerStatus.Error); + } + + public static void WriteError(string message, string category) + { + WriteLine(message, category, TracerStatus.Error); + } + + public static void WriteWarning(string message) + { + WriteLine(message, TracerStatus.Warning); + } + + public static void WriteWarning(string message, string category) + { + WriteLine(message, category, TracerStatus.Warning); + } + + public static void WriteInformation(string message) + { + WriteLine(message, TracerStatus.Infromation); + } + + public static void WriteInformation(string message, string category) + { + WriteLine(message, category, TracerStatus.Infromation); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/TracerEventArgs.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/TracerEventArgs.cs index e7f3ff6..084dd8c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/TracerEventArgs.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/TracerEventArgs.cs @@ -1,17 +1,16 @@ -using System; - -namespace MyNes.Core -{ - public class TracerEventArgs : EventArgs - { - public string Message { get; private set; } - - public TracerStatus Status { get; private set; } - - public TracerEventArgs(string message, TracerStatus status) - { - Message = message; - Status = status; - } - } +using System; + +namespace MyNes.Core; + +public class TracerEventArgs : EventArgs +{ + public string Message { get; private set; } + + public TracerStatus Status { get; private set; } + + public TracerEventArgs(string message, TracerStatus status) + { + Message = message; + Status = status; + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/TracerStatus.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/TracerStatus.cs index d099294..9837d79 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/TracerStatus.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/TracerStatus.cs @@ -1,10 +1,9 @@ -namespace MyNes.Core -{ - public enum TracerStatus - { - Normal, - Error, - Warning, - Infromation - } +namespace MyNes.Core; + +public enum TracerStatus +{ + Normal, + Error, + Warning, + Infromation } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Pulse.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Pulse.cs index 789ea01..8d8c5ce 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Pulse.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Pulse.cs @@ -1,116 +1,115 @@ -using System.IO; - -namespace MyNes.Core -{ - internal class VRC6Pulse - { - private int dutyForm; - - private int dutyStep; - - private bool enabled = true; - - internal bool Outputable; - - private bool mode = false; - - private byte volume; - - private int freqTimer; - - private int frequency; - - private int cycles; - - internal int output; - - internal void HardReset() - { - dutyForm = 0; - dutyStep = 15; - enabled = true; - mode = false; - output = 0; - } - - internal void Write0(ref byte data) - { - mode = (data & 0x80) == 128; - dutyForm = (data & 0x70) >> 4; - volume = (byte)(data & 0xFu); - } - - internal void Write1(ref byte data) - { - frequency = (frequency & 0xF00) | data; - } - - internal void Write2(ref byte data) - { - frequency = (frequency & 0xFF) | ((data & 0xF) << 8); - enabled = (data & 0x80) == 128; - } - - internal void ClockSingle() - { - if (--cycles > 0) - { - return; - } - cycles = (frequency << 1) + 2; - if (!enabled) - { - return; - } - if (mode) - { - output = volume; - return; - } - dutyStep--; - if (dutyStep < 0) - { - dutyStep = 15; - } - if (dutyStep <= dutyForm) - { - if (Outputable) - { - output = volume; - } - else - { - output = 0; - } - } - else - { - output = 0; - } - } - - internal void SaveState(ref BinaryWriter stream) - { - stream.Write(dutyForm); - stream.Write(dutyStep); - stream.Write(enabled); - stream.Write(mode); - stream.Write(volume); - stream.Write(freqTimer); - stream.Write(frequency); - stream.Write(cycles); - } - - internal void LoadState(ref BinaryReader stream) - { - dutyForm = stream.ReadInt32(); - dutyStep = stream.ReadInt32(); - enabled = stream.ReadBoolean(); - mode = stream.ReadBoolean(); - volume = stream.ReadByte(); - freqTimer = stream.ReadInt32(); - frequency = stream.ReadInt32(); - cycles = stream.ReadInt32(); - } - } +using System.IO; + +namespace MyNes.Core; + +internal class VRC6Pulse +{ + private int dutyForm; + + private int dutyStep; + + private bool enabled = true; + + internal bool Outputable; + + private bool mode; + + private byte volume; + + private int freqTimer; + + private int frequency; + + private int cycles; + + internal int output; + + internal void HardReset() + { + dutyForm = 0; + dutyStep = 15; + enabled = true; + mode = false; + output = 0; + } + + internal void Write0(ref byte data) + { + mode = (data & 0x80) == 128; + dutyForm = (data & 0x70) >> 4; + volume = (byte)(data & 0xFu); + } + + internal void Write1(ref byte data) + { + frequency = (frequency & 0xF00) | data; + } + + internal void Write2(ref byte data) + { + frequency = (frequency & 0xFF) | ((data & 0xF) << 8); + enabled = (data & 0x80) == 128; + } + + internal void ClockSingle() + { + if (--cycles > 0) + { + return; + } + cycles = (frequency << 1) + 2; + if (!enabled) + { + return; + } + if (mode) + { + output = volume; + return; + } + dutyStep--; + if (dutyStep < 0) + { + dutyStep = 15; + } + if (dutyStep <= dutyForm) + { + if (Outputable) + { + output = volume; + } + else + { + output = 0; + } + } + else + { + output = 0; + } + } + + internal void SaveState(ref BinaryWriter stream) + { + stream.Write(dutyForm); + stream.Write(dutyStep); + stream.Write(enabled); + stream.Write(mode); + stream.Write(volume); + stream.Write(freqTimer); + stream.Write(frequency); + stream.Write(cycles); + } + + internal void LoadState(ref BinaryReader stream) + { + dutyForm = stream.ReadInt32(); + dutyStep = stream.ReadInt32(); + enabled = stream.ReadBoolean(); + mode = stream.ReadBoolean(); + volume = stream.ReadByte(); + freqTimer = stream.ReadInt32(); + frequency = stream.ReadInt32(); + cycles = stream.ReadInt32(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Sawtooth.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Sawtooth.cs index 23b2e56..4f05471 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Sawtooth.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/VRC6Sawtooth.cs @@ -1,114 +1,113 @@ -using System.IO; - -namespace MyNes.Core -{ - internal class VRC6Sawtooth - { - private byte AccumRate; - - private int accumClock; - - private byte accumulationRegister; - - private int frequency; - - private int freqTimer; - - private int cycles; - - private bool enabled; - - internal int output; - - internal bool Outputable; - - internal void HardReset() - { - } - - private void UpdateFrequency() - { - freqTimer = (frequency + 1) * 2; - } - - internal void Write0(ref byte data) - { - AccumRate = (byte)(data & 0x3Fu); - } - - internal void Write1(ref byte data) - { - frequency = (frequency & 0xF00) | data; - UpdateFrequency(); - } - - internal void Write2(ref byte data) - { - frequency = (frequency & 0xFF) | ((data & 0xF) << 8); - enabled = (data & 0x80) == 128; - UpdateFrequency(); - } - - internal void ClockSingle() - { - if (--cycles > 0) - { - return; - } - cycles = freqTimer; - if (enabled) - { - accumClock++; - switch (++accumClock) - { - case 2: - case 4: - case 6: - case 8: - case 10: - case 12: - accumulationRegister += AccumRate; - break; - case 14: - accumulationRegister = 0; - accumClock = 0; - break; - } - if (Outputable) - { - output = (accumulationRegister >> 3) & 0x1F; - } - else - { - output = 0; - } - } - else - { - output = 0; - } - } - - internal void SaveState(ref BinaryWriter stream) - { - stream.Write(AccumRate); - stream.Write(accumClock); - stream.Write(accumulationRegister); - stream.Write(frequency); - stream.Write(freqTimer); - stream.Write(cycles); - stream.Write(enabled); - } - - internal void LoadState(ref BinaryReader stream) - { - AccumRate = stream.ReadByte(); - accumClock = stream.ReadInt32(); - accumulationRegister = stream.ReadByte(); - frequency = stream.ReadInt32(); - freqTimer = stream.ReadInt32(); - cycles = stream.ReadInt32(); - enabled = stream.ReadBoolean(); - } - } +using System.IO; + +namespace MyNes.Core; + +internal class VRC6Sawtooth +{ + private byte AccumRate; + + private int accumClock; + + private byte accumulationRegister; + + private int frequency; + + private int freqTimer; + + private int cycles; + + private bool enabled; + + internal int output; + + internal bool Outputable; + + internal void HardReset() + { + } + + private void UpdateFrequency() + { + freqTimer = (frequency + 1) * 2; + } + + internal void Write0(ref byte data) + { + AccumRate = (byte)(data & 0x3Fu); + } + + internal void Write1(ref byte data) + { + frequency = (frequency & 0xF00) | data; + UpdateFrequency(); + } + + internal void Write2(ref byte data) + { + frequency = (frequency & 0xFF) | ((data & 0xF) << 8); + enabled = (data & 0x80) == 128; + UpdateFrequency(); + } + + internal void ClockSingle() + { + if (--cycles > 0) + { + return; + } + cycles = freqTimer; + if (enabled) + { + accumClock++; + switch (++accumClock) + { + case 2: + case 4: + case 6: + case 8: + case 10: + case 12: + accumulationRegister += AccumRate; + break; + case 14: + accumulationRegister = 0; + accumClock = 0; + break; + } + if (Outputable) + { + output = (accumulationRegister >> 3) & 0x1F; + } + else + { + output = 0; + } + } + else + { + output = 0; + } + } + + internal void SaveState(ref BinaryWriter stream) + { + stream.Write(AccumRate); + stream.Write(accumClock); + stream.Write(accumulationRegister); + stream.Write(frequency); + stream.Write(freqTimer); + stream.Write(cycles); + stream.Write(enabled); + } + + internal void LoadState(ref BinaryReader stream) + { + AccumRate = stream.ReadByte(); + accumClock = stream.ReadInt32(); + accumulationRegister = stream.ReadByte(); + frequency = stream.ReadInt32(); + freqTimer = stream.ReadInt32(); + cycles = stream.ReadInt32(); + enabled = stream.ReadBoolean(); + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/WaveRecorder.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/WaveRecorder.cs index e90b79f..cf8f66d 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/WaveRecorder.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/WaveRecorder.cs @@ -1,302 +1,301 @@ -using System; -using System.IO; -using System.Text; - -namespace MyNes.Core -{ - public class WaveRecorder - { - private string _fileName; - - private Stream STR; - - private bool _IsRecording = false; - - private int SIZE = 0; - - private int NoOfSamples = 0; - - private int _Time = 0; - - private int TimeSamples = 0; - - private short channels; - - private short bitsPerSample; - - private int Frequency; - - public int Time => _Time; - - public bool IsRecording => _IsRecording; - - public void Record(string FilePath, short channels, short bitsPerSample, int Frequency) - { - _fileName = FilePath; - this.channels = channels; - this.bitsPerSample = bitsPerSample; - this.Frequency = Frequency; - _Time = 0; - STR = new FileStream(FilePath, FileMode.Create); - ASCIIEncoding aSCIIEncoding = new ASCIIEncoding(); - STR.Write(aSCIIEncoding.GetBytes("RIFF"), 0, 4); - STR.WriteByte(0); - STR.WriteByte(0); - STR.WriteByte(0); - STR.WriteByte(0); - STR.Write(aSCIIEncoding.GetBytes("WAVE"), 0, 4); - STR.Write(aSCIIEncoding.GetBytes("fmt "), 0, 4); - STR.WriteByte(16); - STR.WriteByte(0); - STR.WriteByte(0); - STR.WriteByte(0); - STR.WriteByte(1); - STR.WriteByte(0); - STR.WriteByte((byte)((uint)channels & 0xFFu)); - STR.WriteByte((byte)((channels & 0xFF00) >> 8)); - STR.WriteByte((byte)((uint)Frequency & 0xFFu)); - STR.WriteByte((byte)((Frequency & 0xFF00) >> 8)); - STR.WriteByte((byte)((Frequency & 0xFF0000) >> 16)); - STR.WriteByte((byte)((Frequency & 0xFF000000u) >> 24)); - int num = Frequency * channels * (bitsPerSample / 8); - STR.WriteByte((byte)((uint)num & 0xFFu)); - STR.WriteByte((byte)((num & 0xFF00) >> 8)); - STR.WriteByte((byte)((num & 0xFF0000) >> 16)); - STR.WriteByte((byte)((num & 0xFF000000u) >> 24)); - short num2 = (short)(channels * (bitsPerSample / 8)); - STR.WriteByte((byte)((uint)num2 & 0xFFu)); - STR.WriteByte((byte)((num2 & 0xFF00) >> 8)); - STR.WriteByte((byte)((uint)bitsPerSample & 0xFFu)); - STR.WriteByte((byte)((bitsPerSample & 0xFF00) >> 8)); - STR.Write(aSCIIEncoding.GetBytes("data"), 0, 4); - STR.WriteByte(0); - STR.WriteByte(0); - STR.WriteByte(0); - STR.WriteByte(0); - _IsRecording = true; - } - - public void AddBuffer(ref byte[] buffer) - { - for (int i = 0; i < buffer.Length; i++) - { - switch (channels) - { - case 1: - switch (bitsPerSample) - { - case 8: - STR.WriteByte(buffer[i]); - NoOfSamples++; - TimeSamples++; - if (TimeSamples >= Frequency) - { - _Time++; - TimeSamples = 0; - } - break; - case 16: - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - NoOfSamples++; - TimeSamples++; - if (TimeSamples >= Frequency) - { - _Time++; - TimeSamples = 0; - } - break; - case 32: - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - NoOfSamples++; - TimeSamples++; - if (TimeSamples >= Frequency) - { - _Time++; - TimeSamples = 0; - } - break; - } - break; - case 2: - switch (bitsPerSample) - { - case 8: - STR.WriteByte(buffer[i]); - STR.WriteByte(buffer[i]); - NoOfSamples++; - TimeSamples++; - if (TimeSamples >= Frequency) - { - _Time++; - TimeSamples = 0; - } - break; - case 16: - STR.WriteByte(buffer[i]); - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - STR.WriteByte(buffer[i]); - NoOfSamples++; - TimeSamples++; - if (TimeSamples >= Frequency) - { - _Time++; - TimeSamples = 0; - } - break; - case 32: - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - STR.WriteByte(buffer[i]); - i++; - STR.WriteByte(buffer[i]); - NoOfSamples++; - TimeSamples++; - if (TimeSamples >= Frequency) - { - _Time++; - TimeSamples = 0; - } - break; - } - break; - } - } - } - - public void AddSample(int Sample) - { - if (!_IsRecording) - { - return; - } - switch (channels) - { - case 1: - switch (bitsPerSample) - { - case 8: - AddSample_mono_08(Sample); - break; - case 16: - AddSample_mono_16(Sample); - break; - case 32: - AddSample_mono_32(Sample); - break; - } - break; - case 2: - switch (bitsPerSample) - { - case 8: - AddSample_stereo_08(Sample); - break; - case 16: - AddSample_stereo_16(Sample); - break; - case 32: - AddSample_stereo_32(Sample); - break; - } - break; - } - NoOfSamples++; - TimeSamples++; - if (TimeSamples >= Frequency) - { - _Time++; - TimeSamples = 0; - } - } - - private void AddSample_mono_08(int Sample) - { - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - } - - private void AddSample_mono_16(int Sample) - { - STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - } - - private void AddSample_mono_32(int Sample) - { - STR.WriteByte((byte)((Sample & 0xFF000000u) >> 24)); - STR.WriteByte((byte)((Sample & 0xFF0000) >> 16)); - STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - } - - private void AddSample_stereo_08(int Sample) - { - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - } - - private void AddSample_stereo_16(int Sample) - { - STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - } - - private void AddSample_stereo_32(int Sample) - { - STR.WriteByte((byte)((Sample & 0xFF000000u) >> 24)); - STR.WriteByte((byte)((Sample & 0xFF0000) >> 16)); - STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - STR.WriteByte((byte)((Sample & 0xFF000000u) >> 24)); - STR.WriteByte((byte)((Sample & 0xFF0000) >> 16)); - STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); - STR.WriteByte((byte)((uint)Sample & 0xFFu)); - } - - public void Stop() - { - if (_IsRecording & (STR != null)) - { - NoOfSamples *= channels * (bitsPerSample / 8); - SIZE = NoOfSamples + 36; - byte[] array = new byte[4]; - byte[] array2 = new byte[4]; - array = BitConverter.GetBytes(SIZE); - if (!BitConverter.IsLittleEndian) - { - Array.Reverse(array); - } - array2 = BitConverter.GetBytes(NoOfSamples); - if (!BitConverter.IsLittleEndian) - { - Array.Reverse(array2); - } - _IsRecording = false; - STR.Position = 4L; - STR.Write(array, 0, 4); - STR.Position = 40L; - STR.Write(array2, 0, 4); - STR.Close(); - MyNesMain.VideoProvider.WriteInfoNotification("Sound file saved at " + Path.GetFileName(_fileName), instant: false); - } - } - } +using System; +using System.IO; +using System.Text; + +namespace MyNes.Core; + +public class WaveRecorder +{ + private string _fileName; + + private Stream STR; + + private bool _IsRecording; + + private int SIZE; + + private int NoOfSamples; + + private int _Time; + + private int TimeSamples; + + private short channels; + + private short bitsPerSample; + + private int Frequency; + + public int Time => _Time; + + public bool IsRecording => _IsRecording; + + public void Record(string FilePath, short channels, short bitsPerSample, int Frequency) + { + _fileName = FilePath; + this.channels = channels; + this.bitsPerSample = bitsPerSample; + this.Frequency = Frequency; + _Time = 0; + STR = new FileStream(FilePath, FileMode.Create); + ASCIIEncoding aSCIIEncoding = new ASCIIEncoding(); + STR.Write(aSCIIEncoding.GetBytes("RIFF"), 0, 4); + STR.WriteByte(0); + STR.WriteByte(0); + STR.WriteByte(0); + STR.WriteByte(0); + STR.Write(aSCIIEncoding.GetBytes("WAVE"), 0, 4); + STR.Write(aSCIIEncoding.GetBytes("fmt "), 0, 4); + STR.WriteByte(16); + STR.WriteByte(0); + STR.WriteByte(0); + STR.WriteByte(0); + STR.WriteByte(1); + STR.WriteByte(0); + STR.WriteByte((byte)((uint)channels & 0xFFu)); + STR.WriteByte((byte)((channels & 0xFF00) >> 8)); + STR.WriteByte((byte)((uint)Frequency & 0xFFu)); + STR.WriteByte((byte)((Frequency & 0xFF00) >> 8)); + STR.WriteByte((byte)((Frequency & 0xFF0000) >> 16)); + STR.WriteByte((byte)((Frequency & 0xFF000000u) >> 24)); + int num = Frequency * channels * (bitsPerSample / 8); + STR.WriteByte((byte)((uint)num & 0xFFu)); + STR.WriteByte((byte)((num & 0xFF00) >> 8)); + STR.WriteByte((byte)((num & 0xFF0000) >> 16)); + STR.WriteByte((byte)((num & 0xFF000000u) >> 24)); + short num2 = (short)(channels * (bitsPerSample / 8)); + STR.WriteByte((byte)((uint)num2 & 0xFFu)); + STR.WriteByte((byte)((num2 & 0xFF00) >> 8)); + STR.WriteByte((byte)((uint)bitsPerSample & 0xFFu)); + STR.WriteByte((byte)((bitsPerSample & 0xFF00) >> 8)); + STR.Write(aSCIIEncoding.GetBytes("data"), 0, 4); + STR.WriteByte(0); + STR.WriteByte(0); + STR.WriteByte(0); + STR.WriteByte(0); + _IsRecording = true; + } + + public void AddBuffer(ref byte[] buffer) + { + for (int i = 0; i < buffer.Length; i++) + { + switch (channels) + { + case 1: + switch (bitsPerSample) + { + case 8: + STR.WriteByte(buffer[i]); + NoOfSamples++; + TimeSamples++; + if (TimeSamples >= Frequency) + { + _Time++; + TimeSamples = 0; + } + break; + case 16: + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + NoOfSamples++; + TimeSamples++; + if (TimeSamples >= Frequency) + { + _Time++; + TimeSamples = 0; + } + break; + case 32: + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + NoOfSamples++; + TimeSamples++; + if (TimeSamples >= Frequency) + { + _Time++; + TimeSamples = 0; + } + break; + } + break; + case 2: + switch (bitsPerSample) + { + case 8: + STR.WriteByte(buffer[i]); + STR.WriteByte(buffer[i]); + NoOfSamples++; + TimeSamples++; + if (TimeSamples >= Frequency) + { + _Time++; + TimeSamples = 0; + } + break; + case 16: + STR.WriteByte(buffer[i]); + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + STR.WriteByte(buffer[i]); + NoOfSamples++; + TimeSamples++; + if (TimeSamples >= Frequency) + { + _Time++; + TimeSamples = 0; + } + break; + case 32: + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + STR.WriteByte(buffer[i]); + i++; + STR.WriteByte(buffer[i]); + NoOfSamples++; + TimeSamples++; + if (TimeSamples >= Frequency) + { + _Time++; + TimeSamples = 0; + } + break; + } + break; + } + } + } + + public void AddSample(int Sample) + { + if (!_IsRecording) + { + return; + } + switch (channels) + { + case 1: + switch (bitsPerSample) + { + case 8: + AddSample_mono_08(Sample); + break; + case 16: + AddSample_mono_16(Sample); + break; + case 32: + AddSample_mono_32(Sample); + break; + } + break; + case 2: + switch (bitsPerSample) + { + case 8: + AddSample_stereo_08(Sample); + break; + case 16: + AddSample_stereo_16(Sample); + break; + case 32: + AddSample_stereo_32(Sample); + break; + } + break; + } + NoOfSamples++; + TimeSamples++; + if (TimeSamples >= Frequency) + { + _Time++; + TimeSamples = 0; + } + } + + private void AddSample_mono_08(int Sample) + { + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + } + + private void AddSample_mono_16(int Sample) + { + STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + } + + private void AddSample_mono_32(int Sample) + { + STR.WriteByte((byte)((Sample & 0xFF000000u) >> 24)); + STR.WriteByte((byte)((Sample & 0xFF0000) >> 16)); + STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + } + + private void AddSample_stereo_08(int Sample) + { + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + } + + private void AddSample_stereo_16(int Sample) + { + STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + } + + private void AddSample_stereo_32(int Sample) + { + STR.WriteByte((byte)((Sample & 0xFF000000u) >> 24)); + STR.WriteByte((byte)((Sample & 0xFF0000) >> 16)); + STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + STR.WriteByte((byte)((Sample & 0xFF000000u) >> 24)); + STR.WriteByte((byte)((Sample & 0xFF0000) >> 16)); + STR.WriteByte((byte)((Sample & 0xFF00) >> 8)); + STR.WriteByte((byte)((uint)Sample & 0xFFu)); + } + + public void Stop() + { + if (_IsRecording & (STR != null)) + { + NoOfSamples *= channels * (bitsPerSample / 8); + SIZE = NoOfSamples + 36; + byte[] array = new byte[4]; + byte[] array2 = new byte[4]; + array = BitConverter.GetBytes(SIZE); + if (!BitConverter.IsLittleEndian) + { + Array.Reverse(array); + } + array2 = BitConverter.GetBytes(NoOfSamples); + if (!BitConverter.IsLittleEndian) + { + Array.Reverse(array2); + } + _IsRecording = false; + STR.Position = 4L; + STR.Write(array, 0, 4); + STR.Position = 40L; + STR.Write(array2, 0, 4); + STR.Close(); + MyNesMain.VideoProvider.WriteInfoNotification("Sound file saved at " + Path.GetFileName(_fileName), instant: false); + } + } } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/WithExternalSoundAttribute.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/WithExternalSoundAttribute.cs index 3d5b982..d38eb43 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/WithExternalSoundAttribute.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/WithExternalSoundAttribute.cs @@ -1,8 +1,7 @@ -using System; - -namespace MyNes.Core -{ - internal class WithExternalSoundAttribute : Attribute - { - } +using System; + +namespace MyNes.Core; + +internal class WithExternalSoundAttribute : Attribute +{ } diff --git a/AxibugEmuOnline.Client/Assets/MyNes.Core/ZlipWrapper.cs b/AxibugEmuOnline.Client/Assets/MyNes.Core/ZlipWrapper.cs index 26e02fe..96ae23c 100644 --- a/AxibugEmuOnline.Client/Assets/MyNes.Core/ZlipWrapper.cs +++ b/AxibugEmuOnline.Client/Assets/MyNes.Core/ZlipWrapper.cs @@ -1,39 +1,38 @@ -using System.IO; -using ComponentAce.Compression.Libs.zlib; - -namespace MyNes.Core -{ - internal class ZlipWrapper - { - internal static void CompressData(byte[] inData, out byte[] outData) - { - using MemoryStream memoryStream = new MemoryStream(); - using ZOutputStream zOutputStream = new ZOutputStream(memoryStream, -1); - using Stream input = new MemoryStream(inData); - CopyStream(input, zOutputStream); - zOutputStream.finish(); - outData = memoryStream.ToArray(); - } - - internal static void DecompressData(byte[] inData, out byte[] outData) - { - using MemoryStream memoryStream = new MemoryStream(); - using ZOutputStream zOutputStream = new ZOutputStream(memoryStream); - using Stream input = new MemoryStream(inData); - CopyStream(input, zOutputStream); - zOutputStream.finish(); - outData = memoryStream.ToArray(); - } - - internal static void CopyStream(Stream input, Stream output) - { - byte[] buffer = new byte[2000]; - int count; - while ((count = input.Read(buffer, 0, 2000)) > 0) - { - output.Write(buffer, 0, count); - } - output.Flush(); - } - } +using System.IO; +using ComponentAce.Compression.Libs.zlib; + +namespace MyNes.Core; + +internal class ZlipWrapper +{ + internal static void CompressData(byte[] inData, out byte[] outData) + { + using MemoryStream memoryStream = new MemoryStream(); + using ZOutputStream zOutputStream = new ZOutputStream(memoryStream, -1); + using Stream input = new MemoryStream(inData); + CopyStream(input, zOutputStream); + zOutputStream.finish(); + outData = memoryStream.ToArray(); + } + + internal static void DecompressData(byte[] inData, out byte[] outData) + { + using MemoryStream memoryStream = new MemoryStream(); + using ZOutputStream zOutputStream = new ZOutputStream(memoryStream); + using Stream input = new MemoryStream(inData); + CopyStream(input, zOutputStream); + zOutputStream.finish(); + outData = memoryStream.ToArray(); + } + + internal static void CopyStream(Stream input, Stream output) + { + byte[] buffer = new byte[2000]; + int count; + while ((count = input.Read(buffer, 0, 2000)) > 0) + { + output.Write(buffer, 0, count); + } + output.Flush(); + } }