68 lines
1.5 KiB
C++
68 lines
1.5 KiB
C++
#include "doctest.h"
|
|
|
|
#include <cpu/cpu.h>
|
|
#include <memory/ram.h>
|
|
|
|
TEST_CASE("EI followed by DI should not trigger interrupt")
|
|
{
|
|
u8 test_ram[] = {
|
|
0xFB, // EI
|
|
0xF3, // DI
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
RAM r(test_ram, 0x20, true);
|
|
Cpu cpu(&r);
|
|
|
|
cpu.state.IE = 0x1F; // Enable all types of interrupts
|
|
cpu.state.IF = 0x1F; // All interrupts pending
|
|
|
|
CHECK(cpu.state.PC == 0x0);
|
|
CHECK(cpu.state.IME == IME_OFF);
|
|
|
|
cpu.step();
|
|
|
|
CHECK(cpu.state.PC == 0x1);
|
|
CHECK(cpu.state.IME == IME_SCHEDULED);
|
|
|
|
cpu.step();
|
|
|
|
CHECK(cpu.state.PC == 0x2);
|
|
CHECK(cpu.state.IME == IME_OFF);
|
|
|
|
cpu.step();
|
|
|
|
CHECK(cpu.state.PC == 0x3);
|
|
CHECK(cpu.state.IME == IME_OFF);
|
|
}
|
|
|
|
TEST_CASE("interrupt triggers call to correct ISR")
|
|
{
|
|
RAM r(0x100);
|
|
Cpu cpu(&r);
|
|
|
|
cpu.state.IME = IME_ON;
|
|
cpu.state.IE = INT_MASK;
|
|
|
|
InterruptType it;
|
|
u8 expected_pc;
|
|
|
|
SUBCASE("VBlank") { it = INT_VBlank; expected_pc = 0x40; }
|
|
SUBCASE("LCDSTAT") { it = INT_LCDSTAT; expected_pc = 0x48; }
|
|
SUBCASE("Timer") { it = INT_Timer; expected_pc = 0x50; }
|
|
SUBCASE("Serial") { it = INT_Serial; expected_pc = 0x58; }
|
|
SUBCASE("Joypad") { it = INT_Joypad; expected_pc = 0x60; }
|
|
|
|
cpu.signalInterrupt(it);
|
|
|
|
CHECK(cpu.state.IF == it);
|
|
|
|
cpu.step();
|
|
|
|
CHECK(cpu.state.IF == 0);
|
|
CHECK(cpu.state.PC == expected_pc);
|
|
CHECK(cpu.state.IME == IME_OFF);
|
|
|
|
}
|