all repos — mgba @ 6c399882f9f07dfb959f84f5a0e364b7188f85b1

mGBA Game Boy Advance Emulator

LR35902: Implement DAA
Jeffrey Pfau jeffrey@endrift.com
Wed, 20 Jan 2016 22:35:34 -0800
commit

6c399882f9f07dfb959f84f5a0e364b7188f85b1

parent

f8469822d73580272ffdb388cc6b3f17bf1500b3

2 files changed, 26 insertions(+), 13 deletions(-)

jump to
M src/lr35902/emitter-lr35902.hsrc/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.csrc/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, \