aboutsummaryrefslogtreecommitdiff
path: root/SPI.cpp
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2016-12-04 03:20:50 +0100
committerStapleButter <thetotalworm@gmail.com>2016-12-04 03:20:50 +0100
commita14c01208a6be3cc57586d24e007c74652dc467d (patch)
tree021eb77973c2bd48895f24c75ef48a0ce7de7646 /SPI.cpp
parentd7c1d77ba2c9339685aadc2d0967763952fec85f (diff)
fix some shit. add support for SPI and firmware.
Diffstat (limited to 'SPI.cpp')
-rw-r--r--SPI.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/SPI.cpp b/SPI.cpp
new file mode 100644
index 0000000..40bbf11
--- /dev/null
+++ b/SPI.cpp
@@ -0,0 +1,158 @@
+#include <stdio.h>
+#include "NDS.h"
+#include "SPI.h"
+
+
+namespace SPI_Firmware
+{
+
+u8* Firmware;
+u32 FirmwareLength;
+
+u32 Hold;
+u8 CurCmd;
+u32 DataPos;
+u8 Data;
+
+u32 Addr;
+
+void Init()
+{
+ Firmware = NULL;
+}
+
+void Reset()
+{
+ if (Firmware) delete[] Firmware;
+
+ FILE* f = fopen("firmware.bin", "rb");
+ fseek(f, 0, SEEK_END);
+ FirmwareLength = (u32)ftell(f);
+ Firmware = new u8[FirmwareLength];
+
+ fseek(f, 0, SEEK_SET);
+ fread(Firmware, FirmwareLength, 1, f);
+
+ fclose(f);
+
+ Hold = 0;
+ CurCmd = 0;
+ Data = 0;
+}
+
+u8 Read()
+{
+ return Data;
+}
+
+void Write(u8 val, u32 hold)
+{
+ if (!hold)
+ {
+ Hold = 0;
+ }
+
+ if (hold && (!Hold))
+ {
+ CurCmd = val;
+ Hold = 1;
+ DataPos = 1;
+ Addr = 0;
+ printf("firmware SPI command %02X\n", CurCmd);
+ return;
+ }
+
+ switch (CurCmd)
+ {
+ case 0x03: // read
+ {
+ if (DataPos < 4)
+ {
+ Addr <<= 8;
+ Addr |= val;
+ Data = 0;
+
+ if (DataPos == 3) printf("firmware SPI read %08X\n", Addr);
+ }
+ else
+ {
+ if (Addr >= FirmwareLength)
+ Data = 0;
+ else
+ Data = Firmware[Addr];
+
+ Addr++;
+ }
+
+ DataPos++;
+ }
+ break;
+
+ default:
+ printf("unknown firmware SPI command %02X\n", CurCmd);
+ break;
+ }
+}
+
+}
+
+
+namespace SPI
+{
+
+u16 CNT;
+
+u32 CurDevice;
+
+
+void Init()
+{
+ SPI_Firmware::Init();
+}
+
+void Reset()
+{
+ CNT = 0;
+
+ SPI_Firmware::Reset();
+}
+
+
+u16 ReadCnt()
+{
+ return CNT;
+}
+
+void WriteCnt(u16 val)
+{
+ CNT = val & 0xCF03;
+ if (val & 0x0400) printf("!! CRAPOED 16BIT SPI MODE\n");
+}
+
+u8 ReadData()
+{
+ if (!(CNT & (1<<15))) return 0;
+
+ switch (CNT & 0x0300)
+ {
+ case 0x0100: return SPI_Firmware::Read();
+ default: return 0;
+ }
+}
+
+void WriteData(u8 val)
+{
+ if (!(CNT & (1<<15))) return;
+
+ // TODO: take delays into account
+
+ switch (CNT & 0x0300)
+ {
+ case 0x0100: SPI_Firmware::Write(val, CNT&(1<<11)); break;
+ }
+
+ if (CNT & (1<<14))
+ NDS::TriggerIRQ(1, NDS::IRQ_SPI);
+}
+
+}