Skip to content

Commit

Permalink
Add EXTD_SLP instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
TollyH committed Jun 1, 2024
1 parent 937d844 commit db559a2
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
7 changes: 7 additions & 0 deletions Data.cs
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,13 @@ public static class Data
{ ("EXTD_MPA", new OperandType[2] { OperandType.Register, OperandType.Pointer }), new Opcode(0x03, 0x30) },
{ ("EXTD_MPA", new OperandType[2] { OperandType.Address, OperandType.Pointer }), new Opcode(0x03, 0x31) },
{ ("EXTD_MPA", new OperandType[2] { OperandType.Pointer, OperandType.Pointer }), new Opcode(0x03, 0x32) },

// EXTD_SLP (Sleep)
{ ("EXTD_SLP", new OperandType[1] { OperandType.Register }), new Opcode(0x03, 0x40) },
{ ("EXTD_SLP", new OperandType[1] { OperandType.Literal }), new Opcode(0x03, 0x41) },
{ ("EXTD_SLP", new OperandType[1] { OperandType.Address }), new Opcode(0x03, 0x42) },
{ ("EXTD_SLP", new OperandType[1] { OperandType.Pointer }), new Opcode(0x03, 0x43) },

#endif

#if EXTENSION_SET_EXTERNAL_ASM
Expand Down
24 changes: 24 additions & 0 deletions Processor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3078,6 +3078,30 @@ is not (ulong)StatusFlags.Sign and not (ulong)StatusFlags.Overflow)
throw new InvalidOpcodeException(string.Format(Strings_Processor.Error_Opcode_Low_Extended_MovePointerAddress, opcodeLow));
}
break;
case 0x40: // Sleep
switch (opcodeLow)
{
case 0x0: // EXTD_SLP reg
result = ReadMemoryRegister(operandStart);
Registers[(ulong)Register.rpo]++;
break;
case 0x1: // EXTD_SLP lit
result = ReadMemoryQWord(operandStart);
Registers[(ulong)Register.rpo] += 8;
break;
case 0x2: // EXTD_SLP adr
result = ReadMemoryPointedQWord(operandStart);
Registers[(ulong)Register.rpo] += 8;
break;
case 0x3: // EXTD_SLP ptr
result = ReadMemoryRegisterPointedNumber(operandStart, out byteCount);
Registers[(ulong)Register.rpo] += byteCount;
break;
default:
throw new InvalidOpcodeException(string.Format(Strings_Processor.Error_Opcode_Low_Extended_Halt, opcodeLow));
}
Thread.Sleep(TimeSpan.FromMilliseconds(result));
break;
default:
throw new InvalidOpcodeException(string.Format(Strings_Processor.Error_Opcode_High_Extended, opcodeHigh));
}
Expand Down
60 changes: 59 additions & 1 deletion Test/ProcessorTests/FullOpcodeTest.Extended.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace AssEmbly.Test.ProcessorTests
using System.Diagnostics;

namespace AssEmbly.Test.ProcessorTests
{
public static partial class FullOpcodeTest
{
Expand Down Expand Up @@ -295,6 +297,62 @@ public void EXTD_MPA_Pointer_Pointer()
Assert.AreEqual(0x30609200UL, testProcessor.ReadMemoryQWord(0x140), "Instruction did not produce correct result");
Assert.AreEqual(0UL, testProcessor.Registers[(int)Register.rsf], "Instruction updated the status flags");
}

[TestMethod]
public void EXTD_SLP_Register()
{
Processor testProcessor = new(2046);
testProcessor.Registers[(int)Register.rg7] = 567;
testProcessor.LoadProgram(new byte[] { 0xFF, 0x03, 0x40, (int)Register.rg7 });
Stopwatch timer = Stopwatch.StartNew();
_ = testProcessor.Execute(false);
timer.Stop();
Assert.AreEqual(4UL, testProcessor.Registers[(int)Register.rpo], "Instruction updated the rpo register by an incorrect amount");
Assert.AreEqual(0UL, testProcessor.Registers[(int)Register.rsf], "Instruction updated the status flags");
Assert.IsTrue(timer.ElapsedMilliseconds is >= 500 and <= 1000, "Instruction did not sleep");
}

[TestMethod]
public void EXTD_SLP_Literal()
{
Processor testProcessor = new(2046);
testProcessor.LoadProgram(new byte[] { 0xFF, 0x03, 0x41, 0x37, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
Stopwatch timer = Stopwatch.StartNew();
_ = testProcessor.Execute(false);
timer.Stop();
Assert.AreEqual(11UL, testProcessor.Registers[(int)Register.rpo], "Instruction updated the rpo register by an incorrect amount");
Assert.AreEqual(0UL, testProcessor.Registers[(int)Register.rsf], "Instruction updated the status flags");
Assert.IsTrue(timer.ElapsedMilliseconds is >= 500 and <= 1000, "Instruction did not sleep");
}

[TestMethod]
public void EXTD_SLP_Address()
{
Processor testProcessor = new(2046);
testProcessor.LoadProgram(new byte[] { 0xFF, 0x03, 0x42, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
testProcessor.WriteMemoryQWord(0x140, 567);
Stopwatch timer = Stopwatch.StartNew();
_ = testProcessor.Execute(false);
timer.Stop();
Assert.AreEqual(11UL, testProcessor.Registers[(int)Register.rpo], "Instruction updated the rpo register by an incorrect amount");
Assert.AreEqual(0UL, testProcessor.Registers[(int)Register.rsf], "Instruction updated the status flags");
Assert.IsTrue(timer.ElapsedMilliseconds is >= 500 and <= 1000, "Instruction did not sleep");
}

[TestMethod]
public void EXTD_SLP_Pointer()
{
Processor testProcessor = new(2046);
testProcessor.Registers[(int)Register.rg7] = 0x140;
testProcessor.LoadProgram(new byte[] { 0xFF, 0x03, 0x43, (int)Register.rg7 });
testProcessor.WriteMemoryQWord(0x140, 567);
Stopwatch timer = Stopwatch.StartNew();
_ = testProcessor.Execute(false);
timer.Stop();
Assert.AreEqual(4UL, testProcessor.Registers[(int)Register.rpo], "Instruction updated the rpo register by an incorrect amount");
Assert.AreEqual(0UL, testProcessor.Registers[(int)Register.rsf], "Instruction updated the status flags");
Assert.IsTrue(timer.ElapsedMilliseconds is >= 500 and <= 1000, "Instruction did not sleep");
}
}
}
}

0 comments on commit db559a2

Please sign in to comment.