diff --git a/include/mgba/internal/ds/io.h b/include/mgba/internal/ds/io.h index acffb94c6..a6c8e2f10 100644 --- a/include/mgba/internal/ds/io.h +++ b/include/mgba/internal/ds/io.h @@ -61,6 +61,10 @@ enum DSIORegisters { DS_REG_TM3CNT_LO = 0x10C, DS_REG_TM3CNT_HI = 0x10E, + // Keypad + DS_REG_KEYINPUT = 0x130, + DS_REG_KEYCNT = 0x132, + // IPC DS_REG_IPCSYNC = 0x180, DS_REG_IPCFIFOCNT = 0x184, @@ -79,8 +83,6 @@ enum DSIORegisters { enum DS7IORegisters { // Keypad - DS7_REG_KEYINPUT = 0x130, - DS7_REG_KEYCNT = 0x132, DS7_REG_EXTKEYIN = 0x136, DS7_REG_RTC = 0x138, @@ -208,10 +210,6 @@ enum DS9IORegisters { DS9_REG_B_BLDY = 0x1054, DS9_REG_B_MASTER_BRIGHT = 0x106C, - // Keypad - DS9_REG_KEYINPUT = 0x130, - DS9_REG_KEYCNT = 0x132, - // Game card DS9_REG_AUXSPICNT = 0x1A0, DS9_REG_AUXSPIDATA = 0x1A2, diff --git a/src/ds/io.c b/src/ds/io.c index 4eb8c206d..8b9d895a7 100644 --- a/src/ds/io.c +++ b/src/ds/io.c @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include #include #include @@ -97,6 +98,28 @@ static uint32_t DSIOWrite(struct DSCommon* dscore, uint32_t address, uint16_t va return value | 0x10000; } +static uint16_t DSIOReadKeyInput(struct DS* ds) { + uint16_t input = 0x3FF; + if (ds->keyCallback) { + input = ds->keyCallback->readKeys(ds->keyCallback); + } else if (ds->keySource) { + input = *ds->keySource; + } + // TODO: Put back + /*if (!dscore->p->allowOpposingDirections) { + unsigned rl = input & 0x030; + unsigned ud = input & 0x0C0; + input &= 0x30F; + if (rl != 0x030) { + input |= rl; + } + if (ud != 0x0C0) { + input |= ud; + } + }*/ + return 0x3FF ^ input; +} + static void DSIOUpdateTimer(struct DSCommon* dscore, uint32_t address) { switch (address) { case DS_REG_TM0CNT_LO: @@ -218,6 +241,8 @@ uint16_t DS7IORead(struct DS* ds, uint32_t address) { case DS_REG_TM3CNT_LO: DSIOUpdateTimer(&ds->ds7, address); break; + case DS_REG_KEYINPUT: + return DSIOReadKeyInput(ds); case DS_REG_DMA0FILL_LO: case DS_REG_DMA0FILL_HI: case DS_REG_DMA1FILL_LO: @@ -366,6 +391,8 @@ uint16_t DS9IORead(struct DS* ds, uint32_t address) { case DS_REG_TM3CNT_LO: DSIOUpdateTimer(&ds->ds9, address); break; + case DS_REG_KEYINPUT: + return DSIOReadKeyInput(ds); case DS_REG_DMA0FILL_LO: case DS_REG_DMA0FILL_HI: case DS_REG_DMA1FILL_LO: