totally rewrite main emulation loop! YOUR SAVESTATES ARE INVALIDATED. your timing is all different. but, your timing is more precise, a few hidden old bugs surfaced and were smashed, and some games work that didn't used to. INSTRUCTIONS_PER_BATCH is a thing of the past. crazymax and luigi, I may have broken your parts, but hopefully only a little bit. your new hookups into the emulation loop are more complicated but potentially faster and definitely more precise.
This commit is contained in:
parent
b54420e5a7
commit
28435d9334
|
@ -1,21 +1,31 @@
|
||||||
0.9.4 -> ??? (r2437-r???)
|
0.9.4 -> ??? (r2437-r???)
|
||||||
|
|
||||||
|
??? introduces an entirely rewritten main emulation loop.
|
||||||
|
This totally changes the timing, and totally breaks old savestates.
|
||||||
|
|
||||||
Highlights:
|
Highlights:
|
||||||
* win32: lua engine, path configuration, 7z dearchiving support
|
* win32: lua engine, path configuration, 7z dearchiving support
|
||||||
|
* rewritten main emulation loop
|
||||||
|
|
||||||
General/Core:
|
General/Core:
|
||||||
bug: fix cflash directory support for non-windows
|
bug: fix cflash directory support for non-windows
|
||||||
bug: fix freeze in cart irq
|
bug: fix freeze in cart irq
|
||||||
bug: correctly emulate dma to/from tcm
|
bug: correctly emulate dma to/from tcm
|
||||||
|
enh: add guitar grip emulation
|
||||||
|
enh: add more powerful antigrain-based drawing library and rewrite OSD system
|
||||||
enh: ideas-style debugging prints
|
enh: ideas-style debugging prints
|
||||||
|
|
||||||
Graphics:
|
Graphics:
|
||||||
bug: fixing of obj blending and bmp obj rendering
|
bug: fixing of obj blending and bmp obj rendering
|
||||||
|
bug: fix backdrop blending with garbage
|
||||||
|
bug: fix 256B granularity sprite addressing for sub gpu
|
||||||
bug: swrast: add clear image emulation
|
bug: swrast: add clear image emulation
|
||||||
bug: swrast: add edge marking
|
bug: swrast: add edge marking
|
||||||
|
|
||||||
Windows:
|
Windows:
|
||||||
bug: improve map view tool
|
bug: improve map view tool to support more modes
|
||||||
|
enh: added 2x resizing filters (hq2x, 2xsai, supereagle, scanlines)
|
||||||
|
enh: soundview can now mute channels
|
||||||
|
|
||||||
Linux:
|
Linux:
|
||||||
enh: alsa microphone support
|
enh: alsa microphone support
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "MMU.h"
|
#include "MMU.h"
|
||||||
|
#include "NDSSystem.h"
|
||||||
|
|
||||||
// ========================================================= IPC FIFO
|
// ========================================================= IPC FIFO
|
||||||
IPC_FIFO ipc_fifo[2]; // 0 - ARM9
|
IPC_FIFO ipc_fifo[2]; // 0 - ARM9
|
||||||
|
@ -174,6 +175,8 @@ void GFX_FIFOsend(u8 cmd, u32 param)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
||||||
|
|
||||||
|
NDS_RescheduleGXFIFO();
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
||||||
|
@ -183,6 +186,7 @@ BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
||||||
if (gxstat & 0xC0000000)
|
if (gxstat & 0xC0000000)
|
||||||
{
|
{
|
||||||
setIF(0, (1<<21));
|
setIF(0, (1<<21));
|
||||||
|
//NDS_makeARM9Int(21);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (gxFIFO.tail == 0) // empty
|
if (gxFIFO.tail == 0) // empty
|
||||||
|
@ -193,18 +197,23 @@ BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
||||||
if ((gxstat & 0x80000000)) // empty
|
if ((gxstat & 0x80000000)) // empty
|
||||||
{
|
{
|
||||||
setIF(0, (1<<21));
|
setIF(0, (1<<21));
|
||||||
|
//NDS_makeARM9Int(21);
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gxstat & 0x40000000) // IRQ: less half
|
if (gxstat & 0x40000000) // IRQ: less half
|
||||||
{
|
{
|
||||||
if (gxstat & 0x02000000) setIF(0, (1<<21));
|
if (gxstat & 0x02000000)
|
||||||
|
setIF(0, (1<<21));
|
||||||
|
//NDS_makeARM9Int(21);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((gxstat & 0x80000000)) // IRQ: empty
|
if ((gxstat & 0x80000000)) // IRQ: empty
|
||||||
{
|
{
|
||||||
if (gxstat & 0x04000000) setIF(0, (1<<21));
|
if (gxstat & 0x04000000)
|
||||||
|
setIF(0, (1<<21));
|
||||||
|
//NDS_makeARM9Int(21);
|
||||||
}
|
}
|
||||||
|
|
||||||
gxstat &= 0xF000FFFF;
|
gxstat &= 0xF000FFFF;
|
||||||
|
@ -228,6 +237,8 @@ BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
||||||
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
||||||
|
|
||||||
|
NDS_RescheduleGXFIFO();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,9 +253,12 @@ void GFX_FIFOcnt(u32 val)
|
||||||
}
|
}
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
||||||
|
|
||||||
|
NDS_RescheduleGXFIFO();
|
||||||
|
|
||||||
/*if (gxstat & 0xC0000000)
|
/*if (gxstat & 0xC0000000)
|
||||||
{
|
{
|
||||||
setIF(0, (1<<21));
|
setIF(0, (1<<21));
|
||||||
|
//NDS_makeARM9Int(21);
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -410,23 +410,8 @@ u8 *MMU_RenderMapToLCD(u32 vram_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<u8 DMA_CHANNEL>
|
|
||||||
void DMAtoVRAMmapping()
|
|
||||||
{
|
|
||||||
//THIS IS ALSO DANGEROUS!!!!!!
|
|
||||||
//but i dont think it needs to be done
|
|
||||||
|
|
||||||
/*u32 dst = DMADst[ARMCPU_ARM9][DMA_CHANNEL];
|
|
||||||
|
|
||||||
bool unmapped;
|
|
||||||
dst = MMU_LCDmap(dst,unmapped);
|
|
||||||
|
|
||||||
DMADst[ARMCPU_ARM9][DMA_CHANNEL] = dst;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOG_VRAM_ERROR() LOG("No data for block %i MST %i\n", block, VRAMBankCnt & 0x07);
|
#define LOG_VRAM_ERROR() LOG("No data for block %i MST %i\n", block, VRAMBankCnt & 0x07);
|
||||||
|
|
||||||
|
|
||||||
struct VramConfiguration {
|
struct VramConfiguration {
|
||||||
|
|
||||||
enum Purpose {
|
enum Purpose {
|
||||||
|
@ -983,7 +968,7 @@ void MMU_clearMem()
|
||||||
memset(MMU.reg_IF, 0, sizeof(u32) * 2);
|
memset(MMU.reg_IF, 0, sizeof(u32) * 2);
|
||||||
|
|
||||||
memset(MMU.DMAStartTime, 0, sizeof(u32) * 2 * 4);
|
memset(MMU.DMAStartTime, 0, sizeof(u32) * 2 * 4);
|
||||||
memset(MMU.DMACycle, 0, sizeof(s32) * 2 * 4);
|
memset(MMU.DMACycle, 0, sizeof(MMU.DMACycle));
|
||||||
memset(MMU.DMACrt, 0, sizeof(u32) * 2 * 4);
|
memset(MMU.DMACrt, 0, sizeof(u32) * 2 * 4);
|
||||||
memset(MMU.DMAing, 0, sizeof(BOOL) * 2 * 4);
|
memset(MMU.DMAing, 0, sizeof(BOOL) * 2 * 4);
|
||||||
|
|
||||||
|
@ -1011,9 +996,7 @@ void MMU_clearMem()
|
||||||
partie = 1;
|
partie = 1;
|
||||||
addonsReset();
|
addonsReset();
|
||||||
Mic_Reset();
|
Mic_Reset();
|
||||||
#ifdef USE_GEOMETRY_FIFO_EMULATION
|
|
||||||
MMU.gfx3dCycles = 0;
|
MMU.gfx3dCycles = 0;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMU_setRom(u8 * rom, u32 mask)
|
void MMU_setRom(u8 * rom, u32 mask)
|
||||||
|
@ -1062,10 +1045,11 @@ static void execsqrt() {
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B4, 0);
|
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B4, 0);
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B0, cnt | 0x8000);
|
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2B0, cnt | 0x8000);
|
||||||
|
|
||||||
MMU.sqrtCycles = (nds.cycles + 26);
|
MMU.sqrtCycles = nds_timer + 26;
|
||||||
MMU.sqrtResult = ret;
|
MMU.sqrtResult = ret;
|
||||||
MMU.sqrtCnt = (cnt & 0x7FFF);
|
MMU.sqrtCnt = (cnt & 0x7FFF);
|
||||||
MMU.sqrtRunning = TRUE;
|
MMU.sqrtRunning = TRUE;
|
||||||
|
NDS_Reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void execdiv() {
|
static void execdiv() {
|
||||||
|
@ -1078,19 +1062,19 @@ static void execdiv() {
|
||||||
case 0:
|
case 0:
|
||||||
num = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
num = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
||||||
den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
||||||
MMU.divCycles = (nds.cycles + 36);
|
MMU.divCycles = nds_timer + 36;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 3: //gbatek says this is same as mode 1
|
case 3: //gbatek says this is same as mode 1
|
||||||
num = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
num = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
||||||
den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
||||||
MMU.divCycles = (nds.cycles + 68);
|
MMU.divCycles = nds_timer + 68;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
default:
|
default:
|
||||||
num = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
num = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
||||||
den = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
den = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
||||||
MMU.divCycles = (nds.cycles + 68);
|
MMU.divCycles = nds_timer + 68;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1122,6 +1106,7 @@ static void execdiv() {
|
||||||
MMU.divMod = mod;
|
MMU.divMod = mod;
|
||||||
MMU.divCnt = (cnt & 0x7FFF);
|
MMU.divCnt = (cnt & 0x7FFF);
|
||||||
MMU.divRunning = TRUE;
|
MMU.divRunning = TRUE;
|
||||||
|
NDS_Reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int PROCNUM>
|
template<int PROCNUM>
|
||||||
|
@ -1150,19 +1135,21 @@ void FASTCALL MMU_doDMA(u32 num)
|
||||||
taille = (MMU.DMACrt[PROCNUM][num]&0x1FFFFF);
|
taille = (MMU.DMACrt[PROCNUM][num]&0x1FFFFF);
|
||||||
if(taille == 0) taille = 0x200000; //according to gbatek..
|
if(taille == 0) taille = 0x200000; //according to gbatek..
|
||||||
|
|
||||||
|
//THIS IS A BIG HACK
|
||||||
// If we are in "Main memory display" mode just copy an entire
|
// If we are in "Main memory display" mode just copy an entire
|
||||||
// screen (256x192 pixels).
|
// screen (256x192 pixels).
|
||||||
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
|
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
|
||||||
// (under DISP_MMEM_FIFO)
|
// (under DISP_MMEM_FIFO)
|
||||||
if ((MMU.DMAStartTime[PROCNUM][num]==4) && // Must be in main memory display mode
|
if ((MMU.DMAStartTime[PROCNUM][num]==EDMAMode_MemDisplay) && // Must be in main memory display mode
|
||||||
(taille==4) && // Word must be 4
|
(taille==4) && // Word must be 4
|
||||||
(((MMU.DMACrt[PROCNUM][num]>>26)&1) == 1)) // Transfer mode must be 32bit wide
|
(((MMU.DMACrt[PROCNUM][num]>>26)&1) == 1)) // Transfer mode must be 32bit wide
|
||||||
taille = 24576; //256*192/2;
|
taille = 24576; //256*192/2;
|
||||||
|
|
||||||
if(MMU.DMAStartTime[PROCNUM][num] == 5)
|
if(MMU.DMAStartTime[PROCNUM][num] == EDMAMode_Card)
|
||||||
taille *= 0x80;
|
taille *= 0x80;
|
||||||
|
|
||||||
MMU.DMACycle[PROCNUM][num] = taille + nds.cycles;
|
MMU.DMACycle[PROCNUM][num] = taille + nds_timer; //TODO - surely this is a gross simplification
|
||||||
|
|
||||||
MMU.DMAing[PROCNUM][num] = TRUE;
|
MMU.DMAing[PROCNUM][num] = TRUE;
|
||||||
MMU.CheckDMAs |= (1<<(num+(PROCNUM<<2)));
|
MMU.CheckDMAs |= (1<<(num+(PROCNUM<<2)));
|
||||||
|
|
||||||
|
@ -1173,6 +1160,8 @@ void FASTCALL MMU_doDMA(u32 num)
|
||||||
if(!(MMU.DMACrt[PROCNUM][num]&(1<<25)))
|
if(!(MMU.DMACrt[PROCNUM][num]&(1<<25)))
|
||||||
MMU.DMAStartTime[PROCNUM][num] = 0;
|
MMU.DMAStartTime[PROCNUM][num] = 0;
|
||||||
|
|
||||||
|
NDS_RescheduleDMA();
|
||||||
|
|
||||||
// transfer
|
// transfer
|
||||||
{
|
{
|
||||||
u32 i=0;
|
u32 i=0;
|
||||||
|
@ -1315,6 +1304,97 @@ static INLINE void MMU_IPCSync(u8 proc, u32 val)
|
||||||
setIF(proc^1, ( 1 << 16 ));
|
setIF(proc^1, ( 1 << 16 ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INLINE u16 read_timer(int proc, int timerIndex)
|
||||||
|
{
|
||||||
|
//chained timers are always up to date
|
||||||
|
if(MMU.timerMODE[proc][timerIndex] == 0xFFFF)
|
||||||
|
return MMU.timer[proc][timerIndex];
|
||||||
|
|
||||||
|
//for unchained timers, we do not keep the timer up to date. its value will need to be calculated here
|
||||||
|
s32 diff = (s32)(nds.timerCycle[proc][timerIndex] - nds_timer);
|
||||||
|
assert(diff>=0);
|
||||||
|
if(diff<0)
|
||||||
|
printf("NEW EMULOOP BAD NEWS PLEASE REPORT: TIME READ DIFF < 0 (%d) (%d) (%d)\n",diff,timerIndex,MMU.timerMODE[proc][timerIndex]);
|
||||||
|
|
||||||
|
s32 units = diff / (1<<MMU.timerMODE[proc][timerIndex]);
|
||||||
|
|
||||||
|
s32 ret = 65535 - units;
|
||||||
|
assert(ret>=0);
|
||||||
|
if(ret<0) printf("NEW EMULOOP BAD NEWS PLEASE REPORT: TIME READ RETURN < 0\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void write_timer(int proc, int timerIndex, u16 val)
|
||||||
|
{
|
||||||
|
int mask = ((val&0x80)>>7) << timerIndex;
|
||||||
|
//MMU.CheckTimers = (MMU.CheckTimers & (~mask)) | mask;
|
||||||
|
|
||||||
|
if(val&0x80)
|
||||||
|
MMU.timer[proc][timerIndex] = MMU.timerReload[proc][timerIndex];
|
||||||
|
|
||||||
|
MMU.timerON[proc][timerIndex] = val & 0x80;
|
||||||
|
|
||||||
|
switch(val&7)
|
||||||
|
{
|
||||||
|
case 0 :
|
||||||
|
MMU.timerMODE[proc][timerIndex] = 0+1;
|
||||||
|
break;
|
||||||
|
case 1 :
|
||||||
|
MMU.timerMODE[proc][timerIndex] = 6+1;
|
||||||
|
break;
|
||||||
|
case 2 :
|
||||||
|
MMU.timerMODE[proc][timerIndex] = 8+1;
|
||||||
|
break;
|
||||||
|
case 3 :
|
||||||
|
MMU.timerMODE[proc][timerIndex] = 10+1;
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
MMU.timerMODE[proc][timerIndex] = 0xFFFF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int remain = 65536 - MMU.timerReload[proc][timerIndex];
|
||||||
|
nds.timerCycle[proc][timerIndex] = nds_timer + (remain<<MMU.timerMODE[proc][timerIndex]);
|
||||||
|
|
||||||
|
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x102+timerIndex*4, val);
|
||||||
|
NDS_RescheduleTimers();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int proc> static INLINE void write_dma_hictrl(const int dmanum, const u16 val)
|
||||||
|
{
|
||||||
|
u32 baseAddr = 0xB0 + dmanum*12;
|
||||||
|
|
||||||
|
//write this control value
|
||||||
|
T1WriteWord(MMU.MMU_MEM[proc][0x40], baseAddr+10, val);
|
||||||
|
|
||||||
|
//read back the src and dst addr
|
||||||
|
DMASrc[proc][dmanum] = T1ReadLong(MMU.MMU_MEM[proc][0x40], baseAddr);
|
||||||
|
DMADst[proc][dmanum] = T1ReadLong(MMU.MMU_MEM[proc][0x40], baseAddr+4);
|
||||||
|
|
||||||
|
//analyze the control value
|
||||||
|
u32 v = T1ReadLong(MMU.MMU_MEM[proc][0x40], baseAddr+8);
|
||||||
|
if(proc==ARMCPU_ARM9) MMU.DMAStartTime[proc][dmanum] = (v>>27) & 0x7;
|
||||||
|
else {
|
||||||
|
static const EDMAMode lookup[] = {EDMAMode_Immediate,EDMAMode_VBlank,EDMAMode_Card,EDMAMode7_Wifi};
|
||||||
|
MMU.DMAStartTime[proc][dmanum] = lookup[(v>>28) & 0x3];
|
||||||
|
if(MMU.DMAStartTime[proc][dmanum] == EDMAMode7_Wifi && (dmanum==1 || dmanum==3))
|
||||||
|
MMU.DMAStartTime[proc][dmanum] = EDMAMode7_GBASlot;
|
||||||
|
}
|
||||||
|
MMU.DMACrt[proc][dmanum] = v;
|
||||||
|
if(MMU.DMAStartTime[proc][dmanum] == EDMAMode_Immediate
|
||||||
|
//TODO HACK: I think this is a gxfifo hack:
|
||||||
|
|| MMU.DMAStartTime[proc][dmanum] == EDMAMode_GXFifo)
|
||||||
|
{
|
||||||
|
MMU_doDMA<proc>(dmanum);
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("dma ctrl %d %d\n",proc,dmanum);
|
||||||
|
|
||||||
|
//LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM9, 0, DMASrc[ARMCPU_ARM9][0], DMADst[ARMCPU_ARM9][0], (val&(1<<25))?"ON":"OFF");
|
||||||
|
|
||||||
|
NDS_RescheduleDMA();
|
||||||
|
}
|
||||||
|
|
||||||
static INLINE void write_auxspicnt(const int proc, const int size, const int adr, const int val)
|
static INLINE void write_auxspicnt(const int proc, const int size, const int adr, const int val)
|
||||||
{
|
{
|
||||||
//why val==0 to reset? is it a particular bit? its not bit 6...
|
//why val==0 to reset? is it a particular bit? its not bit 6...
|
||||||
|
@ -1869,6 +1949,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
||||||
|
|
||||||
case REG_IME:
|
case REG_IME:
|
||||||
{
|
{
|
||||||
|
NDS_Reschedule();
|
||||||
u32 old_val = MMU.reg_IME[ARMCPU_ARM9];
|
u32 old_val = MMU.reg_IME[ARMCPU_ARM9];
|
||||||
u32 new_val = val & 0x01;
|
u32 new_val = val & 0x01;
|
||||||
MMU.reg_IME[ARMCPU_ARM9] = new_val;
|
MMU.reg_IME[ARMCPU_ARM9] = new_val;
|
||||||
|
@ -1887,6 +1968,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case REG_IE :
|
case REG_IE :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF0000) | val;
|
MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF0000) | val;
|
||||||
#ifndef NEW_IRQ
|
#ifndef NEW_IRQ
|
||||||
if ( MMU.reg_IME[ARMCPU_ARM9])
|
if ( MMU.reg_IME[ARMCPU_ARM9])
|
||||||
|
@ -1901,6 +1983,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
case REG_IE + 2 :
|
case REG_IE + 2 :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF) | (((u32)val)<<16);
|
MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF) | (((u32)val)<<16);
|
||||||
#ifndef NEW_IRQ
|
#ifndef NEW_IRQ
|
||||||
if ( MMU.reg_IME[ARMCPU_ARM9])
|
if ( MMU.reg_IME[ARMCPU_ARM9])
|
||||||
|
@ -1916,9 +1999,11 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REG_IF :
|
case REG_IF :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IF[ARMCPU_ARM9] &= (~((u32)val));
|
MMU.reg_IF[ARMCPU_ARM9] &= (~((u32)val));
|
||||||
return;
|
return;
|
||||||
case REG_IF + 2 :
|
case REG_IF + 2 :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IF[ARMCPU_ARM9] &= (~(((u32)val)<<16));
|
MMU.reg_IF[ARMCPU_ARM9] &= (~(((u32)val)<<16));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1941,37 +2026,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
||||||
case REG_TM3CNTH :
|
case REG_TM3CNTH :
|
||||||
{
|
{
|
||||||
int timerIndex = ((adr-2)>>2)&0x3;
|
int timerIndex = ((adr-2)>>2)&0x3;
|
||||||
int mask = ((val&0x80)>>7) << timerIndex;
|
write_timer(ARMCPU_ARM9, timerIndex, val);
|
||||||
MMU.CheckTimers = (MMU.CheckTimers & (~mask)) | mask;
|
|
||||||
|
|
||||||
if(val&0x80)
|
|
||||||
MMU.timer[ARMCPU_ARM9][timerIndex] = MMU.timerReload[ARMCPU_ARM9][((adr-2)>>2)&0x3];
|
|
||||||
|
|
||||||
MMU.timerON[ARMCPU_ARM9][((adr-2)>>2)&0x3] = val & 0x80;
|
|
||||||
|
|
||||||
switch(val&7)
|
|
||||||
{
|
|
||||||
case 0 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 0+1;//ARMCPU_ARM9;
|
|
||||||
break;
|
|
||||||
case 1 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 6+1;//ARMCPU_ARM9;
|
|
||||||
break;
|
|
||||||
case 2 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 8+1;//ARMCPU_ARM9;
|
|
||||||
break;
|
|
||||||
case 3 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 10+1;//ARMCPU_ARM9;
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 0xFFFF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!(val & 0x80))
|
|
||||||
MMU.timerRUN[ARMCPU_ARM9][timerIndex] = FALSE;
|
|
||||||
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & 0xFFF, val);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2021,95 +2076,17 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
case REG_DMA0CNTH :
|
case REG_DMA0CNTH :
|
||||||
{
|
write_dma_hictrl<ARMCPU_ARM9>(0,val);
|
||||||
u32 v;
|
|
||||||
//if(val&0x8000) emu_halt();
|
|
||||||
//LOG("16 bit dma0 %04X\r\n", val);
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xBA, val);
|
|
||||||
DMASrc[ARMCPU_ARM9][0] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xB0);
|
|
||||||
DMADst[ARMCPU_ARM9][0] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xB4);
|
|
||||||
DMAtoVRAMmapping<0>();
|
|
||||||
v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xB8);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][0] = (v>>27) & 0x7;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM9][0] = v;
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][0] == 0)
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(0);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM9, 0, DMASrc[ARMCPU_ARM9][0], DMADst[ARMCPU_ARM9][0], (val&(1<<25))?"ON":"OFF");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA1CNTH :
|
case REG_DMA1CNTH :
|
||||||
{
|
write_dma_hictrl<ARMCPU_ARM9>(1,val);
|
||||||
u32 v;
|
|
||||||
//if(val&0x8000) emu_halt();
|
|
||||||
//LOG("16 bit dma1 %04X\r\n", val);
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC6, val);
|
|
||||||
DMASrc[ARMCPU_ARM9][1] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xBC);
|
|
||||||
DMADst[ARMCPU_ARM9][1] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC0);
|
|
||||||
DMAtoVRAMmapping<1>();
|
|
||||||
v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC4);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][1] = (v>>27) & 0x7;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM9][1] = v;
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][1] == 0)
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(1);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM9, 1, DMASrc[ARMCPU_ARM9][1], DMADst[ARMCPU_ARM9][1], (val&(1<<25))?"ON":"OFF");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA2CNTH :
|
case REG_DMA2CNTH :
|
||||||
{
|
write_dma_hictrl<ARMCPU_ARM9>(2,val);
|
||||||
u32 v;
|
|
||||||
//if(val&0x8000) emu_halt();
|
|
||||||
//LOG("16 bit dma2 %04X\r\n", val);
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD2, val);
|
|
||||||
DMASrc[ARMCPU_ARM9][2] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC8);
|
|
||||||
DMADst[ARMCPU_ARM9][2] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xCC);
|
|
||||||
DMAtoVRAMmapping<2>();
|
|
||||||
v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD0);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][2] = (v>>27) & 0x7;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM9][2] = v;
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][2] == 0)
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(2);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM9, 2, DMASrc[ARMCPU_ARM9][2], DMADst[ARMCPU_ARM9][2], (val&(1<<25))?"ON":"OFF");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA3CNTH :
|
case REG_DMA3CNTH :
|
||||||
{
|
write_dma_hictrl<ARMCPU_ARM9>(3,val);
|
||||||
u32 v;
|
|
||||||
//if(val&0x8000) emu_halt();
|
|
||||||
//LOG("16 bit dma3 %04X\r\n", val);
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xDE, val);
|
|
||||||
DMASrc[ARMCPU_ARM9][3] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD4);
|
|
||||||
DMADst[ARMCPU_ARM9][3] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD8);
|
|
||||||
DMAtoVRAMmapping<3>();
|
|
||||||
v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xDC);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][3] = (v>>27) & 0x7;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM9][3] = v;
|
|
||||||
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][3] == 0)
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(3);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM9, 3, DMASrc[ARMCPU_ARM9][3], DMADst[ARMCPU_ARM9][3], (val&(1<<25))?"ON":"OFF");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
//case REG_AUXSPICNT : emu_halt();
|
|
||||||
case REG_DISPA_DISPMMEMFIFO:
|
case REG_DISPA_DISPMMEMFIFO:
|
||||||
{
|
{
|
||||||
DISP_FIFOsend(val);
|
DISP_FIFOsend(val);
|
||||||
|
@ -2382,6 +2359,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
||||||
|
|
||||||
case REG_IME :
|
case REG_IME :
|
||||||
{
|
{
|
||||||
|
NDS_Reschedule();
|
||||||
u32 old_val = MMU.reg_IME[ARMCPU_ARM9];
|
u32 old_val = MMU.reg_IME[ARMCPU_ARM9];
|
||||||
u32 new_val = val & 0x01;
|
u32 new_val = val & 0x01;
|
||||||
MMU.reg_IME[ARMCPU_ARM9] = new_val;
|
MMU.reg_IME[ARMCPU_ARM9] = new_val;
|
||||||
|
@ -2401,6 +2379,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REG_IE :
|
case REG_IE :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IE[ARMCPU_ARM9] = val;
|
MMU.reg_IE[ARMCPU_ARM9] = val;
|
||||||
#ifndef NEW_IRQ
|
#ifndef NEW_IRQ
|
||||||
if ( MMU.reg_IME[ARMCPU_ARM9])
|
if ( MMU.reg_IME[ARMCPU_ARM9])
|
||||||
|
@ -2416,6 +2395,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REG_IF :
|
case REG_IF :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IF[ARMCPU_ARM9] &= (~val);
|
MMU.reg_IF[ARMCPU_ARM9] &= (~val);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2425,36 +2405,9 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
||||||
case REG_TM3CNTL:
|
case REG_TM3CNTL:
|
||||||
{
|
{
|
||||||
int timerIndex = (adr>>2)&0x3;
|
int timerIndex = (adr>>2)&0x3;
|
||||||
int mask = ((val & 0x800000)>>(16+7)) << timerIndex;
|
|
||||||
MMU.CheckTimers = (MMU.CheckTimers & (~mask)) | mask;
|
|
||||||
|
|
||||||
MMU.timerReload[ARMCPU_ARM9][timerIndex] = (u16)val;
|
MMU.timerReload[ARMCPU_ARM9][timerIndex] = (u16)val;
|
||||||
if(val&0x800000)
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & 0xFFF, val);
|
||||||
MMU.timer[ARMCPU_ARM9][timerIndex] = MMU.timerReload[ARMCPU_ARM9][(adr>>2)&0x3];
|
write_timer(ARMCPU_ARM9, timerIndex, val>>16);
|
||||||
|
|
||||||
MMU.timerON[ARMCPU_ARM9][timerIndex] = val & 0x800000;
|
|
||||||
switch((val>>16)&7)
|
|
||||||
{
|
|
||||||
case 0 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 0+1;//ARMCPU_ARM9;
|
|
||||||
break;
|
|
||||||
case 1 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 6+1;//ARMCPU_ARM9;
|
|
||||||
break;
|
|
||||||
case 2 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 8+1;//ARMCPU_ARM9;
|
|
||||||
break;
|
|
||||||
case 3 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 10+1;//ARMCPU_ARM9;
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM9][timerIndex] = 0xFFFF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!(val & 0x800000))
|
|
||||||
MMU.timerRUN[ARMCPU_ARM9][timerIndex] = FALSE;
|
|
||||||
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & 0xFFF, val);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2492,77 +2445,20 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REG_DMA0CNTL :
|
case REG_DMA0CNTL :
|
||||||
//LOG("32 bit dma0 %04X\r\n", val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xB8, val); //write the low word
|
||||||
DMASrc[ARMCPU_ARM9][0] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xB0);
|
write_dma_hictrl<ARMCPU_ARM9>(0,val>>16);
|
||||||
DMADst[ARMCPU_ARM9][0] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xB4);
|
|
||||||
DMAtoVRAMmapping<0>();
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][0] = (val>>27) & 0x7;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM9][0] = val;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xB8, val);
|
|
||||||
if( MMU.DMAStartTime[ARMCPU_ARM9][0] == 0 ||
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][0] == 7) // Start Immediately
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(0);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X start taille %d %d\r\n", ARMCPU_ARM9, 0, DMASrc[ARMCPU_ARM9][0], DMADst[ARMCPU_ARM9][0], 0, ((MMU.DMACrt[ARMCPU_ARM9][0]>>27)&7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//emu_halt();
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA1CNTL:
|
case REG_DMA1CNTL:
|
||||||
//LOG("32 bit dma1 %04X\r\n", val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC4, val); //write the low word
|
||||||
DMASrc[ARMCPU_ARM9][1] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xBC);
|
write_dma_hictrl<ARMCPU_ARM9>(1,val>>16);
|
||||||
DMADst[ARMCPU_ARM9][1] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC0);
|
|
||||||
DMAtoVRAMmapping<1>();
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][1] = (val>>27) & 0x7;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM9][1] = val;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC4, val);
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][1] == 0 ||
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][1] == 7) // Start Immediately
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(1);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X start taille %d %d\r\n", ARMCPU_ARM9, 1, DMASrc[ARMCPU_ARM9][1], DMADst[ARMCPU_ARM9][1], 0, ((MMU.DMACrt[ARMCPU_ARM9][1]>>27)&7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA2CNTL :
|
case REG_DMA2CNTL :
|
||||||
//LOG("32 bit dma2 %04X\r\n", val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD0, val); //write the low word
|
||||||
DMASrc[ARMCPU_ARM9][2] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC8);
|
write_dma_hictrl<ARMCPU_ARM9>(2,val>>16);
|
||||||
DMADst[ARMCPU_ARM9][2] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xCC);
|
|
||||||
DMAtoVRAMmapping<2>();
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][2] = (val>>27) & 0x7;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM9][2] = val;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD0, val);
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][2] == 0 ||
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][2] == 7) // Start Immediately
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(2);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X start taille %d %d\r\n", ARMCPU_ARM9, 2, DMASrc[ARMCPU_ARM9][2], DMADst[ARMCPU_ARM9][2], 0, ((MMU.DMACrt[ARMCPU_ARM9][2]>>27)&7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA3CNTL :
|
case REG_DMA3CNTL :
|
||||||
//LOG("32 bit dma3 %04X\r\n", val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xDC, val); //write the low word
|
||||||
DMASrc[ARMCPU_ARM9][3] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD4);
|
write_dma_hictrl<ARMCPU_ARM9>(3,val>>16);
|
||||||
DMADst[ARMCPU_ARM9][3] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD8);
|
|
||||||
DMAtoVRAMmapping<3>();
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][3] = (val>>27) & 0x7;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM9][3] = val;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xDC, val);
|
|
||||||
if( MMU.DMAStartTime[ARMCPU_ARM9][3] == 0 ||
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM9][3] == 7) // Start Immediately
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(3);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM9 %d, dma %d src %08X dst %08X start taille %d %d\r\n", ARMCPU_ARM9, 3, DMASrc[ARMCPU_ARM9][3], DMADst[ARMCPU_ARM9][3], 0, ((MMU.DMACrt[ARMCPU_ARM9][3]>>27)&7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
case REG_GCROMCTRL :
|
case REG_GCROMCTRL :
|
||||||
{
|
{
|
||||||
|
@ -2640,23 +2536,11 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
||||||
val |= 0x00800000;
|
val |= 0x00800000;
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4, val);
|
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4, val);
|
||||||
|
|
||||||
/* launch DMA if start flag was set to "DS Cart" */
|
//launch DMA if start flag was set to "DS Cart"
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][0] == 5)
|
if(MMU.DMAStartTime[ARMCPU_ARM9][0] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM9>(0);
|
||||||
{
|
if(MMU.DMAStartTime[ARMCPU_ARM9][1] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM9>(1);
|
||||||
MMU_doDMA<ARMCPU_ARM9>(0);
|
if(MMU.DMAStartTime[ARMCPU_ARM9][2] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM9>(2);
|
||||||
}
|
if(MMU.DMAStartTime[ARMCPU_ARM9][3] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM9>(3);
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][1] == 5)
|
|
||||||
{
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(1);
|
|
||||||
}
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][2] == 5)
|
|
||||||
{
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(2);
|
|
||||||
}
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM9][3] == 5)
|
|
||||||
{
|
|
||||||
MMU_doDMA<ARMCPU_ARM9>(3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case REG_DISPA_DISPCAPCNT :
|
case REG_DISPA_DISPCAPCNT :
|
||||||
|
@ -2768,7 +2652,7 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr)
|
||||||
case REG_TM1CNTL :
|
case REG_TM1CNTL :
|
||||||
case REG_TM2CNTL :
|
case REG_TM2CNTL :
|
||||||
case REG_TM3CNTL :
|
case REG_TM3CNTL :
|
||||||
return MMU.timer[ARMCPU_ARM9][(adr&0xF)>>2];
|
return read_timer(ARMCPU_ARM9,(adr&0xF)>>2);
|
||||||
|
|
||||||
case REG_AUXSPICNT:
|
case REG_AUXSPICNT:
|
||||||
return MMU.AUX_SPI_CNT;
|
return MMU.AUX_SPI_CNT;
|
||||||
|
@ -3246,6 +3130,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
||||||
|
|
||||||
case REG_IME :
|
case REG_IME :
|
||||||
{
|
{
|
||||||
|
NDS_Reschedule();
|
||||||
u32 old_val = MMU.reg_IME[ARMCPU_ARM7];
|
u32 old_val = MMU.reg_IME[ARMCPU_ARM7];
|
||||||
u32 new_val = val & 1;
|
u32 new_val = val & 1;
|
||||||
MMU.reg_IME[ARMCPU_ARM7] = new_val;
|
MMU.reg_IME[ARMCPU_ARM7] = new_val;
|
||||||
|
@ -3264,6 +3149,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case REG_IE :
|
case REG_IE :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF0000) | val;
|
MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF0000) | val;
|
||||||
#ifndef NEW_IRQ
|
#ifndef NEW_IRQ
|
||||||
if ( MMU.reg_IME[ARMCPU_ARM7])
|
if ( MMU.reg_IME[ARMCPU_ARM7])
|
||||||
|
@ -3278,6 +3164,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
case REG_IE + 2 :
|
case REG_IE + 2 :
|
||||||
|
NDS_Reschedule();
|
||||||
//emu_halt();
|
//emu_halt();
|
||||||
MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF) | (((u32)val)<<16);
|
MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF) | (((u32)val)<<16);
|
||||||
#ifndef NEW_IRQ
|
#ifndef NEW_IRQ
|
||||||
|
@ -3294,10 +3181,12 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REG_IF :
|
case REG_IF :
|
||||||
|
NDS_Reschedule();
|
||||||
//emu_halt();
|
//emu_halt();
|
||||||
MMU.reg_IF[ARMCPU_ARM7] &= (~((u32)val));
|
MMU.reg_IF[ARMCPU_ARM7] &= (~((u32)val));
|
||||||
return;
|
return;
|
||||||
case REG_IF + 2 :
|
case REG_IF + 2 :
|
||||||
|
NDS_Reschedule();
|
||||||
//emu_halt();
|
//emu_halt();
|
||||||
MMU.reg_IF[ARMCPU_ARM7] &= (~(((u32)val)<<16));
|
MMU.reg_IF[ARMCPU_ARM7] &= (~(((u32)val)<<16));
|
||||||
return;
|
return;
|
||||||
|
@ -3321,127 +3210,22 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
||||||
case REG_TM3CNTH :
|
case REG_TM3CNTH :
|
||||||
{
|
{
|
||||||
int timerIndex = ((adr-2)>>2)&0x3;
|
int timerIndex = ((adr-2)>>2)&0x3;
|
||||||
int mask = ((val&0x80)>>7) << (timerIndex+(ARMCPU_ARM7<<2));
|
write_timer(ARMCPU_ARM7, timerIndex, val);
|
||||||
MMU.CheckTimers = (MMU.CheckTimers & (~mask)) | mask;
|
|
||||||
|
|
||||||
if(val&0x80)
|
|
||||||
MMU.timer[ARMCPU_ARM7][timerIndex] = MMU.timerReload[ARMCPU_ARM7][((adr-2)>>2)&0x3];
|
|
||||||
|
|
||||||
MMU.timerON[ARMCPU_ARM7][((adr-2)>>2)&0x3] = val & 0x80;
|
|
||||||
|
|
||||||
switch(val&7)
|
|
||||||
{
|
|
||||||
case 0 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 0+1;//ARMCPU_ARM7;
|
|
||||||
break;
|
|
||||||
case 1 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 6+1;//ARMCPU_ARM7;
|
|
||||||
break;
|
|
||||||
case 2 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 8+1;//ARMCPU_ARM7;
|
|
||||||
break;
|
|
||||||
case 3 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 10+1;//ARMCPU_ARM7;
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 0xFFFF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!(val & 0x80))
|
|
||||||
MMU.timerRUN[ARMCPU_ARM7][timerIndex] = FALSE;
|
|
||||||
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & 0xFFF, val);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
case REG_DMA0CNTH :
|
case REG_DMA0CNTH :
|
||||||
{
|
write_dma_hictrl<ARMCPU_ARM7>(0,val);
|
||||||
u32 v;
|
|
||||||
|
|
||||||
//if(val&0x8000) emu_halt();
|
|
||||||
//LOG("16 bit dma0 %04X\r\n", val);
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xBA, val);
|
|
||||||
DMASrc[ARMCPU_ARM7][0] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xB0);
|
|
||||||
DMADst[ARMCPU_ARM7][0] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xB4);
|
|
||||||
v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xB8);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][0] = (v>>28) & 0x3;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM7][0] = v;
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM7][0] == 0)
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(0);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM7 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM7, 0, DMASrc[ARMCPU_ARM7][0], DMADst[ARMCPU_ARM7][0], (val&(1<<25))?"ON":"OFF");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA1CNTH :
|
case REG_DMA1CNTH :
|
||||||
{
|
write_dma_hictrl<ARMCPU_ARM7>(1,val);
|
||||||
u32 v;
|
|
||||||
//if(val&0x8000) emu_halt();
|
|
||||||
//LOG("16 bit dma1 %04X\r\n", val);
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC6, val);
|
|
||||||
DMASrc[ARMCPU_ARM7][1] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xBC);
|
|
||||||
DMADst[ARMCPU_ARM7][1] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC0);
|
|
||||||
v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC4);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][1] = (v>>28) & 0x3;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM7][1] = v;
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM7][1] == 0)
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(1);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM7 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM7, 1, DMASrc[ARMCPU_ARM7][1], DMADst[ARMCPU_ARM7][1], (val&(1<<25))?"ON":"OFF");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA2CNTH :
|
case REG_DMA2CNTH :
|
||||||
{
|
write_dma_hictrl<ARMCPU_ARM7>(2,val);
|
||||||
u32 v;
|
|
||||||
//if(val&0x8000) emu_halt();
|
|
||||||
//LOG("16 bit dma2 %04X\r\n", val);
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD2, val);
|
|
||||||
DMASrc[ARMCPU_ARM7][2] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC8);
|
|
||||||
DMADst[ARMCPU_ARM7][2] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xCC);
|
|
||||||
v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD0);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][2] = (v>>28) & 0x3;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM7][2] = v;
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM7][2] == 0)
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(2);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM7 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM7, 2, DMASrc[ARMCPU_ARM7][2], DMADst[ARMCPU_ARM7][2], (val&(1<<25))?"ON":"OFF");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA3CNTH :
|
case REG_DMA3CNTH :
|
||||||
{
|
write_dma_hictrl<ARMCPU_ARM7>(3,val);
|
||||||
u32 v;
|
|
||||||
//if(val&0x8000) emu_halt();
|
|
||||||
//LOG("16 bit dma3 %04X\r\n", val);
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xDE, val);
|
|
||||||
DMASrc[ARMCPU_ARM7][3] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD4);
|
|
||||||
DMADst[ARMCPU_ARM7][3] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD8);
|
|
||||||
v = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xDC);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][3] = (v>>28) & 0x3;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM7][3] = v;
|
|
||||||
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM7][3] == 0)
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(3);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
//else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM7 %d, dma %d src %08X dst %08X %s\r\n", ARMCPU_ARM7, 3, DMASrc[ARMCPU_ARM7][3], DMADst[ARMCPU_ARM7][3], (val&(1<<25))?"ON":"OFF");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
//case REG_AUXSPICNT : emu_halt();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr&MMU.MMU_MASK[ARMCPU_ARM7][adr>>20], val);
|
||||||
|
@ -3497,6 +3281,7 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
||||||
|
|
||||||
case REG_IME :
|
case REG_IME :
|
||||||
{
|
{
|
||||||
|
NDS_Reschedule();
|
||||||
u32 old_val = MMU.reg_IME[ARMCPU_ARM7];
|
u32 old_val = MMU.reg_IME[ARMCPU_ARM7];
|
||||||
u32 new_val = val & 1;
|
u32 new_val = val & 1;
|
||||||
MMU.reg_IME[ARMCPU_ARM7] = new_val;
|
MMU.reg_IME[ARMCPU_ARM7] = new_val;
|
||||||
|
@ -3516,6 +3301,7 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
||||||
}
|
}
|
||||||
|
|
||||||
case REG_IE :
|
case REG_IE :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IE[ARMCPU_ARM7] = val;
|
MMU.reg_IE[ARMCPU_ARM7] = val;
|
||||||
#ifndef NEW_IRQ
|
#ifndef NEW_IRQ
|
||||||
if ( MMU.reg_IME[ARMCPU_ARM7])
|
if ( MMU.reg_IME[ARMCPU_ARM7])
|
||||||
|
@ -3531,6 +3317,7 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REG_IF :
|
case REG_IF :
|
||||||
|
NDS_Reschedule();
|
||||||
MMU.reg_IF[ARMCPU_ARM7] &= (~val);
|
MMU.reg_IF[ARMCPU_ARM7] &= (~val);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3540,38 +3327,13 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
||||||
case REG_TM3CNTL:
|
case REG_TM3CNTL:
|
||||||
{
|
{
|
||||||
int timerIndex = (adr>>2)&0x3;
|
int timerIndex = (adr>>2)&0x3;
|
||||||
int mask = ((val & 0x800000)>>(16+7)) << (timerIndex+(ARMCPU_ARM7<<2));
|
|
||||||
MMU.CheckTimers = (MMU.CheckTimers & (~mask)) | mask;
|
|
||||||
|
|
||||||
MMU.timerReload[ARMCPU_ARM7][timerIndex] = (u16)val;
|
MMU.timerReload[ARMCPU_ARM7][timerIndex] = (u16)val;
|
||||||
if(val&0x800000)
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & 0xFFF, val);
|
||||||
MMU.timer[ARMCPU_ARM7][timerIndex] = MMU.timerReload[ARMCPU_ARM7][(adr>>2)&0x3];
|
write_timer(ARMCPU_ARM7, timerIndex, val>>16);
|
||||||
|
|
||||||
MMU.timerON[ARMCPU_ARM7][timerIndex] = val & 0x800000;
|
|
||||||
switch((val>>16)&7)
|
|
||||||
{
|
|
||||||
case 0 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 0+1;//ARMCPU_ARM7;
|
|
||||||
break;
|
|
||||||
case 1 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 6+1;//ARMCPU_ARM7;
|
|
||||||
break;
|
|
||||||
case 2 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 8+1;//ARMCPU_ARM7;
|
|
||||||
break;
|
|
||||||
case 3 :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 10+1;//ARMCPU_ARM7;
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
MMU.timerMODE[ARMCPU_ARM7][timerIndex] = 0xFFFF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!(val & 0x800000))
|
|
||||||
MMU.timerRUN[ARMCPU_ARM7][timerIndex] = FALSE;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & 0xFFF, val);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case REG_IPCSYNC :
|
case REG_IPCSYNC :
|
||||||
MMU_IPCSync(ARMCPU_ARM7, val);
|
MMU_IPCSync(ARMCPU_ARM7, val);
|
||||||
return;
|
return;
|
||||||
|
@ -3579,75 +3341,24 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
||||||
case REG_IPCFIFOSEND :
|
case REG_IPCFIFOSEND :
|
||||||
IPC_FIFOsend(ARMCPU_ARM7, val);
|
IPC_FIFOsend(ARMCPU_ARM7, val);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REG_DMA0CNTL :
|
case REG_DMA0CNTL :
|
||||||
//LOG("32 bit dma0 %04X\r\n", val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xB8, val); //write the low word
|
||||||
DMASrc[ARMCPU_ARM7][0] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xB0);
|
write_dma_hictrl<ARMCPU_ARM7>(0,val>>16);
|
||||||
DMADst[ARMCPU_ARM7][0] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xB4);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][0] = (val>>28) & 0x3;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM7][0] = val;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xB8, val);
|
|
||||||
if( MMU.DMAStartTime[ARMCPU_ARM7][0] == 0 ||
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][0] == 7) // Start Immediately
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(0);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM7 %d, dma %d src %08X dst %08X start taille %d %d\r\n", ARMCPU_ARM7, 0, DMASrc[ARMCPU_ARM7][0], DMADst[ARMCPU_ARM7][0], 0, ((MMU.DMACrt[ARMCPU_ARM7][0]>>27)&7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//emu_halt();
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA1CNTL:
|
case REG_DMA1CNTL:
|
||||||
//LOG("32 bit dma1 %04X\r\n", val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC4, val); //write the low word
|
||||||
DMASrc[ARMCPU_ARM7][1] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xBC);
|
write_dma_hictrl<ARMCPU_ARM7>(1,val>>16);
|
||||||
DMADst[ARMCPU_ARM7][1] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC0);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][1] = (val>>28) & 0x3;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM7][1] = val;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC4, val);
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM7][1] == 0 ||
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][1] == 7) // Start Immediately
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(1);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM7 %d, dma %d src %08X dst %08X start taille %d %d\r\n", ARMCPU_ARM7, 1, DMASrc[ARMCPU_ARM7][1], DMADst[ARMCPU_ARM7][1], 0, ((MMU.DMACrt[ARMCPU_ARM7][1]>>27)&7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA2CNTL :
|
case REG_DMA2CNTL :
|
||||||
//LOG("32 bit dma2 %04X\r\n", val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD0, val); //write the low word
|
||||||
DMASrc[ARMCPU_ARM7][2] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC8);
|
write_dma_hictrl<ARMCPU_ARM7>(2,val>>16);
|
||||||
DMADst[ARMCPU_ARM7][2] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xCC);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][2] = (val>>28) & 0x3;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM7][2] = val;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD0, val);
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM7][2] == 0 ||
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][2] == 7) // Start Immediately
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(2);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM7 %d, dma %d src %08X dst %08X start taille %d %d\r\n", ARMCPU_ARM7, 2, DMASrc[ARMCPU_ARM7][2], DMADst[ARMCPU_ARM7][2], 0, ((MMU.DMACrt[ARMCPU_ARM7][2]>>27)&7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
case REG_DMA3CNTL :
|
case REG_DMA3CNTL :
|
||||||
//LOG("32 bit dma3 %04X\r\n", val);
|
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xDC, val); //write the low word
|
||||||
DMASrc[ARMCPU_ARM7][3] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD4);
|
write_dma_hictrl<ARMCPU_ARM7>(3,val>>16);
|
||||||
DMADst[ARMCPU_ARM7][3] = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD8);
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][3] = (val>>28) & 0x3;
|
|
||||||
MMU.DMACrt[ARMCPU_ARM7][3] = val;
|
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xDC, val);
|
|
||||||
if( MMU.DMAStartTime[ARMCPU_ARM7][3] == 0 ||
|
|
||||||
MMU.DMAStartTime[ARMCPU_ARM7][3] == 7) // Start Immediately
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(3);
|
|
||||||
#ifdef LOG_DMA2
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG("ARMCPU_ARM7 %d, dma %d src %08X dst %08X start taille %d %d\r\n", ARMCPU_ARM7, 3, DMASrc[ARMCPU_ARM7][3], DMADst[ARMCPU_ARM7][3], 0, ((MMU.DMACrt[ARMCPU_ARM7][3]>>27)&7));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case REG_GCROMCTRL :
|
case REG_GCROMCTRL :
|
||||||
{
|
{
|
||||||
if(!(val & 0x80000000))
|
if(!(val & 0x80000000))
|
||||||
|
@ -3707,16 +3418,11 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
||||||
val |= 0x00800000;
|
val |= 0x00800000;
|
||||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4, val);
|
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4, val);
|
||||||
|
|
||||||
/* launch DMA if start flag was set to "DS Cart" */
|
//launch DMA if start flag was set to "DS Cart"
|
||||||
|
if(MMU.DMAStartTime[ARMCPU_ARM7][0] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(0);
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM7][2] == 2)
|
if(MMU.DMAStartTime[ARMCPU_ARM7][1] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(1);
|
||||||
{
|
if(MMU.DMAStartTime[ARMCPU_ARM7][2] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(2);
|
||||||
MMU_doDMA<ARMCPU_ARM7>(2);
|
if(MMU.DMAStartTime[ARMCPU_ARM7][3] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(3);
|
||||||
}
|
|
||||||
if(MMU.DMAStartTime[ARMCPU_ARM7][3] == 2)
|
|
||||||
{
|
|
||||||
MMU_doDMA<ARMCPU_ARM7>(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3803,7 +3509,7 @@ u16 FASTCALL _MMU_ARM7_read16(u32 adr)
|
||||||
case REG_TM1CNTL :
|
case REG_TM1CNTL :
|
||||||
case REG_TM2CNTL :
|
case REG_TM2CNTL :
|
||||||
case REG_TM3CNTL :
|
case REG_TM3CNTL :
|
||||||
return MMU.timer[ARMCPU_ARM7][(adr&0xF)>>2];
|
return read_timer(ARMCPU_ARM7,(adr&0xF)>>2);
|
||||||
|
|
||||||
case REG_AUXSPICNT:
|
case REG_AUXSPICNT:
|
||||||
return MMU.AUX_SPI_CNT;
|
return MMU.AUX_SPI_CNT;
|
||||||
|
|
|
@ -97,7 +97,7 @@ struct MMU_struct {
|
||||||
u32 reg_IF[2];
|
u32 reg_IF[2];
|
||||||
|
|
||||||
u32 DMAStartTime[2][4];
|
u32 DMAStartTime[2][4];
|
||||||
s32 DMACycle[2][4];
|
u64 DMACycle[2][4];
|
||||||
u32 DMACrt[2][4];
|
u32 DMACrt[2][4];
|
||||||
BOOL DMAing[2][4];
|
BOOL DMAing[2][4];
|
||||||
|
|
||||||
|
@ -105,21 +105,19 @@ struct MMU_struct {
|
||||||
s64 divResult;
|
s64 divResult;
|
||||||
s64 divMod;
|
s64 divMod;
|
||||||
u32 divCnt;
|
u32 divCnt;
|
||||||
s32 divCycles;
|
u64 divCycles;
|
||||||
|
|
||||||
BOOL sqrtRunning;
|
BOOL sqrtRunning;
|
||||||
u32 sqrtResult;
|
u32 sqrtResult;
|
||||||
u32 sqrtCnt;
|
u32 sqrtCnt;
|
||||||
s32 sqrtCycles;
|
u64 sqrtCycles;
|
||||||
|
|
||||||
u16 SPI_CNT;
|
u16 SPI_CNT;
|
||||||
u16 SPI_CMD;
|
u16 SPI_CMD;
|
||||||
u16 AUX_SPI_CNT;
|
u16 AUX_SPI_CNT;
|
||||||
u16 AUX_SPI_CMD;
|
u16 AUX_SPI_CMD;
|
||||||
|
|
||||||
#ifdef USE_GEOMETRY_FIFO_EMULATION
|
u64 gfx3dCycles;
|
||||||
s32 gfx3dCycles;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
u8 powerMan_CntReg;
|
u8 powerMan_CntReg;
|
||||||
BOOL powerMan_CntRegWritten;
|
BOOL powerMan_CntRegWritten;
|
||||||
|
@ -265,6 +263,20 @@ inline void SetupMMU(bool debugConsole) {
|
||||||
//T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF],
|
//T1ReadWord(MMU.MMU_MEM[ARMCPU_ARM7][(adr >> 20) & 0xFF],
|
||||||
// adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]);
|
// adr & MMU.MMU_MASK[ARMCPU_ARM7][(adr >> 20) & 0xFF]);
|
||||||
|
|
||||||
|
enum EDMAMode
|
||||||
|
{
|
||||||
|
EDMAMode_Immediate = 0,
|
||||||
|
EDMAMode_VBlank = 1,
|
||||||
|
EDMAMode_HBlank = 2,
|
||||||
|
EDMAMode_HStart = 3,
|
||||||
|
EDMAMode_MemDisplay = 4,
|
||||||
|
EDMAMode_Card = 5,
|
||||||
|
EDMAMode_GBASlot = 6,
|
||||||
|
EDMAMode_GXFifo = 7,
|
||||||
|
EDMAMode7_Wifi = 8,
|
||||||
|
EDMAMode7_GBASlot = 9,
|
||||||
|
};
|
||||||
|
|
||||||
FORCEINLINE u8 _MMU_read08(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr)
|
FORCEINLINE u8 _MMU_read08(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr)
|
||||||
{
|
{
|
||||||
//special handling for DMA: read 0 from TCM
|
//special handling for DMA: read 0 from TCM
|
||||||
|
@ -427,6 +439,10 @@ FORCEINLINE void _MMU_write16(const int PROCNUM, const MMU_ACCESS_TYPE AT, const
|
||||||
|
|
||||||
FORCEINLINE void _MMU_write32(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr, u32 val)
|
FORCEINLINE void _MMU_write32(const int PROCNUM, const MMU_ACCESS_TYPE AT, const u32 addr, u32 val)
|
||||||
{
|
{
|
||||||
|
if(addr == 0x022D7900)
|
||||||
|
{
|
||||||
|
int zzz=9;
|
||||||
|
}
|
||||||
//special handling for DMA: discard writes to TCM
|
//special handling for DMA: discard writes to TCM
|
||||||
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_DMA)
|
if(PROCNUM==ARMCPU_ARM9 && AT == MMU_AT_DMA)
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -173,19 +173,19 @@ struct NDS_header
|
||||||
extern void debug();
|
extern void debug();
|
||||||
void emu_halt();
|
void emu_halt();
|
||||||
|
|
||||||
|
extern u64 nds_timer;
|
||||||
|
void NDS_Reschedule();
|
||||||
|
void NDS_RescheduleGXFIFO();
|
||||||
|
void NDS_RescheduleDMA();
|
||||||
|
void NDS_RescheduleTimers();
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
s32 ARM9Cycle;
|
|
||||||
s32 ARM7Cycle;
|
|
||||||
s32 wifiCycle;
|
s32 wifiCycle;
|
||||||
s32 cycles;
|
s32 cycles;
|
||||||
s32 timerCycle[2][4];
|
u64 timerCycle[2][4];
|
||||||
BOOL timerOver[2][4];
|
|
||||||
s32 nextHBlank;
|
|
||||||
u32 VCount;
|
u32 VCount;
|
||||||
u32 old;
|
u32 old;
|
||||||
s32 diff;
|
|
||||||
BOOL lignerendu;
|
|
||||||
|
|
||||||
u16 touchX;
|
u16 touchX;
|
||||||
u16 touchY;
|
u16 touchY;
|
||||||
|
|
|
@ -318,7 +318,7 @@ u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
|
||||||
|
|
||||||
case FIQ :
|
case FIQ :
|
||||||
{
|
{
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
|
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
|
||||||
SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
|
SWAP(armcpu->R[9], armcpu->R9_fiq, tmp);
|
||||||
SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
|
SWAP(armcpu->R[10], armcpu->R10_fiq, tmp);
|
||||||
|
|
|
@ -234,6 +234,8 @@ static INLINE void setIF(int PROCNUM, u32 flag)
|
||||||
|
|
||||||
if(ARMPROC.waitIRQ)
|
if(ARMPROC.waitIRQ)
|
||||||
ARMPROC.newIrqFlags |= flag;
|
ARMPROC.newIrqFlags |= flag;
|
||||||
|
extern void NDS_Reschedule();
|
||||||
|
NDS_Reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void NDS_makeARM9Int(u32 num)
|
static INLINE void NDS_makeARM9Int(u32 num)
|
||||||
|
|
|
@ -61,8 +61,10 @@ in this function: */
|
||||||
static void gfx3d_doFlush();
|
static void gfx3d_doFlush();
|
||||||
|
|
||||||
#ifdef USE_GEOMETRY_FIFO_EMULATION
|
#ifdef USE_GEOMETRY_FIFO_EMULATION
|
||||||
#define GFX_DELAY(x) MMU.gfx3dCycles = nds.cycles + (2*x)
|
inline void GFX_DELAY(int x) {
|
||||||
#define GFX_DELAY_M2(x) MMU.gfx3dCycles += (2*x)
|
MMU.gfx3dCycles = nds_timer + (2*x); NDS_RescheduleGXFIFO(); }
|
||||||
|
inline void GFX_DELAY_M2(int x) {
|
||||||
|
MMU.gfx3dCycles += (2*x); NDS_RescheduleGXFIFO(); }
|
||||||
#else
|
#else
|
||||||
#define GFX_DELAY(x)
|
#define GFX_DELAY(x)
|
||||||
#define GFX_DELAY_M2(x)
|
#define GFX_DELAY_M2(x)
|
||||||
|
|
|
@ -85,6 +85,8 @@ int write32le(u32 b, std::ostream* os)
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void writebool(bool b, std::ostream* os) { write32le(b?1:0,os); }
|
||||||
|
|
||||||
int write64le(u64 b, std::ostream* os)
|
int write64le(u64 b, std::ostream* os)
|
||||||
{
|
{
|
||||||
u8 s[8];
|
u8 s[8];
|
||||||
|
@ -155,6 +157,14 @@ int read32le(u32 *Bufo, std::istream *is)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int readbool(bool *b, std::istream* is)
|
||||||
|
{
|
||||||
|
u32 temp;
|
||||||
|
int ret = read32le(&temp,is);
|
||||||
|
*b = (bool)temp;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int readbuffer(std::vector<u8> &vec, std::istream* is)
|
int readbuffer(std::vector<u8> &vec, std::istream* is)
|
||||||
{
|
{
|
||||||
u32 size;
|
u32 size;
|
||||||
|
|
|
@ -21,6 +21,8 @@ int read32le(u32 *Bufo, FILE *fp);
|
||||||
int read16le(u16 *Bufo, std::istream *is);
|
int read16le(u16 *Bufo, std::istream *is);
|
||||||
inline int read16le(s16 *Bufo, std::istream* is) { return read16le((u16*)Bufo,is); }
|
inline int read16le(s16 *Bufo, std::istream* is) { return read16le((u16*)Bufo,is); }
|
||||||
int read8le(u8 *Bufo, std::istream *is);
|
int read8le(u8 *Bufo, std::istream *is);
|
||||||
|
int readbool(bool *b, std::istream* is);
|
||||||
|
void writebool(bool b, std::ostream* os);
|
||||||
|
|
||||||
int readbuffer(std::vector<u8> &vec, std::istream* is);
|
int readbuffer(std::vector<u8> &vec, std::istream* is);
|
||||||
int writebuffer(std::vector<u8>& vec, std::ostream* os);
|
int writebuffer(std::vector<u8>& vec, std::ostream* os);
|
||||||
|
|
|
@ -52,7 +52,7 @@ int lastSaveState = 0; //Keeps track of last savestate used for quick save/load
|
||||||
|
|
||||||
savestates_t savestates[NB_STATES];
|
savestates_t savestates[NB_STATES];
|
||||||
|
|
||||||
#define SAVESTATE_VERSION 11
|
#define SAVESTATE_VERSION 12
|
||||||
static const char* magic = "DeSmuME SState\0";
|
static const char* magic = "DeSmuME SState\0";
|
||||||
|
|
||||||
//a savestate chunk loader can set this if it wants to permit a silent failure (for compatibility)
|
//a savestate chunk loader can set this if it wants to permit a silent failure (for compatibility)
|
||||||
|
@ -161,17 +161,10 @@ SFORMAT SF_MEM[]={
|
||||||
};
|
};
|
||||||
|
|
||||||
SFORMAT SF_NDS[]={
|
SFORMAT SF_NDS[]={
|
||||||
{ "_9CY", 4, 1, &nds.ARM9Cycle},
|
|
||||||
{ "_7CY", 4, 1, &nds.ARM7Cycle},
|
|
||||||
{ "_CYC", 4, 1, &nds.cycles},
|
|
||||||
{ "_WCY", 4, 1, &nds.wifiCycle},
|
{ "_WCY", 4, 1, &nds.wifiCycle},
|
||||||
{ "_TCY", 4, 8, nds.timerCycle},
|
{ "_TCY", 8, 8, nds.timerCycle},
|
||||||
{ "_TOV", 4, 8, nds.timerOver},
|
|
||||||
{ "_NHB", 4, 1, &nds.nextHBlank},
|
|
||||||
{ "_VCT", 4, 1, &nds.VCount},
|
{ "_VCT", 4, 1, &nds.VCount},
|
||||||
{ "_OLD", 4, 1, &nds.old},
|
{ "_OLD", 4, 1, &nds.old},
|
||||||
{ "_DIF", 4, 1, &nds.diff},
|
|
||||||
{ "_LIG", 4, 1, &nds.lignerendu},
|
|
||||||
{ "_TPX", 2, 1, &nds.touchX},
|
{ "_TPX", 2, 1, &nds.touchX},
|
||||||
{ "_TPY", 2, 1, &nds.touchY},
|
{ "_TPY", 2, 1, &nds.touchY},
|
||||||
{ "_TPB", 4, 1, &nds.isTouch},
|
{ "_TPB", 4, 1, &nds.isTouch},
|
||||||
|
@ -201,13 +194,15 @@ SFORMAT SF_MMU[]={
|
||||||
{ "MIE_", 4, 2, MMU.reg_IE},
|
{ "MIE_", 4, 2, MMU.reg_IE},
|
||||||
{ "MIF_", 4, 2, MMU.reg_IF},
|
{ "MIF_", 4, 2, MMU.reg_IF},
|
||||||
|
|
||||||
|
{ "MGXC", 8, 1, &MMU.gfx3dCycles},
|
||||||
|
|
||||||
{ "M_SX", 1, 2, &MMU.SPI_CNT},
|
{ "M_SX", 1, 2, &MMU.SPI_CNT},
|
||||||
{ "M_SC", 1, 2, &MMU.SPI_CMD},
|
{ "M_SC", 1, 2, &MMU.SPI_CMD},
|
||||||
{ "MASX", 1, 2, &MMU.AUX_SPI_CNT},
|
{ "MASX", 1, 2, &MMU.AUX_SPI_CNT},
|
||||||
{ "MASC", 1, 2, &MMU.AUX_SPI_CMD},
|
{ "MASC", 1, 2, &MMU.AUX_SPI_CMD},
|
||||||
|
|
||||||
{ "MDST", 4, 8, MMU.DMAStartTime},
|
{ "MDST", 4, 8, MMU.DMAStartTime},
|
||||||
{ "MDCY", 4, 8, MMU.DMACycle},
|
{ "MDCY", 8, 8, MMU.DMACycle},
|
||||||
{ "MDCR", 4, 8, MMU.DMACrt},
|
{ "MDCR", 4, 8, MMU.DMACrt},
|
||||||
{ "MDMA", 4, 8, MMU.DMAing},
|
{ "MDMA", 4, 8, MMU.DMAing},
|
||||||
{ "MDSR", 4, 8, DMASrc},
|
{ "MDSR", 4, 8, DMASrc},
|
||||||
|
@ -217,12 +212,12 @@ SFORMAT SF_MMU[]={
|
||||||
{ "MDV2", 8, 1, &MMU.divResult},
|
{ "MDV2", 8, 1, &MMU.divResult},
|
||||||
{ "MDV3", 8, 1, &MMU.divMod},
|
{ "MDV3", 8, 1, &MMU.divMod},
|
||||||
{ "MDV4", 4, 1, &MMU.divCnt},
|
{ "MDV4", 4, 1, &MMU.divCnt},
|
||||||
{ "MDV5", 4, 1, &MMU.divCycles},
|
{ "MDV5", 8, 1, &MMU.divCycles},
|
||||||
|
|
||||||
{ "MSQ1", 4, 1, &MMU.sqrtRunning},
|
{ "MSQ1", 4, 1, &MMU.sqrtRunning},
|
||||||
{ "MSQ2", 4, 1, &MMU.sqrtResult},
|
{ "MSQ2", 4, 1, &MMU.sqrtResult},
|
||||||
{ "MSQ3", 4, 1, &MMU.sqrtCnt},
|
{ "MSQ3", 4, 1, &MMU.sqrtCnt},
|
||||||
{ "MSQ4", 4, 1, &MMU.sqrtCycles},
|
{ "MSQ4", 8, 1, &MMU.sqrtCycles},
|
||||||
|
|
||||||
//begin memory chips
|
//begin memory chips
|
||||||
//we are skipping the firmware, because we really don't want to save the firmware to the savestate
|
//we are skipping the firmware, because we really don't want to save the firmware to the savestate
|
||||||
|
@ -262,6 +257,9 @@ SFORMAT SF_MOVIE[]={
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void nds_savestate(std::ostream* os);
|
||||||
|
bool nds_loadstate(std::istream* is, int size);
|
||||||
|
|
||||||
static void mmu_savestate(std::ostream* os)
|
static void mmu_savestate(std::ostream* os)
|
||||||
{
|
{
|
||||||
//version
|
//version
|
||||||
|
@ -824,6 +822,7 @@ static void writechunks(std::ostream* os) {
|
||||||
savestate_WriteChunk(os,3,cp15_savestate);
|
savestate_WriteChunk(os,3,cp15_savestate);
|
||||||
savestate_WriteChunk(os,4,SF_MEM);
|
savestate_WriteChunk(os,4,SF_MEM);
|
||||||
savestate_WriteChunk(os,5,SF_NDS);
|
savestate_WriteChunk(os,5,SF_NDS);
|
||||||
|
savestate_WriteChunk(os,51,nds_savestate);
|
||||||
savestate_WriteChunk(os,60,SF_MMU);
|
savestate_WriteChunk(os,60,SF_MMU);
|
||||||
savestate_WriteChunk(os,61,mmu_savestate);
|
savestate_WriteChunk(os,61,mmu_savestate);
|
||||||
savestate_WriteChunk(os,7,gpu_savestate);
|
savestate_WriteChunk(os,7,gpu_savestate);
|
||||||
|
@ -852,6 +851,7 @@ static bool ReadStateChunks(std::istream* is, s32 totalsize)
|
||||||
case 3: if(!cp15_loadstate(is,size)) ret=false; break;
|
case 3: if(!cp15_loadstate(is,size)) ret=false; break;
|
||||||
case 4: if(!ReadStateChunk(is,SF_MEM,size)) ret=false; break;
|
case 4: if(!ReadStateChunk(is,SF_MEM,size)) ret=false; break;
|
||||||
case 5: if(!ReadStateChunk(is,SF_NDS,size)) ret=false; break;
|
case 5: if(!ReadStateChunk(is,SF_NDS,size)) ret=false; break;
|
||||||
|
case 51: if(!nds_loadstate(is,size)) ret=false; break;
|
||||||
case 60: if(!ReadStateChunk(is,SF_MMU,size)) ret=false; break;
|
case 60: if(!ReadStateChunk(is,SF_MMU,size)) ret=false; break;
|
||||||
case 61: if(!mmu_loadstate(is,size)) ret=false; break;
|
case 61: if(!mmu_loadstate(is,size)) ret=false; break;
|
||||||
case 7: if(!gpu_loadstate(is,size)) ret=false; break;
|
case 7: if(!gpu_loadstate(is,size)) ret=false; break;
|
||||||
|
|
|
@ -105,7 +105,7 @@
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8;
|
||||||
typedef unsigned short u16;
|
typedef unsigned short u16;
|
||||||
typedef unsigned int u32;
|
typedef unsigned int u32;
|
||||||
typedef unsigned long u64;
|
typedef unsigned long long u64;
|
||||||
|
|
||||||
typedef signed char s8;
|
typedef signed char s8;
|
||||||
typedef signed short s16;
|
typedef signed short s16;
|
||||||
|
|
|
@ -594,6 +594,22 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="filter"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath=".\filter\2xsai.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\filter\hq2x.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\filter\scanline.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="utils"
|
Name="utils"
|
||||||
|
@ -750,10 +766,6 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<File
|
|
||||||
RelativePath=".\filter\2xsai.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\addons.cpp"
|
RelativePath="..\addons.cpp"
|
||||||
>
|
>
|
||||||
|
@ -958,10 +970,6 @@
|
||||||
RelativePath="..\GPU_osd.h"
|
RelativePath="..\GPU_osd.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\filter\hq2x.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\lua-engine.cpp"
|
RelativePath="..\lua-engine.cpp"
|
||||||
>
|
>
|
||||||
|
@ -1090,10 +1098,6 @@
|
||||||
RelativePath="..\saves.h"
|
RelativePath="..\saves.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\filter\scanline.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath="..\shaders.h"
|
RelativePath="..\shaders.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -924,8 +924,8 @@ DWORD WINAPI run()
|
||||||
for(int i=0;i<16;i++)
|
for(int i=0;i<16;i++)
|
||||||
load = load/8 + nds.runCycleCollector[(i+nds.idleFrameCounter)&15]*7/8;
|
load = load/8 + nds.runCycleCollector[(i+nds.idleFrameCounter)&15]*7/8;
|
||||||
load = std::min(100,std::max(0,(int)(load*100/1120380)));
|
load = std::min(100,std::max(0,(int)(load*100/1120380)));
|
||||||
sprintf(txt,"(%02d%%) %s", load, DESMUME_NAME_AND_VERSION);
|
//sprintf(txt,"(%02d%%) %s", load, DESMUME_NAME_AND_VERSION);
|
||||||
SetWindowText(hwnd, txt);
|
SetWindowText(hwnd, DESMUME_NAME_AND_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!skipnextframe)
|
if(!skipnextframe)
|
||||||
|
|
Loading…
Reference in New Issue