all repos — mgba @ 3679e1e8d6049a150b7f55a71808df7b2aba4bd7

mGBA Game Boy Advance Emulator

DS IPC: Implement IPC read
Vicki Pfau vi@endrift.com
Mon, 30 Jan 2017 15:02:19 -0800
commit

3679e1e8d6049a150b7f55a71808df7b2aba4bd7

parent

f7ed6ec99f2054dc9dbd3650da33f56d7998c45c

4 files changed, 44 insertions(+), 2 deletions(-)

jump to
M include/mgba/internal/ds/io.hinclude/mgba/internal/ds/io.h

@@ -282,12 +282,14 @@ void DS7IOWrite(struct DS* ds, uint32_t address, uint16_t value);

void DS7IOWrite8(struct DS* ds, uint32_t address, uint8_t value); void DS7IOWrite32(struct DS* ds, uint32_t address, uint32_t value); uint16_t DS7IORead(struct DS* ds, uint32_t address); +uint32_t DS7IORead32(struct DS* ds, uint32_t address); void DS9IOInit(struct DS* ds); void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value); void DS9IOWrite8(struct DS* ds, uint32_t address, uint8_t value); void DS9IOWrite32(struct DS* ds, uint32_t address, uint32_t value); uint16_t DS9IORead(struct DS* ds, uint32_t address); +uint32_t DS9IORead32(struct DS* ds, uint32_t address); CXX_GUARD_END
M src/ds/io.csrc/ds/io.c

@@ -207,6 +207,7 @@ case DS_REG_TM1CNT_HI:

case DS_REG_TM2CNT_HI: case DS_REG_TM3CNT_HI: case DS_REG_IPCSYNC: + case DS_REG_IPCFIFOCNT: case DS_REG_IME: case DS_REG_IE_LO: case DS_REG_IE_HI:

@@ -221,6 +222,15 @@ if (address < DS7_REG_MAX) {

return ds->memory.io7[address >> 1]; } return 0; +} + +uint32_t DS7IORead32(struct DS* ds, uint32_t address) { + switch (address) { + case DS_REG_IPCFIFORECV_LO: + return DSIPCReadFIFO(&ds->ds7); + default: + return DS7IORead(ds, address & 0x00FFFFFC) | (DS7IORead(ds, (address & 0x00FFFFFC) | 2) << 16); + } } void DS9IOInit(struct DS* ds) {

@@ -328,6 +338,7 @@ case DS_REG_TM1CNT_HI:

case DS_REG_TM2CNT_HI: case DS_REG_TM3CNT_HI: case DS_REG_IPCSYNC: + case DS_REG_IPCFIFOCNT: case DS_REG_IME: case DS_REG_IE_LO: case DS_REG_IE_HI:

@@ -343,3 +354,12 @@ return ds->ds9.memory.io[address >> 1];

} return 0; } + +uint32_t DS9IORead32(struct DS* ds, uint32_t address) { + switch (address) { + case DS_REG_IPCFIFORECV_LO: + return DSIPCReadFIFO(&ds->ds9); + default: + return DS9IORead(ds, address & 0x00FFFFFC) | (DS9IORead(ds, (address & 0x00FFFFFC) | 2) << 16); + } +}
M src/ds/ipc.csrc/ds/ipc.c

@@ -48,3 +48,23 @@ dscore->memory.io[DS_REG_IPCFIFOCNT >> 1] = DSIPCFIFOCNTFillSendFull(dscore->memory.io[DS_REG_IPCFIFOCNT >> 1]);

dscore->ipc->memory.io[DS_REG_IPCFIFOCNT >> 1] = DSIPCFIFOCNTFillRecvFull(dscore->ipc->memory.io[DS_REG_IPCFIFOCNT >> 1]); } } + +int32_t DSIPCReadFIFO(struct DSCommon* dscore) { + if (!DSIPCFIFOCNTIsEnable(dscore->memory.io[DS_REG_IPCFIFOCNT >> 1])) { + return 0; + } + int32_t value = ((int32_t*) dscore->ipc->memory.io)[DS_REG_IPCFIFOSEND_LO >> 2]; // TODO: actual last value + CircleBufferRead32(&dscore->fifo, &value); + size_t fullness = CircleBufferSize(&dscore->fifo); + dscore->memory.io[DS_REG_IPCFIFOCNT >> 1] = DSIPCFIFOCNTClearRecvFull(dscore->memory.io[DS_REG_IPCFIFOCNT >> 1]); + dscore->ipc->memory.io[DS_REG_IPCFIFOCNT >> 1] = DSIPCFIFOCNTClearSendFull(dscore->ipc->memory.io[DS_REG_IPCFIFOCNT >> 1]); + if (fullness == 0) { + dscore->memory.io[DS_REG_IPCFIFOCNT >> 1] = DSIPCFIFOCNTFillRecvEmpty(dscore->memory.io[DS_REG_IPCFIFOCNT >> 1]); + dscore->ipc->memory.io[DS_REG_IPCFIFOCNT >> 1] = DSIPCFIFOCNTFillSendEmpty(dscore->ipc->memory.io[DS_REG_IPCFIFOCNT >> 1]); + if (DSIPCFIFOCNTIsSendIRQ(dscore->ipc->memory.io[DS_REG_IPCFIFOCNT >> 1])) { + // TODO: Adaptive time slicing? + DSRaiseIRQ(dscore->ipc->cpu, dscore->ipc->memory.io, DS_IRQ_IPC_NOT_EMPTY); + } + } + return value; +}
M src/ds/memory.csrc/ds/memory.c

@@ -237,7 +237,7 @@ }

mLOG(DS_MEM, STUB, "Unimplemented DS7 Load32: %08X", address); break; case DS_REGION_IO: - value = DS7IORead(ds, address & 0x00FFFFFC) | (DS7IORead(ds, (address & 0x00FFFFFC) | 2) << 16); + value = DS7IORead32(ds, address & 0x00FFFFFC); break; default: mLOG(DS_MEM, STUB, "Unimplemented DS7 Load32: %08X", address);

@@ -681,7 +681,7 @@ }

mLOG(DS_MEM, STUB, "Unimplemented DS9 Load32: %08X", address); break; case DS_REGION_IO: - value = DS9IORead(ds, address & 0x00FFFFFC) | (DS9IORead(ds, (address & 0x00FFFFFC) | 2) << 16); + value = DS9IORead32(ds, address & 0x00FFFFFC); break; case DS9_REGION_BIOS: // TODO: Fix undersized BIOS