DS Slot-1: Fix Slot-1 DMA end condition

This commit is contained in:
Vicki Pfau 2017-02-26 19:06:25 -08:00
parent aaa56c0c7c
commit b86fe419ec
1 changed files with 38 additions and 27 deletions

View File

@ -60,6 +60,34 @@ static void _transferEvent(struct mTiming* timing, void* context, uint32_t cycle
DSSlot1ROMCNT romcnt;
// TODO: Big endian
LOAD_32(romcnt, DS_REG_ROMCNT_LO, ds->memory.io7);
struct DSCommon* dscore;
if (ds->ds7.memory.slot1Access) {
dscore = &ds->ds7;
} else {
dscore = &ds->ds9;
}
struct GBADMA* dma = NULL;
if (ds->memory.slot1.dmaSource >= 0) {
dma = &dscore->memory.dma[ds->memory.slot1.dmaSource];
}
bool hasDMA = false;
if (dma) {
if (ds->ds7.memory.slot1Access && GBADMARegisterGetTiming(dma->reg) == DS7_DMA_TIMING_SLOT1) {
hasDMA = true;
}
if (ds->ds9.memory.slot1Access && GBADMARegisterGetTiming9(dma->reg) == DS9_DMA_TIMING_SLOT1) {
hasDMA = true;
}
if (!GBADMARegisterIsEnable(dma->reg)) {
hasDMA = false;
}
}
if (!hasDMA) {
ds->memory.slot1.dmaSource = -1;
}
if (ds->memory.slot1.transferRemaining) {
ds->romVf->read(ds->romVf, ds->memory.slot1.readBuffer, 4);
// TODO: Error check
@ -67,28 +95,10 @@ static void _transferEvent(struct mTiming* timing, void* context, uint32_t cycle
ds->memory.slot1.transferRemaining -= 4;
romcnt = DSSlot1ROMCNTFillWordReady(romcnt);
if (ds->memory.slot1.dmaSource >= 0) {
struct DSCommon* dscore;
if (ds->ds7.memory.slot1Access) {
dscore = &ds->ds7;
} else {
dscore = &ds->ds9;
}
struct GBADMA* dma = &dscore->memory.dma[ds->memory.slot1.dmaSource];
bool cond = false;
if (ds->ds7.memory.slot1Access && GBADMARegisterGetTiming(dma->reg) == DS7_DMA_TIMING_SLOT1) {
cond = true;
}
if (ds->ds9.memory.slot1Access && GBADMARegisterGetTiming9(dma->reg) == DS9_DMA_TIMING_SLOT1) {
cond = true;
}
if (cond) {
dma->when = mTimingCurrentTime(timing);
dma->nextCount = 1;
DSDMAUpdate(dscore);
} else {
ds->memory.slot1.dmaSource = -1;
}
if (hasDMA) {
dma->when = mTimingCurrentTime(timing);
dma->nextCount = 1;
DSDMAUpdate(dscore);
}
} else {
DSSlot1AUXSPICNT config = ds->memory.io7[DS_REG_AUXSPICNT >> 1];
@ -96,11 +106,12 @@ static void _transferEvent(struct mTiming* timing, void* context, uint32_t cycle
romcnt = DSSlot1ROMCNTClearWordReady(romcnt);
romcnt = DSSlot1ROMCNTClearBlockBusy(romcnt);
if (DSSlot1AUXSPICNTIsDoIRQ(config)) {
if (ds->ds7.memory.slot1Access) {
DSRaiseIRQ(ds->ds7.cpu, ds->ds7.memory.io, DS_IRQ_SLOT1_TRANS);
} else {
DSRaiseIRQ(ds->ds9.cpu, ds->ds9.memory.io, DS_IRQ_SLOT1_TRANS);
}
DSRaiseIRQ(dscore->cpu, dscore->memory.io, DS_IRQ_SLOT1_TRANS);
}
if (hasDMA) {
dma->reg = GBADMARegisterClearEnable(dma->reg);
dma->reg = GBADMARegisterClearRepeat(dma->reg);
dscore->memory.io[(DS_REG_DMA0CNT_HI + ds->memory.slot1.dmaSource * (DS_REG_DMA1CNT_HI - DS_REG_DMA0CNT_HI)) >> 1] = dma->reg;
}
}
STORE_32(romcnt, DS_REG_ROMCNT_LO, ds->memory.io7);