diff options
Diffstat (limited to 'NDS.cpp')
| -rw-r--r-- | NDS.cpp | 130 | 
1 files changed, 130 insertions, 0 deletions
| @@ -21,6 +21,7 @@  #include "NDS.h"  #include "ARM.h"  #include "CP15.h" +#include "FIFO.h"  #include "GPU2D.h"  #include "SPI.h"  #include "Wifi.h" @@ -35,6 +36,9 @@ namespace SPI_Firmware  namespace NDS  { +// TODO: stick all the variables in a big structure? +// would make it easier to deal with savestates +  SchedEvent SchedBuffer[SCHED_BUF_LEN];  SchedEvent* SchedQueue; @@ -76,6 +80,9 @@ u16 PowerControl7;  Timer Timers[8];  u16 IPCSync9, IPCSync7; +u16 IPCFIFOCnt9, IPCFIFOCnt7; +FIFO* IPCFIFO9; // FIFO in which the ARM9 writes +FIFO* IPCFIFO7;  u32 ROMSPIControl;  u32 ROMControl; @@ -95,6 +102,9 @@ void Init()      ARM9 = new ARM(0);      ARM7 = new ARM(1); +    IPCFIFO9 = new FIFO(16); +    IPCFIFO7 = new FIFO(16); +      SPI::Init();      Reset(); @@ -191,6 +201,10 @@ void Reset()      IPCSync9 = 0;      IPCSync7 = 0; +    IPCFIFOCnt9 = 0; +    IPCFIFOCnt7 = 0; +    IPCFIFO9->Clear(); +    IPCFIFO7->Clear();      ROMSPIControl = 0;      ROMControl = 0; @@ -726,6 +740,15 @@ u16 ARM9Read16(u32 addr)          case 0x04000130: return KeyInput & 0xFFFF;          case 0x04000180: return IPCSync9; +        case 0x04000184: +            { +                u16 val = IPCFIFOCnt9; +                if (IPCFIFO9->IsEmpty())     val |= 0x0001; +                else if (IPCFIFO9->IsFull()) val |= 0x0002; +                if (IPCFIFO7->IsEmpty())     val |= 0x0100; +                else if (IPCFIFO7->IsFull()) val |= 0x0200; +                return val; +            }          case 0x04000204: return 0;//0xFFFF; @@ -815,6 +838,27 @@ u32 ARM9Read32(u32 addr)          case 0x04000208: return IME[0];          case 0x04000210: return IE[0];          case 0x04000214: return IF[0]; + +        case 0x04100000: +            if (IPCFIFOCnt9 & 0x8000) +            { +                u32 ret; +                if (IPCFIFO7->IsEmpty()) +                { +                    IPCFIFOCnt9 |= 0x4000; +                    ret = IPCFIFO7->Peek(); +                } +                else +                { +                    ret = IPCFIFO7->Read(); + +                    if (IPCFIFO7->IsEmpty() && (IPCFIFOCnt7 & 0x0004)) +                        TriggerIRQ(1, IRQ_IPCSendDone); +                } +                return ret; +            } +            else +                return IPCFIFO7->Peek();          }          printf("unknown arm9 IO read32 %08X | %08X %08X %08X\n", addr, ARM9->R[15], ARM9->R[12], ARM9Read32(0x027FF820)); @@ -955,6 +999,18 @@ void ARM9Write16(u32 addr, u16 val)              CompensateARM7();              return; +        case 0x04000184: +            if (val & 0x0008) +                IPCFIFO9->Clear(); +            if ((val & 0x0004) && (!(IPCFIFOCnt9 & 0x0004)) && IPCFIFO9->IsEmpty()) +                TriggerIRQ(0, IRQ_IPCSendDone); +            if ((val & 0x0400) && (!(IPCFIFOCnt9 & 0x0400)) && (!IPCFIFO7->IsEmpty())) +                TriggerIRQ(0, IRQ_IPCRecv); +            if (val & 0x4000) +                IPCFIFOCnt9 &= ~0x4000; +            IPCFIFOCnt9 = val & 0x8404; +            return; +          case 0x040001A0:              ROMSPIControl = val;              return; @@ -1061,6 +1117,20 @@ void ARM9Write32(u32 addr, u32 val)              TimerStart(3, val>>16);              return; +        case 0x04000188: +            if (IPCFIFOCnt9 & 0x8000) +            { +                if (IPCFIFO9->IsFull()) +                    IPCFIFOCnt9 |= 0x4000; +                else +                { +                    IPCFIFO9->Write(val); +                    if (IPCFIFOCnt7 & 0x0400) +                        TriggerIRQ(1, IRQ_IPCRecv); +                } +            } +            return; +          case 0x040001A0:              ROMSPIControl = val & 0xFFFF;              // TODO: SPI shit @@ -1160,6 +1230,10 @@ u8 ARM7Read8(u32 addr)          case 0x04000300:              printf("ARM7 POSTFLG READ @ %08X\n", ARM7->R[15]);              return 0; + +        case 0x04000403: +            Halt(); +            return 0;          }          printf("unknown arm7 IO read8 %08X\n", addr);          return 0; @@ -1221,6 +1295,15 @@ u16 ARM7Read16(u32 addr)          case 0x04000138: return 0; // RTC shit          case 0x04000180: return IPCSync7; +        case 0x04000184: +            { +                u16 val = IPCFIFOCnt7; +                if (IPCFIFO7->IsEmpty())     val |= 0x0001; +                else if (IPCFIFO7->IsFull()) val |= 0x0002; +                if (IPCFIFO9->IsEmpty())     val |= 0x0100; +                else if (IPCFIFO9->IsFull()) val |= 0x0200; +                return val; +            }          case 0x040001C0: return SPI::ReadCnt();          case 0x040001C2: return SPI::ReadData(); @@ -1298,6 +1381,27 @@ u32 ARM7Read32(u32 addr)          case 0x04000210: return IE[1];          case 0x04000214: return IF[1]; +        case 0x04100000: +            if (IPCFIFOCnt7 & 0x8000) +            { +                u32 ret; +                if (IPCFIFO9->IsEmpty()) +                { +                    IPCFIFOCnt7 |= 0x4000; +                    ret = IPCFIFO9->Peek(); +                } +                else +                { +                    ret = IPCFIFO9->Read(); + +                    if (IPCFIFO9->IsEmpty() && (IPCFIFOCnt9 & 0x0004)) +                        TriggerIRQ(0, IRQ_IPCSendDone); +                } +                return ret; +            } +            else +                return IPCFIFO9->Peek(); +          case 0x04100010: return ROMReadData(1);          } @@ -1458,6 +1562,18 @@ void ARM7Write16(u32 addr, u16 val)              }              return; +        case 0x04000184: +            if (val & 0x0008) +                IPCFIFO7->Clear(); +            if ((val & 0x0004) && (!(IPCFIFOCnt7 & 0x0004)) && IPCFIFO7->IsEmpty()) +                TriggerIRQ(1, IRQ_IPCSendDone); +            if ((val & 0x0400) && (!(IPCFIFOCnt7 & 0x0400)) && (!IPCFIFO9->IsEmpty())) +                TriggerIRQ(1, IRQ_IPCRecv); +            if (val & 0x4000) +                IPCFIFOCnt7 &= ~0x4000; +            IPCFIFOCnt7 = val & 0x8404; +            return; +          case 0x040001A0:              ROMSPIControl = val;              return; @@ -1540,6 +1656,20 @@ void ARM7Write32(u32 addr, u32 val)              TimerStart(7, val>>16);              return; +        case 0x04000188: +            if (IPCFIFOCnt7 & 0x8000) +            { +                if (IPCFIFO7->IsFull()) +                    IPCFIFOCnt7 |= 0x4000; +                else +                { +                    IPCFIFO7->Write(val); +                    if (IPCFIFOCnt9 & 0x0400) +                        TriggerIRQ(0, IRQ_IPCRecv); +                } +            } +            return; +          case 0x040001A0:              ROMSPIControl = val & 0xFFFF;              // TODO: SPI shit |