From 603b8969ab3cf179f6457d98ca2fb4996ff37b57 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Mon, 5 Sep 2016 22:13:28 +0300 Subject: [PATCH] Correct (disconnected) serial emulation. --- Core/gb.c | 4 ++-- Core/gb.h | 1 + Core/memory.c | 16 ++++++++++++---- Core/timing.c | 12 ++++++++++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Core/gb.c b/Core/gb.c index 76ccf87e..dd591d03 100755 --- a/Core/gb.c +++ b/Core/gb.c @@ -111,8 +111,8 @@ void GB_init(GB_gameboy_t *gb) gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0xFF; - gb->io_registers[GB_IO_JOYP] = 0xF; + gb->io_registers[GB_IO_SC] = 0x7E; } void GB_init_cgb(GB_gameboy_t *gb) @@ -134,8 +134,8 @@ void GB_init_cgb(GB_gameboy_t *gb) gb->cartridge_type = &GB_cart_defs[0]; // Default cartridge type gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0xFF; - gb->io_registers[GB_IO_JOYP] = 0xF; + gb->io_registers[GB_IO_SC] = 0x7C; } void GB_free(GB_gameboy_t *gb) diff --git a/Core/gb.h b/Core/gb.h index bd8d0eb8..dd6c7c01 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -295,6 +295,7 @@ typedef struct GB_gameboy_s { GB_PADDING(uint32_t, dma_cycles); GB_aligned_double apu_cycles; uint8_t tima_reload_state; /* After TIMA overflows, it becomes 0 for 4 cycles before actually reloading. */ + uint16_t serial_cycles; ); /* APU */ diff --git a/Core/memory.c b/Core/memory.c index 9fd2a54b..8faa0dff 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -162,6 +162,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) case GB_IO_OBP1: case GB_IO_WY: case GB_IO_WX: + case GB_IO_SC: case GB_IO_SB: return gb->io_registers[addr & 0xFF]; case GB_IO_TIMA: @@ -220,8 +221,6 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) } return ret; } - case GB_IO_SC: /* Serial not supported yet */ - return 0x7E; default: if ((addr & 0xFF) >= GB_IO_NR10 && (addr & 0xFF) <= GB_IO_WAV_END) { return GB_apu_read(gb, addr & 0xFF); @@ -521,10 +520,19 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) gb->hdma_cycles = 0; return; + /* Todo: what happens when starting a transfer during a transfer? + What happens when starting a transfer during external clock? + */ case GB_IO_SC: + if (!gb->cgb_mode) { + value |= 2; + } + gb->io_registers[GB_IO_SC] = value | (~0x83); if ((value & 0x80) && (value & 0x1) ) { - gb->io_registers[GB_IO_SB] = 0xFF; - gb->io_registers[GB_IO_IF] |= 0x8; + gb->serial_cycles = gb->cgb_mode && (value & 2)? 128 : 4096; + } + else { + gb->serial_cycles = 0; } return; diff --git a/Core/timing.c b/Core/timing.c index 24f7da70..726fb36d 100644 --- a/Core/timing.c +++ b/Core/timing.c @@ -41,6 +41,18 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles) } } + if (gb->serial_cycles) { + if (gb->serial_cycles <= cycles) { + gb->serial_cycles = 0; + gb->io_registers[GB_IO_SC] &= ~0x80; + gb->io_registers[GB_IO_SB] = 0xFF; + gb->io_registers[GB_IO_IF] |= 8; + } + else { + gb->serial_cycles -= cycles; + } + } + if (gb->cgb_double_speed) { cycles >>=1; }