Browse Source

Emulator: Implement RL/RR opcodes

master
Riyyi 2 years ago
parent
commit
fb6ba43ff1
  1. 88
      src/cpu-prefix.cpp
  2. 6
      src/cpu.cpp
  3. 2
      src/cpu.h

88
src/cpu-prefix.cpp

@ -28,6 +28,12 @@ void CPU::prefix()
else if (opcode >= 0x08 && opcode <= 0x0f) { else if (opcode >= 0x08 && opcode <= 0x0f) {
rrc(); rrc();
} }
else if (opcode >= 0x10 && opcode <= 0x17) {
rl();
}
else if (opcode >= 0x18 && opcode <= 0x1f) {
rr();
}
else if (opcode >= 0x30 && opcode <= 0x3f) { else if (opcode >= 0x30 && opcode <= 0x3f) {
swap(); swap();
} }
@ -385,6 +391,47 @@ void CPU::swap()
} }
} }
void CPU::rl()
{
auto rotate_left_carry = [this](uint32_t& register_) -> void {
// RL r8, flags: Z 0 0 C
m_wait_cycles += 8;
// Copy bit 7 into carry flag
uint32_t old_carry = m_cf != 0;
m_cf = (register_ & 0x80) == 0x80;
// Rotate register r8 left through carry
register_ = (old_carry | (register_ << 1)) & 0xff;
// Set other flags
m_zf = register_ == 0;
m_nf = 0;
m_hf = 0;
};
uint8_t opcode = pcRead();
switch (opcode) {
case 0x10: /* RL B */ rotate_left_carry(m_b); break;
case 0x11: /* RL C */ rotate_left_carry(m_c); break;
case 0x12: /* RL D */ rotate_left_carry(m_d); break;
case 0x13: /* RL E */ rotate_left_carry(m_e); break;
case 0x14: /* RL H */ rotate_left_carry(m_h); break;
case 0x15: /* RL L */ rotate_left_carry(m_l); break;
case 0x16: /* RL (HL) */ {
m_wait_cycles += 8; // + 8 = 16 total
uint32_t data = read(hl());
rotate_left_carry(data);
write(hl(), data);
break;
}
case 0x17: /* RL A */ rotate_left_carry(m_a); break;
default:
VERIFY_NOT_REACHED();
}
}
void CPU::rlc() void CPU::rlc()
{ {
auto rotate_left = [this](uint32_t& register_) -> void { auto rotate_left = [this](uint32_t& register_) -> void {
@ -426,6 +473,47 @@ void CPU::rlc()
} }
} }
void CPU::rr()
{
auto rotate_right_carry = [this](uint32_t& register_) -> void {
// RR r8, flags: Z 0 0 C
m_wait_cycles += 8;
// Copy bit 0 into carry flag
uint32_t old_carry = m_cf != 0;
m_cf = (register_ & 0x01) == 0x01;
// Rotate register r8 right through carry
register_ = ((register_ >> 1) | (old_carry << 7)) & 0xff;
// Set other flags
m_zf = register_ == 0;
m_nf = 0;
m_hf = 0;
};
uint8_t opcode = pcRead();
switch (opcode) {
case 0x18: /* RR B */ rotate_right_carry(m_b); break;
case 0x19: /* RR C */ rotate_right_carry(m_c); break;
case 0x1a: /* RR D */ rotate_right_carry(m_d); break;
case 0x1b: /* RR E */ rotate_right_carry(m_e); break;
case 0x1c: /* RR H */ rotate_right_carry(m_h); break;
case 0x1d: /* RR L */ rotate_right_carry(m_l); break;
case 0x1e: /* RR (HL) */ {
m_wait_cycles += 8; // + 8 = 16 total
uint32_t data = read(hl());
rotate_right_carry(data);
write(hl(), data);
break;
}
case 0x1f: /* RR A */ rotate_right_carry(m_a); break;
default:
VERIFY_NOT_REACHED();
}
}
void CPU::rrc() void CPU::rrc()
{ {
auto rotate_right = [this](uint32_t& register_) -> void { auto rotate_right = [this](uint32_t& register_) -> void {

6
src/cpu.cpp

@ -703,8 +703,9 @@ void CPU::ra()
// └─────────┘ // └─────────┘
// A // A
// Copy bit 7 into carry flag
uint32_t old_carry = m_cf != 0; uint32_t old_carry = m_cf != 0;
m_cf = (m_a & 0x80) == 0x80; // Copy bit 7 into carry flag m_cf = (m_a & 0x80) == 0x80;
// Rotate register A left through carry // Rotate register A left through carry
m_a = old_carry | (m_a << 1); m_a = old_carry | (m_a << 1);
@ -719,8 +720,9 @@ void CPU::ra()
// └─────────┘ // └─────────┘
// A // A
// Copy bit 0 into carry flag
uint32_t old_carry = m_cf != 0; uint32_t old_carry = m_cf != 0;
m_cf = (m_a & 0x1) == 0x1; // Copy bit 0 into carry flag m_cf = (m_a & 0x1) == 0x1;
// Rotate register A right through carry // Rotate register A right through carry
m_a = (m_a >> 1) | (old_carry << 7); m_a = (m_a >> 1) | (old_carry << 7);

2
src/cpu.h

@ -50,7 +50,9 @@ public:
// Bit Shift Instructions // Bit Shift Instructions
void ra(); void ra();
void rl();
void rlc(); void rlc();
void rr();
void rrc(); void rrc();
// ------------------------------------- // -------------------------------------

Loading…
Cancel
Save