diff --git a/Ryujinx.Graphics.Gpu/Engine/MethodFirmware.cs b/Ryujinx.Graphics.Gpu/Engine/MethodFirmware.cs new file mode 100644 index 0000000000..25a48af9d4 --- /dev/null +++ b/Ryujinx.Graphics.Gpu/Engine/MethodFirmware.cs @@ -0,0 +1,12 @@ +using Ryujinx.Graphics.Gpu.State; + +namespace Ryujinx.Graphics.Gpu.Engine +{ + partial class Methods + { + private void FirmwareCall4(GpuState state, int argument) + { + state.Write(0xd00, 1); + } + } +} diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs index 823ac878a6..31769f5a23 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs @@ -83,6 +83,8 @@ namespace Ryujinx.Graphics.Gpu.Engine state.RegisterCallback(MethodOffset.Report, Report); + state.RegisterCallback(MethodOffset.FirmwareCall4, FirmwareCall4); + state.RegisterCallback(MethodOffset.UniformBufferUpdateData, 16, UniformBufferUpdate); state.RegisterCallback(MethodOffset.UniformBufferBindVertex, UniformBufferBindVertex); diff --git a/Ryujinx.Graphics.Gpu/MacroInterpreter.cs b/Ryujinx.Graphics.Gpu/MacroInterpreter.cs index c853da73fb..4287f05501 100644 --- a/Ryujinx.Graphics.Gpu/MacroInterpreter.cs +++ b/Ryujinx.Graphics.Gpu/MacroInterpreter.cs @@ -58,6 +58,8 @@ namespace Ryujinx.Graphics.Gpu private int _pipeOp; + private bool _ignoreExitFlag; + private int _pc; /// @@ -232,12 +234,19 @@ namespace Ryujinx.Graphics.Gpu { FetchOpCode(mme); } + else + { + // The delay slot instruction exit flag should be ignored. + _ignoreExitFlag = true; + } return true; } } - bool exit = (_opCode & 0x80) != 0; + bool exit = (_opCode & 0x80) != 0 && !_ignoreExitFlag; + + _ignoreExitFlag = false; return !exit; } diff --git a/Ryujinx.Graphics.Gpu/State/GpuState.cs b/Ryujinx.Graphics.Gpu/State/GpuState.cs index c6052f4a65..de09f3e7da 100644 --- a/Ryujinx.Graphics.Gpu/State/GpuState.cs +++ b/Ryujinx.Graphics.Gpu/State/GpuState.cs @@ -93,6 +93,16 @@ namespace Ryujinx.Graphics.Gpu.State return _backingMemory[offset]; } + /// + /// Writes data to the GPU register at the given offset. + /// + /// Offset to be written + /// Value to be written + public void Write(int offset, int value) + { + _backingMemory[offset] = value; + } + /// /// Writes an offset value at the uniform buffer offset register. /// diff --git a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs index 904cf8ff49..a89fc3797e 100644 --- a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs +++ b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs @@ -80,6 +80,14 @@ namespace Ryujinx.Graphics.Gpu.State BlendState = 0x780, VertexBufferEndAddress = 0x7c0, ShaderState = 0x800, + FirmwareCall0 = 0x8c0, + FirmwareCall1 = 0x8c1, + FirmwareCall2 = 0x8c2, + FirmwareCall3 = 0x8c3, + FirmwareCall4 = 0x8c4, + FirmwareCall5 = 0x8c5, + FirmwareCall6 = 0x8c6, + FirmwareCall7 = 0x8c7, UniformBufferState = 0x8e0, UniformBufferUpdateData = 0x8e4, UniformBufferBindVertex = 0x904,