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; }