From 566a8df6cd5af057a77cf8bed091e1b7a18bfecd Mon Sep 17 00:00:00 2001
From: Arisotura <thetotalworm@gmail.com>
Date: Sun, 16 Jun 2019 15:05:18 +0200
Subject: add IE2/IF2

---
 src/DSi.cpp | 10 ++++++++++
 src/NDS.cpp | 16 ++++++++++++++++
 src/NDS.h   | 41 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/src/DSi.cpp b/src/DSi.cpp
index ae1bed2..206c253 100644
--- a/src/DSi.cpp
+++ b/src/DSi.cpp
@@ -897,6 +897,9 @@ u16 ARM7IORead16(u32 addr)
 {
     switch (addr)
     {
+    case 0x04000218: return NDS::IE2;
+    case 0x0400021C: return NDS::IF2;
+
     case 0x04004004: return 0x0187;
     case 0x04004006: return 0; // JTAG register
     }
@@ -908,6 +911,9 @@ u32 ARM7IORead32(u32 addr)
 {
     switch (addr)
     {
+    case 0x04000218: return NDS::IE2;
+    case 0x0400021C: return NDS::IF2;
+
     case 0x04004008: return 0x80000000; // HAX
     }
 
@@ -929,6 +935,8 @@ void ARM7IOWrite16(u32 addr, u16 val)
 {
     switch (addr)
     {
+    case 0x04000218: NDS::IE2 = (val & 0x7FF7); NDS::UpdateIRQ(1); return;
+    case 0x0400021C: NDS::IF2 &= ~(val & 0x7FF7); NDS::UpdateIRQ(1); return;
     }
 
     return NDS::ARM7IOWrite16(addr, val);
@@ -938,6 +946,8 @@ void ARM7IOWrite32(u32 addr, u32 val)
 {
     switch (addr)
     {
+    case 0x04000218: NDS::IE2 = (val & 0x7FF7); NDS::UpdateIRQ(1); return;
+    case 0x0400021C: NDS::IF2 &= ~(val & 0x7FF7); NDS::UpdateIRQ(1); return;
     }
 
     return NDS::ARM7IOWrite32(addr, val);
diff --git a/src/NDS.cpp b/src/NDS.cpp
index c285910..5ca55f3 100644
--- a/src/NDS.cpp
+++ b/src/NDS.cpp
@@ -107,6 +107,7 @@ u8 ROMSeed1[2*8];
 // IO shit
 u32 IME[2];
 u32 IE[2], IF[2];
+u32 IE2, IF2;
 
 u8 PostFlag9;
 u8 PostFlag7;
@@ -462,6 +463,8 @@ void Reset()
     IME[1] = 0;
     IE[1] = 0;
     IF[1] = 0;
+    IE2 = 0;
+    IF2 = 0;
 
     PostFlag9 = 0x00;
     PostFlag7 = 0x00;
@@ -1067,6 +1070,7 @@ void UpdateIRQ(u32 cpu)
     if (IME[cpu] & 0x1)
     {
         arm->IRQ = IE[cpu] & IF[cpu];
+        if (cpu) arm->IRQ |= (IE2 & IF2);
     }
     else
     {
@@ -1086,6 +1090,18 @@ void ClearIRQ(u32 cpu, u32 irq)
     UpdateIRQ(cpu);
 }
 
+void SetIRQ2(u32 irq)
+{
+    IF2 |= (1 << irq);
+    UpdateIRQ(1);
+}
+
+void ClearIRQ2(u32 irq)
+{
+    IF2 &= ~(1 << irq);
+    UpdateIRQ(1);
+}
+
 bool HaltInterrupted(u32 cpu)
 {
     if (cpu == 0)
diff --git a/src/NDS.h b/src/NDS.h
index e8bb44d..e6cd2ee 100644
--- a/src/NDS.h
+++ b/src/NDS.h
@@ -74,12 +74,42 @@ enum
     IRQ_IPCSync,
     IRQ_IPCSendDone,
     IRQ_IPCRecv,
-    IRQ_CartSendDone,
-    IRQ_CartIREQMC,
+    IRQ_CartSendDone, // TODO: less misleading name
+    IRQ_CartIREQMC,   // IRQ triggered by game cart (example: Pok�mon Typing Adventure, BT controller)
     IRQ_GXFIFO,
     IRQ_LidOpen,
     IRQ_SPI,
-    IRQ_Wifi
+    IRQ_Wifi,
+
+    // DSi IRQs
+    IRQ_DSi_DSP = 24,
+    IRQ_DSi_Camera,
+    IRQ_DSi_Unk26,
+    IRQ_DSi_Unk27,
+    IRQ_DSi_NDMA0,
+    IRQ_DSi_NDMA1,
+    IRQ_DSi_NDMA2,
+    IRQ_DSi_NDMA3,
+};
+
+enum
+{
+    // DSi ARM7-side IE2/IF2
+    IRQ2_DSi_GPIO18_0 = 0,
+    IRQ2_DSi_GPIO18_1,
+    IRQ2_DSi_GPIO18_2,
+    IRQ2_DSi_Unused35,
+    IRQ2_DSi_GPIO33_0,
+    IRQ2_DSi_Headphone,
+    IRQ2_DSi_PowerButton,
+    IRQ2_DSi_GPIO33_3, // "sound enable input"
+    IRQ2_DSi_SDMMC,
+    IRQ2_DSi_SD_Data1,
+    IRQ2_DSi_SDIO,
+    IRQ2_DSi_SDIO_Data1,
+    IRQ2_DSi_AES,
+    IRQ2_DSi_I2C,
+    IRQ2_DSi_MicExt
 };
 
 typedef struct
@@ -109,6 +139,8 @@ extern u32 ARM9ClockShift;
 extern u32 IME[2];
 extern u32 IE[2];
 extern u32 IF[2];
+extern u32 IE2;
+extern u32 IF2;
 extern Timer Timers[8];
 
 extern u16 PowerControl9;
@@ -162,8 +194,11 @@ void Halt();
 
 void MapSharedWRAM(u8 val);
 
+void UpdateIRQ(u32 cpu);
 void SetIRQ(u32 cpu, u32 irq);
 void ClearIRQ(u32 cpu, u32 irq);
+void SetIRQ2(u32 irq);
+void ClearIRQ2(u32 irq);
 bool HaltInterrupted(u32 cpu);
 void StopCPU(u32 cpu, u32 mask);
 void ResumeCPU(u32 cpu, u32 mask);
-- 
cgit v1.2.3