rewrite disp3dcnt register emulation and add support for accesses of all widths. one down, one thousand to go.

This commit is contained in:
zeromus 2010-09-27 08:28:22 +00:00
parent 6a33eb0cf8
commit 2be21622ae
4 changed files with 87 additions and 33 deletions

View File

@ -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<ARMCPU_ARM9>(0,val); break;
case REG_IF+1: REG_IF_WriteByte<ARMCPU_ARM9>(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<ARMCPU_ARM9>();
case REG_POWCNT1:
return readreg_POWCNT1(32,adr);
case REG_GCDATAIN: return MMU_readFromGC<ARMCPU_ARM9>();
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]);
}

View File

@ -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<int PROCNUM> u32 gen_IF();
BOOL divRunning;

View File

@ -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

View File

@ -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;
}