CpuTest.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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 AMemoryAlloc Allocator;
  18. private AMemory Memory;
  19. private AThread Thread;
  20. [SetUp]
  21. public void Setup()
  22. {
  23. Position = 0x0;
  24. Size = 0x1000;
  25. EntryPoint = Position;
  26. Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
  27. Allocator = new AMemoryAlloc();
  28. Memory = new AMemory(Ram, Allocator);
  29. Memory.Manager.MapPhys(Position, Size, 2, AMemoryPerm.Read | AMemoryPerm.Write | AMemoryPerm.Execute);
  30. Thread = new AThread(Memory, ThreadPriority.Normal, EntryPoint);
  31. }
  32. [TearDown]
  33. public void Teardown()
  34. {
  35. Thread = null;
  36. Memory = null;
  37. Allocator = null;
  38. Marshal.FreeHGlobal(Ram);
  39. }
  40. protected void Reset()
  41. {
  42. Teardown();
  43. Setup();
  44. }
  45. protected void Opcode(uint Opcode)
  46. {
  47. Thread.Memory.WriteUInt32(Position, Opcode);
  48. Position += 4;
  49. }
  50. protected void SetThreadState(ulong X0 = 0, ulong X1 = 0, ulong X2 = 0,
  51. AVec V0 = default(AVec), AVec V1 = default(AVec), AVec V2 = default(AVec),
  52. bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false)
  53. {
  54. Thread.ThreadState.X0 = X0;
  55. Thread.ThreadState.X1 = X1;
  56. Thread.ThreadState.X2 = X2;
  57. Thread.ThreadState.V0 = V0;
  58. Thread.ThreadState.V1 = V1;
  59. Thread.ThreadState.V2 = V2;
  60. Thread.ThreadState.Overflow = Overflow;
  61. Thread.ThreadState.Carry = Carry;
  62. Thread.ThreadState.Zero = Zero;
  63. Thread.ThreadState.Negative = Negative;
  64. }
  65. protected void ExecuteOpcodes()
  66. {
  67. using (ManualResetEvent Wait = new ManualResetEvent(false))
  68. {
  69. Thread.ThreadState.Break += (sender, e) => Thread.StopExecution();
  70. Thread.WorkFinished += (sender, e) => Wait.Set();
  71. Thread.Execute();
  72. Wait.WaitOne();
  73. }
  74. }
  75. protected AThreadState GetThreadState()
  76. {
  77. return Thread.ThreadState;
  78. }
  79. protected AThreadState SingleOpcode(uint Opcode,
  80. ulong X0 = 0, ulong X1 = 0, ulong X2 = 0,
  81. AVec V0 = default(AVec), AVec V1 = default(AVec), AVec V2 = default(AVec),
  82. bool Overflow = false, bool Carry = false, bool Zero = false, bool Negative = false)
  83. {
  84. this.Opcode(Opcode);
  85. this.Opcode(0xD4200000); // BRK #0
  86. this.Opcode(0xD65F03C0); // RET
  87. SetThreadState(X0, X1, X2, V0, V1, V2, Overflow, Carry, Zero, Negative);
  88. ExecuteOpcodes();
  89. return GetThreadState();
  90. }
  91. }
  92. }