From 0cd1c3ffeb1076666d91b677844632f331b9bb68 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 26 Feb 2019 21:17:19 -0800 Subject: [PATCH 01/20] Qt: Add missing link library on Windows --- src/platform/qt/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index cc719d97a..cc02550ed 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -286,7 +286,7 @@ if(QT_STATIC) find_library(QTPCRE NAMES qtpcre2 qtpcre) if(WIN32) list(APPEND QT_LIBRARIES qwindows dwmapi imm32 uxtheme Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport) - set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ws2_32") + set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ws2_32;iphlpapi") elseif(APPLE) find_package(Cups) find_package(Qt5PrintSupport) From f8cd425fad34dca37c373cee762915202a07e686 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 26 Feb 2019 21:56:53 -0800 Subject: [PATCH 02/20] Qt: Add missing HEVC NVENC option (fixes #1323) --- CHANGES | 1 + src/platform/qt/VideoView.ui | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/CHANGES b/CHANGES index 7aa062fe0..f78f68473 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Misc: - GB Memory: Support running from blocked memory - Qt: Don't unload ROM immediately if it crashes - Debugger: Add breakpoint and watchpoint listing + - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/VideoView.ui b/src/platform/qt/VideoView.ui index 1e9dfe367..24a3c5e75 100644 --- a/src/platform/qt/VideoView.ui +++ b/src/platform/qt/VideoView.ui @@ -269,6 +269,11 @@ HEVC + + + HEVC (NVENC) + + VP8 From 27f8abff155aad5df5632b415a8d83213586a34f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Feb 2019 19:02:19 -0800 Subject: [PATCH 03/20] Qt: Fix build on macOS --- src/platform/qt/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index cc02550ed..3e5400838 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -293,7 +293,7 @@ if(QT_STATIC) find_library(QTFREETYPE NAMES qtfreetype) find_library(QTHARFBUZZ NAMES qtharfbuzzng qtharfbuzz) find_library(QTPLATFORMSUPPORT NAMES Qt5PlatformSupport) - list(APPEND QT_LIBRARIES Cups Qt5::PrintSupport Qt5::QCocoaIntegrationPlugin Qt5::CoreAudioPlugin Qt5::AVFServicePlugin Qt5::QCocoaPrinterSupportPlugin ${QTPLATFORMSUPPORT} "-framework AVFoundation" "-framework CoreMedia") + list(APPEND QT_LIBRARIES Cups Qt5::PrintSupport Qt5::QCocoaIntegrationPlugin Qt5::CoreAudioPlugin Qt5::AVFServicePlugin Qt5::QCocoaPrinterSupportPlugin ${QTPLATFORMSUPPORT} "-framework AVFoundation" "-framework CoreMedia" "-framework SystemConfiguration" "-framework Security") set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};${QTHARFBUZZ};${QTFREETYPE}") link_directories() endif() From 3c5a9258a72ef9b7f5904783857c42232064119d Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Feb 2019 19:02:40 -0800 Subject: [PATCH 04/20] Qt: Fix updater not flushing --- src/platform/qt/AbstractUpdater.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platform/qt/AbstractUpdater.cpp b/src/platform/qt/AbstractUpdater.cpp index c165ae1a0..02f23c956 100644 --- a/src/platform/qt/AbstractUpdater.cpp +++ b/src/platform/qt/AbstractUpdater.cpp @@ -85,5 +85,7 @@ void AbstractUpdater::updateDownloaded(QNetworkReply* reply) { } f.write(bytes); } + f.flush(); + f.close(); emit updateDone(true); } From 6ee24a21de74fd76fe0af51ee4db7db2e6fcc786 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Feb 2019 19:42:22 -0800 Subject: [PATCH 05/20] Qt: Update static build info --- src/platform/qt/CMakeLists.txt | 6 +++--- src/platform/qt/main.cpp | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/platform/qt/CMakeLists.txt b/src/platform/qt/CMakeLists.txt index 3e5400838..36766daf7 100644 --- a/src/platform/qt/CMakeLists.txt +++ b/src/platform/qt/CMakeLists.txt @@ -181,7 +181,7 @@ if(Qt5Multimedia_FOUND) list(APPEND SOURCE_FILES VideoDumper.cpp) if (WIN32 AND QT_STATIC) - list(APPEND QT_LIBRARIES Qt5::QWindowsAudioPlugin Qt5::DSServicePlugin + list(APPEND QT_LIBRARIES Qt5::QWindowsAudioPlugin Qt5::DSServicePlugin Qt5::QWindowsVistaStylePlugin strmiids mfuuid mfplat mf ksguid dxva2 evr d3d9) endif() list(APPEND QT_LIBRARIES Qt5::Multimedia) @@ -285,8 +285,8 @@ endif() if(QT_STATIC) find_library(QTPCRE NAMES qtpcre2 qtpcre) if(WIN32) - list(APPEND QT_LIBRARIES qwindows dwmapi imm32 uxtheme Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport) - set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ws2_32;iphlpapi") + list(APPEND QT_LIBRARIES qwindows dwmapi imm32 uxtheme Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport Qt5WindowsUIAutomationSupport) + set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ssl;crypto;ws2_32;iphlpapi;crypt32;userenv;netapi32;wtsapi32") elseif(APPLE) find_package(Cups) find_package(Qt5PrintSupport) diff --git a/src/platform/qt/main.cpp b/src/platform/qt/main.cpp index 8edc96e79..ec6a1b9e8 100644 --- a/src/platform/qt/main.cpp +++ b/src/platform/qt/main.cpp @@ -21,6 +21,7 @@ #include #ifdef Q_OS_WIN Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); +Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin); #ifdef BUILD_QT_MULTIMEDIA Q_IMPORT_PLUGIN(QWindowsAudioPlugin); Q_IMPORT_PLUGIN(DSServicePlugin); From 16688a59717d43518dfa7f9c2c10fdde148e1a70 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Wed, 27 Feb 2019 22:07:34 -0800 Subject: [PATCH 06/20] Qt: Minor about screen fixes --- src/platform/qt/AboutScreen.ui | 2 +- src/platform/qt/Window.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/qt/AboutScreen.ui b/src/platform/qt/AboutScreen.ui index d01aacdbb..c6f166e57 100644 --- a/src/platform/qt/AboutScreen.ui +++ b/src/platform/qt/AboutScreen.ui @@ -83,7 +83,7 @@ - © 2013 – 2018 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 + © 2013 – 2019 Jeffrey Pfau, licensed under the Mozilla Public License, version 2.0 Game Boy Advance is a registered trademark of Nintendo Co., Ltd. diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 506e410e1..7a8c97dfc 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -1190,7 +1190,7 @@ void Window::setupMenu(QMenuBar* menubar) { fileMenu->addSeparator(); #endif - QAction* about = new QAction(tr("About"), fileMenu); + QAction* about = new QAction(tr("About..."), fileMenu); connect(about, &QAction::triggered, openTView()); fileMenu->addAction(about); From eafb1ca06be6adcaa737cabf52eeef41e1b0d7d4 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 28 Feb 2019 19:23:35 -0800 Subject: [PATCH 07/20] Qt: Fix load recent from archive (fixes #1325) --- CHANGES | 1 + src/platform/qt/CoreManager.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index f78f68473..4e9653d92 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,7 @@ Bugfixes: - GBA: Reset now reloads multiboot ROMs - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - Qt: More app metadata fixes + - Qt: Fix load recent from archive (fixes mgba.io/i/1325) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/platform/qt/CoreManager.cpp b/src/platform/qt/CoreManager.cpp index adb002c18..a77334cc5 100644 --- a/src/platform/qt/CoreManager.cpp +++ b/src/platform/qt/CoreManager.cpp @@ -49,7 +49,7 @@ CoreController* CoreManager::loadGame(const QString& path) { vf = vfclone; } dir->close(dir); - loadGame(vf, fname, base); + return loadGame(vf, fname, base); } else { LOG(QT, ERROR) << tr("Failed to open game file: %1").arg(path); } From f9ff88302f3de521a0f71ffbe8d15d9bfd9d0c8c Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 12:46:46 -0800 Subject: [PATCH 08/20] GB Video: Delay LYC STAT check (fixes #1331) --- CHANGES | 1 + src/gb/video.c | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 4e9653d92..e79ec1691 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ Bugfixes: - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) + - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/gb/video.c b/src/gb/video.c index d63460088..8aa978292 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -224,7 +224,6 @@ void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) { ++video->ly; video->p->memory.io[REG_LY] = video->ly; GBRegisterSTAT oldStat = video->stat; - video->stat = GBRegisterSTATSetLYC(video->stat, lyc == video->ly); if (video->ly < GB_VIDEO_VERTICAL_PIXELS) { next = GB_VIDEO_MODE_2_LENGTH; video->mode = 2; @@ -246,6 +245,14 @@ void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) { if (!_statIRQAsserted(video, oldStat) && _statIRQAsserted(video, video->stat)) { video->p->memory.io[REG_IF] |= (1 << GB_IRQ_LCDSTAT); } + + // LYC stat is delayed 1 T-cycle + oldStat = video->stat; + video->stat = GBRegisterSTATSetLYC(video->stat, lyc == video->ly); + if (!_statIRQAsserted(video, oldStat) && _statIRQAsserted(video, video->stat)) { + video->p->memory.io[REG_IF] |= (1 << GB_IRQ_LCDSTAT); + } + GBUpdateIRQs(video->p); video->p->memory.io[REG_STAT] = video->stat; mTimingSchedule(timing, &video->modeEvent, (next << video->p->doubleSpeed) - cyclesLate); From f9b12a86122f4da639fbaad72c32ba7e4a97bb8f Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 14:14:21 -0800 Subject: [PATCH 09/20] GBA I/O: Fix IRQ register write checks (fixes #1335) --- src/gba/io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gba/io.c b/src/gba/io.c index 7b7c4ba3a..68c77c8d5 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -548,16 +548,16 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { break; case REG_IE: gba->memory.io[REG_IE >> 1] = value; - GBATestIRQ(gba->cpu, 1); + GBATestIRQ(gba, 1); return; case REG_IF: value = gba->memory.io[REG_IF >> 1] & ~value; gba->memory.io[REG_IF >> 1] = value; - GBATestIRQ(gba->cpu, 1); + GBATestIRQ(gba, 1); return; case REG_IME: gba->memory.io[REG_IME >> 1] = value; - GBATestIRQ(gba->cpu, 1); + GBATestIRQ(gba, 1); return; case REG_MAX: // Some bad interrupt libraries will write to this From b78825738ee6d094e892c3980c730d67db315c13 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 14:21:36 -0800 Subject: [PATCH 10/20] CHANGES: Break out emulation fixes from other fixes --- CHANGES | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index e79ec1691..7cc88f132 100644 --- a/CHANGES +++ b/CHANGES @@ -3,13 +3,14 @@ Features: - Improved logging configuration - One-Player BattleChip/Progress/Beast Link Gate support - Add Game Boy Color palettes for original Game Boy games -Bugfixes: +Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) + - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) +Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) - - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash From a3c79c92d78c5802d0608639bc4feb87d2faa1d2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 17:27:53 -0800 Subject: [PATCH 11/20] GB Video: Fix window being enabled mid-scanline (fixes #1328) --- CHANGES | 1 + include/mgba/internal/gb/renderers/software.h | 2 ++ src/gb/renderers/software.c | 20 +++++++++++++++---- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 7cc88f132..04eb39e17 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,7 @@ Emulation fixes: - GBA: Reset now reloads multiboot ROMs - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) + - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/include/mgba/internal/gb/renderers/software.h b/include/mgba/internal/gb/renderers/software.h index 3b8f7a210..fe4b1ff98 100644 --- a/include/mgba/internal/gb/renderers/software.h +++ b/include/mgba/internal/gb/renderers/software.h @@ -32,7 +32,9 @@ struct GBVideoSoftwareRenderer { uint8_t wy; uint8_t wx; uint8_t currentWy; + uint8_t currentWx; int lastY; + int lastX; bool hasWindow; GBRegisterLCDC lcdc; diff --git a/src/gb/renderers/software.c b/src/gb/renderers/software.c index c5e0d3c7a..4b1517ae0 100644 --- a/src/gb/renderers/software.c +++ b/src/gb/renderers/software.c @@ -190,7 +190,9 @@ static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum G softwareRenderer->scx = 0; softwareRenderer->wy = 0; softwareRenderer->currentWy = 0; + softwareRenderer->currentWx = 0; softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS; + softwareRenderer->lastX = 0; softwareRenderer->hasWindow = false; softwareRenderer->wx = 0; softwareRenderer->model = model; @@ -232,6 +234,9 @@ static void GBVideoSoftwareRendererUpdateWindow(struct GBVideoSoftwareRenderer* renderer->currentWy = GB_VIDEO_VERTICAL_PIXELS; } else { renderer->currentWy = renderer->lastY - renderer->wy; + if (renderer->lastY == renderer->wy && renderer->lastX > renderer->wx) { + ++renderer->currentWy; + } } } else { renderer->currentWy += renderer->lastY; @@ -489,6 +494,7 @@ static void GBVideoSoftwareRendererWriteOAM(struct GBVideoRenderer* renderer, ui static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; softwareRenderer->lastY = y; + softwareRenderer->lastX = endX; uint8_t* maps = &softwareRenderer->d.vram[GB_BASE_MAP]; if (GBRegisterLCDCIsTileMap(softwareRenderer->lcdc)) { maps += GB_SIZE_MAP; @@ -498,9 +504,10 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i } if (GBRegisterLCDCIsBgEnable(softwareRenderer->lcdc) || softwareRenderer->model >= GB_MODEL_CGB) { int wy = softwareRenderer->wy + softwareRenderer->currentWy; - if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy <= y && endX >= softwareRenderer->wx - 7) { - if (softwareRenderer->wx - 7 > 0 && !softwareRenderer->d.disableBG) { - GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, softwareRenderer->wx - 7, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); + int wx = softwareRenderer->wx + softwareRenderer->currentWx - 7; + if (GBRegisterLCDCIsWindow(softwareRenderer->lcdc) && wy <= y && wx <= endX) { + if (wx > 0 && !softwareRenderer->d.disableBG) { + GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, wx, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); } maps = &softwareRenderer->d.vram[GB_BASE_MAP]; @@ -508,7 +515,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i maps += GB_SIZE_MAP; } if (!softwareRenderer->d.disableWIN) { - GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, softwareRenderer->wx - 7, endX, 7 - softwareRenderer->wx - softwareRenderer->offsetWx, y - wy - softwareRenderer->offsetWy); + GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, wx, endX, -wx - softwareRenderer->offsetWx, y - wy - softwareRenderer->offsetWy); } } else if (!softwareRenderer->d.disableBG) { GBVideoSoftwareRendererDrawBackground(softwareRenderer, maps, startX, endX, softwareRenderer->scx - softwareRenderer->offsetScx, softwareRenderer->scy + y - softwareRenderer->offsetScy); @@ -612,6 +619,9 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i static void GBVideoSoftwareRendererFinishScanline(struct GBVideoRenderer* renderer, int y) { struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; + softwareRenderer->lastX = 0; + softwareRenderer->currentWx = 0; + if (softwareRenderer->sgbTransfer == 1) { size_t offset = 2 * ((y & 7) + (y >> 3) * GB_VIDEO_HORIZONTAL_PIXELS); if (offset >= 0x1000) { @@ -702,7 +712,9 @@ static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer) } } softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS; + softwareRenderer->lastX = 0; softwareRenderer->currentWy = 0; + softwareRenderer->currentWx = 0; softwareRenderer->hasWindow = false; } From 267074fcd975527cc068f3b1334050344257e3d2 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 17:56:33 -0800 Subject: [PATCH 12/20] GB I/O: Filter IE top bits properly (fixes #1329) --- CHANGES | 1 + src/gb/io.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 04eb39e17..6f66be9c1 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,7 @@ Emulation fixes: - GBA BIOS: Fix multiboot entry point (fixes Magic Floor) - GB Video: Delay LYC STAT check (fixes mgba.io/i/1331) - GB Video: Fix window being enabled mid-scanline (fixes mgba.io/i/1328) + - GB I/O: Filter IE top bits properly (fixes mgba.io/i/1329) Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) diff --git a/src/gb/io.c b/src/gb/io.c index 84b3a35bc..c5f138b60 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -465,7 +465,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { } break; case REG_IE: - gb->memory.ie = value; + gb->memory.ie = value & 0x1F; GBUpdateIRQs(gb); return; default: @@ -578,7 +578,7 @@ uint8_t GBIORead(struct GB* gb, unsigned address) { case REG_JOYP: return _readKeysFiltered(gb); case REG_IE: - return gb->memory.ie; + return gb->memory.ie | 0xE0; case REG_WAVE_0: case REG_WAVE_1: case REG_WAVE_2: From ce2732823985041f17107a4178d43ac3234ea1f7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 18:03:06 -0800 Subject: [PATCH 13/20] cinema: Add tests for #1328 --- cinema/gb/window/007wne-hud/baseline_0000.png | Bin 0 -> 4734 bytes cinema/gb/window/007wne-hud/baseline_0001.png | Bin 0 -> 4734 bytes cinema/gb/window/007wne-hud/baseline_0002.png | Bin 0 -> 4734 bytes cinema/gb/window/007wne-hud/baseline_0003.png | Bin 0 -> 4734 bytes cinema/gb/window/007wne-hud/test.mvl | Bin 0 -> 14295 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 cinema/gb/window/007wne-hud/baseline_0000.png create mode 100644 cinema/gb/window/007wne-hud/baseline_0001.png create mode 100644 cinema/gb/window/007wne-hud/baseline_0002.png create mode 100644 cinema/gb/window/007wne-hud/baseline_0003.png create mode 100644 cinema/gb/window/007wne-hud/test.mvl diff --git a/cinema/gb/window/007wne-hud/baseline_0000.png b/cinema/gb/window/007wne-hud/baseline_0000.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae2a2a5c9d96d240c97f421f6b8a61fabb7b54d GIT binary patch literal 4734 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/007wne-hud/baseline_0001.png b/cinema/gb/window/007wne-hud/baseline_0001.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae2a2a5c9d96d240c97f421f6b8a61fabb7b54d GIT binary patch literal 4734 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/007wne-hud/baseline_0002.png b/cinema/gb/window/007wne-hud/baseline_0002.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae2a2a5c9d96d240c97f421f6b8a61fabb7b54d GIT binary patch literal 4734 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/007wne-hud/baseline_0003.png b/cinema/gb/window/007wne-hud/baseline_0003.png new file mode 100644 index 0000000000000000000000000000000000000000..9ae2a2a5c9d96d240c97f421f6b8a61fabb7b54d GIT binary patch literal 4734 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 literal 0 HcmV?d00001 diff --git a/cinema/gb/window/007wne-hud/test.mvl b/cinema/gb/window/007wne-hud/test.mvl new file mode 100644 index 0000000000000000000000000000000000000000..d5dc5d28826cd831880a6dc48ec269004b8fdb7e GIT binary patch literal 14295 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 literal 0 HcmV?d00001 From 0421228a77fdf228551584fbcb300c6e27f2583e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 3 Mar 2019 18:07:10 -0800 Subject: [PATCH 14/20] GB I/O: Alternate fix for #1329 that doesn't break tests --- src/gb/gb.c | 2 +- src/gb/io.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gb/gb.c b/src/gb/gb.c index 038401c83..fc3c174b0 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -630,7 +630,7 @@ void GBDetectModel(struct GB* gb) { } void GBUpdateIRQs(struct GB* gb) { - int irqs = gb->memory.ie & gb->memory.io[REG_IF]; + int irqs = gb->memory.ie & gb->memory.io[REG_IF] & 0x1F; if (!irqs) { gb->cpu->irqPending = false; return; diff --git a/src/gb/io.c b/src/gb/io.c index c5f138b60..84b3a35bc 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -465,7 +465,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { } break; case REG_IE: - gb->memory.ie = value & 0x1F; + gb->memory.ie = value; GBUpdateIRQs(gb); return; default: @@ -578,7 +578,7 @@ uint8_t GBIORead(struct GB* gb, unsigned address) { case REG_JOYP: return _readKeysFiltered(gb); case REG_IE: - return gb->memory.ie | 0xE0; + return gb->memory.ie; case REG_WAVE_0: case REG_WAVE_1: case REG_WAVE_2: From f5ddeb3611248a9632fdd6ed28d0e390ac1fb6c7 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 18:24:45 -0800 Subject: [PATCH 15/20] LR35902: Fix disassembly of several CB-prefix instructions --- CHANGES | 1 + src/lr35902/decoder.c | 36 ++++++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 6f66be9c1..217ec4ddf 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,7 @@ Emulation fixes: Other fixes: - Qt: More app metadata fixes - Qt: Fix load recent from archive (fixes mgba.io/i/1325) + - LR35902: Fix disassembly of several CB-prefix instructions Misc: - GBA Savedata: EEPROM performance fixes - GBA Savedata: Automatically map 1Mbit Flash files as 1Mbit Flash diff --git a/src/lr35902/decoder.c b/src/lr35902/decoder.c index 3d3098441..76c6b9f02 100644 --- a/src/lr35902/decoder.c +++ b/src/lr35902/decoder.c @@ -314,15 +314,21 @@ DEFINE_POPPUSH_DECODER_LR35902(DE); DEFINE_POPPUSH_DECODER_LR35902(HL); DEFINE_POPPUSH_DECODER_LR35902(AF); +#define DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, OP) \ + DEFINE_DECODER_LR35902(NAME ## B, info->OP.reg = LR35902_REG_B; BODY) \ + DEFINE_DECODER_LR35902(NAME ## C, info->OP.reg = LR35902_REG_C; BODY) \ + DEFINE_DECODER_LR35902(NAME ## D, info->OP.reg = LR35902_REG_D; BODY) \ + DEFINE_DECODER_LR35902(NAME ## E, info->OP.reg = LR35902_REG_E; BODY) \ + DEFINE_DECODER_LR35902(NAME ## H, info->OP.reg = LR35902_REG_H; BODY) \ + DEFINE_DECODER_LR35902(NAME ## L, info->OP.reg = LR35902_REG_L; BODY) \ + DEFINE_DECODER_LR35902(NAME ## HL, info->OP.reg = LR35902_REG_HL; info->OP.flags = LR35902_OP_FLAG_MEMORY; BODY) \ + DEFINE_DECODER_LR35902(NAME ## A, info->OP.reg = LR35902_REG_A; BODY) + #define DEFINE_CB_2_DECODER_LR35902(NAME, BODY) \ - DEFINE_DECODER_LR35902(NAME ## B, info->op2.reg = LR35902_REG_B; BODY) \ - DEFINE_DECODER_LR35902(NAME ## C, info->op2.reg = LR35902_REG_C; BODY) \ - DEFINE_DECODER_LR35902(NAME ## D, info->op2.reg = LR35902_REG_D; BODY) \ - DEFINE_DECODER_LR35902(NAME ## E, info->op2.reg = LR35902_REG_E; BODY) \ - DEFINE_DECODER_LR35902(NAME ## H, info->op2.reg = LR35902_REG_H; BODY) \ - DEFINE_DECODER_LR35902(NAME ## L, info->op2.reg = LR35902_REG_L; BODY) \ - DEFINE_DECODER_LR35902(NAME ## HL, info->op2.reg = LR35902_REG_HL; info->op2.flags = LR35902_OP_FLAG_MEMORY; BODY) \ - DEFINE_DECODER_LR35902(NAME ## A, info->op2.reg = LR35902_REG_A; BODY) + DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op2) + +#define DEFINE_CB_1_DECODER_LR35902(NAME, BODY) \ + DEFINE_CB_OP_DECODER_LR35902(NAME, BODY, op1) #define DEFINE_CB_DECODER_LR35902(NAME, BODY) \ DEFINE_CB_2_DECODER_LR35902(NAME ## 0, info->op1.immediate = 0; BODY) \ @@ -339,17 +345,19 @@ DEFINE_CB_DECODER_LR35902(RES, info->mnemonic = LR35902_MN_RES) DEFINE_CB_DECODER_LR35902(SET, info->mnemonic = LR35902_MN_SET) #define DEFINE_CB_X_DECODER_LR35902(NAME) \ - DEFINE_CB_2_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \ - DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; info->op1.reg = LR35902_REG_A) + DEFINE_CB_1_DECODER_LR35902(NAME, info->mnemonic = LR35902_MN_ ## NAME) \ + DEFINE_DECODER_LR35902(NAME ## A_, info->mnemonic = LR35902_MN_ ## NAME; \ + info->op1.flags = LR35902_OP_FLAG_IMPLICIT; \ + info->op1.reg = LR35902_REG_A;) DEFINE_CB_X_DECODER_LR35902(RL) DEFINE_CB_X_DECODER_LR35902(RLC) DEFINE_CB_X_DECODER_LR35902(RR) DEFINE_CB_X_DECODER_LR35902(RRC) -DEFINE_CB_2_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA) -DEFINE_CB_2_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA) -DEFINE_CB_2_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL) -DEFINE_CB_2_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP) +DEFINE_CB_1_DECODER_LR35902(SLA, info->mnemonic = LR35902_MN_SLA) +DEFINE_CB_1_DECODER_LR35902(SRA, info->mnemonic = LR35902_MN_SRA) +DEFINE_CB_1_DECODER_LR35902(SRL, info->mnemonic = LR35902_MN_SRL) +DEFINE_CB_1_DECODER_LR35902(SWAP, info->mnemonic = LR35902_MN_SWAP) DEFINE_DECODER_LR35902(DI, info->mnemonic = LR35902_MN_DI) DEFINE_DECODER_LR35902(EI, info->mnemonic = LR35902_MN_EI) From c3ec7311e80127bb648418defee171178be9075b Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 18:27:13 -0800 Subject: [PATCH 16/20] Debugger: Add unary operators and memory dereferencing --- CHANGES | 1 + include/mgba/internal/debugger/parser.h | 1 + src/debugger/parser.c | 86 +++++++++++++++++++++++-- src/lr35902/debugger/cli-debugger.c | 2 +- src/lr35902/debugger/debugger.c | 2 +- 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index 217ec4ddf..962e2e6a2 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,7 @@ Features: - Improved logging configuration - One-Player BattleChip/Progress/Beast Link Gate support - Add Game Boy Color palettes for original Game Boy games + - Debugger: Add unary operators and memory dereferencing Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/include/mgba/internal/debugger/parser.h b/include/mgba/internal/debugger/parser.h index 6092c1f8c..37f194ddb 100644 --- a/include/mgba/internal/debugger/parser.h +++ b/include/mgba/internal/debugger/parser.h @@ -38,6 +38,7 @@ enum Operation { OP_NOT, OP_SHIFT_L, OP_SHIFT_R, + OP_DEREFERENCE, }; struct Token { diff --git a/src/debugger/parser.c b/src/debugger/parser.c index 41eafc6d4..adad22e21 100644 --- a/src/debugger/parser.c +++ b/src/debugger/parser.c @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include #include #include @@ -89,6 +90,29 @@ static void _lexOperator(struct LexVector* lv, char operator, enum LexState* sta break; } *state = LEX_ERROR; + } + if (*state == LEX_ROOT || *state == LEX_ERROR) { + struct Token* lvNext = LexVectorAppend(lv); + lvNext->type = TOKEN_OPERATOR_TYPE; + *state = LEX_ROOT; + switch (operator) { + case '-': + lvNext->operatorValue = OP_NEGATE; + break; + case '~': + lvNext->operatorValue = OP_FLIP; + break; + case '!': + lvNext->operatorValue = OP_NOT; + break; + case '*': + lvNext->operatorValue = OP_DEREFERENCE; + break; + default: + lvNext->type = TOKEN_ERROR_TYPE; + *state = LEX_ERROR; + break; + } return; } struct Token* lvNext = LexVectorAppend(lv); @@ -247,6 +271,12 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length, co lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_OPEN_PAREN_TYPE; break; + case '!': + case '-': + case '~': + case '*': + _lexOperator(lv, token, &state); + break; case ' ': case '\t': break; @@ -499,6 +529,7 @@ static const int _operatorPrecedence[] = { [OP_NOT] = 2, [OP_SHIFT_L] = 5, [OP_SHIFT_R] = 5, + [OP_DEREFERENCE] = 2, }; static struct ParseTree* _parseTreeCreate() { @@ -622,7 +653,7 @@ void parseFree(struct ParseTree* tree) { } } -static bool _performOperation(enum Operation operation, int32_t current, int32_t next, int32_t* value) { +static bool _performOperation(struct mDebugger* debugger, enum Operation operation, int32_t current, int32_t next, int32_t* value, int* segment) { switch (operation) { case OP_ASSIGN: current = next; @@ -683,12 +714,29 @@ static bool _performOperation(enum Operation operation, int32_t current, int32_t case OP_GE: current = current >= next; break; + case OP_NEGATE: + current = -next; + break; + case OP_FLIP: + current = ~next; + break; + case OP_NOT: + current = !next; + break; case OP_SHIFT_L: current <<= next; break; case OP_SHIFT_R: current >>= next; break; + case OP_DEREFERENCE: + if (*segment < 0) { + current = debugger->core->busRead8(debugger->core, next); + } else { + current = debugger->core->rawRead8(debugger->core, next, *segment); + } + *segment = -1; + break; default: return false; } @@ -714,13 +762,37 @@ bool mDebuggerEvaluateParseTree(struct mDebugger* debugger, struct ParseTree* tr } return mDebuggerEvaluateParseTree(debugger, tree->lhs, segment, NULL); case TOKEN_OPERATOR_TYPE: - if (!mDebuggerEvaluateParseTree(debugger, tree->lhs, &lhs, segment)) { - return false; + switch (tree->token.operatorValue) { + case OP_ASSIGN: + case OP_ADD: + case OP_SUBTRACT: + case OP_MULTIPLY: + case OP_DIVIDE: + case OP_MODULO: + case OP_AND: + case OP_OR: + case OP_XOR: + case OP_LESS: + case OP_GREATER: + case OP_EQUAL: + case OP_NOT_EQUAL: + case OP_LOGICAL_AND: + case OP_LOGICAL_OR: + case OP_LE: + case OP_GE: + case OP_SHIFT_L: + case OP_SHIFT_R: + if (!mDebuggerEvaluateParseTree(debugger, tree->lhs, &lhs, segment)) { + return false; + } + // Fall through + default: + if (!mDebuggerEvaluateParseTree(debugger, tree->rhs, &rhs, segment)) { + return false; + } + break; } - if (!mDebuggerEvaluateParseTree(debugger, tree->rhs, &rhs, segment)) { - return false; - } - return _performOperation(tree->token.operatorValue, lhs, rhs, value); + return _performOperation(debugger, tree->token.operatorValue, lhs, rhs, value, segment); case TOKEN_IDENTIFIER_TYPE: return mDebuggerLookupIdentifier(debugger, tree->token.identifierValue, value, segment); case TOKEN_ERROR_TYPE: diff --git a/src/lr35902/debugger/cli-debugger.c b/src/lr35902/debugger/cli-debugger.c index fe85bca27..4fefd77f3 100644 --- a/src/lr35902/debugger/cli-debugger.c +++ b/src/lr35902/debugger/cli-debugger.c @@ -74,7 +74,7 @@ static inline uint16_t _printLine(struct CLIDebugger* debugger, uint16_t address }; disPtr[0] = '\t'; ++disPtr; - LR35902Disassemble(&info, disPtr, sizeof(disassembly) - (disPtr - disassembly)); + LR35902Disassemble(&info, address, disPtr, sizeof(disassembly) - (disPtr - disassembly)); be->printf(be, "%s\n", disassembly); return address; } diff --git a/src/lr35902/debugger/debugger.c b/src/lr35902/debugger/debugger.c index 398131d5d..47ae68533 100644 --- a/src/lr35902/debugger/debugger.c +++ b/src/lr35902/debugger/debugger.c @@ -215,7 +215,7 @@ static void LR35902DebuggerTrace(struct mDebuggerPlatform* d, char* out, size_t* disPtr[0] = ':'; disPtr[1] = ' '; disPtr += 2; - LR35902Disassemble(&info, disPtr, sizeof(disassembly) - (disPtr - disassembly)); + LR35902Disassemble(&info, address, disPtr, sizeof(disassembly) - (disPtr - disassembly)); *length = snprintf(out, *length, "A: %02X F: %02X B: %02X C: %02X D: %02X E: %02X H: %02X L: %02X SP: %04X PC: %02X:%04X | %s", cpu->a, cpu->f.packed, cpu->b, cpu->c, From d6ac0dc6f526ac111c4e750e282050c034724b76 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 18:28:27 -0800 Subject: [PATCH 17/20] LR35902: Support PC-relative opcode decoding --- CHANGES | 1 + include/mgba/internal/lr35902/decoder.h | 3 ++- src/lr35902/decoder.c | 16 +++++++++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 962e2e6a2..c5c787633 100644 --- a/CHANGES +++ b/CHANGES @@ -22,6 +22,7 @@ Misc: - Qt: Don't unload ROM immediately if it crashes - Debugger: Add breakpoint and watchpoint listing - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) + - LR35902: Support PC-relative opcode decoding 0.7.1: (2019-02-24) Bugfixes: diff --git a/include/mgba/internal/lr35902/decoder.h b/include/mgba/internal/lr35902/decoder.h index 101a104c3..ba9ceec36 100644 --- a/include/mgba/internal/lr35902/decoder.h +++ b/include/mgba/internal/lr35902/decoder.h @@ -86,6 +86,7 @@ enum { LR35902_OP_FLAG_MEMORY = 2, LR35902_OP_FLAG_INCREMENT = 4, LR35902_OP_FLAG_DECREMENT = 8, + LR35902_OP_FLAG_RELATIVE = 16, }; struct LR35902Operand { @@ -104,7 +105,7 @@ struct LR35902InstructionInfo { }; size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info); -int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen); +int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen); CXX_GUARD_END diff --git a/src/lr35902/decoder.c b/src/lr35902/decoder.c index 76c6b9f02..089b52c69 100644 --- a/src/lr35902/decoder.c +++ b/src/lr35902/decoder.c @@ -199,6 +199,7 @@ DEFINE_DECODER_LR35902(ADDSP, info->mnemonic = LR35902_MN_ADD; \ DEFINE_DECODER_LR35902(JR ## CONDITION_NAME, \ info->mnemonic = LR35902_MN_JR; \ info->condition = CONDITION; \ + info->op1.flags = LR35902_OP_FLAG_RELATIVE; \ return 1;) #define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \ @@ -497,7 +498,7 @@ static const char* _lr35902MnemonicStrings[] = { }; -static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) { +static int _decodeOperand(struct LR35902Operand op, uint16_t pc, char* buffer, int blen) { int total = 0; if (op.flags & LR35902_OP_FLAG_IMPLICIT) { return 0; @@ -511,7 +512,12 @@ static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) { int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]); ADVANCE(written); } else { - int written = snprintf(buffer, blen - 1, "$%02X", op.immediate); + int written; + if (op.flags & LR35902_OP_FLAG_RELATIVE) { + written = snprintf(buffer, blen - 1, "$%04X", pc + (int8_t) op.immediate); + } else { + written = snprintf(buffer, blen - 1, "$%02X", op.immediate); + } ADVANCE(written); if (op.reg) { strncpy(buffer, "+", blen - 1); @@ -533,7 +539,7 @@ static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) { return total; } -int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen) { +int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen) { const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic]; int written; int total = 0; @@ -553,7 +559,7 @@ int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int bl } if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) { - written = _decodeOperand(info->op1, buffer, blen); + written = _decodeOperand(info->op1, pc, buffer, blen); ADVANCE(written); } @@ -562,7 +568,7 @@ int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int bl strncpy(buffer, ", ", blen - 1); ADVANCE(2); } - written = _decodeOperand(info->op2, buffer, blen); + written = _decodeOperand(info->op2, pc, buffer, blen); ADVANCE(written); } From b3687bfbe9611b0534da93ebd1075ae8d9b129cd Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 18:30:36 -0800 Subject: [PATCH 18/20] GB Debugger: Expose platform info in CLI --- CHANGES | 1 + CMakeLists.txt | 1 + include/mgba/internal/gb/debugger/debugger.h | 20 ++++++++ .../mgba/internal/lr35902/debugger/debugger.h | 3 ++ src/gb/core.c | 22 +-------- src/gb/debugger/debugger.c | 46 +++++++++++++++++++ src/lr35902/debugger/cli-debugger.c | 5 +- src/lr35902/debugger/debugger.c | 31 +++++++------ 8 files changed, 93 insertions(+), 36 deletions(-) create mode 100644 include/mgba/internal/gb/debugger/debugger.h create mode 100644 src/gb/debugger/debugger.c diff --git a/CHANGES b/CHANGES index c5c787633..e55b9ad74 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,7 @@ Features: - One-Player BattleChip/Progress/Beast Link Gate support - Add Game Boy Color palettes for original Game Boy games - Debugger: Add unary operators and memory dereferencing + - GB: Expose platform information to CLI debugger Emulation fixes: - GBA: All IRQs have 7 cycle delay (fixes mgba.io/i/539, mgba.io/i/1208) - GBA: Reset now reloads multiboot ROMs diff --git a/CMakeLists.txt b/CMakeLists.txt index fa01e3a50..a3dd284a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -747,6 +747,7 @@ if(M_CORE_GB) ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/debugger.c ${CMAKE_CURRENT_SOURCE_DIR}/src/lr35902/debugger/memory-debugger.c ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/cli.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/debugger.c ${CMAKE_CURRENT_SOURCE_DIR}/src/gb/debugger/symbols.c) list(APPEND TEST_SRC ${LR35902_TEST_SRC} diff --git a/include/mgba/internal/gb/debugger/debugger.h b/include/mgba/internal/gb/debugger/debugger.h new file mode 100644 index 000000000..2eeee8ed1 --- /dev/null +++ b/include/mgba/internal/gb/debugger/debugger.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2013-2019 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef GB_DEBUGGER_H +#define GB_DEBUGGER_H + +#include + +CXX_GUARD_START + +struct GB; +struct mDebuggerPlatform; + +struct mDebuggerPlatform* GBDebuggerCreate(struct GB* gb); + +CXX_GUARD_END + +#endif \ No newline at end of file diff --git a/include/mgba/internal/lr35902/debugger/debugger.h b/include/mgba/internal/lr35902/debugger/debugger.h index 1114c5c1a..6e62b6ce9 100644 --- a/include/mgba/internal/lr35902/debugger/debugger.h +++ b/include/mgba/internal/lr35902/debugger/debugger.h @@ -20,6 +20,7 @@ struct LR35902Segment { const char* name; }; +struct CLIDebuggerSystem; struct LR35902Debugger { struct mDebuggerPlatform d; struct LR35902Core* cpu; @@ -31,6 +32,8 @@ struct LR35902Debugger { ssize_t nextId; const struct LR35902Segment* segments; + + void (*printStatus)(struct CLIDebuggerSystem*); }; struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void); diff --git a/src/gb/core.c b/src/gb/core.c index 68b613108..1671a1142 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -37,20 +38,6 @@ static const struct mCoreChannelInfo _GBAudioChannels[] = { { 3, "ch4", "Channel 4", "Noise" }, }; -static const struct LR35902Segment _GBSegments[] = { - { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, - { .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 }, - { 0 } -}; - -static const struct LR35902Segment _GBCSegments[] = { - { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, - { .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 }, - { .name = "WRAM", .start = GB_BASE_WORKING_RAM_BANK1, .end = 0xE000 }, - { .name = "VRAM", .start = GB_BASE_VRAM, .end = GB_BASE_EXTERNAL_RAM }, - { 0 } -}; - static const struct mCoreMemoryBlock _GBMemoryBlocks[] = { { -1, "mem", "All", "All", 0, 0x10000, 0x10000, mCORE_MEMORY_VIRTUAL }, { GB_REGION_CART_BANK0, "cart0", "ROM Bank", "Game Pak (32kiB)", GB_BASE_CART_BANK0, GB_SIZE_CART_BANK0 * 2, 0x800000, mCORE_MEMORY_READ | mCORE_MEMORY_MAPPED, 511 }, @@ -692,12 +679,7 @@ static struct mDebuggerPlatform* _GBCoreDebuggerPlatform(struct mCore* core) { struct GBCore* gbcore = (struct GBCore*) core; struct GB* gb = core->board; if (!gbcore->debuggerPlatform) { - struct LR35902Debugger* platform = (struct LR35902Debugger*) LR35902DebuggerPlatformCreate(); - if (gb->model >= GB_MODEL_CGB) { - platform->segments = _GBCSegments; - } else { - platform->segments = _GBSegments; - } + struct LR35902Debugger* platform = (struct LR35902Debugger*) GBDebuggerCreate(gb); gbcore->debuggerPlatform = &platform->d; } return gbcore->debuggerPlatform; diff --git a/src/gb/debugger/debugger.c b/src/gb/debugger/debugger.c new file mode 100644 index 000000000..41444806b --- /dev/null +++ b/src/gb/debugger/debugger.c @@ -0,0 +1,46 @@ +/* Copyright (c) 2013-2019 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + #include + + #include + #include + #include + #include + #include + #include + +static const struct LR35902Segment _GBSegments[] = { + { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, + { .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 }, + { 0 } +}; + +static const struct LR35902Segment _GBCSegments[] = { + { .name = "ROM", .start = GB_BASE_CART_BANK1, .end = GB_BASE_VRAM }, + { .name = "RAM", .start = GB_BASE_EXTERNAL_RAM, .end = GB_BASE_WORKING_RAM_BANK0 }, + { .name = "WRAM", .start = GB_BASE_WORKING_RAM_BANK1, .end = 0xE000 }, + { .name = "VRAM", .start = GB_BASE_VRAM, .end = GB_BASE_EXTERNAL_RAM }, + { 0 } +}; + +static void _printStatus(struct CLIDebuggerSystem* debugger) { + struct CLIDebuggerBackend* be = debugger->p->backend; + struct GB* gb = debugger->p->d.core->board; + be->printf(be, "IE: %02X IF: %02X IME: %i\n", gb->memory.ie, gb->memory.io[REG_IF], gb->memory.ime); + be->printf(be, "LCDC: %02X STAT: %02X LY: %02X\n", gb->memory.io[REG_LCDC], gb->memory.io[REG_STAT] | 0x80, gb->memory.io[REG_LY]); + be->printf(be, "Next video mode: %i\n", mTimingUntil(&gb->timing, &gb->video.modeEvent) / 4); +} + +struct mDebuggerPlatform* GBDebuggerCreate(struct GB* gb) { + struct LR35902Debugger* platform = (struct LR35902Debugger*) LR35902DebuggerPlatformCreate(); + if (gb->model >= GB_MODEL_CGB) { + platform->segments = _GBCSegments; + } else { + platform->segments = _GBSegments; + } + platform->printStatus = _printStatus; + return &platform->d; +} \ No newline at end of file diff --git a/src/lr35902/debugger/cli-debugger.c b/src/lr35902/debugger/cli-debugger.c index 4fefd77f3..300a3dd8f 100644 --- a/src/lr35902/debugger/cli-debugger.c +++ b/src/lr35902/debugger/cli-debugger.c @@ -87,6 +87,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) { be->printf(be, "D: %02X E: %02X (DE: %04X)\n", cpu->d, cpu->e, cpu->de); be->printf(be, "H: %02X L: %02X (HL: %04X)\n", cpu->h, cpu->l, cpu->hl); be->printf(be, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp); + _printFlags(be, cpu->f); struct LR35902Debugger* platDebugger = (struct LR35902Debugger*) debugger->p->d.platform; size_t i; @@ -96,7 +97,9 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) { if (i) { be->printf(be, "\n"); } - _printFlags(be, cpu->f); + if (platDebugger->printStatus) { + platDebugger->printStatus(debugger); + } _printLine(debugger->p, cpu->pc, cpu->memory.currentSegment(cpu, cpu->pc)); } diff --git a/src/lr35902/debugger/debugger.c b/src/lr35902/debugger/debugger.c index 47ae68533..fb7e4a247 100644 --- a/src/lr35902/debugger/debugger.c +++ b/src/lr35902/debugger/debugger.c @@ -75,21 +75,22 @@ static bool LR35902DebuggerGetRegister(struct mDebuggerPlatform*, const char* na static bool LR35902DebuggerSetRegister(struct mDebuggerPlatform*, const char* name, int32_t value); struct mDebuggerPlatform* LR35902DebuggerPlatformCreate(void) { - struct mDebuggerPlatform* platform = (struct mDebuggerPlatform*) malloc(sizeof(struct LR35902Debugger)); - platform->entered = LR35902DebuggerEnter; - platform->init = LR35902DebuggerInit; - platform->deinit = LR35902DebuggerDeinit; - platform->setBreakpoint = LR35902DebuggerSetBreakpoint; - platform->listBreakpoints = LR35902DebuggerListBreakpoints; - platform->clearBreakpoint = LR35902DebuggerClearBreakpoint; - platform->setWatchpoint = LR35902DebuggerSetWatchpoint; - platform->listWatchpoints = LR35902DebuggerListWatchpoints; - platform->checkBreakpoints = LR35902DebuggerCheckBreakpoints; - platform->hasBreakpoints = LR35902DebuggerHasBreakpoints; - platform->trace = LR35902DebuggerTrace; - platform->getRegister = LR35902DebuggerGetRegister; - platform->setRegister = LR35902DebuggerSetRegister; - return platform; + struct LR35902Debugger* platform = malloc(sizeof(struct LR35902Debugger)); + platform->d.entered = LR35902DebuggerEnter; + platform->d.init = LR35902DebuggerInit; + platform->d.deinit = LR35902DebuggerDeinit; + platform->d.setBreakpoint = LR35902DebuggerSetBreakpoint; + platform->d.listBreakpoints = LR35902DebuggerListBreakpoints; + platform->d.clearBreakpoint = LR35902DebuggerClearBreakpoint; + platform->d.setWatchpoint = LR35902DebuggerSetWatchpoint; + platform->d.listWatchpoints = LR35902DebuggerListWatchpoints; + platform->d.checkBreakpoints = LR35902DebuggerCheckBreakpoints; + platform->d.hasBreakpoints = LR35902DebuggerHasBreakpoints; + platform->d.trace = LR35902DebuggerTrace; + platform->d.getRegister = LR35902DebuggerGetRegister; + platform->d.setRegister = LR35902DebuggerSetRegister; + platform->printStatus = NULL; + return &platform->d; } void LR35902DebuggerInit(void* cpu, struct mDebuggerPlatform* platform) { From 7b59e620f13acfe8498b85bce67340a207d0b610 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 4 Mar 2019 19:16:43 -0800 Subject: [PATCH 19/20] Debugger: Clean up token lexing --- src/debugger/parser.c | 52 ++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/debugger/parser.c b/src/debugger/parser.c index adad22e21..9d8db0262 100644 --- a/src/debugger/parser.c +++ b/src/debugger/parser.c @@ -92,73 +92,75 @@ static void _lexOperator(struct LexVector* lv, char operator, enum LexState* sta *state = LEX_ERROR; } if (*state == LEX_ROOT || *state == LEX_ERROR) { - struct Token* lvNext = LexVectorAppend(lv); - lvNext->type = TOKEN_OPERATOR_TYPE; + struct Token lvNext; + lvNext.type = TOKEN_OPERATOR_TYPE; *state = LEX_ROOT; switch (operator) { case '-': - lvNext->operatorValue = OP_NEGATE; + lvNext.operatorValue = OP_NEGATE; break; case '~': - lvNext->operatorValue = OP_FLIP; + lvNext.operatorValue = OP_FLIP; break; case '!': - lvNext->operatorValue = OP_NOT; + lvNext.operatorValue = OP_NOT; break; case '*': - lvNext->operatorValue = OP_DEREFERENCE; + lvNext.operatorValue = OP_DEREFERENCE; break; default: - lvNext->type = TOKEN_ERROR_TYPE; + lvNext.type = TOKEN_ERROR_TYPE; *state = LEX_ERROR; - break; + return; } + *LexVectorAppend(lv) = lvNext; return; } - struct Token* lvNext = LexVectorAppend(lv); - lvNext->type = TOKEN_OPERATOR_TYPE; - *state = LEX_EXPECT_OPERATOR2; + struct Token lvNext; + lvNext.type = TOKEN_OPERATOR_TYPE; switch (operator) { case '=': - lvNext->operatorValue = OP_ASSIGN; + lvNext.operatorValue = OP_ASSIGN; break; case '+': - lvNext->operatorValue = OP_ADD; + lvNext.operatorValue = OP_ADD; break; case '-': - lvNext->operatorValue = OP_SUBTRACT; + lvNext.operatorValue = OP_SUBTRACT; break; case '*': - lvNext->operatorValue = OP_MULTIPLY; + lvNext.operatorValue = OP_MULTIPLY; break; case '/': - lvNext->operatorValue = OP_DIVIDE; + lvNext.operatorValue = OP_DIVIDE; break; case '%': - lvNext->operatorValue = OP_MODULO; + lvNext.operatorValue = OP_MODULO; break; case '&': - lvNext->operatorValue = OP_AND; + lvNext.operatorValue = OP_AND; break; case '|': - lvNext->operatorValue = OP_OR; + lvNext.operatorValue = OP_OR; break; case '^': - lvNext->operatorValue = OP_XOR; + lvNext.operatorValue = OP_XOR; break; case '<': - lvNext->operatorValue = OP_LESS; + lvNext.operatorValue = OP_LESS; break; case '>': - lvNext->operatorValue = OP_GREATER; + lvNext.operatorValue = OP_GREATER; break; case '!': - lvNext->operatorValue = OP_NOT; + lvNext.operatorValue = OP_NOT; break; default: - lvNext->type = TOKEN_ERROR_TYPE; - break; + *state = LEX_ERROR; + return; } + *state = LEX_EXPECT_OPERATOR2; + *LexVectorAppend(lv) = lvNext; } static void _lexValue(struct LexVector* lv, char token, uint32_t next, enum LexState* state) { From 03aed12d2889544f9e88ef8da32c6037b9375362 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 5 Mar 2019 17:34:02 -0800 Subject: [PATCH 20/20] Qt: Improve camera initialization --- CHANGES | 1 + src/platform/qt/InputController.cpp | 28 ++++++++++++++++++++-------- src/platform/qt/InputController.h | 6 ++++-- src/platform/qt/VideoDumper.cpp | 18 +++++++++++------- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/CHANGES b/CHANGES index e55b9ad74..e644bca84 100644 --- a/CHANGES +++ b/CHANGES @@ -24,6 +24,7 @@ Misc: - Debugger: Add breakpoint and watchpoint listing - Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323) - LR35902: Support PC-relative opcode decoding + - Qt: Improve camera initialization 0.7.1: (2019-02-24) Bugfixes: diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index ce73a5255..8869dac82 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -725,12 +725,23 @@ void InputController::setupCam() { #ifdef BUILD_QT_MULTIMEDIA if (!m_camera) { m_camera = std::make_unique(); + connect(m_camera.get(), &QCamera::statusChanged, this, &InputController::prepareCamSettings); } - QVideoFrame::PixelFormat format(QVideoFrame::Format_RGB32); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) + m_camera->setCaptureMode(QCamera::CaptureVideo); + m_camera->setViewfinder(&m_videoDumper); m_camera->load(); +#endif +} + +#ifdef BUILD_QT_MULTIMEDIA +void InputController::prepareCamSettings(QCamera::Status status) { + if (status != QCamera::LoadedStatus || m_camera->state() == QCamera::ActiveState) { + return; + } +#if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) + QVideoFrame::PixelFormat format(QVideoFrame::Format_RGB32); QCameraViewfinderSettings settings; - QSize size(1920, 1080); + QSize size(1280, 720); auto cameraRes = m_camera->supportedViewfinderResolutions(settings); for (auto& cameraSize : cameraRes) { if (cameraSize.width() < m_image.w || cameraSize.height() < m_image.h) { @@ -741,10 +752,11 @@ void InputController::setupCam() { } } settings.setResolution(size); + auto cameraFormats = m_camera->supportedViewfinderPixelFormats(settings); auto goodFormats = m_videoDumper.supportedPixelFormats(); bool goodFormatFound = false; - for (auto& goodFormat : goodFormats) { + for (const auto& goodFormat : goodFormats) { if (cameraFormats.contains(goodFormat)) { settings.setPixelFormat(goodFormat); format = goodFormat; @@ -754,20 +766,20 @@ void InputController::setupCam() { } if (!goodFormatFound) { LOG(QT, WARN) << "Could not find a valid camera format!"; + for (const auto& format : cameraFormats) { + LOG(QT, WARN) << "Camera supported format: " << QString::number(format); + } } m_camera->setViewfinderSettings(settings); #endif - m_camera->setCaptureMode(QCamera::CaptureVideo); - m_camera->setViewfinder(&m_videoDumper); m_camera->start(); -#endif } +#endif void InputController::teardownCam() { #ifdef BUILD_QT_MULTIMEDIA if (m_camera) { m_camera->stop(); - m_camera.reset(); } #endif } diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index 0fb6b16e0..d15bd0e22 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -27,13 +27,12 @@ #ifdef BUILD_QT_MULTIMEDIA #include "VideoDumper.h" +#include #endif struct mRotationSource; struct mRumble; -class QCamera; - namespace QGBA { class ConfigController; @@ -124,6 +123,9 @@ public slots: void setCamImage(const QImage& image); private slots: +#ifdef BUILD_QT_MULTIMEDIA + void prepareCamSettings(QCamera::Status); +#endif void setupCam(); void teardownCam(); diff --git a/src/platform/qt/VideoDumper.cpp b/src/platform/qt/VideoDumper.cpp index c5ed93eb2..c5df8d208 100644 --- a/src/platform/qt/VideoDumper.cpp +++ b/src/platform/qt/VideoDumper.cpp @@ -23,14 +23,18 @@ bool VideoDumper::present(const QVideoFrame& frame) { QImage::Format format = QVideoFrame::imageFormatFromPixelFormat(vFormat); bool swap = false; if (format == QImage::Format_Invalid) { - vFormat = static_cast(vFormat - QVideoFrame::Format_BGRA32 + QVideoFrame::Format_ARGB32); - format = QVideoFrame::imageFormatFromPixelFormat(vFormat); - if (format == QImage::Format_ARGB32) { - format = QImage::Format_RGBA8888; - } else if (format == QImage::Format_ARGB32_Premultiplied) { - format = QImage::Format_RGBA8888_Premultiplied; + if (vFormat < QVideoFrame::Format_BGRA5658_Premultiplied) { + vFormat = static_cast(vFormat - QVideoFrame::Format_BGRA32 + QVideoFrame::Format_ARGB32); + format = QVideoFrame::imageFormatFromPixelFormat(vFormat); + if (format == QImage::Format_ARGB32) { + format = QImage::Format_RGBA8888; + } else if (format == QImage::Format_ARGB32_Premultiplied) { + format = QImage::Format_RGBA8888_Premultiplied; + } + swap = true; + } else { + return false; } - swap = true; } uchar* bits = mappedFrame.bits(); QImage image(bits, mappedFrame.width(), mappedFrame.height(), mappedFrame.bytesPerLine(), format);