diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 8cf7ccc1e..61440ac79 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -1714,8 +1714,7 @@ u32 TGXSTAT::read32() // using in "The Wild West" ret |= ((_hack_getMatrixStackLevel(0) << 13) | (_hack_getMatrixStackLevel(1) << 8)); //matrix stack levels //no proof that these are needed yet - //todo: stack busy flag (bit14) - + ret |= sb<<14; //stack busy ret |= se<<15; ret |= (std::min(gxFIFO.size,(u32)255))<<16; if(gxFIFO.size>=255) ret |= BIT(24); //fifo full @@ -1758,16 +1757,18 @@ void TGXSTAT::write32(const u32 val) void TGXSTAT::savestate(EMUFILE *f) { - write32le(0,f); //version - write8le(tb,f); write8le(tr,f); write8le(se,f); write8le(gxfifo_irq,f); + write32le(1,f); //version + write8le(tb,f); write8le(tr,f); write8le(se,f); write8le(gxfifo_irq,f); write8le(sb,f); } bool TGXSTAT::loadstate(EMUFILE *f) { u32 version; if(read32le(&version,f) != 1) return false; - if(version != 0) return false; + if(version > 1) return false; read8le(&tb,f); read8le(&tr,f); read8le(&se,f); read8le(&gxfifo_irq,f); + if (version >= 1) + read8le(&sb,f); return true; } @@ -3174,10 +3175,10 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) } case REG_DISPA_BLDY: - GPU_setBLDY_EVY(MainScreen.gpu,val) ; + GPU_setBLDY_EVY(MainScreen.gpu,val&0xFFFF) ; break ; case REG_DISPB_BLDY: - GPU_setBLDY_EVY(SubScreen.gpu,val) ; + GPU_setBLDY_EVY(SubScreen.gpu,val&0xFFFF); break; case REG_DISPA_DISPCNT : diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h index 8ee4b8f73..75690d848 100644 --- a/desmume/src/MMU.h +++ b/desmume/src/MMU.h @@ -115,11 +115,12 @@ public: struct TGXSTAT : public TRegister_32 { TGXSTAT() { - gxfifo_irq = se = tr = tb = 0; + gxfifo_irq = se = tr = tb = sb = 0; } u8 tb; //test busy u8 tr; //test result u8 se; //stack error + u8 sb; //stack busy u8 gxfifo_irq; //irq configuration virtual u32 read32(); diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index e9f907144..270e0fd1b 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -1172,10 +1172,15 @@ struct TSequenceItem_divider : public TSequenceItem { IF_DEVELOPER(DEBUG_statistics.sequencerExecutionCounters[2]++); MMU_new.div.busy = 0; +#ifdef _WIN64 + T1WriteQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A0, MMU.divResult); + T1WriteQuad(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A8, MMU.divMod); +#else T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A0, (u32)MMU.divResult); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A4, (u32)(MMU.divResult >> 32)); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2A8, (u32)MMU.divMod); T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x2AC, (u32)(MMU.divMod >> 32)); +#endif MMU.divRunning = FALSE; } @@ -1764,6 +1769,7 @@ static /*donotinline*/ std::pair armInnerLoop( timer = minarmtime(arm9,arm7); nds_timer = nds_timer_base + timer; + if (nds_timer >= MMU.gfx3dCycles) MMU_new.gxstat.sb = 0; // clear stack busy flag } return std::make_pair(arm9, arm7); diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index a1e6f1ff4..43b4e6c5c 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -317,10 +317,10 @@ CACHE_ALIGN u8 gfx3d_convertedScreen[256*192*4]; // Matrix stack handling CACHE_ALIGN MatrixStack mtxStack[4] = { - MatrixStack(1), // Projection stack - MatrixStack(31), // Coordinate stack - MatrixStack(31), // Directional stack - MatrixStack(1), // Texture stack + MatrixStack(1, 0), // Projection stack + MatrixStack(31, 1), // Coordinate stack + MatrixStack(31, 2), // Directional stack + MatrixStack(1, 3), // Texture stack }; int _hack_getMatrixStackLevel(int which) { return mtxStack[which].position; } @@ -785,19 +785,9 @@ static void gfx3d_glMatrixMode(u32 v) static void gfx3d_glPushMatrix() { - //u32 gxstat = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode short mymode = (mode==1?2:mode); - if (mtxStack[mymode].position > mtxStack[mymode].size) - { - MMU_new.gxstat.se = 1; - //gxstat |= (1<<15); - return; - } - - //gxstat &= 0xFFFF00FF; - MatrixStackPushMatrix(&mtxStack[mymode], mtxCurrent[mymode]); GFX_DELAY(17); @@ -805,36 +795,30 @@ static void gfx3d_glPushMatrix() if(mymode==2) MatrixStackPushMatrix (&mtxStack[1], mtxCurrent[1]); - //gxstat |= ((mtxStack[0].position << 13) | (mtxStack[1].position << 8)); + MMU_new.gxstat.sb = 1; // set busy } static void gfx3d_glPopMatrix(s32 i) { + // The stack has only one level (at address 0) in projection mode, + // in that mode, the parameter value is ignored, the offset is always +1 in that mode. + if (mode == 0) i = 1; + //this command always works on both pos and vector when either pos or pos-vector are the current mtx mode short mymode = (mode==1?2:mode); //6 bits, sign extended //this was necessary to fix sims apartment pets - i = (i<<26)>>26; - - if (i > mtxStack[mymode].position) - { - //was commented out before zero sep modifications - //handled in matrix now - //MMU_new.gxstat.se = 1; - // T1WriteLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600, gxstat); - // return; - } - + //i = (i<<26)>>26; - MatrixCopy(mtxCurrent[mymode], MatrixStackPopMatrix (&mtxStack[mymode], i)); + MatrixStackPopMatrix((float*)mtxCurrent[mymode], &mtxStack[mymode], i); GFX_DELAY(36); if (mymode == 2) - MatrixCopy(mtxCurrent[1], MatrixStackPopMatrix (&mtxStack[1], i)); + MatrixStackPopMatrix((float*)mtxCurrent[1], &mtxStack[1], i); - //gxstat |= ((mtxStack[0].position << 13) | (mtxStack[1].position << 8)); + MMU_new.gxstat.sb = 1; // set busy } static void gfx3d_glStoreMatrix(u32 v) @@ -1660,14 +1644,137 @@ unsigned int gfx3d_glGetPosRes(unsigned int index) return (unsigned int)(PTcoords[index] * 4096.0f); } +void log3D(u8 cmd, u32 param) +{ + INFO("3D command 0x%02X: ", cmd); + switch (cmd) + { + case 0x10: // MTX_MODE - Set Matrix Mode (W) + printf("MTX_MODE(%08X)", param); + break; + case 0x11: // MTX_PUSH - Push Current Matrix on Stack (W) + printf("MTX_PUSH()\t"); + break; + case 0x12: // MTX_POP - Pop Current Matrix from Stack (W) + printf("MTX_POP(%08X)", param); + break; + case 0x13: // MTX_STORE - Store Current Matrix on Stack (W) + printf("MTX_STORE(%08X)", param); + break; + case 0x14: // MTX_RESTORE - Restore Current Matrix from Stack (W) + printf("MTX_RESTORE(%08X)", param); + break; + case 0x15: // MTX_IDENTITY - Load Unit Matrix to Current Matrix (W) + printf("MTX_IDENTIFY()\t"); + break; + case 0x16: // MTX_LOAD_4x4 - Load 4x4 Matrix to Current Matrix (W) + printf("MTX_LOAD_4x4(%08X)", param); + break; + case 0x17: // MTX_LOAD_4x3 - Load 4x3 Matrix to Current Matrix (W) + printf("MTX_LOAD_4x3(%08X)", param); + break; + case 0x18: // MTX_MULT_4x4 - Multiply Current Matrix by 4x4 Matrix (W) + printf("MTX_MULT_4x4(%08X)", param); + break; + case 0x19: // MTX_MULT_4x3 - Multiply Current Matrix by 4x3 Matrix (W) + printf("MTX_MULT_4x3(%08X)", param); + break; + case 0x1A: // MTX_MULT_3x3 - Multiply Current Matrix by 3x3 Matrix (W) + printf("MTX_MULT_3x3(%08X)", param); + break; + case 0x1B: // MTX_SCALE - Multiply Current Matrix by Scale Matrix (W) + printf("MTX_SCALE(%08X)", param); + break; + case 0x1C: // MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W) + printf("MTX_TRANS(%08X)", param); + break; + case 0x20: // COLOR - Directly Set Vertex Color (W) + printf("COLOR(%08X)", param); + break; + case 0x21: // NORMAL - Set Normal Vector (W) + printf("NORMAL(%08X)", param); + break; + case 0x22: // TEXCOORD - Set Texture Coordinates (W) + printf("TEXCOORD(%08X)", param); + break; + case 0x23: // VTX_16 - Set Vertex XYZ Coordinates (W) + printf("VTX_16(%08X)", param); + break; + case 0x24: // VTX_10 - Set Vertex XYZ Coordinates (W) + printf("VTX_10(%08X)", param); + break; + case 0x25: // VTX_XY - Set Vertex XY Coordinates (W) + printf("VTX_XY(%08X)", param); + break; + case 0x26: // VTX_XZ - Set Vertex XZ Coordinates (W) + printf("VTX_XZ(%08X)", param); + break; + case 0x27: // VTX_YZ - Set Vertex YZ Coordinates (W) + printf("VTX_YZ(%08X)", param); + break; + case 0x28: // VTX_DIFF - Set Relative Vertex Coordinates (W) + printf("VTX_DIFF(%08X)", param); + break; + case 0x29: // POLYGON_ATTR - Set Polygon Attributes (W) + printf("POLYGON_ATTR(%08X)", param); + break; + case 0x2A: // TEXIMAGE_PARAM - Set Texture Parameters (W) + printf("TEXIMAGE_PARAM(%08X)", param); + break; + case 0x2B: // PLTT_BASE - Set Texture Palette Base Address (W) + printf("PLTT_BASE(%08X)", param); + break; + case 0x30: // DIF_AMB - MaterialColor0 - Diffuse/Ambient Reflect. (W) + printf("DIF_AMB(%08X)", param); + break; + case 0x31: // SPE_EMI - MaterialColor1 - Specular Ref. & Emission (W) + printf("SPE_EMI(%08X)", param); + break; + case 0x32: // LIGHT_VECTOR - Set Light's Directional Vector (W) + printf("LIGHT_VECTOR(%08X)", param); + break; + case 0x33: // LIGHT_COLOR - Set Light Color (W) + printf("LIGHT_COLOR(%08X)", param); + break; + case 0x34: // SHININESS - Specular Reflection Shininess Table (W) + printf("SHININESS(%08X)", param); + break; + case 0x40: // BEGIN_VTXS - Start of Vertex List (W) + printf("BEGIN_VTXS(%08X)", param); + break; + case 0x41: // END_VTXS - End of Vertex List (W) + printf("END_VTXS()\t"); + break; + case 0x50: // SWAP_BUFFERS - Swap Rendering Engine Buffer (W) + printf("SWAP_BUFFERS(%08X)", param); + break; + case 0x60: // VIEWPORT - Set Viewport (W) + printf("VIEWPORT(%08X)", param); + break; + case 0x70: // BOX_TEST - Test if Cuboid Sits inside View Volume (W) + printf("BOX_TEST(%08X)", param); + break; + case 0x71: // POS_TEST - Set Position Coordinates for Test (W) + printf("POS_TEST(%08X)", param); + break; + case 0x72: // VEC_TEST - Set Directional Vector for Test (W) + printf("VEC_TEST(%08X)", param); + break; + default: + INFO("!!! Unknown(%08X)", param); + break; + } + printf("\t\t(FIFO size %i)\n", gxFIFO.size); +} + //#define _3D_LOG_EXEC static void gfx3d_execute(u8 cmd, u32 param) { - //printf("*** gxFIFO: exec 0x%02X, size %03i\n", cmd, gxFIFO.size); #ifdef _3D_LOG_EXEC - u32 gxstat2 = T1ReadLong(MMU.MMU_MEM[ARMCPU_ARM9][0x40], 0x600); - INFO("*** gxFIFO: exec 0x%02X, tail %03i, gxstat 0x%08X (timer %i)\n", cmd, gxFIFO.tail, gxstat2, nds_timer); + log3D(cmd, param); #endif + + MMU_new.gxstat.sb = 0; // clear stack busy flag switch (cmd) { case 0x10: // MTX_MODE - Set Matrix Mode (W) diff --git a/desmume/src/matrix.cpp b/desmume/src/matrix.cpp index 83a9eee9b..344e69612 100644 --- a/desmume/src/matrix.cpp +++ b/desmume/src/matrix.cpp @@ -211,38 +211,39 @@ void MatrixStackSetMaxSize (MatrixStack *stack, int size) } -MatrixStack::MatrixStack(int size) +MatrixStack::MatrixStack(int size, int type) { MatrixStackSetMaxSize(this,size); + this->type = type; } void MatrixStackSetStackPosition (MatrixStack *stack, int pos) { - //printf("SetPosition: %d by %d",stack->position,pos); stack->position += pos; - //this wraparound behavior fixed sims apartment pets which was constantly going up to 32 - s32 newpos = stack->position; - stack->position &= (stack->size); - - if(newpos != stack->position) + if((stack->position < 0) || (stack->position > stack->size)) MMU_new.gxstat.se = 1; - - //printf(" to %d (size %d)\n",stack->position,stack->size); + stack->position &= stack->size; } void MatrixStackPushMatrix (MatrixStack *stack, const float *ptr) { - MatrixCopy (&stack->matrix[stack->position*16], ptr); - + //printf("Push %i pos %i\n", stack->type, stack->position); + if ((stack->type == 0) || (stack->type == 3)) + MatrixCopy (&stack->matrix[0], ptr); + else + MatrixCopy (&stack->matrix[stack->position*16], ptr); MatrixStackSetStackPosition (stack, 1); } -float * MatrixStackPopMatrix (MatrixStack *stack, int size) +void MatrixStackPopMatrix (float *mtxCurr, MatrixStack *stack, int size) { + //printf("Pop %i pos %i (change %d)\n", stack->type, stack->position, -size); MatrixStackSetStackPosition(stack, -size); - - return &stack->matrix[stack->position*16]; + if ((stack->type == 0) || (stack->type == 3)) + MatrixCopy (mtxCurr, &stack->matrix[0]); + else + MatrixCopy (mtxCurr, &stack->matrix[stack->position*16]); } float * MatrixStackGetPos (MatrixStack *stack, int pos) diff --git a/desmume/src/matrix.h b/desmume/src/matrix.h index b6a75979b..60b1865fd 100644 --- a/desmume/src/matrix.h +++ b/desmume/src/matrix.h @@ -37,10 +37,11 @@ struct MatrixStack { - MatrixStack(int size); + MatrixStack(int size, int type); float *matrix; s32 position; s32 size; + u8 type; }; void MatrixInit (float *matrix); @@ -60,7 +61,7 @@ void MatrixStackInit (MatrixStack *stack); void MatrixStackSetMaxSize (MatrixStack *stack, int size); void MatrixStackSetStackPosition (MatrixStack *stack, int pos); void MatrixStackPushMatrix (MatrixStack *stack, const float *ptr); -float* MatrixStackPopMatrix (MatrixStack *stack, int size); +void MatrixStackPopMatrix (float *mtxCurr, MatrixStack *stack, int size); float* MatrixStackGetPos (MatrixStack *stack, int pos); float* MatrixStackGet (MatrixStack *stack); void MatrixStackLoadMatrix (MatrixStack *stack, int pos, const float *ptr); diff --git a/desmume/src/mc.cpp b/desmume/src/mc.cpp index ac3f947d3..1121047fd 100644 --- a/desmume/src/mc.cpp +++ b/desmume/src/mc.cpp @@ -719,6 +719,7 @@ bool BackupDevice::load_no_gba(const char *fname) if (in_buf) delete [] in_buf; if (out_buf) delete [] out_buf; + fclose(fsrc); return true; } if (out_buf) delete [] out_buf; diff --git a/desmume/src/mem.h b/desmume/src/mem.h index 7cbb9ccae..c8b1f6774 100644 --- a/desmume/src/mem.h +++ b/desmume/src/mem.h @@ -122,6 +122,21 @@ static INLINE void T1WriteLong(u8* const mem, const u32 addr, const u32 val) #endif } +static INLINE void T1WriteQuad(u8* const mem, const u32 addr, const u64 val) +{ +#ifdef WORDS_BIGENDIAN + mem[addr + 7] = (val >> 56); + mem[addr + 6] = (val >> 48) & 0xFF; + mem[addr + 5] = (val >> 40) & 0xFF; + mem[addr + 4] = (val >> 32) & 0xFF; + mem[addr + 3] = (val >> 24) & 0xFF; + mem[addr + 2] = (val >> 16) & 0xFF; + mem[addr + 1] = (val >> 8) & 0xFF; + mem[addr] = val & 0xFF; +#else + *((u64 *) (mem + addr)) = val; +#endif +} //static INLINE u8 T2ReadByte(u8* const mem, const u32 addr) //{ diff --git a/desmume/src/wifi.h b/desmume/src/wifi.h index d535f01f4..e5d1a94d7 100644 --- a/desmume/src/wifi.h +++ b/desmume/src/wifi.h @@ -421,7 +421,7 @@ enum EAPStatus { APStatus_Disconnected = 0, APStatus_Authenticated, - APStatus_Associated, + APStatus_Associated }; /* wifimac_t: the buildin mac (arm7 addressrange: 0x04800000-0x04FFFFFF )*/