summaryrefslogtreecommitdiff
path: root/Q1.tests/Core/ChipTests.cs
blob: 2b0d20f97b32ce4c29f53b01b38a3d40d0d93e7a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
namespace Q1.tests.Core;

using core.Arch;
using core.Arch.Constants;

[TestFixture]
public class ChipTests : ChipTestBase
{
    [TestCase(ChipRegisters.AX)]
    [TestCase(ChipRegisters.DX)]
    [TestCase(ChipRegisters.LX)]
    public void Register_ShouldRoundTrip(u8 register)
    {
        var chip = this.CreateChip();

        u16 value = (u16) (register * 0x1111); // unique value for each register
        chip.SetRegister(register, value);
        u16 readValue = chip.GetRegister(register);

        Assert.That(readValue, Is.EqualTo(value), $"Register {register:X2} should round trip");
    }

    [Test]
    public void PushPop_ShouldRoundTrip()
    {
        var chip = this.CreateChip();

        u16 value = 0xABCD;
        chip.Push(value);
        u16 poppedValue = chip.Pop();

        Assert.That(poppedValue, Is.EqualTo(value), "Popped value should match pushed value");
    }

    [Test]
    public void StackOverflow_ShouldThrow()
    {
        var chip = this.CreateChip();

        // Fill the stack to its limit
        for (int i = 0; i < ChipLayout.STACK_COUNT; i++)
            chip.Push((u16) i);

        // Next push should cause overflow
        Assert.Throws<InvalidOperationException>(() => chip.Push(0xFFFF), "Expected stack overflow to throw");
    }

    [Test]
    public void StackUnderflow_ShouldThrow()
    {
        var chip = this.CreateChip();
        
        // Attempt to pop from an empty stack
        Assert.Throws<InvalidOperationException>(() => chip.Pop(), "Expected stack underflow to throw");
    }
    
    [Test]
    public void InvalidRegisterAccess_ShouldThrow()
    {
        var chip = this.CreateChip();
        
        // Attempt to access an invalid register index
        Assert.Throws<InvalidOperationException>(() => chip.GetRegister(0xFF), "Expected invalid register access to throw");
        Assert.Throws<InvalidOperationException>(() => chip.SetRegister(0xFF, 0x1234), "Expected invalid register access to throw");
    }
    
    [Test]
    public void InterruptHandling_ShouldJumpToInterruptVector()
    {
        var chip = this.CreateChip();

        var originalPc = chip.Pc;
        
        // Set up an interrupt vector at 0xFFFE
        u16 interruptHandlerAddress = 0x1234;
        chip.RegisterInterruptHandler(8, interruptHandlerAddress); // Register handler for interrupt 8
        
        // Trigger the interrupt
        chip.Interrupt(8);
        
        Assert.Multiple(() =>
        {
            Assert.That(chip.Pc, Is.EqualTo(interruptHandlerAddress), "PC should jump to interrupt handler address");
            Assert.That(chip.Pop(), Is.EqualTo(originalPc), "PC should be pushed onto the stack during interrupt");
        });
    }
}