Improved serial interrupt timing, fixes boot_sclk_align.
This commit is contained in:
parent
623f92378d
commit
c4ccbd5cce
@ -479,6 +479,8 @@ void GB_reset(GB_gameboy_t *gb)
|
||||
}
|
||||
gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0xFF;
|
||||
}
|
||||
/* The serial interrupt always occur on the 0xF8th cycle of every 0x100 cycle since boot. */
|
||||
gb->serial_cycles = 0x100 - 0xF8;
|
||||
gb->io_registers[GB_IO_SC] = 0x7E;
|
||||
gb->magic = (uintptr_t)'SAME';
|
||||
}
|
||||
|
@ -329,7 +329,9 @@ struct GB_gameboy_internal_s {
|
||||
uint32_t display_cycles;
|
||||
uint32_t div_cycles;
|
||||
uint8_t tima_reload_state; /* After TIMA overflows, it becomes 0 for 4 cycles before actually reloading. */
|
||||
uint16_t serial_cycles;
|
||||
GB_PADDING(uint16_t, serial_cycles);
|
||||
uint16_t serial_cycles; /* This field changed its meaning in v0.10 */
|
||||
uint16_t serial_length;
|
||||
);
|
||||
|
||||
/* APU */
|
||||
|
@ -617,13 +617,15 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value)
|
||||
}
|
||||
gb->io_registers[GB_IO_SC] = value | (~0x83);
|
||||
if ((value & 0x80) && (value & 0x1) ) {
|
||||
gb->serial_cycles = gb->cgb_mode && (value & 2)? 128 : 4096;
|
||||
gb->serial_length = gb->cgb_mode && (value & 2)? 128 : 4096;
|
||||
/* Todo: This is probably incorrect for CGB's faster clock mode. */
|
||||
gb->serial_cycles &= 0xFF;
|
||||
if (gb->serial_transfer_start_callback) {
|
||||
gb->serial_transfer_start_callback(gb, gb->io_registers[GB_IO_SB]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
gb->serial_cycles = 0;
|
||||
gb->serial_length = 0;
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -107,9 +107,11 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
||||
}
|
||||
}
|
||||
|
||||
if (gb->serial_cycles) {
|
||||
if (gb->serial_cycles <= cycles) {
|
||||
gb->serial_cycles = 0;
|
||||
uint16_t previous_serial_cycles = gb->serial_cycles;
|
||||
gb->serial_cycles += cycles;
|
||||
if (gb->serial_length) {
|
||||
if ((gb->serial_cycles & gb->serial_length) != (previous_serial_cycles & gb->serial_length)) {
|
||||
gb->serial_length = 0;
|
||||
gb->io_registers[GB_IO_SC] &= ~0x80;
|
||||
/* TODO: Does SB "update" bit by bit? */
|
||||
if (gb->serial_transfer_end_callback) {
|
||||
@ -121,9 +123,6 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles)
|
||||
|
||||
gb->io_registers[GB_IO_IF] |= 8;
|
||||
}
|
||||
else {
|
||||
gb->serial_cycles -= cycles;
|
||||
}
|
||||
}
|
||||
|
||||
gb->debugger_ticks += cycles;
|
||||
|
Loading…
Reference in New Issue
Block a user