I want to first preface my question by first saying that I am quite an experienced programmer, particularly with Java having used it for 8 years.
I decided, in an effort to improve my understanding of hardware operation and operating system topics, to program a simple Gameboy emulator. Having programmed the core functionality in just a few days I tested the emulator only to discover that nothing was drawn on the screen. After stepping through several hundred opcodes in my emulator one at a time and comparing it to the values found in the BGB emulator, I realized that the tiles and sprites in question were being loaded into memory, just not drawn. From this I figured that the issue must be in one or more of my opcode implementations which causes the program to exhibit wrong behavior at some point. Because of this, I decided to use Blargg's cpu test roms (http://gbdev.gg8.se/files/roms/blargg-gb-tests/) to help me pin down the issue. However, running the first test rom, gives the following error message:
01-special
36E1FE30
DAA
Failed #6
I have checked the DAA operation several times and it appears to be correctly implemented to me. The error code given ("36E1FE30") is totally unhelpful as I cannot seem to find what that means. To me this implies that either DAA is incorrectly implemented and I just can't see my mistake or one of the operations used to validate the correctness of DAA is incorrect. If I run any of the other tests they appear to loop indefinitely
03-op sp,hl
03-op sp,hl
03-op sp,hl
03-op sp,hl
For reference my DAA implementation is on github (https://github.com/qkmaxware/GBemu/blob/master/src/gameboy/cpu/Opcodes.java) or can be seen below as follows:
Op DAA = new Op(0x27, "DAA", map, () -> {
int a = reg.a();
if(!reg.subtract()){
if(reg.halfcarry() || (a & 0xF) > 9)
a += 0x06;
if(reg.carry() || a > 0x9F)
a += 0x60;
}else{
if(reg.halfcarry())
a = (a - 0x6) & 0xFF;
if(reg.carry())
a = (a - 0x60) & 0xFF;
}
reg.a(a);
reg.zero(isZero(a));
reg.carry((a & 0x100) == 0x100);
reg.halfcarry(false);
clock.m(1);
clock.t(4);
});
Where calls such as reg.a() means read from register a, reg.a(value) means write to register a (mask to 8 or 16 bits depending on the register). Similarly, the flags Z,N,H,C can be obtained or set/reset with the zero, subtract, halfcarry, an carry functions of the 'reg' object.
So my question is threefold, have I implemented the DAA operation incorrectly so that it fails Blargg's tests, does anyone know what the error code I have means, or does anyone have any ideas how I can focus my search for the incorrect operation.