From f1a9ebec8a34295ebeb0a4c2ba2d285009a868ed Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sat, 23 Jun 2018 16:34:35 -0700 Subject: [PATCH] GB I/O: Fix JOYP IRQs --- src/gb/io.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/gb/io.c b/src/gb/io.c index 62f8e5b32..14e3b3621 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -104,6 +104,8 @@ static const uint8_t _registerMask[] = { [REG_IE] = 0xE0, }; +static uint8_t _readKeys(struct GB* gb); + static void _writeSGBBits(struct GB* gb, int bits) { if (!bits) { gb->sgbBit = -1; @@ -394,10 +396,12 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) { } break; case REG_JOYP: + gb->memory.io[REG_JOYP] = value | 0x0F; + _readKeys(gb); if (gb->model == GB_MODEL_SGB) { _writeSGBBits(gb, (value >> 4) & 3); } - break; + return; case REG_TIMA: if (value && mTimingUntil(&gb->timing, &gb->timer.irq) > 1) { mTimingDeschedule(&gb->timing, &gb->timer.irq); @@ -522,7 +526,8 @@ static uint8_t _readKeys(struct GB* gb) { if (gb->sgbCurrentController != 0) { keys = 0; } - switch (gb->memory.io[REG_JOYP] & 0x30) { + uint8_t joyp = gb->memory.io[REG_JOYP]; + switch (joyp & 0x30) { case 0x30: keys = gb->sgbCurrentController; break; @@ -535,7 +540,12 @@ static uint8_t _readKeys(struct GB* gb) { keys |= keys >> 4; break; } - return (0xC0 | (gb->memory.io[REG_JOYP] | 0xF)) ^ (keys & 0xF); + gb->memory.io[REG_JOYP] = (0xCF | joyp) ^ (keys & 0xF); + if (joyp & ~gb->memory.io[REG_JOYP] & 0xF) { + gb->memory.io[REG_IF] |= (1 << GB_IRQ_KEYPAD); + GBUpdateIRQs(gb); + } + return gb->memory.io[REG_JOYP]; } uint8_t GBIORead(struct GB* gb, unsigned address) { @@ -639,10 +649,7 @@ uint8_t GBIORead(struct GB* gb, unsigned address) { } void GBTestKeypadIRQ(struct GB* gb) { - if (_readKeys(gb)) { - gb->memory.io[REG_IF] |= (1 << GB_IRQ_KEYPAD); - GBUpdateIRQs(gb); - } + _readKeys(gb); } struct GBSerializedState;