Ensure that DMAs read back from I/O memory properly

This commit is contained in:
Jeffrey Pfau 2013-04-18 00:58:22 -07:00
parent 4f8c288f20
commit 1e1c8fd2dd
3 changed files with 18 additions and 6 deletions

View File

@ -11,25 +11,25 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
GBAMemoryWriteDMACNT_LO(&gba->memory, 0, value);
break;
case REG_DMA0CNT_HI:
GBAMemoryWriteDMACNT_HI(&gba->memory, 0, value);
value = GBAMemoryWriteDMACNT_HI(&gba->memory, 0, value);
break;
case REG_DMA1CNT_LO:
GBAMemoryWriteDMACNT_LO(&gba->memory, 1, value);
break;
case REG_DMA1CNT_HI:
GBAMemoryWriteDMACNT_HI(&gba->memory, 1, value);
value = GBAMemoryWriteDMACNT_HI(&gba->memory, 1, value);
break;
case REG_DMA2CNT_LO:
GBAMemoryWriteDMACNT_LO(&gba->memory, 2, value);
break;
case REG_DMA2CNT_HI:
GBAMemoryWriteDMACNT_HI(&gba->memory, 2, value);
value = GBAMemoryWriteDMACNT_HI(&gba->memory, 2, value);
break;
case REG_DMA3CNT_LO:
GBAMemoryWriteDMACNT_LO(&gba->memory, 3, value);
break;
case REG_DMA3CNT_HI:
GBAMemoryWriteDMACNT_HI(&gba->memory, 3, value);
value = GBAMemoryWriteDMACNT_HI(&gba->memory, 3, value);
break;
case REG_WAITCNT:
@ -94,6 +94,16 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
case REG_DISPSTAT:
return GBAVideoReadDISPSTAT(&gba->video);
break;
case REG_DMA0CNT_LO:
case REG_DMA1CNT_LO:
case REG_DMA2CNT_LO:
case REG_DMA3CNT_LO:
// Write-only register
return 0;
case REG_DMA0CNT_HI:
case REG_DMA1CNT_HI:
case REG_DMA2CNT_HI:
case REG_DMA3CNT_HI:
case REG_IE:
case REG_WAITCNT:
case REG_IME:

View File

@ -461,7 +461,7 @@ void GBAMemoryWriteDMACNT_LO(struct GBAMemory* memory, int dma, uint16_t count)
memory->dma[dma].count = count ? count : (dma == 3 ? 0x10000 : 0x4000);
}
void GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control) {
uint16_t GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control) {
struct GBADMA* currentDma = &memory->dma[dma];
int wasEnabled = currentDma->enable;
currentDma->packed = control;
@ -477,6 +477,8 @@ void GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control
currentDma->nextCount = currentDma->count;
GBAMemoryScheduleDMA(memory, dma, currentDma);
}
// If the DMA has already occurred, this value might have changed since the function started
return currentDma->packed;
};
void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* info) {

View File

@ -134,7 +134,7 @@ void GBAAdjustWaitstates(struct GBAMemory* memory, uint16_t parameters);
void GBAMemoryWriteDMASAD(struct GBAMemory* memory, int dma, uint32_t address);
void GBAMemoryWriteDMADAD(struct GBAMemory* memory, int dma, uint32_t address);
void GBAMemoryWriteDMACNT_LO(struct GBAMemory* memory, int dma, uint16_t count);
void GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control);
uint16_t GBAMemoryWriteDMACNT_HI(struct GBAMemory* memory, int dma, uint16_t control);
void GBAMemoryScheduleDMA(struct GBAMemory* memory, int number, struct GBADMA* info);
void GBAMemoryServiceDMA(struct GBAMemory* memory, int number, struct GBADMA* info);