Browse Source

Test: Add way to run opcodes in test cases, add test for ADC, POP, PUSH

master
Riyyi 2 years ago
parent
commit
3b132a6820
  1. 8
      src/cpu.cpp
  2. 124
      test/testcpu.cpp

8
src/cpu.cpp

@ -1363,9 +1363,9 @@ void CPU::pop()
m_wait_cycles += 12; m_wait_cycles += 12;
// Pop register r16 from stack // Pop register r16 from stack
register_low = read(m_sp); register_low = read(m_sp); // lsb(r16)
m_sp = (m_sp + 1) & 0xffff; m_sp = (m_sp + 1) & 0xffff;
register_high = read(m_sp); register_high = read(m_sp); // msb(r16)
m_sp = (m_sp + 1) & 0xffff; m_sp = (m_sp + 1) & 0xffff;
}; };
@ -1398,9 +1398,9 @@ void CPU::push()
// Push register r16 into stack // Push register r16 into stack
m_sp = (m_sp - 1) & 0xffff; m_sp = (m_sp - 1) & 0xffff;
write(m_sp, register_ >> 8); write(m_sp, register_ >> 8); // msb(r16)
m_sp = (m_sp - 1) & 0xffff; m_sp = (m_sp - 1) & 0xffff;
write(m_sp, register_ & 0xff); write(m_sp, register_ & 0xff); // lsb(r16)
}; };
uint8_t opcode = pcRead(); uint8_t opcode = pcRead();

124
test/testcpu.cpp

@ -4,7 +4,10 @@
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
*/ */
#include <vector>
#include "cpu.h" #include "cpu.h"
#include "emu.h"
#include "macro.h" #include "macro.h"
#include "testcase.h" #include "testcase.h"
#include "testsuite.h" #include "testsuite.h"
@ -23,6 +26,28 @@ struct CPUTest {
} }
}; };
CPU runCPUTest(std::vector<uint8_t> test)
{
CPU cpu(4000000);
Emu::the().destroy();
Emu::the().init(8000000);
Emu::the().addProcessingUnit("cpu", &cpu);
Emu::the().addMemorySpace("FULL", 0x0000, 0xffff);
// Load the test
for (size_t i = 0; i < test.size(); ++i) {
Emu::the().writeMemory(i, test[i]);
}
// Run the test
while (cpu.pc() < test.size()) {
Emu::the().update();
}
return cpu;
}
// ----------------------------------------- // -----------------------------------------
TEST_CASE(CPUIsCarry) TEST_CASE(CPUIsCarry)
@ -55,3 +80,102 @@ TEST_CASE(CPUIsCarry)
EXPECT(test.isCarry(0xff, 254, 2) == true); EXPECT(test.isCarry(0xff, 254, 2) == true);
} }
TEST_CASE(CPUAddPlusCarry)
{
CPU cpu(0);
// ADC A,E
std::vector<uint8_t> adc_r8 = {
// clang-format off
0x3e, 0xe1, // LD A,i8
0x1e, 0x0f, // LD E,i8
0x37, // SCF
0x8b, // ADC A,E
// clang-format on
};
cpu = runCPUTest(adc_r8);
EXPECT_EQ(cpu.a(), 0xf1);
EXPECT_EQ(cpu.zf(), 0x0);
EXPECT_EQ(cpu.nf(), 0x0);
EXPECT_EQ(cpu.hf(), 0x1);
EXPECT_EQ(cpu.cf(), 0x0);
// ADC A,i8
std::vector<uint8_t> adc_i8 = {
// clang-format off
0x3e, 0xe1, // LD A,i8
0x37, // SCF
0xce, 0x3b, // ADC A,i8
// clang-format on
};
cpu = runCPUTest(adc_i8);
EXPECT_EQ(cpu.a(), 0x1d);
EXPECT_EQ(cpu.zf(), 0x0);
EXPECT_EQ(cpu.nf(), 0x0);
EXPECT_EQ(cpu.hf(), 0x0);
EXPECT_EQ(cpu.cf(), 0x1);
// ADC A,(HL)
std::vector<uint8_t> adc_hl = {
// clang-format off
0x3e, 0xe1, // LD A,i8
0x36, 0x1e, // LD (HL),i8
0x37, // SCF
0x8e, // ADC A,(HL)
// clang-format on
};
cpu = runCPUTest(adc_hl);
EXPECT_EQ(cpu.a(), 0x0);
EXPECT_EQ(cpu.zf(), 0x1);
EXPECT_EQ(cpu.nf(), 0x0);
EXPECT_EQ(cpu.hf(), 0x1);
EXPECT_EQ(cpu.cf(), 0x1);
}
TEST_CASE(CPUSetStackPointer)
{
std::vector<uint8_t> test = { 0x31, 0xfe, 0xff }; // LD SP,i16
CPU cpu = runCPUTest(test);
EXPECT_EQ(cpu.sp(), 0xfffe);
}
TEST_CASE(CPUPushToStack)
{
// PUSH BC
std::vector<uint8_t> push_bc = {
// clang-format off
0x31, 0xfe, 0xff, // LD SP,i16
0x01, 0xfc, 0xff, // LD BC,i16
0xc5, // PUSH BC
// clang-format on
};
CPU cpu = runCPUTest(push_bc);
EXPECT_EQ(cpu.bc(), 0xfffc);
EXPECT_EQ(cpu.sp(), 0xfffc);
EXPECT_EQ(Emu::the().readMemory(0xfffd), 0xff);
EXPECT_EQ(Emu::the().readMemory(0xfffc), 0xfc);
}
TEST_CASE(CPUPopFromStack)
{
// POP BC
std::vector<uint8_t> pop_bc = {
// clang-format off
0x31, 0xfe, 0xff, // LD SP,i16
0x11, 0x5f, 0x3c, // LD DE,i16
0xd5, // PUSH DE
0xc1, // POP BC
// clang-format on
};
CPU cpu = runCPUTest(pop_bc);
EXPECT_EQ(cpu.bc(), 0x3c5f);
EXPECT_EQ(cpu.sp(), 0xfffe);
EXPECT_EQ(Emu::the().readMemory(0xfffd), 0x3c);
EXPECT_EQ(Emu::the().readMemory(0xfffc), 0x5f);
}

Loading…
Cancel
Save