* some basic BG display code
* basic, frozen-in-time RTC * power management device
This commit is contained in:
parent
d7c1d2a2cd
commit
3e5e8f60c4
2
DMA.cpp
2
DMA.cpp
|
@ -106,7 +106,7 @@ void DMA::Start()
|
||||||
if ((Cnt & 0x00060000) == 0x00060000)
|
if ((Cnt & 0x00060000) == 0x00060000)
|
||||||
CurDstAddr = DstAddr;
|
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!!
|
// TODO: NOT MAKE THE DMA INSTANT!!
|
||||||
if (!(Cnt & 0x04000000))
|
if (!(Cnt & 0x04000000))
|
||||||
|
|
34
GPU2D.cpp
34
GPU2D.cpp
|
@ -89,9 +89,11 @@ void GPU2D::Write16(u32 addr, u16 val)
|
||||||
{
|
{
|
||||||
case 0x000:
|
case 0x000:
|
||||||
DispCnt = (DispCnt & 0xFFFF0000) | val;
|
DispCnt = (DispCnt & 0xFFFF0000) | val;
|
||||||
|
printf("[L] DISPCNT=%08X\n", DispCnt);
|
||||||
return;
|
return;
|
||||||
case 0x002:
|
case 0x002:
|
||||||
DispCnt = (DispCnt & 0x0000FFFF) | (val << 16);
|
DispCnt = (DispCnt & 0x0000FFFF) | (val << 16);
|
||||||
|
printf("[H] DISPCNT=%08X\n", DispCnt);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x008: BGCnt[0] = val; return;
|
case 0x008: BGCnt[0] = val; return;
|
||||||
|
@ -108,6 +110,7 @@ void GPU2D::Write32(u32 addr, u32 val)
|
||||||
switch (addr & 0x00000FFF)
|
switch (addr & 0x00000FFF)
|
||||||
{
|
{
|
||||||
case 0x000:
|
case 0x000:
|
||||||
|
printf("DISPCNT=%08X\n", val);
|
||||||
DispCnt = val;
|
DispCnt = val;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -159,18 +162,40 @@ void GPU2D::DrawScanline(u32 line)
|
||||||
|
|
||||||
void GPU2D::DrawScanline_Mode1(u32 line, u16* dst)
|
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++)
|
for (int i = 0; i < 256>>1; i++)
|
||||||
((u32*)dst)[i] = 0; // TODO: backdrop
|
((u32*)dst)[i] = backdrop;
|
||||||
|
|
||||||
switch (DispCnt & 0x7)
|
switch (DispCnt & 0x7)
|
||||||
{
|
{
|
||||||
case 0:
|
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--)
|
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)
|
if ((BGCnt[0] & 0x3) == i)
|
||||||
{
|
{
|
||||||
DrawBG_Text_4bpp(line, dst, 0);
|
if (DispCnt & 0x0100) DrawBG_Text_4bpp(line, dst, 0);
|
||||||
// todo: sprites
|
// todo: sprites
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,7 +284,8 @@ void GPU2D::DrawBG_Text_4bpp(u32 line, u16* dst, u32 bgnum)
|
||||||
}
|
}
|
||||||
//color = (i >> 4) + ((line >> 4) << 4);
|
//color = (i >> 4) + ((line >> 4) << 4);
|
||||||
//if (Num) color = 0;
|
//if (Num) color = 0;
|
||||||
dst[i] = curpal[color];
|
if (color)
|
||||||
|
dst[i] = curpal[color];
|
||||||
|
|
||||||
xoff++;
|
xoff++;
|
||||||
}
|
}
|
||||||
|
|
51
NDS.cpp
51
NDS.cpp
|
@ -25,6 +25,7 @@
|
||||||
#include "FIFO.h"
|
#include "FIFO.h"
|
||||||
#include "GPU.h"
|
#include "GPU.h"
|
||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
|
#include "RTC.h"
|
||||||
#include "Wifi.h"
|
#include "Wifi.h"
|
||||||
|
|
||||||
// derp
|
// derp
|
||||||
|
@ -128,6 +129,7 @@ void Init()
|
||||||
|
|
||||||
GPU::Init();
|
GPU::Init();
|
||||||
SPI::Init();
|
SPI::Init();
|
||||||
|
RTC::Init();
|
||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
@ -248,6 +250,7 @@ void Reset()
|
||||||
|
|
||||||
GPU::Reset();
|
GPU::Reset();
|
||||||
SPI::Reset();
|
SPI::Reset();
|
||||||
|
RTC::Reset();
|
||||||
Wifi::Reset();
|
Wifi::Reset();
|
||||||
|
|
||||||
memset(SchedBuffer, 0, sizeof(SchedEvent)*SCHED_BUF_LEN);
|
memset(SchedBuffer, 0, sizeof(SchedEvent)*SCHED_BUF_LEN);
|
||||||
|
@ -1022,6 +1025,7 @@ void ARM9Write16(u32 addr, u16 val)
|
||||||
void ARM9Write32(u32 addr, u32 val)
|
void ARM9Write32(u32 addr, u32 val)
|
||||||
{
|
{
|
||||||
if (addr == ARM9->R[15]) printf("!!!!!!!!!!!!9999 %08X %08X\n", addr, 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)
|
if (addr < ARM9ITCMSize)
|
||||||
{
|
{
|
||||||
*(u32*)&ARM9ITCM[addr & 0x7FFF] = val;
|
*(u32*)&ARM9ITCM[addr & 0x7FFF] = val;
|
||||||
|
@ -1203,6 +1207,7 @@ u32 ARM7Read32(u32 addr)
|
||||||
void ARM7Write8(u32 addr, u8 val)
|
void ARM7Write8(u32 addr, u8 val)
|
||||||
{
|
{
|
||||||
if (addr==0x3807764) printf("DERP! %02X %08X\n", val, ARM7->R[15]);
|
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)
|
switch (addr & 0xFF800000)
|
||||||
{
|
{
|
||||||
case 0x02000000:
|
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 == ARM7->R[15]) printf("!!!!!!!!!!!!7777 %08X %04X\n", addr, val);
|
||||||
if (addr==0x3807764) printf("DERP! %04X %08X\n", val, ARM7->R[15]);
|
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)
|
switch (addr & 0xFF800000)
|
||||||
{
|
{
|
||||||
case 0x02000000:
|
case 0x02000000:
|
||||||
|
@ -1280,7 +1287,7 @@ void ARM7Write16(u32 addr, u16 val)
|
||||||
void ARM7Write32(u32 addr, u32 val)
|
void ARM7Write32(u32 addr, u32 val)
|
||||||
{
|
{
|
||||||
if (addr == ARM7->R[15]) printf("!!!!!!!!!!!!7777 %08X %08X\n", addr, 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)
|
switch (addr & 0xFF800000)
|
||||||
{
|
{
|
||||||
case 0x02000000:
|
case 0x02000000:
|
||||||
|
@ -1689,7 +1696,7 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x04000208: IME[0] = val & 0x1; 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 0x04000214: IF[0] &= ~val; return;
|
||||||
|
|
||||||
case 0x04000240:
|
case 0x04000240:
|
||||||
|
@ -1734,7 +1741,7 @@ u8 ARM7IORead8(u32 addr)
|
||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x04000138: return 0; // RTC shit
|
case 0x04000138: return RTC::Read() & 0xFF;
|
||||||
|
|
||||||
case 0x040001C2: return SPI::ReadData();
|
case 0x040001C2: return SPI::ReadData();
|
||||||
|
|
||||||
|
@ -1749,6 +1756,7 @@ u8 ARM7IORead8(u32 addr)
|
||||||
//Halt();
|
//Halt();
|
||||||
//return 0;
|
//return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr >= 0x04000400 && addr < 0x04000520)
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
{
|
{
|
||||||
// sound I/O
|
// sound I/O
|
||||||
|
@ -1779,7 +1787,7 @@ u16 ARM7IORead16(u32 addr)
|
||||||
case 0x04000136: return KeyInput >> 16;
|
case 0x04000136: return KeyInput >> 16;
|
||||||
|
|
||||||
case 0x04000134: return 0x8000;
|
case 0x04000134: return 0x8000;
|
||||||
case 0x04000138: return 0; // RTC shit. TODO!!
|
case 0x04000138: return RTC::Read();
|
||||||
|
|
||||||
case 0x04000180: return IPCSync7;
|
case 0x04000180: return IPCSync7;
|
||||||
case 0x04000184:
|
case 0x04000184:
|
||||||
|
@ -1803,6 +1811,12 @@ u16 ARM7IORead16(u32 addr)
|
||||||
case 0x04000504: return _soundbias;
|
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]);
|
printf("unknown ARM7 IO read16 %08X %08X\n", addr, ARM9->R[15]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1865,6 +1879,12 @@ u32 ARM7IORead32(u32 addr)
|
||||||
case 0x04100010: return ROMReadData(1);
|
case 0x04100010: return ROMReadData(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
|
{
|
||||||
|
// sound I/O
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
printf("unknown ARM7 IO read32 %08X\n", addr);
|
printf("unknown ARM7 IO read32 %08X\n", addr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1873,8 +1893,7 @@ void ARM7IOWrite8(u32 addr, u8 val)
|
||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case 0x04000138:
|
case 0x04000138: RTC::Write(val, true); return;
|
||||||
return;
|
|
||||||
|
|
||||||
case 0x040001A0:
|
case 0x040001A0:
|
||||||
ROMSPIControl &= 0xFF00;
|
ROMSPIControl &= 0xFF00;
|
||||||
|
@ -1912,6 +1931,12 @@ void ARM7IOWrite8(u32 addr, u8 val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
|
{
|
||||||
|
// sound I/O
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
printf("unknown ARM7 IO write8 %08X %02X\n", addr, val);
|
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 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:
|
case 0x04000180:
|
||||||
IPCSync9 &= 0xFFF0;
|
IPCSync9 &= 0xFFF0;
|
||||||
|
@ -1985,6 +2010,12 @@ void ARM7IOWrite16(u32 addr, u16 val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr >= 0x04000400 && addr < 0x04000520)
|
||||||
|
{
|
||||||
|
// sound I/O
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
printf("unknown ARM7 IO write16 %08X %04X\n", addr, val);
|
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;
|
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);
|
printf("unknown ARM7 IO write32 %08X %08X\n", addr, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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<<InputBit);
|
||||||
|
|
||||||
|
InputBit++;
|
||||||
|
if (InputBit >= 8)
|
||||||
|
{
|
||||||
|
InputBit = 0;
|
||||||
|
ByteIn(Input);
|
||||||
|
Input = 0;
|
||||||
|
InputPos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// read
|
||||||
|
if (Output[OutputPos] & (1<<OutputBit))
|
||||||
|
IO |= 0x0001;
|
||||||
|
else
|
||||||
|
IO &= 0xFFFE;
|
||||||
|
|
||||||
|
OutputBit++;
|
||||||
|
if (OutputBit >= 8)
|
||||||
|
{
|
||||||
|
OutputBit = 0;
|
||||||
|
if (OutputPos < 7)
|
||||||
|
OutputPos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val & 0x0010)
|
||||||
|
IO = val;
|
||||||
|
else
|
||||||
|
IO = (IO & 0x0001) | (val & 0xFFFE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
81
SPI.cpp
81
SPI.cpp
|
@ -17,6 +17,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
#include "SPI.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
|
namespace SPI
|
||||||
{
|
{
|
||||||
|
@ -197,6 +272,7 @@ u32 CurDevice;
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
SPI_Firmware::Init();
|
SPI_Firmware::Init();
|
||||||
|
SPI_Powerman::Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
|
@ -204,6 +280,7 @@ void Reset()
|
||||||
CNT = 0;
|
CNT = 0;
|
||||||
|
|
||||||
SPI_Firmware::Reset();
|
SPI_Firmware::Reset();
|
||||||
|
SPI_Powerman::Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -224,6 +301,7 @@ u8 ReadData()
|
||||||
|
|
||||||
switch (CNT & 0x0300)
|
switch (CNT & 0x0300)
|
||||||
{
|
{
|
||||||
|
case 0x0000: return SPI_Powerman::Read();
|
||||||
case 0x0100: return SPI_Firmware::Read();
|
case 0x0100: return SPI_Firmware::Read();
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
|
@ -237,8 +315,9 @@ void WriteData(u8 val)
|
||||||
|
|
||||||
switch (CNT & 0x0300)
|
switch (CNT & 0x0300)
|
||||||
{
|
{
|
||||||
|
case 0x0000: SPI_Powerman::Write(val, CNT&(1<<11)); break;
|
||||||
case 0x0100: SPI_Firmware::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))
|
if (CNT & (1<<14))
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
</Compiler>
|
</Compiler>
|
||||||
<Linker>
|
<Linker>
|
||||||
<Add option="-s" />
|
<Add option="-s" />
|
||||||
|
<Add library="C:/MinGW/lib/libgdi32.a" />
|
||||||
</Linker>
|
</Linker>
|
||||||
</Target>
|
</Target>
|
||||||
</Build>
|
</Build>
|
||||||
|
@ -52,10 +53,14 @@
|
||||||
<Unit filename="DMA.h" />
|
<Unit filename="DMA.h" />
|
||||||
<Unit filename="FIFO.cpp" />
|
<Unit filename="FIFO.cpp" />
|
||||||
<Unit filename="FIFO.h" />
|
<Unit filename="FIFO.h" />
|
||||||
|
<Unit filename="GPU.cpp" />
|
||||||
|
<Unit filename="GPU.h" />
|
||||||
<Unit filename="GPU2D.cpp" />
|
<Unit filename="GPU2D.cpp" />
|
||||||
<Unit filename="GPU2D.h" />
|
<Unit filename="GPU2D.h" />
|
||||||
<Unit filename="NDS.cpp" />
|
<Unit filename="NDS.cpp" />
|
||||||
<Unit filename="NDS.h" />
|
<Unit filename="NDS.h" />
|
||||||
|
<Unit filename="RTC.cpp" />
|
||||||
|
<Unit filename="RTC.h" />
|
||||||
<Unit filename="SPI.cpp" />
|
<Unit filename="SPI.cpp" />
|
||||||
<Unit filename="SPI.h" />
|
<Unit filename="SPI.h" />
|
||||||
<Unit filename="Wifi.cpp" />
|
<Unit filename="Wifi.cpp" />
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
1481161027 c:\documents\sources\melonds\types.h
|
1481161027 c:\documents\sources\melonds\types.h
|
||||||
|
|
||||||
1484758082 source:c:\documents\sources\melonds\nds.cpp
|
1484868036 source:c:\documents\sources\melonds\nds.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
<string.h>
|
<string.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
|
@ -20,9 +20,10 @@
|
||||||
"FIFO.h"
|
"FIFO.h"
|
||||||
"GPU.h"
|
"GPU.h"
|
||||||
"SPI.h"
|
"SPI.h"
|
||||||
|
"RTC.h"
|
||||||
"Wifi.h"
|
"Wifi.h"
|
||||||
|
|
||||||
1484754523 source:c:\documents\sources\melonds\arm.cpp
|
1484870885 source:c:\documents\sources\melonds\arm.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"ARM.h"
|
"ARM.h"
|
||||||
|
@ -76,12 +77,13 @@
|
||||||
|
|
||||||
1480957111 c:\documents\sources\melonds\spi.h
|
1480957111 c:\documents\sources\melonds\spi.h
|
||||||
|
|
||||||
1484524946 source:c:\documents\sources\melonds\spi.cpp
|
1484762789 source:c:\documents\sources\melonds\spi.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
|
<string.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"SPI.h"
|
"SPI.h"
|
||||||
|
|
||||||
1484758294 source:c:\documents\sources\melonds\gpu2d.cpp
|
1484870914 source:c:\documents\sources\melonds\gpu2d.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
<string.h>
|
<string.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
|
@ -103,7 +105,7 @@
|
||||||
1484612398 c:\documents\sources\melonds\fifo.h
|
1484612398 c:\documents\sources\melonds\fifo.h
|
||||||
"types.h"
|
"types.h"
|
||||||
|
|
||||||
1484756268 source:c:\documents\sources\melonds\dma.cpp
|
1484762586 source:c:\documents\sources\melonds\dma.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"DMA.h"
|
"DMA.h"
|
||||||
|
@ -120,3 +122,11 @@
|
||||||
1484709419 c:\documents\sources\melonds\gpu.h
|
1484709419 c:\documents\sources\melonds\gpu.h
|
||||||
"GPU2D.h"
|
"GPU2D.h"
|
||||||
|
|
||||||
|
1484848282 c:\documents\sources\melonds\rtc.h
|
||||||
|
"types.h"
|
||||||
|
|
||||||
|
1484870861 source:c:\documents\sources\melonds\rtc.cpp
|
||||||
|
<stdio.h>
|
||||||
|
<string.h>
|
||||||
|
"RTC.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue