From e224b455761b32263deeb36821f8091fadc63399 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Mon, 6 Dec 2021 03:27:35 -0800 Subject: [PATCH] GBA: Correct key IRQ edge behavior --- src/gba/core.c | 1 + src/gba/gba.c | 25 ++++++++++++------------- src/gba/io.c | 3 +++ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/gba/core.c b/src/gba/core.c index f186d130a..1d0292f4a 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -709,6 +709,7 @@ static void _GBACoreAddKeys(struct mCore* core, uint32_t keys) { static void _GBACoreClearKeys(struct mCore* core, uint32_t keys) { struct GBA* gba = core->board; gba->keysActive &= ~keys; + GBATestKeypadIRQ(gba); } static int32_t _GBACoreFrameCounter(const struct mCore* core) { diff --git a/src/gba/gba.c b/src/gba/gba.c index 6df5086a1..16d02fd2c 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -91,7 +91,7 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) { GBAHardwareInit(&gba->memory.hw, NULL); gba->keysActive = 0; - gba->keysLast = 0; + gba->keysLast = 0x400; gba->rotationSource = 0; gba->luminanceSource = 0; gba->rtcSource = 0; @@ -878,27 +878,26 @@ void GBAFrameEnded(struct GBA* gba) { } void GBATestKeypadIRQ(struct GBA* gba) { - if (gba->keysActive == gba->keysLast) { - return; - } + uint16_t keysLast = gba->keysLast; + uint16_t keysActive = gba->keysActive; + uint16_t keycnt = gba->memory.io[REG_KEYCNT >> 1]; if (!(keycnt & 0x4000)) { return; } + gba->keysLast = keysActive; int isAnd = keycnt & 0x8000; keycnt &= 0x3FF; - uint16_t keyInput = gba->keysActive & keycnt; - uint16_t lastInput = gba->keysLast & keycnt; - gba->keysLast = gba->keysActive; - if (keyInput == lastInput) { - return; - } - - if (isAnd && keycnt == keyInput) { + if (isAnd && keycnt == (keysActive & keycnt)) { + if (keysLast == keysActive) { + return; + } GBARaiseIRQ(gba, IRQ_KEYPAD, 0); - } else if (!isAnd && keyInput) { + } else if (!isAnd && (keysActive & keycnt)) { GBARaiseIRQ(gba, IRQ_KEYPAD, 0); + } else { + gba->keysLast = 0x400; } } diff --git a/src/gba/io.c b/src/gba/io.c index 5c90f946a..8c6bbb5ad 100644 --- a/src/gba/io.c +++ b/src/gba/io.c @@ -547,6 +547,9 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) { // Interrupts and misc case REG_KEYCNT: value &= 0xC3FF; + if (gba->keysLast < 0x400) { + gba->keysLast &= gba->memory.io[address >> 1] | ~value; + } gba->memory.io[address >> 1] = value; GBATestKeypadIRQ(gba); return;