From 5a940dc2be511a4083adf2386dd31f35e94c6583 Mon Sep 17 00:00:00 2001 From: zeromus Date: Sun, 28 Dec 2008 02:27:13 +0000 Subject: [PATCH] - add IDM_DEFSIZE to resource.h (luigi__ will have merge issues). - add code to use bios if the bios files exist. this code is preliminary. it seems to freeze games right now. to use this, make sure BiosNds7.ROM and BiosNds9.ROM exist in the application startup working directory. this is probably not a good way to do it, but it is a start. - fix recently created spu issues with adpcm and psg. - change execute = FALSE; to emu_pause(); so that other things can be done or disabled in one place. - analyze performance of MatrixIdentity for speedup. - accept crazymax's correction to my matrix caching. that was boneheaded, sorry! --- desmume/src/FIFO.cpp | 326 ++--- desmume/src/MMU.cpp | 38 +- desmume/src/NDSSystem.cpp | 1620 +++++++++++------------ desmume/src/NDSSystem.h | 5 +- desmume/src/SPU.cpp | 39 +- desmume/src/arm_instructions.cpp | 70 +- desmume/src/armcpu.cpp | 5 - desmume/src/bios.cpp | 4 +- desmume/src/gfx3d.cpp | 23 +- desmume/src/matrix.cpp | 9 +- desmume/src/thumb_instructions.cpp | 1906 ++++++++++++++-------------- desmume/src/windows/main.cpp | 6 +- desmume/src/windows/resource.h | 1 + desmume/src/windows/resources.rc | 6 +- 14 files changed, 2059 insertions(+), 1999 deletions(-) diff --git a/desmume/src/FIFO.cpp b/desmume/src/FIFO.cpp index 8fe54f5cd..0ca38baae 100644 --- a/desmume/src/FIFO.cpp +++ b/desmume/src/FIFO.cpp @@ -1,166 +1,166 @@ -/* Copyright (C) 2006 yopyop - yopyop156@ifrance.com - yopyop156.ifrance.com - - Copyright (C) 2007 shash - - This file is part of DeSmuME - - DeSmuME is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DeSmuME is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DeSmuME; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "FIFO.h" -#include -#include "armcpu.h" -#include "debug.h" -#include "mem.h" -#include "MMU.h" - -// ========================================================= IPC FIFO -IPC_FIFO ipc_fifo; - -void IPC_FIFOclear() -{ - memset(&ipc_fifo, 0, sizeof(IPC_FIFO)); - //LOG("FIFO is cleared\n"); -} - -void IPC_FIFOsend(u8 proc, u32 val) -{ - //LOG("IPC%s send FIFO 0x%08X\n", proc?"7":"9", val); - u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); - if (!(cnt_l & 0x8000)) return; // FIFO disabled - u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); - - if (ipc_fifo.sendTail[proc] < 16) // last full == error - { - ipc_fifo.sendBuf[proc][ipc_fifo.sendTail[proc]] = val; - ipc_fifo.sendTail[proc]++; - if (ipc_fifo.sendTail[proc] == 16) cnt_l |= 0x02; // full - cnt_l &= 0xFFFE; - - if (ipc_fifo.recvTail[proc^1] < 16) // last full == error - { - ipc_fifo.recvBuf[proc^1][ipc_fifo.recvTail[proc^1]] = val; - ipc_fifo.recvTail[proc^1]++; - if (ipc_fifo.recvTail[proc^1] == 16) cnt_r |= 0x0200; // full - cnt_r &= 0xFEFF; - } - else - cnt_r |= 0x4200; - } - else - cnt_l |= 0x4002; - - // save in mem - T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); - T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); - - if ((cnt_r & (1<<10))) - NDS_makeInt(proc^1, 18); -} - -u32 IPC_FIFOrecv(u8 proc) -{ - //LOG("IPC%s recv FIFO:\n", proc?"7":"9"); - u32 val = 0; - u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); - u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); - - if (ipc_fifo.recvTail[proc] > 0) // not empty - { - val = ipc_fifo.recvBuf[proc][0]; - for (int i = 0; i < ipc_fifo.recvTail[proc]; i++) - ipc_fifo.recvBuf[proc][i] = ipc_fifo.recvBuf[proc][i+1]; - ipc_fifo.recvTail[proc]--; - if (ipc_fifo.recvTail[proc] == 0) // empty - cnt_l |= 0x0100; - - // remove from head - for (int i = 0; i < ipc_fifo.sendTail[proc^1]; i++) - ipc_fifo.sendBuf[proc^1][i] = ipc_fifo.sendBuf[proc^1][i+1]; - ipc_fifo.sendTail[proc^1]--; - if (ipc_fifo.sendTail[proc^1] == 0) // empty - cnt_r |= 0x0001; - } - else - cnt_l |= 0x4100; - - T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); - T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); - - if ((cnt_l & (1<<3))) - NDS_makeInt(proc, 19); - return (val); -} - -void IPC_FIFOcnt(u8 proc, u16 val) -{ - //LOG("IPC%s FIFO context 0x%X\n", proc?"7":"9", val); - - u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); - - cnt_l &= ~0x8404; - cnt_l |= (val & 0x8404); - cnt_l &= (~(val & 0x4000)); - if (val & 0x0008) - { - IPC_FIFOclear(); - cnt_l |= 0x0101; - } - T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); - - if ((cnt_l & 0x0004)) - NDS_makeInt(proc, 18); -} - -// ========================================================= GFX FIFO -GFX_FIFO gxFIFO; - -void GFX_FIFOclear() -{ - u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); - - memset(&gxFIFO, 0, sizeof(GFX_FIFO)); - - // TODO: irq handle - gxstat &= 0x0000FF00; +/* Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + Copyright (C) 2007 shash + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "FIFO.h" +#include +#include "armcpu.h" +#include "debug.h" +#include "mem.h" +#include "MMU.h" + +// ========================================================= IPC FIFO +IPC_FIFO ipc_fifo; + +void IPC_FIFOclear() +{ + memset(&ipc_fifo, 0, sizeof(IPC_FIFO)); + //LOG("FIFO is cleared\n"); +} + +void IPC_FIFOsend(u8 proc, u32 val) +{ + //LOG("IPC%s send FIFO 0x%08X\n", proc?"7":"9", val); + u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); + if (!(cnt_l & 0x8000)) return; // FIFO disabled + u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); + + if (ipc_fifo.sendTail[proc] < 16) // last full == error + { + ipc_fifo.sendBuf[proc][ipc_fifo.sendTail[proc]] = val; + ipc_fifo.sendTail[proc]++; + if (ipc_fifo.sendTail[proc] == 16) cnt_l |= 0x02; // full + cnt_l &= 0xFFFE; + + if (ipc_fifo.recvTail[proc^1] < 16) // last full == error + { + ipc_fifo.recvBuf[proc^1][ipc_fifo.recvTail[proc^1]] = val; + ipc_fifo.recvTail[proc^1]++; + if (ipc_fifo.recvTail[proc^1] == 16) cnt_r |= 0x0200; // full + cnt_r &= 0xFEFF; + } + else + cnt_r |= 0x4200; + } + else + cnt_l |= 0x4002; + + // save in mem + T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); + T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); + + if ((cnt_r & (1<<10))) + NDS_makeInt(proc^1, 18); +} + +u32 IPC_FIFOrecv(u8 proc) +{ + //LOG("IPC%s recv FIFO:\n", proc?"7":"9"); + u32 val = 0; + u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); + u16 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184); + + if (ipc_fifo.recvTail[proc] > 0) // not empty + { + val = ipc_fifo.recvBuf[proc][0]; + for (int i = 0; i < ipc_fifo.recvTail[proc]; i++) + ipc_fifo.recvBuf[proc][i] = ipc_fifo.recvBuf[proc][i+1]; + ipc_fifo.recvTail[proc]--; + if (ipc_fifo.recvTail[proc] == 0) // empty + cnt_l |= 0x0100; + + // remove from head + for (int i = 0; i < ipc_fifo.sendTail[proc^1]; i++) + ipc_fifo.sendBuf[proc^1][i] = ipc_fifo.sendBuf[proc^1][i+1]; + ipc_fifo.sendTail[proc^1]--; + if (ipc_fifo.sendTail[proc^1] == 0) // empty + cnt_r |= 0x0001; + } + else + cnt_l |= 0x4100; + + T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); + T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, cnt_r); + + if ((cnt_l & (1<<3))) + NDS_makeInt(proc, 19); + return (val); +} + +void IPC_FIFOcnt(u8 proc, u16 val) +{ + //LOG("IPC%s FIFO context 0x%X\n", proc?"7":"9", val); + + u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184); + + cnt_l &= ~0x8404; + cnt_l |= (val & 0x8404); + cnt_l &= (~(val & 0x4000)); + if (val & 0x0008) + { + IPC_FIFOclear(); + cnt_l |= 0x0101; + } + T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, cnt_l); + + if ((cnt_l & 0x0004)) + NDS_makeInt(proc, 18); +} + +// ========================================================= GFX FIFO +GFX_FIFO gxFIFO; + +void GFX_FIFOclear() +{ + u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); + + memset(&gxFIFO, 0, sizeof(GFX_FIFO)); + + // TODO: irq handle + gxstat &= 0x0000FF00; gxstat |= 0x00000002; // this is hack gxstat |= 0x86000000; T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); -} - -void GFX_FIFOsend(u32 cmd, u32 param) -{ - u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); - gxstat &= 0x0000FF00; - gxstat |= 0x00000002; // this is hack - - if (gxFIFO.tail < 260) - { - gxFIFO.cmd[gxFIFO.tail] = cmd & 0xFF; - gxFIFO.param[gxFIFO.tail] = param; - gxFIFO.tail++; - // TODO: irq handle - if (gxFIFO.tail < 130) - gxstat |= 0x72000000; - if (gxFIFO.tail == 16) - gxstat |= 0x01000000; - } - else - gxstat |= 0x01000000; - - T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); -} +} + +void GFX_FIFOsend(u32 cmd, u32 param) +{ + u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); + gxstat &= 0x0000FF00; + gxstat |= 0x00000002; // this is hack + + if (gxFIFO.tail < 260) + { + gxFIFO.cmd[gxFIFO.tail] = cmd & 0xFF; + gxFIFO.param[gxFIFO.tail] = param; + gxFIFO.tail++; + // TODO: irq handle + if (gxFIFO.tail < 130) + gxstat |= 0x72000000; + if (gxFIFO.tail == 16) + gxstat |= 0x01000000; + } + else + gxstat |= 0x01000000; + + T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); +} diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index e2ab24e88..e8489b5ba 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -2040,7 +2040,7 @@ static void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) } case REG_DISPB_DISPCNT+2 : { - //execute = FALSE; + //emu_halt(); u32 v = (T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000) & 0xFFFF) | ((u32) val << 16); GPU_setVideoProp(SubScreen.gpu, v); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x1000, v); @@ -2049,7 +2049,7 @@ static void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DMA0CNTH : { u32 v; - //if(val&0x8000) execute = FALSE; + //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); @@ -2070,7 +2070,7 @@ static void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DMA1CNTH : { u32 v; - //if(val&0x8000) execute = FALSE; + //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); @@ -2091,7 +2091,7 @@ static void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DMA2CNTH : { u32 v; - //if(val&0x8000) execute = FALSE; + //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); @@ -2112,7 +2112,7 @@ static void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DMA3CNTH : { u32 v; - //if(val&0x8000) execute = FALSE; + //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); @@ -2131,7 +2131,7 @@ static void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) #endif } return; - //case REG_AUXSPICNT : execute = FALSE; + //case REG_AUXSPICNT : emu_halt(); } #ifdef _MMU_DEBUG mmu_log_debug_ARM9(adr, "(write16) %0x%X", val); @@ -2464,7 +2464,7 @@ static void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) 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 - //execute = FALSE; + //emu_halt(); return; case REG_DMA1CNTL: //LOG("32 bit dma1 %04X\r\n", val); @@ -2579,7 +2579,7 @@ static void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) case REG_DISPA_BG0CNT : GPU_setBGProp(MainScreen.gpu, 0, (val&0xFFFF)); GPU_setBGProp(MainScreen.gpu, 1, (val>>16)); - //if((val>>16)==0x400) execute = FALSE; + //if((val>>16)==0x400) emu_halt(); T1WriteLong(ARM9Mem.ARM9_REG, 8, val); return; case REG_DISPA_BG2CNT : @@ -3006,14 +3006,14 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) val = 0; break; case 0x10 : - //execute = FALSE; + //emu_halt(); if(SPI_CNT&(1<<11)) { if(partie) { val = ((nds.touchY<<3)&0x7FF); partie = 0; - //execute = FALSE; + //emu_halt(); break; } val = (nds.touchY>>5); @@ -3102,7 +3102,7 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) #endif return; case REG_IE + 2 : - //execute = FALSE; + //emu_halt(); MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF) | (((u32)val)<<16); #ifndef NEW_IRQ if ( MMU.reg_IME[ARMCPU_ARM7]) @@ -3118,11 +3118,11 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) return; case REG_IF : - //execute = FALSE; + //emu_halt(); MMU.reg_IF[ARMCPU_ARM7] &= (~((u32)val)); return; case REG_IF + 2 : - //execute = FALSE; + //emu_halt(); MMU.reg_IF[ARMCPU_ARM7] &= (~(((u32)val)<<16)); return; @@ -3183,7 +3183,7 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) { u32 v; - //if(val&0x8000) execute = FALSE; + //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); @@ -3204,7 +3204,7 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) case REG_DMA1CNTH : { u32 v; - //if(val&0x8000) execute = FALSE; + //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); @@ -3225,7 +3225,7 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) case REG_DMA2CNTH : { u32 v; - //if(val&0x8000) execute = FALSE; + //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); @@ -3246,7 +3246,7 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) case REG_DMA3CNTH : { u32 v; - //if(val&0x8000) execute = FALSE; + //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); @@ -3265,7 +3265,7 @@ static void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) #endif } return; - //case REG_AUXSPICNT : execute = FALSE; + //case REG_AUXSPICNT : emu_halt(); } #ifdef _MMU_DEBUG mmu_log_debug_ARM7(adr, "(write16) %0x%X", val); @@ -3408,7 +3408,7 @@ static void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val) 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 - //execute = FALSE; + //emu_halt(); return; case REG_DMA1CNTL: //LOG("32 bit dma1 %04X\r\n", val); diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 06e90242d..5c02360a8 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1,22 +1,22 @@ /* Copyright (C) 2006 yopyop - yopyop156@ifrance.com - yopyop156.ifrance.com +yopyop156@ifrance.com +yopyop156.ifrance.com - This file is part of DeSmuME +This file is part of DeSmuME - DeSmuME is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. +DeSmuME is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. - DeSmuME is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +DeSmuME is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with DeSmuME; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +You should have received a copy of the GNU General Public License +along with DeSmuME; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include @@ -33,7 +33,7 @@ #include "ROMReader.h" #include "gfx3d.h" #include "utils/decrypt/decrypt.h" - +#include "bios.h" #include "debug.h" #ifdef _WIN32 @@ -50,162 +50,162 @@ NDSSystem nds; static u32 calc_CRC16( u32 start, const u8 *data, int count) { - int i,j; - u32 crc = start & 0xffff; - const u16 val[8] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 }; - for(i = 0; i < count; i++) - { - crc = crc ^ data[i]; + int i,j; + u32 crc = start & 0xffff; + const u16 val[8] = { 0xC0C1,0xC181,0xC301,0xC601,0xCC01,0xD801,0xF001,0xA001 }; + for(i = 0; i < count; i++) + { + crc = crc ^ data[i]; - for(j = 0; j < 8; j++) { - int do_bit = 0; + for(j = 0; j < 8; j++) { + int do_bit = 0; - if ( crc & 0x1) - do_bit = 1; + if ( crc & 0x1) + do_bit = 1; - crc = crc >> 1; + crc = crc >> 1; - if ( do_bit) { - crc = crc ^ (val[j] << (7-j)); - } - } - } - return crc; + if ( do_bit) { + crc = crc ^ (val[j] << (7-j)); + } + } + } + return crc; } static int copy_firmware_user_data( u8 *dest_buffer, const u8 *fw_data) { - /* - * Determine which of the two user settings in the firmware is the current - * and valid one and then copy this into the destination buffer. - * - * The current setting will have a greater count. - * Settings are only valid if its CRC16 is correct. - */ - int user1_valid = 0; - int user2_valid = 0; - u32 user_settings_offset; - u32 fw_crc; - u32 crc; - int copy_good = 0; + /* + * Determine which of the two user settings in the firmware is the current + * and valid one and then copy this into the destination buffer. + * + * The current setting will have a greater count. + * Settings are only valid if its CRC16 is correct. + */ + int user1_valid = 0; + int user2_valid = 0; + u32 user_settings_offset; + u32 fw_crc; + u32 crc; + int copy_good = 0; - user_settings_offset = fw_data[0x20]; - user_settings_offset |= fw_data[0x21] << 8; - user_settings_offset <<= 3; + user_settings_offset = fw_data[0x20]; + user_settings_offset |= fw_data[0x21] << 8; + user_settings_offset <<= 3; - if ( user_settings_offset <= 0x3FE00) { - s32 copy_settings_offset = -1; + if ( user_settings_offset <= 0x3FE00) { + s32 copy_settings_offset = -1; - crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset], - NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); - fw_crc = fw_data[user_settings_offset + 0x72]; - fw_crc |= fw_data[user_settings_offset + 0x73] << 8; - if ( crc == fw_crc) { - user1_valid = 1; - } + crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset], + NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); + fw_crc = fw_data[user_settings_offset + 0x72]; + fw_crc |= fw_data[user_settings_offset + 0x73] << 8; + if ( crc == fw_crc) { + user1_valid = 1; + } - crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset + 0x100], - NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); - fw_crc = fw_data[user_settings_offset + 0x100 + 0x72]; - fw_crc |= fw_data[user_settings_offset + 0x100 + 0x73] << 8; - if ( crc == fw_crc) { - user2_valid = 1; - } + crc = calc_CRC16( 0xffff, &fw_data[user_settings_offset + 0x100], + NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); + fw_crc = fw_data[user_settings_offset + 0x100 + 0x72]; + fw_crc |= fw_data[user_settings_offset + 0x100 + 0x73] << 8; + if ( crc == fw_crc) { + user2_valid = 1; + } - if ( user1_valid) { - if ( user2_valid) { - u16 count1, count2; + if ( user1_valid) { + if ( user2_valid) { + u16 count1, count2; - count1 = fw_data[user_settings_offset + 0x70]; - count1 |= fw_data[user_settings_offset + 0x71] << 8; + count1 = fw_data[user_settings_offset + 0x70]; + count1 |= fw_data[user_settings_offset + 0x71] << 8; - count2 = fw_data[user_settings_offset + 0x100 + 0x70]; - count2 |= fw_data[user_settings_offset + 0x100 + 0x71] << 8; + count2 = fw_data[user_settings_offset + 0x100 + 0x70]; + count2 |= fw_data[user_settings_offset + 0x100 + 0x71] << 8; - if ( count2 > count1) { - copy_settings_offset = user_settings_offset + 0x100; - } - else { - copy_settings_offset = user_settings_offset; - } - } - else { - copy_settings_offset = user_settings_offset; - } - } - else if ( user2_valid) { - /* copy the second user settings */ - copy_settings_offset = user_settings_offset + 0x100; - } + if ( count2 > count1) { + copy_settings_offset = user_settings_offset + 0x100; + } + else { + copy_settings_offset = user_settings_offset; + } + } + else { + copy_settings_offset = user_settings_offset; + } + } + else if ( user2_valid) { + /* copy the second user settings */ + copy_settings_offset = user_settings_offset + 0x100; + } - if ( copy_settings_offset > 0) { - memcpy( dest_buffer, &fw_data[copy_settings_offset], - NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); - copy_good = 1; - } - } + if ( copy_settings_offset > 0) { + memcpy( dest_buffer, &fw_data[copy_settings_offset], + NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT); + copy_good = 1; + } + } - return copy_good; + return copy_good; } #ifdef GDB_STUB int NDS_Init( struct armcpu_memory_iface *arm9_mem_if, - struct armcpu_ctrl_iface **arm9_ctrl_iface, - struct armcpu_memory_iface *arm7_mem_if, - struct armcpu_ctrl_iface **arm7_ctrl_iface) { +struct armcpu_ctrl_iface **arm9_ctrl_iface, +struct armcpu_memory_iface *arm7_mem_if, +struct armcpu_ctrl_iface **arm7_ctrl_iface) { #else int NDS_Init( void) { #endif - nds.ARM9Cycle = 0; - nds.ARM7Cycle = 0; - nds.cycles = 0; - nds.idleFrameCounter = 0; - memset(nds.runCycleCollector,0,sizeof(nds.runCycleCollector)); - MMU_Init(); - nds.nextHBlank = 3168; - nds.VCount = 0; - nds.lignerendu = FALSE; + nds.ARM9Cycle = 0; + nds.ARM7Cycle = 0; + nds.cycles = 0; + nds.idleFrameCounter = 0; + memset(nds.runCycleCollector,0,sizeof(nds.runCycleCollector)); + MMU_Init(); + nds.nextHBlank = 3168; + nds.VCount = 0; + nds.lignerendu = FALSE; - if (Screen_Init(GFXCORE_DUMMY) != 0) - return -1; + if (Screen_Init(GFXCORE_DUMMY) != 0) + return -1; + + gfx3d_init(); - gfx3d_init(); - #ifdef GDB_STUB - armcpu_new(&NDS_ARM7,1, arm7_mem_if, arm7_ctrl_iface); - armcpu_new(&NDS_ARM9,0, arm9_mem_if, arm9_ctrl_iface); + armcpu_new(&NDS_ARM7,1, arm7_mem_if, arm7_ctrl_iface); + armcpu_new(&NDS_ARM9,0, arm9_mem_if, arm9_ctrl_iface); #else - armcpu_new(&NDS_ARM7,1); - armcpu_new(&NDS_ARM9,0); + armcpu_new(&NDS_ARM7,1); + armcpu_new(&NDS_ARM9,0); #endif - if (SPU_Init(SNDCORE_DUMMY, 740) != 0) - return -1; + if (SPU_Init(SNDCORE_DUMMY, 740) != 0) + return -1; #ifdef EXPERIMENTAL_WIFI - WIFI_Init(&wifiMac) ; + WIFI_Init(&wifiMac) ; #endif - return 0; + return 0; } void NDS_DeInit(void) { - if(MMU.CART_ROM != MMU.UNUSED_RAM) - NDS_FreeROM(); + if(MMU.CART_ROM != MMU.UNUSED_RAM) + NDS_FreeROM(); - nds.nextHBlank = 3168; - SPU_DeInit(); - Screen_DeInit(); - MMU_DeInit(); - gpu3D->NDS_3D_Close(); + nds.nextHBlank = 3168; + SPU_DeInit(); + Screen_DeInit(); + MMU_DeInit(); + gpu3D->NDS_3D_Close(); } BOOL NDS_SetROM(u8 * rom, u32 mask) { - MMU_setRom(rom, mask); + MMU_setRom(rom, mask); - return TRUE; + return TRUE; } NDS_header * NDS_getROMHeader(void) @@ -254,57 +254,57 @@ NDS_header * NDS_getROMHeader(void) return header; - //return (NDS_header *)MMU.CART_ROM; + //return (NDS_header *)MMU.CART_ROM; } void NDS_setTouchPos(u16 x, u16 y) { - nds.touchX = (x <<4); - nds.touchY = (y <<4); - nds.isTouch = 1; - - MMU.ARM7_REG[0x136] &= 0xBF; + nds.touchX = (x <<4); + nds.touchY = (y <<4); + nds.isTouch = 1; + + MMU.ARM7_REG[0x136] &= 0xBF; } void NDS_releaseTouch(void) { - nds.touchX = 0; - nds.touchY = 0; - nds.isTouch = 0; - - MMU.ARM7_REG[0x136] |= 0x40; + nds.touchX = 0; + nds.touchY = 0; + nds.isTouch = 0; + + MMU.ARM7_REG[0x136] |= 0x40; } void debug() { - //if(NDS_ARM9.R[15]==0x020520DC) execute = FALSE; - //DSLinux - //if(NDS_ARM9.CPSR.bits.mode == 0) execute = FALSE; - //if((NDS_ARM9.R[15]&0xFFFFF000)==0) execute = FALSE; - //if((NDS_ARM9.R[15]==0x0201B4F4)/*&&(NDS_ARM9.R[1]==0x0)*/) execute = FALSE; - //AOE - //if((NDS_ARM9.R[15]==0x01FFE194)&&(NDS_ARM9.R[0]==0)) execute = FALSE; - //if((NDS_ARM9.R[15]==0x01FFE134)&&(NDS_ARM9.R[0]==0)) execute = FALSE; + //if(NDS_ARM9.R[15]==0x020520DC) emu_halt(); + //DSLinux + //if(NDS_ARM9.CPSR.bits.mode == 0) emu_halt(); + //if((NDS_ARM9.R[15]&0xFFFFF000)==0) emu_halt(); + //if((NDS_ARM9.R[15]==0x0201B4F4)/*&&(NDS_ARM9.R[1]==0x0)*/) emu_halt(); + //AOE + //if((NDS_ARM9.R[15]==0x01FFE194)&&(NDS_ARM9.R[0]==0)) emu_halt(); + //if((NDS_ARM9.R[15]==0x01FFE134)&&(NDS_ARM9.R[0]==0)) emu_halt(); - //BBMAN - //if(NDS_ARM9.R[15]==0x02098B4C) execute = FALSE; - //if(NDS_ARM9.R[15]==0x02004924) execute = FALSE; - //if(NDS_ARM9.R[15]==0x02004890) execute = FALSE; - - //if(NDS_ARM9.R[15]==0x0202B800) execute = FALSE; - //if(NDS_ARM9.R[15]==0x0202B3DC) execute = FALSE; - //if((NDS_ARM9.R[1]==0x9AC29AC1)&&(!fait)) {execute = FALSE;fait = TRUE;} - //if(NDS_ARM9.R[1]==0x0400004A) {execute = FALSE;fait = TRUE;} - /*if(NDS_ARM9.R[4]==0x2E33373C) execute = FALSE; - if(NDS_ARM9.R[15]==0x02036668) //execute = FALSE; - { - nds.logcount++; - sprintf(logbuf, "%d %08X", nds.logcount, NDS_ARM9.R[13]); - log::ajouter(logbuf); - if(nds.logcount==89) execute=FALSE; - }*/ - //if(NDS_ARM9.instruction==0) execute = FALSE; - //if((NDS_ARM9.R[15]>>28)) execute = FALSE; + //BBMAN + //if(NDS_ARM9.R[15]==0x02098B4C) emu_halt(); + //if(NDS_ARM9.R[15]==0x02004924) emu_halt(); + //if(NDS_ARM9.R[15]==0x02004890) emu_halt(); + + //if(NDS_ARM9.R[15]==0x0202B800) emu_halt(); + //if(NDS_ARM9.R[15]==0x0202B3DC) emu_halt(); + //if((NDS_ARM9.R[1]==0x9AC29AC1)&&(!fait)) {emu_halt();fait = TRUE;} + //if(NDS_ARM9.R[1]==0x0400004A) {emu_halt();fait = TRUE;} + /*if(NDS_ARM9.R[4]==0x2E33373C) emu_halt(); + if(NDS_ARM9.R[15]==0x02036668) //emu_halt(); + { + nds.logcount++; + sprintf(logbuf, "%d %08X", nds.logcount, NDS_ARM9.R[13]); + log::ajouter(logbuf); + if(nds.logcount==89) execute=FALSE; + }*/ + //if(NDS_ARM9.instruction==0) emu_halt(); + //if((NDS_ARM9.R[15]>>28)) emu_halt(); } #define DSGBA_EXTENSTION ".ds.gba" @@ -318,494 +318,515 @@ enum //http://www.aggregate.org/MAGIC/#Population%20Count%20(Ones%20Count) static u32 ones32(u32 x) { - /* 32-bit recursive reduction using SWAR... - but first step is mapping 2-bit values - into sum of 2 1-bit values in sneaky way + /* 32-bit recursive reduction using SWAR... + but first step is mapping 2-bit values + into sum of 2 1-bit values in sneaky way */ - x -= ((x >> 1) & 0x55555555); - x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); - x = (((x >> 4) + x) & 0x0f0f0f0f); - x += (x >> 8); - x += (x >> 16); - return(x & 0x0000003f); + x -= ((x >> 1) & 0x55555555); + x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); + x = (((x >> 4) + x) & 0x0f0f0f0f); + x += (x >> 8); + x += (x >> 16); + return(x & 0x0000003f); } int NDS_LoadROM( const char *filename, int bmtype, u32 bmsize, - const char *cflash_disk_image_file) + const char *cflash_disk_image_file) { - int i; - int type; - char * p; - - ROMReader_struct * reader; - void* file; - u32 size, mask; - u8 *data; - char * noext; + int i; + int type; + char * p; - if (filename == NULL) - return -1; + ROMReader_struct * reader; + void* file; + u32 size, mask; + u8 *data; + char * noext; - noext = strdup(filename); - - reader = ROMReaderInit(&noext); - type = ROM_NDS; + if (filename == NULL) + return -1; - p = noext; - p += strlen(p); - p -= strlen(DSGBA_EXTENSTION); + noext = strdup(filename); - if(memcmp(p, DSGBA_EXTENSTION, strlen(DSGBA_EXTENSTION)) == 0) - type = ROM_DSGBA; + reader = ROMReaderInit(&noext); + type = ROM_NDS; - file = reader->Init(filename); + p = noext; + p += strlen(p); + p -= strlen(DSGBA_EXTENSTION); - if (!file) - { - reader->DeInit(file); - free(noext); - return -1; - } - size = reader->Size(file); + if(memcmp(p, DSGBA_EXTENSTION, strlen(DSGBA_EXTENSTION)) == 0) + type = ROM_DSGBA; - if(type == ROM_DSGBA) - { - reader->Seek(file, DSGBA_LOADER_SIZE, SEEK_SET); - size -= DSGBA_LOADER_SIZE; - } + file = reader->Init(filename); - //check that size is at least the size of the header - if (size < 352+160) { - reader->DeInit(file); - free(noext); - return -1; - } - - //zero 25-dec-08 - this used to yield a mask which was 2x large - //mask = size; - mask = size-1; - mask |= (mask >>1); - mask |= (mask >>2); - mask |= (mask >>4); - mask |= (mask >>8); - mask |= (mask >>16); - - // Make sure old ROM is freed first(at least this way we won't be eating - // up a ton of ram before the old ROM is freed) - if(MMU.CART_ROM != MMU.UNUSED_RAM) - NDS_FreeROM(); + if (!file) + { + reader->DeInit(file); + free(noext); + return -1; + } + size = reader->Size(file); - if ((data = (u8*)malloc(mask + 1)) == NULL) - { - reader->DeInit(file); - free(noext); - return -1; - } - - i = reader->Read(file, data, size); - reader->DeInit(file); + if(type == ROM_DSGBA) + { + reader->Seek(file, DSGBA_LOADER_SIZE, SEEK_SET); + size -= DSGBA_LOADER_SIZE; + } - //decrypt if necessary.. - //but this is untested and suspected to fail on big endian, so lets not support this on big endian - #ifndef WORDS_BIGENDIAN - DecryptSecureArea(data,size); - #endif + //check that size is at least the size of the header + if (size < 352+160) { + reader->DeInit(file); + free(noext); + return -1; + } - MMU_unsetRom(); - NDS_SetROM(data, mask); - NDS_Reset(); + //zero 25-dec-08 - this used to yield a mask which was 2x large + //mask = size; + mask = size-1; + mask |= (mask >>1); + mask |= (mask >>2); + mask |= (mask >>4); + mask |= (mask >>8); + mask |= (mask >>16); - /* I guess any directory can be used - * so the current one should be ok */ - strncpy(szRomPath, ".", ARRAY_SIZE(szRomPath)); - cflash_close(); - cflash_init( cflash_disk_image_file); + // Make sure old ROM is freed first(at least this way we won't be eating + // up a ton of ram before the old ROM is freed) + if(MMU.CART_ROM != MMU.UNUSED_RAM) + NDS_FreeROM(); - strncpy(szRomBaseName, filename, ARRAY_SIZE(szRomBaseName)); + if ((data = (u8*)malloc(mask + 1)) == NULL) + { + reader->DeInit(file); + free(noext); + return -1; + } - if(type == ROM_DSGBA) - szRomBaseName[strlen(szRomBaseName)-strlen(DSGBA_EXTENSTION)] = 0x00; - else - szRomBaseName[strlen(szRomBaseName)-4] = 0x00; + i = reader->Read(file, data, size); + reader->DeInit(file); - // Setup Backup Memory - if(type == ROM_DSGBA) - { - /* be sure that we dont overwrite anything before stringstart */ - if (strlen(noext)>= strlen(DSGBA_EXTENSTION)) - strncpy(noext + strlen(noext) - strlen(DSGBA_EXTENSTION), ".sav",strlen(DSGBA_EXTENSTION)+1); - else - { - free(noext); - return -1; - } - } - else - { - /* be sure that we dont overwrite anything before stringstart */ - if (strlen(noext)>=4) - strncpy(noext + strlen(noext) - 4, ".sav",5); - else - { - free(noext); - return -1; - } - } + //decrypt if necessary.. + //but this is untested and suspected to fail on big endian, so lets not support this on big endian +#ifndef WORDS_BIGENDIAN + DecryptSecureArea(data,size); +#endif - mc_realloc(&MMU.bupmem, bmtype, bmsize); - mc_load_file(&MMU.bupmem, noext); - free(noext); + MMU_unsetRom(); + NDS_SetROM(data, mask); + NDS_Reset(); - return i; + /* I guess any directory can be used + * so the current one should be ok */ + strncpy(szRomPath, ".", ARRAY_SIZE(szRomPath)); + cflash_close(); + cflash_init( cflash_disk_image_file); + + strncpy(szRomBaseName, filename, ARRAY_SIZE(szRomBaseName)); + + if(type == ROM_DSGBA) + szRomBaseName[strlen(szRomBaseName)-strlen(DSGBA_EXTENSTION)] = 0x00; + else + szRomBaseName[strlen(szRomBaseName)-4] = 0x00; + + // Setup Backup Memory + if(type == ROM_DSGBA) + { + /* be sure that we dont overwrite anything before stringstart */ + if (strlen(noext)>= strlen(DSGBA_EXTENSTION)) + strncpy(noext + strlen(noext) - strlen(DSGBA_EXTENSTION), ".sav",strlen(DSGBA_EXTENSTION)+1); + else + { + free(noext); + return -1; + } + } + else + { + /* be sure that we dont overwrite anything before stringstart */ + if (strlen(noext)>=4) + strncpy(noext + strlen(noext) - 4, ".sav",5); + else + { + free(noext); + return -1; + } + } + + mc_realloc(&MMU.bupmem, bmtype, bmsize); + mc_load_file(&MMU.bupmem, noext); + free(noext); + + return i; } void NDS_FreeROM(void) { - if (MMU.CART_ROM != MMU.UNUSED_RAM) - free(MMU.CART_ROM); - MMU_unsetRom(); - if (MMU.bupmem.fp) - fclose(MMU.bupmem.fp); - MMU.bupmem.fp = NULL; + if (MMU.CART_ROM != MMU.UNUSED_RAM) + free(MMU.CART_ROM); + MMU_unsetRom(); + if (MMU.bupmem.fp) + fclose(MMU.bupmem.fp); + MMU.bupmem.fp = NULL; } void NDS_Reset( void) { - unsigned int i; - u32 src; - u32 dst; - NDS_header * header = NDS_getROMHeader(); + unsigned int i; + u32 src; + u32 dst; + NDS_header * header = NDS_getROMHeader(); - if (!header) return ; + if (!header) return ; - MMU_clearMem(); + MMU_clearMem(); - src = header->ARM9src; - dst = header->ARM9cpy; + src = header->ARM9src; + dst = header->ARM9cpy; - for(i = 0; i < (header->ARM9binSize>>2); ++i) - { - MMU_write32(0, dst, T1ReadLong(MMU.CART_ROM, src)); - dst += 4; - src += 4; - } + for(i = 0; i < (header->ARM9binSize>>2); ++i) + { + MMU_write32(0, dst, T1ReadLong(MMU.CART_ROM, src)); + dst += 4; + src += 4; + } - src = header->ARM7src; - dst = header->ARM7cpy; + src = header->ARM7src; + dst = header->ARM7cpy; - for(i = 0; i < (header->ARM7binSize>>2); ++i) - { - MMU_write32(1, dst, T1ReadLong(MMU.CART_ROM, src)); - dst += 4; - src += 4; - } + for(i = 0; i < (header->ARM7binSize>>2); ++i) + { + MMU_write32(1, dst, T1ReadLong(MMU.CART_ROM, src)); + dst += 4; + src += 4; + } - armcpu_init(&NDS_ARM7, header->ARM7exe); - armcpu_init(&NDS_ARM9, header->ARM9exe); - nds.ARM9Cycle = 0; - nds.ARM7Cycle = 0; - nds.cycles = 0; - memset(nds.timerCycle, 0, sizeof(s32) * 2 * 4); - memset(nds.timerOver, 0, sizeof(BOOL) * 2 * 4); - nds.nextHBlank = 3168; - nds.VCount = 0; - nds.old = 0; - nds.diff = 0; - nds.lignerendu = FALSE; - nds.touchX = nds.touchY = 0; - nds.isTouch = 0; + armcpu_init(&NDS_ARM7, header->ARM7exe); + armcpu_init(&NDS_ARM9, header->ARM9exe); + nds.ARM9Cycle = 0; + nds.ARM7Cycle = 0; + nds.cycles = 0; + memset(nds.timerCycle, 0, sizeof(s32) * 2 * 4); + memset(nds.timerOver, 0, sizeof(BOOL) * 2 * 4); + nds.nextHBlank = 3168; + nds.VCount = 0; + nds.old = 0; + nds.diff = 0; + nds.lignerendu = FALSE; + nds.touchX = nds.touchY = 0; + nds.isTouch = 0; - MMU_write16(0, 0x04000130, 0x3FF); - MMU_write16(1, 0x04000130, 0x3FF); - MMU_write8(1, 0x04000136, 0x43); + MMU_write16(0, 0x04000130, 0x3FF); + MMU_write16(1, 0x04000130, 0x3FF); + MMU_write8(1, 0x04000136, 0x43); - LidClosed = FALSE; + LidClosed = FALSE; LidKeyCount = 0; - /* - * Setup a copy of the firmware user settings in memory. - * (this is what the DS firmware would do). - */ - { - u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT]; - int fw_index; + /* + * Setup a copy of the firmware user settings in memory. + * (this is what the DS firmware would do). + */ + { + u8 temp_buffer[NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT]; + int fw_index; - if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) { - for ( fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++) - MMU_write8( 0, 0x027FFC80 + fw_index, temp_buffer[fw_index]); - } - } + if ( copy_firmware_user_data( temp_buffer, MMU.fw.data)) { + for ( fw_index = 0; fw_index < NDS_FW_USER_SETTINGS_MEM_BYTE_COUNT; fw_index++) + MMU_write8( 0, 0x027FFC80 + fw_index, temp_buffer[fw_index]); + } + } - // Copy the whole header to Main RAM 0x27FFE00 on startup. - // Reference: http://nocash.emubase.de/gbatek.htm#dscartridgeheader - for (i = 0; i < ((0x170+0x90)/4); i++) { - MMU_write32 (0, 0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); - } - MainScreen.offset = 0; - SubScreen.offset = 192; - - //MMU_write32(0, 0x02007FFC, 0xE92D4030); + // Copy the whole header to Main RAM 0x27FFE00 on startup. + // Reference: http://nocash.emubase.de/gbatek.htm#dscartridgeheader + for (i = 0; i < ((0x170+0x90)/4); i++) { + MMU_write32 (0, 0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i])); + } + MainScreen.offset = 0; + SubScreen.offset = 192; - //ARM7 BIOS IRQ HANDLER - MMU_write32(1, 0x00, 0xE25EF002); - MMU_write32(1, 0x04, 0xEAFFFFFE); - MMU_write32(1, 0x18, 0xEA000000); - MMU_write32(1, 0x20, 0xE92D500F); - MMU_write32(1, 0x24, 0xE3A00301); - MMU_write32(1, 0x28, 0xE28FE000); - MMU_write32(1, 0x2C, 0xE510F004); - MMU_write32(1, 0x30, 0xE8BD500F); - MMU_write32(1, 0x34, 0xE25EF004); + //MMU_write32(0, 0x02007FFC, 0xE92D4030); - //ARM9 BIOS IRQ HANDLER - MMU_write32(0, 0xFFFF0018, 0xEA000000); - MMU_write32(0, 0xFFFF0020, 0xE92D500F); - MMU_write32(0, 0xFFFF0024, 0xEE190F11); - MMU_write32(0, 0xFFFF0028, 0xE1A00620); - MMU_write32(0, 0xFFFF002C, 0xE1A00600); - MMU_write32(0, 0xFFFF0030, 0xE2800C40); - MMU_write32(0, 0xFFFF0034, 0xE28FE000); - MMU_write32(0, 0xFFFF0038, 0xE510F004); - MMU_write32(0, 0xFFFF003C, 0xE8BD500F); - MMU_write32(0, 0xFFFF0040, 0xE25EF004); + FILE* inf = 0; + + //ARM7 BIOS IRQ HANDLER + inf = fopen("BiosNds7.ROM","rb"); + if(inf) { + fread(MMU.ARM7_BIOS,1,16384,inf); + fclose(inf); + NDS_ARM7.swi_tab = 0; + } else { + NDS_ARM7.swi_tab = ARM7_swi_tab; + MMU_write32(1, 0x00, 0xE25EF002); + MMU_write32(1, 0x04, 0xEAFFFFFE); + MMU_write32(1, 0x18, 0xEA000000); + MMU_write32(1, 0x20, 0xE92D500F); + MMU_write32(1, 0x24, 0xE3A00301); + MMU_write32(1, 0x28, 0xE28FE000); + MMU_write32(1, 0x2C, 0xE510F004); + MMU_write32(1, 0x30, 0xE8BD500F); + MMU_write32(1, 0x34, 0xE25EF004); + } - MMU_write32(0, 0x0000004, 0xE3A0010E); - MMU_write32(0, 0x0000008, 0xE3A01020); -// MMU_write32(0, 0x000000C, 0xE1B02110); - MMU_write32(0, 0x000000C, 0xE1B02040); - MMU_write32(0, 0x0000010, 0xE3B02020); -// MMU_write32(0, 0x0000010, 0xE2100202); + //ARM9 BIOS IRQ HANDLER + inf = fopen("BiosNds9.ROM","rb"); + if(inf) { + fread(ARM9Mem.ARM9_BIOS,1,4096,inf); + fclose(inf); + NDS_ARM9.swi_tab = 0; + } else { + NDS_ARM9.swi_tab = ARM9_swi_tab; + MMU_write32(0, 0xFFFF0018, 0xEA000000); + MMU_write32(0, 0xFFFF0020, 0xE92D500F); + MMU_write32(0, 0xFFFF0024, 0xEE190F11); + MMU_write32(0, 0xFFFF0028, 0xE1A00620); + MMU_write32(0, 0xFFFF002C, 0xE1A00600); + MMU_write32(0, 0xFFFF0030, 0xE2800C40); + MMU_write32(0, 0xFFFF0034, 0xE28FE000); + MMU_write32(0, 0xFFFF0038, 0xE510F004); + MMU_write32(0, 0xFFFF003C, 0xE8BD500F); + MMU_write32(0, 0xFFFF0040, 0xE25EF004); + } + + - delete header; - GPU_Reset(MainScreen.gpu, 0); - GPU_Reset(SubScreen.gpu, 1); - gfx3d_reset(); - gpu3D->NDS_3D_Reset(); - SPU_Reset(); + MMU_write32(0, 0x0000004, 0xE3A0010E); + MMU_write32(0, 0x0000008, 0xE3A01020); + // MMU_write32(0, 0x000000C, 0xE1B02110); + MMU_write32(0, 0x000000C, 0xE1B02040); + MMU_write32(0, 0x0000010, 0xE3B02020); + // MMU_write32(0, 0x0000010, 0xE2100202); + + delete header; + + GPU_Reset(MainScreen.gpu, 0); + GPU_Reset(SubScreen.gpu, 1); + gfx3d_reset(); + gpu3D->NDS_3D_Reset(); + SPU_Reset(); } int NDS_ImportSave(const char *filename) { - if (strlen(filename) < 4) - return 0; + if (strlen(filename) < 4) + return 0; - if (memcmp(filename+strlen(filename)-4, ".duc", 4) == 0) - return mc_load_duc(&MMU.bupmem, filename); + if (memcmp(filename+strlen(filename)-4, ".duc", 4) == 0) + return mc_load_duc(&MMU.bupmem, filename); - return 0; + return 0; } typedef struct { - u32 size; - s32 width; - s32 height; - u16 planes; - u16 bpp; - u32 cmptype; - u32 imgsize; - s32 hppm; - s32 vppm; - u32 numcol; - u32 numimpcol; + u32 size; + s32 width; + s32 height; + u16 planes; + u16 bpp; + u32 cmptype; + u32 imgsize; + s32 hppm; + s32 vppm; + u32 numcol; + u32 numimpcol; } bmpimgheader_struct; #include "PACKED.h" typedef struct { - u16 id __PACKED; - u32 size __PACKED; - u16 reserved1 __PACKED; - u16 reserved2 __PACKED; - u32 imgoffset __PACKED; + u16 id __PACKED; + u32 size __PACKED; + u16 reserved1 __PACKED; + u16 reserved2 __PACKED; + u32 imgoffset __PACKED; } bmpfileheader_struct; #include "PACKED_END.h" int NDS_WriteBMP(const char *filename) { - bmpfileheader_struct fileheader; - bmpimgheader_struct imageheader; - FILE *file; - int i,j; - u16 * bmp = (u16 *)GPU_screen; - size_t elems_written = 0; + bmpfileheader_struct fileheader; + bmpimgheader_struct imageheader; + FILE *file; + int i,j; + u16 * bmp = (u16 *)GPU_screen; + size_t elems_written = 0; - memset(&fileheader, 0, sizeof(fileheader)); - fileheader.size = sizeof(fileheader); - fileheader.id = 'B' | ('M' << 8); - fileheader.imgoffset = sizeof(fileheader)+sizeof(imageheader); - - memset(&imageheader, 0, sizeof(imageheader)); - imageheader.size = sizeof(imageheader); - imageheader.width = 256; - imageheader.height = 192*2; - imageheader.planes = 1; - imageheader.bpp = 24; - imageheader.cmptype = 0; // None - imageheader.imgsize = imageheader.width * imageheader.height * 3; - - if ((file = fopen(filename,"wb")) == NULL) - return 0; + memset(&fileheader, 0, sizeof(fileheader)); + fileheader.size = sizeof(fileheader); + fileheader.id = 'B' | ('M' << 8); + fileheader.imgoffset = sizeof(fileheader)+sizeof(imageheader); - elems_written += fwrite(&fileheader, 1, sizeof(fileheader), file); - elems_written += fwrite(&imageheader, 1, sizeof(imageheader), file); + memset(&imageheader, 0, sizeof(imageheader)); + imageheader.size = sizeof(imageheader); + imageheader.width = 256; + imageheader.height = 192*2; + imageheader.planes = 1; + imageheader.bpp = 24; + imageheader.cmptype = 0; // None + imageheader.imgsize = imageheader.width * imageheader.height * 3; - for(j=0;j<192*2;j++) - { - for(i=0;i<256;i++) - { - u8 r,g,b; - u16 pixel = bmp[(192*2-j-1)*256+i]; - r = pixel>>10; - pixel-=r<<10; - g = pixel>>5; - pixel-=g<<5; - b = pixel; - r*=255/31; - g*=255/31; - b*=255/31; - elems_written += fwrite(&r, 1, sizeof(u8), file); - elems_written += fwrite(&g, 1, sizeof(u8), file); - elems_written += fwrite(&b, 1, sizeof(u8), file); - } - } - fclose(file); + if ((file = fopen(filename,"wb")) == NULL) + return 0; - return 1; + elems_written += fwrite(&fileheader, 1, sizeof(fileheader), file); + elems_written += fwrite(&imageheader, 1, sizeof(imageheader), file); + + for(j=0;j<192*2;j++) + { + for(i=0;i<256;i++) + { + u8 r,g,b; + u16 pixel = bmp[(192*2-j-1)*256+i]; + r = pixel>>10; + pixel-=r<<10; + g = pixel>>5; + pixel-=g<<5; + b = pixel; + r*=255/31; + g*=255/31; + b*=255/31; + elems_written += fwrite(&r, 1, sizeof(u8), file); + elems_written += fwrite(&g, 1, sizeof(u8), file); + elems_written += fwrite(&b, 1, sizeof(u8), file); + } + } + fclose(file); + + return 1; } int NDS_WriteBMP_32bppBuffer(int width, int height, const void* buf, const char *filename) { - bmpfileheader_struct fileheader; - bmpimgheader_struct imageheader; - FILE *file; - size_t elems_written = 0; - memset(&fileheader, 0, sizeof(fileheader)); - fileheader.size = sizeof(fileheader); - fileheader.id = 'B' | ('M' << 8); - fileheader.imgoffset = sizeof(fileheader)+sizeof(imageheader); - - memset(&imageheader, 0, sizeof(imageheader)); - imageheader.size = sizeof(imageheader); - imageheader.width = width; - imageheader.height = height; - imageheader.planes = 1; - imageheader.bpp = 32; - imageheader.cmptype = 0; // None - imageheader.imgsize = imageheader.width * imageheader.height * 4; - - if ((file = fopen(filename,"wb")) == NULL) - return 0; + bmpfileheader_struct fileheader; + bmpimgheader_struct imageheader; + FILE *file; + size_t elems_written = 0; + memset(&fileheader, 0, sizeof(fileheader)); + fileheader.size = sizeof(fileheader); + fileheader.id = 'B' | ('M' << 8); + fileheader.imgoffset = sizeof(fileheader)+sizeof(imageheader); - elems_written += fwrite(&fileheader, 1, sizeof(fileheader), file); - elems_written += fwrite(&imageheader, 1, sizeof(imageheader), file); + memset(&imageheader, 0, sizeof(imageheader)); + imageheader.size = sizeof(imageheader); + imageheader.width = width; + imageheader.height = height; + imageheader.planes = 1; + imageheader.bpp = 32; + imageheader.cmptype = 0; // None + imageheader.imgsize = imageheader.width * imageheader.height * 4; - elems_written += fwrite(buf,1,imageheader.imgsize,file); - fclose(file); + if ((file = fopen(filename,"wb")) == NULL) + return 0; - return 1; + elems_written += fwrite(&fileheader, 1, sizeof(fileheader), file); + elems_written += fwrite(&imageheader, 1, sizeof(imageheader), file); + + elems_written += fwrite(buf,1,imageheader.imgsize,file); + fclose(file); + + return 1; } static void fill_user_data_area( struct NDS_fw_config_data *user_settings, - u8 *data, int count) { - u32 crc; - int i; - u8 *ts_cal_data_area; + u8 *data, int count) { + u32 crc; + int i; + u8 *ts_cal_data_area; - memset( data, 0, 0x100); + memset( data, 0, 0x100); - /* version */ - data[0x00] = 5; - data[0x01] = 0; + /* version */ + data[0x00] = 5; + data[0x01] = 0; - /* colour */ - data[0x02] = user_settings->fav_colour; + /* colour */ + data[0x02] = user_settings->fav_colour; - /* birthday month and day */ - data[0x03] = user_settings->birth_month; - data[0x04] = user_settings->birth_day; + /* birthday month and day */ + data[0x03] = user_settings->birth_month; + data[0x04] = user_settings->birth_day; - /* nickname and length */ - for ( i = 0; i < MAX_FW_NICKNAME_LENGTH; i++) { - data[0x06 + (i * 2)] = user_settings->nickname[i] & 0xff; - data[0x06 + (i * 2) + 1] = (user_settings->nickname[i] >> 8) & 0xff; - } + /* nickname and length */ + for ( i = 0; i < MAX_FW_NICKNAME_LENGTH; i++) { + data[0x06 + (i * 2)] = user_settings->nickname[i] & 0xff; + data[0x06 + (i * 2) + 1] = (user_settings->nickname[i] >> 8) & 0xff; + } - data[0x1a] = user_settings->nickname_len; + data[0x1a] = user_settings->nickname_len; - /* Message */ - for ( i = 0; i < MAX_FW_MESSAGE_LENGTH; i++) { - data[0x1c + (i * 2)] = user_settings->message[i] & 0xff; - data[0x1c + (i * 2) + 1] = (user_settings->message[i] >> 8) & 0xff; - } + /* Message */ + for ( i = 0; i < MAX_FW_MESSAGE_LENGTH; i++) { + data[0x1c + (i * 2)] = user_settings->message[i] & 0xff; + data[0x1c + (i * 2) + 1] = (user_settings->message[i] >> 8) & 0xff; + } - data[0x50] = user_settings->message_len; + data[0x50] = user_settings->message_len; - /* - * touch screen calibration - */ - ts_cal_data_area = &data[0x58]; - for ( i = 0; i < 2; i++) { - /* ADC x y */ - *ts_cal_data_area++ = user_settings->touch_cal[i].adc_x & 0xff; - *ts_cal_data_area++ = (user_settings->touch_cal[i].adc_x >> 8) & 0xff; - *ts_cal_data_area++ = user_settings->touch_cal[i].adc_y & 0xff; - *ts_cal_data_area++ = (user_settings->touch_cal[i].adc_y >> 8) & 0xff; + /* + * touch screen calibration + */ + ts_cal_data_area = &data[0x58]; + for ( i = 0; i < 2; i++) { + /* ADC x y */ + *ts_cal_data_area++ = user_settings->touch_cal[i].adc_x & 0xff; + *ts_cal_data_area++ = (user_settings->touch_cal[i].adc_x >> 8) & 0xff; + *ts_cal_data_area++ = user_settings->touch_cal[i].adc_y & 0xff; + *ts_cal_data_area++ = (user_settings->touch_cal[i].adc_y >> 8) & 0xff; - /* screen x y */ - *ts_cal_data_area++ = user_settings->touch_cal[i].screen_x; - *ts_cal_data_area++ = user_settings->touch_cal[i].screen_y; - } + /* screen x y */ + *ts_cal_data_area++ = user_settings->touch_cal[i].screen_x; + *ts_cal_data_area++ = user_settings->touch_cal[i].screen_y; + } - /* language and flags */ - data[0x64] = user_settings->language; - data[0x65] = 0xfc; + /* language and flags */ + data[0x64] = user_settings->language; + data[0x65] = 0xfc; - /* update count and crc */ - data[0x70] = count & 0xff; - data[0x71] = (count >> 8) & 0xff; + /* update count and crc */ + data[0x70] = count & 0xff; + data[0x71] = (count >> 8) & 0xff; - crc = calc_CRC16( 0xffff, data, 0x70); - data[0x72] = crc & 0xff; - data[0x73] = (crc >> 8) & 0xff; + crc = calc_CRC16( 0xffff, data, 0x70); + data[0x72] = crc & 0xff; + data[0x73] = (crc >> 8) & 0xff; - memset( &data[0x74], 0xff, 0x100 - 0x74); + memset( &data[0x74], 0xff, 0x100 - 0x74); } /* creates an firmware flash image, which contains all needed info to initiate a wifi connection */ int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings) { - /* - * Create the firmware header - */ - memset( MMU.fw.data, 0, 0x40000); + /* + * Create the firmware header + */ + memset( MMU.fw.data, 0, 0x40000); - /* firmware identifier */ - MMU.fw.data[0x8] = 'M'; - MMU.fw.data[0x8 + 1] = 'A'; - MMU.fw.data[0x8 + 2] = 'C'; - MMU.fw.data[0x8 + 3] = 'P'; + /* firmware identifier */ + MMU.fw.data[0x8] = 'M'; + MMU.fw.data[0x8 + 1] = 'A'; + MMU.fw.data[0x8 + 2] = 'C'; + MMU.fw.data[0x8 + 3] = 'P'; - /* DS type */ - if ( user_settings->ds_type == NDS_FW_DS_TYPE_LITE) - MMU.fw.data[0x1d] = 0x20; - else - MMU.fw.data[0x1d] = 0xff; + /* DS type */ + if ( user_settings->ds_type == NDS_FW_DS_TYPE_LITE) + MMU.fw.data[0x1d] = 0x20; + else + MMU.fw.data[0x1d] = 0xff; - /* User Settings offset 0x3fe00 / 8 */ - MMU.fw.data[0x20] = 0xc0; - MMU.fw.data[0x21] = 0x7f; + /* User Settings offset 0x3fe00 / 8 */ + MMU.fw.data[0x20] = 0xc0; + MMU.fw.data[0x21] = 0x7f; - /* - * User settings (at 0x3FE00 and 0x3FF00) - */ - fill_user_data_area( user_settings, &MMU.fw.data[ 0x3FE00], 0); - fill_user_data_area( user_settings, &MMU.fw.data[ 0x3FF00], 1); - + /* + * User settings (at 0x3FE00 and 0x3FF00) + */ + fill_user_data_area( user_settings, &MMU.fw.data[ 0x3FE00], 0); + fill_user_data_area( user_settings, &MMU.fw.data[ 0x3FF00], 1); + /* Wifi config length */ MMU.fw.data[0x2C] = 0x38; MMU.fw.data[0x2D] = 0x01; @@ -853,7 +874,7 @@ int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings) (*(u16*)(MMU.fw.data + 0x3FAFE)) = (u16)calc_CRC16(0, (MMU.fw.data + 0x3FA00), 0xFE); (*(u16*)(MMU.fw.data + 0x3FBFE)) = (u16)calc_CRC16(0, (MMU.fw.data + 0x3FB00), 0xFE); (*(u16*)(MMU.fw.data + 0x3FCFE)) = (u16)calc_CRC16(0, (MMU.fw.data + 0x3FC00), 0xFE); - + MMU.fw.data[0x162] = 0x19; memset((MMU.fw.data + 0x163), 0xFF, 0x9D); @@ -866,69 +887,69 @@ int NDS_CreateDummyFirmware( struct NDS_fw_config_data *user_settings) void NDS_FillDefaultFirmwareConfigData( struct NDS_fw_config_data *fw_config) { - const char *default_nickname = "yopyop"; - const char *default_message = "DeSmuME makes you happy!"; - int i; - int str_length; + const char *default_nickname = "yopyop"; + const char *default_message = "DeSmuME makes you happy!"; + int i; + int str_length; - memset( fw_config, 0, sizeof( struct NDS_fw_config_data)); - fw_config->ds_type = NDS_FW_DS_TYPE_FAT; + memset( fw_config, 0, sizeof( struct NDS_fw_config_data)); + fw_config->ds_type = NDS_FW_DS_TYPE_FAT; - fw_config->fav_colour = 7; + fw_config->fav_colour = 7; - fw_config->birth_day = 23; - fw_config->birth_month = 6; + fw_config->birth_day = 23; + fw_config->birth_month = 6; - str_length = strlen( default_nickname); - for ( i = 0; i < str_length; i++) { - fw_config->nickname[i] = default_nickname[i]; - } - fw_config->nickname_len = str_length; + str_length = strlen( default_nickname); + for ( i = 0; i < str_length; i++) { + fw_config->nickname[i] = default_nickname[i]; + } + fw_config->nickname_len = str_length; - str_length = strlen( default_message); - for ( i = 0; i < str_length; i++) { - fw_config->message[i] = default_message[i]; - } - fw_config->message_len = str_length; + str_length = strlen( default_message); + for ( i = 0; i < str_length; i++) { + fw_config->message[i] = default_message[i]; + } + fw_config->message_len = str_length; - /* default to English */ - fw_config->language = 1; + /* default to English */ + fw_config->language = 1; - /* default touchscreen calibration */ - fw_config->touch_cal[0].adc_x = 0x200; - fw_config->touch_cal[0].adc_y = 0x200; - fw_config->touch_cal[0].screen_x = 0x20; - fw_config->touch_cal[0].screen_y = 0x20; + /* default touchscreen calibration */ + fw_config->touch_cal[0].adc_x = 0x200; + fw_config->touch_cal[0].adc_y = 0x200; + fw_config->touch_cal[0].screen_x = 0x20; + fw_config->touch_cal[0].screen_y = 0x20; - fw_config->touch_cal[1].adc_x = 0xe00; - fw_config->touch_cal[1].adc_y = 0x800; - fw_config->touch_cal[1].screen_x = 0xe0; - fw_config->touch_cal[1].screen_y = 0x80; + fw_config->touch_cal[1].adc_x = 0xe00; + fw_config->touch_cal[1].adc_y = 0x800; + fw_config->touch_cal[1].screen_x = 0xe0; + fw_config->touch_cal[1].screen_y = 0x80; } int NDS_LoadFirmware(const char *filename) { - int i; - unsigned long size; - FILE *file; - - if ((file = fopen(filename, "rb")) == NULL) - return -1; - - fseek(file, 0, SEEK_END); - size = ftell(file); - fseek(file, 0, SEEK_SET); - - if(size > MMU.fw.size) - { - fclose(file); - return -1; - } - - i = fread(MMU.fw.data, size, 1, file); - fclose(file); - - return i; + int i; + unsigned long size; + FILE *file; + + if ((file = fopen(filename, "rb")) == NULL) + return -1; + + fseek(file, 0, SEEK_END); + size = ftell(file); + fseek(file, 0, SEEK_SET); + + if(size > MMU.fw.size) + { + fclose(file); + return -1; + } + + i = fread(MMU.fw.data, size, 1, file); + fclose(file); + + return i; } #define INDEX(i) ((((i)>>16)&0xFF0)|(((i)>>4)&0xF)) @@ -939,18 +960,18 @@ u32 NDS_exec(s32 nb) { int i, j; - nb += nds.cycles;//(nds.cycles>>26)<<26; + nb += nds.cycles;//(nds.cycles>>26)<<26; - //increase this to execute more instructions in each batch (reducing overhead) - //the value of 4 seems to optimize speed.. do lower values increase precision? - const int INSTRUCTIONS_PER_BATCH = 4; + //increase this to execute more instructions in each batch (reducing overhead) + //the value of 4 seems to optimize speed.. do lower values increase precision? + const int INSTRUCTIONS_PER_BATCH = 4; - //decreasing this should increase precision at the cost of speed - //the traditional value was somewhere between 100 and 400 depending on circumstances - const int CYCLES_TO_WAIT_FOR_IRQ = 400; - - for(; (nb >= nds.cycles) && ((FORCE)||(execute)); ) - { + //decreasing this should increase precision at the cost of speed + //the traditional value was somewhere between 100 and 400 depending on circumstances + const int CYCLES_TO_WAIT_FOR_IRQ = 400; + + for(; (nb >= nds.cycles) && ((FORCE)||(execute)); ) + { for (j = 0; j < INSTRUCTIONS_PER_BATCH && (!FORCE) && (execute); j++) { if(nds.ARM9Cycle<=nds.cycles) @@ -1022,145 +1043,145 @@ u32 NDS_exec(s32 nb) } nds.cycles = std::min(nds.ARM9Cycle,nds.ARM7Cycle); - - //debug(); + + //debug(); if(nds.cycles>=nds.nextHBlank) - { - if(!nds.lignerendu) - { - T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 2); - T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 2); - NDS_ARM9HBlankInt(); - NDS_ARM7HBlankInt(); + { + if(!nds.lignerendu) + { + T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 2); + T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 2); + NDS_ARM9HBlankInt(); + NDS_ARM7HBlankInt(); - if(nds.VCount<192) - { - GPU_ligne(&MainScreen, nds.VCount); - GPU_ligne(&SubScreen, nds.VCount); - - if(MMU.DMAStartTime[0][0] == 2) - MMU_doDMA(0, 0); - if(MMU.DMAStartTime[0][1] == 2) - MMU_doDMA(0, 1); - if(MMU.DMAStartTime[0][2] == 2) - MMU_doDMA(0, 2); - if(MMU.DMAStartTime[0][3] == 2) - MMU_doDMA(0, 3); - } - nds.lignerendu = TRUE; - } - if(nds.cycles>=nds.nextHBlank+1092) - { - u32 vmatch; + if(nds.VCount<192) + { + GPU_ligne(&MainScreen, nds.VCount); + GPU_ligne(&SubScreen, nds.VCount); - ++nds.VCount; - nds.nextHBlank += 4260; - T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFD); - T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFD); - - if(MMU.DMAStartTime[0][0] == 3) - MMU_doDMA(0, 0); - if(MMU.DMAStartTime[0][1] == 3) - MMU_doDMA(0, 1); - if(MMU.DMAStartTime[0][2] == 3) - MMU_doDMA(0, 2); - if(MMU.DMAStartTime[0][3] == 3) - MMU_doDMA(0, 3); + if(MMU.DMAStartTime[0][0] == 2) + MMU_doDMA(0, 0); + if(MMU.DMAStartTime[0][1] == 2) + MMU_doDMA(0, 1); + if(MMU.DMAStartTime[0][2] == 2) + MMU_doDMA(0, 2); + if(MMU.DMAStartTime[0][3] == 2) + MMU_doDMA(0, 3); + } + nds.lignerendu = TRUE; + } + if(nds.cycles>=nds.nextHBlank+1092) + { + u32 vmatch; - // Main memory display - if(MMU.DMAStartTime[0][0] == 4) - { - MMU_doDMA(0, 0); - MMU.DMAStartTime[0][0] = 0; - } - if(MMU.DMAStartTime[0][1] == 4) - { - MMU_doDMA(0, 1); - MMU.DMAStartTime[0][1] = 0; - } - if(MMU.DMAStartTime[0][2] == 4) - { - MMU_doDMA(0, 2); - MMU.DMAStartTime[0][2] = 0; - } - if(MMU.DMAStartTime[0][3] == 4) - { - MMU_doDMA(0, 3); - MMU.DMAStartTime[0][3] = 0; - } + ++nds.VCount; + nds.nextHBlank += 4260; + T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFD); + T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFD); - if(MMU.DMAStartTime[1][0] == 4) - { - MMU_doDMA(1, 0); - MMU.DMAStartTime[1][0] = 0; - } - if(MMU.DMAStartTime[1][1] == 4) - { - MMU_doDMA(1, 1); - MMU.DMAStartTime[0][1] = 0; - } - if(MMU.DMAStartTime[1][2] == 4) - { - MMU_doDMA(1, 2); - MMU.DMAStartTime[1][2] = 0; - } - if(MMU.DMAStartTime[1][3] == 4) - { - MMU_doDMA(1, 3); - MMU.DMAStartTime[1][3] = 0; - } - - nds.lignerendu = FALSE; - if(nds.VCount==192) - { + if(MMU.DMAStartTime[0][0] == 3) + MMU_doDMA(0, 0); + if(MMU.DMAStartTime[0][1] == 3) + MMU_doDMA(0, 1); + if(MMU.DMAStartTime[0][2] == 3) + MMU_doDMA(0, 2); + if(MMU.DMAStartTime[0][3] == 3) + MMU_doDMA(0, 3); + + // Main memory display + if(MMU.DMAStartTime[0][0] == 4) + { + MMU_doDMA(0, 0); + MMU.DMAStartTime[0][0] = 0; + } + if(MMU.DMAStartTime[0][1] == 4) + { + MMU_doDMA(0, 1); + MMU.DMAStartTime[0][1] = 0; + } + if(MMU.DMAStartTime[0][2] == 4) + { + MMU_doDMA(0, 2); + MMU.DMAStartTime[0][2] = 0; + } + if(MMU.DMAStartTime[0][3] == 4) + { + MMU_doDMA(0, 3); + MMU.DMAStartTime[0][3] = 0; + } + + if(MMU.DMAStartTime[1][0] == 4) + { + MMU_doDMA(1, 0); + MMU.DMAStartTime[1][0] = 0; + } + if(MMU.DMAStartTime[1][1] == 4) + { + MMU_doDMA(1, 1); + MMU.DMAStartTime[0][1] = 0; + } + if(MMU.DMAStartTime[1][2] == 4) + { + MMU_doDMA(1, 2); + MMU.DMAStartTime[1][2] = 0; + } + if(MMU.DMAStartTime[1][3] == 4) + { + MMU_doDMA(1, 3); + MMU.DMAStartTime[1][3] = 0; + } + + nds.lignerendu = FALSE; + if(nds.VCount==192) + { //osdA->update(); //================================= this is don't correct, need swap engine gfx3d_VBlankSignal(); - T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 1); - T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 1); - NDS_ARM9VBlankInt(); - NDS_ARM7VBlankInt(); - nds.runCycleCollector[nds.idleFrameCounter] = 1120380-nds.idleCycles; - nds.idleFrameCounter++; - nds.idleFrameCounter &= 15; - nds.idleCycles = 0; + T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 1); + T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 1); + NDS_ARM9VBlankInt(); + NDS_ARM7VBlankInt(); + nds.runCycleCollector[nds.idleFrameCounter] = 1120380-nds.idleCycles; + nds.idleFrameCounter++; + nds.idleFrameCounter &= 15; + nds.idleCycles = 0; - - if(MMU.DMAStartTime[0][0] == 1) - MMU_doDMA(0, 0); - if(MMU.DMAStartTime[0][1] == 1) - MMU_doDMA(0, 1); - if(MMU.DMAStartTime[0][2] == 1) - MMU_doDMA(0, 2); - if(MMU.DMAStartTime[0][3] == 1) - MMU_doDMA(0, 3); - - if(MMU.DMAStartTime[1][0] == 1) - MMU_doDMA(1, 0); - if(MMU.DMAStartTime[1][1] == 1) - MMU_doDMA(1, 1); - if(MMU.DMAStartTime[1][2] == 1) - MMU_doDMA(1, 2); - if(MMU.DMAStartTime[1][3] == 1) - MMU_doDMA(1, 3); - } - else if(nds.VCount==214) { - gfx3d_VBlankEndSignal(); - } - else if(nds.VCount==263) - { + + if(MMU.DMAStartTime[0][0] == 1) + MMU_doDMA(0, 0); + if(MMU.DMAStartTime[0][1] == 1) + MMU_doDMA(0, 1); + if(MMU.DMAStartTime[0][2] == 1) + MMU_doDMA(0, 2); + if(MMU.DMAStartTime[0][3] == 1) + MMU_doDMA(0, 3); + + if(MMU.DMAStartTime[1][0] == 1) + MMU_doDMA(1, 0); + if(MMU.DMAStartTime[1][1] == 1) + MMU_doDMA(1, 1); + if(MMU.DMAStartTime[1][2] == 1) + MMU_doDMA(1, 2); + if(MMU.DMAStartTime[1][3] == 1) + MMU_doDMA(1, 3); + } + else if(nds.VCount==214) { + gfx3d_VBlankEndSignal(); + } + else if(nds.VCount==263) + { //osd->update(); //osdB->update(); //================================= this is don't correct, need swap engine - nds.nextHBlank = 3168; - nds.VCount = 0; - T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFE); - T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFE); + nds.nextHBlank = 3168; + nds.VCount = 0; + T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFE); + T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFE); - nds.cycles -= (560190<<1); - nds.ARM9Cycle -= (560190<<1); - nds.ARM7Cycle -= (560190<<1); + nds.cycles -= (560190<<1); + nds.ARM9Cycle -= (560190<<1); + nds.ARM7Cycle -= (560190<<1); nb -= (560190<<1); if(MMU.divRunning) @@ -1179,7 +1200,7 @@ u32 NDS_exec(s32 nb) if(MMU.timerON[0][1]) nds.timerCycle[0][1] -= (560190<<1); if(MMU.timerON[0][2]) nds.timerCycle[0][2] -= (560190<<1); if(MMU.timerON[0][3]) nds.timerCycle[0][3] -= (560190<<1); - + if(MMU.timerON[1][0]) nds.timerCycle[1][0] -= (560190<<1); if(MMU.timerON[1][1]) nds.timerCycle[1][1] -= (560190<<1); if(MMU.timerON[1][2]) nds.timerCycle[1][2] -= (560190<<1); @@ -1198,32 +1219,32 @@ u32 NDS_exec(s32 nb) if(MMU.DMAing[1][2]) MMU.DMACycle[1][2] -= (560190<<1); if(MMU.DMAing[1][3]) MMU.DMACycle[1][3] -= (560190<<1); } - } - - T1WriteWord(ARM9Mem.ARM9_REG, 6, nds.VCount); - T1WriteWord(MMU.ARM7_REG, 6, nds.VCount); - - vmatch = T1ReadWord(ARM9Mem.ARM9_REG, 4); - if(nds.VCount==((vmatch>>8)|((vmatch<<1)&(1<<8)))) - { - T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 4); - if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 32) - NDS_makeARM9Int(2); - } - else - T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFB); - - vmatch = T1ReadWord(MMU.ARM7_REG, 4); - if(nds.VCount==((vmatch>>8)|((vmatch<<1)&(1<<8)))) - { - T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 4); - if(T1ReadWord(MMU.ARM7_REG, 4) & 32) - NDS_makeARM7Int(2); - } - else - T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFB); - } - } + } + + T1WriteWord(ARM9Mem.ARM9_REG, 6, nds.VCount); + T1WriteWord(MMU.ARM7_REG, 6, nds.VCount); + + vmatch = T1ReadWord(ARM9Mem.ARM9_REG, 4); + if(nds.VCount==((vmatch>>8)|((vmatch<<1)&(1<<8)))) + { + T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) | 4); + if(T1ReadWord(ARM9Mem.ARM9_REG, 4) & 32) + NDS_makeARM9Int(2); + } + else + T1WriteWord(ARM9Mem.ARM9_REG, 4, T1ReadWord(ARM9Mem.ARM9_REG, 4) & 0xFFFB); + + vmatch = T1ReadWord(MMU.ARM7_REG, 4); + if(nds.VCount==((vmatch>>8)|((vmatch<<1)&(1<<8)))) + { + T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) | 4); + if(T1ReadWord(MMU.ARM7_REG, 4) & 32) + NDS_makeARM7Int(2); + } + else + T1WriteWord(MMU.ARM7_REG, 4, T1ReadWord(MMU.ARM7_REG, 4) & 0xFFFB); + } + } if(MMU.divRunning) { @@ -1581,7 +1602,7 @@ u32 NDS_exec(s32 nb) if (MMU.CheckDMAs) { - + if((MMU.DMAing[0][0])&&(MMU.DMACycle[0][0]<=nds.cycles)) { T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF); @@ -1589,7 +1610,7 @@ u32 NDS_exec(s32 nb) MMU.DMAing[0][0] = FALSE; MMU.CheckDMAs &= ~(1<<(0+(0<<2))); } - + if((MMU.DMAing[0][1])&&(MMU.DMACycle[0][1]<=nds.cycles)) { T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF); @@ -1597,7 +1618,7 @@ u32 NDS_exec(s32 nb) MMU.DMAing[0][1] = FALSE; MMU.CheckDMAs &= ~(1<<(1+(0<<2))); } - + if((MMU.DMAing[0][2])&&(MMU.DMACycle[0][2]<=nds.cycles)) { T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF); @@ -1605,7 +1626,7 @@ u32 NDS_exec(s32 nb) MMU.DMAing[0][2] = FALSE; MMU.CheckDMAs &= ~(1<<(2+(0<<2))); } - + if((MMU.DMAing[0][3])&&(MMU.DMACycle[0][3]<=nds.cycles)) { T1WriteLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3), T1ReadLong(ARM9Mem.ARM9_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF); @@ -1613,7 +1634,7 @@ u32 NDS_exec(s32 nb) MMU.DMAing[0][3] = FALSE; MMU.CheckDMAs &= ~(1<<(3+(0<<2))); } - + if((MMU.DMAing[1][0])&&(MMU.DMACycle[1][0]<=nds.cycles)) { T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*0), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*0)) & 0x7FFFFFFF); @@ -1621,7 +1642,7 @@ u32 NDS_exec(s32 nb) MMU.DMAing[1][0] = FALSE; MMU.CheckDMAs &= ~(1<<(0+(1<<2))); } - + if((MMU.DMAing[1][1])&&(MMU.DMACycle[1][1]<=nds.cycles)) { T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*1), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*1)) & 0x7FFFFFFF); @@ -1629,7 +1650,7 @@ u32 NDS_exec(s32 nb) MMU.DMAing[1][1] = FALSE; MMU.CheckDMAs &= ~(1<<(1+(1<<2))); } - + if((MMU.DMAing[1][2])&&(MMU.DMACycle[1][2]<=nds.cycles)) { T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*2), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*2)) & 0x7FFFFFFF); @@ -1637,7 +1658,7 @@ u32 NDS_exec(s32 nb) MMU.DMAing[1][2] = FALSE; MMU.CheckDMAs &= ~(1<<(2+(1<<2))); } - + if((MMU.DMAing[1][3])&&(MMU.DMACycle[1][3]<=nds.cycles)) { T1WriteLong(MMU.ARM7_REG, 0xB8 + (0xC*3), T1ReadLong(MMU.ARM7_REG, 0xB8 + (0xC*3)) & 0x7FFFFFFF); @@ -1646,7 +1667,7 @@ u32 NDS_exec(s32 nb) MMU.CheckDMAs &= ~(1<<(3+(1<<2))); } } - + if(MMU.reg_IE[ARMCPU_ARM9]&(1<<21)) NDS_makeARM9Int(21); // GX geometry @@ -1675,16 +1696,16 @@ u32 NDS_exec(s32 nb) } - - - } - + + + } + return nds.cycles; } void NDS_setPadFromMovie(u16 pad) { - #define FIX(b,n) (((pad>>n)&1)!=0) +#define FIX(b,n) (((pad>>n)&1)!=0) NDS_setPad( FIX(pad,0), FIX(pad,1), @@ -1701,15 +1722,15 @@ void NDS_setPadFromMovie(u16 pad) FIX(pad,12), FIX(pad,13) ); - #undef FIX +#undef FIX } void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,bool X,bool W,bool E,bool G, bool F) { - + //this macro is the opposite of what you would expect - #define FIX(b) (b?0:0x80) - +#define FIX(b) (b?0:0x80) + int r = FIX(R); int l = FIX(L); int d = FIX(D); @@ -1724,27 +1745,27 @@ void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,b int e = FIX(E); int g = FIX(G); int f = FIX(F); - + u16 pad = (0 | - ((a) >> 7) | - ((b) >> 6) | - ((s) >> 5) | - ((t) >> 4) | - ((r) >> 3) | - ((l) >> 2) | - ((u) >> 1) | - ((d)) | - ((e) << 1) | - ((w) << 2)) ; + ((a) >> 7) | + ((b) >> 6) | + ((s) >> 5) | + ((t) >> 4) | + ((r) >> 3) | + ((l) >> 2) | + ((u) >> 1) | + ((d)) | + ((e) << 1) | + ((w) << 2)) ; ((u16 *)ARM9Mem.ARM9_REG)[0x130>>1] = (u16)pad; ((u16 *)MMU.ARM7_REG)[0x130>>1] = (u16)pad; u16 padExt = (((u16 *)MMU.ARM7_REG)[0x136>>1] & 0x0070) | - ((x) >> 7) | - ((y) >> 6) | - ((g) >> 4) | - 0x0034; + ((x) >> 7) | + ((y) >> 6) | + ((g) >> 4) | + 0x0034; // todo: mute sound when Lided close if (!f) @@ -1760,13 +1781,13 @@ void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,b } else LidKeyCount = 0; if (LidClosed) padExt |= 1 << 7; - + ((u16 *)MMU.ARM7_REG)[0x136>>1] = (u16)padExt; - + //put into the format we want for the movie system //RLDUTSBAYXWEGF - #undef FIX - #define FIX(b) (b?1:0) +#undef FIX +#define FIX(b) (b?1:0) r = FIX(R); l = FIX(L); @@ -1782,7 +1803,7 @@ void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,b e = FIX(E); g = FIX(G); f = FIX(F); - + nds.pad = (FIX(r)<<0)| @@ -1799,10 +1820,15 @@ void NDS_setPad(bool R,bool L,bool D,bool U,bool T,bool S,bool B,bool A,bool Y,b (FIX(e)<<11)| (FIX(g)<<12)| (FIX(f)<<13); - + // TODO: low power IRQ } + +void emu_halt() { + execute = false; +} + //these templates needed to be instantiated manually template u32 NDS_exec(s32 nb); template u32 NDS_exec(s32 nb); diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index ac076213a..9150e2337 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -102,6 +102,7 @@ typedef struct } NDS_header; extern void debug(); +void emu_halt(); typedef struct { @@ -232,7 +233,7 @@ inline u32 NDS_exec(s32 nb) { return NDS_exec(nb); } { MMU.reg_IF[0] |= 1;// & (MMU.reg_IME[0]);// (MMU.reg_IE[0] & 1); NDS_ARM9.wIRQ = TRUE; - //execute = FALSE; + //emu_halt(); /*logcount++;*/ } } @@ -242,7 +243,7 @@ inline u32 NDS_exec(s32 nb) { return NDS_exec(nb); } if(T1ReadWord(MMU.ARM7_REG, 4) & 0x8) MMU.reg_IF[1] |= 1;// & (MMU.reg_IME[1]);// (MMU.reg_IE[1] & 1); NDS_ARM7.wIRQ = TRUE; - //execute = FALSE; + //emu_halt(); } static INLINE void NDS_swapScreen(void) diff --git a/desmume/src/SPU.cpp b/desmume/src/SPU.cpp index 19ec2ec31..e25def70e 100644 --- a/desmume/src/SPU.cpp +++ b/desmume/src/SPU.cpp @@ -792,7 +792,7 @@ static void SPU_ChanUpdate8LR(SPU_struct* SPU, channel_struct *chan) ////////////////////////////////////////////////////////////////////////////// -static void SPU_ChanUpdateNoMix(SPU_struct *SPU, channel_struct *chan) +static void SPU_ChanUpdate8NoMix(SPU_struct *SPU, channel_struct *chan) { for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) { @@ -837,6 +837,16 @@ static void SPU_ChanUpdate8R(SPU_struct* SPU, channel_struct *chan) ////////////////////////////////////////////////////////////////////////////// +static void SPU_ChanUpdate16NoMix(SPU_struct *SPU, channel_struct *chan) +{ + for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) + { + // check to see if we're passed the length and need to loop, etc. + TestForLoop(SPU, chan); + } +} + + static void SPU_ChanUpdate16LR(SPU_struct* SPU, channel_struct *chan) { for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) @@ -891,6 +901,16 @@ static void SPU_ChanUpdate16R(SPU_struct* SPU, channel_struct *chan) ////////////////////////////////////////////////////////////////////////////// +static void SPU_ChanUpdateADPCMNoMix(SPU_struct *SPU, channel_struct *chan) +{ + for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) + { + // check to see if we're passed the length and need to loop, etc. + TestForLoop2(SPU, chan); + } +} + + static void SPU_ChanUpdateADPCMLR(SPU_struct* SPU, channel_struct *chan) { for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) @@ -945,6 +965,15 @@ static void SPU_ChanUpdateADPCMR(SPU_struct* SPU, channel_struct *chan) ////////////////////////////////////////////////////////////////////////////// +static void SPU_ChanUpdatePSGNoMix(SPU_struct* SPU, channel_struct *chan) +{ + for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) + { + chan->sampcnt += chan->sampinc; + } +} + + static void SPU_ChanUpdatePSGLR(SPU_struct* SPU, channel_struct *chan) { for (; SPU->bufpos < SPU->buflength; SPU->bufpos++) @@ -1001,25 +1030,25 @@ void (*SPU_ChanUpdate[4][4])(SPU_struct* SPU, channel_struct *chan) = { SPU_ChanUpdate8L, SPU_ChanUpdate8LR, SPU_ChanUpdate8R, - SPU_ChanUpdateNoMix + SPU_ChanUpdate8NoMix }, { // 16-bit PCM SPU_ChanUpdate16L, SPU_ChanUpdate16LR, SPU_ChanUpdate16R, - SPU_ChanUpdateNoMix, + SPU_ChanUpdate16NoMix, }, { // IMA-ADPCM SPU_ChanUpdateADPCML, SPU_ChanUpdateADPCMLR, SPU_ChanUpdateADPCMR, - SPU_ChanUpdateNoMix + SPU_ChanUpdateADPCMNoMix }, { // PSG/White Noise SPU_ChanUpdatePSGL, SPU_ChanUpdatePSGLR, SPU_ChanUpdatePSGR, - SPU_ChanUpdateNoMix + SPU_ChanUpdatePSGNoMix } }; diff --git a/desmume/src/arm_instructions.cpp b/desmume/src/arm_instructions.cpp index 06718caab..aedde58b5 100644 --- a/desmume/src/arm_instructions.cpp +++ b/desmume/src/arm_instructions.cpp @@ -31,6 +31,7 @@ #include "debug.h" #include "MMU.h" #include "armcpu.h" +#include "NDSSystem.h" #define cpu (&ARMPROC) #define TEMPLATE template @@ -248,7 +249,7 @@ extern volatile BOOL execute; TEMPLATE static u32 FASTCALL OP_UND() { LOG("Undefined instruction: %08X\n", cpu->instruction); - execute = FALSE; + emu_halt(); LOG("Stopped (OP_UND)\n"); return 1; } @@ -269,7 +270,7 @@ TEMPLATE static u32 FASTCALL OP_UND() } \ else \ { \ - execute = FALSE; \ + emu_halt(); \ return 4; \ } \ @@ -5033,7 +5034,7 @@ TEMPLATE static u32 FASTCALL OP_STR_P_IMM_OFF() u32 adr = cpu->R[REG_POS(i,16)] + IMM_OFF_12; WRITE32(cpu->mem_if->data, adr, cpu->R[REG_POS(i,12)]); -// execute = false; +// emu_halt(); return 2 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; } @@ -5791,7 +5792,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_IMM_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_M_IMM_OFF_POSTIND\n"); @@ -5817,7 +5818,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_REG_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_P_REG_OFF_POSTIND\n"); @@ -5843,7 +5844,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_LSL_IMM_OFF_POSTIND() if(cpu->CPSR.bits.mode==USR) return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_P_LSL_IMM_OFF_POSTIND\n"); @@ -5871,7 +5872,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_LSL_IMM_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_M_LSL_IMM_OFF_POSTIND\n"); @@ -5899,7 +5900,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_LSR_IMM_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_P_LSR_IMM_OFF_POSTIND\n"); @@ -5927,7 +5928,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_LSR_IMM_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_M_LSR_IMM_OFF_POSTIND\n"); @@ -5955,7 +5956,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_ASR_IMM_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_P_ASR_IMM_OFF_POSTIND\n"); @@ -5983,7 +5984,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_ASR_IMM_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_M_ASR_IMM_OFF_POSTIND\n"); @@ -6011,7 +6012,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_P_ROR_IMM_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_P_ROR_IMM_OFF_POSTIND\n"); @@ -6039,7 +6040,7 @@ TEMPLATE static u32 FASTCALL OP_LDRBT_M_ROR_IMM_OFF_POSTIND() return 2; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDRBT_M_ROR_IMM_OFF_POSTIND\n"); @@ -6774,7 +6775,7 @@ TEMPLATE static u32 FASTCALL OP_LDMIB2() u32 start = cpu->R[REG_POS(i,16)]; u32 * registres; TWaitState* waitState; - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDMIB2\n"); if(BIT15(i)==0) @@ -6833,7 +6834,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2() TWaitState* waitState; u32 start = cpu->R[REG_POS(i,16)]; - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_LDMDA2\n"); if(BIT15(i)==0) @@ -6958,7 +6959,7 @@ TEMPLATE static u32 FASTCALL OP_LDMIA2_W() TWaitState* waitState; u32 tmp; Status_Reg SPSR; -// execute = FALSE; +// emu_halt(); if(BIT15(i)==0) { if(cpu->CPSR.bits.mode==USR) @@ -7073,7 +7074,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2_W() u32 * registres; TWaitState * waitState; Status_Reg SPSR; -// execute = FALSE; +// emu_halt(); if(BIT15(i)==0) { if(cpu->CPSR.bits.mode==USR) @@ -7133,7 +7134,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2_W() u32 * registres; TWaitState* waitState; Status_Reg SPSR; -// execute = FALSE; +// emu_halt(); if(BIT15(i)==0) { if(cpu->CPSR.bits.mode==USR) @@ -7352,7 +7353,7 @@ TEMPLATE static u32 FASTCALL OP_STMIA2() start = cpu->R[REG_POS(i,16)]; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_STMIA2\n"); for(b=0; b<16; ++b) @@ -7383,7 +7384,7 @@ TEMPLATE static u32 FASTCALL OP_STMIB2() start = cpu->R[REG_POS(i,16)]; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_STMIB2\n"); for(b=0; b<16; ++b) @@ -7414,7 +7415,7 @@ TEMPLATE static u32 FASTCALL OP_STMDA2() start = cpu->R[REG_POS(i,16)]; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_STMDA2\n"); for(b=0; b<16; ++b) @@ -7473,7 +7474,7 @@ TEMPLATE static u32 FASTCALL OP_STMIA2_W() start = cpu->R[REG_POS(i,16)]; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_STMIA2_W\n"); for(b=0; b<16; ++b) @@ -7533,7 +7534,7 @@ TEMPLATE static u32 FASTCALL OP_STMDA2_W() c = 0; start = cpu->R[REG_POS(i,16)]; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_STMDA2_W\n"); for(b=0; b<16; ++b) @@ -7567,7 +7568,7 @@ TEMPLATE static u32 FASTCALL OP_STMDB2_W() start = cpu->R[REG_POS(i,16)]; oldmode = armcpu_switchMode(cpu, SYS); - //execute = FALSE; + //emu_halt(); LOG("Untested opcode: OP_STMDB2_W\n"); for(b=0; b<16; ++b) @@ -7757,7 +7758,7 @@ TEMPLATE static u32 FASTCALL OP_MCR() if(!cpu->coproc[cpnum]) { - execute = FALSE; + emu_halt(); LOG("Stopped (OP_MCR)\n"); return 2; } @@ -7776,7 +7777,7 @@ TEMPLATE static u32 FASTCALL OP_MRC() if(!cpu->coproc[cpnum]) { - execute = FALSE; + emu_halt(); LOG("Stopped (OP_MRC)\n"); return 2; } @@ -7789,26 +7790,23 @@ TEMPLATE static u32 FASTCALL OP_MRC() //--------------SWI------------------------------- TEMPLATE static u32 FASTCALL OP_SWI() { - if (((cpu->intVector != 0) ^ (PROCNUM == ARMCPU_ARM9))) - { + if(cpu->swi_tab) { + u32 swinum = (cpu->instruction>>16)&0x1F; + return cpu->swi_tab[swinum](cpu) + 3; + } else { /* TODO (#1#): translocated SWI vectors */ /* we use an irq thats not in the irq tab, as it was replaced duie to a changed intVector */ Status_Reg tmp = cpu->CPSR; armcpu_switchMode(cpu, SVC); /* enter svc mode */ - cpu->R[14] = cpu->R[15] - 4; /* jump to swi Vector */ + cpu->R[14] = cpu->next_instruction; cpu->SPSR = tmp; /* save old CPSR as new SPSR */ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ - cpu->CPSR.bits.I = cpu->SPSR.bits.I; /* keep int disable flag */ - cpu->R[15] = cpu->intVector + 0x08; + cpu->CPSR.bits.I = 1; + cpu->R[15] = cpu->intVector + 0x08; cpu->next_instruction = cpu->R[15]; return 4; } - else - { - u32 swinum = (cpu->instruction>>16)&0x1F; - return cpu->swi_tab[swinum](cpu) + 3; - } } //----------------BKPT------------------------- diff --git a/desmume/src/armcpu.cpp b/desmume/src/armcpu.cpp index f6426175d..94e7546f4 100644 --- a/desmume/src/armcpu.cpp +++ b/desmume/src/armcpu.cpp @@ -181,11 +181,6 @@ int armcpu_new( armcpu_t *armcpu, u32 id) { armcpu->proc_ID = id; - if(id==0) - armcpu->swi_tab = ARM9_swi_tab; - else - armcpu->swi_tab = ARM7_swi_tab; - #ifdef GDB_STUB armcpu->mem_if = mem_if; diff --git a/desmume/src/bios.cpp b/desmume/src/bios.cpp index 1efbc49c9..6c0c6b678 100644 --- a/desmume/src/bios.cpp +++ b/desmume/src/bios.cpp @@ -212,7 +212,7 @@ static u32 intrWaitARM(armcpu_t * cpu) u32 intr; u32 intrFlag = 0; - //execute = FALSE; + //emu_halt(); if(cpu->proc_ID) { intrFlagAdr = 0x380FFF8; @@ -246,7 +246,7 @@ static u32 waitVBlankARM(armcpu_t * cpu) u32 intr; u32 intrFlag = 0; - //execute = FALSE; + //emu_halt(); if(cpu->proc_ID) { intrFlagAdr = 0x380FFF8; diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index f9299df07..23321f93a 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -624,23 +624,26 @@ static void SetVertex() break; } - if(completed) { + if(completed) + { POLY &poly = polylist->list[polylist->count]; //todo - dont overrun proj list //see if the last entry in the proj list matches the current matrix, if there is one. if(projlist->count != 0 && - //but as a speed hack, we consider the matrices different if the first element differs. - //i think this should be good enough. - !MatrixCompare(mtxCurrent[0],projlist->projMatrix[projlist->count-1]) - - // if compare only one value this is broke some games - // zeromus check it please + //here is an example of something that does not work. + //(for a speed hack, we consider the matrices different if the first element differs) //mtxCurrent[0][0] == projlist->projMatrix[projlist->count-1][0] - ) { + + //here is what we must do: make sure the matrices are identical + !MatrixCompare(mtxCurrent[0],projlist->projMatrix[projlist->count-1]) + ) + { //it matches. use it poly.projIndex = projlist->count-1; - } else { + } + else + { MatrixCopy(projlist->projMatrix[projlist->count],mtxCurrent[0]); poly.projIndex = projlist->count; projlist->count++; @@ -1150,7 +1153,7 @@ void gfx3d_FlushFIFO() } for (int i=0; i< gxFIFO.tail; i++) { - cmd = gxFIFO.cmd[i]; + cmd = gxFIFO.cmd[i]; param = gxFIFO.param[i]; gfx3d_execute(cmd, param); } diff --git a/desmume/src/matrix.cpp b/desmume/src/matrix.cpp index 416d6542f..de4c31c37 100644 --- a/desmume/src/matrix.cpp +++ b/desmume/src/matrix.cpp @@ -127,7 +127,14 @@ void MatrixTranspose(float *matrix) void MATRIXFASTCALL MatrixIdentity (float *matrix) //============== TODO { - memset (matrix, 0, sizeof(float)*16); + //memset (matrix, 0, sizeof(float)*16); + //this is fastest for SSE2 i think. + //study code generation and split into sse2 specific module later + for(int i=0;i<16;i++) + matrix[i] = 0.0f; + //matrix[1] = matrix[2] = matrix[3] = matrix[4] = 0.0f; + //matrix[6] = matrix[7] = matrix[8] = matrix[9] = 0.0f; + //matrix[11] = matrix[12] = matrix[13] = matrix[14] = 0.0f; matrix[0] = matrix[5] = matrix[10] = matrix[15] = 1.f; } diff --git a/desmume/src/thumb_instructions.cpp b/desmume/src/thumb_instructions.cpp index 45f60b2d4..383bf5f1e 100644 --- a/desmume/src/thumb_instructions.cpp +++ b/desmume/src/thumb_instructions.cpp @@ -1,861 +1,862 @@ -/* - Copyright (C) 2006 yopyop - yopyop156@ifrance.com - yopyop156.ifrance.com - - Code added on 18/08/2006 by shash - - Missing missaligned addresses correction - (reference in http://nocash.emubase.de/gbatek.htm#cpumemoryalignments) - - This file is part of DeSmuME - - DeSmuME is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DeSmuME is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DeSmuME; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -//zero 9/8/08 - fixed a bug -//SIGNED_UNDERFLOW(a, (!cpu->CPSR.bits.C), tmp) -//was being called. but SIGNED_UNDERFLOW expects values in bit31. replaced with -//SIGNED_UNDERFLOW(a, (cpu->CPSR.bits.C?0:0x80000000), tmp) - -#include "bios.h" -#include "debug.h" -#include "MMU.h" - -#define cpu (&ARMPROC) -#define TEMPLATE template - -#define REG_NUM(i, n) (((i)>>n)&0x7) - -extern volatile BOOL execute; - -// Use this macros for reading/writing, so the GDB stub isn't broken -#ifdef GDB_STUB - #define READ32(a,b) cpu->mem_if->read32(a,b & 0xFFFFFFFC) - #define WRITE32(a,b,c) cpu->mem_if->write32(a,b & 0xFFFFFFFC,c) - #define READ16(a,b) cpu->mem_if->read16(a,b & 0xFFFFFFFE) - #define WRITE16(a,b,c) cpu->mem_if->write16(a,b & 0xFFFFFFFE,c) - #define READ8(a,b) cpu->mem_if->read8(a,b) - #define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c) -#else - #define READ32(a,b) MMU_read32(PROCNUM, b & 0xFFFFFFFC) - #define WRITE32(a,b,c) MMU_write32(PROCNUM,b & 0xFFFFFFFC,c) - #define READ16(a,b) MMU_read16(PROCNUM, b & 0xFFFFFFFE) - #define WRITE16(a,b,c) MMU_write16(PROCNUM,b & 0xFFFFFFFE,c) - #define READ8(a,b) MMU_read8(PROCNUM, b) - #define WRITE8(a,b,c) MMU_write8(PROCNUM,b,c) -#endif - -TEMPLATE static u32 FASTCALL OP_UND_THUMB() -{ - execute = FALSE; - return 1; -} - -TEMPLATE static u32 FASTCALL OP_LSL_0() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)]; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_LSL() -{ - const u32 &i = cpu->instruction; - u32 v = (i>>6) & 0x1F; - cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v); - cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_LSR_0() -{ - const u32 &i = cpu->instruction; - // cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); - cpu->R[REG_NUM(i, 0)] = 0; - cpu->CPSR.bits.N = 0; - cpu->CPSR.bits.Z = 1; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_LSR() -{ - const u32 &i = cpu->instruction; - u32 v = (i>>6) & 0x1F; - cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); - cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_ASR_0() -{ - const u32 &i = cpu->instruction; - cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); - cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_ASR() -{ - const u32 &i = cpu->instruction; - u32 v = (i>>6) & 0x1F; - cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1); - cpu->R[REG_NUM(i, 0)] = (((s32)cpu->R[REG_NUM(i, 3)]) >> v); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_ADD_REG() -{ - const u32 &i = cpu->instruction; - u32 a = cpu->R[REG_NUM(i, 3)]; - u32 b = cpu->R[REG_NUM(i, 6)]; - cpu->R[REG_NUM(i, 0)] = a + b; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_SUB_REG() -{ - const u32 &i = cpu->instruction; - u32 a = cpu->R[REG_NUM(i, 3)]; - u32 b = cpu->R[REG_NUM(i, 6)]; - cpu->R[REG_NUM(i, 0)] = a - b; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_ADD_IMM3() -{ - const u32 &i = cpu->instruction; - u32 a = cpu->R[REG_NUM(i, 3)]; - cpu->R[REG_NUM(i, 0)] = a + REG_NUM(i, 6); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_SUB_IMM3() -{ - const u32 &i = cpu->instruction; - u32 a = cpu->R[REG_NUM(i, 3)]; - cpu->R[REG_NUM(i, 0)] = a - REG_NUM(i, 6); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_MOV_IMM8() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 8)] = i & 0xFF; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_CMP_IMM8() -{ - const u32 &i = cpu->instruction; - u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF); - cpu->CPSR.bits.N = BIT31(tmp); - cpu->CPSR.bits.Z = tmp == 0; - cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); - cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_ADD_IMM8() -{ - const u32 &i = cpu->instruction; - u32 tmp = cpu->R[REG_NUM(i, 8)] + (i & 0xFF); - cpu->CPSR.bits.N = BIT31(tmp); - cpu->CPSR.bits.Z = tmp == 0; - cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); - cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); - cpu->R[REG_NUM(i, 8)] = tmp; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_SUB_IMM8() -{ - const u32 &i = cpu->instruction; - u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF); - cpu->CPSR.bits.N = BIT31(tmp); - cpu->CPSR.bits.Z = tmp == 0; - cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); - cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); - cpu->R[REG_NUM(i, 8)] = tmp; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_AND() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)]; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_EOR() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)]; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_LSL_REG() -{ - const u32 &i = cpu->instruction; - u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; - - if(!v) - { - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - return 3; - } - if(v<32) - { - cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v); - cpu->R[REG_NUM(i, 0)] <<= v; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - return 3; - } - if(v==32) - cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]); - else - cpu->CPSR.bits.C = 0; - cpu->R[REG_NUM(i, 0)] = 0; - cpu->CPSR.bits.N = 0; - cpu->CPSR.bits.Z = 1; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_LSR_REG() -{ - const u32 &i = cpu->instruction; - u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; - - if(!v) - { - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - return 3; - } - if(v<32) - { - cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); - cpu->R[REG_NUM(i, 0)] >>= v; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - return 3; - } - if(v==32) - cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); - else - cpu->CPSR.bits.C = 0; - cpu->R[REG_NUM(i, 0)] = 0; - cpu->CPSR.bits.N = 0; - cpu->CPSR.bits.Z = 1; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_ASR_REG() -{ - const u32 &i = cpu->instruction; - u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; - - if(!v) - { - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - return 3; - } - if(v<32) - { - cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); - cpu->R[REG_NUM(i, 0)] = (u32)(((s32)cpu->R[REG_NUM(i, 0)]) >> v); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - return 3; - } - - cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_ADC_REG() -{ - const u32 &i = cpu->instruction; - u32 a = cpu->R[REG_NUM(i, 0)]; - u32 b = cpu->R[REG_NUM(i, 3)]; - u32 tmp = b + cpu->CPSR.bits.C; - u32 res = a + tmp; - - cpu->R[REG_NUM(i, 0)] = res; - - cpu->CPSR.bits.N = BIT31(res); - cpu->CPSR.bits.Z = res == 0; - - cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(b, (u32) cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(tmp, a, res); - cpu->CPSR.bits.V = SIGNED_OVERFLOW(b, (u32) cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, a, res); - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_SBC_REG() -{ - const u32 &i = cpu->instruction; - u32 a = cpu->R[REG_NUM(i, 0)]; - u32 b = cpu->R[REG_NUM(i, 3)]; - u32 tmp = a - (!cpu->CPSR.bits.C); - u32 res = tmp - b; - cpu->R[REG_NUM(i, 0)] = res; - - cpu->CPSR.bits.N = BIT31(res); - cpu->CPSR.bits.Z = res == 0; - - cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(a, (u32)(cpu->CPSR.bits.C?0:0x80000000), tmp)) & (!UNSIGNED_OVERFLOW(tmp, b, res)); - cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, (u32)(cpu->CPSR.bits.C?0:0x80000000), tmp) | SIGNED_OVERFLOW(tmp, b, res); - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_ROR_REG() -{ - const u32 &i = cpu->instruction; - u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; - - if(v == 0) - { - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - return 3; - } - v &= 0xF; - if(v == 0) - { - cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - return 3; - } - cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); - cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_TST() -{ - const u32 &i = cpu->instruction; - u32 tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)]; - cpu->CPSR.bits.N = BIT31(tmp); - cpu->CPSR.bits.Z = tmp == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_NEG() -{ - const u32 &i = cpu->instruction; - u32 a = cpu->R[REG_NUM(i, 3)]; - cpu->R[REG_NUM(i, 0)] = -((signed int)a); - - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW((u32)0, a, cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.V = SIGNED_UNDERFLOW((u32)0, a, cpu->R[REG_NUM(i, 0)]); - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_CMP() -{ - const u32 &i = cpu->instruction; - u32 tmp = cpu->R[REG_NUM(i, 0)] -cpu->R[REG_NUM(i, 3)]; - - cpu->CPSR.bits.N = BIT31(tmp); - cpu->CPSR.bits.Z = tmp == 0; - cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); - cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_CMN() -{ - const u32 &i = cpu->instruction; - u32 tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)]; - - //execute = FALSE; - //log::ajouter("OP_CMN THUMB"); - cpu->CPSR.bits.N = BIT31(tmp); - cpu->CPSR.bits.Z = tmp == 0; - cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); - cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_ORR() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)]; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_MUL_REG() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 0)] *= cpu->R[REG_NUM(i, 3)]; - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_BIC() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_MVN() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]); - cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); - cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_ADD_SPE() -{ - const u32 &i = cpu->instruction; - u32 Rd = (i&7) | ((i>>4)&8); - cpu->R[Rd] += cpu->R[REG_POS(i, 3)]; - - if(Rd==15) - cpu->next_instruction = cpu->R[15]; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_CMP_SPE() -{ - const u32 &i = cpu->instruction; - u32 Rn = (i&7) | ((i>>4)&8); - u32 tmp = cpu->R[Rn] -cpu->R[REG_POS(i, 3)]; - - cpu->CPSR.bits.N = BIT31(tmp); - cpu->CPSR.bits.Z = tmp == 0; - cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp); - cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp); - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_MOV_SPE() -{ - const u32 &i = cpu->instruction; - u32 Rd = (i&7) | ((i>>4)&8); - cpu->R[Rd] = cpu->R[REG_POS(i, 3)]; - - if(Rd==15) - cpu->next_instruction = cpu->R[15]; - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_BX_THUMB() -{ - u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)]; - - cpu->CPSR.bits.T = BIT0(Rm); - cpu->R[15] = (Rm & 0xFFFFFFFE); - cpu->next_instruction = cpu->R[15]; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_BLX_THUMB() -{ - u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)]; - - cpu->CPSR.bits.T = BIT0(Rm); - cpu->R[14] = cpu->next_instruction | 1; - cpu->R[15] = (Rm & 0xFFFFFFFE); - cpu->next_instruction = cpu->R[15]; - - return 3; -} - -TEMPLATE static u32 FASTCALL OP_LDR_PCREL() -{ - u32 adr = (cpu->R[15]&0xFFFFFFFC) + ((cpu->instruction&0xFF)<<2); - - cpu->R[REG_NUM(cpu->instruction, 8)] = READ32(cpu->mem_if->data, adr); - - return 3 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_STR_REG_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)]; - WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]); - - return 2 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_STRH_REG_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; - WRITE16(cpu->mem_if->data, adr, ((u16)cpu->R[REG_NUM(i, 0)])); - - return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_STRB_REG_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; - WRITE8(cpu->mem_if->data, adr, ((u8)cpu->R[REG_NUM(i, 0)])); - - return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDRSB_REG_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; - cpu->R[REG_NUM(i, 0)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); - - return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDR_REG_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]); - u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC); - - adr = (adr&3)*8; - tempValue = (tempValue>>adr) | (tempValue<<(32-adr)); - cpu->R[REG_NUM(i, 0)] = tempValue; - - return 3 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDRH_REG_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; - cpu->R[REG_NUM(i, 0)] = (u32)READ16(cpu->mem_if->data, adr); - - return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDRB_REG_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; - cpu->R[REG_NUM(i, 0)] = (u32)READ8(cpu->mem_if->data, adr); - - return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDRSH_REG_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; - cpu->R[REG_NUM(i, 0)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); - - return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_STR_IMM_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); - WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]); - - return 2 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDR_IMM_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); - u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC); - adr = (adr&3)*8; - tempValue = (tempValue>>adr) | (tempValue<<(32-adr)); - cpu->R[REG_NUM(i, 0)] = tempValue; - - return 3 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_STRB_IMM_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); - WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_NUM(i, 0)]); - - return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDRB_IMM_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); - cpu->R[REG_NUM(i, 0)] = READ8(cpu->mem_if->data, adr); - - return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_STRH_IMM_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); - WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_NUM(i, 0)]); - - return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDRH_IMM_OFF() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); - cpu->R[REG_NUM(i, 0)] = READ16(cpu->mem_if->data, adr); - - return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_STR_SPREL() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[13] + ((i&0xFF)<<2); - WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]); - - return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_LDR_SPREL() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[13] + ((i&0xFF)<<2); - cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr); - - return 3 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; -} - -TEMPLATE static u32 FASTCALL OP_ADD_2PC() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2); - - return 5; -} - -TEMPLATE static u32 FASTCALL OP_ADD_2SP() -{ - const u32 &i = cpu->instruction; - cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2); - - return 2; -} - -TEMPLATE static u32 FASTCALL OP_ADJUST_P_SP() -{ - cpu->R[13] += ((cpu->instruction&0x7F)<<2); - - return 1; -} - -TEMPLATE static u32 FASTCALL OP_ADJUST_M_SP() -{ - cpu->R[13] -= ((cpu->instruction&0x7F)<<2); - - return 1; -} - -TEMPLATE static u32 FASTCALL OP_PUSH() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[13] - 4; - u32 c = 0, j; - - for(j = 0; j<8; ++j) - if(BIT_N(i, 7-j)) - { - WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]); - c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; - adr -= 4; - } - cpu->R[13] = adr + 4; - - return c + 3; -} - -TEMPLATE static u32 FASTCALL OP_PUSH_LR() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[13] - 4; - u32 c = 0, j; - - WRITE32(cpu->mem_if->data, adr, cpu->R[14]); - c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; - adr -= 4; - - for(j = 0; j<8; ++j) - if(BIT_N(i, 7-j)) - { - WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]); - c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; - adr -= 4; - } - cpu->R[13] = adr + 4; - - return c + 4; -} - -TEMPLATE static u32 FASTCALL OP_POP() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[13]; - u32 c = 0, j; - - for(j = 0; j<8; ++j) - if(BIT_N(i, j)) - { - cpu->R[j] = READ32(cpu->mem_if->data, adr); - c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; - adr += 4; - } - cpu->R[13] = adr; - - return c + 2; -} - -TEMPLATE static u32 FASTCALL OP_POP_PC() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[13]; - u32 c = 0, j; - u32 v; - - for(j = 0; j<8; ++j) - if(BIT_N(i, j)) - { - cpu->R[j] = READ32(cpu->mem_if->data, adr); - c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; - adr += 4; - } - - v = READ32(cpu->mem_if->data, adr); - c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; - cpu->R[15] = v & 0xFFFFFFFE; - cpu->next_instruction = v & 0xFFFFFFFE; - if(PROCNUM==0) - cpu->CPSR.bits.T = BIT0(v); - adr += 4; - - cpu->R[13] = adr; - return c + 5; -} - -TEMPLATE static u32 FASTCALL OP_BKPT_THUMB() -{ - return 1; -} - -TEMPLATE static u32 FASTCALL OP_STMIA_THUMB() -{ - const u32 &i = cpu->instruction; - u32 adr = cpu->R[REG_NUM(i, 8)]; - u32 c = 0, j; - - for(j = 0; j<8; ++j) - if(BIT_N(i, j)) - { - WRITE32(cpu->mem_if->data, adr, cpu->R[j]); - c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; - adr += 4; - } - cpu->R[REG_NUM(i, 8)] = adr; - return c + 2; -} - +/* + Copyright (C) 2006 yopyop + yopyop156@ifrance.com + yopyop156.ifrance.com + + Code added on 18/08/2006 by shash + - Missing missaligned addresses correction + (reference in http://nocash.emubase.de/gbatek.htm#cpumemoryalignments) + + This file is part of DeSmuME + + DeSmuME is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DeSmuME is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//zero 9/8/08 - fixed a bug +//SIGNED_UNDERFLOW(a, (!cpu->CPSR.bits.C), tmp) +//was being called. but SIGNED_UNDERFLOW expects values in bit31. replaced with +//SIGNED_UNDERFLOW(a, (cpu->CPSR.bits.C?0:0x80000000), tmp) + +#include "bios.h" +#include "debug.h" +#include "MMU.h" +#include "NDSSystem.h" + +#define cpu (&ARMPROC) +#define TEMPLATE template + +#define REG_NUM(i, n) (((i)>>n)&0x7) + +extern volatile BOOL execute; + +// Use this macros for reading/writing, so the GDB stub isn't broken +#ifdef GDB_STUB + #define READ32(a,b) cpu->mem_if->read32(a,b & 0xFFFFFFFC) + #define WRITE32(a,b,c) cpu->mem_if->write32(a,b & 0xFFFFFFFC,c) + #define READ16(a,b) cpu->mem_if->read16(a,b & 0xFFFFFFFE) + #define WRITE16(a,b,c) cpu->mem_if->write16(a,b & 0xFFFFFFFE,c) + #define READ8(a,b) cpu->mem_if->read8(a,b) + #define WRITE8(a,b,c) cpu->mem_if->write8(a,b,c) +#else + #define READ32(a,b) MMU_read32(PROCNUM, b & 0xFFFFFFFC) + #define WRITE32(a,b,c) MMU_write32(PROCNUM,b & 0xFFFFFFFC,c) + #define READ16(a,b) MMU_read16(PROCNUM, b & 0xFFFFFFFE) + #define WRITE16(a,b,c) MMU_write16(PROCNUM,b & 0xFFFFFFFE,c) + #define READ8(a,b) MMU_read8(PROCNUM, b) + #define WRITE8(a,b,c) MMU_write8(PROCNUM,b,c) +#endif + +TEMPLATE static u32 FASTCALL OP_UND_THUMB() +{ + emu_halt(); + return 1; +} + +TEMPLATE static u32 FASTCALL OP_LSL_0() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] = cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_LSL() +{ + const u32 &i = cpu->instruction; + u32 v = (i>>6) & 0x1F; + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], 32-v); + cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] << v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_LSR_0() +{ + const u32 &i = cpu->instruction; + // cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); + cpu->R[REG_NUM(i, 0)] = 0; + cpu->CPSR.bits.N = 0; + cpu->CPSR.bits.Z = 1; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_LSR() +{ + const u32 &i = cpu->instruction; + u32 v = (i>>6) & 0x1F; + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); + cpu->R[REG_NUM(i, 0)] = (cpu->R[REG_NUM(i, 3)] >> v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_ASR_0() +{ + const u32 &i = cpu->instruction; + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 3)]); + cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 3)])*0xFFFFFFFF; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_ASR() +{ + const u32 &i = cpu->instruction; + u32 v = (i>>6) & 0x1F; + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 3)], v-1); + cpu->R[REG_NUM(i, 0)] = (((s32)cpu->R[REG_NUM(i, 3)]) >> v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_ADD_REG() +{ + const u32 &i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + u32 b = cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = a + b; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_SUB_REG() +{ + const u32 &i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + u32 b = cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = a - b; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, b, cpu->R[REG_NUM(i, 0)]); + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_ADD_IMM3() +{ + const u32 &i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + cpu->R[REG_NUM(i, 0)] = a + REG_NUM(i, 6); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_SUB_IMM3() +{ + const u32 &i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + cpu->R[REG_NUM(i, 0)] = a - REG_NUM(i, 6); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, REG_NUM(i, 6), cpu->R[REG_NUM(i, 0)]); + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_MOV_IMM8() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 8)] = i & 0xFF; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 8)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 8)] == 0; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_CMP_IMM8() +{ + const u32 &i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF); + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_ADD_IMM8() +{ + const u32 &i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 8)] + (i & 0xFF); + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->R[REG_NUM(i, 8)] = tmp; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_SUB_IMM8() +{ + const u32 &i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 8)] - (i & 0xFF); + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 8)], (i & 0xFF), tmp); + cpu->R[REG_NUM(i, 8)] = tmp; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_AND() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] &= cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_EOR() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] ^= cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_LSL_REG() +{ + const u32 &i = cpu->instruction; + u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; + + if(!v) + { + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v<32) + { + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], 32-v); + cpu->R[REG_NUM(i, 0)] <<= v; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v==32) + cpu->CPSR.bits.C = BIT0(cpu->R[REG_NUM(i, 0)]); + else + cpu->CPSR.bits.C = 0; + cpu->R[REG_NUM(i, 0)] = 0; + cpu->CPSR.bits.N = 0; + cpu->CPSR.bits.Z = 1; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_LSR_REG() +{ + const u32 &i = cpu->instruction; + u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; + + if(!v) + { + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v<32) + { + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); + cpu->R[REG_NUM(i, 0)] >>= v; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v==32) + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); + else + cpu->CPSR.bits.C = 0; + cpu->R[REG_NUM(i, 0)] = 0; + cpu->CPSR.bits.N = 0; + cpu->CPSR.bits.Z = 1; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_ASR_REG() +{ + const u32 &i = cpu->instruction; + u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; + + if(!v) + { + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + if(v<32) + { + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); + cpu->R[REG_NUM(i, 0)] = (u32)(((s32)cpu->R[REG_NUM(i, 0)]) >> v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->R[REG_NUM(i, 0)] = BIT31(cpu->R[REG_NUM(i, 0)])*0xFFFFFFFF; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_ADC_REG() +{ + const u32 &i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 0)]; + u32 b = cpu->R[REG_NUM(i, 3)]; + u32 tmp = b + cpu->CPSR.bits.C; + u32 res = a + tmp; + + cpu->R[REG_NUM(i, 0)] = res; + + cpu->CPSR.bits.N = BIT31(res); + cpu->CPSR.bits.Z = res == 0; + + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(b, (u32) cpu->CPSR.bits.C, tmp) | UNSIGNED_OVERFLOW(tmp, a, res); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(b, (u32) cpu->CPSR.bits.C, tmp) | SIGNED_OVERFLOW(tmp, a, res); + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_SBC_REG() +{ + const u32 &i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 0)]; + u32 b = cpu->R[REG_NUM(i, 3)]; + u32 tmp = a - (!cpu->CPSR.bits.C); + u32 res = tmp - b; + cpu->R[REG_NUM(i, 0)] = res; + + cpu->CPSR.bits.N = BIT31(res); + cpu->CPSR.bits.Z = res == 0; + + cpu->CPSR.bits.C = (!UNSIGNED_UNDERFLOW(a, (u32)(cpu->CPSR.bits.C?0:0x80000000), tmp)) & (!UNSIGNED_OVERFLOW(tmp, b, res)); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(a, (u32)(cpu->CPSR.bits.C?0:0x80000000), tmp) | SIGNED_OVERFLOW(tmp, b, res); + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_ROR_REG() +{ + const u32 &i = cpu->instruction; + u32 v = cpu->R[REG_NUM(i, 3)]&0xFF; + + if(v == 0) + { + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + v &= 0xF; + if(v == 0) + { + cpu->CPSR.bits.C = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + return 3; + } + cpu->CPSR.bits.C = BIT_N(cpu->R[REG_NUM(i, 0)], v-1); + cpu->R[REG_NUM(i, 0)] = ROR(cpu->R[REG_NUM(i, 0)], v); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_TST() +{ + const u32 &i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 0)] & cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_NEG() +{ + const u32 &i = cpu->instruction; + u32 a = cpu->R[REG_NUM(i, 3)]; + cpu->R[REG_NUM(i, 0)] = -((signed int)a); + + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW((u32)0, a, cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW((u32)0, a, cpu->R[REG_NUM(i, 0)]); + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_CMP() +{ + const u32 &i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 0)] -cpu->R[REG_NUM(i, 3)]; + + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_CMN() +{ + const u32 &i = cpu->instruction; + u32 tmp = cpu->R[REG_NUM(i, 0)] + cpu->R[REG_NUM(i, 3)]; + + //emu_halt(); + //log::ajouter("OP_CMN THUMB"); + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = UNSIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); + cpu->CPSR.bits.V = SIGNED_OVERFLOW(cpu->R[REG_NUM(i, 0)], cpu->R[REG_NUM(i, 3)], tmp); + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_ORR() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] |= cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_MUL_REG() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] *= cpu->R[REG_NUM(i, 3)]; + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_BIC() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] &= (~cpu->R[REG_NUM(i, 3)]); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_MVN() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 0)] = (~cpu->R[REG_NUM(i, 3)]); + cpu->CPSR.bits.N = BIT31(cpu->R[REG_NUM(i, 0)]); + cpu->CPSR.bits.Z = cpu->R[REG_NUM(i, 0)] == 0; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_ADD_SPE() +{ + const u32 &i = cpu->instruction; + u32 Rd = (i&7) | ((i>>4)&8); + cpu->R[Rd] += cpu->R[REG_POS(i, 3)]; + + if(Rd==15) + cpu->next_instruction = cpu->R[15]; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_CMP_SPE() +{ + const u32 &i = cpu->instruction; + u32 Rn = (i&7) | ((i>>4)&8); + u32 tmp = cpu->R[Rn] -cpu->R[REG_POS(i, 3)]; + + cpu->CPSR.bits.N = BIT31(tmp); + cpu->CPSR.bits.Z = tmp == 0; + cpu->CPSR.bits.C = !UNSIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp); + cpu->CPSR.bits.V = SIGNED_UNDERFLOW(cpu->R[Rn], cpu->R[REG_POS(i, 3)], tmp); + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_MOV_SPE() +{ + const u32 &i = cpu->instruction; + u32 Rd = (i&7) | ((i>>4)&8); + cpu->R[Rd] = cpu->R[REG_POS(i, 3)]; + + if(Rd==15) + cpu->next_instruction = cpu->R[15]; + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_BX_THUMB() +{ + u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)]; + + cpu->CPSR.bits.T = BIT0(Rm); + cpu->R[15] = (Rm & 0xFFFFFFFE); + cpu->next_instruction = cpu->R[15]; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_BLX_THUMB() +{ + u32 Rm = cpu->R[REG_POS(cpu->instruction, 3)]; + + cpu->CPSR.bits.T = BIT0(Rm); + cpu->R[14] = cpu->next_instruction | 1; + cpu->R[15] = (Rm & 0xFFFFFFFE); + cpu->next_instruction = cpu->R[15]; + + return 3; +} + +TEMPLATE static u32 FASTCALL OP_LDR_PCREL() +{ + u32 adr = (cpu->R[15]&0xFFFFFFFC) + ((cpu->instruction&0xFF)<<2); + + cpu->R[REG_NUM(cpu->instruction, 8)] = READ32(cpu->mem_if->data, adr); + + return 3 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_STR_REG_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 6)] + cpu->R[REG_NUM(i, 3)]; + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]); + + return 2 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_STRH_REG_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + WRITE16(cpu->mem_if->data, adr, ((u16)cpu->R[REG_NUM(i, 0)])); + + return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_STRB_REG_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + WRITE8(cpu->mem_if->data, adr, ((u8)cpu->R[REG_NUM(i, 0)])); + + return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDRSB_REG_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = (s32)((s8)READ8(cpu->mem_if->data, adr)); + + return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDR_REG_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = (cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]); + u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC); + + adr = (adr&3)*8; + tempValue = (tempValue>>adr) | (tempValue<<(32-adr)); + cpu->R[REG_NUM(i, 0)] = tempValue; + + return 3 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDRH_REG_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = (u32)READ16(cpu->mem_if->data, adr); + + return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDRB_REG_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = (u32)READ8(cpu->mem_if->data, adr); + + return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDRSH_REG_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + cpu->R[REG_NUM(i, 6)]; + cpu->R[REG_NUM(i, 0)] = (s32)((s16)READ16(cpu->mem_if->data, adr)); + + return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_STR_IMM_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 0)]); + + return 2 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDR_IMM_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>4)&0x7C); + u32 tempValue = READ32(cpu->mem_if->data, adr&0xFFFFFFFC); + adr = (adr&3)*8; + tempValue = (tempValue>>adr) | (tempValue<<(32-adr)); + cpu->R[REG_NUM(i, 0)] = tempValue; + + return 3 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_STRB_IMM_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); + WRITE8(cpu->mem_if->data, adr, (u8)cpu->R[REG_NUM(i, 0)]); + + return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDRB_IMM_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>6)&0x1F); + cpu->R[REG_NUM(i, 0)] = READ8(cpu->mem_if->data, adr); + + return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_STRH_IMM_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); + WRITE16(cpu->mem_if->data, adr, (u16)cpu->R[REG_NUM(i, 0)]); + + return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDRH_IMM_OFF() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 3)] + ((i>>5)&0x3E); + cpu->R[REG_NUM(i, 0)] = READ16(cpu->mem_if->data, adr); + + return 3 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_STR_SPREL() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[13] + ((i&0xFF)<<2); + WRITE32(cpu->mem_if->data, adr, cpu->R[REG_NUM(i, 8)]); + + return 2 + MMU.MMU_WAIT16[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_LDR_SPREL() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[13] + ((i&0xFF)<<2); + cpu->R[REG_NUM(i, 8)] = READ32(cpu->mem_if->data, adr); + + return 3 + MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; +} + +TEMPLATE static u32 FASTCALL OP_ADD_2PC() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 8)] = (cpu->R[15]&0xFFFFFFFC) + ((i&0xFF)<<2); + + return 5; +} + +TEMPLATE static u32 FASTCALL OP_ADD_2SP() +{ + const u32 &i = cpu->instruction; + cpu->R[REG_NUM(i, 8)] = cpu->R[13] + ((i&0xFF)<<2); + + return 2; +} + +TEMPLATE static u32 FASTCALL OP_ADJUST_P_SP() +{ + cpu->R[13] += ((cpu->instruction&0x7F)<<2); + + return 1; +} + +TEMPLATE static u32 FASTCALL OP_ADJUST_M_SP() +{ + cpu->R[13] -= ((cpu->instruction&0x7F)<<2); + + return 1; +} + +TEMPLATE static u32 FASTCALL OP_PUSH() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[13] - 4; + u32 c = 0, j; + + for(j = 0; j<8; ++j) + if(BIT_N(i, 7-j)) + { + WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]); + c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; + adr -= 4; + } + cpu->R[13] = adr + 4; + + return c + 3; +} + +TEMPLATE static u32 FASTCALL OP_PUSH_LR() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[13] - 4; + u32 c = 0, j; + + WRITE32(cpu->mem_if->data, adr, cpu->R[14]); + c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; + adr -= 4; + + for(j = 0; j<8; ++j) + if(BIT_N(i, 7-j)) + { + WRITE32(cpu->mem_if->data, adr, cpu->R[7-j]); + c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; + adr -= 4; + } + cpu->R[13] = adr + 4; + + return c + 4; +} + +TEMPLATE static u32 FASTCALL OP_POP() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[13]; + u32 c = 0, j; + + for(j = 0; j<8; ++j) + if(BIT_N(i, j)) + { + cpu->R[j] = READ32(cpu->mem_if->data, adr); + c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; + adr += 4; + } + cpu->R[13] = adr; + + return c + 2; +} + +TEMPLATE static u32 FASTCALL OP_POP_PC() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[13]; + u32 c = 0, j; + u32 v; + + for(j = 0; j<8; ++j) + if(BIT_N(i, j)) + { + cpu->R[j] = READ32(cpu->mem_if->data, adr); + c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; + adr += 4; + } + + v = READ32(cpu->mem_if->data, adr); + c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; + cpu->R[15] = v & 0xFFFFFFFE; + cpu->next_instruction = v & 0xFFFFFFFE; + if(PROCNUM==0) + cpu->CPSR.bits.T = BIT0(v); + adr += 4; + + cpu->R[13] = adr; + return c + 5; +} + +TEMPLATE static u32 FASTCALL OP_BKPT_THUMB() +{ + return 1; +} + +TEMPLATE static u32 FASTCALL OP_STMIA_THUMB() +{ + const u32 &i = cpu->instruction; + u32 adr = cpu->R[REG_NUM(i, 8)]; + u32 c = 0, j; + + for(j = 0; j<8; ++j) + if(BIT_N(i, j)) + { + WRITE32(cpu->mem_if->data, adr, cpu->R[j]); + c += MMU.MMU_WAIT32[PROCNUM][(adr>>24)&0xF]; + adr += 4; + } + cpu->R[REG_NUM(i, 8)] = adr; + return c + 2; +} + TEMPLATE static u32 FASTCALL OP_LDMIA_THUMB() { const u32 &i = cpu->instruction; @@ -876,100 +877,97 @@ TEMPLATE static u32 FASTCALL OP_LDMIA_THUMB() cpu->R[regIndex] = adr; return c + 3; -} - -TEMPLATE static u32 FASTCALL OP_B_COND() -{ - const u32 &i = cpu->instruction; - if(!TEST_COND((i>>8)&0xF, 0, cpu->CPSR)) - return 1; - - cpu->R[15] += ((s32)((s8)(i&0xFF)))<<1; - cpu->next_instruction = cpu->R[15]; - return 3; -} - -TEMPLATE static u32 FASTCALL OP_SWI_THUMB() -{ - if (((cpu->intVector != 0) ^ (PROCNUM == ARMCPU_ARM9))) - { - /* we use an irq thats not in the irq tab, as - it was replaced duie to a changed intVector */ - Status_Reg tmp = cpu->CPSR; - armcpu_switchMode(cpu, SVC); /* enter svc mode */ - cpu->R[14] = cpu->R[15] - 4; /* jump to swi Vector */ - cpu->SPSR = tmp; /* save old CPSR as new SPSR */ - cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ - cpu->CPSR.bits.I = cpu->SPSR.bits.I; /* keep int disable flag */ - cpu->R[15] = cpu->intVector + 0x08; - cpu->next_instruction = cpu->R[15]; - return 3; - } - else - { - //zero 25-dec-2008 - in arm, we were masking to 0x1F. - //this is probably safer since an invalid opcode could crash the emu - //u32 swinum = cpu->instruction & 0xFF; - u32 swinum = cpu->instruction & 0x1F; +} + +TEMPLATE static u32 FASTCALL OP_B_COND() +{ + const u32 &i = cpu->instruction; + if(!TEST_COND((i>>8)&0xF, 0, cpu->CPSR)) + return 1; + + cpu->R[15] += ((s32)((s8)(i&0xFF)))<<1; + cpu->next_instruction = cpu->R[15]; + return 3; +} + +TEMPLATE static u32 FASTCALL OP_SWI_THUMB() +{ + if(cpu->swi_tab) { + //zero 25-dec-2008 - in arm, we were masking to 0x1F. + //this is probably safer since an invalid opcode could crash the emu + //u32 swinum = cpu->instruction & 0xFF; + u32 swinum = cpu->instruction & 0x1F; return cpu->swi_tab[swinum](cpu) + 3; - } - //return 3; -} - -#define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800)) - -TEMPLATE static u32 FASTCALL OP_B_UNCOND() -{ - const u32 &i = cpu->instruction; - cpu->R[15] += (SIGNEEXT_IMM11(i)<<1); - cpu->next_instruction = cpu->R[15]; - return 3; -} - -TEMPLATE static u32 FASTCALL OP_BLX() -{ - const u32 &i = cpu->instruction; - cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC; - cpu->R[14] = cpu->next_instruction | 1; - cpu->next_instruction = cpu->R[15]; - cpu->CPSR.bits.T = 0; - return 3; -} - -TEMPLATE static u32 FASTCALL OP_BL_10() -{ - const u32 &i = cpu->instruction; - cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12); - return 1; -} - -TEMPLATE static u32 FASTCALL OP_BL_THUMB() -{ - const u32 &i = cpu->instruction; - cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1)); - cpu->R[14] = cpu->next_instruction | 1; - cpu->next_instruction = cpu->R[15]; - return 3; -} - -#define TYPE_RETOUR u32 -#define CALLTYPE FASTCALL -#define PARAMETRES -#define NOM_THUMB_TAB thumb_instructions_set_0 -#define TABDECL(x) x<0> - -#include "thumb_tabdef.inc" - -#undef TYPE_RETOUR -#undef PARAMETRES -#undef CALLTYPE -#undef NOM_THUMB_TAB -#undef TABDECL - -#define TYPE_RETOUR u32 -#define PARAMETRES -#define CALLTYPE FASTCALL -#define NOM_THUMB_TAB thumb_instructions_set_1 -#define TABDECL(x) x<1> - -#include "thumb_tabdef.inc" + } + else { + /* we use an irq thats not in the irq tab, as + it was replaced duie to a changed intVector */ + Status_Reg tmp = cpu->CPSR; + armcpu_switchMode(cpu, SVC); /* enter svc mode */ + cpu->R[14] = cpu->next_instruction; /* jump to swi Vector */ + cpu->SPSR = tmp; /* save old CPSR as new SPSR */ + cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ + cpu->CPSR.bits.I = 1; + cpu->R[15] = cpu->intVector + 0x08; + cpu->next_instruction = cpu->R[15]; + return 3; + } +} + +#define SIGNEEXT_IMM11(i) (((i)&0x7FF) | (BIT10(i) * 0xFFFFF800)) + +TEMPLATE static u32 FASTCALL OP_B_UNCOND() +{ + const u32 &i = cpu->instruction; + cpu->R[15] += (SIGNEEXT_IMM11(i)<<1); + cpu->next_instruction = cpu->R[15]; + return 3; +} + +TEMPLATE static u32 FASTCALL OP_BLX() +{ + const u32 &i = cpu->instruction; + cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1))&0xFFFFFFFC; + cpu->R[14] = cpu->next_instruction | 1; + cpu->next_instruction = cpu->R[15]; + cpu->CPSR.bits.T = 0; + return 3; +} + +TEMPLATE static u32 FASTCALL OP_BL_10() +{ + const u32 &i = cpu->instruction; + cpu->R[14] = cpu->R[15] + (SIGNEEXT_IMM11(i)<<12); + return 1; +} + +TEMPLATE static u32 FASTCALL OP_BL_THUMB() +{ + const u32 &i = cpu->instruction; + cpu->R[15] = (cpu->R[14] + ((i&0x7FF)<<1)); + cpu->R[14] = cpu->next_instruction | 1; + cpu->next_instruction = cpu->R[15]; + return 3; +} + +#define TYPE_RETOUR u32 +#define CALLTYPE FASTCALL +#define PARAMETRES +#define NOM_THUMB_TAB thumb_instructions_set_0 +#define TABDECL(x) x<0> + +#include "thumb_tabdef.inc" + +#undef TYPE_RETOUR +#undef PARAMETRES +#undef CALLTYPE +#undef NOM_THUMB_TAB +#undef TABDECL + +#define TYPE_RETOUR u32 +#define PARAMETRES +#define CALLTYPE FASTCALL +#define NOM_THUMB_TAB thumb_instructions_set_1 +#define TABDECL(x) x<1> + +#include "thumb_tabdef.inc" diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 623d8b3d9..0d4498e11 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -1019,7 +1019,7 @@ DWORD WINAPI run() if (frameAdvance) { frameAdvance = false; - execute = FALSE; + emu_halt(); SPU_Pause(1); } frameCounter++; @@ -1043,7 +1043,7 @@ void NDS_Pause() { if (!paused) { - execute = FALSE; + emu_halt(); paused = TRUE; SPU_Pause(1); while (!paused) {} @@ -1229,7 +1229,7 @@ int RegClass(WNDPROC Proc, LPCTSTR szName) static void ExitRunLoop() { finished = TRUE; - execute = FALSE; + emu_halt(); } int WINAPI WinMain (HINSTANCE hThisInstance, diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index c8f5c7c9e..e62722abf 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -101,6 +101,7 @@ #define IDC_LANGENGLISH 210 #define IDC_LANGFRENCH 211 #define IDC_LANGDANISH 212 +#define IDM_DEFSIZE 213 #define IDD_MEM_VIEWER 301 #define IDC_8_BIT 302 #define IDC_16_BIT 303 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index c2f2a8ea7..8cddd354e 100644 --- a/desmume/src/windows/resources.rc +++ b/desmume/src/windows/resources.rc @@ -7,7 +7,8 @@ // // Generated from the TEXTINCLUDE 2 resource. // -#include "afxres.h" +#include "afxres.h" + ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -2362,7 +2363,8 @@ END // // Generated from the TEXTINCLUDE 3 resource. // - + + ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED