From e344e2efa5fb7766e12cd72317b677da9c39936b Mon Sep 17 00:00:00 2001
From: Vicki Pfau <vi@endrift.com>
Date: Sun, 14 Jan 2018 21:03:10 -0800
Subject: [PATCH] GBA I/O: Fix writing to DISPCNT CGB flag (fixes #902)

---
 CHANGES                            | 1 +
 src/gba/extra/proxy.c              | 7 ++++++-
 src/gba/renderers/video-software.c | 1 +
 src/gba/video.c                    | 3 +++
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/CHANGES b/CHANGES
index 6217fa584..67315169e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -16,6 +16,7 @@ Bugfixes:
  - GB MBC: Fix MBC2 saves (fixes mgba.io/i/954)
  - GBA Memory: Fix copy-on-write memory leak
  - Core: Fix ROM patches not being unloaded when disabled (fixes mgba.io/i/962)
+ - GBA I/O: Fix writing to DISPCNT CGB flag (fixes mgba.io/i/902)
 Misc:
  - GBA: Improve multiboot image detection
  - GB MBC: Remove erroneous bank 0 wrapping
diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c
index e75da94c4..578c5fc21 100644
--- a/src/gba/extra/proxy.c
+++ b/src/gba/extra/proxy.c
@@ -171,11 +171,16 @@ static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address) {
 uint16_t GBAVideoProxyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
 	struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
 	switch (address) {
+	case REG_DISPCNT:
+		value &= 0xFFF7;
+		break;
 	case REG_BG0CNT:
 	case REG_BG1CNT:
+		value &= 0xDFFF;
+		break;
 	case REG_BG2CNT:
 	case REG_BG3CNT:
-		value &= 0xFFCF;
+		value &= 0xFFFF;
 		break;
 	case REG_BG0HOFS:
 	case REG_BG0VOFS:
diff --git a/src/gba/renderers/video-software.c b/src/gba/renderers/video-software.c
index 1b0017d30..43e5b1415 100644
--- a/src/gba/renderers/video-software.c
+++ b/src/gba/renderers/video-software.c
@@ -147,6 +147,7 @@ static uint16_t GBAVideoSoftwareRendererWriteVideoRegister(struct GBAVideoRender
 	struct GBAVideoSoftwareRenderer* softwareRenderer = (struct GBAVideoSoftwareRenderer*) renderer;
 	switch (address) {
 	case REG_DISPCNT:
+		value &= 0xFFF7;
 		softwareRenderer->dispcnt = value;
 		GBAVideoSoftwareRendererUpdateDISPCNT(softwareRenderer);
 		break;
diff --git a/src/gba/video.c b/src/gba/video.c
index 87af353d1..492df5067 100644
--- a/src/gba/video.c
+++ b/src/gba/video.c
@@ -216,6 +216,9 @@ static void GBAVideoDummyRendererDeinit(struct GBAVideoRenderer* renderer) {
 static uint16_t GBAVideoDummyRendererWriteVideoRegister(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
 	UNUSED(renderer);
 	switch (address) {
+	case REG_DISPCNT:
+		value &= 0xFFF7;
+		break;
 	case REG_BG0CNT:
 	case REG_BG1CNT:
 		value &= 0xDFFF;