mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2024-11-14 13:27:41 -07:00
DMA support!
This commit is contained in:
parent
b10a0d64a2
commit
9808b73c6f
34
ARM.cpp
34
ARM.cpp
@ -291,43 +291,15 @@ s32 ARM::Execute(s32 cycles)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// zorp
|
// TODO optimize this shit!!!
|
||||||
if (NDS::HaltInterrupted(Num))
|
if (NDS::HaltInterrupted(Num))
|
||||||
{
|
{
|
||||||
if (NDS::IME[Num]&1)
|
if (NDS::IME[Num]&1)
|
||||||
TriggerIRQ();
|
TriggerIRQ();
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (R[15]==0x2DD0)
|
//if (R[15] >= 0x3800170+4 && R[15]<=0x0380017A+4)
|
||||||
// printf("-> %08X %08X\n", R[13], Read32(0x0380FF7C));
|
// printf("!! %08X: %08X | %08X %08X\n", R[15]-4, R[13], R[0], R[1]);
|
||||||
|
|
||||||
//if (R[15]==0x37FEC7A)
|
|
||||||
// printf("!!!!!!!! %08X %08X\n", R[14], CPSR);
|
|
||||||
|
|
||||||
//if (R[15] == 0x037FF102+4 && CPSR&0x20) printf("!!!!! %08X -> %08X, %08X -> %08X, %08X, %08X/%08X\n",
|
|
||||||
// addr, R[15], cpsr, CPSR, CurInstr, R_SVC[2], R_IRQ[2]);
|
|
||||||
|
|
||||||
if (addr >= 0x37FAD68 && addr < 0x37FAE40)
|
|
||||||
{
|
|
||||||
if (addr==0x037FAE2A) debug=2;
|
|
||||||
//printf("!!! @ %08X %08X / %08X %08X/%08X\n", addr, R[15], Read32(0x03FFFFFC), Read32(0x04000210), Read32(0x04000214));
|
|
||||||
}
|
|
||||||
else if (debug==2)// && (CPSR&0x1F)==0x12)
|
|
||||||
{
|
|
||||||
//printf("[%08X|%08X] IRQ RET VAL = %08X | %d\n", R[15], CPSR, Read32(0x0380FF7C), cyclesrun);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (R[15] == 0x03802D54+2)
|
|
||||||
printf("%08X -> %08X\n", addr, R[15]);
|
|
||||||
|
|
||||||
// 37FE284(ARM) -> 37FE256 -> 37FECA0 !!!
|
|
||||||
if (R[15] == 0x037FE256+4)
|
|
||||||
printf("ROYAL %08X %s -> %08X %s | %08X\n",
|
|
||||||
addr, (cpsr&0x20)?"THUMB":"ARM", R[15], (CPSR&0x20)?"THUMB":"ARM",
|
|
||||||
R[0]);
|
|
||||||
if (R[15] == 0x37FE27C)
|
|
||||||
printf("NOTROYAL %08X %08X %08X/%08X\n", R[0], Read32(0x0380593C + 0x3C), R_SVC[2], Read32(0x0380593C-4));*/
|
|
||||||
// R0 = 0380593C
|
|
||||||
|
|
||||||
addr = R[15] - (CPSR&0x20 ? 4:8);
|
addr = R[15] - (CPSR&0x20 ? 4:8);
|
||||||
cpsr = CPSR;
|
cpsr = CPSR;
|
||||||
|
144
DMA.cpp
Normal file
144
DMA.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
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 "NDS.h"
|
||||||
|
#include "DMA.h"
|
||||||
|
|
||||||
|
|
||||||
|
// NOTES ON DMA SHIT
|
||||||
|
//
|
||||||
|
// * could use optimized code paths for common types of DMA transfers. for example, VRAM
|
||||||
|
// * needs to eventually be made more accurate anyway. DMA isn't instant.
|
||||||
|
|
||||||
|
|
||||||
|
DMA::DMA(u32 cpu, u32 num)
|
||||||
|
{
|
||||||
|
CPU = cpu;
|
||||||
|
Num = num;
|
||||||
|
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
DMA::~DMA()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMA::Reset()
|
||||||
|
{
|
||||||
|
SrcAddr = 0;
|
||||||
|
DstAddr = 0;
|
||||||
|
Cnt = 0;
|
||||||
|
|
||||||
|
StartMode = 0;
|
||||||
|
CurSrcAddr = 0;
|
||||||
|
CurDstAddr = 0;
|
||||||
|
RemCount = 0;
|
||||||
|
SrcAddrInc = 0;
|
||||||
|
DstAddrInc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMA::WriteCnt(u32 val)
|
||||||
|
{
|
||||||
|
u32 oldcnt = Cnt;
|
||||||
|
Cnt = val;
|
||||||
|
|
||||||
|
if ((!(oldcnt & 0x80000000)) && (val & 0x80000000))
|
||||||
|
{
|
||||||
|
CurSrcAddr = SrcAddr;
|
||||||
|
CurDstAddr = DstAddr;
|
||||||
|
|
||||||
|
switch (Cnt & 0x00060000)
|
||||||
|
{
|
||||||
|
case 0x00000000: DstAddrInc = 1; break;
|
||||||
|
case 0x00020000: DstAddrInc = -1; break;
|
||||||
|
case 0x00040000: DstAddrInc = 0; break;
|
||||||
|
case 0x00060000: DstAddrInc = 1; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (Cnt & 0x00180000)
|
||||||
|
{
|
||||||
|
case 0x00000000: SrcAddrInc = 1; break;
|
||||||
|
case 0x00080000: SrcAddrInc = -1; break;
|
||||||
|
case 0x00100000: SrcAddrInc = 0; break;
|
||||||
|
case 0x00180000: SrcAddrInc = 1; printf("BAD DMA SRC INC MODE 3\n"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CPU == 0)
|
||||||
|
StartMode = (Cnt >> 27) & 0x7;
|
||||||
|
else
|
||||||
|
StartMode = ((Cnt >> 28) & 0x3) | 0x8;
|
||||||
|
|
||||||
|
if ((StartMode & 0x7) == 0)
|
||||||
|
Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DMA::Start()
|
||||||
|
{
|
||||||
|
u32 countmask;
|
||||||
|
if (CPU == 0)
|
||||||
|
countmask = 0x001FFFFF;
|
||||||
|
else
|
||||||
|
countmask = (Num==3 ? 0x0000FFFF : 0x00003FFF);
|
||||||
|
|
||||||
|
RemCount = Cnt & countmask;
|
||||||
|
if (!RemCount)
|
||||||
|
RemCount = countmask+1;
|
||||||
|
|
||||||
|
if ((Cnt & 0x00060000) == 0x00060000)
|
||||||
|
CurDstAddr = DstAddr;
|
||||||
|
|
||||||
|
printf("ARM%d DMA%d %08X->%08X %d units %dbit\n", CPU?7:9, Num, CurSrcAddr, CurDstAddr, RemCount, (Cnt & 0x04000000)?16:32);
|
||||||
|
|
||||||
|
// TODO: NOT MAKE THE DMA INSTANT!!
|
||||||
|
if (Cnt & 0x04000000)
|
||||||
|
{
|
||||||
|
u16 (*readfn)(u32) = CPU ? NDS::ARM7Read16 : NDS::ARM9Read16;
|
||||||
|
void (*writefn)(u32,u16) = CPU ? NDS::ARM7Write16 : NDS::ARM9Write16;
|
||||||
|
|
||||||
|
while (RemCount > 0)
|
||||||
|
{
|
||||||
|
writefn(CurDstAddr, readfn(CurSrcAddr));
|
||||||
|
|
||||||
|
CurSrcAddr += SrcAddrInc<<1;
|
||||||
|
CurDstAddr += DstAddrInc<<1;
|
||||||
|
RemCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
u32 (*readfn)(u32) = CPU ? NDS::ARM7Read32 : NDS::ARM9Read32;
|
||||||
|
void (*writefn)(u32,u32) = CPU ? NDS::ARM7Write32 : NDS::ARM9Write32;
|
||||||
|
|
||||||
|
while (RemCount > 0)
|
||||||
|
{
|
||||||
|
writefn(CurDstAddr, readfn(CurSrcAddr));
|
||||||
|
|
||||||
|
CurSrcAddr += SrcAddrInc<<2;
|
||||||
|
CurDstAddr += DstAddrInc<<2;
|
||||||
|
RemCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Cnt & 0x02000000))
|
||||||
|
Cnt &= ~0x80000000;
|
||||||
|
|
||||||
|
if (Cnt & 0x40000000)
|
||||||
|
NDS::TriggerIRQ(CPU, NDS::IRQ_DMA0 + Num);
|
||||||
|
}
|
56
DMA.h
Normal file
56
DMA.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
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 DMA_H
|
||||||
|
#define DMA_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
class DMA
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DMA(u32 cpu, u32 num);
|
||||||
|
~DMA();
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
void WriteCnt(u32 val);
|
||||||
|
void Start();
|
||||||
|
|
||||||
|
void StartIfNeeded(u32 mode)
|
||||||
|
{
|
||||||
|
if ((mode == StartMode) && (Cnt & 0x80000000))
|
||||||
|
Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 SrcAddr;
|
||||||
|
u32 DstAddr;
|
||||||
|
u32 Cnt;
|
||||||
|
|
||||||
|
private:
|
||||||
|
u32 CPU, Num;
|
||||||
|
|
||||||
|
u32 StartMode;
|
||||||
|
u32 CurSrcAddr;
|
||||||
|
u32 CurDstAddr;
|
||||||
|
u32 RemCount;
|
||||||
|
u32 SrcAddrInc;
|
||||||
|
u32 DstAddrInc;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
90
NDS.cpp
90
NDS.cpp
@ -21,6 +21,7 @@
|
|||||||
#include "NDS.h"
|
#include "NDS.h"
|
||||||
#include "ARM.h"
|
#include "ARM.h"
|
||||||
#include "CP15.h"
|
#include "CP15.h"
|
||||||
|
#include "DMA.h"
|
||||||
#include "FIFO.h"
|
#include "FIFO.h"
|
||||||
#include "GPU2D.h"
|
#include "GPU2D.h"
|
||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
@ -79,6 +80,9 @@ u16 PowerControl7;
|
|||||||
|
|
||||||
Timer Timers[8];
|
Timer Timers[8];
|
||||||
|
|
||||||
|
DMA* DMAs[8];
|
||||||
|
u32 DMA9Fill[4];
|
||||||
|
|
||||||
u16 IPCSync9, IPCSync7;
|
u16 IPCSync9, IPCSync7;
|
||||||
u16 IPCFIFOCnt9, IPCFIFOCnt7;
|
u16 IPCFIFOCnt9, IPCFIFOCnt7;
|
||||||
FIFO* IPCFIFO9; // FIFO in which the ARM9 writes
|
FIFO* IPCFIFO9; // FIFO in which the ARM9 writes
|
||||||
@ -102,6 +106,15 @@ void Init()
|
|||||||
ARM9 = new ARM(0);
|
ARM9 = new ARM(0);
|
||||||
ARM7 = new ARM(1);
|
ARM7 = new ARM(1);
|
||||||
|
|
||||||
|
DMAs[0] = new DMA(0, 0);
|
||||||
|
DMAs[1] = new DMA(0, 1);
|
||||||
|
DMAs[2] = new DMA(0, 2);
|
||||||
|
DMAs[3] = new DMA(0, 3);
|
||||||
|
DMAs[4] = new DMA(1, 0);
|
||||||
|
DMAs[5] = new DMA(1, 1);
|
||||||
|
DMAs[6] = new DMA(1, 2);
|
||||||
|
DMAs[7] = new DMA(1, 3);
|
||||||
|
|
||||||
IPCFIFO9 = new FIFO(16);
|
IPCFIFO9 = new FIFO(16);
|
||||||
IPCFIFO7 = new FIFO(16);
|
IPCFIFO7 = new FIFO(16);
|
||||||
|
|
||||||
@ -156,6 +169,7 @@ void LoadROM()
|
|||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
FILE* f;
|
FILE* f;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
f = fopen("bios9.bin", "rb");
|
f = fopen("bios9.bin", "rb");
|
||||||
if (!f)
|
if (!f)
|
||||||
@ -216,6 +230,9 @@ void Reset()
|
|||||||
|
|
||||||
memset(Timers, 0, 8*sizeof(Timer));
|
memset(Timers, 0, 8*sizeof(Timer));
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) DMAs[i]->Reset();
|
||||||
|
memset(DMA9Fill, 0, 4*4);
|
||||||
|
|
||||||
GPU2D::Reset();
|
GPU2D::Reset();
|
||||||
SPI::Reset();
|
SPI::Reset();
|
||||||
Wifi::Reset();
|
Wifi::Reset();
|
||||||
@ -991,7 +1008,7 @@ u8 ARM7Read8(u32 addr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("unknown arm7 read8 %08X\n", addr);
|
printf("unknown arm7 read8 %08X %08X %08X/%08X\n", addr, ARM7->R[15], ARM7->R[0], ARM7->R[1]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1229,6 +1246,15 @@ u16 ARM9IORead16(u32 addr)
|
|||||||
case 0x04000004: return GPU2D::DispStat[0];
|
case 0x04000004: return GPU2D::DispStat[0];
|
||||||
case 0x04000006: return GPU2D::VCount;
|
case 0x04000006: return GPU2D::VCount;
|
||||||
|
|
||||||
|
case 0x040000E0: return ((u16*)DMA9Fill)[0];
|
||||||
|
case 0x040000E2: return ((u16*)DMA9Fill)[1];
|
||||||
|
case 0x040000E4: return ((u16*)DMA9Fill)[2];
|
||||||
|
case 0x040000E6: return ((u16*)DMA9Fill)[3];
|
||||||
|
case 0x040000E8: return ((u16*)DMA9Fill)[4];
|
||||||
|
case 0x040000EA: return ((u16*)DMA9Fill)[5];
|
||||||
|
case 0x040000EC: return ((u16*)DMA9Fill)[6];
|
||||||
|
case 0x040000EE: return ((u16*)DMA9Fill)[7];
|
||||||
|
|
||||||
case 0x04000100: return Timers[0].Counter;
|
case 0x04000100: return Timers[0].Counter;
|
||||||
case 0x04000102: return Timers[0].Control;
|
case 0x04000102: return Timers[0].Control;
|
||||||
case 0x04000104: return Timers[1].Counter;
|
case 0x04000104: return Timers[1].Counter;
|
||||||
@ -1268,6 +1294,24 @@ u32 ARM9IORead32(u32 addr)
|
|||||||
{
|
{
|
||||||
case 0x04000004: return GPU2D::DispStat[0] | (GPU2D::VCount << 16);
|
case 0x04000004: return GPU2D::DispStat[0] | (GPU2D::VCount << 16);
|
||||||
|
|
||||||
|
case 0x040000B0: return DMAs[0]->SrcAddr;
|
||||||
|
case 0x040000B4: return DMAs[0]->DstAddr;
|
||||||
|
case 0x040000B8: return DMAs[0]->Cnt;
|
||||||
|
case 0x040000BC: return DMAs[1]->SrcAddr;
|
||||||
|
case 0x040000C0: return DMAs[1]->DstAddr;
|
||||||
|
case 0x040000C4: return DMAs[1]->Cnt;
|
||||||
|
case 0x040000C8: return DMAs[2]->SrcAddr;
|
||||||
|
case 0x040000CC: return DMAs[2]->DstAddr;
|
||||||
|
case 0x040000D0: return DMAs[2]->Cnt;
|
||||||
|
case 0x040000D4: return DMAs[3]->SrcAddr;
|
||||||
|
case 0x040000D8: return DMAs[3]->DstAddr;
|
||||||
|
case 0x040000DC: return DMAs[3]->Cnt;
|
||||||
|
|
||||||
|
case 0x040000E0: return DMA9Fill[0];
|
||||||
|
case 0x040000E4: return DMA9Fill[1];
|
||||||
|
case 0x040000E8: return DMA9Fill[2];
|
||||||
|
case 0x040000EC: return DMA9Fill[3];
|
||||||
|
|
||||||
case 0x04000100: return Timers[0].Counter | (Timers[0].Control << 16);
|
case 0x04000100: return Timers[0].Counter | (Timers[0].Control << 16);
|
||||||
case 0x04000104: return Timers[1].Counter | (Timers[1].Control << 16);
|
case 0x04000104: return Timers[1].Counter | (Timers[1].Control << 16);
|
||||||
case 0x04000108: return Timers[2].Counter | (Timers[2].Control << 16);
|
case 0x04000108: return Timers[2].Counter | (Timers[2].Control << 16);
|
||||||
@ -1409,6 +1453,24 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
|||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
case 0x040000B0: DMAs[0]->SrcAddr = val; return;
|
||||||
|
case 0x040000B4: DMAs[0]->DstAddr = val; return;
|
||||||
|
case 0x040000B8: DMAs[0]->WriteCnt(val); return;
|
||||||
|
case 0x040000BC: DMAs[1]->SrcAddr = val; return;
|
||||||
|
case 0x040000C0: DMAs[1]->DstAddr = val; return;
|
||||||
|
case 0x040000C4: DMAs[1]->WriteCnt(val); return;
|
||||||
|
case 0x040000C8: DMAs[2]->SrcAddr = val; return;
|
||||||
|
case 0x040000CC: DMAs[2]->DstAddr = val; return;
|
||||||
|
case 0x040000D0: DMAs[2]->WriteCnt(val); return;
|
||||||
|
case 0x040000D4: DMAs[3]->SrcAddr = val; return;
|
||||||
|
case 0x040000D8: DMAs[3]->DstAddr = val; return;
|
||||||
|
case 0x040000DC: DMAs[3]->WriteCnt(val); return;
|
||||||
|
|
||||||
|
case 0x040000E0: DMA9Fill[0] = val; return;
|
||||||
|
case 0x040000E4: DMA9Fill[1] = val; return;
|
||||||
|
case 0x040000E8: DMA9Fill[2] = val; return;
|
||||||
|
case 0x040000EC: DMA9Fill[3] = val; return;
|
||||||
|
|
||||||
case 0x04000100:
|
case 0x04000100:
|
||||||
Timers[0].Reload = val & 0xFFFF;
|
Timers[0].Reload = val & 0xFFFF;
|
||||||
TimerStart(0, val>>16);
|
TimerStart(0, val>>16);
|
||||||
@ -1561,6 +1623,19 @@ u32 ARM7IORead32(u32 addr)
|
|||||||
{
|
{
|
||||||
case 0x04000004: return GPU2D::DispStat[1] | (GPU2D::VCount << 16);
|
case 0x04000004: return GPU2D::DispStat[1] | (GPU2D::VCount << 16);
|
||||||
|
|
||||||
|
case 0x040000B0: return DMAs[4]->SrcAddr;
|
||||||
|
case 0x040000B4: return DMAs[4]->DstAddr;
|
||||||
|
case 0x040000B8: return DMAs[4]->Cnt;
|
||||||
|
case 0x040000BC: return DMAs[5]->SrcAddr;
|
||||||
|
case 0x040000C0: return DMAs[5]->DstAddr;
|
||||||
|
case 0x040000C4: return DMAs[5]->Cnt;
|
||||||
|
case 0x040000C8: return DMAs[6]->SrcAddr;
|
||||||
|
case 0x040000CC: return DMAs[6]->DstAddr;
|
||||||
|
case 0x040000D0: return DMAs[6]->Cnt;
|
||||||
|
case 0x040000D4: return DMAs[7]->SrcAddr;
|
||||||
|
case 0x040000D8: return DMAs[7]->DstAddr;
|
||||||
|
case 0x040000DC: return DMAs[7]->Cnt;
|
||||||
|
|
||||||
case 0x04000100: return Timers[4].Counter | (Timers[4].Control << 16);
|
case 0x04000100: return Timers[4].Counter | (Timers[4].Control << 16);
|
||||||
case 0x04000104: return Timers[5].Counter | (Timers[5].Control << 16);
|
case 0x04000104: return Timers[5].Counter | (Timers[5].Control << 16);
|
||||||
case 0x04000108: return Timers[6].Counter | (Timers[6].Control << 16);
|
case 0x04000108: return Timers[6].Counter | (Timers[6].Control << 16);
|
||||||
@ -1713,6 +1788,19 @@ void ARM7IOWrite32(u32 addr, u32 val)
|
|||||||
{
|
{
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
|
case 0x040000B0: DMAs[4]->SrcAddr = val; return;
|
||||||
|
case 0x040000B4: DMAs[4]->DstAddr = val; return;
|
||||||
|
case 0x040000B8: DMAs[4]->WriteCnt(val); return;
|
||||||
|
case 0x040000BC: DMAs[5]->SrcAddr = val; return;
|
||||||
|
case 0x040000C0: DMAs[5]->DstAddr = val; return;
|
||||||
|
case 0x040000C4: DMAs[5]->WriteCnt(val); return;
|
||||||
|
case 0x040000C8: DMAs[6]->SrcAddr = val; return;
|
||||||
|
case 0x040000CC: DMAs[6]->DstAddr = val; return;
|
||||||
|
case 0x040000D0: DMAs[6]->WriteCnt(val); return;
|
||||||
|
case 0x040000D4: DMAs[7]->SrcAddr = val; return;
|
||||||
|
case 0x040000D8: DMAs[7]->DstAddr = val; return;
|
||||||
|
case 0x040000DC: DMAs[7]->WriteCnt(val); return;
|
||||||
|
|
||||||
case 0x04000100:
|
case 0x04000100:
|
||||||
Timers[4].Reload = val & 0xFFFF;
|
Timers[4].Reload = val & 0xFFFF;
|
||||||
TimerStart(4, val>>16);
|
TimerStart(4, val>>16);
|
||||||
|
18
main.cpp
18
main.cpp
@ -128,6 +128,9 @@ int main()
|
|||||||
|
|
||||||
NDS::Init();
|
NDS::Init();
|
||||||
|
|
||||||
|
u32 nframes = 0;
|
||||||
|
u32 lasttick = GetTickCount();
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg;
|
||||||
@ -149,6 +152,21 @@ int main()
|
|||||||
HDC dc = GetDC(melon);
|
HDC dc = GetDC(melon);
|
||||||
SetDIBitsToDevice(dc, 0, 0, 256, 384, 0, 0, 0, 384, GPU2D::Framebuffer, (BITMAPINFO*)&bmp, DIB_RGB_COLORS);
|
SetDIBitsToDevice(dc, 0, 0, 256, 384, 0, 0, 0, 384, GPU2D::Framebuffer, (BITMAPINFO*)&bmp, DIB_RGB_COLORS);
|
||||||
UpdateWindow(melon);
|
UpdateWindow(melon);
|
||||||
|
|
||||||
|
nframes++;
|
||||||
|
if (nframes >= 30)
|
||||||
|
{
|
||||||
|
u32 tick = GetTickCount();
|
||||||
|
u32 diff = tick - lasttick;
|
||||||
|
lasttick = tick;
|
||||||
|
|
||||||
|
u32 fps = (nframes * 1000) / diff;
|
||||||
|
nframes = 0;
|
||||||
|
|
||||||
|
char melontitle[100];
|
||||||
|
sprintf(melontitle, "melonDS | %d FPS", fps);
|
||||||
|
SetWindowText(melon, melontitle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -48,6 +48,8 @@
|
|||||||
<Unit filename="ARM_InstrTable.h" />
|
<Unit filename="ARM_InstrTable.h" />
|
||||||
<Unit filename="CP15.cpp" />
|
<Unit filename="CP15.cpp" />
|
||||||
<Unit filename="CP15.h" />
|
<Unit filename="CP15.h" />
|
||||||
|
<Unit filename="DMA.cpp" />
|
||||||
|
<Unit filename="DMA.h" />
|
||||||
<Unit filename="FIFO.cpp" />
|
<Unit filename="FIFO.cpp" />
|
||||||
<Unit filename="FIFO.h" />
|
<Unit filename="FIFO.h" />
|
||||||
<Unit filename="GPU2D.cpp" />
|
<Unit filename="GPU2D.cpp" />
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# depslib dependency file v1.0
|
# depslib dependency file v1.0
|
||||||
1481167563 source:c:\documents\sources\melonds\main.cpp
|
1484695094 source:c:\documents\sources\melonds\main.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
<windows.h>
|
<windows.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
@ -10,18 +10,19 @@
|
|||||||
|
|
||||||
1481161027 c:\documents\sources\melonds\types.h
|
1481161027 c:\documents\sources\melonds\types.h
|
||||||
|
|
||||||
1484616465 source:c:\documents\sources\melonds\nds.cpp
|
1484699425 source:c:\documents\sources\melonds\nds.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
<string.h>
|
<string.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"ARM.h"
|
"ARM.h"
|
||||||
"CP15.h"
|
"CP15.h"
|
||||||
|
"DMA.h"
|
||||||
"FIFO.h"
|
"FIFO.h"
|
||||||
"GPU2D.h"
|
"GPU2D.h"
|
||||||
"SPI.h"
|
"SPI.h"
|
||||||
"Wifi.h"
|
"Wifi.h"
|
||||||
|
|
||||||
1484538131 source:c:\documents\sources\melonds\arm.cpp
|
1484693558 source:c:\documents\sources\melonds\arm.cpp
|
||||||
<stdio.h>
|
<stdio.h>
|
||||||
"NDS.h"
|
"NDS.h"
|
||||||
"ARM.h"
|
"ARM.h"
|
||||||
@ -102,3 +103,11 @@
|
|||||||
1484612398 c:\documents\sources\melonds\fifo.h
|
1484612398 c:\documents\sources\melonds\fifo.h
|
||||||
"types.h"
|
"types.h"
|
||||||
|
|
||||||
|
1484699433 source:c:\documents\sources\melonds\dma.cpp
|
||||||
|
<stdio.h>
|
||||||
|
"NDS.h"
|
||||||
|
"DMA.h"
|
||||||
|
|
||||||
|
1484698068 c:\documents\sources\melonds\dma.h
|
||||||
|
"types.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user