From 6c399882f9f07dfb959f84f5a0e364b7188f85b1 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 20 Jan 2016 22:35:34 -0800 Subject: [PATCH] LR35902: Implement DAA --- src/lr35902/emitter-lr35902.h | 2 +- src/lr35902/isa-lr35902.c | 37 +++++++++++++++++++++++------------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/lr35902/emitter-lr35902.h b/src/lr35902/emitter-lr35902.h index 57166eb68..ff25b9343 100644 --- a/src/lr35902/emitter-lr35902.h +++ b/src/lr35902/emitter-lr35902.h @@ -49,7 +49,7 @@ 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), \ diff --git a/src/lr35902/isa-lr35902.c b/src/lr35902/isa-lr35902.c index b91e796a2..ff8675620 100644 --- a/src/lr35902/isa-lr35902.c +++ b/src/lr35902/isa-lr35902.c @@ -159,8 +159,8 @@ DEFINE_CONDITIONAL_INSTRUCTION_LR35902(RET) 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 @@ static void _LR35902InstructionLDA_Bus(struct LR35902Core*); 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 @@ static void _LR35902InstructionLDA_Bus(struct LR35902Core*); 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 @@ static void _LR35902InstructionLDA_Bus(struct LR35902Core*); 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 @@ static void _LR35902InstructionLDA_Bus(struct LR35902Core*); 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 @@ DEFINE_INSTRUCTION_LR35902(INC_HLDelay, 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 @@ DEFINE_INSTRUCTION_LR35902(DEC_HLDelay, 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;) @@ -589,6 +589,19 @@ DEFINE_INSTRUCTION_LR35902(CPL_, 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, \ cpu-> L = cpu->bus; \