emulate slot-1 read timings (fixes SF bug 1258)
This commit is contained in:
parent
6600a2c393
commit
281268e05f
|
@ -1351,11 +1351,14 @@ void FASTCALL MMU_writeToGCControl(u32 val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
val |= 0x00800000;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
|
T1WriteLong(MMU.MMU_MEM[PROCNUM][0x40], 0x1A4, val);
|
||||||
|
|
||||||
|
//don't do this yet. it needs to be scheduled for the future
|
||||||
|
//val |= 0x00800000;
|
||||||
// Launch DMA if start flag was set to "DS Cart"
|
// Launch DMA if start flag was set to "DS Cart"
|
||||||
triggerDma(EDMAMode_Card);
|
//triggerDma(EDMAMode_Card);
|
||||||
|
|
||||||
|
NDS_RescheduleReadSlot1(blocksize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*template<int PROCNUM>
|
/*template<int PROCNUM>
|
||||||
|
|
|
@ -1085,6 +1085,31 @@ template<int procnum, int chan> struct TSequenceItem_DMA : public TSequenceItem
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TSequenceItem_ReadSlot1 : public TSequenceItem
|
||||||
|
{
|
||||||
|
FORCEINLINE bool isTriggered()
|
||||||
|
{
|
||||||
|
return enabled && nds_timer >= timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEnabled() { return this->enabled; }
|
||||||
|
|
||||||
|
FORCEINLINE u64 next()
|
||||||
|
{
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exec()
|
||||||
|
{
|
||||||
|
enabled = false;
|
||||||
|
u32 val = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4);
|
||||||
|
val |= 0x00800000;
|
||||||
|
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4, val);
|
||||||
|
triggerDma(EDMAMode_Card);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct TSequenceItem_divider : public TSequenceItem
|
struct TSequenceItem_divider : public TSequenceItem
|
||||||
{
|
{
|
||||||
FORCEINLINE bool isTriggered()
|
FORCEINLINE bool isTriggered()
|
||||||
|
@ -1150,6 +1175,7 @@ struct Sequencer
|
||||||
TSequenceItem_divider divider;
|
TSequenceItem_divider divider;
|
||||||
TSequenceItem_sqrtunit sqrtunit;
|
TSequenceItem_sqrtunit sqrtunit;
|
||||||
TSequenceItem_GXFIFO gxfifo;
|
TSequenceItem_GXFIFO gxfifo;
|
||||||
|
TSequenceItem_ReadSlot1 readslot1;
|
||||||
TSequenceItem_DMA<0,0> dma_0_0; TSequenceItem_DMA<0,1> dma_0_1;
|
TSequenceItem_DMA<0,0> dma_0_0; TSequenceItem_DMA<0,1> dma_0_1;
|
||||||
TSequenceItem_DMA<0,2> dma_0_2; TSequenceItem_DMA<0,3> dma_0_3;
|
TSequenceItem_DMA<0,2> dma_0_2; TSequenceItem_DMA<0,3> dma_0_3;
|
||||||
TSequenceItem_DMA<1,0> dma_1_0; TSequenceItem_DMA<1,1> dma_1_1;
|
TSequenceItem_DMA<1,0> dma_1_0; TSequenceItem_DMA<1,1> dma_1_1;
|
||||||
|
@ -1173,6 +1199,7 @@ struct Sequencer
|
||||||
divider.save(os);
|
divider.save(os);
|
||||||
sqrtunit.save(os);
|
sqrtunit.save(os);
|
||||||
gxfifo.save(os);
|
gxfifo.save(os);
|
||||||
|
readslot1.save(os);
|
||||||
wifi.save(os);
|
wifi.save(os);
|
||||||
#define SAVE(I,X,Y) I##_##X##_##Y .save(os);
|
#define SAVE(I,X,Y) I##_##X##_##Y .save(os);
|
||||||
SAVE(timer,0,0); SAVE(timer,0,1); SAVE(timer,0,2); SAVE(timer,0,3);
|
SAVE(timer,0,0); SAVE(timer,0,1); SAVE(timer,0,2); SAVE(timer,0,3);
|
||||||
|
@ -1191,6 +1218,7 @@ struct Sequencer
|
||||||
if(!divider.load(is)) return false;
|
if(!divider.load(is)) return false;
|
||||||
if(!sqrtunit.load(is)) return false;
|
if(!sqrtunit.load(is)) return false;
|
||||||
if(!gxfifo.load(is)) return false;
|
if(!gxfifo.load(is)) return false;
|
||||||
|
if(!readslot1.load(is)) return false;
|
||||||
if(version >= 1) if(!wifi.load(is)) return false;
|
if(version >= 1) if(!wifi.load(is)) return false;
|
||||||
#define LOAD(I,X,Y) if(!I##_##X##_##Y .load(is)) return false;
|
#define LOAD(I,X,Y) if(!I##_##X##_##Y .load(is)) return false;
|
||||||
LOAD(timer,0,0); LOAD(timer,0,1); LOAD(timer,0,2); LOAD(timer,0,3);
|
LOAD(timer,0,0); LOAD(timer,0,1); LOAD(timer,0,2); LOAD(timer,0,3);
|
||||||
|
@ -1224,6 +1252,28 @@ void NDS_RescheduleTimers()
|
||||||
NDS_Reschedule();
|
NDS_Reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NDS_RescheduleReadSlot1(int size)
|
||||||
|
{
|
||||||
|
u32 gcromctrl = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4);
|
||||||
|
|
||||||
|
u32 clocks = (gcromctrl & (1<<27)) ? 8 : 5;
|
||||||
|
u32 gap = gcromctrl & 0x1FFF;
|
||||||
|
|
||||||
|
//time to send 8 command bytes, and then wait for the gap
|
||||||
|
u32 delay = (8+gap)*clocks;
|
||||||
|
|
||||||
|
//if data is to be returned, the first word is read before it's available and irqs and dmas fire
|
||||||
|
if(size != 0) delay += 4;
|
||||||
|
|
||||||
|
//timings are basically 33mhz but internal tracking is 66mhz
|
||||||
|
delay *= 2;
|
||||||
|
|
||||||
|
sequencer.readslot1.timestamp = nds_timer + delay;
|
||||||
|
sequencer.readslot1.enabled = true;
|
||||||
|
|
||||||
|
NDS_Reschedule();
|
||||||
|
}
|
||||||
|
|
||||||
void NDS_RescheduleDMA()
|
void NDS_RescheduleDMA()
|
||||||
{
|
{
|
||||||
//TBD
|
//TBD
|
||||||
|
@ -1604,6 +1654,7 @@ u64 Sequencer::findNext()
|
||||||
if(divider.isEnabled()) next = _fast_min(next,divider.next());
|
if(divider.isEnabled()) next = _fast_min(next,divider.next());
|
||||||
if(sqrtunit.isEnabled()) next = _fast_min(next,sqrtunit.next());
|
if(sqrtunit.isEnabled()) next = _fast_min(next,sqrtunit.next());
|
||||||
if(gxfifo.enabled) next = _fast_min(next,gxfifo.next());
|
if(gxfifo.enabled) next = _fast_min(next,gxfifo.next());
|
||||||
|
if(readslot1.isEnabled()) next = _fast_min(next,readslot1.next());
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_WIFI_COMM
|
#ifdef EXPERIMENTAL_WIFI_COMM
|
||||||
next = _fast_min(next,wifi.next());
|
next = _fast_min(next,wifi.next());
|
||||||
|
@ -1674,6 +1725,7 @@ void Sequencer::execHardware()
|
||||||
if(divider.isTriggered()) divider.exec();
|
if(divider.isTriggered()) divider.exec();
|
||||||
if(sqrtunit.isTriggered()) sqrtunit.exec();
|
if(sqrtunit.isTriggered()) sqrtunit.exec();
|
||||||
if(gxfifo.isTriggered()) gxfifo.exec();
|
if(gxfifo.isTriggered()) gxfifo.exec();
|
||||||
|
if(readslot1.isTriggered()) readslot1.exec();
|
||||||
|
|
||||||
|
|
||||||
#define test(X,Y) if(dma_##X##_##Y .isTriggered()) dma_##X##_##Y .exec();
|
#define test(X,Y) if(dma_##X##_##Y .isTriggered()) dma_##X##_##Y .exec();
|
||||||
|
|
|
@ -149,6 +149,7 @@ extern u64 nds_timer;
|
||||||
void NDS_Reschedule();
|
void NDS_Reschedule();
|
||||||
void NDS_RescheduleGXFIFO(u32 cost);
|
void NDS_RescheduleGXFIFO(u32 cost);
|
||||||
void NDS_RescheduleDMA();
|
void NDS_RescheduleDMA();
|
||||||
|
void NDS_RescheduleReadSlot1(int size);
|
||||||
void NDS_RescheduleTimers();
|
void NDS_RescheduleTimers();
|
||||||
|
|
||||||
enum ENSATA_HANDSHAKE
|
enum ENSATA_HANDSHAKE
|
||||||
|
|
Loading…
Reference in New Issue