DS Slot-1: Emulate initial SPI command delay

This commit is contained in:
Vicki Pfau 2017-04-15 12:08:02 -07:00
parent c2f43bc503
commit b796a689cb
2 changed files with 10 additions and 6 deletions

View File

@ -20,6 +20,7 @@ Bugfixes:
- DS GX: Don't reset state between buffer swaps (fixes mgba.io/i/642) - DS GX: Don't reset state between buffer swaps (fixes mgba.io/i/642)
- DS GX: Allow viewport to change in the middle of a frame - DS GX: Allow viewport to change in the middle of a frame
- DS GX: Properly mask address for slot 2 4x4-texel textures - DS GX: Properly mask address for slot 2 4x4-texel textures
- DS Slot-1: Emulate initial SPI command delay
Misc: Misc:
- DS: Set boot complete bit in RAM on boot (fixes mgba.io/i/576, mgba.io/i/580, mgba.io/i/586) - DS: Set boot complete bit in RAM on boot (fixes mgba.io/i/576, mgba.io/i/580, mgba.io/i/586)
- DS Memory: Ensure DS9 I/O is 8-byte aligned - DS Memory: Ensure DS9 I/O is 8-byte aligned

View File

@ -41,7 +41,7 @@ void DSSlot1Reset(struct DS* ds) {
ds->memory.slot1.spiAddressingBits = 16; ds->memory.slot1.spiAddressingBits = 16;
} }
static void _scheduleTransfer(struct DS* ds, struct mTiming* timing, uint32_t cyclesLate) { static void _scheduleTransfer(struct DS* ds, struct mTiming* timing, uint32_t bytes, uint32_t cyclesLate) {
DSSlot1ROMCNT romcnt = ds->memory.io7[DS_REG_ROMCNT_HI >> 1] << 16; DSSlot1ROMCNT romcnt = ds->memory.io7[DS_REG_ROMCNT_HI >> 1] << 16;
uint32_t cycles; uint32_t cycles;
if (DSSlot1ROMCNTIsTransferRate(romcnt)) { if (DSSlot1ROMCNTIsTransferRate(romcnt)) {
@ -52,6 +52,7 @@ static void _scheduleTransfer(struct DS* ds, struct mTiming* timing, uint32_t cy
if (!ds->ds7.memory.slot1Access) { if (!ds->ds7.memory.slot1Access) {
cycles <<= 1; cycles <<= 1;
} }
cycles *= bytes / 4;
cycles -= cyclesLate; cycles -= cyclesLate;
mTimingDeschedule(timing, &ds->memory.slot1.transferEvent); mTimingDeschedule(timing, &ds->memory.slot1.transferEvent);
mTimingSchedule(timing, &ds->memory.slot1.transferEvent, cycles); mTimingSchedule(timing, &ds->memory.slot1.transferEvent, cycles);
@ -142,9 +143,9 @@ static void DSSlot1StartTransfer(struct DS* ds) {
} }
ds->memory.slot1.transferRemaining = ds->memory.slot1.transferSize; ds->memory.slot1.transferRemaining = ds->memory.slot1.transferSize;
if (ds->ds7.memory.slot1Access) { if (ds->ds7.memory.slot1Access) {
_scheduleTransfer(ds, &ds->ds7.timing, 0); _scheduleTransfer(ds, &ds->ds7.timing, 12, 0);
} else { } else {
_scheduleTransfer(ds, &ds->ds9.timing, 0); _scheduleTransfer(ds, &ds->ds9.timing, 12, 0);
} }
break; break;
case 0xB8: case 0xB8:
@ -185,8 +186,10 @@ DSSlot1ROMCNT DSSlot1Control(struct DS* ds, DSSlot1ROMCNT control) {
if (DSSlot1ROMCNTIsBlockBusy(control)) { if (DSSlot1ROMCNTIsBlockBusy(control)) {
DSSlot1StartTransfer(ds); DSSlot1StartTransfer(ds);
// TODO: timing // TODO: timing
if (ds->memory.slot1.command[0] != 0xB7) {
control = DSSlot1ROMCNTFillWordReady(control); control = DSSlot1ROMCNTFillWordReady(control);
} }
}
return control; return control;
} }
@ -194,9 +197,9 @@ uint32_t DSSlot1Read(struct DS* ds) {
uint32_t result; uint32_t result;
LOAD_32(result, 0, ds->memory.slot1.readBuffer); LOAD_32(result, 0, ds->memory.slot1.readBuffer);
if (ds->ds7.memory.slot1Access) { if (ds->ds7.memory.slot1Access) {
_scheduleTransfer(ds, &ds->ds7.timing, 0); _scheduleTransfer(ds, &ds->ds7.timing, 4, 0);
} else { } else {
_scheduleTransfer(ds, &ds->ds9.timing, 0); _scheduleTransfer(ds, &ds->ds9.timing, 4, 0);
} }
return result; return result;
} }