diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 7467c98e7..c641900ae 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -19,8 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define NEW_IRQ 1 - #include #include #include @@ -2412,6 +2410,11 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) writereg_POWCNT1(8,adr,val); break; + case eng_3D_CLEAR_COLOR+0: case eng_3D_CLEAR_COLOR+1: + case eng_3D_CLEAR_COLOR+2: case eng_3D_CLEAR_COLOR+3: + T1WriteByte((u8*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val); + break; + case REG_VRAMCNTA: case REG_VRAMCNTB: case REG_VRAMCNTC: @@ -2545,13 +2548,14 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) gfx3d_glAlphaFunc(val); return; } - // Clear background color setup - Parameters:2 + case eng_3D_CLEAR_COLOR: + case eng_3D_CLEAR_COLOR+2: { - ((u16 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x350>>1] = val; - gfx3d_glClearColor(val); - return; + T1WriteWord((u8*)&gfx3d.state.clearColor,adr-eng_3D_CLEAR_COLOR,val); + break; } + // Clear background depth setup - Parameters:2 case eng_3D_CLEAR_DEPTH: { @@ -2803,47 +2807,16 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) u32 new_val = val & 0x01; MMU.reg_IME[ARMCPU_ARM9] = new_val; T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x208, val); -#ifndef NEW_IRQ - if ( new_val && old_val != new_val) - { - // raise an interrupt request to the CPU if needed - if ( MMU.reg_IE[ARMCPU_ARM9] & MMU.reg_IF[ARMCPU_ARM9]) - { - NDS_ARM9.waitIRQ = FALSE; - } - } -#endif - return; + return; } case REG_IE : NDS_Reschedule(); MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF0000) | val; -#ifndef NEW_IRQ - if ( MMU.reg_IME[ARMCPU_ARM9]) - { - // raise an interrupt request to the CPU if needed - if ( MMU.reg_IE[ARMCPU_ARM9] & MMU.reg_IF[ARMCPU_ARM9]) - { - NDS_ARM9.waitIRQ = FALSE; - } - } -#endif return; case REG_IE + 2 : NDS_Reschedule(); MMU.reg_IE[ARMCPU_ARM9] = (MMU.reg_IE[ARMCPU_ARM9]&0xFFFF) | (((u32)val)<<16); -#ifndef NEW_IRQ - if ( MMU.reg_IME[ARMCPU_ARM9]) - { - // raise an interrupt request to the CPU if needed - if ( MMU.reg_IE[ARMCPU_ARM9] & MMU.reg_IF[ARMCPU_ARM9]) - { - NDS_ARM9.waitIRQ = FALSE; - } - } -#endif return; - case REG_IF : NDS_Reschedule(); MMU.reg_IF[ARMCPU_ARM9] &= (~((u32)val)); @@ -3108,21 +3081,19 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; // Alpha test reference value - Parameters:1 - case 0x04000340: + case eng_3D_ALPHA_TEST_REF: { ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x340>>2] = val; gfx3d_glAlphaFunc(val); return; } - // Clear background color setup - Parameters:2 - case 0x04000350: - { - ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x350>>2] = val; - gfx3d_glClearColor(val); - return; - } + + case eng_3D_CLEAR_COLOR: + T1WriteLong((u8*)&gfx3d.state.clearColor,0,val); + break; + // Clear background depth setup - Parameters:2 - case 0x04000354: + case eng_3D_CLEAR_DEPTH: { ((u32 *)(MMU.MMU_MEM[ARMCPU_ARM9][0x40]))[0x354>>2] = val; gfx3d_glClearDepth(val); @@ -3249,32 +3220,12 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) u32 new_val = val & 0x01; MMU.reg_IME[ARMCPU_ARM9] = new_val; T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x208, val); -#ifndef NEW_IRQ - if ( new_val && old_val != new_val) - { - // raise an interrupt request to the CPU if needed - if ( MMU.reg_IE[ARMCPU_ARM9] & MMU.reg_IF[ARMCPU_ARM9]) - { - NDS_ARM9.waitIRQ = FALSE; - } - } -#endif } return; case REG_IE : NDS_Reschedule(); MMU.reg_IE[ARMCPU_ARM9] = val; -#ifndef NEW_IRQ - if ( MMU.reg_IME[ARMCPU_ARM9]) - { - // raise an interrupt request to the CPU if needed - if ( MMU.reg_IE[ARMCPU_ARM9] & MMU.reg_IF[ARMCPU_ARM9]) - { - NDS_ARM9.waitIRQ = FALSE; - } - } -#endif return; case REG_IF : @@ -3378,10 +3329,7 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20], val); return; } - if(adr>=0x05000000 && adr<0x06200000) - { - int zzz=9; - } + bool unmapped; adr = MMU_LCDmap(adr, unmapped); @@ -3980,46 +3928,16 @@ void FASTCALL _MMU_ARM7_write16(u32 adr, u16 val) u32 new_val = val & 1; MMU.reg_IME[ARMCPU_ARM7] = new_val; T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x208, val); -#ifndef NEW_IRQ - if ( new_val && old_val != new_val) - { - /* raise an interrupt request to the CPU if needed */ - if ( MMU.reg_IE[ARMCPU_ARM7] & MMU.reg_IF[ARMCPU_ARM7]) - { - NDS_ARM7.waitIRQ = FALSE; - } - } -#endif - return; + return; } case REG_IE : NDS_Reschedule(); MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF0000) | val; -#ifndef NEW_IRQ - if ( MMU.reg_IME[ARMCPU_ARM7]) - { - /* raise an interrupt request to the CPU if needed */ - if ( MMU.reg_IE[ARMCPU_ARM7] & MMU.reg_IF[ARMCPU_ARM7]) - { - NDS_ARM7.waitIRQ = FALSE; - } - } -#endif return; case REG_IE + 2 : NDS_Reschedule(); //emu_halt(); MMU.reg_IE[ARMCPU_ARM7] = (MMU.reg_IE[ARMCPU_ARM7]&0xFFFF) | (((u32)val)<<16); -#ifndef NEW_IRQ - if ( MMU.reg_IME[ARMCPU_ARM7]) - { - /* raise an interrupt request to the CPU if needed */ - if ( MMU.reg_IE[ARMCPU_ARM7] & MMU.reg_IF[ARMCPU_ARM7]) - { - NDS_ARM7.waitIRQ = FALSE; - } - } -#endif return; case REG_IF : @@ -4117,32 +4035,12 @@ void FASTCALL _MMU_ARM7_write32(u32 adr, u32 val) u32 new_val = val & 1; MMU.reg_IME[ARMCPU_ARM7] = new_val; T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x208, val); -#ifndef NEW_IRQ - if ( new_val && old_val != new_val) - { - // raise an interrupt request to the CPU if needed - if ( MMU.reg_IE[ARMCPU_ARM7] & MMU.reg_IF[ARMCPU_ARM7]) - { - NDS_ARM7.waitIRQ = FALSE; - } - } -#endif return; } case REG_IE : NDS_Reschedule(); MMU.reg_IE[ARMCPU_ARM7] = val; -#ifndef NEW_IRQ - if ( MMU.reg_IME[ARMCPU_ARM7]) - { - /* raise an interrupt request to the CPU if needed */ - if ( MMU.reg_IE[ARMCPU_ARM7] & MMU.reg_IF[ARMCPU_ARM7]) - { - NDS_ARM7.waitIRQ = FALSE; - } - } -#endif return; case REG_IF : diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index 56823dc63..458e116a3 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1937,11 +1937,11 @@ void execHardware_interrupts() { if((MMU.reg_IF[0]&MMU.reg_IE[0]) && (MMU.reg_IME[0])) { -#ifdef GDB_STUB - if ( armcpu_flagIrq( &NDS_ARM9)) -#else +//#ifdef GDB_STUB +// if ( armcpu_flagIrq( &NDS_ARM9)) +//#else if ( armcpu_irqException(&NDS_ARM9)) -#endif +//#endif { //printf("ARM9 interrupt! flags: %08X ; mask: %08X ; result: %08X\n",MMU.reg_IF[0],MMU.reg_IE[0],MMU.reg_IF[0]&MMU.reg_IE[0]); //nds.ARM9Cycle = nds.cycles; @@ -1950,11 +1950,11 @@ void execHardware_interrupts() if((MMU.reg_IF[1]&MMU.reg_IE[1]) && (MMU.reg_IME[1])) { -#ifdef GDB_STUB - if ( armcpu_flagIrq( &NDS_ARM7)) -#else +//#ifdef GDB_STUB +// if ( armcpu_flagIrq( &NDS_ARM7)) +//#else if ( armcpu_irqException(&NDS_ARM7)) -#endif +//#endif { //nds.ARM7Cycle = nds.cycles; } diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 30482745a..d68ad57e0 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2006 yopyop Copyright (C) 2006-2007 shash + Copyright (C) 2008-2010 DeSmuME team This file is part of DeSmuME @@ -15,8 +16,8 @@ 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 + along with DeSmuME; if not, write to the + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //problem - alpha-on-alpha texture rendering might work but the dest alpha buffer isnt tracked correctly @@ -685,7 +686,7 @@ static void BeginRenderPoly() { lastEnvMode = envMode; - int _envModes[4] = {0, 1, (2 + gfx3d.state.shading), 0}; + int _envModes[4] = {0, 1, (2 + gfx3d.renderState.shading), 0}; glUniform1i(texBlendLoc, _envModes[envMode]); } } @@ -723,16 +724,16 @@ static void InstallPolygonAttrib(unsigned long val) static void Control() { - if(gfx3d.state.enableTexturing) glEnable (GL_TEXTURE_2D); + if(gfx3d.renderState.enableTexturing) glEnable (GL_TEXTURE_2D); else glDisable (GL_TEXTURE_2D); - if(gfx3d.state.enableAlphaTest) + if(gfx3d.renderState.enableAlphaTest) // FIXME: alpha test should pass gfx3d.alphaTestRef==poly->getAlpha - glAlphaFunc (GL_GREATER, gfx3d.state.alphaTestRef/31.f); + glAlphaFunc (GL_GREATER, gfx3d.renderState.alphaTestRef/31.f); else glAlphaFunc (GL_GREATER, 0); - if(gfx3d.state.enableAlphaBlending) + if(gfx3d.renderState.enableAlphaBlending) { glEnable (GL_BLEND); } @@ -820,27 +821,27 @@ static void OGLRender() if(hasShaders) { - if (gfx3d.state.invalidateToon) + if (gfx3d.renderState.invalidateToon) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_1D, oglToonTableTextureID); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, &gfx3d.state.rgbToonTable[0]); - gfx3d.state.invalidateToon = false; + glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, &gfx3d.renderState.rgbToonTable[0]); + gfx3d.renderState.invalidateToon = false; } } xglDepthMask(GL_TRUE); float clearColor[4] = { - ((float)(gfx3d.state.clearColor&0x1F))/31.0f, - ((float)((gfx3d.state.clearColor>>5)&0x1F))/31.0f, - ((float)((gfx3d.state.clearColor>>10)&0x1F))/31.0f, - ((float)((gfx3d.state.clearColor>>16)&0x1F))/31.0f, + ((float)(gfx3d.renderState.clearColor&0x1F))/31.0f, + ((float)((gfx3d.renderState.clearColor>>5)&0x1F))/31.0f, + ((float)((gfx3d.renderState.clearColor>>10)&0x1F))/31.0f, + ((float)((gfx3d.renderState.clearColor>>16)&0x1F))/31.0f, }; glClearColor(clearColor[0],clearColor[1],clearColor[2],clearColor[3]); - glClearDepth(gfx3d.state.clearDepth); - glClearStencil((gfx3d.state.clearColor >> 24) & 0x3F); + glClearDepth(gfx3d.renderState.clearDepth); + glClearStencil((gfx3d.renderState.clearColor >> 24) & 0x3F); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glMatrixMode(GL_PROJECTION); diff --git a/desmume/src/arm_instructions.cpp b/desmume/src/arm_instructions.cpp index cc2fea9b1..dca41e770 100644 --- a/desmume/src/arm_instructions.cpp +++ b/desmume/src/arm_instructions.cpp @@ -16,7 +16,7 @@ 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 + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // ARM core TODO: @@ -268,6 +268,7 @@ TEMPLATE static u32 FASTCALL OP_UND(const u32 i) 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->changeCPSR(); \ cpu->R[15] = cpu->intVector + 0x04; \ cpu->next_instruction = cpu->R[15]; \ return 4; \ @@ -300,6 +301,7 @@ TEMPLATE static u32 FASTCALL OP_UND(const u32 i) SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -443,6 +445,7 @@ TEMPLATE static u32 FASTCALL OP_AND_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -585,6 +588,7 @@ TEMPLATE static u32 FASTCALL OP_EOR_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -741,6 +745,7 @@ TEMPLATE static u32 FASTCALL OP_SUB_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -897,6 +902,7 @@ TEMPLATE static u32 FASTCALL OP_RSB_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1055,6 +1061,7 @@ TEMPLATE static u32 FASTCALL OP_ADD_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1215,6 +1222,7 @@ TEMPLATE static u32 FASTCALL OP_ADC_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1375,6 +1383,7 @@ TEMPLATE static u32 FASTCALL OP_SBC_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1811,6 +1820,7 @@ TEMPLATE static u32 FASTCALL OP_CMN_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -1954,6 +1964,7 @@ TEMPLATE static u32 FASTCALL OP_ORR_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -2100,6 +2111,7 @@ TEMPLATE static u32 FASTCALL OP_MOV_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -2242,6 +2254,7 @@ TEMPLATE static u32 FASTCALL OP_BIC_S_IMM_VAL(const u32 i) Status_Reg SPSR = cpu->SPSR; \ armcpu_switchMode(cpu, SPSR.bits.mode); \ cpu->CPSR=SPSR; \ + cpu->changeCPSR(); \ cpu->R[15] &= (0XFFFFFFFC|(((u32)SPSR.bits.T)<<1)); \ cpu->next_instruction = cpu->R[15]; \ return b; \ @@ -3069,7 +3082,9 @@ TEMPLATE static u32 FASTCALL OP_MSR_CPSR(const u32 i) } if(BIT19(i)) cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (operand & 0xFF000000); - + + cpu->changeCPSR(); + return 1; } @@ -3115,6 +3130,8 @@ TEMPLATE static u32 FASTCALL OP_MSR_CPSR_IMM_VAL(const u32 i) //cpu->CPSR.val = (cpu->CPSR.val & 0xFF000000) | (shift_op & 0XFF000000); cpu->CPSR.val = (cpu->CPSR.val & 0x00FFFFFF) | (shift_op & 0xFF000000); } + + cpu->changeCPSR(); return 1; } @@ -3137,6 +3154,8 @@ TEMPLATE static u32 FASTCALL OP_MSR_SPSR_IMM_VAL(const u32 i) if(BIT19(i)) cpu->SPSR.val = (cpu->SPSR.val & 0xFF000000) | (shift_op & 0XFF000000); + cpu->changeCPSR(); + return 1; } @@ -3695,7 +3714,7 @@ TEMPLATE static u32 FASTCALL OP_LDR_M_LSR_IMM_OFF(const u32 i) { cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; - cpu->next_instruction = cpu->R[15]; + cpu->next_instruction = cpu->R[15]; return MMU_aluMemAccessCycles(5,adr); } @@ -3743,7 +3762,7 @@ TEMPLATE static u32 FASTCALL OP_LDR_M_ASR_IMM_OFF(const u32 i) { cpu->R[15] = val & (0XFFFFFFFC | (((u32)cpu->LDTBit)<<1)); cpu->CPSR.bits.T = BIT0(val) & cpu->LDTBit; - cpu->next_instruction = cpu->R[15]; + cpu->next_instruction = cpu->R[15]; return MMU_aluMemAccessCycles(5,adr); } @@ -4312,7 +4331,7 @@ TEMPLATE static u32 FASTCALL OP_LDR_P_ROR_IMM_OFF_POSTIND(const u32 i) return MMU_aluMemAccessCycles(5,adr); } - cpu->R[REG_POS(i,16)] = adr + shift_op; + cpu->R[REG_POS(i,16)] = adr + shift_op; cpu->R[REG_POS(i,12)] = val; return MMU_aluMemAccessCycles(3,adr); @@ -5826,6 +5845,7 @@ TEMPLATE static u32 FASTCALL OP_LDMIA2(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; + cpu->changeCPSR(); //start += 4; cpu->next_instruction = cpu->R[15]; c += MMU_memAccessCycles(start); @@ -5882,7 +5902,8 @@ TEMPLATE static u32 FASTCALL OP_LDMIB2(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; - cpu->next_instruction = registres[15]; + cpu->changeCPSR(); + cpu->next_instruction = registres[15]; c += MMU_memAccessCycles(start); } return MMU_aluMemCycles(2, c); @@ -5913,6 +5934,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2(const u32 i) u32 tmp = READ32(cpu->mem_if->data, start); registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); cpu->CPSR = cpu->SPSR; + cpu->changeCPSR(); c += MMU_memAccessCycles(start); start -= 4; cpu->next_instruction = registres[15]; @@ -5943,6 +5965,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2(const u32 i) Status_Reg SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; + cpu->changeCPSR(); } return MMU_aluMemCycles(2, c); @@ -5971,6 +5994,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2(const u32 i) tmp = READ32(cpu->mem_if->data, start); registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); cpu->CPSR = cpu->SPSR; + cpu->changeCPSR(); cpu->next_instruction = registres[15]; c += MMU_memAccessCycles(start); } @@ -6000,6 +6024,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2(const u32 i) Status_Reg SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; + cpu->changeCPSR(); } return MMU_aluMemCycles(2, c); @@ -6053,6 +6078,7 @@ TEMPLATE static u32 FASTCALL OP_LDMIA2_W(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; + cpu->changeCPSR(); cpu->next_instruction = registres[15]; c += MMU_memAccessCycles(start); @@ -6106,10 +6132,12 @@ TEMPLATE static u32 FASTCALL OP_LDMIB2_W(const u32 i) tmp = READ32(cpu->mem_if->data, start + 4); registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); cpu->CPSR = cpu->SPSR; + cpu->changeCPSR(); cpu->next_instruction = registres[15]; SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; + cpu->changeCPSR(); c += MMU_memAccessCycles(start); return MMU_aluMemCycles(2, c); @@ -6169,6 +6197,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDA2_W(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; + cpu->changeCPSR(); return MMU_aluMemCycles(2, c); } @@ -6198,6 +6227,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2_W(const u32 i) c += MMU_memAccessCycles(start); registres[15] = tmp & (0XFFFFFFFC | (BIT0(tmp)<<1)); cpu->CPSR = cpu->SPSR; + cpu->changeCPSR(); cpu->next_instruction = registres[15]; } @@ -6228,6 +6258,7 @@ TEMPLATE static u32 FASTCALL OP_LDMDB2_W(const u32 i) SPSR = cpu->SPSR; armcpu_switchMode(cpu, SPSR.bits.mode); cpu->CPSR=SPSR; + cpu->changeCPSR(); return MMU_aluMemCycles(2, c); } @@ -6869,6 +6900,7 @@ TEMPLATE static u32 FASTCALL OP_SWI(const u32 i) cpu->SPSR = tmp; /* save old CPSR as new SPSR */ cpu->CPSR.bits.T = 0; /* handle as ARM32 code */ cpu->CPSR.bits.I = 1; + cpu->changeCPSR(); cpu->R[15] = cpu->intVector + 0x08; cpu->next_instruction = cpu->R[15]; return 4; diff --git a/desmume/src/armcpu.cpp b/desmume/src/armcpu.cpp index 18d6232a4..07ebb15c2 100644 --- a/desmume/src/armcpu.cpp +++ b/desmume/src/armcpu.cpp @@ -210,6 +210,13 @@ int armcpu_new( armcpu_t *armcpu, u32 id) return 0; } +//call this whenever CPSR is changed (other than CNVZQ or T flags); interrupts may need to be unleashed +void armcpu_t::changeCPSR() +{ + //but all it does is give them a chance to unleash by forcing an immediate reschedule + NDS_Reschedule(); +} + void armcpu_init(armcpu_t *armcpu, u32 adr) { u32 i; @@ -260,7 +267,7 @@ void armcpu_init(armcpu_t *armcpu, u32 adr) u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode) { - u32 oldmode = armcpu->CPSR.bits.mode; + u32 oldmode = armcpu->CPSR.bits.mode; switch(oldmode) { @@ -362,6 +369,7 @@ u32 armcpu_switchMode(armcpu_t *armcpu, u8 mode) } armcpu->CPSR.bits.mode = mode & 0x1F; + armcpu->changeCPSR(); return oldmode; } @@ -466,45 +474,44 @@ BOOL armcpu_irqException(armcpu_t *armcpu) if(armcpu->CPSR.bits.I) return FALSE; -#ifdef GDB_STUB - armcpu->irq_flag = 0; -#endif +//#ifdef GDB_STUB +// armcpu->irq_flag = 0; +//#endif tmp = armcpu->CPSR; armcpu_switchMode(armcpu, IRQ); -#ifdef GDB_STUB - armcpu->R[14] = armcpu->next_instruction + 4; -#else +//#ifdef GDB_STUB +// armcpu->R[14] = armcpu->next_instruction + 4; +//#else armcpu->R[14] = armcpu->instruct_adr + 4; -#endif +//#endif armcpu->SPSR = tmp; armcpu->CPSR.bits.T = 0; armcpu->CPSR.bits.I = 1; armcpu->next_instruction = armcpu->intVector + 0x18; armcpu->waitIRQ = 0; -#ifndef GDB_STUB +//#ifndef GDB_STUB armcpu->R[15] = armcpu->next_instruction + 8; armcpu_prefetch(armcpu); -#endif +//#endif return TRUE; } -BOOL -armcpu_flagIrq( armcpu_t *armcpu) { - if(armcpu->CPSR.bits.I) return FALSE; - - armcpu->waitIRQ = 0; - -#ifdef GDB_STUB - armcpu->irq_flag = 1; -#endif - - return TRUE; -} - +//BOOL +//armcpu_flagIrq( armcpu_t *armcpu) { +// if(armcpu->CPSR.bits.I) return FALSE; +// +// armcpu->waitIRQ = 0; +// +//#ifdef GDB_STUB +// armcpu->irq_flag = 1; +//#endif +// +// return TRUE; +//} template u32 armcpu_exec() diff --git a/desmume/src/armcpu.h b/desmume/src/armcpu.h index 4b4af184d..3faa5cfe2 100644 --- a/desmume/src/armcpu.h +++ b/desmume/src/armcpu.h @@ -1,6 +1,5 @@ /* Copyright (C) 2006 yopyop - yopyop156@ifrance.com - yopyop156.ifrance.com + Copyright (C) 2008-2010 DeSmuME team This file is part of DeSmuME @@ -16,7 +15,7 @@ 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 + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef ARM_CPU @@ -148,7 +147,7 @@ struct armcpu_ctrl_iface { typedef void* armcp_t; -typedef struct armcpu_t +struct armcpu_t { u32 proc_ID; u32 instruction; //4 @@ -159,6 +158,8 @@ typedef struct armcpu_t Status_Reg CPSR; //80 Status_Reg SPSR; + void changeCPSR(); + u32 R13_usr, R14_usr; u32 R13_svc, R14_svc; u32 R13_abt, R14_abt; @@ -197,7 +198,7 @@ typedef struct armcpu_t /** the ctrl interface */ struct armcpu_ctrl_iface ctrl_iface; #endif -} armcpu_t; +}; #ifdef GDB_STUB int armcpu_new( armcpu_t *armcpu, u32 id, struct armcpu_memory_iface *mem_if, @@ -224,32 +225,25 @@ static INLINE void setIF(int PROCNUM, u32 flag) extern void NDS_Reschedule(); NDS_Reschedule(); + + //generate the interrupt if enabled + if ((MMU.reg_IE[PROCNUM] & (flag)) && MMU.reg_IME[PROCNUM]) + { + if(PROCNUM==0) + NDS_ARM9.waitIRQ = FALSE; + else + NDS_ARM7.waitIRQ = FALSE; + } } static INLINE void NDS_makeARM9Int(u32 num) { - /* flag the interrupt request source */ - // MMU.reg_IF[0] |= (1<>24)+1)-((v>>8)&0xFF); } -void gfx3d_glClearColor(u32 v) -{ - gfx3d.state.clearColor = v; -} - void gfx3d_glFogColor(u32 v) { gfx3d.state.fogColor = v; @@ -2013,6 +2008,8 @@ static void gfx3d_doFlush() gfx3d.state.enableClearImage = BIT14(control); gfx3d.state.fogShift = (control>>8)&0xF; + gfx3d.renderState = gfx3d.state; + int polycount = polylist->count; //find the min and max y values for each poly. diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index 3c5120f2e..37992c622 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -1,8 +1,6 @@ -/* Copyright (C) 2006 yopyop - yopyop156@ifrance.com - yopyop156.ifrance.com - - Copyright (C) 2008-2009 DeSmuME team +/* gfx3d.h + Copyright (C) 2006 yopyop + Copyright (C) 2008-2010 DeSmuME team This file is part of DeSmuME @@ -367,8 +365,11 @@ struct GFX3D , frameCtrRaw(0) { } + //currently set values GFX3D_State state; + //values used for the currently-rendered frame (committed with each flush) + GFX3D_State renderState; POLYLIST* polylist; VERTLIST* vertlist; @@ -406,7 +407,6 @@ int _hack_getMatrixStackLevel(int); void gfx3d_glFlush(u32 v); // end GE commands -void gfx3d_glClearColor(u32 v); void gfx3d_glFogColor(u32 v); void gfx3d_glFogOffset (u32 v); void gfx3d_glClearDepth(u32 v); diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index 07c7185a8..a874d1a66 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -266,7 +266,7 @@ FORCEINLINE int edge_fx_fl::Step() { static FORCEINLINE void alphaBlend(FragmentColor & dst, const FragmentColor & src) { - if(gfx3d.state.enableAlphaBlending) + if(gfx3d.renderState.enableAlphaBlending) { if(src.a == 0 || dst.a == 0) { @@ -500,7 +500,7 @@ public: } else { - if(gfx3d.state.shading == GFX3D_State::HIGHLIGHT) + if(gfx3d.renderState.shading == GFX3D_State::HIGHLIGHT) { dst.r = modulate_table[texColor.r][shader.materialColor.r]; dst.g = modulate_table[texColor.g][shader.materialColor.r]; @@ -548,7 +548,7 @@ public: FragmentColor &destFragmentColor = engine->screenColor[adr]; u32 depth; - if(gfx3d.state.wbuffer) + if(gfx3d.renderState.wbuffer) { //not sure about this //this value was chosen to make the skybox, castle window decals, and water level render correctly in SM64 @@ -632,9 +632,9 @@ public: if(shaderOutput.a != 0) { //alpha test (don't have any test cases for this...? is it in the right place...?) - if(gfx3d.state.enableAlphaTest) + if(gfx3d.renderState.enableAlphaTest) { - if(shaderOutput.a < gfx3d.state.alphaTestRef) + if(shaderOutput.a < gfx3d.renderState.alphaTestRef) goto rejected_fragment; } @@ -1087,19 +1087,19 @@ void SoftRasterizerEngine::initFramebuffer(const int width, const int height, co Fragment clearFragment; FragmentColor clearFragmentColor; clearFragment.isTranslucentPoly = 0; - clearFragmentColor.r = GFX3D_5TO6(gfx3d.state.clearColor&0x1F); - clearFragmentColor.g = GFX3D_5TO6((gfx3d.state.clearColor>>5)&0x1F); - clearFragmentColor.b = GFX3D_5TO6((gfx3d.state.clearColor>>10)&0x1F); - clearFragmentColor.a = ((gfx3d.state.clearColor>>16)&0x1F); - clearFragment.polyid.opaque = (gfx3d.state.clearColor>>24)&0x3F; + clearFragmentColor.r = GFX3D_5TO6(gfx3d.renderState.clearColor&0x1F); + clearFragmentColor.g = GFX3D_5TO6((gfx3d.renderState.clearColor>>5)&0x1F); + clearFragmentColor.b = GFX3D_5TO6((gfx3d.renderState.clearColor>>10)&0x1F); + clearFragmentColor.a = ((gfx3d.renderState.clearColor>>16)&0x1F); + clearFragment.polyid.opaque = (gfx3d.renderState.clearColor>>24)&0x3F; //special value for uninitialized translucent polyid. without this, fires in spiderman2 dont display //I am not sure whether it is right, though. previously this was cleared to 0, as a guess, //but in spiderman2 some fires with polyid 0 try to render on top of the background clearFragment.polyid.translucent = kUnsetTranslucentPolyID; - clearFragment.depth = gfx3d.state.clearDepth; + clearFragment.depth = gfx3d.renderState.clearDepth; clearFragment.stencil = 0; clearFragment.isTranslucentPoly = 0; - clearFragment.fogged = BIT15(gfx3d.state.clearColor); + clearFragment.fogged = BIT15(gfx3d.renderState.clearColor); for(int i=0;i> 2) & 0x3F; - toonTable[i].g = (gfx3d.state.rgbToonTable[i] >> 10) & 0x3F; - toonTable[i].b = (gfx3d.state.rgbToonTable[i] >> 18) & 0x3F; + toonTable[i].r = (gfx3d.renderState.rgbToonTable[i] >> 2) & 0x3F; + toonTable[i].g = (gfx3d.renderState.rgbToonTable[i] >> 10) & 0x3F; + toonTable[i].b = (gfx3d.renderState.rgbToonTable[i] >> 18) & 0x3F; } - gfx3d.state.invalidateToon = false; + gfx3d.renderState.invalidateToon = false; } void SoftRasterizerEngine::updateFogTable() @@ -1167,14 +1167,14 @@ void SoftRasterizerEngine::updateFogTable() #if 0 //TODO - this might be a little slow; //we might need to hash all the variables and only recompute this when something changes - const int increment = (0x400 >> gfx3d.state.fogShift); + const int increment = (0x400 >> gfx3d.renderState.fogShift); for(u32 i=0;i<32768;i++) { - if(i> gfx3d.state.fogShift); - const int incrementDivShift = 10 - gfx3d.state.fogShift; - u32 fogOffset = min(max(gfx3d.state.fogOffset, 0), 32768); + const int increment = ((1 << 10) >> gfx3d.renderState.fogShift); + const int incrementDivShift = 10 - gfx3d.renderState.fogShift; + u32 fogOffset = min(max(gfx3d.renderState.fogOffset, 0), 32768); u32 iMin = min(32768, (( 1 + 1) << incrementDivShift) + fogOffset + 1 - increment); u32 iMax = min(32768, ((32 + 1) << incrementDivShift) + fogOffset + 1 - increment); assert(iMin <= iMax); @@ -1233,7 +1233,7 @@ void SoftRasterizerEngine::framebufferProcess() // - the edges are completely sharp/opaque on the very brief title screen intro, // - the level-start intro gets a pseudo-antialiasing effect around the silhouette, // - the character edges in-level are clearly transparent, and also show well through shield powerups. - if(gfx3d.state.enableEdgeMarking && CommonSettings.GFX3D_EdgeMark) + if(gfx3d.renderState.enableEdgeMarking && CommonSettings.GFX3D_EdgeMark) { //TODO - need to test and find out whether these get grabbed at flush time, or at render time //we can do this by rendering a 3d frame and then freezing the system, but only changing the edge mark colors @@ -1303,12 +1303,12 @@ void SoftRasterizerEngine::framebufferProcess() } } - if(gfx3d.state.enableFog && CommonSettings.GFX3D_Fog) + if(gfx3d.renderState.enableFog && CommonSettings.GFX3D_Fog) { - u32 r = GFX3D_5TO6((gfx3d.state.fogColor)&0x1F); - u32 g = GFX3D_5TO6((gfx3d.state.fogColor>>5)&0x1F); - u32 b = GFX3D_5TO6((gfx3d.state.fogColor>>10)&0x1F); - u32 a = (gfx3d.state.fogColor>>16)&0x1F; + u32 r = GFX3D_5TO6((gfx3d.renderState.fogColor)&0x1F); + u32 g = GFX3D_5TO6((gfx3d.renderState.fogColor>>5)&0x1F); + u32 b = GFX3D_5TO6((gfx3d.renderState.fogColor>>10)&0x1F); + u32 a = (gfx3d.renderState.fogColor>>16)&0x1F; for(int i=0;i<256*192;i++) { Fragment &destFragment = screen[i]; @@ -1318,7 +1318,7 @@ void SoftRasterizerEngine::framebufferProcess() assert(fogIndex<32768); u8 fog = fogTable[fogIndex]; if(fog==127) fog=128; - if(!gfx3d.state.enableFogAlphaOnly) + if(!gfx3d.renderState.enableFogAlphaOnly) { destFragmentColor.r = ((128-fog)*destFragmentColor.r + r*fog)>>7; destFragmentColor.g = ((128-fog)*destFragmentColor.g + g*fog)>>7; @@ -1506,10 +1506,10 @@ static void SoftRastRender() mainSoftRasterizer.height = 192; //setup fog variables (but only if fog is enabled) - if(gfx3d.state.enableFog && CommonSettings.GFX3D_Fog) + if(gfx3d.renderState.enableFog && CommonSettings.GFX3D_Fog) mainSoftRasterizer.updateFogTable(); - mainSoftRasterizer.initFramebuffer(256,192,gfx3d.state.enableClearImage?true:false); + mainSoftRasterizer.initFramebuffer(256,192,gfx3d.renderState.enableClearImage?true:false); mainSoftRasterizer.updateToonTable(); mainSoftRasterizer.updateFloatColors(); mainSoftRasterizer.performClipping(CommonSettings.GFX3D_HighResolutionInterpolateColor); diff --git a/desmume/src/thumb_instructions.cpp b/desmume/src/thumb_instructions.cpp index 003f0739f..2721d52dc 100644 --- a/desmume/src/thumb_instructions.cpp +++ b/desmume/src/thumb_instructions.cpp @@ -1,6 +1,5 @@ /* Copyright (C) 2006 yopyop - yopyop156@ifrance.com - yopyop156.ifrance.com + Copyright (C) 2008-2010 DeSmuME team Code added on 18/08/2006 by shash - Missing missaligned addresses correction @@ -20,7 +19,7 @@ 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 + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // THUMB core TODO: @@ -1003,7 +1002,7 @@ TEMPLATE static u32 FASTCALL OP_SWI_THUMB(const u32 i) } else { /* we use an irq thats not in the irq tab, as - it was replaced duie to a changed intVector */ + it was replaced due 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 */ diff --git a/desmume/src/windows/hotkey.cpp b/desmume/src/windows/hotkey.cpp index 92fe40798..027033980 100644 --- a/desmume/src/windows/hotkey.cpp +++ b/desmume/src/windows/hotkey.cpp @@ -2,7 +2,7 @@ // licensed under the terms supplied at the end of this file (for the terms are very long!) // Differences from that baseline version are: // -// Copyright (C) 2009 DeSmuME team +// Copyright (C) 2009-2010 DeSmuME team // // DeSmuME is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ // // 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 +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //*/ #include "hotkey.h" @@ -200,7 +200,7 @@ void HK_AutoHoldKeyUp(int) {AutoHoldPressed = false;} void HK_StylusAutoHoldKeyDown(int, bool justPressed) { StylusAutoHoldPressed = !StylusAutoHoldPressed; if (StylusAutoHoldPressed) - NDS_setTouchPos(winLastTouch.x, winLastTouch.y); + NDS_setTouchPos((u16)winLastTouch.x, (u16)winLastTouch.y); else if (!userTouchesScreen) NDS_releaseTouch(); }