Stewmath / GameYob

[Super] Gameboy [Color] emulator for the Nintendo [3]DS
MIT License
276 stars 60 forks source link

Blargg's Game Boy tests: Instructions #15

Closed Nebuleon closed 11 years ago

Nebuleon commented 11 years ago

Tests are at http://slack.net/~ant/old/gb-tests/cpu_instrs.zip - to run one and get a description of the failed test, extract the zip file onto your storage card and load one of the ROMs in cpu_instrs/rom_singles.

Only opcodes E8 (ADD SP, s8) and F8 (LDHL SP, s8) fail as of commit c77c6133134fb0745ee6b711c1b70ee6f81981c2 (2013-03-12).

The failures may be down to the behavio(u)r of the Half-carry flag. Blargg's test ROM carries out testing on the values of all registers and flags.

Generally, 1% of the tests fail.

Nebuleon commented 11 years ago

-- Quote: Drenn, 2013-02-23, http://gbatemp.net/threads/gameyob-a-gameboy-emulator-for-ds.343407/page-3#post-4563539

I was able to fix a few problems with flags, but I don't know about instructions E8 and F8. I'd better take a look at Gambatte.

-- Quote: End

Nebuleon commented 11 years ago

I've looked into Gambatte. It appears the half-carry flag is bit 4 (overflowing from 0xF into 0x10), not 12 (overflowing from 0xFFF into 0x1000).

See this code:

#define sp_plus_n(sumout) do { \
    unsigned sp_plus_n_var_n; \
    PC_READ(sp_plus_n_var_n); \
    sp_plus_n_var_n = (sp_plus_n_var_n ^ 0x80) - 0x80; \
    \
    const unsigned sp_plus_n_var_sum = SP + sp_plus_n_var_n; \
    CF = SP ^ sp_plus_n_var_n ^ sp_plus_n_var_sum; \
    HF2 = CF << 5 & 0x200; /* this sets the half-carry flag to bit 4's value */ \
    ZF = 1; \
    cycleCounter += 4; \
    (sumout) = sp_plus_n_var_sum & 0xFFFF; \
} while (0)
Stewmath commented 11 years ago

I tried adapting this code, and it didn't really work. When I googled it I came up with this, blargg explaining to dwedit how E8 and F8 work. It has several differences, including that the negative and zero flags should be cleared. Also the carry flag is apparently based on the lower byte of SP added with the immediate value, considered unsigned. Maybe gambatte does this, I didn't really study all that XORing in detail. Gameyob passes the test now, but it's strange that those other differences exist since gambatte apparently passes the test too.