CpuTest.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using ChocolArm64;
  2. using ChocolArm64.Memory;
  3. using ChocolArm64.State;
  4. using NUnit.Framework;
  5. using System;
  6. using System.Runtime.InteropServices;
  7. using System.Threading;
  8. namespace Ryujinx.Tests.Cpu
  9. {
  10. [TestFixture]
  11. public class CpuTest
  12. {
  13. protected long Position { get; private set; }
  14. private long Size;
  15. private long EntryPoint;
  16. private IntPtr Ram;
  17. private AMemory Memory;
  18. private AThread Thread;
  19. [SetUp]
  20. public void Setup()
  21. {
  22. Position = 0x0;
  23. Size = 0x1000;
  24. EntryPoint = Position;
  25. Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
  26. ATranslator Translator = new ATranslator();
  27. Memory = new AMemory(Ram);
  28. Memory.Manager.Map(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
  29. Thread = new AThread(Translator, Memory, ThreadPriority.Normal, EntryPoint);
  30. }
  31. [TearDown]
  32. public void Teardown()
  33. {
  34. Thread = null;
  35. Memory = null;
  36. Marshal.FreeHGlobal(Ram);
  37. }
  38. protected void Reset()
  39. {
  40. Teardown();
  41. Setup();
  42. }
  43. protected void Opcode(uint Opcode)
  44. {
  45. Thread.Memory.WriteUInt32(Position, Opcode);
  46. Position += 4;
  47. }
  48. protected void SetThreadState(ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X31 = 0,
  49. AVec V0 = default(AVec), AVec V1 = default(AVec), AVec V2 = default(AVec),
  50. bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false)
  51. {
  52. Thread.ThreadState.X0 = X0;
  53. Thread.ThreadState.X1 = X1;
  54. Thread.ThreadState.X2 = X2;
  55. Thread.ThreadState.X31 = X31;
  56. Thread.ThreadState.V0 = V0;
  57. Thread.ThreadState.V1 = V1;
  58. Thread.ThreadState.V2 = V2;
  59. Thread.ThreadState.Overflow = Overflow;
  60. Thread.ThreadState.Carry = Carry;
  61. Thread.ThreadState.Zero = Zero;
  62. Thread.ThreadState.Negative = Negative;
  63. }
  64. protected void ExecuteOpcodes()
  65. {
  66. using (ManualResetEvent Wait = new ManualResetEvent(false))
  67. {
  68. Thread.ThreadState.Break += (sender, e) => Thread.StopExecution();
  69. Thread.WorkFinished += (sender, e) => Wait.Set();
  70. Thread.Execute();
  71. Wait.WaitOne();
  72. }
  73. }
  74. protected AThreadState GetThreadState()
  75. {
  76. return Thread.ThreadState;
  77. }
  78. protected AThreadState SingleOpcode(uint Opcode,
  79. ulong X0 = 0, ulong X1 = 0, ulong X2 = 0, ulong X31 = 0,
  80. AVec V0 = default(AVec), AVec V1 = default(AVec), AVec V2 = default(AVec),
  81. bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false)
  82. {
  83. this.Opcode(Opcode);
  84. this.Opcode(0xD4200000); // BRK #0
  85. this.Opcode(0xD65F03C0); // RET
  86. SetThreadState(X0, X1, X2, X31, V0, V1, V2, Overflow, Carry, Zero, Negative);
  87. ExecuteOpcodes();
  88. return GetThreadState();
  89. }
  90. }
  91. }