diff --git a/Ryujinx.conf b/Ryujinx.conf index 590318fe..ee21ad90 100644 --- a/Ryujinx.conf +++ b/Ryujinx.conf @@ -2,10 +2,10 @@ Logging_Enable_Info = true #Enabled print trace logs -Logging_Enable_Trace = true +Logging_Enable_Trace = false #Enabled print debug logs -Logging_Enable_Debug = true +Logging_Enable_Debug = false #Enabled print warning logs Logging_Enable_Warn = true diff --git a/Ryujinx/Cpu/Decoder/ADecoder.cs b/Ryujinx/Cpu/Decoder/ADecoder.cs index 1d340039..5eb0e0dd 100644 --- a/Ryujinx/Cpu/Decoder/ADecoder.cs +++ b/Ryujinx/Cpu/Decoder/ADecoder.cs @@ -150,7 +150,8 @@ namespace ChocolArm64.Decoder private static bool IsException(AOpCode OpCode) { - return OpCode.Emitter == AInstEmit.Svc || + return OpCode.Emitter == AInstEmit.Brk || + OpCode.Emitter == AInstEmit.Svc || OpCode.Emitter == AInstEmit.Und; } diff --git a/Ryujinx/Cpu/Decoder/AOpCodeException.cs b/Ryujinx/Cpu/Decoder/AOpCodeException.cs index 6d4a0386..c3591a92 100644 --- a/Ryujinx/Cpu/Decoder/AOpCodeException.cs +++ b/Ryujinx/Cpu/Decoder/AOpCodeException.cs @@ -8,7 +8,7 @@ namespace ChocolArm64.Decoder public AOpCodeException(AInst Inst, long Position, int OpCode) : base(Inst, Position) { - Id = (OpCode >> 5) & 0xfff; + Id = (OpCode >> 5) & 0xffff; } } } \ No newline at end of file diff --git a/Ryujinx/Cpu/Instruction/AInstEmitException.cs b/Ryujinx/Cpu/Instruction/AInstEmitException.cs index 2f1edf78..c343291a 100644 --- a/Ryujinx/Cpu/Instruction/AInstEmitException.cs +++ b/Ryujinx/Cpu/Instruction/AInstEmitException.cs @@ -7,7 +7,17 @@ namespace ChocolArm64.Instruction { static partial class AInstEmit { + public static void Brk(AILEmitterCtx Context) + { + EmitExceptionCall(Context, nameof(ARegisters.OnBreak)); + } + public static void Svc(AILEmitterCtx Context) + { + EmitExceptionCall(Context, nameof(ARegisters.OnSvcCall)); + } + + private static void EmitExceptionCall(AILEmitterCtx Context, string MthdName) { AOpCodeException Op = (AOpCodeException)Context.CurrOp; @@ -17,7 +27,7 @@ namespace ChocolArm64.Instruction Context.EmitLdc_I4(Op.Id); - Context.EmitCall(typeof(ARegisters), nameof(ARegisters.OnSvcCall)); + Context.EmitCall(typeof(ARegisters), MthdName); if (Context.CurrBlock.Next != null) { diff --git a/Ryujinx/Cpu/State/SvcEventArgs.cs b/Ryujinx/Cpu/State/AExceptionEventArgs.cs similarity index 61% rename from Ryujinx/Cpu/State/SvcEventArgs.cs rename to Ryujinx/Cpu/State/AExceptionEventArgs.cs index 3a43241a..53d2ed48 100644 --- a/Ryujinx/Cpu/State/SvcEventArgs.cs +++ b/Ryujinx/Cpu/State/AExceptionEventArgs.cs @@ -2,11 +2,11 @@ using System; namespace ChocolArm64.State { - public class SvcEventArgs : EventArgs + public class AExceptionEventArgs : EventArgs { public int Id { get; private set; } - public SvcEventArgs(int Id) + public AExceptionEventArgs(int Id) { this.Id = Id; } diff --git a/Ryujinx/Cpu/State/ARegisters.cs b/Ryujinx/Cpu/State/ARegisters.cs index 76b8f9b3..1a8f2f13 100644 --- a/Ryujinx/Cpu/State/ARegisters.cs +++ b/Ryujinx/Cpu/State/ARegisters.cs @@ -42,12 +42,18 @@ namespace ChocolArm64.State public long CntpctEl0 => Environment.TickCount * TicksPerMS; - public event EventHandler SvcCall; - public event EventHandler Undefined; + public event EventHandler Break; + public event EventHandler SvcCall; + public event EventHandler Undefined; + + public void OnBreak(int Imm) + { + Break?.Invoke(this, new AExceptionEventArgs(Imm)); + } public void OnSvcCall(int Imm) { - SvcCall?.Invoke(this, new SvcEventArgs(Imm)); + SvcCall?.Invoke(this, new AExceptionEventArgs(Imm)); } public void OnUndefined() diff --git a/Ryujinx/OsHle/Exceptions/GuestBrokeExecutionException.cs b/Ryujinx/OsHle/Exceptions/GuestBrokeExecutionException.cs new file mode 100644 index 00000000..1369c57b --- /dev/null +++ b/Ryujinx/OsHle/Exceptions/GuestBrokeExecutionException.cs @@ -0,0 +1,11 @@ +using System; + +namespace Ryujinx.OsHle.Exceptions +{ + public class GuestBrokeExecutionException : Exception + { + private const string ExMsg = "The guest program broke execution!"; + + public GuestBrokeExecutionException() : base(ExMsg) { } + } +} \ No newline at end of file diff --git a/Ryujinx/OsHle/Objects/Am/IApplicationProxy.cs b/Ryujinx/OsHle/Objects/Am/IApplicationProxy.cs index 15940f67..3d692d6b 100644 --- a/Ryujinx/OsHle/Objects/Am/IApplicationProxy.cs +++ b/Ryujinx/OsHle/Objects/Am/IApplicationProxy.cs @@ -1,10 +1,9 @@ using Ryujinx.OsHle.Ipc; -using Ryujinx.OsHle.Objects.Am; using System.Collections.Generic; using static Ryujinx.OsHle.Objects.ObjHelper; -namespace Ryujinx.OsHle.Objects +namespace Ryujinx.OsHle.Objects.Am { class IApplicationProxy : IIpcInterface { diff --git a/Ryujinx/OsHle/Process.cs b/Ryujinx/OsHle/Process.cs index b723b165..3c91605a 100644 --- a/Ryujinx/OsHle/Process.cs +++ b/Ryujinx/OsHle/Process.cs @@ -1,7 +1,9 @@ using ChocolArm64; using ChocolArm64.Memory; +using ChocolArm64.State; using Ryujinx.Loaders; using Ryujinx.Loaders.Executables; +using Ryujinx.OsHle.Exceptions; using Ryujinx.OsHle.Handles; using Ryujinx.OsHle.Svc; using System; @@ -135,6 +137,7 @@ namespace Ryujinx.OsHle return -1; } + Thread.Registers.Break += BreakHandler; Thread.Registers.SvcCall += SvcHandler.SvcCall; Thread.Registers.ProcessId = ProcessId; Thread.Registers.ThreadId = Ns.Os.IdGen.GenerateId(); @@ -148,6 +151,11 @@ namespace Ryujinx.OsHle return Handle; } + private void BreakHandler(object sender, AExceptionEventArgs e) + { + throw new GuestBrokeExecutionException(); + } + private int GetFreeTlsSlot(AThread Thread) { for (int Index = 1; Index < TotalTlsSlots; Index++) diff --git a/Ryujinx/OsHle/ServiceCtx.cs b/Ryujinx/OsHle/ServiceCtx.cs index 61356e6c..501d8d0f 100644 --- a/Ryujinx/OsHle/ServiceCtx.cs +++ b/Ryujinx/OsHle/ServiceCtx.cs @@ -7,7 +7,7 @@ namespace Ryujinx.OsHle { class ServiceCtx { - public Switch Ns { get; private set; } + public Switch Ns { get; private set; } public AMemory Memory { get; private set; } public HSession Session { get; private set; } public IpcMessage Request { get; private set; } diff --git a/Ryujinx/OsHle/Services/ServiceAppletOE.cs b/Ryujinx/OsHle/Services/ServiceAppletOE.cs index cd0ed92b..9f2391df 100644 --- a/Ryujinx/OsHle/Services/ServiceAppletOE.cs +++ b/Ryujinx/OsHle/Services/ServiceAppletOE.cs @@ -1,4 +1,4 @@ -using Ryujinx.OsHle.Objects; +using Ryujinx.OsHle.Objects.Am; using static Ryujinx.OsHle.Objects.ObjHelper; diff --git a/Ryujinx/OsHle/Svc/SvcHandler.cs b/Ryujinx/OsHle/Svc/SvcHandler.cs index 9aea2ded..ccff71e4 100644 --- a/Ryujinx/OsHle/Svc/SvcHandler.cs +++ b/Ryujinx/OsHle/Svc/SvcHandler.cs @@ -63,7 +63,7 @@ namespace Ryujinx.OsHle.Svc Rng = new Random(); } - public void SvcCall(object sender, SvcEventArgs e) + public void SvcCall(object sender, AExceptionEventArgs e) { ARegisters Registers = (ARegisters)sender; @@ -75,7 +75,7 @@ namespace Ryujinx.OsHle.Svc } else { - throw new NotImplementedException(e.Id.ToString("x3")); + throw new NotImplementedException(e.Id.ToString("x4")); } } }