diff options
Diffstat (limited to 'src/NDSCart.cpp')
-rw-r--r-- | src/NDSCart.cpp | 87 |
1 files changed, 43 insertions, 44 deletions
diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index f291d7b..696666b 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -246,7 +246,7 @@ void Write_Discover(u8 val, bool islast) { Discover_MemoryType = 5; } - else if (len > 2+128) // Flash + else if ((len > 2+128) || (len > 1+16 && CurCmd == 0xA)) // Flash { Discover_MemoryType = 4; } @@ -284,7 +284,7 @@ void Write_EEPROMTiny(u8 val, bool islast) } else { - SRAM[(Addr & 0xFF) | ((CurCmd==0x0A)?0x100:0)] = val; + SRAM[(Addr + ((CurCmd==0x0A)?0x100:0)) & 0x1FF] = val; Addr++; } break; @@ -298,7 +298,7 @@ void Write_EEPROMTiny(u8 val, bool islast) } else { - Data = SRAM[(Addr & 0xFF) | ((CurCmd==0x0B)?0x100:0)]; + Data = SRAM[(Addr + ((CurCmd==0x0B)?0x100:0)) & 0x1FF]; Addr++; } break; @@ -471,11 +471,20 @@ void Write(u8 val, u32 hold) switch (CurCmd) { + case 0x00: + // Pokémon carts have an IR transceiver thing, and send this + // to bypass it and access SRAM. + // TODO: design better + CurCmd = val; + break; + case 0x02: case 0x03: case 0x0A: case 0x0B: case 0x9F: + case 0xD8: + case 0xDB: WriteFunc(val, islast); DataPos++; break; @@ -496,7 +505,7 @@ void Write(u8 val, u32 hold) default: if (DataPos==0) - printf("unknown save SPI command %02X\n", CurCmd); + printf("unknown save SPI command %02X %08X\n", CurCmd); break; } @@ -801,9 +810,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)) @@ -820,16 +828,16 @@ void ROMPrepareData(u32 param) DataOutPos += 4; ROMCnt |= (1<<23); - NDS::CheckDMAs(0, 0x06); - NDS::CheckDMAs(1, 0x12); - //if (DataOutPos < DataOutLen) - // NDS::ScheduleEvent((ROMCnt & (1<<27)) ? 8:5, ROMPrepareData, 0); + if (NDS::ExMemCnt[0] & (1<<11)) + NDS::CheckDMAs(1, 0x12); + else + NDS::CheckDMAs(0, 0x05); } void WriteROMCnt(u32 val) { - ROMCnt = val & 0xFF7F7FFF; + ROMCnt = (val & 0xFF7F7FFF) | (ROMCnt & 0x00800000); if (!(SPICnt & (1<<15))) return; @@ -958,52 +966,43 @@ 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 + // TODO: advance read position if bit28 is set + + u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5; + u32 cmddelay = 8 + (ROMCnt & 0x1FFF); + if (datasize) cmddelay += ((ROMCnt >> 16) & 0x3F); if (datasize == 0) - EndTransfer(); + NDS::ScheduleEvent(NDS::Event_ROMTransfer, false, xfercycle*cmddelay, 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*(cmddelay+4), ROMPrepareData, 0); } u32 ReadROMData() { - /*if (ROMCnt & (1<<23)) + if (ROMCnt & (1<<23)) { ROMCnt &= ~(1<<23); - if (DataOutPos >= DataOutLen) - EndTransfer(); - } - - return ROMDataOut;*/ - u32 ret; - if (DataOutPos >= DataOutLen) - ret = 0; - else - ret = *(u32*)&DataOut[DataOutPos]; - - DataOutPos += 4; - if (DataOutPos == DataOutLen) - EndTransfer(); - - return ret; -} + if (DataOutPos < DataOutLen) + { + u32 xfercycle = (ROMCnt & (1<<27)) ? 8 : 5; + u32 delay = 4; + if (!(DataOutPos & 0x1FF)) delay += ((ROMCnt >> 16) & 0x3F); -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]); + NDS::ScheduleEvent(NDS::Event_ROMTransfer, true, xfercycle*delay, ROMPrepareData, 0); + } + else + ROMEndTransfer(0); } - EndTransfer(); + return ROMDataOut; } |