Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec0f8bf02e | ||
|
|
ac03d70d83 | ||
|
|
99c768d400 | ||
|
|
fb6ba43ff1 | ||
|
|
275cab4da4 | ||
|
|
d53f4759e3 |
+376
-4
@@ -14,13 +14,39 @@
|
|||||||
|
|
||||||
void CPU::prefix()
|
void CPU::prefix()
|
||||||
{
|
{
|
||||||
// Skip 0xcb opcode
|
// Note: All these opcodes are considered 2 bytes, as the prefix is included
|
||||||
|
|
||||||
|
// Skip 0xcb prefix opcode
|
||||||
m_pc = (m_pc + 1) & 0xffff;
|
m_pc = (m_pc + 1) & 0xffff;
|
||||||
|
|
||||||
// Read next opcode
|
// Read next opcode
|
||||||
uint8_t opcode = read(m_pc);
|
uint8_t opcode = read(m_pc);
|
||||||
print("running opcode: {:#04x} @ ({:#06x})\n", opcode, m_pc);
|
print("running opcode: {:#04x} @ ({:#06x})\n", opcode, m_pc);
|
||||||
if (opcode >= 0x40 && opcode <= 0x7f) {
|
if (opcode >= 0x00 && opcode <= 0x07) {
|
||||||
|
rlc();
|
||||||
|
}
|
||||||
|
else if (opcode >= 0x08 && opcode <= 0x0f) {
|
||||||
|
rrc();
|
||||||
|
}
|
||||||
|
else if (opcode >= 0x10 && opcode <= 0x17) {
|
||||||
|
rl();
|
||||||
|
}
|
||||||
|
else if (opcode >= 0x18 && opcode <= 0x1f) {
|
||||||
|
rr();
|
||||||
|
}
|
||||||
|
else if (opcode >= 0x20 && opcode <= 0x27) {
|
||||||
|
sla();
|
||||||
|
}
|
||||||
|
else if (opcode >= 0x28 && opcode <= 0x2f) {
|
||||||
|
sra();
|
||||||
|
}
|
||||||
|
else if (opcode >= 0x30 && opcode <= 0x37) {
|
||||||
|
swap();
|
||||||
|
}
|
||||||
|
else if (opcode >= 0x38 && opcode <= 0x3f) {
|
||||||
|
srl();
|
||||||
|
}
|
||||||
|
else if (opcode >= 0x40 && opcode <= 0x7f) {
|
||||||
bit();
|
bit();
|
||||||
}
|
}
|
||||||
else if (opcode >= 0x80 && opcode <= 0xbf) {
|
else if (opcode >= 0x80 && opcode <= 0xbf) {
|
||||||
@@ -31,7 +57,7 @@ void CPU::prefix()
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print("opcode {:#04x} not implemented\n", opcode);
|
print("opcode {:#04x} not implemented\n", opcode);
|
||||||
print("immediate: {:#04x}\n", m_pc, pcRead());
|
print("immediate: {:#04x}\n", pcRead());
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,7 +354,353 @@ void CPU::set()
|
|||||||
case 0x7c: /* SET 7,H */ set_bit(0x80, m_h); break;
|
case 0x7c: /* SET 7,H */ set_bit(0x80, m_h); break;
|
||||||
case 0x7d: /* SET 7,L */ set_bit(0x80, m_l); break;
|
case 0x7d: /* SET 7,L */ set_bit(0x80, m_l); break;
|
||||||
case 0x7e: /* SET 7,(HL) */ set_bit_hl(0x80); break;
|
case 0x7e: /* SET 7,(HL) */ set_bit_hl(0x80); break;
|
||||||
case 0x7f: /* RES 7,A */ set_bit(0x80, m_a); break;
|
case 0x7f: /* SET 7,A */ set_bit(0x80, m_a); break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPU::swap()
|
||||||
|
{
|
||||||
|
auto swap_bits = [this](uint32_t& register_) -> void {
|
||||||
|
// SWAP r8, flags: Z 0 0 0
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
|
// Swap upper 4 bits in register r8 with lower 4 bits
|
||||||
|
register_ = register_ & 0xff;
|
||||||
|
register_ = (register_ >> 4) | (register_ << 4);
|
||||||
|
|
||||||
|
// Set flags
|
||||||
|
m_zf = register_ == 0;
|
||||||
|
m_nf = 0;
|
||||||
|
m_hf = 0;
|
||||||
|
m_cf = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t opcode = pcRead();
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x78: /* SWAP B */ swap_bits(m_b); break;
|
||||||
|
case 0x79: /* SWAP C */ swap_bits(m_c); break;
|
||||||
|
case 0x7a: /* SWAP D */ swap_bits(m_d); break;
|
||||||
|
case 0x7b: /* SWAP E */ swap_bits(m_e); break;
|
||||||
|
case 0x7c: /* SWAP H */ swap_bits(m_h); break;
|
||||||
|
case 0x7d: /* SWAP L */ swap_bits(m_l); break;
|
||||||
|
case 0x7e: /* SWAP (HL) */ {
|
||||||
|
m_wait_cycles += 8; // + 8 = 16 total
|
||||||
|
|
||||||
|
// Swap upper 4 bits in the byte pointed by HL with lower 4 bits
|
||||||
|
uint32_t data = read(hl());
|
||||||
|
swap_bits(data);
|
||||||
|
write(hl(), data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x7f: /* SWAP A */ swap_bits(m_a); break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
auto rotate_left = [this](uint32_t& register_) -> void {
|
||||||
|
// RLC r8, flags: Z 0 0 C
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
|
// Copy bit 7 into carry flag
|
||||||
|
m_cf = (register_ & 0x80) == 0x80;
|
||||||
|
|
||||||
|
// Rotate register r8 left
|
||||||
|
register_ = ((register_ >> 7) | (register_ << 1)) & 0xff;
|
||||||
|
|
||||||
|
// Set other flags
|
||||||
|
m_zf = register_ == 0;
|
||||||
|
m_nf = 0;
|
||||||
|
m_hf = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t opcode = pcRead();
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x00: /* RLC B */ rotate_left(m_b); break;
|
||||||
|
case 0x01: /* RLC C */ rotate_left(m_c); break;
|
||||||
|
case 0x02: /* RLC D */ rotate_left(m_d); break;
|
||||||
|
case 0x03: /* RLC E */ rotate_left(m_e); break;
|
||||||
|
case 0x04: /* RLC H */ rotate_left(m_h); break;
|
||||||
|
case 0x05: /* RLC L */ rotate_left(m_l); break;
|
||||||
|
case 0x06: /* RLC (HL) */ {
|
||||||
|
m_wait_cycles += 8; // + 8 = 16 total
|
||||||
|
|
||||||
|
// Rotate the byte pointed to by HL left
|
||||||
|
uint32_t data = read(hl());
|
||||||
|
rotate_left(data);
|
||||||
|
write(hl(), data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x07: /* RLC A */ rotate_left(m_a); break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
auto rotate_right = [this](uint32_t& register_) -> void {
|
||||||
|
// RRC r8, flags: Z 0 0 C
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
|
// Copy bit 0 into carry flag
|
||||||
|
m_cf = (register_ & 0x1) == 0x1;
|
||||||
|
|
||||||
|
// Rotate register r8 right
|
||||||
|
register_ = ((register_ >> 1) | (register_ << 7)) & 0xff;
|
||||||
|
|
||||||
|
// Set other flags
|
||||||
|
m_zf = register_ == 0;
|
||||||
|
m_nf = 0;
|
||||||
|
m_hf = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t opcode = pcRead();
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x08: /* RRC B */ rotate_right(m_b); break;
|
||||||
|
case 0x09: /* RRC C */ rotate_right(m_c); break;
|
||||||
|
case 0x0a: /* RRC D */ rotate_right(m_d); break;
|
||||||
|
case 0x0b: /* RRC E */ rotate_right(m_e); break;
|
||||||
|
case 0x0c: /* RRC H */ rotate_right(m_h); break;
|
||||||
|
case 0x0d: /* RRC L */ rotate_right(m_l); break;
|
||||||
|
case 0x0e: /* RRC (HL) */ {
|
||||||
|
m_wait_cycles += 8; // + 8 = 16 total
|
||||||
|
|
||||||
|
// Rotate the byte pointed to by HL right
|
||||||
|
uint32_t data = read(hl());
|
||||||
|
rotate_right(data);
|
||||||
|
write(hl(), data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0f: /* RRC A */ rotate_right(m_a); break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPU::sla()
|
||||||
|
{
|
||||||
|
auto shift_left_arithmatically = [this](uint32_t& register_) -> void {
|
||||||
|
// SLA r8, flags: Z 0 0 C
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
|
// Shift Left Arithmetically register r8
|
||||||
|
// ┌─────────┐
|
||||||
|
// C <─│7 <── 0│<─ 0
|
||||||
|
// └─────────┘
|
||||||
|
// r8
|
||||||
|
|
||||||
|
// Copy bit 7 into carry flag
|
||||||
|
m_cf = (m_a & 0x80) == 0x80;
|
||||||
|
|
||||||
|
// Shift Left Arithmetically register r8
|
||||||
|
register_ = (register_ << 1) & 0xff;
|
||||||
|
|
||||||
|
// Set other flags
|
||||||
|
m_zf = register_ == 0;
|
||||||
|
m_nf = 0;
|
||||||
|
m_hf = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t opcode = pcRead();
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x20: /* SLA B */ shift_left_arithmatically(m_b); break;
|
||||||
|
case 0x21: /* SLA C */ shift_left_arithmatically(m_c); break;
|
||||||
|
case 0x22: /* SLA D */ shift_left_arithmatically(m_d); break;
|
||||||
|
case 0x23: /* SLA E */ shift_left_arithmatically(m_e); break;
|
||||||
|
case 0x24: /* SLA H */ shift_left_arithmatically(m_h); break;
|
||||||
|
case 0x25: /* SLA L */ shift_left_arithmatically(m_l); break;
|
||||||
|
case 0x26: /* SLA (HL) */ {
|
||||||
|
m_wait_cycles += 8; // + 8 = 16 total
|
||||||
|
|
||||||
|
// Rotate the byte pointed to by HL right
|
||||||
|
uint32_t data = read(hl());
|
||||||
|
shift_left_arithmatically(data);
|
||||||
|
write(hl(), data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x27: /* SLA A */ shift_left_arithmatically(m_a); break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPU::sra()
|
||||||
|
{
|
||||||
|
auto shift_right_arithmatically = [this](uint32_t& register_) -> void {
|
||||||
|
// SRL r8, flags: Z 0 0 C
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
|
// Shift Right Arithmatically register r8
|
||||||
|
// ┌─────────┐
|
||||||
|
// ┌─│7 ──> 0│─> C
|
||||||
|
// │ └─────────┘
|
||||||
|
// │ ^ r8
|
||||||
|
// └──┘
|
||||||
|
|
||||||
|
// Copy bit 0 into carry flag
|
||||||
|
m_cf = (m_a & 0x01) == 0x01;
|
||||||
|
|
||||||
|
// Shift Right Arithmatically register r8
|
||||||
|
register_ = (register_ >> 1) | (register_ & 0x80); // Note: bit 7 remains
|
||||||
|
|
||||||
|
// Set other flags
|
||||||
|
m_zf = register_ == 0;
|
||||||
|
m_nf = 0;
|
||||||
|
m_hf = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t opcode = pcRead();
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x28: /* SRA B */ shift_right_arithmatically(m_b); break;
|
||||||
|
case 0x29: /* SRA C */ shift_right_arithmatically(m_c); break;
|
||||||
|
case 0x2a: /* SRA D */ shift_right_arithmatically(m_d); break;
|
||||||
|
case 0x2b: /* SRA E */ shift_right_arithmatically(m_e); break;
|
||||||
|
case 0x2c: /* SRA H */ shift_right_arithmatically(m_h); break;
|
||||||
|
case 0x2d: /* SRA L */ shift_right_arithmatically(m_l); break;
|
||||||
|
case 0x2e: /* SRA (HL) */ {
|
||||||
|
m_wait_cycles += 8; // + 8 = 16 total
|
||||||
|
|
||||||
|
// Rotate the byte pointed to by HL right
|
||||||
|
uint32_t data = read(hl());
|
||||||
|
shift_right_arithmatically(data);
|
||||||
|
write(hl(), data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x2f: /* SRA A */ shift_right_arithmatically(m_a); break;
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPU::srl()
|
||||||
|
{
|
||||||
|
auto shift_right_logically = [this](uint32_t& register_) -> void {
|
||||||
|
// SRL r8, flags: Z 0 0 C
|
||||||
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
|
// Shift Right Locically register r8
|
||||||
|
// ┌─────────┐
|
||||||
|
// 0 ─>│7 ──> 0│─> C
|
||||||
|
// └─────────┘
|
||||||
|
// r8
|
||||||
|
|
||||||
|
// Copy bit 0 into carry flag
|
||||||
|
m_cf = (m_a & 0x01) == 0x01;
|
||||||
|
|
||||||
|
// Shift Right Locically register r8
|
||||||
|
register_ = (register_ >> 1) & 0x7f; // Note: bit 7 is set to 0
|
||||||
|
|
||||||
|
// Set other flags
|
||||||
|
m_zf = register_ == 0;
|
||||||
|
m_nf = 0;
|
||||||
|
m_hf = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint8_t opcode = pcRead();
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x38: /* SRL B */ shift_right_logically(m_b); break;
|
||||||
|
case 0x39: /* SRL C */ shift_right_logically(m_c); break;
|
||||||
|
case 0x3a: /* SRL D */ shift_right_logically(m_d); break;
|
||||||
|
case 0x3b: /* SRL E */ shift_right_logically(m_e); break;
|
||||||
|
case 0x3c: /* SRL H */ shift_right_logically(m_h); break;
|
||||||
|
case 0x3d: /* SRL L */ shift_right_logically(m_l); break;
|
||||||
|
case 0x3e: /* SRL (HL) */ {
|
||||||
|
m_wait_cycles += 8; // + 8 = 16 total
|
||||||
|
|
||||||
|
// Rotate the byte pointed to by HL right
|
||||||
|
uint32_t data = read(hl());
|
||||||
|
shift_right_logically(data);
|
||||||
|
write(hl(), data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x3f: /* SRL A */ shift_right_logically(m_a); break;
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-27
@@ -228,7 +228,7 @@ void CPU::update()
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
print("opcode {:#x} not implemented\n", opcode);
|
print("opcode {:#x} not implemented\n", opcode);
|
||||||
print("immediate: {:#04x}\n", m_pc, pcRead());
|
print("immediate: {:#04x}\n", pcRead());
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -308,19 +308,19 @@ void CPU::and8()
|
|||||||
|
|
||||||
void CPU::dec8()
|
void CPU::dec8()
|
||||||
{
|
{
|
||||||
auto decrement = [this](uint32_t& reg) -> void {
|
auto decrement = [this](uint32_t& register_) -> void {
|
||||||
// DEC r8, flags: Z 1 H -
|
// DEC r8, flags: Z 1 H -
|
||||||
m_wait_cycles += 4;
|
m_wait_cycles += 4;
|
||||||
|
|
||||||
// Set flags
|
// Set flags
|
||||||
m_nf = 1;
|
m_nf = 1;
|
||||||
m_hf = isCarry(reg, -1, 0x10);
|
m_hf = isCarry(register_, -1, 0x10);
|
||||||
|
|
||||||
// Decrement value in register r8 by 1
|
// Decrement value in register r8 by 1
|
||||||
reg = (reg - 1) & 0xff;
|
register_ = (register_ - 1) & 0xff;
|
||||||
|
|
||||||
// Zero flag
|
// Zero flag
|
||||||
m_zf = reg == 0;
|
m_zf = register_ == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t opcode = pcRead();
|
uint8_t opcode = pcRead();
|
||||||
@@ -410,17 +410,17 @@ void CPU::lda8()
|
|||||||
|
|
||||||
void CPU::addr16()
|
void CPU::addr16()
|
||||||
{
|
{
|
||||||
auto add = [this](uint32_t reg) -> void {
|
auto add = [this](uint32_t register_) -> void {
|
||||||
// ADD HL,r16, flags: - 0 H C
|
// ADD HL,r16, flags: - 0 H C
|
||||||
m_wait_cycles += 8;
|
m_wait_cycles += 8;
|
||||||
|
|
||||||
// Set flags
|
// Set flags
|
||||||
m_nf = 0;
|
m_nf = 0;
|
||||||
m_hf = isCarry(hl(), reg, 0x1000);
|
m_hf = isCarry(hl(), register_, 0x1000);
|
||||||
m_cf = isCarry(hl(), reg, 0x10000);
|
m_cf = isCarry(hl(), register_, 0x10000);
|
||||||
|
|
||||||
// Add the value in r16 to HL
|
// Add the value in r16 to HL
|
||||||
uint32_t data = (hl() + reg) & 0xffff;
|
uint32_t data = (hl() + register_) & 0xffff;
|
||||||
m_l = data & 0xff;
|
m_l = data & 0xff;
|
||||||
m_h = data >> 8;
|
m_h = data >> 8;
|
||||||
};
|
};
|
||||||
@@ -666,8 +666,7 @@ void CPU::ra()
|
|||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case 0x07: // RLCA
|
case 0x07: // RLCA
|
||||||
|
|
||||||
// Rotates A to the left with bit 7 being moved to bit 0 and also stored
|
// Rotates A to the left
|
||||||
// into the carry
|
|
||||||
// ┌──────────────┐
|
// ┌──────────────┐
|
||||||
// │ ┌─────────┐ │
|
// │ ┌─────────┐ │
|
||||||
// C <─┴─│7 <── 0│<─┘
|
// C <─┴─│7 <── 0│<─┘
|
||||||
@@ -678,12 +677,11 @@ void CPU::ra()
|
|||||||
m_cf = (m_a & 0x80) == 0x80;
|
m_cf = (m_a & 0x80) == 0x80;
|
||||||
|
|
||||||
// Rotate register A left
|
// Rotate register A left
|
||||||
m_a = (m_a << 1) | (m_a >> 7);
|
m_a = (m_a >> 7) | (m_a << 1);
|
||||||
break;
|
break;
|
||||||
case 0x0f: // RRCA
|
case 0x0f: // RRCA
|
||||||
|
|
||||||
// Rotates A to the right with bit 0 being moved to bit 7 and also
|
// Rotates A to the right
|
||||||
// stored into the carry
|
|
||||||
// ┌──────────────┐
|
// ┌──────────────┐
|
||||||
// │ ┌─────────┐ │
|
// │ ┌─────────┐ │
|
||||||
// └─>│7 ──> 0│─┴─> C
|
// └─>│7 ──> 0│─┴─> C
|
||||||
@@ -694,40 +692,40 @@ void CPU::ra()
|
|||||||
m_cf = (m_a & 0x1) == 0x1;
|
m_cf = (m_a & 0x1) == 0x1;
|
||||||
|
|
||||||
// Rotate register A right
|
// Rotate register A right
|
||||||
m_a = (m_a << 7) | (m_a >> 1);
|
m_a = (m_a >> 1) | (m_a << 7);
|
||||||
break;
|
break;
|
||||||
case 0x17: { // RLA
|
case 0x17: { // RLA
|
||||||
|
|
||||||
// Rotates A to the left with the carry's value put into bit 0 and bit 7
|
// Rotate register A left through carry
|
||||||
// is put into the carry
|
|
||||||
// ┌────────────────────┐
|
// ┌────────────────────┐
|
||||||
// │ ┌─────────┐ │
|
// │ ┌─────────┐ │
|
||||||
// └─ C <──│7 <── 0│<─┘
|
// └─ C <──│7 <── 0│<─┘
|
||||||
// └─────────┘
|
// └─────────┘
|
||||||
// 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 = (m_a << 1) | old_carry;
|
m_a = old_carry | (m_a << 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x1f: { // RRA
|
case 0x1f: { // RRA
|
||||||
|
|
||||||
// Rotates A to the right with the carry's value put into bit 7 and bit 0
|
// Rotate register A right through carry
|
||||||
// is put into the carry
|
|
||||||
// ┌────────────────────┐
|
// ┌────────────────────┐
|
||||||
// │ ┌─────────┐ │
|
// │ ┌─────────┐ │
|
||||||
// └─>│7 ──> 0│──> C ─┘
|
// └─>│7 ──> 0│──> C ─┘
|
||||||
// └─────────┘
|
// └─────────┘
|
||||||
// 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 = (old_carry << 7) | (m_a >> 1);
|
m_a = (m_a >> 1) | (old_carry << 7);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -784,19 +782,19 @@ void CPU::cp()
|
|||||||
|
|
||||||
void CPU::inc()
|
void CPU::inc()
|
||||||
{
|
{
|
||||||
auto increment = [this](uint32_t& reg) -> void {
|
auto increment = [this](uint32_t& register_) -> void {
|
||||||
// INC r8, flags: Z 0 H -
|
// INC r8, flags: Z 0 H -
|
||||||
m_wait_cycles += 4;
|
m_wait_cycles += 4;
|
||||||
|
|
||||||
// Set flags
|
// Set flags
|
||||||
m_nf = 0;
|
m_nf = 0;
|
||||||
m_hf = isCarry(reg, 1, 0x10);
|
m_hf = isCarry(register_, 1, 0x10);
|
||||||
|
|
||||||
// Increment value in register r8 by 1
|
// Increment value in register r8 by 1
|
||||||
reg = (reg + 1) & 0xff;
|
register_ = (register_ + 1) & 0xff;
|
||||||
|
|
||||||
// Zero flag
|
// Zero flag
|
||||||
m_zf = reg == 0;
|
m_zf = register_ == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t opcode = pcRead();
|
uint8_t opcode = pcRead();
|
||||||
|
|||||||
@@ -44,11 +44,19 @@ public:
|
|||||||
void bit();
|
void bit();
|
||||||
void res();
|
void res();
|
||||||
void set();
|
void set();
|
||||||
|
void swap();
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
// Bit Shift Instructions
|
// Bit Shift Instructions
|
||||||
|
|
||||||
void ra();
|
void ra();
|
||||||
|
void rl();
|
||||||
|
void rlc();
|
||||||
|
void rr();
|
||||||
|
void rrc();
|
||||||
|
void sla();
|
||||||
|
void sra();
|
||||||
|
void srl();
|
||||||
|
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
// Load Instructions
|
// Load Instructions
|
||||||
|
|||||||
Reference in New Issue
Block a user