diff --git a/GLScreen.cs b/GLScreen.cs
index 3e16f7f1d..982816931 100644
--- a/GLScreen.cs
+++ b/GLScreen.cs
@@ -351,7 +351,9 @@ void main(void) {
protected override void OnRenderFrame(FrameEventArgs e)
{
GL.Viewport(0, 0, 1280, 720);
-
+
+ Title = $"Ryujinx Screen - (Vsync: {VSync} - FPS: {1f / e.Time:0})";
+
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
RenderFb();
diff --git a/Program.cs b/Program.cs
index 44dc67c1f..5569cd49d 100644
--- a/Program.cs
+++ b/Program.cs
@@ -9,6 +9,10 @@ namespace Ryujinx
{
static void Main(string[] args)
{
+ Config.Read();
+
+ Console.Title = "Ryujinx Console";
+
IGalRenderer Renderer = new OpenGLRenderer();
Switch Ns = new Switch(Renderer);
@@ -21,27 +25,30 @@ namespace Ryujinx
if (RomFsFiles.Length > 0)
{
- Console.WriteLine("Loading as cart with RomFS.");
+ Logging.Info("Loading as cart with RomFS.");
+ Console.Title += " - Cart (with RomFS) - " + args[0];
Ns.Os.LoadCart(args[0], RomFsFiles[0]);
}
else
{
- Console.WriteLine("Loading as cart WITHOUT RomFS.");
+ Logging.Info("Loading as cart WITHOUT RomFS.");
+ Console.Title += " - Cart (without RomFS) - " + args[0];
Ns.Os.LoadCart(args[0]);
}
}
else if (File.Exists(args[0]))
{
- Console.WriteLine("Loading as homebrew.");
+ Logging.Info("Loading as homebrew.");
+ Console.Title += " - Homebrew - " + args[0];
Ns.Os.LoadProgram(args[0]);
}
}
else
{
- Console.WriteLine("Please specify the folder with the NSOs/IStorage or a NSO/NRO.");
+ Logging.Error("Please specify the folder with the NSOs/IStorage or a NSO/NRO.");
}
using (GLScreen Screen = new GLScreen(Ns, Renderer))
diff --git a/Ryujinx.conf b/Ryujinx.conf
new file mode 100644
index 000000000..590318fe7
--- /dev/null
+++ b/Ryujinx.conf
@@ -0,0 +1,20 @@
+#Enabled print informations logs
+Logging_Enable_Info = true
+
+#Enabled print trace logs
+Logging_Enable_Trace = true
+
+#Enabled print debug logs
+Logging_Enable_Debug = true
+
+#Enabled print warning logs
+Logging_Enable_Warn = true
+
+#Enabled print error logs
+Logging_Enable_Error = true
+
+#Enabled print fatal logs
+Logging_Enable_Fatal = true
+
+#Saved logs into Ryujinx.log
+Logging_Enable_LogFile = false
diff --git a/Ryujinx.csproj b/Ryujinx.csproj
index 2c25afc0f..9ad696d89 100644
--- a/Ryujinx.csproj
+++ b/Ryujinx.csproj
@@ -9,4 +9,9 @@
+
+
+ PreserveNewest
+
+
\ No newline at end of file
diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs
new file mode 100644
index 000000000..c27060d2c
--- /dev/null
+++ b/Ryujinx/Config.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace Ryujinx
+{
+ public static class Config
+ {
+ public static bool LoggingEnableInfo { get; private set; }
+ public static bool LoggingEnableTrace { get; private set; }
+ public static bool LoggingEnableDebug { get; private set; }
+ public static bool LoggingEnableWarn { get; private set; }
+ public static bool LoggingEnableError { get; private set; }
+ public static bool LoggingEnableFatal { get; private set; }
+ public static bool LoggingEnableLogFile { get; private set; }
+
+ public static void Read()
+ {
+ IniParser Parser = new IniParser(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "Ryujinx.conf"));
+
+ LoggingEnableInfo = Convert.ToBoolean(Parser.Value("Logging_Enable_Info"));
+ LoggingEnableTrace = Convert.ToBoolean(Parser.Value("Logging_Enable_Trace"));
+ LoggingEnableDebug = Convert.ToBoolean(Parser.Value("Logging_Enable_Debug"));
+ LoggingEnableWarn = Convert.ToBoolean(Parser.Value("Logging_Enable_Warn"));
+ LoggingEnableError = Convert.ToBoolean(Parser.Value("Logging_Enable_Error"));
+ LoggingEnableFatal = Convert.ToBoolean(Parser.Value("Logging_Enable_Fatal"));
+ LoggingEnableLogFile = Convert.ToBoolean(Parser.Value("Logging_Enable_LogFile"));
+ }
+ }
+
+ // https://stackoverflow.com/a/37772571
+ public class IniParser
+ {
+ private Dictionary Values;
+
+ public IniParser(string Path)
+ {
+ Values = File.ReadLines(Path)
+ .Where(Line => (!String.IsNullOrWhiteSpace(Line) && !Line.StartsWith("#")))
+ .Select(Line => Line.Split(new char[] { '=' }, 2, 0))
+ .ToDictionary(Parts => Parts[0].Trim(), Parts => Parts.Length > 1 ? Parts[1].Trim() : null);
+ }
+
+ public string Value(string Name, string Value = null)
+ {
+ if (Values != null && Values.ContainsKey(Name))
+ {
+ return Values[Name];
+ }
+ return Value;
+ }
+ }
+}
diff --git a/Ryujinx/Cpu/AOpCodeTable.cs b/Ryujinx/Cpu/AOpCodeTable.cs
index a7deb2c7f..14c249950 100644
--- a/Ryujinx/Cpu/AOpCodeTable.cs
+++ b/Ryujinx/Cpu/AOpCodeTable.cs
@@ -152,12 +152,13 @@ namespace ChocolArm64
Set("x0011110xx110000000000xxxxxxxxxx", AInstEmit.Fcvtms_S, typeof(AOpCodeSimdCvt));
Set("x0011110xx101000000000xxxxxxxxxx", AInstEmit.Fcvtps_S, typeof(AOpCodeSimdCvt));
Set("x0011110xx111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_S, typeof(AOpCodeSimdCvt));
- Set("0x0011101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzs_V, typeof(AOpCodeSimd));
- Set("x0011110xx111001000000xxxxxxxxxx", AInstEmit.Fcvtzu_S, typeof(AOpCodeSimdCvt));
- Set("0x1011101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzu_V, typeof(AOpCodeSimd));
- Set("0x1011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzu_V_Fix, typeof(AOpCodeSimdShImm));
Set("x0011110xx011000xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzs_Fix, typeof(AOpCodeSimdCvt));
+ Set("0x0011101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzs_V, typeof(AOpCodeSimd));
+ Set("0x0011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzs_V, typeof(AOpCodeSimdShImm));
+ Set("x0011110xx111001000000xxxxxxxxxx", AInstEmit.Fcvtzu_S, typeof(AOpCodeSimdCvt));
Set("x0011110xx011001xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzu_Fix, typeof(AOpCodeSimdCvt));
+ Set("0x1011101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzu_V, typeof(AOpCodeSimd));
+ Set("0x1011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzu_V, typeof(AOpCodeSimdShImm));
Set("00011110xx1xxxxx000110xxxxxxxxxx", AInstEmit.Fdiv_S, typeof(AOpCodeSimdReg));
Set("00011111xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Fmadd_S, typeof(AOpCodeSimdReg));
Set("00011110xx1xxxxx010010xxxxxxxxxx", AInstEmit.Fmax_S, typeof(AOpCodeSimdReg));
@@ -186,8 +187,10 @@ namespace ChocolArm64
Set("0x0011101x1xxxxx110101xxxxxxxxxx", AInstEmit.Fsub_V, typeof(AOpCodeSimdReg));
Set("01001110000xxxxx000111xxxxxxxxxx", AInstEmit.Ins_Gp, typeof(AOpCodeSimdIns));
Set("01101110000xxxxx0xxxx1xxxxxxxxxx", AInstEmit.Ins_V, typeof(AOpCodeSimdIns));
- Set("0x00110001000000xxxxxxxxxxxxxxxx", AInstEmit.Ld__V, typeof(AOpCodeSimdMemMult));
- Set("0x001100110xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ld__V, typeof(AOpCodeSimdMemMult));
+ Set("0x00110001000000xxxxxxxxxxxxxxxx", AInstEmit.Ld__Vms, typeof(AOpCodeSimdMemMs));
+ Set("0x001100110xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ld__Vms, typeof(AOpCodeSimdMemMs));
+ Set("0x00110101000000xx0xxxxxxxxxxxxx", AInstEmit.Ld__Vss, typeof(AOpCodeSimdMemSs));
+ Set("0x001101110xxxxxxx0xxxxxxxxxxxxx", AInstEmit.Ld__Vss, typeof(AOpCodeSimdMemSs));
Set("xx10110xx1xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldp, typeof(AOpCodeSimdMemPair));
Set("xx111100x10xxxxxxxxx00xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemImm));
Set("xx111100x10xxxxxxxxx01xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemImm));
@@ -218,8 +221,8 @@ namespace ChocolArm64
Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm));
Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S, typeof(AOpCodeSimdShImm));
Set("0x0011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm));
- Set("0x00110000000000xxxxxxxxxxxxxxxx", AInstEmit.St__V, typeof(AOpCodeSimdMemMult));
- Set("0x001100100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__V, typeof(AOpCodeSimdMemMult));
+ Set("0x00110000000000xxxxxxxxxxxxxxxx", AInstEmit.St__V, typeof(AOpCodeSimdMemMs));
+ Set("0x001100100xxxxxxxxxxxxxxxxxxxxx", AInstEmit.St__V, typeof(AOpCodeSimdMemMs));
Set("xx10110xx0xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Stp, typeof(AOpCodeSimdMemPair));
Set("xx111100x00xxxxxxxxx00xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemImm));
Set("xx111100x00xxxxxxxxx01xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemImm));
diff --git a/Ryujinx/Cpu/AOptimizations.cs b/Ryujinx/Cpu/AOptimizations.cs
new file mode 100644
index 000000000..cbfd1ce51
--- /dev/null
+++ b/Ryujinx/Cpu/AOptimizations.cs
@@ -0,0 +1,4 @@
+public static class AOptimizations
+{
+
+}
\ No newline at end of file
diff --git a/Ryujinx/Cpu/Decoder/AOpCodeSimdMemMult.cs b/Ryujinx/Cpu/Decoder/AOpCodeSimdMemMs.cs
similarity index 91%
rename from Ryujinx/Cpu/Decoder/AOpCodeSimdMemMult.cs
rename to Ryujinx/Cpu/Decoder/AOpCodeSimdMemMs.cs
index 9731c7e74..0e8480b03 100644
--- a/Ryujinx/Cpu/Decoder/AOpCodeSimdMemMult.cs
+++ b/Ryujinx/Cpu/Decoder/AOpCodeSimdMemMs.cs
@@ -3,7 +3,7 @@ using ChocolArm64.State;
namespace ChocolArm64.Decoder
{
- class AOpCodeSimdMemMult : AOpCode, IAOpCodeSimd
+ class AOpCodeSimdMemMs : AOpCode, IAOpCodeSimd
{
public int Rt { get; private set; }
public int Rn { get; private set; }
@@ -14,7 +14,7 @@ namespace ChocolArm64.Decoder
public int Elems { get; private set; }
public bool WBack { get; private set; }
- public AOpCodeSimdMemMult(AInst Inst, long Position, int OpCode) : base(Inst, Position)
+ public AOpCodeSimdMemMs(AInst Inst, long Position, int OpCode) : base(Inst, Position)
{
switch ((OpCode >> 12) & 0xf)
{
diff --git a/Ryujinx/Cpu/Decoder/AOpCodeSimdMemSs.cs b/Ryujinx/Cpu/Decoder/AOpCodeSimdMemSs.cs
new file mode 100644
index 000000000..c2917dfc8
--- /dev/null
+++ b/Ryujinx/Cpu/Decoder/AOpCodeSimdMemSs.cs
@@ -0,0 +1,104 @@
+using ChocolArm64.Instruction;
+using ChocolArm64.State;
+
+namespace ChocolArm64.Decoder
+{
+ class AOpCodeSimdMemSs : AOpCode, IAOpCodeSimd
+ {
+ public int Rt { get; private set; }
+ public int Rn { get; private set; }
+ public int Size { get; private set; }
+ public int Rm { get; private set; }
+ public int SElems { get; private set; }
+ public int Index { get; private set; }
+ public bool Replicate { get; private set; }
+ public bool WBack { get; private set; }
+
+ public AOpCodeSimdMemSs(AInst Inst, long Position, int OpCode) : base(Inst, Position)
+ {
+ int Size = (OpCode >> 10) & 3;
+ int S = (OpCode >> 12) & 1;
+ int SElems = (OpCode >> 12) & 2;
+ int Scale = (OpCode >> 14) & 3;
+ int L = (OpCode >> 22) & 1;
+ int Q = (OpCode >> 30) & 1;
+
+ SElems |= (OpCode >> 21) & 1;
+
+ SElems++;
+
+ int Index = (Q << 3) | (S << 2) | Size;
+
+ switch (Scale)
+ {
+ case 0: Index >>= 0; break;
+
+ case 1:
+ {
+ if ((Index & 1) != 0)
+ {
+ Inst = AInst.Undefined;
+
+ return;
+ }
+
+ Index >>= 1;
+
+ break;
+ }
+
+ case 2:
+ {
+ if ((Index & 2) != 0 ||
+ ((Index & 1) != 0 && S != 0))
+ {
+ Inst = AInst.Undefined;
+
+ return;
+ }
+
+ if ((Index & 1) != 0)
+ {
+ Index >>= 3;
+ }
+ else
+ {
+ Index >>= 2;
+
+ Scale = 3;
+ }
+
+ break;
+ }
+
+ case 3:
+ {
+ if (L == 0 || S != 0)
+ {
+ Inst = AInst.Undefined;
+
+ return;
+ }
+
+ Scale = Size;
+
+ Replicate = true;
+
+ break;
+ }
+ }
+
+ this.SElems = SElems;
+ this.Size = Scale;
+
+ Rt = (OpCode >> 0) & 0x1f;
+ Rn = (OpCode >> 5) & 0x1f;
+ Rm = (OpCode >> 16) & 0x1f;
+ WBack = ((OpCode >> 23) & 0x1) != 0;
+
+ RegisterSize = Q != 0
+ ? ARegisterSize.SIMD128
+ : ARegisterSize.SIMD64;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx/Cpu/Decoder/AOpCodeSimdShImm.cs b/Ryujinx/Cpu/Decoder/AOpCodeSimdShImm.cs
index a677e579b..6c8398817 100644
--- a/Ryujinx/Cpu/Decoder/AOpCodeSimdShImm.cs
+++ b/Ryujinx/Cpu/Decoder/AOpCodeSimdShImm.cs
@@ -1,26 +1,16 @@
using ChocolArm64.Instruction;
-using ChocolArm64.State;
namespace ChocolArm64.Decoder
{
- class AOpCodeSimdShImm : AOpCode, IAOpCodeSimd
+ class AOpCodeSimdShImm : AOpCodeSimd
{
- public int Rd { get; private set; }
- public int Rn { get; private set; }
- public int Imm { get; private set; }
- public int Size { get; private set; }
+ public int Imm { get; private set; }
- public AOpCodeSimdShImm(AInst Inst, long Position, int OpCode) : base(Inst, Position)
+ public AOpCodeSimdShImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
{
- Rd = (OpCode >> 0) & 0x1f;
- Rn = (OpCode >> 5) & 0x1f;
Imm = (OpCode >> 16) & 0x7f;
Size = ABitUtils.HighestBitSet32(Imm >> 3);
-
- RegisterSize = ((OpCode >> 30) & 1) != 0
- ? ARegisterSize.SIMD128
- : ARegisterSize.SIMD64;
}
}
}
\ No newline at end of file
diff --git a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
index 8d4ade3a1..75c308c35 100644
--- a/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
+++ b/Ryujinx/Cpu/Instruction/AInstEmitSimd.cs
@@ -102,64 +102,10 @@ namespace ChocolArm64.Instruction
public static void Eor_V(AILEmitterCtx Context) => EmitVectorBinaryZx(Context, OpCodes.Xor);
- public static void Fadd_V(AILEmitterCtx Context)
- {
- AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+ public static void Fadd_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Add);
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdvec(Op.Rm);
- Context.EmitLdc_I4(Op.SizeF);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Fadd64),
- nameof(ASoftFallback.Fadd128));
-
- Context.EmitStvec(Op.Rd);
- }
-
- public static void Fcvtzs_V(AILEmitterCtx Context)
- {
- AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
-
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdc_I4(Op.SizeF);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Fcvtzs_V64),
- nameof(ASoftFallback.Fcvtzs_V128));
-
- Context.EmitStvec(Op.Rd);
- }
-
- public static void Fcvtzu_V(AILEmitterCtx Context)
- {
- AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
-
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdc_I4(0);
- Context.EmitLdc_I4(Op.SizeF);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Fcvtzu_V_64),
- nameof(ASoftFallback.Fcvtzu_V_128));
-
- Context.EmitStvec(Op.Rd);
- }
-
- public static void Fcvtzu_V_Fix(AILEmitterCtx Context)
- {
- AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
-
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
- Context.EmitLdc_I4(Op.Size - 2);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Fcvtzu_V_64),
- nameof(ASoftFallback.Fcvtzu_V_128));
-
- Context.EmitStvec(Op.Rd);
- }
+ public static void Fcvtzs_V(AILEmitterCtx Context) => EmitVectorFcvtS(Context);
+ public static void Fcvtzu_V(AILEmitterCtx Context) => EmitVectorFcvtU(Context);
public static void Fmla_V(AILEmitterCtx Context)
{
@@ -208,20 +154,7 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
- public static void Fmul_V(AILEmitterCtx Context)
- {
- AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
-
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdvec(Op.Rm);
- Context.EmitLdc_I4(Op.SizeF);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Fmul64),
- nameof(ASoftFallback.Fmul128));
-
- Context.EmitStvec(Op.Rd);
- }
+ public static void Fmul_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Mul);
public static void Fmul_Vs(AILEmitterCtx Context)
{
@@ -239,20 +172,7 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
- public static void Fsub_V(AILEmitterCtx Context)
- {
- AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
-
- Context.EmitLdvec(Op.Rn);
- Context.EmitLdvec(Op.Rm);
- Context.EmitLdc_I4(Op.SizeF);
-
- ASoftFallback.EmitCall(Context,
- nameof(ASoftFallback.Fsub64),
- nameof(ASoftFallback.Fsub128));
-
- Context.EmitStvec(Op.Rd);
- }
+ public static void Fsub_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Sub);
public static void Ins_Gp(AILEmitterCtx Context)
{
@@ -283,7 +203,8 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
- public static void Ld__V(AILEmitterCtx Context) => EmitSimdMultLdSt(Context, IsLoad: true);
+ public static void Ld__Vms(AILEmitterCtx Context) => EmitSimdMemMs(Context, IsLoad: true);
+ public static void Ld__Vss(AILEmitterCtx Context) => EmitSimdMemSs(Context, IsLoad: true);
public static void Mla_V(AILEmitterCtx Context) => EmitVectorMla(Context);
@@ -391,7 +312,7 @@ namespace ChocolArm64.Instruction
EmitVectorImmBinarySx(Context, OpCodes.Shr, (8 << (Op.Size + 1)) - Op.Imm);
}
- public static void St__V(AILEmitterCtx Context) => EmitSimdMultLdSt(Context, IsLoad: false);
+ public static void St__V(AILEmitterCtx Context) => EmitSimdMemMs(Context, IsLoad: false);
public static void Sub_V(AILEmitterCtx Context) => EmitVectorBinaryZx(Context, OpCodes.Sub);
@@ -571,9 +492,9 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
- private static void EmitSimdMultLdSt(AILEmitterCtx Context, bool IsLoad)
+ private static void EmitSimdMemMs(AILEmitterCtx Context, bool IsLoad)
{
- AOpCodeSimdMemMult Op = (AOpCodeSimdMemMult)Context.CurrOp;
+ AOpCodeSimdMemMs Op = (AOpCodeSimdMemMs)Context.CurrOp;
int Offset = 0;
@@ -644,6 +565,79 @@ namespace ChocolArm64.Instruction
}
}
+ private static void EmitSimdMemSs(AILEmitterCtx Context, bool IsLoad)
+ {
+ AOpCodeSimdMemSs Op = (AOpCodeSimdMemSs)Context.CurrOp;
+
+ //TODO: Replicate mode.
+
+ int Offset = 0;
+
+ for (int SElem = 0; SElem < Op.SElems; SElem++)
+ {
+ int Rt = (Op.Rt + SElem) & 0x1f;
+
+ if (IsLoad)
+ {
+ Context.EmitLdvec(Rt);
+ Context.EmitLdc_I4(Op.Index);
+ Context.EmitLdc_I4(Op.Size);
+ Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
+ Context.EmitLdint(Op.Rn);
+ Context.EmitLdc_I8(Offset);
+
+ Context.Emit(OpCodes.Add);
+
+ EmitReadZxCall(Context, Op.Size);
+
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.InsertVec));
+
+ Context.EmitStvec(Rt);
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Rt);
+ }
+ }
+ else
+ {
+ Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
+ Context.EmitLdint(Op.Rn);
+ Context.EmitLdc_I8(Offset);
+
+ Context.Emit(OpCodes.Add);
+
+ Context.EmitLdvec(Rt);
+ Context.EmitLdc_I4(Op.Index);
+ Context.EmitLdc_I4(Op.Size);
+
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.ExtractVec));
+
+ EmitWriteCall(Context, Op.Size);
+ }
+
+ Offset += 1 << Op.Size;
+ }
+
+ if (Op.WBack)
+ {
+ Context.EmitLdint(Op.Rn);
+
+ if (Op.Rm != ARegisters.ZRIndex)
+ {
+ Context.EmitLdint(Op.Rm);
+ }
+ else
+ {
+ Context.EmitLdc_I8(Offset);
+ }
+
+ Context.Emit(OpCodes.Add);
+
+ Context.EmitStint(Op.Rn);
+ }
+ }
+
private static void EmitVectorAddv(AILEmitterCtx Context)
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
@@ -780,6 +774,114 @@ namespace ChocolArm64.Instruction
});
}
+ private static void EmitVectorFcvtS(AILEmitterCtx Context)
+ {
+ EmitVectorCvtOp(Context, CvtDir.Fcvt, true);
+ }
+
+ private static void EmitVectorFcvtU(AILEmitterCtx Context)
+ {
+ EmitVectorCvtOp(Context, CvtDir.Fcvt, false);
+ }
+
+ private static void EmitVectorCvtfS(AILEmitterCtx Context)
+ {
+ EmitVectorCvtOp(Context, CvtDir.Cvtf, true);
+ }
+
+ private static void EmitVectorCvtfU(AILEmitterCtx Context)
+ {
+ EmitVectorCvtOp(Context, CvtDir.Cvtf, false);
+ }
+
+ private enum CvtDir
+ {
+ Fcvt,
+ Cvtf
+ }
+
+ private static void EmitVectorCvtOp(AILEmitterCtx Context, CvtDir Dir, bool Signed)
+ {
+ AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
+
+ int SizeF = Op.Size & 1;
+ int SizeI = SizeF + 2;
+
+ int FBits = 0;
+
+ if (Op is AOpCodeSimdShImm OpImm)
+ {
+ FBits = (8 << (Op.Size + 1)) - OpImm.Imm;
+ }
+
+ int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+ for (int Index = 0; Index < (Bytes >> SizeI); Index++)
+ {
+ EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
+
+ Context.EmitLdc_I4(FBits);
+
+ if (Dir == CvtDir.Fcvt)
+ {
+ //Float to Integer.
+ if (SizeF == 0)
+ {
+ ASoftFallback.EmitCall(Context, Signed
+ ? nameof(ASoftFallback.SatSingleToInt32)
+ : nameof(ASoftFallback.SatSingleToUInt32));
+ }
+ else if (SizeF == 1)
+ {
+ ASoftFallback.EmitCall(Context, Signed
+ ? nameof(ASoftFallback.SatDoubleToInt64)
+ : nameof(ASoftFallback.SatDoubleToUInt64));
+ }
+ }
+ else if (Dir == CvtDir.Cvtf)
+ {
+ //Integer to Float.
+ //TODO.
+ }
+
+ EmitVectorInsert(Context, Op.Rd, Index, SizeI);
+ }
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+
+ private static void EmitVectorBinaryFOp(AILEmitterCtx Context, OpCode ILOp)
+ {
+ EmitVectorBinaryFOp(Context, () => Context.Emit(ILOp));
+ }
+
+ private static void EmitVectorBinaryFOp(AILEmitterCtx Context, Action Emit)
+ {
+ AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
+
+ int SizeF = Op.Size & 1;
+
+ int Bytes = Context.CurrOp.GetBitsCount() >> 3;
+
+ for (int Index = 0; Index < (Bytes >> SizeF + 2); Index++)
+ {
+ EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
+ EmitVectorExtractF(Context, Op.Rm, Index, SizeF);
+
+ Emit();
+
+ EmitVectorInsertF(Context, Op.Rd, Index, SizeF);
+ }
+
+ if (Op.RegisterSize == ARegisterSize.SIMD64)
+ {
+ EmitVectorZeroUpper(Context, Op.Rd);
+ }
+ }
+
private static void EmitVectorUnarySx(AILEmitterCtx Context, OpCode ILOp)
{
EmitVectorUnarySx(Context, () => Context.Emit(ILOp));
@@ -957,6 +1059,25 @@ namespace ChocolArm64.Instruction
}
}
+ private static void EmitVectorExtractF(AILEmitterCtx Context, int Reg, int Index, int Size)
+ {
+ Context.EmitLdvec(Reg);
+ Context.EmitLdc_I4(Index);
+
+ if (Size == 0)
+ {
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorExtractSingle));
+ }
+ else if (Size == 1)
+ {
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorExtractDouble));
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(Size));
+ }
+ }
+
private static void EmitVectorExtractSx(AILEmitterCtx Context, int Reg, int Index)
{
EmitVectorExtract(Context, Reg, Index, true);
@@ -980,6 +1101,27 @@ namespace ChocolArm64.Instruction
: nameof(ASoftFallback.ExtractVec));
}
+ private static void EmitVectorInsertF(AILEmitterCtx Context, int Reg, int Index, int Size)
+ {
+ Context.EmitLdvec(Reg);
+ Context.EmitLdc_I4(Index);
+
+ if (Size == 0)
+ {
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorInsertSingle));
+ }
+ else if (Size == 1)
+ {
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorInsertDouble));
+ }
+ else
+ {
+ throw new ArgumentOutOfRangeException(nameof(Size));
+ }
+
+ Context.EmitStvec(Reg);
+ }
+
private static void EmitVectorZeroLower(AILEmitterCtx Context, int Rd)
{
EmitVectorInsert(Context, Rd, 0, 3, 0);
@@ -990,6 +1132,17 @@ namespace ChocolArm64.Instruction
EmitVectorInsert(Context, Rd, 1, 3, 0);
}
+ private static void EmitVectorInsert(AILEmitterCtx Context, int Reg, int Index, int Size)
+ {
+ Context.EmitLdvec(Reg);
+ Context.EmitLdc_I4(Index);
+ Context.EmitLdc_I4(Size);
+
+ ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorInsertInt));
+
+ Context.EmitStvec(Reg);
+ }
+
private static void EmitVectorInsert(AILEmitterCtx Context, int Reg, int Index, int Size, long Value)
{
Context.EmitLdvec(Reg);
diff --git a/Ryujinx/Cpu/Instruction/ASoftFallback.cs b/Ryujinx/Cpu/Instruction/ASoftFallback.cs
index 0d5271320..a7508d7f3 100644
--- a/Ryujinx/Cpu/Instruction/ASoftFallback.cs
+++ b/Ryujinx/Cpu/Instruction/ASoftFallback.cs
@@ -365,122 +365,6 @@ namespace ChocolArm64.Instruction
return Res;
}
- public static AVec Fadd64(AVec LHS, AVec RHS, int Size)
- {
- return Fadd(LHS, RHS, Size, 2);
- }
-
- public static AVec Fadd128(AVec LHS, AVec RHS, int Size)
- {
- return Fadd(LHS, RHS, Size, 4);
- }
-
- private static AVec Fadd(AVec LHS, AVec RHS, int Size, int Bytes)
- {
- AVec Res = new AVec();
-
- int Elems = Bytes >> Size;
-
- if (Size == 0)
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- float L = LHS.ExtractSingle(Index);
- float R = RHS.ExtractSingle(Index);
-
- Res = AVec.InsertSingle(Res, Index, L + R);
- }
- }
- else
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- double L = LHS.ExtractDouble(Index);
- double R = RHS.ExtractDouble(Index);
-
- Res = AVec.InsertDouble(Res, Index, L + R);
- }
- }
-
- return Res;
- }
-
- public static AVec Fcvtzs_V64(AVec Vector, int Size)
- {
- return Fcvtzs_V(Vector, Size, 2);
- }
-
- public static AVec Fcvtzs_V128(AVec Vector, int Size)
- {
- return Fcvtzs_V(Vector, Size, 4);
- }
-
- private static AVec Fcvtzs_V(AVec Vector, int Size, int Bytes)
- {
- AVec Res = new AVec();
-
- int Elems = Bytes >> Size;
-
- if (Size == 0)
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- float Value = Vector.ExtractSingle(Index);
-
- Res = InsertSVec(Res, Index, Size + 2, SatSingleToInt32(Value));
- }
- }
- else
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- double Value = Vector.ExtractDouble(Index);
-
- Res = InsertSVec(Res, Index, Size + 2, SatDoubleToInt64(Value));
- }
- }
-
- return Res;
- }
-
- public static AVec Fcvtzu_V_64(AVec Vector, int FBits, int Size)
- {
- return Fcvtzu_V(Vector, FBits, Size, 2);
- }
-
- public static AVec Fcvtzu_V_128(AVec Vector, int FBits, int Size)
- {
- return Fcvtzu_V(Vector, FBits, Size, 4);
- }
-
- private static AVec Fcvtzu_V(AVec Vector, int FBits, int Size, int Bytes)
- {
- AVec Res = new AVec();
-
- int Elems = Bytes >> Size;
-
- if (Size == 0)
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- float Value = Vector.ExtractSingle(Index);
-
- Res = InsertVec(Res, Index, Size + 2, SatSingleToUInt32(Value, FBits));
- }
- }
- else
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- double Value = Vector.ExtractDouble(Index);
-
- Res = InsertVec(Res, Index, Size + 2, SatDoubleToUInt64(Value, FBits));
- }
- }
-
- return Res;
- }
-
public static AVec Fmla64(AVec Res, AVec LHS, AVec RHS, int Size)
{
return Fmla(Res, LHS, RHS, Size, 2);
@@ -568,46 +452,6 @@ namespace ChocolArm64.Instruction
return InsertVec(new AVec(), Elem, Size, Value);
}
- public static AVec Fmul64(AVec LHS, AVec RHS, int Size)
- {
- return Fmul(LHS, RHS, Size, 2);
- }
-
- public static AVec Fmul128(AVec LHS, AVec RHS, int Size)
- {
- return Fmul(LHS, RHS, Size, 4);
- }
-
- private static AVec Fmul(AVec LHS, AVec RHS, int Size, int Bytes)
- {
- AVec Res = new AVec();
-
- int Elems = Bytes >> Size;
-
- if (Size == 0)
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- float L = LHS.ExtractSingle(Index);
- float R = RHS.ExtractSingle(Index);
-
- Res = AVec.InsertSingle(Res, Index, L * R);
- }
- }
- else
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- double L = LHS.ExtractDouble(Index);
- double R = RHS.ExtractDouble(Index);
-
- Res = AVec.InsertDouble(Res, Index, L * R);
- }
- }
-
- return Res;
- }
-
public static AVec Fmul_Ve64(AVec LHS, AVec RHS, int SIdx, int Size)
{
return Fmul_Ve(LHS, RHS, SIdx, Size, 2);
@@ -650,46 +494,6 @@ namespace ChocolArm64.Instruction
return Res;
}
- public static AVec Fsub64(AVec LHS, AVec RHS, int Size)
- {
- return Fsub(LHS, RHS, Size, 2);
- }
-
- public static AVec Fsub128(AVec LHS, AVec RHS, int Size)
- {
- return Fsub(LHS, RHS, Size, 4);
- }
-
- private static AVec Fsub(AVec LHS, AVec RHS, int Size, int Bytes)
- {
- AVec Res = new AVec();
-
- int Elems = Bytes >> Size;
-
- if (Size == 0)
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- float L = LHS.ExtractSingle(Index);
- float R = RHS.ExtractSingle(Index);
-
- Res = AVec.InsertSingle(Res, Index, L - R);
- }
- }
- else
- {
- for (int Index = 0; Index < Elems; Index++)
- {
- double L = LHS.ExtractDouble(Index);
- double R = RHS.ExtractDouble(Index);
-
- Res = AVec.InsertDouble(Res, Index, L - R);
- }
- }
-
- return Res;
- }
-
public static AVec Ins_Gp(AVec Res, ulong Value, int Elem, int Size)
{
return InsertVec(Res, Elem, Size, Value);
@@ -1126,6 +930,39 @@ namespace ChocolArm64.Instruction
throw new ArgumentOutOfRangeException(nameof(Size));
}
+ public static float VectorExtractSingle(AVec Vector, int Index)
+ {
+ return Vector.ExtractSingle(Index);
+ }
+
+ public static double VectorExtractDouble(AVec Vector, int Index)
+ {
+ return Vector.ExtractDouble(Index);
+ }
+
+ public static AVec VectorInsertSingle(float Value, AVec Vector, int Index)
+ {
+ return AVec.InsertSingle(Vector, Index, Value);
+ }
+
+ public static AVec VectorInsertDouble(double Value, AVec Vector, int Index)
+ {
+ return AVec.InsertDouble(Vector, Index, Value);
+ }
+
+ public static AVec VectorInsertInt(ulong Value, AVec Vector, int Index, int Size)
+ {
+ switch (Size)
+ {
+ case 0: return AVec.InsertByte (Vector, Index, (byte)Value);
+ case 1: return AVec.InsertUInt16(Vector, Index, (ushort)Value);
+ case 2: return AVec.InsertUInt32(Vector, Index, (uint)Value);
+ case 3: return AVec.InsertUInt64(Vector, Index, (ulong)Value);
+ }
+
+ throw new ArgumentOutOfRangeException(nameof(Size));
+ }
+
public static AVec InsertVec(AVec Vector, int Index, int Size, ulong Value)
{
switch (Size)
diff --git a/Ryujinx/Cpu/Memory/AMemory.cs b/Ryujinx/Cpu/Memory/AMemory.cs
index 8159b341e..7952186d5 100644
--- a/Ryujinx/Cpu/Memory/AMemory.cs
+++ b/Ryujinx/Cpu/Memory/AMemory.cs
@@ -1,3 +1,4 @@
+using ChocolArm64.Exceptions;
using ChocolArm64.State;
using System;
using System.Collections.Generic;
@@ -119,26 +120,46 @@ namespace ChocolArm64.Memory
public byte ReadByte(long Position)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Read);
+#endif
+
return *((byte*)(RamPtr + (uint)Position));
}
public ushort ReadUInt16(long Position)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Read);
+#endif
+
return *((ushort*)(RamPtr + (uint)Position));
}
public uint ReadUInt32(long Position)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Read);
+#endif
+
return *((uint*)(RamPtr + (uint)Position));
}
public ulong ReadUInt64(long Position)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Read);
+#endif
+
return *((ulong*)(RamPtr + (uint)Position));
}
public AVec ReadVector128(long Position)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Read);
+#endif
+
return new AVec()
{
X0 = ReadUInt64(Position + 0),
@@ -153,33 +174,61 @@ namespace ChocolArm64.Memory
public void WriteByte(long Position, byte Value)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Write);
+#endif
+
*((byte*)(RamPtr + (uint)Position)) = Value;
}
public void WriteUInt16(long Position, ushort Value)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Write);
+#endif
+
*((ushort*)(RamPtr + (uint)Position)) = Value;
}
public void WriteUInt32(long Position, uint Value)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Write);
+#endif
+
*((uint*)(RamPtr + (uint)Position)) = Value;
}
public void WriteUInt64(long Position, ulong Value)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Write);
+#endif
+
*((ulong*)(RamPtr + (uint)Position)) = Value;
}
public void WriteVector128(long Position, AVec Value)
{
+#if DEBUG
+ EnsureAccessIsValid(Position, AMemoryPerm.Write);
+#endif
+
WriteUInt64(Position + 0, Value.X0);
WriteUInt64(Position + 8, Value.X1);
}
- private bool IsPageCrossed(long Position, int Size)
+ private void EnsureAccessIsValid(long Position, AMemoryPerm Perm)
{
- return (Position & AMemoryMgr.PageMask) + Size > AMemoryMgr.PageSize;
+ if (!Manager.IsMapped(Position))
+ {
+ throw new VmmPageFaultException(Position);
+ }
+
+ if (!Manager.HasPermission(Position, Perm))
+ {
+ throw new VmmAccessViolationException(Position, Perm);
+ }
}
}
}
\ No newline at end of file
diff --git a/Ryujinx/Cpu/Memory/AMemoryMgr.cs b/Ryujinx/Cpu/Memory/AMemoryMgr.cs
index 0c2c5a50b..544e51302 100644
--- a/Ryujinx/Cpu/Memory/AMemoryMgr.cs
+++ b/Ryujinx/Cpu/Memory/AMemoryMgr.cs
@@ -1,5 +1,3 @@
-using ChocolArm64.Exceptions;
-using System;
using System.Runtime.CompilerServices;
namespace ChocolArm64.Memory
@@ -163,7 +161,7 @@ namespace ChocolArm64.Memory
{
while (Size > 0)
{
- if (!HasPTEntry(Position))
+ if (!IsMapped(Position))
{
long PhysPos = Allocator.Alloc(PageSize);
@@ -254,8 +252,13 @@ namespace ChocolArm64.Memory
return new AMemoryMapInfo(Start, Size, BaseEntry.Type, BaseEntry.Perm);
}
+ public bool HasPermission(long Position, AMemoryPerm Perm)
+ {
+ return GetPTEntry(Position).Perm.HasFlag(Perm);
+ }
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private bool HasPTEntry(long Position)
+ public bool IsMapped(long Position)
{
if (Position >> PTLvl0Bits + PTLvl1Bits + PTPageBits != 0)
{
diff --git a/Ryujinx/Loaders/Executable.cs b/Ryujinx/Loaders/Executable.cs
index 785a8c723..650436589 100644
--- a/Ryujinx/Loaders/Executable.cs
+++ b/Ryujinx/Loaders/Executable.cs
@@ -73,12 +73,14 @@ namespace Ryujinx.Loaders
MemoryType Type,
AMemoryPerm Perm)
{
- Memory.Manager.MapPhys(Position, Data.Count, (int)Type, Perm);
+ Memory.Manager.MapPhys(Position, Data.Count, (int)Type, AMemoryPerm.Write);
for (int Index = 0; Index < Data.Count; Index++)
{
Memory.WriteByte(Position + Index, Data[Index]);
}
+
+ Memory.Manager.Reprotect(Position, Data.Count, Perm);
}
private void MapBss(long Position, long Size)
diff --git a/Ryujinx/Logging.cs b/Ryujinx/Logging.cs
new file mode 100644
index 000000000..308f068f8
--- /dev/null
+++ b/Ryujinx/Logging.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+
+namespace Ryujinx
+{
+ public static class Logging
+ {
+ private static Stopwatch ExecutionTime = new Stopwatch();
+ private static string LogFileName = "Ryujinx.log";
+
+ public static bool EnableInfo = Config.LoggingEnableInfo;
+ public static bool EnableTrace = Config.LoggingEnableTrace;
+ public static bool EnableDebug = Config.LoggingEnableDebug;
+ public static bool EnableWarn = Config.LoggingEnableWarn;
+ public static bool EnableError = Config.LoggingEnableError;
+ public static bool EnableFatal = Config.LoggingEnableFatal;
+ public static bool EnableLogFile = Config.LoggingEnableLogFile;
+
+ static Logging()
+ {
+ ExecutionTime.Start();
+
+ if (File.Exists(LogFileName)) File.Delete(LogFileName);
+ }
+
+ public static string GetExecutionTime()
+ {
+ return ExecutionTime.ElapsedMilliseconds.ToString().PadLeft(8, '0') + "ms";
+ }
+
+ private static string WhoCalledMe()
+ {
+ return new StackTrace().GetFrame(2).GetMethod().Name;
+ }
+
+ private static void LogFile(string Message)
+ {
+ if (EnableLogFile)
+ {
+ using (StreamWriter Writer = File.AppendText(LogFileName))
+ {
+ Writer.WriteLine(Message);
+ }
+ }
+ }
+
+ public static void Info(string Message)
+ {
+ if (EnableInfo)
+ {
+ string Text = $"{GetExecutionTime()} | INFO > {Message}";
+
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.WriteLine(Text.PadLeft(Text.Length + 1, ' '));
+ Console.ResetColor();
+
+ LogFile(Text);
+ }
+ }
+
+ public static void Trace(string Message)
+ {
+ if (EnableTrace)
+ {
+ string Text = $"{GetExecutionTime()} | TRACE > {WhoCalledMe()} - {Message}";
+
+ Console.ForegroundColor = ConsoleColor.DarkGray;
+ Console.WriteLine(Text.PadLeft(Text.Length + 1, ' '));
+ Console.ResetColor();
+
+ LogFile(Text);
+ }
+ }
+
+ public static void Debug(string Message)
+ {
+ if (EnableDebug)
+ {
+ string Text = $"{GetExecutionTime()} | DEBUG > {WhoCalledMe()} - {Message}";
+
+ Console.ForegroundColor = ConsoleColor.Gray;
+ Console.WriteLine(Text.PadLeft(Text.Length + 1, ' '));
+ Console.ResetColor();
+
+ LogFile(Text);
+ }
+ }
+
+ public static void Warn(string Message)
+ {
+ if (EnableWarn)
+ {
+ string Text = $"{GetExecutionTime()} | WARN > {WhoCalledMe()} - {Message}";
+
+ Console.ForegroundColor = ConsoleColor.Yellow;
+ Console.WriteLine(Text.PadLeft(Text.Length + 1, ' '));
+ Console.ResetColor();
+
+ LogFile(Text);
+ }
+ }
+
+ public static void Error(string Message)
+ {
+ if (EnableError)
+ {
+ string Text = $"{GetExecutionTime()} | ERROR > {WhoCalledMe()} - {Message}";
+
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.WriteLine(Text.PadLeft(Text.Length + 1, ' '));
+ Console.ResetColor();
+
+ LogFile(Text);
+ }
+ }
+
+ public static void Fatal(string Message)
+ {
+ if (EnableFatal)
+ {
+ string Text = $"{GetExecutionTime()} | FATAL > {WhoCalledMe()} - {Message}";
+
+ Console.ForegroundColor = ConsoleColor.Magenta;
+ Console.WriteLine(Text.PadLeft(Text.Length + 1, ' '));
+ Console.ResetColor();
+
+ LogFile(Text);
+ }
+ }
+ }
+}
diff --git a/Ryujinx/OsHle/Ipc/IpcHandler.cs b/Ryujinx/OsHle/Ipc/IpcHandler.cs
index 4e57889a4..c8b26dba6 100644
--- a/Ryujinx/OsHle/Ipc/IpcHandler.cs
+++ b/Ryujinx/OsHle/Ipc/IpcHandler.cs
@@ -262,6 +262,8 @@ namespace Ryujinx.OsHle.Ipc
}
}
+ Logging.Debug($"IpcMessage: {DbgServiceName}");
+
if (ProcReq != null)
{
using (MemoryStream ResMS = new MemoryStream())
diff --git a/Ryujinx/OsHle/Objects/AudIAudioOut.cs b/Ryujinx/OsHle/Objects/AudIAudioOut.cs
index 965e840d4..029c058f2 100644
--- a/Ryujinx/OsHle/Objects/AudIAudioOut.cs
+++ b/Ryujinx/OsHle/Objects/AudIAudioOut.cs
@@ -1,15 +1,12 @@
using ChocolArm64.Memory;
+using OpenTK.Audio;
+using OpenTK.Audio.OpenAL;
using Ryujinx.OsHle.Handles;
using Ryujinx.OsHle.Ipc;
-using static Ryujinx.OsHle.Objects.ObjHelper;
-
using System;
using System.Collections.Generic;
using System.IO;
-using OpenTK.Audio;
-using OpenTK.Audio.OpenAL;
-
namespace Ryujinx.OsHle.Objects
{
class AudIAudioOut
@@ -22,7 +19,7 @@ namespace Ryujinx.OsHle.Objects
//IAudioOut
private static AudioOutState State = AudioOutState.Stopped;
- private static List KeysQueue = new List();
+ private static Queue KeysQueue = new Queue();
//OpenAL
private static bool OpenALInstalled = true;
@@ -48,9 +45,9 @@ namespace Ryujinx.OsHle.Objects
{
AudioCtx = new AudioContext(); //Create the audio context
}
- catch (Exception ex)
+ catch (Exception)
{
- Console.WriteLine("OpenAL Error! PS: Install OpenAL Core SDK!");
+ Logging.Warn("OpenAL Error! PS: Install OpenAL Core SDK!");
OpenALInstalled = false;
}
@@ -82,7 +79,7 @@ namespace Ryujinx.OsHle.Objects
{
long BufferId = Context.RequestData.ReadInt64();
- KeysQueue.Insert(0, BufferId);
+ KeysQueue.Enqueue(BufferId);
byte[] AudioOutBuffer = AMemoryHelper.ReadBytes(Context.Memory, Context.Request.SendBuff[0].Position, 0x28);
using (MemoryStream MS = new MemoryStream(AudioOutBuffer))
@@ -125,13 +122,9 @@ namespace Ryujinx.OsHle.Objects
{
long TempKey = 0;
- if (KeysQueue.Count > 0)
- {
- TempKey = KeysQueue[KeysQueue.Count - 1];
- KeysQueue.Remove(KeysQueue[KeysQueue.Count - 1]);
- }
+ if (KeysQueue.Count > 0) TempKey = KeysQueue.Dequeue();
- AMemoryHelper.WriteBytes(Context.Memory, Context.Request.ReceiveBuff[0].Position, System.BitConverter.GetBytes(TempKey));
+ AMemoryHelper.WriteBytes(Context.Memory, Context.Request.ReceiveBuff[0].Position, BitConverter.GetBytes(TempKey));
Context.ResponseData.Write((int)TempKey);
diff --git a/Ryujinx/OsHle/Services/ServiceNvDrv.cs b/Ryujinx/OsHle/Services/ServiceNvDrv.cs
index f410e1ab0..405eace2b 100644
--- a/Ryujinx/OsHle/Services/ServiceNvDrv.cs
+++ b/Ryujinx/OsHle/Services/ServiceNvDrv.cs
@@ -563,7 +563,7 @@ namespace Ryujinx.OsHle.Services
NvMap.Kind = Kind;
}
- Console.WriteLine($"NvMapIocAlloc at {NvMap.Address:x16}");
+ Logging.Debug($"NvMapIocAlloc at {NvMap.Address:x16}");
return 0;
}
diff --git a/Ryujinx/OsHle/Svc/SvcHandler.cs b/Ryujinx/OsHle/Svc/SvcHandler.cs
index 937c341e5..9aea2dedb 100644
--- a/Ryujinx/OsHle/Svc/SvcHandler.cs
+++ b/Ryujinx/OsHle/Svc/SvcHandler.cs
@@ -69,7 +69,9 @@ namespace Ryujinx.OsHle.Svc
if (SvcFuncs.TryGetValue(e.Id, out SvcFunc Func))
{
+ Logging.Trace($"{Func.Method.Name} called.");
Func(Ns, Registers, Memory);
+ Logging.Trace($"{Func.Method.Name} ended.");
}
else
{
diff --git a/Ryujinx/OsHle/Svc/SvcSystem.cs b/Ryujinx/OsHle/Svc/SvcSystem.cs
index fa39f5181..3c541381b 100644
--- a/Ryujinx/OsHle/Svc/SvcSystem.cs
+++ b/Ryujinx/OsHle/Svc/SvcSystem.cs
@@ -121,7 +121,7 @@ namespace Ryujinx.OsHle.Svc
string Str = AMemoryHelper.ReadAsciiString(Memory, Position, (int)Size);
- Console.WriteLine($"SvcOutputDebugString: {Str}");
+ Logging.Info($"SvcOutputDebugString: {Str}");
Registers.X0 = (int)SvcResult.Success;
}