From 0e25114e9cd4d3340ae448898b94e05b91520b6e Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Wed, 24 Jul 2024 14:27:10 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E8=BF=AD=E4=BB=A3=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets/Scene/EmuTest.unity | 43 ++ .../Script/AxibugEmuOnline.Client.asmdef | 2 +- .../Assets/Script/NesEmulator.meta | 8 + .../Assets/Script/NesEmulator/CoreDebuger.cs | 20 + .../Script/NesEmulator/CoreDebuger.cs.meta | 11 + .../Script/NesEmulator/CoreSupporter.cs | 49 ++ .../Script/NesEmulator/CoreSupporter.cs.meta | 11 + .../Assets/Script/NesEmulator/NesEmulator.cs | 21 + .../Script/NesEmulator/NesEmulator.cs.meta | 11 + .../Assets/StreamingAssets.meta | 8 + .../Assets/StreamingAssets/Disksys.rom | Bin 0 -> 8192 bytes .../Disksys.rom.meta} | 4 +- .../{Resources => StreamingAssets}/Roms.meta | 0 .../Roms/Kirby.nes} | Bin .../Roms/Kirby.nes.meta} | 4 +- .../Roms/Mario.nes} | Bin .../Roms/Mario.nes.meta} | 4 +- .../Roms/tortoise4.nes} | Bin .../StreamingAssets/Roms/tortoise4.nes.meta | 7 + .../Assets/VirtualNes.Core/APU.cs | 2 + .../Assets/VirtualNes.Core/CoreLibs.meta | 8 + .../Assets/VirtualNes.Core/CoreLibs/CRC.cs | 92 ++++ .../VirtualNes.Core/CoreLibs/CRC.cs.meta | 11 + .../VirtualNes.Core/CoreLibs/ROMClasses.cs | 143 ++++++ .../CoreLibs/ROMClasses.cs.meta | 11 + .../VirtualNes.Core/CoreLibs/RomPatch.cs | 426 ++++++++++++++++++ .../VirtualNes.Core/CoreLibs/RomPatch.cs.meta | 11 + .../Assets/VirtualNes.Core/NES.cs | 1 - .../Assets/VirtualNes.Core/ROM.cs | 203 +++++---- .../VirtualNes.Core/Supporter/Supporter.cs | 19 +- 30 files changed, 1021 insertions(+), 109 deletions(-) create mode 100644 AxibugEmuOnline.Client/Assets/Script/NesEmulator.meta create mode 100644 AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs create mode 100644 AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs create mode 100644 AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs create mode 100644 AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/StreamingAssets.meta create mode 100644 AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom rename AxibugEmuOnline.Client/Assets/{Resources/Roms/Kirby.nes.bytes.meta => StreamingAssets/Disksys.rom.meta} (62%) rename AxibugEmuOnline.Client/Assets/{Resources => StreamingAssets}/Roms.meta (100%) rename AxibugEmuOnline.Client/Assets/{Resources/Roms/Kirby.nes.bytes => StreamingAssets/Roms/Kirby.nes} (100%) rename AxibugEmuOnline.Client/Assets/{Resources/Roms/Mario.nes.bytes.meta => StreamingAssets/Roms/Kirby.nes.meta} (62%) rename AxibugEmuOnline.Client/Assets/{Resources/Roms/Mario.nes.bytes => StreamingAssets/Roms/Mario.nes} (100%) rename AxibugEmuOnline.Client/Assets/{Resources/Roms/tortoise4.nes.bytes.meta => StreamingAssets/Roms/Mario.nes.meta} (62%) rename AxibugEmuOnline.Client/Assets/{Resources/Roms/tortoise4.nes.bytes => StreamingAssets/Roms/tortoise4.nes} (100%) create mode 100644 AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs.meta create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs create mode 100644 AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs.meta diff --git a/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity b/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity index adea99e3..2d477ba1 100644 --- a/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity +++ b/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity @@ -123,6 +123,49 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &149545946 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 149545948} + - component: {fileID: 149545947} + m_Layer: 0 + m_Name: NesEmulator + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &149545947 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149545946} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 39557e19783acee499ace6c68549e8f8, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &149545948 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149545946} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &708549044 GameObject: m_ObjectHideFlags: 0 diff --git a/AxibugEmuOnline.Client/Assets/Script/AxibugEmuOnline.Client.asmdef b/AxibugEmuOnline.Client/Assets/Script/AxibugEmuOnline.Client.asmdef index afae4018..46da2175 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AxibugEmuOnline.Client.asmdef +++ b/AxibugEmuOnline.Client/Assets/Script/AxibugEmuOnline.Client.asmdef @@ -2,7 +2,7 @@ "name": "AxibugEmuOnline.Client", "rootNamespace": "AxibugEmuOnline.Client", "references": [ - "GUID:0c194730510bd1b4fad0398ccfe4235b" + "GUID:390a2c4058e5c304a87e8be70c84d80b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator.meta new file mode 100644 index 00000000..49f52ed7 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5ff32bd86cd0f8245811007dc4e50768 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs new file mode 100644 index 00000000..d0310954 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs @@ -0,0 +1,20 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using VirtualNes.Core.Debug; + +namespace AxibugEmuOnline.Client +{ + public class CoreDebuger : IDebugerImpl + { + public void Log(string message) + { + Debug.Log(message); + } + + public void LogError(string message) + { + Debug.LogError(message); + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs.meta new file mode 100644 index 00000000..b7a75724 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06357866273334741b885e5a1ad23afd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs new file mode 100644 index 00000000..495360b5 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using VirtualNes.Core; + +namespace AxibugEmuOnline.Client +{ + public class CoreSupporter : ISupporterImpl + { + private static string RomDirectoryPath + { + get + { +#if UNITY_EDITOR + return "Assets/StreamingAssets/Roms"; +#else + return $"{Application.streamingAssetsPath}/Roms"; +#endif + } + } + + public Stream OpenRom(string fname) + { + try + { + var stream = File.Open($"{RomDirectoryPath}/{fname}", FileMode.Open); + return stream; + } + catch (Exception ex) + { + Debug.LogError(ex); + return null; + } + } + + public void GetRomPathInfo(string fname, out string fullPath, out string directPath) + { + directPath = RomDirectoryPath; + fullPath = $"{directPath}/{fname}"; + } + + public Stream OpenFile_DISKSYS() + { + return File.Open($"{Application.streamingAssetsPath}/Disksys.rom", FileMode.Open, FileAccess.Read); + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs.meta new file mode 100644 index 00000000..5bad9b00 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8207d923313517f448d7b4d54756e993 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs new file mode 100644 index 00000000..28d02416 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs @@ -0,0 +1,21 @@ +using UnityEngine; +using VirtualNes.Core; +using VirtualNes.Core.Debug; + +namespace AxibugEmuOnline.Client +{ + public class NesEmulator : MonoBehaviour + { + private void Start() + { + StartGame("Kirby.nes"); + } + + public void StartGame(string romName) + { + Supporter.Setup(new CoreSupporter()); + Debuger.Setup(new CoreDebuger()); + NES nes = new NES(romName); + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs.meta new file mode 100644 index 00000000..d178f309 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39557e19783acee499ace6c68549e8f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/StreamingAssets.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets.meta new file mode 100644 index 00000000..a8658aa3 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 353264361911f2f43bb2c088c7e73fec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom b/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom new file mode 100644 index 0000000000000000000000000000000000000000..93a8d933db891715695544411580abf99d14dbda GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom.meta similarity index 62% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes.meta rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom.meta index 97eef8d2..bfab4b09 100644 --- a/AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes.meta +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 01dd757415143ae46921461228964dd5 -TextScriptImporter: +guid: 588a6a32c9d46b943b4909b1757f4572 +DefaultImporter: externalObjects: {} userData: assetBundleName: diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms.meta similarity index 100% rename from AxibugEmuOnline.Client/Assets/Resources/Roms.meta rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms.meta diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes similarity index 100% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes.meta similarity index 62% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes.meta rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes.meta index cfcf9107..803c960a 100644 --- a/AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes.meta +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: ecb5d904338d35c43bb3b98249b36394 -TextScriptImporter: +guid: 41cd7684d8de61f4499c3aa27a6c5b3a +DefaultImporter: externalObjects: {} userData: assetBundleName: diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes similarity index 100% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes.meta similarity index 62% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes.meta index db26e21a..66eb8f20 100644 --- a/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 4933f61382c34574db545f3d9e72b51d -TextScriptImporter: +guid: 50dfce75937af2a44bafd221a0163501 +DefaultImporter: externalObjects: {} userData: assetBundleName: diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes similarity index 100% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes diff --git a/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes.meta new file mode 100644 index 00000000..206dbb7f --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7abf09a3e3fd84648852e5d972dfd260 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs index 02be71cd..510f7b76 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs @@ -19,6 +19,8 @@ namespace VirtualNes.Core public APU(NES parent) { + @internal = new APU_INTERNAL(); + exsound_select = 0; nes = parent; diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs.meta new file mode 100644 index 00000000..7a2e4097 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7b37fc906e6cec64eb2608762f7f80bf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs new file mode 100644 index 00000000..4275dcf3 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs @@ -0,0 +1,92 @@ +using Codice.CM.Client.Differences; +using System; +using System.Collections; +using System.Collections.Generic; +using Unity.VisualScripting.Antlr3.Runtime.Tree; +using UnityEngine; + +namespace VirtualNes.Core +{ + public static class CRC + { + const int CHAR_BIT = 8; + const ulong CRCPOLY1 = 0x04C11DB7UL; + const ulong CRCPOLY2 = 0xEDB88320UL; + + static bool m_Init; + static bool m_InitRev; + static ulong[] m_CrcTable = new ulong[byte.MaxValue + 1]; + static ulong[] m_CrcTableRev = new ulong[byte.MaxValue + 1]; + + public static ulong Crc(int size, Span c) + { + if (!m_Init) + { + MakeTable(); + m_Init = true; + } + + ulong r = 0xFFFFFFFFUL; + int step = 0; + while (--size >= 0) + { + r = (r << CHAR_BIT) ^ m_CrcTable[(byte)(r >> (32 - CHAR_BIT)) ^ c[step]]; + step++; + } + return ~r & 0xFFFFFFFFUL; + } + public static ulong CrcRev(int size, Span c) + { + if (!m_InitRev) + { + MakeTableRev(); + m_InitRev = true; + } + + ulong r = 0xFFFFFFFFUL; + int step = 0; + while (--size >= 0) + { + r = (r >> CHAR_BIT) ^ m_CrcTableRev[(byte)r ^ c[step]]; + step++; + } + return r ^ 0xFFFFFFFFUL; + } + + static void MakeTable() + { + int i, j; + ulong r; + + for (i = 0; i <= byte.MaxValue; i++) + { + r = (ulong)i << (32 - CHAR_BIT); + for (j = 0; j < CHAR_BIT; j++) + { + if ((r & 0x80000000UL) > 0) r = (r << 1) ^ CRCPOLY1; + else r <<= 1; + } + m_CrcTable[i] = r & 0xFFFFFFFFUL; + } + + } + static void MakeTableRev() + { + int i, j; + ulong r; + + for (i = 0; i <= byte.MaxValue; i++) + { + r = (ulong)i; + for (j = 0; j < CHAR_BIT; j++) + { + if ((r & 1) > 0) r = (r >> 1) ^ CRCPOLY2; + else r >>= 1; + } + m_CrcTableRev[i] = r; + } + } + + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs.meta new file mode 100644 index 00000000..e8aecd40 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1939f721bc0cab42add18338dbff333 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs new file mode 100644 index 00000000..e3165016 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace VirtualNes.Core +{ + public enum EnumRomControlByte1 : byte + { + ROM_VMIRROR = 0x01, + ROM_SAVERAM = 0x02, + ROM_TRAINER = 0x04, + ROM_4SCREEN = 0x08, + } + + public enum EnumRomControlByte2 : byte + { + ROM_VSUNISYSTEM = 0x01 + } + + public enum EnumRomType + { + InValid, + NES, + /// Nintendo Disk System + FDS, + NSF + } + + public struct NSFHEADER + { + byte[] ID; + byte Version; + byte TotalSong; + byte StartSong; + ushort LoadAddress; + ushort InitAddress; + ushort PlayAddress; + byte[] SongName; + byte[] ArtistName; + byte[] CopyrightName; + ushort SpeedNTSC; + byte[] BankSwitch; + ushort SpeedPAL; + byte NTSC_PALbits; + byte ExtraChipSelect; + byte[] Expansion; // must be 0 + + + public static int SizeOf() + { + return 128; + } + + public static NSFHEADER GetDefault() + { + var res = new NSFHEADER(); + res.ID = new byte[5]; + res.SongName = new byte[32]; + res.ArtistName = new byte[32]; + res.CopyrightName = new byte[32]; + res.BankSwitch = new byte[8]; + res.Expansion = new byte[4]; + return res; + } + } + + public struct NESHEADER + { + public byte[] ID; + public byte PRG_PAGE_SIZE; + public byte CHR_PAGE_SIZE; + public byte control1; + public byte control2; + public byte[] reserved; + + public bool CheckValid() + { + return GetRomType() != EnumRomType.InValid; + } + + public static int SizeOf() + { + return 16; + } + + public EnumRomType GetRomType() + { + if (ID[0] == 'N' && ID[1] == 'E' && ID[2] == 'S' && ID[3] == 0x1A) + return EnumRomType.NES; + if (ID[0] == 'F' && ID[1] == 'D' && ID[2] == 'S' && ID[3] == 0x1A) + return EnumRomType.FDS; + if (ID[0] == 'N' && ID[1] == 'E' && ID[2] == 'S' && ID[3] == 'M') + return EnumRomType.NSF; + + return EnumRomType.InValid; + } + + public static NESHEADER GetDefault() + { + var res = new NESHEADER(); + res.ID = new byte[4]; + res.reserved = new byte[8]; + return res; + } + + public static NESHEADER Read(Span data) + { + var res = new NESHEADER(); + res.ID = data.Slice(0, 4).ToArray(); + res.PRG_PAGE_SIZE = data[4]; + res.CHR_PAGE_SIZE = data[5]; + res.control1 = data[6]; + res.control2 = data[7]; + res.reserved = data.Slice(8, 8).ToArray(); + + return res; + } + + public byte[] DataToBytes() + { + byte[] res = new byte[16]; + res[0] = ID[0]; + res[1] = ID[1]; + res[2] = ID[2]; + res[3] = ID[3]; + res[4] = PRG_PAGE_SIZE; + res[5] = CHR_PAGE_SIZE; + res[6] = control1; + res[7] = control2; + res[8] = reserved[0]; + res[9] = reserved[1]; + res[10] = reserved[2]; + res[11] = reserved[3]; + res[12] = reserved[4]; + res[13] = reserved[5]; + res[14] = reserved[6]; + res[15] = reserved[7]; + + return res; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs.meta new file mode 100644 index 00000000..da4c0ebb --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65b1ea91f79171f4f82ab91106909f86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs new file mode 100644 index 00000000..ed4d4539 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs @@ -0,0 +1,426 @@ +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Remoting.Messaging; +using UnityEngine; + +namespace VirtualNes.Core +{ + public static class RomPatch + { + public static void DoPatch(ref ulong crc, ref byte[] lpPRG, ref byte[] lpCHR, ref int mapper, ref NESHEADER header) + { + // Mapper 000 + if (crc == 0x57970078) + { // F-1 Race(J) + lpPRG[0x078C] = 0x6C; + lpPRG[0x3FE1] = 0xFF; + lpPRG[0x3FE6] = 0x00; + } + if (crc == 0xaf2bbcbc // Mach Rider(JU) + || crc == 0x3acd4bf1 // Mach Rider(Alt)(JU) 無理矢理パッチ(^^; + || crc == 0x8bbe9bec) + { + lpPRG[0x090D] = 0x6E; + lpPRG[0x7FDF] = 0xFF; + lpPRG[0x7FE4] = 0x00; + + header.control1 = (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0xe16bb5fe) + { // Zippy Race(J) + header.control1 &= 0xf6; + } + if (crc == 0x85534474) + { // Lode Runner(J) + lpPRG[0x29E9] = 0xEA; // セーブメニューを出すパッチ + lpPRG[0x29EA] = 0xEA; + lpPRG[0x29F8] = 0xEA; + lpPRG[0x29F9] = 0xEA; + } + + // Mapper 001 + if (crc == 0x7831b2ff // America Daitouryou Senkyo(J) + || crc == 0x190a3e11 // Be-Bop-Highschool - Koukousei Gokuraku Densetsu(J) + || crc == 0x52449508 // Home Run Nighter - Pennant League!!(J) + || crc == 0x0973f714 // Jangou(J) + || crc == 0x7172f3d4 // Kabushiki Doujou(J) + || crc == 0xa5781280 // Kujaku Ou 2(J) + || crc == 0x8ce9c87b // Money Game, The(J) + || crc == 0xec47296d // Morita Kazuo no Shougi(J) + || crc == 0xcee5857b // Ninjara Hoi!(J) + || crc == 0xe63d9193 // Tanigawa Kouji no Shougi Shinan 3(J) + || crc == 0xd54f5da9 // Tsuppari Wars(J) + || crc == 0x1e0c7ea3) + { // AD&D Dragons of Flame(J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + if (crc == 0x1995ac4e) + { // Ferrari Grand Prix Challenge(J) 無理矢理パッチ(^^; + lpPRG[0x1F7AD] = 0xFF; + lpPRG[0x1F7BC] = 0x00; + } + + if (crc == 0x20d22251) + { // Top rider(J) 無理矢理パッチ(^^; + lpPRG[0x1F17E] = 0xEA; + lpPRG[0x1F17F] = 0xEA; + } + + if (crc == 0x11469ce3) + { // Viva! Las Vegas(J) 無理矢理パッチ(^^; + lpCHR[0x0000] = 0x01; + } + + if (crc == 0x3fccdc7b) + { // Baseball Star - Mezase Sankanou!!(J) 無理矢理パッチ(^^; + lpPRG[0x0F666] = 0x9D; + } + + if (crc == 0xdb564628) + { // Mario Open Golf(J) + lpPRG[0x30195] = 0xC0; + } + + // Mapper 002 + if (crc == 0x63af202f) + { // JJ - Tobidase Daisakusen Part 2(J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0x99a62e47) + { // Black Bass 2, The(J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0x0eaa7515 // Rod Land(J) + || crc == 0x22ab9694) + { // Rod Land(E) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0x2061772a) + { // Tantei Jinguji Taburou Tokino Sugiyukumamani (J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + // Mapper 003 + if (crc == 0x29401686) + { // Minna no Taabou no Nakayoshi Dai Sakusen(J) + // lpPRG[0x2B3E] = 0x60; + } + if (crc == 0x932a077a) + { // TwinBee(J) + mapper = 87; + } + if (crc == 0x8218c637) + { // Space Hunter(J) + // header.control1 &= 0xf6; + // header.control1 |= ROM_4SCREEN; + header.control1 = (byte)EnumRomControlByte1.ROM_VMIRROR; + } + if (crc == 0x2bb6a0f8 // Sherlock Holmes - Hakushaku Reijou Yuukai Jiken(J) + || crc == 0x28c11d24 // Sukeban Deka 3(J) + || crc == 0x02863604) + { // Sukeban Deka 3(J)(Alt) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + // Mapper 004 + if (crc == 0x58581770) + { // Rasaaru Ishii no Childs Quest(J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + if (crc == 0xf3feb3ab // Kunio Kun no Jidaigeki Dayo Zenin Shuugou! (J) + || crc == 0xa524ae9b // Otaku no Seiza - An Adventure in the Otaku Galaxy (J) + || crc == 0x46dc6e57 // SD Gundam - Gachapon Senshi 2 - Capsule Senki (J) + || crc == 0x66b2dec7 // SD Gundam - Gachapon Senshi 3 - Eiyuu Senki (J) + || crc == 0x92b07fd9 // SD Gundam - Gachapon Senshi 4 - New Type Story (J) + || crc == 0x8ee6463a // SD Gundam - Gachapon Senshi 5 - Battle of Universal Century (J) + || crc == 0xaf754426 // Ultraman Club 3 (J) + || crc == 0xfe4e5b11 // Ushio to Tora - Shinen no Daiyou (J) + || crc == 0x57c12c17) + { // Yamamura Misa Suspense - Kyouto Zaiteku Satsujin Jiken (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + if (crc == 0x42e03e4a) + { // RPG Jinsei Game (J) + mapper = 118; + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + if (crc == 0xfd0299c3) + { // METAL MAX(J) + lpPRG[0x3D522] = 0xA9; + lpPRG[0x3D523] = 0x19; + } + if (crc == 0x1d2e5018 // Rockman 3(J) + || crc == 0x6b999aaf) + { // Mega Man 3(U) + // lpPRG[0x3C179] = 0xBA;// + // lpPRG[0x3C9CC] = 0x9E; + } + + // Mapper 005 + if (crc == 0xe91548d8) + { // Shin 4 Nin Uchi Mahjong - Yakuman Tengoku (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + if (crc == 0x255b129c) + { // Gun Sight (J) / Gun Sight (J)[a1] + lpPRG[0x02D0B] = 0x01; + lpPRG[0x0BEC0] = 0x01; + } + + + // Mapper 010 + if (crc == 0xc9cce8f2) + { // Famicom Wars (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 016 + if (crc == 0x983d8175 // Datach - Battle Rush - Build Up Robot Tournament (J) + || crc == 0x894efdbc // Datach - Crayon Shin Chan - Ora to Poi Poi (J) + || crc == 0x19e81461 // Datach - Dragon Ball Z - Gekitou Tenkaichi Budou Kai (J) + || crc == 0xbe06853f // Datach - J League Super Top Players (J) + || crc == 0x0be0a328 // Datach - SD Gundam - Gundam Wars (J) + || crc == 0x5b457641 // Datach - Ultraman Club - Supokon Fight! (J) + || crc == 0xf51a7f46 // Datach - Yuu Yuu Hakusho - Bakutou Ankoku Bujutsu Kai (J) + || crc == 0x31cd9903 // Dragon Ball Z - Kyoushuu! Saiya Jin (J) + || crc == 0xe49fc53e // Dragon Ball Z 2 - Gekishin Freeza!! (J) + || crc == 0x09499f4d // Dragon Ball Z 3 - Ressen Jinzou Ningen (J) + || crc == 0x2e991109 // Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (J) + || crc == 0x170250de) + { // Rokudenashi Blues(J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 019 + if (crc == 0x3296ff7a // Battle Fleet (J) + || crc == 0x429fd177 // Famista '90 (J) + || crc == 0xdd454208 // Hydlide 3 - Yami Kara no Houmonsha (J) + || crc == 0xb1b9e187 // Kaijuu Monogatari (J) + || crc == 0xaf15338f) + { // Mindseeker (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 026 + if (crc == 0x836cc1ab) + { // Mouryou Senki Madara (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 033 + if (crc == 0x547e6cc1) + { // Flintstones - The Rescue of Dino & Hoppy, The(J) + mapper = 48; + } + + // Mapper 065 + if (crc == 0xfd3fc292) + { // Ai Sensei no Oshiete - Watashi no Hoshi (J) + mapper = 32; + } + + // Mapper 068 + if (crc == 0xfde79681) + { // Maharaja (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 069 + if (crc == 0xfeac6916 // Honoo no Toukyuuji - Dodge Danpei 2(J) + || crc == 0x67898319) + { // Barcode World(J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 080 + if (crc == 0x95aaed34 // Mirai Shinwa Jarvas (J) + || crc == 0x17627d4b) + { // Taito Grand Prix - Eikou heno License (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 082 + if (crc == 0x4819a595) + { // Kyuukyoku Harikiri Stadium - Heisei Gannen Ban (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 086 + if (crc == 0xe63f7d0b) + { // Urusei Yatsura - Lum no Wedding Bell(J) + mapper = 101; + } + + // Mapper 118 + if (crc == 0x3b0fb600) + { // Ys 3 - Wonderers From Ys (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 180 + if (crc == 0xc68363f6) + { // Crazy Climber(J) + header.control1 &= 0xf6; + } + + // VS-Unisystem + if (crc == 0x70901b25) + { // VS Slalom + mapper = 99; + } + + if (crc == 0xd5d7eac4) + { // VS Dr. Mario + mapper = 1; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xffbef374 // VS Castlevania + || crc == 0x8c0c2df5) + { // VS Top Gun + mapper = 2; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xeb2dba63 // VS TKO Boxing + || crc == 0x98cfe016 // VS TKO Boxing (Alt) + || crc == 0x9818f656) + { // VS TKO Boxing (f1) + mapper = 4; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0x135adf7c) + { // VS Atari RBI Baseball + mapper = 4; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xf9d3b0a3 // VS Super Xevious + || crc == 0x9924980a // VS Super Xevious (b1) + || crc == 0x66bb838f) + { // VS Super Xevious (b2) + mapper = 4; + header.control1 &= 0xF6; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0x17ae56be) + { // VS Freedom Force + mapper = 4; + header.control1 &= 0xF6; + header.control1 |= (byte)EnumRomControlByte1.ROM_4SCREEN; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xe2c0a2be) + { // VS Platoon + mapper = 68; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xcbe85490 // VS Excitebike + || crc == 0x29155e0c // VS Excitebike (Alt) + || crc == 0xff5135a3) + { // VS Hogan's Alley + header.control1 &= 0xF6; + header.control1 |= (byte)EnumRomControlByte1.ROM_4SCREEN; + } + + if (crc == 0x0b65a917) + { // VS Mach Rider(Endurance Course) + lpPRG[0x7FDF] = 0xFF; + lpPRG[0x7FE4] = 0x00; + } + + if (crc == 0x8a6a9848 // VS Mach Rider(Endurance Course)(Alt) + || crc == 0xae8063ef) + { // VS Mach Rider(Japan, Fighting Course) + lpPRG[0x7FDD] = 0xFF; + lpPRG[0x7FE2] = 0x00; + } + + if (crc == 0x16d3f469) + { // VS Ninja Jajamaru Kun (J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0xc99ec059) + { // VS Raid on Bungeling Bay(J) + mapper = 99; + header.control1 &= 0xF6; + header.control1 |= (byte)EnumRomControlByte1.ROM_4SCREEN; + } + if (crc == 0xca85e56d) + { // VS Mighty Bomb Jack(J) + mapper = 99; + header.control1 &= 0xF6; + header.control1 |= (byte)EnumRomControlByte1.ROM_4SCREEN; + } + + + if (crc == 0xeb2dba63 // VS TKO Boxing + || crc == 0x9818f656 // VS TKO Boxing + || crc == 0xed588f00 // VS Duck Hunt + || crc == 0x8c0c2df5 // VS Top Gun + || crc == 0x16d3f469 // VS Ninja Jajamaru Kun + || crc == 0x8850924b // VS Tetris + || crc == 0xcf36261e // VS Sky Kid + || crc == 0xe1aa8214 // VS Star Luster + || crc == 0xec461db9 // VS Pinball + || crc == 0xe528f651 // VS Pinball (alt) + || crc == 0x17ae56be // VS Freedom Force + || crc == 0xe2c0a2be // VS Platoon + || crc == 0xff5135a3 // VS Hogan's Alley + || crc == 0x70901b25 // VS Slalom + || crc == 0x0b65a917 // VS Mach Rider(Endurance Course) + || crc == 0x8a6a9848 // VS Mach Rider(Endurance Course)(Alt) + || crc == 0xae8063ef // VS Mach Rider(Japan, Fighting Course) + || crc == 0xcc2c4b5d // VS Golf + || crc == 0xa93a5aee // VS Stroke and Match Golf + || crc == 0x86167220 // VS Lady Golf + || crc == 0xffbef374 // VS Castlevania + || crc == 0x135adf7c // VS Atari RBI Baseball + || crc == 0xd5d7eac4 // VS Dr. Mario + || crc == 0x46914e3e // VS Soccer + || crc == 0x70433f2c // VS Battle City + || crc == 0x8d15a6e6 // VS bad .nes + || crc == 0x1e438d52 // VS Goonies + || crc == 0xcbe85490 // VS Excitebike + || crc == 0x29155e0c // VS Excitebike (alt) + || crc == 0x07138c06 // VS Clu Clu Land + || crc == 0x43a357ef // VS Ice Climber + || crc == 0x737dd1bf // VS Super Mario Bros + || crc == 0x4bf3972d // VS Super Mario Bros + || crc == 0x8b60cc58 // VS Super Mario Bros + || crc == 0x8192c804 // VS Super Mario Bros + || crc == 0xd99a2087 // VS Gradius + || crc == 0xf9d3b0a3 // VS Super Xevious + || crc == 0x9924980a // VS Super Xevious + || crc == 0x66bb838f // VS Super Xevious + || crc == 0xc99ec059 // VS Raid on Bungeling Bay(J) + || crc == 0xca85e56d) + { // VS Mighty Bomb Jack(J) + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (mapper == 99 || mapper == 151) + { + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs.meta new file mode 100644 index 00000000..16709527 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 953873ef00535544abd9591708c8e7a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs index b5e2d224..66a5e554 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs @@ -94,7 +94,6 @@ namespace VirtualNes.Core pad = new PAD(this); Debuger.Log("Loading ROM Image..."); - rom = new ROM(fname); } catch (Exception ex) diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs index be753df4..a0d3a5f9 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs @@ -1,4 +1,5 @@ -サソusing System; +サソusing Codice.CM.Client.Differences; +using System; using System.IO; using System.Linq; using VirtualNes.Core.Debug; @@ -8,6 +9,7 @@ namespace VirtualNes.Core public class ROM { protected NESHEADER header; + protected NSFHEADER nsfheader; protected string path; protected string name; protected string fullpath; @@ -21,8 +23,12 @@ namespace VirtualNes.Core protected byte[] lpDisk; protected ulong crc; protected ulong crcall; + protected ulong crcvrom; protected int mapper; protected int diskno; + protected ulong fdsmakerID; + protected ulong fdsgameID; + public ROM(string fname) { Stream fp = null; @@ -46,7 +52,7 @@ namespace VirtualNes.Core try { - fp = Supporter.OpenFile(fname); + fp = Supporter.OpenRom(fname); if (fp == null) { throw new System.Exception($"Open Rom Failed:[{fname}]"); @@ -69,7 +75,7 @@ namespace VirtualNes.Core throw new Exception($"rom file is not valid:[{fname}]"); ulong PRGoffset, CHRoffset; - long PRGsize, CHRsize; + long PRGsize = 0, CHRsize = 0; var romType = header.GetRomType(); if (romType == EnumRomType.NES) @@ -87,7 +93,6 @@ namespace VirtualNes.Core if (PRGsize <= 0 || (PRGsize + CHRsize) > FileSize) { - // NES蜒ソ蜒「蜒溷¢蝣主ソ「蛛ア蛛。 throw new Exception($"Invalid NesHeader:[{fname}]"); } @@ -164,7 +169,7 @@ namespace VirtualNes.Core lpPRG[3] = 0x1A; lpPRG[4] = (byte)diskno; - fp = Supporter.OpenFile("DISKSYS.ROM"); + fp = Supporter.OpenFile_DISKSYS(); if (fp == null) { throw new Exception($"Not found DISKSYS.ROM for [{fname}]"); @@ -183,13 +188,97 @@ namespace VirtualNes.Core lpDiskBios = new byte[8 * 1024]; if (bios[0] == 'N' && bios[1] == 'E' && bios[2] == 'S' && bios[3] == 0x1A) { + Array.Copy(bios, 0x6010, lpDiskBios, 0, lpDiskBios.Length); + } + else + { + Array.Copy(bios, lpDiskBios, lpDiskBios.Length); + } + bios = null; + } + else if (romType == EnumRomType.NSF) + { + bNSF = true; + header = NESHEADER.GetDefault(); + nsfheader = NSFHEADER.GetDefault(); + + PRGsize = FileSize - NSFHEADER.SizeOf(); + Debuger.Log($"PRGSIZE:{PRGsize}"); + PRGsize = (PRGsize + 0x0FFF) & ~0x0FFF; + Debuger.Log($"PRGSIZE:{PRGsize}"); + + lpPRG = new byte[PRGsize]; + Array.Copy(temp, NSFHEADER.SizeOf(), lpPRG, 0, FileSize - NSFHEADER.SizeOf()); + + NSF_PAGE_SIZE = (int)(PRGsize >> 12); + Debuger.Log($"PAGESIZE:{NSF_PAGE_SIZE}"); + } + else + { + throw new Exception($"Unsupport format:[{fname}]"); + } + + Supporter.GetFilePathInfo(fname, out fullpath, out path); + + if (!bNSF) + { + mapper = (header.control1 >> 4) | (header.control2 & 0xF0); + crc = crcall = crcvrom = 0; + + if (mapper != 20) + { + Span sTemp = temp; + if (IsTRAINER()) + { + crcall = CRC.CrcRev((int)(512 + PRGsize + CHRsize), sTemp.Slice(NESHEADER.SizeOf())); + crc = CRC.CrcRev((int)(512 + PRGsize), sTemp); + if (CHRsize > 0) + crcvrom = CRC.CrcRev((int)CHRsize, sTemp.Slice((int)(PRGsize + 512 + NESHEADER.SizeOf()))); + } + else + { + crcall = CRC.CrcRev((int)(PRGsize + CHRsize), sTemp.Slice(NESHEADER.SizeOf())); + crc = CRC.CrcRev((int)(PRGsize), sTemp.Slice(NESHEADER.SizeOf())); + if (CHRsize > 0) + crcvrom = CRC.CrcRev((int)CHRsize, sTemp.Slice((int)(PRGsize + NESHEADER.SizeOf()))); + } + + FileNameCheck(fname); + + RomPatch.DoPatch(ref crc, ref lpPRG, ref lpCHR, ref mapper, ref header); + + fdsmakerID = fdsgameID = 0; + } + else //mapper==20 + { + crc = crcall = crcvrom = 0; + + fdsmakerID = lpPRG[0x1F]; + fdsgameID = (ulong)((lpPRG[0x20] << 24) | (lpPRG[0x21] << 16) | (lpPRG[0x22] << 8) | (lpPRG[0x23] << 0)); } } - } - catch - { + else //NSF + { + mapper = 0x0100; // Private mapper + crc = crcall = crcvrom = 0; + fdsmakerID = fdsgameID = 0; + } + temp = null; + } + catch (Exception ex) + { + fp?.Dispose(); + temp = null; + bios = null; + lpPRG = null; + lpCHR = null; + lpTrainer = null; + lpDiskBios = null; + lpDisk = null; + + throw ex; } } @@ -197,98 +286,16 @@ namespace VirtualNes.Core { return (header.control1 & (byte)EnumRomControlByte1.ROM_TRAINER) > 0; } - } - public enum EnumRomControlByte1 : byte - { - ROM_VMIRROR = 0x01, - ROM_SAVERAM = 0x02, - ROM_TRAINER = 0x04, - ROM_4SCREEN = 0x08, - } - - public enum EnumRomType - { - InValid, - NES, - /// Nintendo Disk System - FDS, - NSF - } - - public struct NESHEADER - { - public byte[] ID; - public byte PRG_PAGE_SIZE; - public byte CHR_PAGE_SIZE; - public byte control1; - public byte control2; - public byte[] reserved; - - public bool CheckValid() + protected void FileNameCheck(string fname) { - return GetRomType() != EnumRomType.InValid; - } - - public static int SizeOf() - { - return 16; - } - - public EnumRomType GetRomType() - { - if (ID[0] == 'N' && ID[1] == 'E' && ID[2] == 'S' && ID[3] == 0x1A) - return EnumRomType.NES; - if (ID[0] == 'F' && ID[1] == 'D' && ID[2] == 'S' && ID[3] == 0x1A) - return EnumRomType.FDS; - if (ID[0] == 'N' && ID[1] == 'E' && ID[2] == 'S' && ID[3] == 'M') - return EnumRomType.NSF; - - return EnumRomType.InValid; - } - - public static NESHEADER GetDefault() - { - var res = new NESHEADER(); - res.ID = new byte[4]; - res.reserved = new byte[8]; - return res; - } - - public static NESHEADER Read(Span data) - { - var res = new NESHEADER(); - res.ID = data.Slice(0, 4).ToArray(); - res.PRG_PAGE_SIZE = data[4]; - res.CHR_PAGE_SIZE = data[5]; - res.control1 = data[6]; - res.control2 = data[7]; - res.reserved = data.Slice(8, 8).ToArray(); - - return res; - } - - public byte[] DataToBytes() - { - byte[] res = new byte[16]; - res[0] = ID[0]; - res[1] = ID[1]; - res[2] = ID[2]; - res[3] = ID[3]; - res[4] = PRG_PAGE_SIZE; - res[5] = CHR_PAGE_SIZE; - res[6] = control1; - res[7] = control2; - res[8] = reserved[0]; - res[9] = reserved[1]; - res[10] = reserved[2]; - res[11] = reserved[3]; - res[12] = reserved[4]; - res[13] = reserved[5]; - res[14] = reserved[6]; - res[15] = reserved[7]; - - return res; + if (fname.Contains("(E)")) + { + bPAL = true; + return; + } } } + + } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs index a4ae83d9..884d34e8 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs @@ -13,14 +13,27 @@ namespace VirtualNes.Core s_support = supporter; } - public static Stream OpenFile(string fname) + public static Stream OpenRom(string fname) { - return s_support.OpenFile(fname); + return s_support.OpenRom(fname); } + + public static void GetFilePathInfo(string fname, out string fullPath, out string directPath) + { + s_support.GetRomPathInfo(fname, out fullPath, out directPath); + } + + public static Stream OpenFile_DISKSYS() + { + return s_support.OpenFile_DISKSYS(); + } + } public interface ISupporterImpl { - Stream OpenFile(string fname); + Stream OpenRom(string fname); + void GetRomPathInfo(string fname, out string fullPath, out string directPath); + Stream OpenFile_DISKSYS(); } }