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) 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); while (gb->audio_copy_in_progress);
double ticks_per_sample = (double) CPU_FREQUENCY / gb->sample_rate; 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_STAT] |= 1;
gb->io_registers[GB_IO_IF] |= 1; gb->io_registers[GB_IO_IF] |= 1;
/* Entering VBlank state triggers the OAM interrupt */ /* Entering VBlank state triggers the OAM interrupt. In CGB, it happens 4 cycles earlier */
if (gb->io_registers[GB_IO_STAT] & 0x20) { if (gb->io_registers[GB_IO_STAT] & 0x20 && !gb->is_cgb) {
gb->stat_interrupt_line = true; gb->stat_interrupt_line = true;
} }
if (gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON) { 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); display_vblank(gb);
} }
} }
/* Handle line 0 right after turning the LCD on */ /* Handle line 0 right after turning the LCD on */
else if (gb->first_scanline) { 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) { if (gb->stat_interrupt_line && !previous_stat_interrupt_line) {
gb->io_registers[GB_IO_IF] |= 2; 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->last_rtc_second = time(NULL);
gb->cgb_ram_bank = 1; gb->cgb_ram_bank = 1;
gb->io_registers[GB_IO_JOYP] = 0xF; 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; gb->mbc_ram_size = mbc_ram_size;
if (cgb) { if (cgb) {
gb->ram_size = 0x2000 * 8; gb->ram_size = 0x2000 * 8;
@ -460,8 +459,7 @@ void GB_reset(GB_gameboy_t *gb)
gb->is_cgb = true; gb->is_cgb = true;
gb->cgb_mode = true; gb->cgb_mode = true;
gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0x00;
gb->io_registers[GB_IO_SC] = 0x7C;
} }
else { else {
gb->ram_size = 0x2000; 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->sprite_palettes_rgb[7] = gb->sprite_palettes_rgb[3] = gb->background_palettes_rgb[3] =
gb->rgb_encode_callback(gb, 0, 0, 0); gb->rgb_encode_callback(gb, 0, 0, 0);
} }
gb->io_registers[GB_IO_OBP0] = gb->io_registers[GB_IO_OBP1] = 0xFF;
gb->io_registers[GB_IO_SC] = 0x7E;
} }
gb->io_registers[GB_IO_SC] = 0x7E;
gb->magic = (uintptr_t)'SAME'; 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: case GB_IO_STAT:
return gb->io_registers[GB_IO_STAT] | 0x80; return gb->io_registers[GB_IO_STAT] | 0x80;
case GB_IO_DMG_EMULATION_INDICATION: case GB_IO_DMG_EMULATION_INDICATION:
if (!gb->is_cgb) { if (!gb->cgb_mode) {
return 0xFF; return 0xFF;
} }
return gb->io_registers[GB_IO_DMG_EMULATION_INDICATION] | 0xFE; 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: case GB_IO_DIV:
return gb->div_cycles >> 8; return gb->div_cycles >> 8;
case GB_IO_HDMA5: 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); return ((gb->hdma_on || gb->hdma_on_hblank)? 0 : 0x80) | ((gb->hdma_steps_left - 1) & 0x7F);
case GB_IO_SVBK: case GB_IO_SVBK:
if (!gb->cgb_mode) { 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; return gb->cgb_ram_bank | ~0x7;
case GB_IO_VBK: case GB_IO_VBK:
if (!gb->cgb_mode) { if (!gb->is_cgb) {
return 0xFF; return 0xFF;
} }
return gb->cgb_vram_bank | ~0x1; 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_BGPI:
case GB_IO_OBPI: case GB_IO_OBPI:
if (!gb->cgb_mode && gb->boot_rom_finished) { if (!gb->is_cgb) {
return 0xFF; return 0xFF;
} }
return gb->io_registers[addr & 0xFF] | 0x40; 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); return (gb->io_registers[GB_IO_KEY1] & 0x7F) | (gb->cgb_double_speed? 0xFE : 0x7E);
case GB_IO_RP: { 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. */ /* You will read your own IR LED if it's on. */
bool read_value = gb->infrared_input || (gb->io_registers[GB_IO_RP] & 1); bool read_value = gb->infrared_input || (gb->io_registers[GB_IO_RP] & 1);
uint8_t ret = (gb->io_registers[GB_IO_RP] & 0xC1) | 0x3C; 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; 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: default:
if ((addr & 0xFF) >= GB_IO_NR10 && (addr & 0xFF) <= GB_IO_WAV_END) { if ((addr & 0xFF) >= GB_IO_NR10 && (addr & 0xFF) <= GB_IO_WAV_END) {
return GB_apu_read(gb, addr & 0xFF); 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_WX:
case GB_IO_SB: case GB_IO_SB:
case GB_IO_DMG_EMULATION_INDICATION: 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; gb->io_registers[addr & 0xFF] = value;
return; 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_BGPI:
case GB_IO_OBPI: case GB_IO_OBPI:
if (!gb->cgb_mode && gb->boot_rom_finished) { if (!gb->is_cgb) {
return; return;
} }
gb->io_registers[addr & 0xFF] = value; 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; gb->io_registers[GB_IO_KEY1] = value;
return; return;
case GB_IO_HDMA1: case GB_IO_HDMA1:
if (gb->is_cgb) { if (gb->cgb_mode) {
gb->hdma_current_src &= 0xF0; gb->hdma_current_src &= 0xF0;
gb->hdma_current_src |= value << 8; gb->hdma_current_src |= value << 8;
} }
return; return;
case GB_IO_HDMA2: case GB_IO_HDMA2:
if (gb->is_cgb) { if (gb->cgb_mode) {
gb->hdma_current_src &= 0xFF00; gb->hdma_current_src &= 0xFF00;
gb->hdma_current_src |= value & 0xF0; gb->hdma_current_src |= value & 0xF0;
} }
return; return;
case GB_IO_HDMA3: case GB_IO_HDMA3:
if (gb->is_cgb) { if (gb->cgb_mode) {
gb->hdma_current_dest &= 0xF0; gb->hdma_current_dest &= 0xF0;
gb->hdma_current_dest |= value << 8; gb->hdma_current_dest |= value << 8;
} }
return; return;
case GB_IO_HDMA4: case GB_IO_HDMA4:
if (gb->is_cgb) { if (gb->cgb_mode) {
gb->hdma_current_dest &= 0x1F00; gb->hdma_current_dest &= 0x1F00;
gb->hdma_current_dest |= value & 0xF0; gb->hdma_current_dest |= value & 0xF0;
} }
return; return;
case GB_IO_HDMA5: case GB_IO_HDMA5:
if (!gb->cgb_mode) return;
if ((value & 0x80) == 0 && gb->hdma_on_hblank) { if ((value & 0x80) == 0 && gb->hdma_on_hblank) {
gb->hdma_on_hblank = false; gb->hdma_on_hblank = false;
return; return;