all repos — mgba @ 9ddf82bebc1915ce8bee833e44b0a8eaa6451bbc

mGBA Game Boy Advance Emulator

GB Video: Fix state after skipping BIOS (fixes #1715 and fixes #1716)
Vicki Pfau vi@endrift.com
Wed, 13 May 2020 01:56:46 -0700
commit

9ddf82bebc1915ce8bee833e44b0a8eaa6451bbc

parent

f33593537beac5434ac1277c594c18ba4e6ff886

4 files changed, 22 insertions(+), 1 deletions(-)

jump to
M CHANGESCHANGES

@@ -6,6 +6,7 @@ Emulation fixes:

- ARM: Fix ALU reading PC after shifting - ARM: Fix STR storing PC after address calculation - GB: Fix GBC game registers after skipping BIOS + - GB Video: Fix state after skipping BIOS (fixes mgba.io/i/1715 and mgba.io/i/1716) - GBA: Add missing RTC overrides for Legendz games - GBA BIOS: Implement dummy sound driver calls - GBA BIOS: Improve HLE BIOS timing
M include/mgba/internal/gb/video.hinclude/mgba/internal/gb/video.h

@@ -161,6 +161,7 @@ void GBVideoInit(struct GBVideo* video);

void GBVideoReset(struct GBVideo* video); void GBVideoDeinit(struct GBVideo* video); void GBVideoAssociateRenderer(struct GBVideo* video, struct GBVideoRenderer* renderer); +void GBVideoSkipBIOS(struct GBVideo* video); void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate); void GBVideoWriteLCDC(struct GBVideo* video, GBRegisterLCDC value);
M src/gb/gb.csrc/gb/gb.c

@@ -460,13 +460,13 @@ }

GBVideoReset(&gb->video); GBTimerReset(&gb->timer); + GBIOReset(gb); if (!gb->biosVf) { GBSkipBIOS(gb); } else { mTimingSchedule(&gb->timing, &gb->timer.event, 0); } - GBIOReset(gb); GBAudioReset(&gb->audio); GBSIOReset(&gb->sio);

@@ -561,6 +561,7 @@ mTimingDeschedule(&gb->timing, &gb->timer.event);

mTimingSchedule(&gb->timing, &gb->timer.event, 0); GBIOWrite(gb, REG_LCDC, 0x91); + GBVideoSkipBIOS(&gb->video); if (gb->biosVf) { GBUnmapBIOS(gb);
M src/gb/video.csrc/gb/video.c

@@ -214,6 +214,24 @@ }

return false; } +void GBVideoSkipBIOS(struct GBVideo* video) { + video->mode = 1; + video->modeEvent.callback = _endMode1; + + if (video->p->model == GB_MODEL_CGB) { + video->ly = GB_VIDEO_VERTICAL_PIXELS; + video->p->memory.io[REG_LY] = video->ly; + video->stat = GBRegisterSTATClearLYC(video->stat); + } + video->stat = GBRegisterSTATSetMode(video->stat, video->mode); + + video->p->memory.io[REG_IF] |= (1 << GB_IRQ_VBLANK); + GBUpdateIRQs(video->p); + video->p->memory.io[REG_STAT] = video->stat; + mTimingDeschedule(&video->p->timing, &video->modeEvent); + mTimingSchedule(&video->p->timing, &video->modeEvent, GB_VIDEO_HORIZONTAL_LENGTH << video->p->doubleSpeed); +} + void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) { struct GBVideo* video = context; if (video->frameskipCounter <= 0) {