diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 9e1fed578..bd3a28aef 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -1280,6 +1280,63 @@ u32 MMU_struct::gen_IF() return IF; } +static void writereg_DISP3DCNT(const int size, const u32 adr, const u32 val) +{ + //UGH. rewrite this shite to use individual values and reconstruct the return value instead of packing things in this !@#)ing register + + //nanostray2 cutscene will test this vs old desmumes by using some kind of 32bit access for setting up this reg for cutscenes + switch(size) + { + case 8: + switch(adr) + { + case REG_DISPA_DISP3DCNT: + MMU.reg_DISP3DCNT_bits &= 0xFFFFFF00; + MMU.reg_DISP3DCNT_bits |= val; + gfx3d_Control(MMU.reg_DISP3DCNT_bits); + break; + case REG_DISPA_DISP3DCNT+1: + { + u32 myval = (val & ~0x30) | (~val & ((MMU.reg_DISP3DCNT_bits>>8) & 0x30)); // bits 12,13 are ack bits + myval &= 0x7F; //top bit isnt connected + MMU.reg_DISP3DCNT_bits = MMU.reg_DISP3DCNT_bits&0xFFFF00FF; + MMU.reg_DISP3DCNT_bits |= (myval<<8); + gfx3d_Control(MMU.reg_DISP3DCNT_bits); + } + break; + } + break; + case 16: + case 32: + writereg_DISP3DCNT(8,adr,val&0xFF); + writereg_DISP3DCNT(8,adr+1,(val>>8)&0xFF); + break; + } +} + +static u32 readreg_DISP3DCNT(const int size, const u32 adr) +{ + //UGH. rewrite this shite to use individual values and reconstruct the return value instead of packing things in this !@#)ing register + switch(size) + { + case 8: + switch(adr) + { + case REG_DISPA_DISP3DCNT: + return MMU.reg_DISP3DCNT_bits & 0xFF; + case REG_DISPA_DISP3DCNT+1: + return ((MMU.reg_DISP3DCNT_bits)>>8)& 0xFF; + } + break; + case 16: + case 32: + return readreg_DISP3DCNT(8,adr)|(readreg_DISP3DCNT(8,adr+1)<<8); + } + assert(false); + return 0; +} + + static u32 readreg_POWCNT1(const int size, const u32 adr) { switch(size) { @@ -2024,22 +2081,6 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) printf("%c",val); break; - case REG_DISPA_DISP3DCNT: - { - u32 &disp3dcnt = MainScreen.gpu->dispx_st->dispA_DISP3DCNT.val; - disp3dcnt = (disp3dcnt&0xFF00) | val; - gfx3d_Control(disp3dcnt); - break; - } - case REG_DISPA_DISP3DCNT+1: - { - u32 &disp3dcnt = MainScreen.gpu->dispx_st->dispA_DISP3DCNT.val; - val = (val & ~0x30) | (~val & ((disp3dcnt>>8) & 0x30)); // bits 12,13 are ack bits - disp3dcnt = (disp3dcnt&0x00FF) | (val<<8); - gfx3d_Control(disp3dcnt); - break; - } - case eng_3D_GXSTAT: MMU_new.gxstat.write(8,adr,val); break; @@ -2175,9 +2216,10 @@ void FASTCALL _MMU_ARM9_write08(u32 adr, u8 val) T1WriteByte(MMU.MMU_MEM[ARMCPU_ARM7][0x40], 0x241, val); break; - case REG_POWCNT1: - writereg_POWCNT1(8,adr,val); - break; + case REG_POWCNT1: writereg_POWCNT1(8,adr,val); break; + + case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(8,adr,val); return; + case REG_DISPA_DISP3DCNT+1: writereg_DISP3DCNT(8,adr,val); return; case REG_IF: REG_IF_WriteByte(0,val); break; case REG_IF+1: REG_IF_WriteByte(1,val); break; @@ -2317,14 +2359,7 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DISPB_BG3YL: SubScreen.gpu->setAffineStartWord(3,1,val,0); break; case REG_DISPB_BG3YH: SubScreen.gpu->setAffineStartWord(3,1,val,1); break; - case REG_DISPA_DISP3DCNT: - { - u32 &disp3dcnt = MainScreen.gpu->dispx_st->dispA_DISP3DCNT.val; - val = (val & ~0x3000) | (~val & (disp3dcnt & 0x3000)); // bits 12,13 are ack bits - disp3dcnt = val; - gfx3d_Control(val); - break; - } + case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(16,adr,val); return; // Alpha test reference value - Parameters:1 case eng_3D_ALPHA_TEST_REF: @@ -3103,6 +3138,8 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; } + case REG_DISPA_DISP3DCNT: writereg_DISP3DCNT(32,adr,val); return; + case REG_GCDATAIN: slot1_device.write32(ARMCPU_ARM9, REG_GCDATAIN,val); return; @@ -3191,6 +3228,11 @@ u8 FASTCALL _MMU_ARM9_read08(u32 adr) case eng_3D_GXSTAT: return MMU_new.gxstat.read(8,adr); + + case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(8,adr); + case REG_DISPA_DISP3DCNT+1: return readreg_DISP3DCNT(8,adr); + case REG_DISPA_DISP3DCNT+2: return readreg_DISP3DCNT(8,adr); + case REG_DISPA_DISP3DCNT+3: return readreg_DISP3DCNT(8,adr); } } @@ -3270,6 +3312,9 @@ u16 FASTCALL _MMU_ARM9_read16(u32 adr) case REG_POWCNT1+2: return readreg_POWCNT1(16,adr); + case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(16,adr); + case REG_DISPA_DISP3DCNT+2: return readreg_DISP3DCNT(16,adr); + case 0x04000130: case 0x04000136: //not sure whether these should trigger from byte reads @@ -3398,11 +3443,9 @@ u32 FASTCALL _MMU_ARM9_read32(u32 adr) return MMU.timer[ARMCPU_ARM9][(adr&0xF)>>2] | (val<<16); } - case REG_GCDATAIN: - return MMU_readFromGC(); - - case REG_POWCNT1: - return readreg_POWCNT1(32,adr); + case REG_GCDATAIN: return MMU_readFromGC(); + case REG_POWCNT1: return readreg_POWCNT1(32,adr); + case REG_DISPA_DISP3DCNT: return readreg_DISP3DCNT(32,adr); } return T1ReadLong_guaranteedAligned(MMU.MMU_MEM[ARMCPU_ARM9][adr>>20], adr & MMU.MMU_MASK[ARMCPU_ARM9][adr>>20]); } diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h index 6d9137efd..d673216cb 100644 --- a/desmume/src/MMU.h +++ b/desmume/src/MMU.h @@ -390,6 +390,8 @@ struct MMU_struct //these are the user-controlled IF bits. some IF bits are generated as necessary from hardware conditions u32 reg_IF_bits[2]; + u32 reg_DISP3DCNT_bits; + template u32 gen_IF(); BOOL divRunning; diff --git a/desmume/src/registers.h b/desmume/src/registers.h index d5cd1ad42..c6b42efb4 100644 --- a/desmume/src/registers.h +++ b/desmume/src/registers.h @@ -283,6 +283,10 @@ #define REG_DISPA_DISPCAPCNT 0x04000064 #define REG_DISPA_DISPMMEMFIFO 0x04000068 +#define REG_DISPA_DISP3DCNT_BIT_RDLINES_UNDERFLOW 0x1000 +#define REG_DISPA_DISP3DCNT_BIT_RAM_OVERFLOW 0x2000 +#define REG_DISPA_DISP3DCNT_BITS_ACK (REG_DISPA_DISP3DCNT_BIT_RDLINES_UNDERFLOW|REG_DISPA_DISP3DCNT_BIT_RAM_OVERFLOW) + #define eng_3D_RDLINES_COUNT 0x04000320 #define eng_3D_EDGE_COLOR 0x04000330 diff --git a/desmume/src/saves.cpp b/desmume/src/saves.cpp index 81e518dbd..b3fac2d25 100644 --- a/desmume/src/saves.cpp +++ b/desmume/src/saves.cpp @@ -247,6 +247,8 @@ SFORMAT SF_MMU[]={ { "PMCN", 1, 1, &MMU.powerMan_CntReg}, { "PMCW", 4, 1, &MMU.powerMan_CntRegWritten}, { "PMCR", 1, 5, &MMU.powerMan_Reg}, + + { "MR3D", 4, 1, &MMU.reg_DISP3DCNT_bits}, { 0 } }; @@ -259,7 +261,7 @@ SFORMAT SF_MOVIE[]={ static void mmu_savestate(EMUFILE* os) { - u32 version = 4; + u32 version = 5; write32le(version,os); //version 2: @@ -450,6 +452,9 @@ static bool mmu_loadstate(EMUFILE* is, int size) MMU_new.gxstat.fifo_low = gxFIFO.size <= 127; MMU_new.gxstat.fifo_empty = gxFIFO.size == 0; + if(version < 5) + MMU.reg_DISP3DCNT_bits = T1ReadWord(MMU.ARM9_REG,0x60); + return ok; }