LR35902: Implement DAA
Jeffrey Pfau jeffrey@endrift.com
Wed, 20 Jan 2016 22:35:34 -0800
2 files changed,
26 insertions(+),
13 deletions(-)
M
src/lr35902/emitter-lr35902.h
→
src/lr35902/emitter-lr35902.h
@@ -49,7 +49,7 @@ DECLARE_INSTRUCTION_LR35902(EMITTER, INCHL), \
DECLARE_INSTRUCTION_LR35902(EMITTER, INCH), \ DECLARE_INSTRUCTION_LR35902(EMITTER, DECH), \ DECLARE_INSTRUCTION_LR35902(EMITTER, LDH_), \ - DECLARE_INSTRUCTION_LR35902(EMITTER, STUB), \ + DECLARE_INSTRUCTION_LR35902(EMITTER, DAA), \ DECLARE_INSTRUCTION_LR35902(EMITTER, JRZ), \ DECLARE_INSTRUCTION_LR35902(EMITTER, ADDHL_HL), \ DECLARE_INSTRUCTION_LR35902(EMITTER, LDA_IHL), \
M
src/lr35902/isa-lr35902.c
→
src/lr35902/isa-lr35902.c
@@ -159,8 +159,8 @@ DEFINE_INSTRUCTION_LR35902(CP ## NAME, \
int diff = cpu->a - OPERAND; \ cpu->f.n = 1; \ cpu->f.z = !diff; \ - cpu->f.c = diff < 0; \ - /* TODO: Find explanation of H flag */) + cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) < 0; \ + cpu->f.c = diff < 0;) #define DEFINE_LDB__INSTRUCTION_LR35902(NAME, OPERAND) \ DEFINE_INSTRUCTION_LR35902(LDB_ ## NAME, \@@ -266,8 +266,8 @@ int diff = cpu->a + OPERAND; \
cpu->a = diff; \ cpu->f.n = 0; \ cpu->f.z = !diff; \ - cpu->f.c = diff >= 0x100; \ - /* TODO: Find explanation of H flag */) + cpu->f.h = (cpu->a & 0xF) + (OPERAND & 0xF) >= 0x10; \ + cpu->f.c = diff >= 0x100;) #define DEFINE_ADC_INSTRUCTION_LR35902(NAME, OPERAND) \ DEFINE_INSTRUCTION_LR35902(ADC ## NAME, \@@ -275,8 +275,8 @@ int diff = cpu->a + OPERAND + cpu->f.c; \
cpu->a = diff; \ cpu->f.n = 0; \ cpu->f.z = !diff; \ - cpu->f.c = diff > 0x100; \ - /* TODO: Find explanation of H flag */) + cpu->f.h = (cpu->a & 0xF) + ((OPERAND + cpu->f.c) & 0xF) >= 0x10; \ + cpu->f.c = diff > 0x100;) #define DEFINE_SUB_INSTRUCTION_LR35902(NAME, OPERAND) \ DEFINE_INSTRUCTION_LR35902(SUB ## NAME, \@@ -284,8 +284,8 @@ int diff = cpu->a - OPERAND; \
cpu->a = diff; \ cpu->f.n = 1; \ cpu->f.z = !diff; \ - cpu->f.c = diff < 0; \ - /* TODO: Find explanation of H flag */) + cpu->f.h = (cpu->a & 0xF) - (OPERAND & 0xF) < 0; \ + cpu->f.c = diff < 0;) #define DEFINE_SBC_INSTRUCTION_LR35902(NAME, OPERAND) \ DEFINE_INSTRUCTION_LR35902(SBC ## NAME, \@@ -293,8 +293,8 @@ int diff = cpu->a - OPERAND - cpu->f.c; \
cpu->a = diff; \ cpu->f.n = 1; \ cpu->f.z = !diff; \ - cpu->f.c = diff < 0; \ - /* TODO: Find explanation of H flag */) + cpu->f.h = (cpu->a & 0xF) - ((OPERAND + cpu->f.c) & 0xF) < 0; \ + cpu->f.c = diff < 0;) DEFINE_ALU_INSTRUCTION_LR35902(LDB_); DEFINE_ALU_INSTRUCTION_LR35902(LDC_);@@ -543,7 +543,7 @@ int diff = cpu->bus + 1;
cpu->bus = diff; cpu->f.n = 0; cpu->f.z = !diff; - /* TODO: Find explanation of H flag */ + cpu->f.h = (cpu->bus & 0xF) == 0xF; cpu->instruction = _LR35902InstructionNOP; cpu->executionState = LR35902_CORE_MEMORY_STORE;)@@ -557,7 +557,7 @@ int diff = cpu->bus - 1;
cpu->bus = diff; cpu->f.n = 1; cpu->f.z = !diff; - /* TODO: Find explanation of H flag */ + cpu->f.h = (cpu->bus & 0xF) == 0; cpu->instruction = _LR35902InstructionNOP; cpu->executionState = LR35902_CORE_MEMORY_STORE;)@@ -588,6 +588,19 @@ DEFINE_INSTRUCTION_LR35902(CPL_,
cpu->a ^= 0xFF; cpu->f.h = 1; cpu->f.n = 1;) + +DEFINE_INSTRUCTION_LR35902(DAA, + if ((cpu->a & 0xF) > 0x9 || cpu->f.h) { + cpu->a += 0x6; + } + if ((cpu->a & 0xF0) > 0x90 || cpu->f.c) { + cpu->a += 0x60; + cpu->f.c = 1; + } else { + cpu->f.c = 0; + } + cpu->f.h = 0; + cpu->f.z = !cpu->a;) #define DEFINE_POPPUSH_INSTRUCTION_LR35902(REG, HH, H, L) \ DEFINE_INSTRUCTION_LR35902(POP ## REG ## Delay, \