From 577e23925bc304b93a3048e080def73eff37a784 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Thu, 22 Mar 2018 20:09:01 +0200 Subject: [PATCH] Fixed sources-dmgABCXmgbS --- Core/gb.c | 5 +++-- Core/memory.c | 40 +++++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Core/gb.c b/Core/gb.c index 43c2980..dabf913 100755 --- a/Core/gb.c +++ b/Core/gb.c @@ -476,7 +476,6 @@ void GB_reset(GB_gameboy_t *gb) gb->is_cgb = true; gb->cgb_mode = true; - gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0x00; } else { gb->ram_size = 0x2000; @@ -494,8 +493,10 @@ void GB_reset(GB_gameboy_t *gb) gb->sprite_palettes_rgb[7] = gb->sprite_palettes_rgb[3] = gb->background_palettes_rgb[3] = gb->rgb_encode_callback(gb, 0, 0, 0); } - gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0xFF; } + + /* These are not deterministic, but 00 (CGB) and FF (DMG) are the most common initial values by far */ + gb->io_registers[GB_IO_DMA] = gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = gb->is_cgb? 0x00 : 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; diff --git a/Core/memory.c b/Core/memory.c index 2bd8215..4180c43 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -31,7 +31,7 @@ static GB_bus_t bus_for_addr(GB_gameboy_t *gb, uint16_t addr) static bool is_addr_in_dma_use(GB_gameboy_t *gb, uint16_t addr) { - if (!gb->dma_steps_left || (gb->dma_cycles < 0 && !gb->is_dma_restarting)) return false; + if (!gb->dma_steps_left || (gb->dma_cycles < 0 && !gb->is_dma_restarting) || addr >= 0xFE00) return false; return bus_for_addr(gb, addr) == bus_for_addr(gb, gb->dma_current_src); } @@ -174,6 +174,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) case GB_IO_WX: case GB_IO_SC: case GB_IO_SB: + case GB_IO_DMA: return gb->io_registers[addr & 0xFF]; case GB_IO_TIMA: if (gb->tima_reload_state == GB_TIMA_RELOADING) { @@ -232,9 +233,6 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) } return ret; } - case GB_IO_DMA: - /* Todo: is this documented? */ - return gb->is_cgb? 0x00 : 0xFF; case GB_IO_UNKNOWN2: case GB_IO_UNKNOWN3: return gb->is_cgb? gb->io_registers[addr & 0xFF] : 0xFF; @@ -509,21 +507,18 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) return; case GB_IO_DMA: - if (value <= 0xE0) { - if (gb->dma_steps_left) { - /* This is not correct emulation, since we're not really delaying the second DMA. - One write that should have happened in the first DMA will not happen. However, - since that byte will be overwritten by the second DMA before it can actually be - read, it doesn't actually matter. */ - gb->is_dma_restarting = true; - } - gb->dma_cycles = -7; - gb->dma_current_dest = 0; - gb->dma_current_src = value << 8; - gb->dma_steps_left = 0xa0; + if (gb->dma_steps_left) { + /* This is not correct emulation, since we're not really delaying the second DMA. + One write that should have happened in the first DMA will not happen. However, + since that byte will be overwritten by the second DMA before it can actually be + read, it doesn't actually matter. */ + gb->is_dma_restarting = true; } - /* else { what? } */ - + gb->dma_cycles = -7; + gb->dma_current_dest = 0; + gb->dma_current_src = value << 8; + gb->dma_steps_left = 0xa0; + gb->io_registers[GB_IO_DMA] = value; return; case GB_IO_SVBK: if (!gb->cgb_mode) { @@ -701,7 +696,14 @@ void GB_dma_run(GB_gameboy_t *gb) /* Todo: measure this value */ gb->dma_cycles -= 4; gb->dma_steps_left--; - gb->oam[gb->dma_current_dest++] = GB_read_memory(gb, gb->dma_current_src); + if (gb->dma_current_src < 0xe000) { + gb->oam[gb->dma_current_dest++] = GB_read_memory(gb, gb->dma_current_src); + } + else { + /* Todo: Not correct on the CGB */ + gb->oam[gb->dma_current_dest++] = GB_read_memory(gb, gb->dma_current_src & ~0x2000); + } + /* dma_current_src must be the correct value during GB_read_memory */ gb->dma_current_src++; if (!gb->dma_steps_left) {