The unimplementable DAA instruction
Posted: Thu Jul 12, 2012 3:16 am
Hi!
I'm making a Gameboy emulator and I've been trying to get the DAA instruciton to pass Blargg's tests for quite some time now.
I've tried to copy the behavior of how gambatte (which passes the tests) handles it.
Gambattes implmentation:
and this is my current code:
What I find the most confusing is the behavior of the H flag after the DAA instruction. According to the documentation it says "set or reset according to operation", which doesn't really explain how it behaves. Currently I'm always clearing it, because I think that is what gambatte does.
I then started comparing it to VBA-M's DAA table and found that the Z flag doesn't always behave as I thought. For example:
Produces the following:
Also, sometimes (I haven't figured out when), the H flag is set.
I couldn't test whether VBA-M is accurate or not because it fails the test before the DAA test is run.
I'm making a Gameboy emulator and I've been trying to get the DAA instruciton to pass Blargg's tests for quite some time now.
I've tried to copy the behavior of how gambatte (which passes the tests) handles it.
Gambattes implmentation:
Code: Select all
case 0x27:
calcHF(HF1, HF2);
{
unsigned correction = (CF & 0x100) ? 0x60 : 0x00;
if (HF2 & 0x200)
correction |= 0x06;
if (!(HF2 &= 0x400)) {
if ((A & 0x0F) > 0x09)
correction |= 0x06;
if (A > 0x99)
correction |= 0x60;
A += correction;
} else
A -= correction;
CF = correction << 2 & 0x100;
ZF = A;
A &= 0xFF;
}
break;
Code: Select all
cycleCounter += 4;
int corr = 0;
corr |= regAF.lo & FLAG_MASK_H? 0x06: 0x00;
corr |= regAF.lo & FLAG_MASK_C? 0x60: 0x00;
if (regAF.lo & FLAG_MASK_N)
{
regAF.hi -= corr;
} else
{
corr |= (regAF.hi & 0x0F) > 0x09? 0x06: 0x00;
corr |= regAF.hi > 0x99? 0x60: 0x00;
regAF.hi += corr;
}
CLEAR_FLAGS(FLAG_MASK_H);
if (corr & 0x60)
{
SET_FLAGS(FLAG_MASK_C);
}
if (corr & 0x06)
{
//SET_FLAGS(FLAG_MASK_H);
}
if (regAF.hi == 0)
{
SET_FLAGS(FLAG_MASK_Z);
} else
{
CLEAR_FLAGS(FLAG_MASK_Z);
}
I then started comparing it to VBA-M's DAA table and found that the Z flag doesn't always behave as I thought. For example:
Code: Select all
A = 0x00
F = 0x80 // Z flag set
execute DAA
Code: Select all
output:
A = 0x00
F = 0x00
I couldn't test whether VBA-M is accurate or not because it fails the test before the DAA test is run.