diff options
author | StapleButter <thetotalworm@gmail.com> | 2016-12-04 03:20:50 +0100 |
---|---|---|
committer | StapleButter <thetotalworm@gmail.com> | 2016-12-04 03:20:50 +0100 |
commit | a14c01208a6be3cc57586d24e007c74652dc467d (patch) | |
tree | 021eb77973c2bd48895f24c75ef48a0ce7de7646 /SPI.cpp | |
parent | d7c1d77ba2c9339685aadc2d0967763952fec85f (diff) |
fix some shit. add support for SPI and firmware.
Diffstat (limited to 'SPI.cpp')
-rw-r--r-- | SPI.cpp | 158 |
1 files changed, 158 insertions, 0 deletions
@@ -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); +} + +} |