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???)
|
||||
|
||||
??? introduces an entirely rewritten main emulation loop.
|
||||
This totally changes the timing, and totally breaks old savestates.
|
||||
|
||||
Highlights:
|
||||
* win32: lua engine, path configuration, 7z dearchiving support
|
||||
* rewritten main emulation loop
|
||||
|
||||
General/Core:
|
||||
bug: fix cflash directory support for non-windows
|
||||
bug: fix freeze in cart irq
|
||||
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
|
||||
|
||||
Graphics:
|
||||
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 edge marking
|
||||
|
||||
|
||||
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:
|
||||
enh: alsa microphone support
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "debug.h"
|
||||
#include "mem.h"
|
||||
#include "MMU.h"
|
||||
#include "NDSSystem.h"
|
||||
|
||||
// ========================================================= IPC FIFO
|
||||
IPC_FIFO ipc_fifo[2]; // 0 - ARM9
|
||||
|
@ -174,6 +175,8 @@ void GFX_FIFOsend(u8 cmd, u32 param)
|
|||
#endif
|
||||
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
||||
|
||||
NDS_RescheduleGXFIFO();
|
||||
}
|
||||
|
||||
BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
||||
|
@ -183,6 +186,7 @@ BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
|||
if (gxstat & 0xC0000000)
|
||||
{
|
||||
setIF(0, (1<<21));
|
||||
//NDS_makeARM9Int(21);
|
||||
}
|
||||
#endif
|
||||
if (gxFIFO.tail == 0) // empty
|
||||
|
@ -193,18 +197,23 @@ BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
|||
if ((gxstat & 0x80000000)) // empty
|
||||
{
|
||||
setIF(0, (1<<21));
|
||||
//NDS_makeARM9Int(21);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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 & 0x04000000) setIF(0, (1<<21));
|
||||
if (gxstat & 0x04000000)
|
||||
setIF(0, (1<<21));
|
||||
//NDS_makeARM9Int(21);
|
||||
}
|
||||
|
||||
gxstat &= 0xF000FFFF;
|
||||
|
@ -228,6 +237,8 @@ BOOL GFX_FIFOrecv(u8 *cmd, u32 *param)
|
|||
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
||||
|
||||
NDS_RescheduleGXFIFO();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -241,10 +252,13 @@ void GFX_FIFOcnt(u32 val)
|
|||
return;
|
||||
}
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat);
|
||||
|
||||
NDS_RescheduleGXFIFO();
|
||||
|
||||
/*if (gxstat & 0xC0000000)
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
struct VramConfiguration {
|
||||
|
||||
enum Purpose {
|
||||
|
@ -983,7 +968,7 @@ void MMU_clearMem()
|
|||
memset(MMU.reg_IF, 0, sizeof(u32) * 2);
|
||||
|
||||
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.DMAing, 0, sizeof(BOOL) * 2 * 4);
|
||||
|
||||
|
@ -1011,9 +996,7 @@ void MMU_clearMem()
|
|||
partie = 1;
|
||||
addonsReset();
|
||||
Mic_Reset();
|
||||
#ifdef USE_GEOMETRY_FIFO_EMULATION
|
||||
MMU.gfx3dCycles = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
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], 0x2B0, cnt | 0x8000);
|
||||
|
||||
MMU.sqrtCycles = (nds.cycles + 26);
|
||||
MMU.sqrtCycles = nds_timer + 26;
|
||||
MMU.sqrtResult = ret;
|
||||
MMU.sqrtCnt = (cnt & 0x7FFF);
|
||||
MMU.sqrtRunning = TRUE;
|
||||
NDS_Reschedule();
|
||||
}
|
||||
|
||||
static void execdiv() {
|
||||
|
@ -1078,19 +1062,19 @@ static void execdiv() {
|
|||
case 0:
|
||||
num = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
||||
den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
||||
MMU.divCycles = (nds.cycles + 36);
|
||||
MMU.divCycles = nds_timer + 36;
|
||||
break;
|
||||
case 1:
|
||||
case 3: //gbatek says this is same as mode 1
|
||||
num = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
||||
den = (s64) (s32) T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
||||
MMU.divCycles = (nds.cycles + 68);
|
||||
MMU.divCycles = nds_timer + 68;
|
||||
break;
|
||||
case 2:
|
||||
default:
|
||||
num = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x290);
|
||||
den = (s64) T1ReadQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x298);
|
||||
MMU.divCycles = (nds.cycles + 68);
|
||||
MMU.divCycles = nds_timer + 68;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1122,6 +1106,7 @@ static void execdiv() {
|
|||
MMU.divMod = mod;
|
||||
MMU.divCnt = (cnt & 0x7FFF);
|
||||
MMU.divRunning = TRUE;
|
||||
NDS_Reschedule();
|
||||
}
|
||||
|
||||
template<int PROCNUM>
|
||||
|
@ -1150,19 +1135,21 @@ void FASTCALL MMU_doDMA(u32 num)
|
|||
taille = (MMU.DMACrt[PROCNUM][num]&0x1FFFFF);
|
||||
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
|
||||
// screen (256x192 pixels).
|
||||
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
|
||||
// (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
|
||||
(((MMU.DMACrt[PROCNUM][num]>>26)&1) == 1)) // Transfer mode must be 32bit wide
|
||||
taille = 24576; //256*192/2;
|
||||
|
||||
if(MMU.DMAStartTime[PROCNUM][num] == 5)
|
||||
if(MMU.DMAStartTime[PROCNUM][num] == EDMAMode_Card)
|
||||
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.CheckDMAs |= (1<<(num+(PROCNUM<<2)));
|
||||
|
||||
|
@ -1172,6 +1159,8 @@ void FASTCALL MMU_doDMA(u32 num)
|
|||
|
||||
if(!(MMU.DMACrt[PROCNUM][num]&(1<<25)))
|
||||
MMU.DMAStartTime[PROCNUM][num] = 0;
|
||||
|
||||
NDS_RescheduleDMA();
|
||||
|
||||
// transfer
|
||||
{
|
||||
|
@ -1315,6 +1304,97 @@ static INLINE void MMU_IPCSync(u8 proc, u32 val)
|
|||
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)
|
||||
{
|
||||
//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:
|
||||
{
|
||||
NDS_Reschedule();
|
||||
u32 old_val = MMU.reg_IME[ARMCPU_ARM9];
|
||||
u32 new_val = val & 0x01;
|
||||
MMU.reg_IME[ARMCPU_ARM9] = new_val;
|
||||
|
@ -1887,6 +1968,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
|||
return;
|
||||
}
|
||||
case REG_IE :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF0000) | val;
|
||||
#ifndef NEW_IRQ
|
||||
if ( MMU.reg_IME[ARMCPU_ARM9])
|
||||
|
@ -1901,6 +1983,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
|||
#endif
|
||||
return;
|
||||
case REG_IE + 2 :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF) | (((u32)val)<<16);
|
||||
#ifndef NEW_IRQ
|
||||
if ( MMU.reg_IME[ARMCPU_ARM9])
|
||||
|
@ -1916,9 +1999,11 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
|||
return;
|
||||
|
||||
case REG_IF :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IF[ARMCPU_ARM9] &= (~((u32)val));
|
||||
return;
|
||||
case REG_IF + 2 :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IF[ARMCPU_ARM9] &= (~(((u32)val)<<16));
|
||||
return;
|
||||
|
||||
|
@ -1941,37 +2026,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
|||
case REG_TM3CNTH :
|
||||
{
|
||||
int timerIndex = ((adr-2)>>2)&0x3;
|
||||
int mask = ((val&0x80)>>7) << timerIndex;
|
||||
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);
|
||||
write_timer(ARMCPU_ARM9, timerIndex, val);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2021,95 +2076,17 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val)
|
|||
}
|
||||
|
||||
case REG_DMA0CNTH :
|
||||
{
|
||||
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
|
||||
}
|
||||
write_dma_hictrl<ARMCPU_ARM9>(0,val);
|
||||
return;
|
||||
case REG_DMA1CNTH :
|
||||
{
|
||||
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
|
||||
}
|
||||
write_dma_hictrl<ARMCPU_ARM9>(1,val);
|
||||
return;
|
||||
case REG_DMA2CNTH :
|
||||
{
|
||||
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
|
||||
}
|
||||
write_dma_hictrl<ARMCPU_ARM9>(2,val);
|
||||
return;
|
||||
case REG_DMA3CNTH :
|
||||
{
|
||||
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
|
||||
}
|
||||
write_dma_hictrl<ARMCPU_ARM9>(3,val);
|
||||
return;
|
||||
//case REG_AUXSPICNT : emu_halt();
|
||||
case REG_DISPA_DISPMMEMFIFO:
|
||||
{
|
||||
DISP_FIFOsend(val);
|
||||
|
@ -2382,6 +2359,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
|
||||
case REG_IME :
|
||||
{
|
||||
NDS_Reschedule();
|
||||
u32 old_val = MMU.reg_IME[ARMCPU_ARM9];
|
||||
u32 new_val = val & 0x01;
|
||||
MMU.reg_IME[ARMCPU_ARM9] = new_val;
|
||||
|
@ -2401,6 +2379,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
return;
|
||||
|
||||
case REG_IE :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IE[ARMCPU_ARM9] = val;
|
||||
#ifndef NEW_IRQ
|
||||
if ( MMU.reg_IME[ARMCPU_ARM9])
|
||||
|
@ -2416,6 +2395,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
return;
|
||||
|
||||
case REG_IF :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IF[ARMCPU_ARM9] &= (~val);
|
||||
return;
|
||||
|
||||
|
@ -2425,36 +2405,9 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
case REG_TM3CNTL:
|
||||
{
|
||||
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;
|
||||
if(val&0x800000)
|
||||
MMU.timer[ARMCPU_ARM9][timerIndex] = MMU.timerReload[ARMCPU_ARM9][(adr>>2)&0x3];
|
||||
|
||||
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);
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], adr & 0xFFF, val);
|
||||
write_timer(ARMCPU_ARM9, timerIndex, val>>16);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2492,77 +2445,20 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
return;
|
||||
|
||||
case REG_DMA0CNTL :
|
||||
//LOG("32 bit dma0 %04X\r\n", 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>();
|
||||
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();
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xB8, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM9>(0,val>>16);
|
||||
return;
|
||||
case REG_DMA1CNTL:
|
||||
//LOG("32 bit dma1 %04X\r\n", 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>();
|
||||
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
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xC4, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM9>(1,val>>16);
|
||||
return;
|
||||
case REG_DMA2CNTL :
|
||||
//LOG("32 bit dma2 %04X\r\n", 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>();
|
||||
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
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xD0, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM9>(2,val>>16);
|
||||
return;
|
||||
case REG_DMA3CNTL :
|
||||
//LOG("32 bit dma3 %04X\r\n", 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>();
|
||||
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
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0xDC, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM9>(3,val>>16);
|
||||
return;
|
||||
case REG_GCROMCTRL :
|
||||
{
|
||||
|
@ -2640,23 +2536,11 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val)
|
|||
val |= 0x00800000;
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1A4, val);
|
||||
|
||||
/* launch DMA if start flag was set to "DS Cart" */
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM9][0] == 5)
|
||||
{
|
||||
MMU_doDMA<ARMCPU_ARM9>(0);
|
||||
}
|
||||
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);
|
||||
}
|
||||
//launch DMA if start flag was set to "DS Cart"
|
||||
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);
|
||||
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);
|
||||
}
|
||||
return;
|
||||
case REG_DISPA_DISPCAPCNT :
|
||||
|
@ -2768,7 +2652,7 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr)
|
|||
case REG_TM1CNTL :
|
||||
case REG_TM2CNTL :
|
||||
case REG_TM3CNTL :
|
||||
return MMU.timer[ARMCPU_ARM9][(adr&0xF)>>2];
|
||||
return read_timer(ARMCPU_ARM9,(adr&0xF)>>2);
|
||||
|
||||
case REG_AUXSPICNT:
|
||||
return MMU.AUX_SPI_CNT;
|
||||
|
@ -3246,6 +3130,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
|||
|
||||
case REG_IME :
|
||||
{
|
||||
NDS_Reschedule();
|
||||
u32 old_val = MMU.reg_IME[ARMCPU_ARM7];
|
||||
u32 new_val = val & 1;
|
||||
MMU.reg_IME[ARMCPU_ARM7] = new_val;
|
||||
|
@ -3264,6 +3149,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
|||
return;
|
||||
}
|
||||
case REG_IE :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF0000) | val;
|
||||
#ifndef NEW_IRQ
|
||||
if ( MMU.reg_IME[ARMCPU_ARM7])
|
||||
|
@ -3278,6 +3164,7 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
|||
#endif
|
||||
return;
|
||||
case REG_IE + 2 :
|
||||
NDS_Reschedule();
|
||||
//emu_halt();
|
||||
MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF) | (((u32)val)<<16);
|
||||
#ifndef NEW_IRQ
|
||||
|
@ -3294,10 +3181,12 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
|||
return;
|
||||
|
||||
case REG_IF :
|
||||
NDS_Reschedule();
|
||||
//emu_halt();
|
||||
MMU.reg_IF[ARMCPU_ARM7] &= (~((u32)val));
|
||||
return;
|
||||
case REG_IF + 2 :
|
||||
NDS_Reschedule();
|
||||
//emu_halt();
|
||||
MMU.reg_IF[ARMCPU_ARM7] &= (~(((u32)val)<<16));
|
||||
return;
|
||||
|
@ -3321,127 +3210,22 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val)
|
|||
case REG_TM3CNTH :
|
||||
{
|
||||
int timerIndex = ((adr-2)>>2)&0x3;
|
||||
int mask = ((val&0x80)>>7) << (timerIndex+(ARMCPU_ARM7<<2));
|
||||
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);
|
||||
write_timer(ARMCPU_ARM7, timerIndex, val);
|
||||
return;
|
||||
}
|
||||
|
||||
case REG_DMA0CNTH :
|
||||
{
|
||||
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
|
||||
}
|
||||
write_dma_hictrl<ARMCPU_ARM7>(0,val);
|
||||
return;
|
||||
case REG_DMA1CNTH :
|
||||
{
|
||||
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
|
||||
}
|
||||
write_dma_hictrl<ARMCPU_ARM7>(1,val);
|
||||
return;
|
||||
case REG_DMA2CNTH :
|
||||
{
|
||||
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
|
||||
}
|
||||
write_dma_hictrl<ARMCPU_ARM7>(2,val);
|
||||
return;
|
||||
case REG_DMA3CNTH :
|
||||
{
|
||||
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
|
||||
}
|
||||
write_dma_hictrl<ARMCPU_ARM7>(3,val);
|
||||
return;
|
||||
//case REG_AUXSPICNT : emu_halt();
|
||||
}
|
||||
|
||||
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 :
|
||||
{
|
||||
NDS_Reschedule();
|
||||
u32 old_val = MMU.reg_IME[ARMCPU_ARM7];
|
||||
u32 new_val = val & 1;
|
||||
MMU.reg_IME[ARMCPU_ARM7] = new_val;
|
||||
|
@ -3516,6 +3301,7 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
|||
}
|
||||
|
||||
case REG_IE :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IE[ARMCPU_ARM7] = val;
|
||||
#ifndef NEW_IRQ
|
||||
if ( MMU.reg_IME[ARMCPU_ARM7])
|
||||
|
@ -3531,6 +3317,7 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
|||
return;
|
||||
|
||||
case REG_IF :
|
||||
NDS_Reschedule();
|
||||
MMU.reg_IF[ARMCPU_ARM7] &= (~val);
|
||||
return;
|
||||
|
||||
|
@ -3540,38 +3327,13 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
|||
case REG_TM3CNTL:
|
||||
{
|
||||
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;
|
||||
if(val&0x800000)
|
||||
MMU.timer[ARMCPU_ARM7][timerIndex] = MMU.timerReload[ARMCPU_ARM7][(adr>>2)&0x3];
|
||||
|
||||
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);
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], adr & 0xFFF, val);
|
||||
write_timer(ARMCPU_ARM7, timerIndex, val>>16);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
case REG_IPCSYNC :
|
||||
MMU_IPCSync(ARMCPU_ARM7, val);
|
||||
return;
|
||||
|
@ -3579,75 +3341,24 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
|||
case REG_IPCFIFOSEND :
|
||||
IPC_FIFOsend(ARMCPU_ARM7, val);
|
||||
return;
|
||||
|
||||
case REG_DMA0CNTL :
|
||||
//LOG("32 bit dma0 %04X\r\n", 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);
|
||||
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();
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xB8, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM7>(0,val>>16);
|
||||
return;
|
||||
case REG_DMA1CNTL:
|
||||
//LOG("32 bit dma1 %04X\r\n", 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);
|
||||
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
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xC4, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM7>(1,val>>16);
|
||||
return;
|
||||
case REG_DMA2CNTL :
|
||||
//LOG("32 bit dma2 %04X\r\n", 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);
|
||||
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
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xD0, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM7>(2,val>>16);
|
||||
return;
|
||||
case REG_DMA3CNTL :
|
||||
//LOG("32 bit dma3 %04X\r\n", 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);
|
||||
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
|
||||
T1WriteWord(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0xDC, val); //write the low word
|
||||
write_dma_hictrl<ARMCPU_ARM7>(3,val>>16);
|
||||
return;
|
||||
|
||||
case REG_GCROMCTRL :
|
||||
{
|
||||
if(!(val & 0x80000000))
|
||||
|
@ -3707,16 +3418,11 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val)
|
|||
val |= 0x00800000;
|
||||
T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x1A4, val);
|
||||
|
||||
/* launch DMA if start flag was set to "DS Cart" */
|
||||
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM7][2] == 2)
|
||||
{
|
||||
MMU_doDMA<ARMCPU_ARM7>(2);
|
||||
}
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM7][3] == 2)
|
||||
{
|
||||
MMU_doDMA<ARMCPU_ARM7>(3);
|
||||
}
|
||||
//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][1] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(1);
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM7][2] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(2);
|
||||
if(MMU.DMAStartTime[ARMCPU_ARM7][3] == EDMAMode_Card) MMU_doDMA<ARMCPU_ARM7>(3);
|
||||
|
||||
return;
|
||||
|
||||
|
@ -3803,7 +3509,7 @@ u16 FASTCALL _MMU_ARM7_read16(u32 adr)
|
|||
case REG_TM1CNTL :
|
||||
case REG_TM2CNTL :
|
||||
case REG_TM3CNTL :
|
||||
return MMU.timer[ARMCPU_ARM7][(adr&0xF)>>2];
|
||||
return read_timer(ARMCPU_ARM7,(adr&0xF)>>2);
|
||||
|
||||
case REG_AUXSPICNT:
|
||||
return MMU.AUX_SPI_CNT;
|
||||
|
|
|
@ -97,7 +97,7 @@ struct MMU_struct {
|
|||
u32 reg_IF[2];
|
||||
|
||||
u32 DMAStartTime[2][4];
|
||||
s32 DMACycle[2][4];
|
||||
u64 DMACycle[2][4];
|
||||
u32 DMACrt[2][4];
|
||||
BOOL DMAing[2][4];
|
||||
|
||||
|
@ -105,21 +105,19 @@ struct MMU_struct {
|
|||
s64 divResult;
|
||||
s64 divMod;
|
||||
u32 divCnt;
|
||||
s32 divCycles;
|
||||
u64 divCycles;
|
||||
|
||||
BOOL sqrtRunning;
|
||||
u32 sqrtResult;
|
||||
u32 sqrtCnt;
|
||||
s32 sqrtCycles;
|
||||
u64 sqrtCycles;
|
||||
|
||||
u16 SPI_CNT;
|
||||
u16 SPI_CMD;
|
||||
u16 AUX_SPI_CNT;
|
||||
u16 AUX_SPI_CMD;
|
||||
|
||||
#ifdef USE_GEOMETRY_FIFO_EMULATION
|
||||
s32 gfx3dCycles;
|
||||
#endif
|
||||
u64 gfx3dCycles;
|
||||
|
||||
u8 powerMan_CntReg;
|
||||
BOOL powerMan_CntRegWritten;
|
||||
|
@ -265,6 +263,20 @@ inline void SetupMMU(bool debugConsole) {
|
|||
//T1ReadWord(MMU.MMU_MEM[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)
|
||||
{
|
||||
//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)
|
||||
{
|
||||
if(addr == 0x022D7900)
|
||||
{
|
||||
int zzz=9;
|
||||
}
|
||||
//special handling for DMA: discard writes to TCM
|
||||
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();
|
||||
void emu_halt();
|
||||
|
||||
extern u64 nds_timer;
|
||||
void NDS_Reschedule();
|
||||
void NDS_RescheduleGXFIFO();
|
||||
void NDS_RescheduleDMA();
|
||||
void NDS_RescheduleTimers();
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s32 ARM9Cycle;
|
||||
s32 ARM7Cycle;
|
||||
s32 wifiCycle;
|
||||
s32 cycles;
|
||||
s32 timerCycle[2][4];
|
||||
BOOL timerOver[2][4];
|
||||
s32 nextHBlank;
|
||||
u64 timerCycle[2][4];
|
||||
u32 VCount;
|
||||
u32 old;
|
||||
s32 diff;
|
||||
BOOL lignerendu;
|
||||
|
||||
u16 touchX;
|
||||
u16 touchY;
|
||||
|
|
|
@ -318,7 +318,7 @@ u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode)
|
|||
|
||||
case FIQ :
|
||||
{
|
||||
u32 tmp;
|
||||
u32 tmp;
|
||||
SWAP(armcpu->R[8], armcpu->R8_fiq, tmp);
|
||||
SWAP(armcpu->R[9], armcpu->R9_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)
|
||||
ARMPROC.newIrqFlags |= flag;
|
||||
extern void NDS_Reschedule();
|
||||
NDS_Reschedule();
|
||||
}
|
||||
|
||||
static INLINE void NDS_makeARM9Int(u32 num)
|
||||
|
|
|
@ -161,4 +161,4 @@ std::string GetRomNameWithoutExtension()
|
|||
if (x > 0)
|
||||
return RomName.substr(0,x);
|
||||
else return RomName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,8 +61,10 @@ in this function: */
|
|||
static void gfx3d_doFlush();
|
||||
|
||||
#ifdef USE_GEOMETRY_FIFO_EMULATION
|
||||
#define GFX_DELAY(x) MMU.gfx3dCycles = nds.cycles + (2*x)
|
||||
#define GFX_DELAY_M2(x) MMU.gfx3dCycles += (2*x)
|
||||
inline void GFX_DELAY(int x) {
|
||||
MMU.gfx3dCycles = nds_timer + (2*x); NDS_RescheduleGXFIFO(); }
|
||||
inline void GFX_DELAY_M2(int x) {
|
||||
MMU.gfx3dCycles += (2*x); NDS_RescheduleGXFIFO(); }
|
||||
#else
|
||||
#define GFX_DELAY(x)
|
||||
#define GFX_DELAY_M2(x)
|
||||
|
|
|
@ -85,6 +85,8 @@ int write32le(u32 b, std::ostream* os)
|
|||
return 4;
|
||||
}
|
||||
|
||||
void writebool(bool b, std::ostream* os) { write32le(b?1:0,os); }
|
||||
|
||||
int write64le(u64 b, std::ostream* os)
|
||||
{
|
||||
u8 s[8];
|
||||
|
@ -155,6 +157,14 @@ int read32le(u32 *Bufo, std::istream *is)
|
|||
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)
|
||||
{
|
||||
u32 size;
|
||||
|
|
|
@ -21,6 +21,8 @@ int read32le(u32 *Bufo, FILE *fp);
|
|||
int read16le(u16 *Bufo, std::istream *is);
|
||||
inline int read16le(s16 *Bufo, std::istream* is) { return read16le((u16*)Bufo,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 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];
|
||||
|
||||
#define SAVESTATE_VERSION 11
|
||||
#define SAVESTATE_VERSION 12
|
||||
static const char* magic = "DeSmuME SState\0";
|
||||
|
||||
//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[]={
|
||||
{ "_9CY", 4, 1, &nds.ARM9Cycle},
|
||||
{ "_7CY", 4, 1, &nds.ARM7Cycle},
|
||||
{ "_CYC", 4, 1, &nds.cycles},
|
||||
{ "_WCY", 4, 1, &nds.wifiCycle},
|
||||
{ "_TCY", 4, 8, nds.timerCycle},
|
||||
{ "_TOV", 4, 8, nds.timerOver},
|
||||
{ "_NHB", 4, 1, &nds.nextHBlank},
|
||||
{ "_TCY", 8, 8, nds.timerCycle},
|
||||
{ "_VCT", 4, 1, &nds.VCount},
|
||||
{ "_OLD", 4, 1, &nds.old},
|
||||
{ "_DIF", 4, 1, &nds.diff},
|
||||
{ "_LIG", 4, 1, &nds.lignerendu},
|
||||
{ "_TPX", 2, 1, &nds.touchX},
|
||||
{ "_TPY", 2, 1, &nds.touchY},
|
||||
{ "_TPB", 4, 1, &nds.isTouch},
|
||||
|
@ -200,6 +193,8 @@ SFORMAT SF_MMU[]={
|
|||
{ "MIME", 4, 2, MMU.reg_IME},
|
||||
{ "MIE_", 4, 2, MMU.reg_IE},
|
||||
{ "MIF_", 4, 2, MMU.reg_IF},
|
||||
|
||||
{ "MGXC", 8, 1, &MMU.gfx3dCycles},
|
||||
|
||||
{ "M_SX", 1, 2, &MMU.SPI_CNT},
|
||||
{ "M_SC", 1, 2, &MMU.SPI_CMD},
|
||||
|
@ -207,7 +202,7 @@ SFORMAT SF_MMU[]={
|
|||
{ "MASC", 1, 2, &MMU.AUX_SPI_CMD},
|
||||
|
||||
{ "MDST", 4, 8, MMU.DMAStartTime},
|
||||
{ "MDCY", 4, 8, MMU.DMACycle},
|
||||
{ "MDCY", 8, 8, MMU.DMACycle},
|
||||
{ "MDCR", 4, 8, MMU.DMACrt},
|
||||
{ "MDMA", 4, 8, MMU.DMAing},
|
||||
{ "MDSR", 4, 8, DMASrc},
|
||||
|
@ -217,12 +212,12 @@ SFORMAT SF_MMU[]={
|
|||
{ "MDV2", 8, 1, &MMU.divResult},
|
||||
{ "MDV3", 8, 1, &MMU.divMod},
|
||||
{ "MDV4", 4, 1, &MMU.divCnt},
|
||||
{ "MDV5", 4, 1, &MMU.divCycles},
|
||||
{ "MDV5", 8, 1, &MMU.divCycles},
|
||||
|
||||
{ "MSQ1", 4, 1, &MMU.sqrtRunning},
|
||||
{ "MSQ2", 4, 1, &MMU.sqrtResult},
|
||||
{ "MSQ3", 4, 1, &MMU.sqrtCnt},
|
||||
{ "MSQ4", 4, 1, &MMU.sqrtCycles},
|
||||
{ "MSQ4", 8, 1, &MMU.sqrtCycles},
|
||||
|
||||
//begin memory chips
|
||||
//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 }
|
||||
};
|
||||
|
||||
void nds_savestate(std::ostream* os);
|
||||
bool nds_loadstate(std::istream* is, int size);
|
||||
|
||||
static void mmu_savestate(std::ostream* os)
|
||||
{
|
||||
//version
|
||||
|
@ -824,6 +822,7 @@ static void writechunks(std::ostream* os) {
|
|||
savestate_WriteChunk(os,3,cp15_savestate);
|
||||
savestate_WriteChunk(os,4,SF_MEM);
|
||||
savestate_WriteChunk(os,5,SF_NDS);
|
||||
savestate_WriteChunk(os,51,nds_savestate);
|
||||
savestate_WriteChunk(os,60,SF_MMU);
|
||||
savestate_WriteChunk(os,61,mmu_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 4: if(!ReadStateChunk(is,SF_MEM,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 61: if(!mmu_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 short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long u64;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
typedef signed char s8;
|
||||
typedef signed short s16;
|
||||
|
|
|
@ -594,6 +594,22 @@
|
|||
>
|
||||
</File>
|
||||
</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
|
||||
Name="utils"
|
||||
|
@ -750,10 +766,6 @@
|
|||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\filter\2xsai.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\addons.cpp"
|
||||
>
|
||||
|
@ -958,10 +970,6 @@
|
|||
RelativePath="..\GPU_osd.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filter\hq2x.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\lua-engine.cpp"
|
||||
>
|
||||
|
@ -1090,10 +1098,6 @@
|
|||
RelativePath="..\saves.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\filter\scanline.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\shaders.h"
|
||||
>
|
||||
|
|
|
@ -924,8 +924,8 @@ DWORD WINAPI run()
|
|||
for(int i=0;i<16;i++)
|
||||
load = load/8 + nds.runCycleCollector[(i+nds.idleFrameCounter)&15]*7/8;
|
||||
load = std::min(100,std::max(0,(int)(load*100/1120380)));
|
||||
sprintf(txt,"(%02d%%) %s", load, DESMUME_NAME_AND_VERSION);
|
||||
SetWindowText(hwnd, txt);
|
||||
//sprintf(txt,"(%02d%%) %s", load, DESMUME_NAME_AND_VERSION);
|
||||
SetWindowText(hwnd, DESMUME_NAME_AND_VERSION);
|
||||
}
|
||||
|
||||
if(!skipnextframe)
|
||||
|
|
Loading…
Reference in New Issue