diff --git a/Core/memory.c b/Core/memory.c index 0b08a79..d0af989 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -29,33 +29,80 @@ static GB_bus_t bus_for_addr(GB_gameboy_t *gb, uint16_t addr) return GB_BUS_INTERNAL; } -static uint8_t bitwise_glitch(uint8_t a, uint8_t b, uint8_t c) +static uint16_t bitwise_glitch(uint16_t a, uint16_t b, uint16_t c) { return ((a ^ c) & (b ^ c)) ^ c; } -static uint8_t bitwise_glitch_read(uint8_t a, uint8_t b, uint8_t c) +static uint16_t bitwise_glitch_read(uint16_t a, uint16_t b, uint16_t c) { return b | (a & c); } -static uint8_t bitwise_glitch_read_increase(uint8_t a, uint8_t b, uint8_t c, uint8_t d) +static uint16_t bitwise_glitch_read_secondary(uint16_t a, uint16_t b, uint16_t c, uint16_t d) { return (b & (a | c | d)) | (a & c & d); } +/* + Used on the MGB in some scenarios +static uint16_t bitwise_glitch_mgb(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e, bool variant) +{ + return (c & (e | d | b | (variant? 0 : a))) | (b & d & (a | e)); +} +*/ + +static uint16_t bitwise_glitch_tertiary_read_1(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e) +{ + return c | (a & b & d & e); +} + +static uint16_t bitwise_glitch_tertiary_read_2(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e) +{ + return (c & (a | b | d | e)) | (a & b & d & e); +} + +static uint16_t bitwise_glitch_tertiary_read_3(uint16_t a, uint16_t b, uint16_t c, uint16_t d, uint16_t e) +{ + return (c & (a | b | d | e)) | (b & d & e); +} + +static uint16_t bitwise_glitch_quaternary_read_dmg(uint16_t a, uint16_t b, uint16_t c, uint16_t d, + uint16_t e, uint16_t f, uint16_t g, uint16_t h) +{ + /* On my DMG, some cases are non-deterministic, while on some other DMGs they yield constant zeros. + The non deterministic cases are affected by (on the row 40 case) 34, 36, 3e and 28, and potentially + others. For my own sanity I'm going to emulate the DMGs that output zeros. */ + (void)a; + return (e & (h | g | (~d & f) | c | b)) | (c & g & h); +} + +/* + +// Oh my. +static uint16_t bitwise_glitch_quaternary_read_mgb(uint16_t a, uint16_t b, uint16_t c, uint16_t d, + uint16_t e, uint16_t f, uint16_t g, uint16_t h) +{ + return (e & (h | g | c | (a & b))) | ((c & h) & (g & (~f | b | a | ~d) | (a & b & f))); +} +*/ + +static uint16_t bitwise_glitch_quaternary_read_sgb2(uint16_t a, uint16_t b, uint16_t c, uint16_t d, + uint16_t e, uint16_t f, uint16_t g, uint16_t h) +{ + return (e & (h | g | c | (a & b))) | ((c & g & h) & (b | a | ~f)); +} + void GB_trigger_oam_bug(GB_gameboy_t *gb, uint16_t address) { if (GB_is_cgb(gb)) return; if (address >= 0xFE00 && address < 0xFF00) { if (gb->accessed_oam_row != 0xff && gb->accessed_oam_row >= 8) { - gb->oam[gb->accessed_oam_row] = bitwise_glitch(gb->oam[gb->accessed_oam_row], - gb->oam[gb->accessed_oam_row - 8], - gb->oam[gb->accessed_oam_row - 4]); - gb->oam[gb->accessed_oam_row + 1] = bitwise_glitch(gb->oam[gb->accessed_oam_row + 1], - gb->oam[gb->accessed_oam_row - 7], - gb->oam[gb->accessed_oam_row - 3]); + uint16_t *base = (uint16_t *)(gb->oam + gb->accessed_oam_row); + base[0] = bitwise_glitch(base[0], + base[-4], + base[-2]); for (unsigned i = 2; i < 8; i++) { gb->oam[gb->accessed_oam_row + i] = gb->oam[gb->accessed_oam_row - 8 + i]; } @@ -63,49 +110,140 @@ void GB_trigger_oam_bug(GB_gameboy_t *gb, uint16_t address) } } +static void oam_bug_secondary_read_corruption(GB_gameboy_t *gb) +{ + if (gb->accessed_oam_row < 0x98) { + uint16_t *base = (uint16_t *)(gb->oam + gb->accessed_oam_row); + base[-4] = bitwise_glitch_read_secondary(base[-8], + base[-4], + base[0], + base[-2]); + for (unsigned i = 0; i < 8; i++) { + gb->oam[gb->accessed_oam_row - 0x10 + i] = gb->oam[gb->accessed_oam_row - 0x08 + i]; + } + } +} + +/* +static void oam_bug_tertiary_read_corruption_mgb(GB_gameboy_t *gb) +{ + if (gb->accessed_oam_row < 0x98) { + uint16_t *base = (uint16_t *)(gb->oam + gb->accessed_oam_row); + uint16_t temp = bitwise_glitch_mgb( + base[0], + base[-2], + base[-4], + base[-8], + base[-16], + true); + + base[-4] = bitwise_glitch_mgb( + base[0], + base[-2], + base[-4], + base[-8], + base[-16], + false); + for (unsigned i = 0; i < 8; i++) { + gb->oam[gb->accessed_oam_row - 0x10 + i] = gb->oam[gb->accessed_oam_row - 0x20 + i] = gb->oam[gb->accessed_oam_row - 0x08 + i]; + } + + base[-8] = temp; + base[-16] = temp; + } +} +*/ + +static void oam_bug_quaternary_read_corruption(GB_gameboy_t *gb, typeof(bitwise_glitch_quaternary_read_dmg) *bitwise_op) +{ + if (gb->accessed_oam_row < 0x98) { + uint16_t *base = (uint16_t *)(gb->oam + gb->accessed_oam_row); + + base[-4] = bitwise_op(*(uint16_t *)gb->oam, + base[0], + base[-2], + base[-3], + base[-4], + base[-7], + base[-8], + base[-16]); + for (unsigned i = 0; i < 8; i++) { + gb->oam[gb->accessed_oam_row - 0x10 + i] = gb->oam[gb->accessed_oam_row - 0x20 + i] = gb->oam[gb->accessed_oam_row - 0x08 + i]; + } + } +} + +static void oam_bug_tertiary_read_corruption(GB_gameboy_t *gb, typeof(bitwise_glitch_tertiary_read_1) *bitwise_op) +{ + if (gb->accessed_oam_row < 0x98) { + uint16_t *base = (uint16_t *)(gb->oam + gb->accessed_oam_row); + + /* On some instances, the corruption row is copied to the first row for some accessed row. On my DMG it happens + for row 80, and on my MGB it happens on row 60. Some instances only copy odd or even bytes. Additionally, + for some instances on accessed rows that do not affect the first row, the last two bytes of the preceeding + row are also corrupted in a non-deterministic probability. */ + + base[-4] = bitwise_op( + base[0], + base[-2], + base[-4], + base[-8], + base[-16]); + for (unsigned i = 0; i < 8; i++) { + gb->oam[gb->accessed_oam_row - 0x10 + i] = gb->oam[gb->accessed_oam_row - 0x20 + i] = gb->oam[gb->accessed_oam_row - 0x08 + i]; + } + } +} + void GB_trigger_oam_bug_read(GB_gameboy_t *gb, uint16_t address) { if (GB_is_cgb(gb)) return; if (address >= 0xFE00 && address < 0xFF00) { if (gb->accessed_oam_row != 0xff && gb->accessed_oam_row >= 8) { - gb->oam[gb->accessed_oam_row - 8] = - gb->oam[gb->accessed_oam_row] = bitwise_glitch_read(gb->oam[gb->accessed_oam_row], - gb->oam[gb->accessed_oam_row - 8], - gb->oam[gb->accessed_oam_row - 4]); - gb->oam[gb->accessed_oam_row - 7] = - gb->oam[gb->accessed_oam_row + 1] = bitwise_glitch_read(gb->oam[gb->accessed_oam_row + 1], - gb->oam[gb->accessed_oam_row - 7], - gb->oam[gb->accessed_oam_row - 3]); - for (unsigned i = 2; i < 8; i++) { + if ((gb->accessed_oam_row & 0x18) == 0x10) { + oam_bug_secondary_read_corruption(gb); + } + else if ((gb->accessed_oam_row & 0x18) == 0x00) { + /* Everything in this specific case is *extremely* revision and instance specific. */ + if (gb->accessed_oam_row == 0x40) { + oam_bug_quaternary_read_corruption(gb, + ((gb->model & ~GB_MODEL_NO_SFC_BIT) == GB_MODEL_SGB2)? + bitwise_glitch_quaternary_read_sgb2: + bitwise_glitch_quaternary_read_dmg); + } + else if ((gb->model & ~GB_MODEL_NO_SFC_BIT) != GB_MODEL_SGB2) { + if (gb->accessed_oam_row == 0x20) { + oam_bug_tertiary_read_corruption(gb, bitwise_glitch_tertiary_read_2); + } + else if (gb->accessed_oam_row == 0x60) { + oam_bug_tertiary_read_corruption(gb, bitwise_glitch_tertiary_read_3); + } + else { + oam_bug_tertiary_read_corruption(gb, bitwise_glitch_tertiary_read_1); + } + } + else { + oam_bug_tertiary_read_corruption(gb, bitwise_glitch_tertiary_read_2); + } + } + else { + uint16_t *base = (uint16_t *)(gb->oam + gb->accessed_oam_row); + base[-4] = + base[0] = bitwise_glitch_read(base[0], + base[-4], + base[-2]); + } + for (unsigned i = 0; i < 8; i++) { gb->oam[gb->accessed_oam_row + i] = gb->oam[gb->accessed_oam_row - 8 + i]; } + if (gb->accessed_oam_row == 0x80) { + memcpy(gb->oam, gb->oam + gb->accessed_oam_row, 8); + } } } } -void GB_trigger_oam_bug_read_increase(GB_gameboy_t *gb, uint16_t address) -{ - if (GB_is_cgb(gb)) return; - - if (address >= 0xFE00 && address < 0xFF00) { - if (gb->accessed_oam_row != 0xff && gb->accessed_oam_row >= 0x20 && gb->accessed_oam_row < 0x98) { - gb->oam[gb->accessed_oam_row - 0x8] = bitwise_glitch_read_increase(gb->oam[gb->accessed_oam_row - 0x10], - gb->oam[gb->accessed_oam_row - 0x08], - gb->oam[gb->accessed_oam_row ], - gb->oam[gb->accessed_oam_row - 0x04] - ); - gb->oam[gb->accessed_oam_row - 0x7] = bitwise_glitch_read_increase(gb->oam[gb->accessed_oam_row - 0x0f], - gb->oam[gb->accessed_oam_row - 0x07], - gb->oam[gb->accessed_oam_row + 0x01], - gb->oam[gb->accessed_oam_row - 0x03] - ); - for (unsigned i = 0; i < 8; i++) { - gb->oam[gb->accessed_oam_row + i] = gb->oam[gb->accessed_oam_row - 0x10 + i] = gb->oam[gb->accessed_oam_row - 0x08 + i]; - } - } - } -} static bool is_addr_in_dma_use(GB_gameboy_t *gb, uint16_t addr) { @@ -281,26 +419,53 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) if (gb->oam_read_blocked) { if (!GB_is_cgb(gb)) { if (addr < 0xFEA0) { + uint16_t *oam = (uint16_t *)gb->oam; if (gb->accessed_oam_row == 0) { - gb->oam[(addr & 0xf8)] = - gb->oam[0] = bitwise_glitch_read(gb->oam[0], - gb->oam[(addr & 0xf8)], - gb->oam[(addr & 0xfe)]); - gb->oam[(addr & 0xf8) + 1] = - gb->oam[1] = bitwise_glitch_read(gb->oam[1], - gb->oam[(addr & 0xf8) + 1], - gb->oam[(addr & 0xfe) | 1]); + oam[(addr & 0xf8) >> 1] = + oam[0] = bitwise_glitch_read(oam[0], + oam[(addr & 0xf8) >> 1], + oam[(addr & 0xff) >> 1]); + for (unsigned i = 2; i < 8; i++) { gb->oam[i] = gb->oam[(addr & 0xf8) + i]; } } else if (gb->accessed_oam_row == 0xa0) { - gb->oam[0x9e] = bitwise_glitch_read(gb->oam[0x9c], - gb->oam[0x9e], - gb->oam[(addr & 0xf8) | 6]); - gb->oam[0x9f] = bitwise_glitch_read(gb->oam[0x9d], - gb->oam[0x9f], - gb->oam[(addr & 0xf8) | 7]); + uint8_t target = (addr & 7) | 0x98; + uint16_t a = oam[0x9c >> 1], + b = oam[target >> 1], + c = oam[(addr & 0xf8) >> 1]; + switch (addr & 7) { + case 0: + case 1: + /* Probably instance specific */ + if ((gb->model & GB_MODEL_FAMILY_MASK) == GB_MODEL_DMG_FAMILY) { + oam[target >> 1] = (a & b) | (a & c) | (b & c); + } + else { + oam[target >> 1] = bitwise_glitch_read(a, b, c); + } + break; + case 2: + case 3: { + /* Probably instance specific */ + c = oam[(addr & 0xfe) >> 1]; + + // MGB only: oam[target >> 1] = bitwise_glitch_read(a, b, c); + oam[target >> 1] = (a & b) | (a & c) | (b & c); + break; + } + case 4: + case 5: + break; // No additional corruption + case 6: + case 7: + oam[target >> 1] = bitwise_glitch_read(a, b, c); + break; + + default: + break; + } for (unsigned i = 0; i < 8; i++) { gb->oam[(addr & 0xf8) + i] = gb->oam[0x98 + i]; diff --git a/Core/memory.h b/Core/memory.h index f0d0390..80020f1 100644 --- a/Core/memory.h +++ b/Core/memory.h @@ -12,7 +12,6 @@ void GB_write_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value); void GB_dma_run(GB_gameboy_t *gb); void GB_hdma_run(GB_gameboy_t *gb); void GB_trigger_oam_bug(GB_gameboy_t *gb, uint16_t address); -void GB_trigger_oam_bug_read_increase(GB_gameboy_t *gb, uint16_t address); #endif #endif /* memory_h */ diff --git a/Core/sm83_cpu.c b/Core/sm83_cpu.c index 20e7691..09499bc 100644 --- a/Core/sm83_cpu.c +++ b/Core/sm83_cpu.c @@ -87,17 +87,6 @@ static uint8_t cycle_read(GB_gameboy_t *gb, uint16_t addr) return ret; } -static uint8_t cycle_read_inc_oam_bug(GB_gameboy_t *gb, uint16_t addr) -{ - if (gb->pending_cycles) { - GB_advance_cycles(gb, gb->pending_cycles); - } - GB_trigger_oam_bug_read_increase(gb, addr); /* Todo: test T-cycle timing */ - uint8_t ret = GB_read_memory(gb, addr); - gb->pending_cycles = 4; - return ret; -} - /* A special case for IF during ISR, returns the old value of IF. */ /* TODO: Verify the timing, it might be wrong in cases where, in the same M cycle, IF is both read be the CPU, modified by the ISR, and modified by an actual interrupt. @@ -388,7 +377,7 @@ static void stop(GB_gameboy_t *gb, uint8_t opcode) } if (!interrupt_pending) { - cycle_read_inc_oam_bug(gb, gb->pc++); + cycle_read(gb, gb->pc++); } /* Todo: speed switching takes 2 extra T-cycles (so 2 PPU ticks in single->double and 1 PPU tick in double->single) */ @@ -451,8 +440,8 @@ static void ld_rr_d16(GB_gameboy_t *gb, uint8_t opcode) uint8_t register_id; uint16_t value; register_id = (opcode >> 4) + 1; - value = cycle_read_inc_oam_bug(gb, gb->pc++); - value |= cycle_read_inc_oam_bug(gb, gb->pc++) << 8; + value = cycle_read(gb, gb->pc++); + value |= cycle_read(gb, gb->pc++) << 8; gb->registers[register_id] = value; } @@ -507,7 +496,7 @@ static void ld_hr_d8(GB_gameboy_t *gb, uint8_t opcode) uint8_t register_id; register_id = ((opcode >> 4) + 1) & 0x03; gb->registers[register_id] &= 0xFF; - gb->registers[register_id] |= cycle_read_inc_oam_bug(gb, gb->pc++) << 8; + gb->registers[register_id] |= cycle_read(gb, gb->pc++) << 8; } static void rlca(GB_gameboy_t *gb, uint8_t opcode) @@ -538,8 +527,8 @@ static void ld_da16_sp(GB_gameboy_t *gb, uint8_t opcode) { /* Todo: Verify order is correct */ uint16_t addr; - addr = cycle_read_inc_oam_bug(gb, gb->pc++); - addr |= cycle_read_inc_oam_bug(gb, gb->pc++) << 8; + addr = cycle_read(gb, gb->pc++); + addr |= cycle_read(gb, gb->pc++) << 8; cycle_write(gb, addr, gb->registers[GB_REGISTER_SP] & 0xFF); cycle_write(gb, addr + 1, gb->registers[GB_REGISTER_SP] >> 8); } @@ -625,7 +614,7 @@ static void ld_lr_d8(GB_gameboy_t *gb, uint8_t opcode) uint8_t register_id; register_id = (opcode >> 4) + 1; gb->registers[register_id] &= 0xFF00; - gb->registers[register_id] |= cycle_read_inc_oam_bug(gb, gb->pc++); + gb->registers[register_id] |= cycle_read(gb, gb->pc++); } static void rrca(GB_gameboy_t *gb, uint8_t opcode) @@ -655,7 +644,7 @@ static void rra(GB_gameboy_t *gb, uint8_t opcode) static void jr_r8(GB_gameboy_t *gb, uint8_t opcode) { /* Todo: Verify timing */ - gb->pc += (int8_t)cycle_read_inc_oam_bug(gb, gb->pc) + 1; + gb->pc += (int8_t)cycle_read(gb, gb->pc) + 1; cycle_no_access(gb); } @@ -677,7 +666,7 @@ static bool condition_code(GB_gameboy_t *gb, uint8_t opcode) static void jr_cc_r8(GB_gameboy_t *gb, uint8_t opcode) { - int8_t offset = cycle_read_inc_oam_bug(gb, gb->pc++); + int8_t offset = cycle_read(gb, gb->pc++); if (condition_code(gb, opcode)) { gb->pc += offset; cycle_no_access(gb); @@ -752,13 +741,13 @@ static void ld_dhld_a(GB_gameboy_t *gb, uint8_t opcode) static void ld_a_dhli(GB_gameboy_t *gb, uint8_t opcode) { gb->registers[GB_REGISTER_AF] &= 0xFF; - gb->registers[GB_REGISTER_AF] |= cycle_read_inc_oam_bug(gb, gb->registers[GB_REGISTER_HL]++) << 8; + gb->registers[GB_REGISTER_AF] |= cycle_read(gb, gb->registers[GB_REGISTER_HL]++) << 8; } static void ld_a_dhld(GB_gameboy_t *gb, uint8_t opcode) { gb->registers[GB_REGISTER_AF] &= 0xFF; - gb->registers[GB_REGISTER_AF] |= cycle_read_inc_oam_bug(gb, gb->registers[GB_REGISTER_HL]--) << 8; + gb->registers[GB_REGISTER_AF] |= cycle_read(gb, gb->registers[GB_REGISTER_HL]--) << 8; } static void inc_dhl(GB_gameboy_t *gb, uint8_t opcode) @@ -796,7 +785,7 @@ static void dec_dhl(GB_gameboy_t *gb, uint8_t opcode) static void ld_dhl_d8(GB_gameboy_t *gb, uint8_t opcode) { - uint8_t data = cycle_read_inc_oam_bug(gb, gb->pc++); + uint8_t data = cycle_read(gb, gb->pc++); cycle_write(gb, gb->registers[GB_REGISTER_HL], data); } @@ -1034,15 +1023,15 @@ static void pop_rr(GB_gameboy_t *gb, uint8_t opcode) { uint8_t register_id; register_id = ((opcode >> 4) + 1) & 3; - gb->registers[register_id] = cycle_read_inc_oam_bug(gb, gb->registers[GB_REGISTER_SP]++); + gb->registers[register_id] = cycle_read(gb, gb->registers[GB_REGISTER_SP]++); gb->registers[register_id] |= cycle_read(gb, gb->registers[GB_REGISTER_SP]++) << 8; gb->registers[GB_REGISTER_AF] &= 0xFFF0; // Make sure we don't set impossible flags on F! See Blargg's PUSH AF test. } static void jp_cc_a16(GB_gameboy_t *gb, uint8_t opcode) { - uint16_t addr = cycle_read_inc_oam_bug(gb, gb->pc++); - addr |= (cycle_read_inc_oam_bug(gb, gb->pc++) << 8); + uint16_t addr = cycle_read(gb, gb->pc++); + addr |= (cycle_read(gb, gb->pc++) << 8); if (condition_code(gb, opcode)) { cycle_no_access(gb); gb->pc = addr; @@ -1051,8 +1040,8 @@ static void jp_cc_a16(GB_gameboy_t *gb, uint8_t opcode) static void jp_a16(GB_gameboy_t *gb, uint8_t opcode) { - uint16_t addr = cycle_read_inc_oam_bug(gb, gb->pc); - addr |= (cycle_read_inc_oam_bug(gb, gb->pc + 1) << 8); + uint16_t addr = cycle_read(gb, gb->pc); + addr |= (cycle_read(gb, gb->pc + 1) << 8); cycle_no_access(gb); gb->pc = addr; @@ -1061,8 +1050,8 @@ static void jp_a16(GB_gameboy_t *gb, uint8_t opcode) static void call_cc_a16(GB_gameboy_t *gb, uint8_t opcode) { uint16_t call_addr = gb->pc - 1; - uint16_t addr = cycle_read_inc_oam_bug(gb, gb->pc++); - addr |= (cycle_read_inc_oam_bug(gb, gb->pc++) << 8); + uint16_t addr = cycle_read(gb, gb->pc++); + addr |= (cycle_read(gb, gb->pc++) << 8); if (condition_code(gb, opcode)) { cycle_oam_bug(gb, GB_REGISTER_SP); cycle_write(gb, --gb->registers[GB_REGISTER_SP], (gb->pc) >> 8); @@ -1085,7 +1074,7 @@ static void push_rr(GB_gameboy_t *gb, uint8_t opcode) static void add_a_d8(GB_gameboy_t *gb, uint8_t opcode) { uint8_t value, a; - value = cycle_read_inc_oam_bug(gb, gb->pc++); + value = cycle_read(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; gb->registers[GB_REGISTER_AF] = (a + value) << 8; if ((uint8_t) (a + value) == 0) { @@ -1102,7 +1091,7 @@ static void add_a_d8(GB_gameboy_t *gb, uint8_t opcode) static void adc_a_d8(GB_gameboy_t *gb, uint8_t opcode) { uint8_t value, a, carry; - value = cycle_read_inc_oam_bug(gb, gb->pc++); + value = cycle_read(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0; gb->registers[GB_REGISTER_AF] = (a + value + carry) << 8; @@ -1121,7 +1110,7 @@ static void adc_a_d8(GB_gameboy_t *gb, uint8_t opcode) static void sub_a_d8(GB_gameboy_t *gb, uint8_t opcode) { uint8_t value, a; - value = cycle_read_inc_oam_bug(gb, gb->pc++); + value = cycle_read(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; gb->registers[GB_REGISTER_AF] = ((a - value) << 8) | GB_SUBTRACT_FLAG; if (a == value) { @@ -1138,7 +1127,7 @@ static void sub_a_d8(GB_gameboy_t *gb, uint8_t opcode) static void sbc_a_d8(GB_gameboy_t *gb, uint8_t opcode) { uint8_t value, a, carry; - value = cycle_read_inc_oam_bug(gb, gb->pc++); + value = cycle_read(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; carry = (gb->registers[GB_REGISTER_AF] & GB_CARRY_FLAG) != 0; gb->registers[GB_REGISTER_AF] = ((a - value - carry) << 8) | GB_SUBTRACT_FLAG; @@ -1157,7 +1146,7 @@ static void sbc_a_d8(GB_gameboy_t *gb, uint8_t opcode) static void and_a_d8(GB_gameboy_t *gb, uint8_t opcode) { uint8_t value, a; - value = cycle_read_inc_oam_bug(gb, gb->pc++); + value = cycle_read(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; gb->registers[GB_REGISTER_AF] = ((a & value) << 8) | GB_HALF_CARRY_FLAG; if ((a & value) == 0) { @@ -1168,7 +1157,7 @@ static void and_a_d8(GB_gameboy_t *gb, uint8_t opcode) static void xor_a_d8(GB_gameboy_t *gb, uint8_t opcode) { uint8_t value, a; - value = cycle_read_inc_oam_bug(gb, gb->pc++); + value = cycle_read(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; gb->registers[GB_REGISTER_AF] = (a ^ value) << 8; if ((a ^ value) == 0) { @@ -1179,7 +1168,7 @@ static void xor_a_d8(GB_gameboy_t *gb, uint8_t opcode) static void or_a_d8(GB_gameboy_t *gb, uint8_t opcode) { uint8_t value, a; - value = cycle_read_inc_oam_bug(gb, gb->pc++); + value = cycle_read(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; gb->registers[GB_REGISTER_AF] = (a | value) << 8; if ((a | value) == 0) { @@ -1190,7 +1179,7 @@ static void or_a_d8(GB_gameboy_t *gb, uint8_t opcode) static void cp_a_d8(GB_gameboy_t *gb, uint8_t opcode) { uint8_t value, a; - value = cycle_read_inc_oam_bug(gb, gb->pc++); + value = cycle_read(gb, gb->pc++); a = gb->registers[GB_REGISTER_AF] >> 8; gb->registers[GB_REGISTER_AF] &= 0xFF00; gb->registers[GB_REGISTER_AF] |= GB_SUBTRACT_FLAG; @@ -1218,7 +1207,7 @@ static void rst(GB_gameboy_t *gb, uint8_t opcode) static void ret(GB_gameboy_t *gb, uint8_t opcode) { GB_debugger_ret_hook(gb); - gb->pc = cycle_read_inc_oam_bug(gb, gb->registers[GB_REGISTER_SP]++); + gb->pc = cycle_read(gb, gb->registers[GB_REGISTER_SP]++); gb->pc |= cycle_read(gb, gb->registers[GB_REGISTER_SP]++) << 8; cycle_no_access(gb); } @@ -1243,8 +1232,8 @@ static void ret_cc(GB_gameboy_t *gb, uint8_t opcode) static void call_a16(GB_gameboy_t *gb, uint8_t opcode) { uint16_t call_addr = gb->pc - 1; - uint16_t addr = cycle_read_inc_oam_bug(gb, gb->pc++); - addr |= (cycle_read_inc_oam_bug(gb, gb->pc++) << 8); + uint16_t addr = cycle_read(gb, gb->pc++); + addr |= (cycle_read(gb, gb->pc++) << 8); cycle_oam_bug(gb, GB_REGISTER_SP); cycle_write(gb, --gb->registers[GB_REGISTER_SP], (gb->pc) >> 8); cycle_write(gb, --gb->registers[GB_REGISTER_SP], (gb->pc) & 0xFF); @@ -1254,14 +1243,14 @@ static void call_a16(GB_gameboy_t *gb, uint8_t opcode) static void ld_da8_a(GB_gameboy_t *gb, uint8_t opcode) { - uint8_t temp = cycle_read_inc_oam_bug(gb, gb->pc++); + uint8_t temp = cycle_read(gb, gb->pc++); cycle_write(gb, 0xFF00 + temp, gb->registers[GB_REGISTER_AF] >> 8); } static void ld_a_da8(GB_gameboy_t *gb, uint8_t opcode) { gb->registers[GB_REGISTER_AF] &= 0xFF; - uint8_t temp = cycle_read_inc_oam_bug(gb, gb->pc++); + uint8_t temp = cycle_read(gb, gb->pc++); gb->registers[GB_REGISTER_AF] |= cycle_read(gb, 0xFF00 + temp) << 8; } @@ -1280,7 +1269,7 @@ static void add_sp_r8(GB_gameboy_t *gb, uint8_t opcode) { int16_t offset; uint16_t sp = gb->registers[GB_REGISTER_SP]; - offset = (int8_t) cycle_read_inc_oam_bug(gb, gb->pc++); + offset = (int8_t) cycle_read(gb, gb->pc++); cycle_no_access(gb); cycle_no_access(gb); gb->registers[GB_REGISTER_SP] += offset; @@ -1305,8 +1294,8 @@ static void jp_hl(GB_gameboy_t *gb, uint8_t opcode) static void ld_da16_a(GB_gameboy_t *gb, uint8_t opcode) { uint16_t addr; - addr = cycle_read_inc_oam_bug(gb, gb->pc++); - addr |= cycle_read_inc_oam_bug(gb, gb->pc++) << 8; + addr = cycle_read(gb, gb->pc++); + addr |= cycle_read(gb, gb->pc++) << 8; cycle_write(gb, addr, gb->registers[GB_REGISTER_AF] >> 8); } @@ -1314,8 +1303,8 @@ static void ld_a_da16(GB_gameboy_t *gb, uint8_t opcode) { uint16_t addr; gb->registers[GB_REGISTER_AF] &= 0xFF; - addr = cycle_read_inc_oam_bug(gb, gb->pc++); - addr |= cycle_read_inc_oam_bug(gb, gb->pc++) << 8; + addr = cycle_read(gb, gb->pc++); + addr |= cycle_read(gb, gb->pc++) << 8; gb->registers[GB_REGISTER_AF] |= cycle_read(gb, addr) << 8; } @@ -1338,7 +1327,7 @@ static void ld_hl_sp_r8(GB_gameboy_t *gb, uint8_t opcode) { int16_t offset; gb->registers[GB_REGISTER_AF] &= 0xFF00; - offset = (int8_t) cycle_read_inc_oam_bug(gb, gb->pc++); + offset = (int8_t) cycle_read(gb, gb->pc++); cycle_no_access(gb); gb->registers[GB_REGISTER_HL] = gb->registers[GB_REGISTER_SP] + offset; @@ -1512,7 +1501,7 @@ static void bit_r(GB_gameboy_t *gb, uint8_t opcode) static void cb_prefix(GB_gameboy_t *gb, uint8_t opcode) { - opcode = cycle_read_inc_oam_bug(gb, gb->pc++); + opcode = cycle_read(gb, gb->pc++); switch (opcode >> 3) { case 0: rlc_r(gb, opcode); @@ -1629,7 +1618,7 @@ void GB_cpu_run(GB_gameboy_t *gb) gb->speed_switch_halt_countdown = 0; uint16_t call_addr = gb->pc; - gb->last_opcode_read = cycle_read_inc_oam_bug(gb, gb->pc++); + gb->last_opcode_read = cycle_read(gb, gb->pc++); cycle_oam_bug_pc(gb); gb->pc--; GB_trigger_oam_bug(gb, gb->registers[GB_REGISTER_SP]); /* Todo: test T-cycle timing */ @@ -1664,7 +1653,7 @@ void GB_cpu_run(GB_gameboy_t *gb) } /* Run mode */ else if (!gb->halted) { - gb->last_opcode_read = cycle_read_inc_oam_bug(gb, gb->pc++); + gb->last_opcode_read = cycle_read(gb, gb->pc++); if (gb->halt_bug) { gb->pc--; gb->halt_bug = false;