From c59272d46d55ba6a92084488ecddc9006158a924 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Wed, 21 Jun 2017 09:35:57 +0300 Subject: [PATCH] Misc minor fixes, fixes several Mooneye-GB tests --- Core/apu.c | 8 +++++++- Core/display.c | 13 +++++++++++-- Core/gb.c | 8 +++----- Core/memory.c | 36 ++++++++++++++++++++++++++---------- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/Core/apu.c b/Core/apu.c index cb87e66..e0e0b89 100755 --- a/Core/apu.c +++ b/Core/apu.c @@ -185,7 +185,13 @@ void GB_apu_get_samples_and_update_pcm_regs(GB_gameboy_t *gb, GB_sample_t *sampl void GB_apu_run(GB_gameboy_t *gb) { - if (gb->sample_rate == 0) return; + if (gb->sample_rate == 0) { + if (gb->apu.apu_cycles > 0xFF00) { + GB_sample_t dummy; + GB_apu_get_samples_and_update_pcm_regs(gb, &dummy); + } + return; + } while (gb->audio_copy_in_progress); double ticks_per_sample = (double) CPU_FREQUENCY / gb->sample_rate; diff --git a/Core/display.c b/Core/display.c index 5208e54..e624ac9 100755 --- a/Core/display.c +++ b/Core/display.c @@ -337,8 +337,8 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles) gb->io_registers[GB_IO_STAT] |= 1; gb->io_registers[GB_IO_IF] |= 1; - /* Entering VBlank state triggers the OAM interrupt */ - if (gb->io_registers[GB_IO_STAT] & 0x20) { + /* Entering VBlank state triggers the OAM interrupt. In CGB, it happens 4 cycles earlier */ + if (gb->io_registers[GB_IO_STAT] & 0x20 && !gb->is_cgb) { gb->stat_interrupt_line = true; } if (gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON) { @@ -355,6 +355,7 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles) display_vblank(gb); } } + /* Handle line 0 right after turning the LCD on */ else if (gb->first_scanline) { @@ -548,6 +549,14 @@ static void update_display_state(GB_gameboy_t *gb, uint8_t cycles) } } + /* On the CGB, the last cycle of line 144 triggers an OAM interrupt + Todo: Verify timing for CGB in CGB mode and double speed CGB */ + if (gb->is_cgb && + gb->display_cycles == LINES * LINE_LENGTH + stat_delay - atomic_increase && + (gb->io_registers[GB_IO_STAT] & 0x20)) { + gb->stat_interrupt_line = true; + } + if (gb->stat_interrupt_line && !previous_stat_interrupt_line) { gb->io_registers[GB_IO_IF] |= 2; } diff --git a/Core/gb.c b/Core/gb.c index 73469dc..ec12b39 100755 --- a/Core/gb.c +++ b/Core/gb.c @@ -450,7 +450,6 @@ void GB_reset(GB_gameboy_t *gb) gb->last_rtc_second = time(NULL); gb->cgb_ram_bank = 1; gb->io_registers[GB_IO_JOYP] = 0xF; - gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0xFF; gb->mbc_ram_size = mbc_ram_size; if (cgb) { gb->ram_size = 0x2000 * 8; @@ -460,8 +459,7 @@ void GB_reset(GB_gameboy_t *gb) gb->is_cgb = true; gb->cgb_mode = true; - - gb->io_registers[GB_IO_SC] = 0x7C; + gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0x00; } else { gb->ram_size = 0x2000; @@ -479,9 +477,9 @@ 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_SC] = 0x7E; + gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0xFF; } + gb->io_registers[GB_IO_SC] = 0x7E; gb->magic = (uintptr_t)'SAME'; } diff --git a/Core/memory.c b/Core/memory.c index 4213585..b913ba5 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -142,7 +142,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) case GB_IO_STAT: return gb->io_registers[GB_IO_STAT] | 0x80; case GB_IO_DMG_EMULATION_INDICATION: - if (!gb->is_cgb) { + if (!gb->cgb_mode) { return 0xFF; } return gb->io_registers[GB_IO_DMG_EMULATION_INDICATION] | 0xFE; @@ -178,7 +178,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) case GB_IO_DIV: return gb->div_cycles >> 8; case GB_IO_HDMA5: - if (!gb->is_cgb) return 0xFF; + if (!gb->cgb_mode) return 0xFF; return ((gb->hdma_on || gb->hdma_on_hblank)? 0 : 0x80) | ((gb->hdma_steps_left - 1) & 0x7F); case GB_IO_SVBK: if (!gb->cgb_mode) { @@ -186,14 +186,15 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) } return gb->cgb_ram_bank | ~0x7; case GB_IO_VBK: - if (!gb->cgb_mode) { + if (!gb->is_cgb) { return 0xFF; } return gb->cgb_vram_bank | ~0x1; + /* Todo: It seems that a CGB in DMG mode can access BGPI and OBPI, but not BGPD and OBPD? */ case GB_IO_BGPI: case GB_IO_OBPI: - if (!gb->cgb_mode && gb->boot_rom_finished) { + if (!gb->is_cgb) { return 0xFF; } return gb->io_registers[addr & 0xFF] | 0x40; @@ -217,7 +218,7 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) return (gb->io_registers[GB_IO_KEY1] & 0x7F) | (gb->cgb_double_speed? 0xFE : 0x7E); case GB_IO_RP: { - if (!gb->is_cgb) return 0xFF; + if (!gb->cgb_mode) return 0xFF; /* You will read your own IR LED if it's on. */ bool read_value = gb->infrared_input || (gb->io_registers[GB_IO_RP] & 1); uint8_t ret = (gb->io_registers[GB_IO_RP] & 0xC1) | 0x3C; @@ -226,6 +227,16 @@ 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; + case GB_IO_UNKNOWN4: + return gb->cgb_mode? gb->io_registers[addr & 0xFF] : 0xFF; + case GB_IO_UNKNOWN5: + return gb->is_cgb? gb->io_registers[addr & 0xFF] | 0x8F : 0xFF; default: if ((addr & 0xFF) >= GB_IO_NR10 && (addr & 0xFF) <= GB_IO_WAV_END) { return GB_apu_read(gb, addr & 0xFF); @@ -412,6 +423,10 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) case GB_IO_WX: case GB_IO_SB: case GB_IO_DMG_EMULATION_INDICATION: + case GB_IO_UNKNOWN2: + case GB_IO_UNKNOWN3: + case GB_IO_UNKNOWN4: + case GB_IO_UNKNOWN5: gb->io_registers[addr & 0xFF] = value; return; @@ -520,7 +535,7 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) case GB_IO_BGPI: case GB_IO_OBPI: - if (!gb->cgb_mode && gb->boot_rom_finished) { + if (!gb->is_cgb) { return; } gb->io_registers[addr & 0xFF] = value; @@ -549,30 +564,31 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) gb->io_registers[GB_IO_KEY1] = value; return; case GB_IO_HDMA1: - if (gb->is_cgb) { + if (gb->cgb_mode) { gb->hdma_current_src &= 0xF0; gb->hdma_current_src |= value << 8; } return; case GB_IO_HDMA2: - if (gb->is_cgb) { + if (gb->cgb_mode) { gb->hdma_current_src &= 0xFF00; gb->hdma_current_src |= value & 0xF0; } return; case GB_IO_HDMA3: - if (gb->is_cgb) { + if (gb->cgb_mode) { gb->hdma_current_dest &= 0xF0; gb->hdma_current_dest |= value << 8; } return; case GB_IO_HDMA4: - if (gb->is_cgb) { + if (gb->cgb_mode) { gb->hdma_current_dest &= 0x1F00; gb->hdma_current_dest |= value & 0xF0; } return; case GB_IO_HDMA5: + if (!gb->cgb_mode) return; if ((value & 0x80) == 0 && gb->hdma_on_hblank) { gb->hdma_on_hblank = false; return;