TEST(IncDecInstructions, Inc8Bit) { CodeGenerator code; code.block( 0x3E, 0x01, // LD A,1 0x06, 0x02, // LD B,2 0x0E, 0x03, // LD C,3 0x16, 0x04, // LD D,4 0x1E, 0x05, // LD E,5 0x26, 0x06, // LD H,6 0x2E, 0x07, // LD L,7 0x3C, // INC A 0x04, // INC B 0x0C, // INC C 0x14, // INC D 0x1C, // INC E 0x24, // INC H 0x2C, // INC L 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.a, 2); EXPECT_EQ(status.b, 3); EXPECT_EQ(status.c, 4); EXPECT_EQ(status.d, 5); EXPECT_EQ(status.e, 6); EXPECT_EQ(status.h, 7); EXPECT_EQ(status.l, 8); }
TEST(IncDecInstructions, Dec8Bit) { CodeGenerator code; code.block( 0x3E, 0x01, // LD A,1 0x06, 0x02, // LD B,2 0x0E, 0x03, // LD C,3 0x16, 0x04, // LD D,4 0x1E, 0x05, // LD E,5 0x26, 0x06, // LD H,6 0x2E, 0x07, // LD L,7 0x3D, // DEC A 0x05, // DEC B 0x0D, // DEC C 0x15, // DEC D 0x1D, // DEC E 0x25, // DEC H 0x2D, // DEC L 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.a, 0); EXPECT_EQ(status.b, 1); EXPECT_EQ(status.c, 2); EXPECT_EQ(status.d, 3); EXPECT_EQ(status.e, 4); EXPECT_EQ(status.h, 5); EXPECT_EQ(status.l, 6); }
TEST(IncDecInstructions, Dec16Bit) { CodeGenerator code; code.block( 0x01, 0x34, 0x12, // LD BC,$1234 0x11, 0x78, 0x56, // LD DE,$5678 0x21, 0xBC, 0x9A, // LD HL,$9ABC 0x31, 0xFE, 0xFF, // LD SP,$FFFE 0x0B, // DEC BC 0x1B, // DEC DE 0x2B, // DEC HL 0x3B, // DEC SP 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.bc, 0x1233); EXPECT_EQ(status.de, 0x5677); EXPECT_EQ(status.hl, 0x9ABB); EXPECT_EQ(status.sp, 0xFFFD); }
static void testInvalidOpcode(uint8_t opcode) { CodeGenerator code; code.block( opcode, 0x76 ); GameboyCore gameboy; (void)run(gameboy, code.rom()); }
TEST(MiscInstructions, SetCarry) { CodeGenerator code; code.block( 0x37, 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.f & CPU::Flags::C, CPU::Flags::C); }
TEST(IncDecInstructions, HalfCarryFlag) { CodeGenerator code; code.block( 0x06, 0x0F, // LD B,$0F 0x04, // INC B 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.f & CPU::Flags::H, CPU::Flags::H); EXPECT_EQ(status.f & CPU::Flags::N, 0); }
TEST(MiscInstructions, ComplementA) { CodeGenerator code; code.block( 0x3E, 0x00, // LD A,$00 0x2F, // CPL 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.a, 0xFF); EXPECT_EQ(status.f & CPU::Flags::H, CPU::Flags::H); EXPECT_EQ(status.f & CPU::Flags::N, CPU::Flags::N); }
TEST(IncDecInstructions, HalfBorrow) { CodeGenerator code; code.block( 0x06, 0x10, // LD B,$10 0x05, // DEC B 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.f & CPU::Flags::C, 0); EXPECT_EQ(status.f & CPU::Flags::H, CPU::Flags::H); EXPECT_EQ(status.f & CPU::Flags::N, CPU::Flags::N); EXPECT_EQ(status.f & CPU::Flags::Z, 0); }
TEST(IncDecInstructions, ZeroFlag) { CodeGenerator code; code.block( 0x06, 0x1, // LD B,1 0x05, // DEC B 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.f & CPU::Flags::Z, CPU::Flags::Z); EXPECT_EQ(status.f & CPU::Flags::N, CPU::Flags::N); }
TEST(IncDecInstructions, DecMemory) { CodeGenerator code; code.block( 0x21, 0x00, 0xC0, // LD HL,$250 0x34, // INC (HL) 0x76 // halt ); GameboyCore gameboy; (void)run(gameboy, code.rom()); auto& mmu = gameboy.getMMU(); EXPECT_EQ(mmu->read(0xC000), 0x01); }
TEST(MiscInstructions, DAA) { CodeGenerator code; code.block( 0x3E, 0x45, // LD A,$45 0x06, 0x38, // LD B,$38 0x80, // ADD A,B 0x27, // DAA 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); EXPECT_EQ(status.a, 0x83); EXPECT_EQ(status.f & CPU::Flags::C, 0); EXPECT_EQ(status.f & CPU::Flags::Z, 0); EXPECT_EQ(status.f & CPU::Flags::H, 0); }
TEST(MiscInstructions, Swap) { CodeGenerator code; code.block( 0x3E, 0x12, // LD A,$12 0x06, 0x34, // LD B,$34 0x0E, 0x56, // LD C,$56 0x16, 0x78, // LD D,$78 0x1E, 0x9A, // LD E,$9A 0x26, 0xC0, // LD H,$C0 0x2E, 0xDE, // LD L,$DE 0x36, 0xF0, // LD (HL),$F0 0xCB, 0x37, // SWAP A 0xCB, 0x30, // SWAP B 0xCB, 0x31, // SWAP C 0xCB, 0x32, // SWAP D 0xCB, 0x33, // SWAP E 0xCB, 0x36, // SWAP (HL) 0xCB, 0x34, // SWAP H 0xCB, 0x35, // SWAP L 0x76 // halt ); GameboyCore gameboy; CPU::Status status = run(gameboy, code.rom()); auto& mmu = gameboy.getMMU(); EXPECT_EQ(status.a, 0x21); EXPECT_EQ(status.b, 0x43); EXPECT_EQ(status.c, 0x65); EXPECT_EQ(status.d, 0x87); EXPECT_EQ(status.e, 0xA9); EXPECT_EQ(status.h, 0x0C); EXPECT_EQ(status.l, 0xED); EXPECT_EQ(mmu->read(0xC0DE), 0x0F); }