mirror of https://github.com/mgba-emu/mgba.git
DS Slot-1: Implement Slot-1 DMAs
This commit is contained in:
parent
9c40ebb301
commit
cf5d6709fe
|
@ -46,6 +46,8 @@ struct DSSlot1 {
|
|||
struct mTimingEvent transferEvent;
|
||||
uint8_t readBuffer[4];
|
||||
|
||||
int dmaSource;
|
||||
|
||||
enum DSSavedataType savedataType;
|
||||
struct mTimingEvent spiEvent;
|
||||
bool spiHoldEnabled;
|
||||
|
@ -64,9 +66,14 @@ struct DS;
|
|||
struct DSCommon;
|
||||
void DSSlot1SPIInit(struct DS* ds, struct VFile* vf);
|
||||
void DSSlot1Reset(struct DS* ds);
|
||||
|
||||
DSSlot1AUXSPICNT DSSlot1Configure(struct DS* ds, DSSlot1AUXSPICNT config);
|
||||
DSSlot1ROMCNT DSSlot1Control(struct DS* ds, DSSlot1ROMCNT control);
|
||||
void DSSlot1WriteSPI(struct DSCommon* dscore, uint8_t datum);
|
||||
|
||||
struct GBADMA;
|
||||
void DSSlot1ScheduleDMA(struct DSCommon* dscore, int number, struct GBADMA* info);
|
||||
|
||||
uint32_t DSSlot1Read(struct DS* ds);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
|
13
src/ds/dma.c
13
src/ds/dma.c
|
@ -81,15 +81,24 @@ void DS9DMAWriteCNT(struct DSCommon* dscore, int dma, uint32_t value) {
|
|||
}
|
||||
|
||||
void DSDMASchedule(struct DSCommon* dscore, int number, struct GBADMA* info) {
|
||||
switch (GBADMARegisterGetTiming(info->reg)) {
|
||||
int which;
|
||||
if (dscore == &dscore->p->ds9) {
|
||||
which = GBADMARegisterGetTiming9(info->reg);
|
||||
} else {
|
||||
which = GBADMARegisterGetTiming(info->reg);
|
||||
}
|
||||
switch (which) {
|
||||
case DS_DMA_TIMING_NOW:
|
||||
info->when = mTimingCurrentTime(&dscore->timing) + 3; // DMAs take 3 cycles to start
|
||||
info->nextCount = info->count;
|
||||
break;
|
||||
case DS_DMA_TIMING_HBLANK:
|
||||
case DS_DMA_TIMING_VBLANK:
|
||||
// Handled implicitly
|
||||
return;
|
||||
case DS9_DMA_TIMING_SLOT1:
|
||||
DSSlot1ScheduleDMA(dscore, number, info);
|
||||
return;
|
||||
case DS_DMA_TIMING_HBLANK: // DS7_DMA_TIMING_SLOT1
|
||||
default:
|
||||
mLOG(DS_MEM, STUB, "Unimplemented DMA");
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <mgba/internal/arm/macros.h>
|
||||
#include <mgba/internal/ds/ds.h>
|
||||
#include <mgba/internal/ds/dma.h>
|
||||
#include <mgba-util/math.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
||||
|
@ -35,6 +36,7 @@ void DSSlot1Reset(struct DS* ds) {
|
|||
ds->memory.slot1.statusReg = 0;
|
||||
ds->memory.slot1.spiCommand = 0;
|
||||
ds->memory.slot1.spiHoldEnabled = 0;
|
||||
ds->memory.slot1.dmaSource = -1;
|
||||
}
|
||||
|
||||
static void _scheduleTransfer(struct DS* ds, struct mTiming* timing, uint32_t cyclesLate) {
|
||||
|
@ -46,7 +48,7 @@ static void _scheduleTransfer(struct DS* ds, struct mTiming* timing, uint32_t cy
|
|||
cycles = 5;
|
||||
}
|
||||
if (!ds->ds7.memory.slot1Access) {
|
||||
cycles << 1;
|
||||
cycles <<= 1;
|
||||
}
|
||||
cycles -= cyclesLate;
|
||||
mTimingDeschedule(timing, &ds->memory.slot1.transferEvent);
|
||||
|
@ -64,6 +66,30 @@ static void _transferEvent(struct mTiming* timing, void* context, uint32_t cycle
|
|||
ds->memory.slot1.address += 4;
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DSSlot1AUXSPICNT config = ds->memory.io7[DS_REG_AUXSPICNT >> 1];
|
||||
memset(ds->memory.slot1.readBuffer, 0, 4);
|
||||
|
@ -331,3 +357,7 @@ static bool _slot1GuaranteeSize(struct DSSlot1* slot1) {
|
|||
}
|
||||
return slot1->spiData;
|
||||
}
|
||||
|
||||
void DSSlot1ScheduleDMA(struct DSCommon* dscore, int number, struct GBADMA* info) {
|
||||
dscore->p->memory.slot1.dmaSource = number;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue