diff --git a/DMA.cpp b/DMA.cpp index 4b97b2fb..cd7bf4d6 100644 --- a/DMA.cpp +++ b/DMA.cpp @@ -106,7 +106,7 @@ void DMA::Start() if ((Cnt & 0x00060000) == 0x00060000) CurDstAddr = DstAddr; - printf("ARM%d DMA%d %08X %08X->%08X %d bytes %dbit\n", CPU?7:9, Num, Cnt, CurSrcAddr, CurDstAddr, RemCount*((Cnt & 0x04000000)?2:4), (Cnt & 0x04000000)?16:32); + //printf("ARM%d DMA%d %08X %08X->%08X %d bytes %dbit\n", CPU?7:9, Num, Cnt, CurSrcAddr, CurDstAddr, RemCount*((Cnt & 0x04000000)?2:4), (Cnt & 0x04000000)?16:32); // TODO: NOT MAKE THE DMA INSTANT!! if (!(Cnt & 0x04000000)) diff --git a/GPU2D.cpp b/GPU2D.cpp index 6b954bf8..12ed1667 100644 --- a/GPU2D.cpp +++ b/GPU2D.cpp @@ -89,9 +89,11 @@ void GPU2D::Write16(u32 addr, u16 val) { case 0x000: DispCnt = (DispCnt & 0xFFFF0000) | val; + printf("[L] DISPCNT=%08X\n", DispCnt); return; case 0x002: DispCnt = (DispCnt & 0x0000FFFF) | (val << 16); + printf("[H] DISPCNT=%08X\n", DispCnt); return; case 0x008: BGCnt[0] = val; return; @@ -108,6 +110,7 @@ void GPU2D::Write32(u32 addr, u32 val) switch (addr & 0x00000FFF) { case 0x000: + printf("DISPCNT=%08X\n", val); DispCnt = val; return; } @@ -159,18 +162,40 @@ void GPU2D::DrawScanline(u32 line) void GPU2D::DrawScanline_Mode1(u32 line, u16* dst) { + u32 backdrop; + if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; + else backdrop = *(u16*)&GPU::Palette[0]; + + // TODO: color effect for backdrop + + backdrop |= (backdrop<<16); for (int i = 0; i < 256>>1; i++) - ((u32*)dst)[i] = 0; // TODO: backdrop + ((u32*)dst)[i] = backdrop; switch (DispCnt & 0x7) { case 0: + //printf("disp %08X %04X %04X %04X %04X\n", DispCnt, BGCnt[0], BGCnt[1], BGCnt[2], BGCnt[3]); for (int i = 3; i >= 0; i--) { - // TODO other BGs + if ((BGCnt[3] & 0x3) == i) + { + if (DispCnt & 0x0800) DrawBG_Text_4bpp(line, dst, 3); + // todo: sprites + } + if ((BGCnt[2] & 0x3) == i) + { + if (DispCnt & 0x0400) DrawBG_Text_4bpp(line, dst, 2); + // todo: sprites + } + if ((BGCnt[1] & 0x3) == i) + { + if (DispCnt & 0x0200) DrawBG_Text_4bpp(line, dst, 1); + // todo: sprites + } if ((BGCnt[0] & 0x3) == i) { - DrawBG_Text_4bpp(line, dst, 0); + if (DispCnt & 0x0100) DrawBG_Text_4bpp(line, dst, 0); // todo: sprites } } @@ -259,7 +284,8 @@ void GPU2D::DrawBG_Text_4bpp(u32 line, u16* dst, u32 bgnum) } //color = (i >> 4) + ((line >> 4) << 4); //if (Num) color = 0; - dst[i] = curpal[color]; + if (color) + dst[i] = curpal[color]; xoff++; } diff --git a/NDS.cpp b/NDS.cpp index d0fcbb7e..8a7a8840 100644 --- a/NDS.cpp +++ b/NDS.cpp @@ -25,6 +25,7 @@ #include "FIFO.h" #include "GPU.h" #include "SPI.h" +#include "RTC.h" #include "Wifi.h" // derp @@ -128,6 +129,7 @@ void Init() GPU::Init(); SPI::Init(); + RTC::Init(); Reset(); } @@ -248,6 +250,7 @@ void Reset() GPU::Reset(); SPI::Reset(); + RTC::Reset(); Wifi::Reset(); memset(SchedBuffer, 0, sizeof(SchedEvent)*SCHED_BUF_LEN); @@ -1022,6 +1025,7 @@ void ARM9Write16(u32 addr, u16 val) void ARM9Write32(u32 addr, u32 val) { if (addr == ARM9->R[15]) printf("!!!!!!!!!!!!9999 %08X %08X\n", addr, val); + if (addr == 0x023549F0) printf("%08X STATE=%08X\n", ARM9->R[15], val); if (addr < ARM9ITCMSize) { *(u32*)&ARM9ITCM[addr & 0x7FFF] = val; @@ -1203,6 +1207,7 @@ u32 ARM7Read32(u32 addr) void ARM7Write8(u32 addr, u8 val) { if (addr==0x3807764) printf("DERP! %02X %08X\n", val, ARM7->R[15]); + if (addr==0x27FFCE4) printf("FIRMWARE STATUS8 %04X %08X\n", val, ARM7->R[15]); switch (addr & 0xFF800000) { case 0x02000000: @@ -1240,6 +1245,8 @@ void ARM7Write16(u32 addr, u16 val) { if (addr == ARM7->R[15]) printf("!!!!!!!!!!!!7777 %08X %04X\n", addr, val); if (addr==0x3807764) printf("DERP! %04X %08X\n", val, ARM7->R[15]); + if (addr==0x27FF816) printf("RTC STATUS %04X %08X\n", val, ARM7->R[15]); + if (addr==0x27FFCE4) printf("FIRMWARE STATUS %04X %08X\n", val, ARM7->R[15]); switch (addr & 0xFF800000) { case 0x02000000: @@ -1280,7 +1287,7 @@ void ARM7Write16(u32 addr, u16 val) void ARM7Write32(u32 addr, u32 val) { if (addr == ARM7->R[15]) printf("!!!!!!!!!!!!7777 %08X %08X\n", addr, val); - +if (addr==0x27FFCE4) printf("FIRMWARE STATUS32 %08X %08X\n", val, ARM7->R[15]); switch (addr & 0xFF800000) { case 0x02000000: @@ -1689,7 +1696,7 @@ void ARM9IOWrite32(u32 addr, u32 val) return; case 0x04000208: IME[0] = val & 0x1; return; - case 0x04000210: IE[0] = val; return; + case 0x04000210: IE[0] = val; if (val&~0x000F0F7D)printf("unusual IRQ %08X\n",val);return; case 0x04000214: IF[0] &= ~val; return; case 0x04000240: @@ -1734,7 +1741,7 @@ u8 ARM7IORead8(u32 addr) { switch (addr) { - case 0x04000138: return 0; // RTC shit + case 0x04000138: return RTC::Read() & 0xFF; case 0x040001C2: return SPI::ReadData(); @@ -1749,6 +1756,7 @@ u8 ARM7IORead8(u32 addr) //Halt(); //return 0; } + if (addr >= 0x04000400 && addr < 0x04000520) { // sound I/O @@ -1779,7 +1787,7 @@ u16 ARM7IORead16(u32 addr) case 0x04000136: return KeyInput >> 16; case 0x04000134: return 0x8000; - case 0x04000138: return 0; // RTC shit. TODO!! + case 0x04000138: return RTC::Read(); case 0x04000180: return IPCSync7; case 0x04000184: @@ -1803,6 +1811,12 @@ u16 ARM7IORead16(u32 addr) case 0x04000504: return _soundbias; } + if (addr >= 0x04000400 && addr < 0x04000520) + { + // sound I/O + return 0; + } + printf("unknown ARM7 IO read16 %08X %08X\n", addr, ARM9->R[15]); return 0; } @@ -1865,6 +1879,12 @@ u32 ARM7IORead32(u32 addr) case 0x04100010: return ROMReadData(1); } + if (addr >= 0x04000400 && addr < 0x04000520) + { + // sound I/O + return 0; + } + printf("unknown ARM7 IO read32 %08X\n", addr); return 0; } @@ -1873,8 +1893,7 @@ void ARM7IOWrite8(u32 addr, u8 val) { switch (addr) { - case 0x04000138: - return; + case 0x04000138: RTC::Write(val, true); return; case 0x040001A0: ROMSPIControl &= 0xFF00; @@ -1912,6 +1931,12 @@ void ARM7IOWrite8(u32 addr, u8 val) return; } + if (addr >= 0x04000400 && addr < 0x04000520) + { + // sound I/O + return; + } + printf("unknown ARM7 IO write8 %08X %02X\n", addr, val); } @@ -1932,7 +1957,7 @@ void ARM7IOWrite16(u32 addr, u16 val) case 0x04000134: return;printf("set debug port %04X %08X\n", val, ARM7Read32(ARM7->R[13]+4)); return; - case 0x04000138: return; // RTC shit. TODO + case 0x04000138: RTC::Write(val, false); return; case 0x04000180: IPCSync9 &= 0xFFF0; @@ -1985,6 +2010,12 @@ void ARM7IOWrite16(u32 addr, u16 val) return; } + if (addr >= 0x04000400 && addr < 0x04000520) + { + // sound I/O + return; + } + printf("unknown ARM7 IO write16 %08X %04X\n", addr, val); } @@ -2052,6 +2083,12 @@ void ARM7IOWrite32(u32 addr, u32 val) case 0x04000214: IF[1] &= ~val; return; } + if (addr >= 0x04000400 && addr < 0x04000520) + { + // sound I/O + return; + } + printf("unknown ARM7 IO write32 %08X %08X\n", addr, val); } diff --git a/RTC.cpp b/RTC.cpp new file mode 100644 index 00000000..5dbe5065 --- /dev/null +++ b/RTC.cpp @@ -0,0 +1,250 @@ +/* + Copyright 2016-2017 StapleButter + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include "RTC.h" + + +namespace RTC +{ + +u16 IO; + +u8 Input; +u32 InputBit; +u32 InputPos; + +u8 Output[8]; +u32 OutputBit; +u32 OutputPos; + +u8 CurCmd; + +u8 StatusReg1; +u8 StatusReg2; +u8 Alarm1[3]; +u8 Alarm2[3]; +u8 ClockAdjust; +u8 FreeReg; + + +void Init() +{ +} + +void Reset() +{ + Input = 0; + InputBit = 0; + InputPos = 0; + + memset(Output, 0, sizeof(Output)); + OutputPos = 0; + + CurCmd = 0; + + StatusReg1 = 0; + StatusReg2 = 0; + memset(Alarm1, 0, sizeof(Alarm1)); + memset(Alarm2, 0, sizeof(Alarm2)); + ClockAdjust = 0; + FreeReg = 0; +} + + +void ByteIn(u8 val) +{ + //printf("RTC IN: %02X\n", val); + if (InputPos == 0) + { + if ((val & 0xF0) == 0x60) + { + u8 rev[16] = {0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6}; + CurCmd = rev[val & 0xF]; + } + else + CurCmd = val; + + if (CurCmd & 0x80) + { + switch (CurCmd & 0x70) + { + case 0x00: Output[0] = StatusReg1; break; + case 0x40: Output[0] = StatusReg2; break; + + case 0x20: + // TODO: get actual system time + Output[0] = 0x16; + Output[1] = 0x01; + Output[2] = 0x19; + Output[3] = 0x03; // day of week. checkme + Output[4] = 0x06; + Output[5] = 0x30; + Output[6] = 0x30; + break; + + case 0x60: + // TODO: get actual system time + Output[0] = 0x06; + Output[1] = 0x30; + Output[2] = 0x30; + break; + + case 0x10: + if (StatusReg2 & 0x04) + { + Output[0] = Alarm1[0]; + Output[1] = Alarm1[1]; + Output[2] = Alarm1[2]; + } + else + Output[0] = Alarm1[2]; + break; + + case 0x50: + Output[0] = Alarm2[0]; + Output[1] = Alarm2[1]; + Output[2] = Alarm2[2]; + break; + + case 0x30: Output[0] = ClockAdjust; break; + case 0x70: Output[0] = FreeReg; break; + } + } + InputPos++; + return; + } + + switch (CurCmd & 0x70) + { + case 0x00: + if (InputPos == 1) StatusReg1 = val & 0x0E; + break; + + case 0x40: + if (InputPos == 1) StatusReg2 = val; + if (StatusReg2 & 0x4F) printf("RTC INTERRUPT ON: %02X\n", StatusReg2); + break; + + case 0x20: + // TODO: set time somehow?? + break; + + case 0x60: + // same shit + break; + + case 0x10: + if (StatusReg2 & 0x04) + { + if (InputPos <= 3) Alarm1[InputPos-1] = val; + } + else + { + if (InputPos == 1) Alarm1[2] = val; + } + break; + + case 0x50: + if (InputPos <= 3) Alarm2[InputPos-1] = val; + break; + + case 0x30: + if (InputPos == 1) ClockAdjust = val; + break; + + case 0x70: + if (InputPos == 1) FreeReg = val; + break; + } + + InputPos++; +} + + +u16 Read() +{ + //printf("RTC READ %04X\n", IO); + return IO; +} + +void Write(u16 val, bool byte) +{ + if (byte) val |= (IO & 0xFF00); + + //printf("RTC WRITE %04X\n", val); + if (val & 0x0004) + { + if (!(IO & 0x0004)) + { + // start transfer + Input = 0; + InputBit = 0; + InputPos = 0; + + memset(Output, 0, sizeof(Output)); + OutputBit = 0; + OutputPos = 0; + } + else + { + if (!(val & 0x0002)) // clock low + { + if (val & 0x0010) + { + // write + if (val & 0x0001) + Input |= (1<= 8) + { + InputBit = 0; + ByteIn(Input); + Input = 0; + InputPos++; + } + } + else + { + // read + if (Output[OutputPos] & (1<= 8) + { + OutputBit = 0; + if (OutputPos < 7) + OutputPos++; + } + } + } + } + } + + if (val & 0x0010) + IO = val; + else + IO = (IO & 0x0001) | (val & 0xFFFE); +} + +} diff --git a/RTC.h b/RTC.h new file mode 100644 index 00000000..b61dbabc --- /dev/null +++ b/RTC.h @@ -0,0 +1,35 @@ +/* + Copyright 2016-2017 StapleButter + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef RTC_H +#define RTC_H + +#include "types.h" + +namespace RTC +{ + +void Init(); +void Reset(); + +u16 Read(); +void Write(u16 val, bool byte); + +} + +#endif diff --git a/SPI.cpp b/SPI.cpp index 3a7001aa..ce68055f 100644 --- a/SPI.cpp +++ b/SPI.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "NDS.h" #include "SPI.h" @@ -185,6 +186,80 @@ void Write(u8 val, u32 hold) } +namespace SPI_Powerman +{ + +u32 Hold; +u32 DataPos; +u8 Index; +u8 Data; + +u8 Registers[8]; +u8 RegMasks[8]; + + +void Init() +{ +} + +void Reset() +{ + Hold = 0; + Index = 0; + Data = 0; + + memset(Registers, 0, sizeof(Registers)); + memset(RegMasks, 0, sizeof(RegMasks)); + + Registers[4] = 0x40; + + RegMasks[0] = 0x7F; + RegMasks[1] = 0x01; + RegMasks[2] = 0x01; + RegMasks[3] = 0x03; + RegMasks[4] = 0x0F; +} + +u8 Read() +{ + return Data; +} + +void Write(u8 val, u32 hold) +{ + if (!hold) + { + Hold = 0; + } + + if (hold && (!Hold)) + { + Index = val; + Hold = 1; + Data = 0; + DataPos = 1; + return; + } + + if (DataPos == 1) + { + if (Index & 0x80) + { + Data = Registers[Index & 0x07]; + } + else + { + Registers[Index & 0x07] = + (Registers[Index & 0x07] & ~RegMasks[Index & 0x07]) | + (val & RegMasks[Index & 0x07]); + } + } + else + Data = 0; +} + +} + namespace SPI { @@ -197,6 +272,7 @@ u32 CurDevice; void Init() { SPI_Firmware::Init(); + SPI_Powerman::Init(); } void Reset() @@ -204,6 +280,7 @@ void Reset() CNT = 0; SPI_Firmware::Reset(); + SPI_Powerman::Reset(); } @@ -224,6 +301,7 @@ u8 ReadData() switch (CNT & 0x0300) { + case 0x0000: return SPI_Powerman::Read(); case 0x0100: return SPI_Firmware::Read(); default: return 0; } @@ -237,8 +315,9 @@ void WriteData(u8 val) switch (CNT & 0x0300) { + case 0x0000: SPI_Powerman::Write(val, CNT&(1<<11)); break; case 0x0100: SPI_Firmware::Write(val, CNT&(1<<11)); break; - default: printf("SPI to unknown device %04X %02X\n", CNT, val); break; + default: break;//printf("SPI to unknown device %04X %02X\n", CNT, val); break; } if (CNT & (1<<14)) diff --git a/melonDS.cbp b/melonDS.cbp index 107ed3db..b16429d0 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -28,6 +28,7 @@ + @@ -52,10 +53,14 @@ + + + + diff --git a/melonDS.depend b/melonDS.depend index 88c83024..7b5eeb1c 100644 --- a/melonDS.depend +++ b/melonDS.depend @@ -10,7 +10,7 @@ 1481161027 c:\documents\sources\melonds\types.h -1484758082 source:c:\documents\sources\melonds\nds.cpp +1484868036 source:c:\documents\sources\melonds\nds.cpp "NDS.h" @@ -20,9 +20,10 @@ "FIFO.h" "GPU.h" "SPI.h" + "RTC.h" "Wifi.h" -1484754523 source:c:\documents\sources\melonds\arm.cpp +1484870885 source:c:\documents\sources\melonds\arm.cpp "NDS.h" "ARM.h" @@ -76,12 +77,13 @@ 1480957111 c:\documents\sources\melonds\spi.h -1484524946 source:c:\documents\sources\melonds\spi.cpp +1484762789 source:c:\documents\sources\melonds\spi.cpp + "NDS.h" "SPI.h" -1484758294 source:c:\documents\sources\melonds\gpu2d.cpp +1484870914 source:c:\documents\sources\melonds\gpu2d.cpp "NDS.h" @@ -103,7 +105,7 @@ 1484612398 c:\documents\sources\melonds\fifo.h "types.h" -1484756268 source:c:\documents\sources\melonds\dma.cpp +1484762586 source:c:\documents\sources\melonds\dma.cpp "NDS.h" "DMA.h" @@ -120,3 +122,11 @@ 1484709419 c:\documents\sources\melonds\gpu.h "GPU2D.h" +1484848282 c:\documents\sources\melonds\rtc.h + "types.h" + +1484870861 source:c:\documents\sources\melonds\rtc.cpp + + + "RTC.h" +