Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c2e5d32d4 | ||
|
|
525391144a | ||
|
|
cfded56dcd | ||
|
|
024e6aecc3 |
+69
-14
@@ -105,6 +105,7 @@ void CPU::update()
|
|||||||
case 0x24: inc8(); break;
|
case 0x24: inc8(); break;
|
||||||
case 0x25: dec8(); break;
|
case 0x25: dec8(); break;
|
||||||
case 0x26: ldi8(); break;
|
case 0x26: ldi8(); break;
|
||||||
|
case 0x27: daa(); break;
|
||||||
case 0x28: jrs8(); break;
|
case 0x28: jrs8(); break;
|
||||||
case 0x29: addr16(); break;
|
case 0x29: addr16(); break;
|
||||||
case 0x2a: lda8(); break;
|
case 0x2a: lda8(); break;
|
||||||
@@ -512,6 +513,56 @@ void CPU::cp()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPU::daa()
|
||||||
|
{
|
||||||
|
uint8_t opcode = pcRead();
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x27: { // DAA, flags: Z - 0 C
|
||||||
|
m_wait_cycles += 4;
|
||||||
|
|
||||||
|
// Decimal Adjust Accumulator to get a correct Binary Coded Decimal
|
||||||
|
// (BCD) representation after an arithmetic instruction
|
||||||
|
|
||||||
|
// BCD is a way of representing decimal quantities using each nibble (4
|
||||||
|
// bits) of a byte (a byte, since it is 8 bits has two nibbles) to store
|
||||||
|
// a decimal digit.
|
||||||
|
// Example: 64 split on each number gives a 6 and a 4, so 0110 0100 as a BCD
|
||||||
|
uint8_t higher_nibble = m_a & 0xf0;
|
||||||
|
uint8_t lower_nibble = m_a & 0xf;
|
||||||
|
|
||||||
|
// Step 1: Check lower nibble of the BCD stored in A.
|
||||||
|
// If it is greater than decimal 9 or half carry flag is set
|
||||||
|
// (meaning that the lower nibble value is > 15),
|
||||||
|
// add decimal 6 to the lower nibble to make it wrap around
|
||||||
|
if (lower_nibble > 9 || m_hf) {
|
||||||
|
lower_nibble += 6;
|
||||||
|
higher_nibble += isCarry(m_a, 6, 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Check higher nibble (after addition of the carry from the lower nibble).
|
||||||
|
// If it is greater than decimal 9 or the carry flag is set
|
||||||
|
// (meaning that the upper nibble value is > 15),
|
||||||
|
// add decimal 6 to the upper nibble to make it wrap around and set carry flag to 1
|
||||||
|
uint32_t new_carry = 0;
|
||||||
|
if (higher_nibble > 9 || m_cf) {
|
||||||
|
higher_nibble += 6;
|
||||||
|
new_carry = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Accumulator to the correct BCD representation
|
||||||
|
m_a = higher_nibble | lower_nibble;
|
||||||
|
|
||||||
|
// Set flags
|
||||||
|
m_zf = m_a == 0;
|
||||||
|
m_hf = 0;
|
||||||
|
m_cf = new_carry;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
VERIFY_NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CPU::dec8()
|
void CPU::dec8()
|
||||||
{
|
{
|
||||||
auto decrement = [this](uint32_t& register_) -> void {
|
auto decrement = [this](uint32_t& register_) -> void {
|
||||||
@@ -642,7 +693,7 @@ void CPU::sbc8()
|
|||||||
// SBC A,r8, flags: Z 1 H C
|
// SBC A,r8, flags: Z 1 H C
|
||||||
m_wait_cycles += 4;
|
m_wait_cycles += 4;
|
||||||
|
|
||||||
uint32_t old_carry = m_cf;
|
uint32_t old_carry = m_cf != 0;
|
||||||
|
|
||||||
// Set flags
|
// Set flags
|
||||||
m_nf = 1;
|
m_nf = 1;
|
||||||
@@ -892,7 +943,7 @@ void CPU::inc16()
|
|||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case 0x03: /* INC BC */ setBC(bc() + 1); break;
|
case 0x03: /* INC BC */ setBC(bc() + 1); break;
|
||||||
case 0x13: /* INC DE */ setDE(de() + 1); break;
|
case 0x13: /* INC DE */ setDE(de() + 1); break;
|
||||||
case 0x23: /* INC HL */ setHL(de() + 1); break;
|
case 0x23: /* INC HL */ setHL(hl() + 1); break;
|
||||||
case 0x24: /* INC SP */ m_sp = (m_sp + 1) & 0xffff; break;
|
case 0x24: /* INC SP */ m_sp = (m_sp + 1) & 0xffff; break;
|
||||||
default:
|
default:
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
@@ -929,24 +980,28 @@ void CPU::ldr8()
|
|||||||
{
|
{
|
||||||
uint8_t opcode = pcRead();
|
uint8_t opcode = pcRead();
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case 0x02: // LD (BC),A
|
case 0x02: /* LD (BC),A */ {
|
||||||
m_wait_cycles += 4;
|
m_wait_cycles += 4; // + 4 = 8 total
|
||||||
write(bc(), m_a);
|
write(bc(), m_a);
|
||||||
break;
|
break;
|
||||||
case 0x0a: // LD A,(BC)
|
}
|
||||||
m_wait_cycles += 4;
|
case 0x0a: /* LD A,(BC) */ {
|
||||||
|
m_wait_cycles += 4; // + 4 = 8 total
|
||||||
m_a = read(bc());
|
m_a = read(bc());
|
||||||
break;
|
break;
|
||||||
case 0x12: // LD (DE),A
|
}
|
||||||
m_wait_cycles += 4;
|
case 0x12: /* LD (DE),A */ {
|
||||||
|
m_wait_cycles += 4; // + 4 = 8 total
|
||||||
write(de(), m_a);
|
write(de(), m_a);
|
||||||
break;
|
break;
|
||||||
case 0x1a: // LD A,(DE)
|
}
|
||||||
m_wait_cycles += 4;
|
case 0x1a: /* LD A,(DE) */ {
|
||||||
|
m_wait_cycles += 4; // + 4 = 8 total
|
||||||
m_a = read(de());
|
m_a = read(de());
|
||||||
break;
|
break;
|
||||||
case 0x22: { // LD (HL+),A == LD (HLI),A == LDI (HL),A
|
}
|
||||||
m_wait_cycles += 4;
|
case 0x22: /* LD (HL+),A == LD (HLI),A == LDI (HL),A */ {
|
||||||
|
m_wait_cycles += 4; // + 4 = 8 total
|
||||||
|
|
||||||
// Put A into memory address in HL
|
// Put A into memory address in HL
|
||||||
uint32_t address = hl();
|
uint32_t address = hl();
|
||||||
@@ -958,8 +1013,8 @@ void CPU::ldr8()
|
|||||||
m_h = address >> 8;
|
m_h = address >> 8;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x32: { // LD (HL-),A == LD (HLD),A == LDD (HL),A
|
case 0x32: /* LD (HL-),A == LD (HLD),A == LDD (HL),A */ {
|
||||||
m_wait_cycles += 4;
|
m_wait_cycles += 4; // + 4 = 8 total
|
||||||
|
|
||||||
// Put A into memory address in HL
|
// Put A into memory address in HL
|
||||||
uint32_t address = hl();
|
uint32_t address = hl();
|
||||||
|
|||||||
+1
-1
@@ -90,7 +90,7 @@ uint32_t Emu::readMemory(uint32_t address) const
|
|||||||
for (const auto& memory_space : m_memory_spaces) {
|
for (const auto& memory_space : m_memory_spaces) {
|
||||||
const auto& memory = memory_space.second;
|
const auto& memory = memory_space.second;
|
||||||
if (address >= memory.start_address && address <= memory.end_address) {
|
if (address >= memory.start_address && address <= memory.end_address) {
|
||||||
return memory.memory[memory.active_bank][address];
|
return memory.memory[memory.active_bank][address - memory.start_address];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user