diff --git a/src/DMA.cpp b/src/DMA.cpp index 9a17f416..8e2a4600 100644 --- a/src/DMA.cpp +++ b/src/DMA.cpp @@ -186,18 +186,6 @@ void DMA::Start() //printf("ARM%d DMA%d %08X %02X %08X->%08X %d bytes %dbit\n", CPU?7:9, Num, Cnt, StartMode, CurSrcAddr, CurDstAddr, RemCount*((Cnt&0x04000000)?4:2), (Cnt&0x04000000)?32:16); - // special path for cart DMA. this is a gross hack. - // emulating it properly requires emulating cart transfer delays, so uh... TODO - if (CurSrcAddr==0x04100010 && RemCount==1 && (Cnt & 0x07E00000)==0x07000000 && - (StartMode==0x05 || StartMode==0x12)) - { - NDSCart::DMA(CurDstAddr); - Cnt &= ~0x80000000; - if (Cnt & 0x40000000) - NDS::SetIRQ(CPU, NDS::IRQ_DMA0 + Num); - return; - } - // special path for the display FIFO. another gross hack. // the display FIFO seems to be more like a circular buffer that holds 16 pixels // from which the display controller reads. DMA is triggered every 8 pixels to fill it diff --git a/src/NDS.h b/src/NDS.h index 583e12c1..46378859 100644 --- a/src/NDS.h +++ b/src/NDS.h @@ -27,9 +27,10 @@ namespace NDS enum { Event_LCD = 0, - Event_SPU, + Event_ROMTransfer, + Event_MAX }; diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 58d4a1ad..2593b407 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -808,9 +808,8 @@ void ReadROM_B7(u32 addr, u32 len, u32 offset) } -void EndTransfer() +void ROMEndTransfer(u32 param) { - ROMCnt &= ~(1<<23); ROMCnt &= ~(1<<31); if (SPICnt & (1<<14)) @@ -827,16 +826,13 @@ void ROMPrepareData(u32 param) DataOutPos += 4; ROMCnt |= (1<<23); - NDS::CheckDMAs(0, 0x06); + NDS::CheckDMAs(0, 0x05); NDS::CheckDMAs(1, 0x12); - - //if (DataOutPos < DataOutLen) - // NDS::ScheduleEvent((ROMCnt & (1<<27)) ? 8:5, ROMPrepareData, 0); } void WriteROMCnt(u32 val) { - ROMCnt = val & 0xFF7F7FFF; + ROMCnt = (val & 0xFF7F7FFF) | (ROMCnt & 0x00800000); if (!(SPICnt & (1<<15))) return; @@ -965,52 +961,36 @@ void WriteROMCnt(u32 val) break; } - //ROMCnt &= ~(1<<23); - ROMCnt |= (1<<23); + ROMCnt &= ~(1<<23); + // ROM transfer timings + // the bus is parallel with 8 bits + // thus a command would take 8 cycles to be transferred + // and it would take 4 cycles to receive a word of data + + u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5; if (datasize == 0) - EndTransfer(); + NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*8, ROMEndTransfer, 0); else - { - NDS::CheckDMAs(0, 0x05); - NDS::CheckDMAs(1, 0x12); - } - //NDS::ScheduleEvent((ROMCnt & (1<<27)) ? 8:5, ROMPrepareData, 0); + NDS::ScheduleEvent(NDS::Event_ROMTransfer, true, xfercycle*(8+4), ROMPrepareData, 0); } u32 ReadROMData() { - /*if (ROMCnt & (1<<23)) + if (ROMCnt & (1<<23)) { ROMCnt &= ~(1<<23); - if (DataOutPos >= DataOutLen) - EndTransfer(); + + if (DataOutPos < DataOutLen) + { + u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5; + NDS::ScheduleEvent(NDS::Event_ROMTransfer, true, xfercycle*4, ROMPrepareData, 0); + } + else + ROMEndTransfer(0); } - return ROMDataOut;*/ - u32 ret; - if (DataOutPos >= DataOutLen) - ret = 0; - else - ret = *(u32*)&DataOut[DataOutPos]; - - DataOutPos += 4; - - if (DataOutPos == DataOutLen) - EndTransfer(); - - return ret; -} - -void DMA(u32 addr) -{ - void (*writefn)(u32,u32) = (NDS::ExMemCnt[0] & (1<<11)) ? NDS::ARM7Write32 : NDS::ARM9Write32; - for (u32 i = 0; i < DataOutLen; i+=4) - { - writefn(addr+i, *(u32*)&DataOut[i]); - } - - EndTransfer(); + return ROMDataOut; } diff --git a/src/NDSCart.h b/src/NDSCart.h index 5125ffae..5bec38d4 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -44,7 +44,6 @@ bool LoadROM(const char* path, bool direct); void WriteROMCnt(u32 val); u32 ReadROMData(); -void DMA(u32 addr); void WriteSPICnt(u16 val); u8 ReadSPIData();