Misc minor fixes, fixes several Mooneye-GB tests

This commit is contained in:
Lior Halphon 2017-06-21 09:35:57 +03:00
parent efbc385417
commit c59272d46d
4 changed files with 47 additions and 18 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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';
}

View File

@ -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;