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
4 files changed,
22 insertions(+),
1 deletions(-)
M
CHANGES
→
CHANGES
@@ -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.h
→
include/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.c
→
src/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.c
→
src/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) {