Просмотр исходного кода

Ignore exit flag on branch delay slot (#899)

gdkchan 6 лет назад
Родитель
Сommit
532ccf929a

+ 12 - 0
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);
+        }
+    }
+}

+ 2 - 0
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);

+ 10 - 1
Ryujinx.Graphics.Gpu/MacroInterpreter.cs

@@ -58,6 +58,8 @@ namespace Ryujinx.Graphics.Gpu
 
         private int _pipeOp;
 
+        private bool _ignoreExitFlag;
+
         private int _pc;
 
         /// <summary>
@@ -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;
         }

+ 10 - 0
Ryujinx.Graphics.Gpu/State/GpuState.cs

@@ -93,6 +93,16 @@ namespace Ryujinx.Graphics.Gpu.State
             return _backingMemory[offset];
         }
 
+        /// <summary>
+        /// Writes data to the GPU register at the given offset.
+        /// </summary>
+        /// <param name="offset">Offset to be written</param>
+        /// <param name="value">Value to be written</param>
+        public void Write(int offset, int value)
+        {
+            _backingMemory[offset] = value;
+        }
+
         /// <summary>
         /// Writes an offset value at the uniform buffer offset register.
         /// </summary>

+ 8 - 0
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,