mirror of https://github.com/mgba-emu/mgba.git
DS IPC: Implement IPC read
This commit is contained in:
parent
f7ed6ec99f
commit
3679e1e8d6
|
@ -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 DS7IOWrite8(struct DS* ds, uint32_t address, uint8_t value);
|
||||||
void DS7IOWrite32(struct DS* ds, uint32_t address, uint32_t value);
|
void DS7IOWrite32(struct DS* ds, uint32_t address, uint32_t value);
|
||||||
uint16_t DS7IORead(struct DS* ds, uint32_t address);
|
uint16_t DS7IORead(struct DS* ds, uint32_t address);
|
||||||
|
uint32_t DS7IORead32(struct DS* ds, uint32_t address);
|
||||||
|
|
||||||
void DS9IOInit(struct DS* ds);
|
void DS9IOInit(struct DS* ds);
|
||||||
void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value);
|
void DS9IOWrite(struct DS* ds, uint32_t address, uint16_t value);
|
||||||
void DS9IOWrite8(struct DS* ds, uint32_t address, uint8_t value);
|
void DS9IOWrite8(struct DS* ds, uint32_t address, uint8_t value);
|
||||||
void DS9IOWrite32(struct DS* ds, uint32_t address, uint32_t value);
|
void DS9IOWrite32(struct DS* ds, uint32_t address, uint32_t value);
|
||||||
uint16_t DS9IORead(struct DS* ds, uint32_t address);
|
uint16_t DS9IORead(struct DS* ds, uint32_t address);
|
||||||
|
uint32_t DS9IORead32(struct DS* ds, uint32_t address);
|
||||||
|
|
||||||
CXX_GUARD_END
|
CXX_GUARD_END
|
||||||
|
|
||||||
|
|
20
src/ds/io.c
20
src/ds/io.c
|
@ -207,6 +207,7 @@ uint16_t DS7IORead(struct DS* ds, uint32_t address) {
|
||||||
case DS_REG_TM2CNT_HI:
|
case DS_REG_TM2CNT_HI:
|
||||||
case DS_REG_TM3CNT_HI:
|
case DS_REG_TM3CNT_HI:
|
||||||
case DS_REG_IPCSYNC:
|
case DS_REG_IPCSYNC:
|
||||||
|
case DS_REG_IPCFIFOCNT:
|
||||||
case DS_REG_IME:
|
case DS_REG_IME:
|
||||||
case DS_REG_IE_LO:
|
case DS_REG_IE_LO:
|
||||||
case DS_REG_IE_HI:
|
case DS_REG_IE_HI:
|
||||||
|
@ -223,6 +224,15 @@ uint16_t DS7IORead(struct DS* ds, uint32_t address) {
|
||||||
return 0;
|
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) {
|
void DS9IOInit(struct DS* ds) {
|
||||||
memset(ds->memory.io9, 0, sizeof(ds->memory.io9));
|
memset(ds->memory.io9, 0, sizeof(ds->memory.io9));
|
||||||
}
|
}
|
||||||
|
@ -328,6 +338,7 @@ uint16_t DS9IORead(struct DS* ds, uint32_t address) {
|
||||||
case DS_REG_TM2CNT_HI:
|
case DS_REG_TM2CNT_HI:
|
||||||
case DS_REG_TM3CNT_HI:
|
case DS_REG_TM3CNT_HI:
|
||||||
case DS_REG_IPCSYNC:
|
case DS_REG_IPCSYNC:
|
||||||
|
case DS_REG_IPCFIFOCNT:
|
||||||
case DS_REG_IME:
|
case DS_REG_IME:
|
||||||
case DS_REG_IE_LO:
|
case DS_REG_IE_LO:
|
||||||
case DS_REG_IE_HI:
|
case DS_REG_IE_HI:
|
||||||
|
@ -343,3 +354,12 @@ uint16_t DS9IORead(struct DS* ds, uint32_t address) {
|
||||||
}
|
}
|
||||||
return 0;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
20
src/ds/ipc.c
20
src/ds/ipc.c
|
@ -48,3 +48,23 @@ void DSIPCWriteFIFO(struct DSCommon* dscore, int32_t value) {
|
||||||
dscore->ipc->memory.io[DS_REG_IPCFIFOCNT >> 1] = DSIPCFIFOCNTFillRecvFull(dscore->ipc->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;
|
||||||
|
}
|
||||||
|
|
|
@ -237,7 +237,7 @@ uint32_t DS7Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||||
mLOG(DS_MEM, STUB, "Unimplemented DS7 Load32: %08X", address);
|
mLOG(DS_MEM, STUB, "Unimplemented DS7 Load32: %08X", address);
|
||||||
break;
|
break;
|
||||||
case DS_REGION_IO:
|
case DS_REGION_IO:
|
||||||
value = DS7IORead(ds, address & 0x00FFFFFC) | (DS7IORead(ds, (address & 0x00FFFFFC) | 2) << 16);
|
value = DS7IORead32(ds, address & 0x00FFFFFC);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mLOG(DS_MEM, STUB, "Unimplemented DS7 Load32: %08X", address);
|
mLOG(DS_MEM, STUB, "Unimplemented DS7 Load32: %08X", address);
|
||||||
|
@ -681,7 +681,7 @@ uint32_t DS9Load32(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||||
mLOG(DS_MEM, STUB, "Unimplemented DS9 Load32: %08X", address);
|
mLOG(DS_MEM, STUB, "Unimplemented DS9 Load32: %08X", address);
|
||||||
break;
|
break;
|
||||||
case DS_REGION_IO:
|
case DS_REGION_IO:
|
||||||
value = DS9IORead(ds, address & 0x00FFFFFC) | (DS9IORead(ds, (address & 0x00FFFFFC) | 2) << 16);
|
value = DS9IORead32(ds, address & 0x00FFFFFC);
|
||||||
break;
|
break;
|
||||||
case DS9_REGION_BIOS:
|
case DS9_REGION_BIOS:
|
||||||
// TODO: Fix undersized BIOS
|
// TODO: Fix undersized BIOS
|
||||||
|
|
Loading…
Reference in New Issue