diff --git a/pcsx2/Counters.cpp b/pcsx2/Counters.cpp index 8b382b4f13..749a1d46e1 100644 --- a/pcsx2/Counters.cpp +++ b/pcsx2/Counters.cpp @@ -633,7 +633,7 @@ static void _rcntSetGate( int index ) } // mode - 0 means hblank source, 8 means vblank source. -void rcntStartGate(uint mode, u32 sCycle) +void __fastcall rcntStartGate(uint mode, u32 sCycle) { int i; @@ -694,7 +694,7 @@ void rcntStartGate(uint mode, u32 sCycle) } // mode - 0 means hblank signal, 8 means vblank signal. -void rcntEndGate(uint mode, u32 sCycle) +void __fastcall rcntEndGate(uint mode, u32 sCycle) { int i; @@ -735,7 +735,7 @@ void rcntEndGate(uint mode, u32 sCycle) // rcntUpdate, since we're being called from there anyway. } -void rcntWmode(int index, u32 value) +void __fastcall rcntWmode(int index, u32 value) { if(counters[index].mode.IsCounting) { if(counters[index].mode.ClockSource != 0x3) { @@ -766,7 +766,7 @@ void rcntWmode(int index, u32 value) _rcntSet( index ); } -void rcntWcount(int index, u32 value) +void __fastcall rcntWcount(int index, u32 value) { EECNT_LOG("EE Counter[%d] writeCount = %x, oldcount=%x, target=%x\n", index, value, counters[index].count, counters[index].target ); @@ -792,7 +792,7 @@ void rcntWcount(int index, u32 value) _rcntSet( index ); } -void rcntWtarget(int index, u32 value) +void __fastcall rcntWtarget(int index, u32 value) { EECNT_LOG("EE Counter[%d] writeTarget = %x\n", index, value); @@ -808,13 +808,13 @@ void rcntWtarget(int index, u32 value) _rcntSet( index ); } -void rcntWhold(int index, u32 value) +void __fastcall rcntWhold(int index, u32 value) { EECNT_LOG("EE Counter[%d] Hold Write = %x\n", index, value); counters[index].hold = value; } -u32 rcntRcount(int index) +u32 __fastcall rcntRcount(int index) { u32 ret; @@ -828,7 +828,7 @@ u32 rcntRcount(int index) return ret; } -u32 rcntCycle(int index) +u32 __fastcall rcntCycle(int index) { if (counters[index].mode.IsCounting && (counters[index].mode.ClockSource != 0x3)) return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate); diff --git a/pcsx2/Counters.h b/pcsx2/Counters.h index 17a483a947..2b9b815d9c 100644 --- a/pcsx2/Counters.h +++ b/pcsx2/Counters.h @@ -132,15 +132,15 @@ extern void rcntUpdate_hScanline(); extern bool rcntUpdate_vSync(); extern bool rcntUpdate(); -void rcntInit(); -void rcntStartGate(unsigned int mode, u32 sCycle); -void rcntEndGate(unsigned int mode, u32 sCycle); -void rcntWcount(int index, u32 value); -void rcntWmode(int index, u32 value); -void rcntWtarget(int index, u32 value); -void rcntWhold(int index, u32 value); -u32 rcntRcount(int index); -u32 rcntCycle(int index); +extern void rcntInit(); +extern void __fastcall rcntStartGate(unsigned int mode, u32 sCycle); +extern void __fastcall rcntEndGate(unsigned int mode, u32 sCycle); +extern void __fastcall rcntWcount(int index, u32 value); +extern void __fastcall rcntWmode(int index, u32 value); +extern void __fastcall rcntWtarget(int index, u32 value); +extern void __fastcall rcntWhold(int index, u32 value); +extern u32 __fastcall rcntRcount(int index); +extern u32 __fastcall rcntCycle(int index); u32 UpdateVSyncRate(); void frameLimitReset(); diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 28f3b9d953..96f3ac50b3 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -146,11 +146,49 @@ __forceinline u16 hwRead16(u32 mem) HW_LOG("Hardware Read16 at 0x%x, value= 0x%x\n", ret, mem); break; } - return ret; } -__forceinline u32 hwRead32(u32 mem) +// Reads hardware registers for page 0 (counters 0 and 1) +mem32_t __fastcall hwRead32_page_00(u32 mem) +{ + mem &= 0xffff; + switch( mem ) + { + case 0x00: return (u16)rcntRcount(0); + case 0x10: return (u16)counters[0].modeval; + case 0x20: return (u16)counters[0].target; + case 0x30: return (u16)counters[0].hold; + + case 0x800: return (u16)rcntRcount(1); + case 0x810: return (u16)counters[1].modeval; + case 0x820: return (u16)counters[1].target; + case 0x830: return (u16)counters[1].hold; + } + + return *((u32*)&PS2MEM_HW[mem]); +} + +// Reads hardware registers for page 1 (counters 2 and 3) +mem32_t __fastcall hwRead32_page_01(u32 mem) +{ + mem &= 0xffff; + switch( mem ) + { + case 0x1000: return (u16)rcntRcount(2); + case 0x1010: return (u16)counters[2].modeval; + case 0x1020: return (u16)counters[2].target; + + case 0x1800: return (u16)rcntRcount(3); + case 0x1810: return (u16)counters[3].modeval; + case 0x1820: return (u16)counters[3].target; + } + + return *((u32*)&PS2MEM_HW[mem]); +} + +// Reads hardware registers for page 15 (0x0F). +mem32_t __fastcall hwRead32_page_0F(u32 mem) { // *Performance Warning* This function is called -A-LOT. Be weary when making changes. It // could impact FPS significantly. @@ -160,113 +198,79 @@ __forceinline u32 hwRead32(u32 mem) // vsynch timers. INTC_STAT has the disadvantage of being in the 0x1000f000 case, which has // a lot of additional registers in it, and combined with it's call frequency is a bad thing. - if(mem == INTC_STAT) + mem &= 0xffff; + + /*if(mem == (INTC_STAT & 0xffff) ) { // This one is checked alot, so leave it commented out unless you love 600 meg logfiles. //HW_LOG("DMAC_STAT Read 32bit %x\n", psHu32(0xe010)); return psHu32(INTC_STAT); + }*/ + + switch( mem ) + { + case 0xf000: + // This one is checked alot, so leave it commented out unless you love 600 meg logfiles. + //HW_LOG("DMAC_STAT Read 32bit %x\n", psHu32(0xe010)); + break; + + case 0xf010: + HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK)); + break; + + case 0xf130: // 0x1000f130 + case 0xf260: // 0x1000f260 SBUS? + case 0xf410: // 0x1000f410 + case 0xf430: // MCH_RICM + return 0; + + case 0xf240: // 0x1000f240: SBUS + return psHu32(0xf240) | 0xF0000102; + + case 0xf440: // 0x1000f440: MCH_DRD + + if( !((psHu32(0xf430) >> 6) & 0xF) ) + { + switch ((psHu32(0xf430)>>16) & 0xFFF) + { + //MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + + case 0x21://INIT + if(rdram_sdevid < rdram_devices) + { + rdram_sdevid++; + return 0x1F; + } + return 0; + + case 0x23://CNFGA + return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5 + + case 0x24://CNFGB + //0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0 + return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0 + + case 0x40://DEVID + return psHu32(0xf430) & 0x1F; // =SDEV + } + } + return 0; } + return *((u32*)&PS2MEM_HW[mem]); +} +mem32_t __fastcall hwRead32_page_02(u32 mem) +{ + return ipuRead32( mem ); +} + +// Used for all pages not explicitly specified above. +mem32_t __fastcall hwRead32_page_other(u32 mem) +{ const u16 masked_mem = mem & 0xffff; - // We optimize the hw register reads by breaking them into manageable 4k chunks (for a total of - // 16 cases spanning the 64k PS2 hw register memory map). It helps also that the EE is, for - // the most part, designed so that various classes of registers are sectioned off into these - // 4k segments. - - // Notes: Breaks from the switch statement will return a standard hw memory read. - // Special case handling of reads should use "return" directly. - switch( masked_mem>>12 ) // switch out as according to the 4k page of the access. { - // Counters Registers - // This code uses some optimized trickery to produce more compact output. - // See below for the "reference" block to get a better idea what this code does. :) - - case 0x0: // counters 0 and 1 - case 0x1: // counters 2 and 3 - { - const uint cntidx = masked_mem >> 11; // neat trick to scale the counter HW address into 0-3 range. - switch( (masked_mem>>4) & 0xf ) - { - case 0x0: return (u16)rcntRcount(cntidx); - case 0x1: return (u16)counters[cntidx].modeval; - case 0x2: return (u16)counters[cntidx].target; - case 0x3: return (u16)counters[cntidx].hold; - } - } - -#if 0 // Counters Reference Block (original case setup) - case 0x10000000: return (u16)rcntRcount(0); - case 0x10000010: return (u16)counters[0].modeval; - case 0x10000020: return (u16)counters[0].target; - case 0x10000030: return (u16)counters[0].hold; - - case 0x10000800: return (u16)rcntRcount(1); - case 0x10000810: return (u16)counters[1].modeval; - case 0x10000820: return (u16)counters[1].target; - case 0x10000830: return (u16)counters[1].hold; - - case 0x10001000: return (u16)rcntRcount(2); - case 0x10001010: return (u16)counters[2].modeval; - case 0x10001020: return (u16)counters[2].target; - - case 0x10001800: return (u16)rcntRcount(3); - case 0x10001810: return (u16)counters[3].modeval; - case 0x10001820: return (u16)counters[3].target; -#endif - - break; - - case 0x2: return ipuRead32( mem ); - - case 0xf: - switch( (masked_mem >> 4) & 0xff ) - { - case 0x01: - HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK)); - break; - - case 0x13: // 0x1000f130 - case 0x26: // 0x1000f260 SBUS? - case 0x41: // 0x1000f410 - case 0x43: // MCH_RICM - return 0; - - case 0x24: // 0x1000f240: SBUS - return psHu32(0xf240) | 0xF0000102; - - case 0x44: // 0x1000f440: MCH_DRD - - if( !((psHu32(0xf430) >> 6) & 0xF) ) - { - switch ((psHu32(0xf430)>>16) & 0xFFF) - { - //MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 - - case 0x21://INIT - if(rdram_sdevid < rdram_devices) - { - rdram_sdevid++; - return 0x1F; - } - return 0; - - case 0x23://CNFGA - return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5 - - case 0x24://CNFGB - //0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0 - return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0 - - case 0x40://DEVID - return psHu32(0xf430) & 0x1F; // =SDEV - } - } - return 0; - } - break; - /////////////////////////////////////////////////////// // Most of the following case handlers are for developer builds only (logging). // It'll all optimize to ziltch in public release builds. @@ -312,10 +316,6 @@ __forceinline u32 hwRead32(u32 mem) jNO_DEFAULT; } - // Optimization note: We masked 'mem' earlier, so it's safe to access PS2MEM_HW directly. - // (checked disasm, and MSVC 2008 fails to optimize it on its own) - - //return psHu32(mem); return *((u32*)&PS2MEM_HW[masked_mem]); } @@ -527,7 +527,6 @@ __forceinline void hwWrite16(u32 mem, u16 value) DmaExec16(dmaVIF0, mem, value); break; -// Latest Fix for Florin by asadr (VIF1) case 0x10009000: // dma1 - vif1 - chcr DMA_LOG("VIF1dma CHCR %lx\n", value); DmaExec16(dmaVIF1, mem, value); @@ -715,58 +714,76 @@ __forceinline void hwWrite16(u32 mem, u16 value) break; default: -#ifndef PCSX2_VIRTUAL_MEM - if (mem < 0x10010000) -#endif - { - psHu16(mem) = value; - } + psHu16(mem) = value; HW_LOG("Unknown Hardware write 16 at %x with value %x\n",mem,value); } } +// Page 0 of HW mwmory houses registers for Counters 0 and 1 +void __fastcall hwWrite32_page_00( u32 mem, u32 value ) +{ + mem &= 0xffff; + switch (mem) + { + case 0x000: rcntWcount(0, value); return; + case 0x010: rcntWmode(0, value); return; + case 0x020: rcntWtarget(0, value); return; + case 0x030: rcntWhold(0, value); return; -__forceinline void hwWrite32(u32 mem, u32 value) { + case 0x800: rcntWcount(1, value); return; + case 0x810: rcntWmode(1, value); return; + case 0x820: rcntWtarget(1, value); return; + case 0x830: rcntWhold(1, value); return; + } - if ((mem>=0x10002000) && (mem<0x10003000)) { //IPU regs - ipuWrite32(mem,value); - return; + *((u32*)&PS2MEM_HW[mem]) = value; +} + +// Page 1 of HW mwmory houses registers for Counters 2 and 3 +void __fastcall hwWrite32_page_01( u32 mem, u32 value ) +{ + mem &= 0xffff; + switch (mem) + { + case 0x1000: rcntWcount(2, value); return; + case 0x1010: rcntWmode(2, value); return; + case 0x1020: rcntWtarget(2, value); return; + + case 0x1800: rcntWcount(3, value); return; + case 0x1810: rcntWmode(3, value); return; + case 0x1820: rcntWtarget(3, value); return; } - if ((mem>=0x10003800) && (mem<0x10003c00)) { - vif0Write32(mem, value); - return; - } - if ((mem>=0x10003c00) && (mem<0x10004000)) { - vif1Write32(mem, value); + + *((u32*)&PS2MEM_HW[mem]) = value; +} + +// page 2 is the IPU register space! +void __fastcall hwWrite32_page_02( u32 mem, u32 value ) +{ + ipuWrite32(mem, value); +} + +// Page 3 contains writes to vif0 and vif1 registers, plus some GIF stuff! +void __fastcall hwWrite32_page_03( u32 mem, u32 value ) +{ + if(mem>=0x10003800) + { + if(mem<0x10003c00) + vif0Write32(mem, value); + else + vif1Write32(mem, value); return; } - switch (mem) { - case 0x10000000: rcntWcount(0, value); break; - case 0x10000010: rcntWmode(0, value); break; - case 0x10000020: rcntWtarget(0, value); break; - case 0x10000030: rcntWhold(0, value); break; - - case 0x10000800: rcntWcount(1, value); break; - case 0x10000810: rcntWmode(1, value); break; - case 0x10000820: rcntWtarget(1, value); break; - case 0x10000830: rcntWhold(1, value); break; - - case 0x10001000: rcntWcount(2, value); break; - case 0x10001010: rcntWmode(2, value); break; - case 0x10001020: rcntWtarget(2, value); break; - - case 0x10001800: rcntWcount(3, value); break; - case 0x10001810: rcntWmode(3, value); break; - case 0x10001820: rcntWtarget(3, value); break; - + switch (mem) + { case GIF_CTRL: //SysPrintf("GIF_CTRL write %x\n", value); psHu32(mem) = value & 0x8; if (value & 0x1) gsGIFReset(); else if( value & 8 ) psHu32(GIF_STAT) |= 8; else psHu32(GIF_STAT) &= ~8; - return; + break; case GIF_MODE: // need to set GIF_MODE (hamster ball) @@ -775,240 +792,210 @@ __forceinline void hwWrite32(u32 mem, u32 value) { else psHu32(GIF_STAT)&= ~0x1; if (value & 0x4) psHu32(GIF_STAT)|= 0x4; else psHu32(GIF_STAT)&= ~0x4; - break; + break; case GIF_STAT: // stat is readonly - SysPrintf("Gifstat write value = %x\n", value); - return; + DevCon::Notice("*PCSX2* Gifstat write value = 0x%x\n", params value); + break; - case 0x10008000: // dma0 - vif0 - DMA_LOG("VIF0dma %lx\n", value); - DmaExec(dmaVIF0, mem, value); - break; -//------------------------------------------------------------------ - case 0x10009000: // dma1 - vif1 - chcr - DMA_LOG("VIF1dma CHCR %lx\n", value); - DmaExec(dmaVIF1, mem, value); - break; -#ifdef PCSX2_DEVBUILD - case 0x10009010: // dma1 - vif1 - madr - HW_LOG("VIF1dma Madr %lx\n", value); - psHu32(mem) = value;//dma1 madr - break; - case 0x10009020: // dma1 - vif1 - qwc - HW_LOG("VIF1dma QWC %lx\n", value); - psHu32(mem) = value;//dma1 qwc - break; - case 0x10009030: // dma1 - vif1 - tadr - HW_LOG("VIF1dma TADR %lx\n", value); - psHu32(mem) = value;//dma1 tadr - break; - case 0x10009040: // dma1 - vif1 - asr0 - HW_LOG("VIF1dma ASR0 %lx\n", value); - psHu32(mem) = value;//dma1 asr0 - break; - case 0x10009050: // dma1 - vif1 - asr1 - HW_LOG("VIF1dma ASR1 %lx\n", value); - psHu32(mem) = value;//dma1 asr1 - break; - case 0x10009080: // dma1 - vif1 - sadr - HW_LOG("VIF1dma SADR %lx\n", value); - psHu32(mem) = value;//dma1 sadr - break; -#endif -//------------------------------------------------------------------ - case 0x1000a000: // dma2 - gif - DMA_LOG("0x%8.8x hwWrite32: GSdma %lx\n", cpuRegs.cycle, value); - DmaExec(dmaGIF, mem, value); - break; -#ifdef PCSX2_DEVBUILD - case 0x1000a010: - psHu32(mem) = value;//dma2 madr - HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x\n",mem,value); - break; - case 0x1000a020: - psHu32(mem) = value;//dma2 qwc - HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x\n",mem,value); - break; - case 0x1000a030: - psHu32(mem) = value;//dma2 taddr - HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x\n",mem,value); - break; - case 0x1000a040: - psHu32(mem) = value;//dma2 asr0 - HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x\n",mem,value); - break; - case 0x1000a050: - psHu32(mem) = value;//dma2 asr1 - HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x\n",mem,value); - break; - case 0x1000a080: - psHu32(mem) = value;//dma2 saddr - HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x\n",mem,value); - break; -#endif -//------------------------------------------------------------------ - case 0x1000b000: // dma3 - fromIPU - DMA_LOG("IPU0dma %lx\n", value); + default: + psHu32(mem) = value; + } +} + +void __fastcall hwWrite32_page_0B( u32 mem, u32 value ) +{ + // Used for developer logging -- optimized away in Public Release. + const char* regName = "Unknown"; + + switch( mem ) + { + case D3_CHCR: // dma3 - fromIPU + DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value); DmaExec(dmaIPU0, mem, value); - break; -//------------------------------------------------------------------ -#ifdef PCSX2_DEVBUILD - case 0x1000b010: - psHu32(mem) = value;//dma2 madr - HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x\n",mem,value); - break; - case 0x1000b020: - psHu32(mem) = value;//dma2 madr - HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x\n",mem,value); - break; - case 0x1000b030: - psHu32(mem) = value;//dma2 tadr - HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x\n",mem,value); - break; - case 0x1000b080: - psHu32(mem) = value;//dma2 saddr - HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x\n",mem,value); - break; -#endif -//------------------------------------------------------------------ - case 0x1000b400: // dma4 - toIPU - DMA_LOG("IPU1dma %lx\n", value); + return; + + case D3_MADR: regName = "IPU0DMA_MADR"; break; + case D3_QWC: regName = "IPU0DMA_QWC"; break; + case D3_TADR: regName = "IPU0DMA_TADR"; break; + case D3_SADR: regName = "IPU0DMA_SADDR"; break; + + //------------------------------------------------------------------ + + case D4_CHCR: // dma4 - toIPU + DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value); DmaExec(dmaIPU1, mem, value); - break; -//------------------------------------------------------------------ -#ifdef PCSX2_DEVBUILD - case 0x1000b410: - psHu32(mem) = value;//dma2 madr - HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x\n",mem,value); - break; - case 0x1000b420: - psHu32(mem) = value;//dma2 madr - HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x\n",mem,value); - break; - case 0x1000b430: - psHu32(mem) = value;//dma2 tadr - HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x\n",mem,value); - break; - case 0x1000b480: - psHu32(mem) = value;//dma2 saddr - HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x\n",mem,value); - break; -#endif -//------------------------------------------------------------------ - case 0x1000c000: // dma5 - sif0 - DMA_LOG("SIF0dma %lx\n", value); - //if (value == 0) psxSu32(0x30) = 0x40000; - DmaExec(dmaSIF0, mem, value); - break; -//------------------------------------------------------------------ - case 0x1000c400: // dma6 - sif1 - DMA_LOG("SIF1dma %lx\n", value); - DmaExec(dmaSIF1, mem, value); - break; -#ifdef PCSX2_DEVBUILD - case 0x1000c420: // dma6 - sif1 - qwc - HW_LOG("SIF1dma QWC = %lx\n", value); - psHu32(mem) = value; - break; - case 0x1000c430: // dma6 - sif1 - tadr - HW_LOG("SIF1dma TADR = %lx\n", value); - psHu32(mem) = value; - break; -#endif -//------------------------------------------------------------------ - case 0x1000c800: // dma7 - sif2 - DMA_LOG("SIF2dma %lx\n", value); - DmaExec(dmaSIF2, mem, value); - break; -//------------------------------------------------------------------ - case 0x1000d000: // dma8 - fromSPR - DMA_LOG("fromSPRdma %lx\n", value); - DmaExec(dmaSPR0, mem, value); - break; -//------------------------------------------------------------------ - case 0x1000d400: // dma9 - toSPR - DMA_LOG("toSPRdma %lx\n", value); - DmaExec(dmaSPR1, mem, value); - break; -//------------------------------------------------------------------ - case 0x1000e000: // DMAC_CTRL - HW_LOG("DMAC_CTRL Write 32bit %x\n", value); - psHu32(0xe000) = value; - break; + return; - case 0x1000e010: // DMAC_STAT - HW_LOG("DMAC_STAT Write 32bit %x\n", value); - psHu16(0xe010)&= ~(value & 0xffff); // clear on 1 - psHu16(0xe012) ^= (u16)(value >> 16); + case D4_MADR: regName = "IPU1DMA_MADR"; break; + case D4_QWC: regName = "IPU1DMA_QWC"; break; + case D4_TADR: regName = "IPU1DMA_TADR"; break; + case D4_SADR: regName = "IPU1DMA_SADDR"; break; + } - cpuTestDMACInts(); - break; -//------------------------------------------------------------------ - case 0x1000f000: // INTC_STAT + HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x\n", mem, regName, value ); + psHu32(mem) = value; +} + +void __fastcall hwWrite32_page_0E( u32 mem, u32 value ) +{ + if( mem == DMAC_CTRL ) + { + HW_LOG("DMAC_CTRL Write 32bit %x\n", value); + } + else if( mem == DMAC_STAT ) + { + HW_LOG("DMAC_STAT Write 32bit %x\n", value); + psHu16(0xe010)&= ~(value & 0xffff); // clear on 1 + psHu16(0xe012) ^= (u16)(value >> 16); + + cpuTestDMACInts(); + return; + } + + psHu32(mem) = value; +} + +void __fastcall hwWrite32_page_0F( u32 mem, u32 value ) +{ + // Shift the middle 8 bits (bits 4-12) into the lower 8 bits. + // This helps the compiler optimize the switch statement into a lookup table. :) + +#define HELPSWITCH(m) (((m)>>4) & 0xff) + + switch( HELPSWITCH(mem) ) + { + case HELPSWITCH(INTC_STAT): HW_LOG("INTC_STAT Write 32bit %x\n", value); - psHu32(0xf000)&=~value; + psHu32(INTC_STAT) &= ~value; //cpuTestINTCInts(); break; - case 0x1000f010: // INTC_MASK + case HELPSWITCH(INTC_MASK): HW_LOG("INTC_MASK Write 32bit %x\n", value); - psHu32(0xf010) ^= (u16)value; + psHu32(INTC_MASK) ^= (u16)value; cpuTestINTCInts(); break; -//------------------------------------------------------------------ - case 0x1000f430://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + + //------------------------------------------------------------------ + case HELPSWITCH(0x1000f430)://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0 rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid psHu32(mem) = value & ~0x80000000; //kill the busy bit break; - case 0x1000f440://MCH_DRD: + case HELPSWITCH(0x1000f440)://MCH_DRD: psHu32(mem) = value; break; -//------------------------------------------------------------------ - case 0x1000f590: // DMAC_ENABLEW + //------------------------------------------------------------------ + case HELPSWITCH(0x1000f590): // DMAC_ENABLEW HW_LOG("DMAC_ENABLEW Write 32bit %lx\n", value); psHu32(0xf590) = value; psHu32(0xf520) = value; - return; -//------------------------------------------------------------------ - case 0x1000f200: + break; + //------------------------------------------------------------------ + case HELPSWITCH(0x1000f200): psHu32(mem) = value; break; - case 0x1000f220: + case HELPSWITCH(0x1000f220): psHu32(mem) |= value; break; - case 0x1000f230: + case HELPSWITCH(0x1000f230): psHu32(mem) &= ~value; break; - case 0x1000f240: + case HELPSWITCH(0x1000f240): if(!(value & 0x100)) psHu32(mem) &= ~0x100; else psHu32(mem) |= 0x100; break; - case 0x1000f260: + case HELPSWITCH(0x1000f260): psHu32(mem) = 0; break; -//------------------------------------------------------------------ - case 0x1000f130: - case 0x1000f410: + //------------------------------------------------------------------ + case HELPSWITCH(0x1000f130): + case HELPSWITCH(0x1000f410): HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); break; -//------------------------------------------------------------------ + default: -#ifndef PCSX2_VIRTUAL_MEM - if (mem < 0x10010000) -#endif - { - psHu32(mem) = value; - } - HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); - break; + psHu32(mem) = value; } } +void __fastcall hwWrite32_page_other( u32 mem, u32 value ) +{ + // Used for developer logging -- optimized away in Public Release. + const char* regName = "Unknown"; + + switch (mem) + { + case D0_CHCR: // dma0 - vif0 + DMA_LOG("VIF0dma EXECUTE, value=0x%x\n", value); + DmaExec(dmaVIF0, mem, value); + return; + +//------------------------------------------------------------------ + case D1_CHCR: // dma1 - vif1 - chcr + DMA_LOG("VIF1dma EXECUTE, value=0x%x\n", value); + DmaExec(dmaVIF1, mem, value); + return; + + case D1_MADR: regName = "VIF1dma MADR"; break; + case D1_QWC: regName = "VIF1dma QWC"; break; + case D1_TADR: regName = "VIF1dma TADR"; break; + case D1_ASR0: regName = "VIF1dma ASR0"; break; + case D1_ASR1: regName = "VIF1dma ASR1"; break; + case D1_SADR: regName = "VIF1dma SADR"; break; + +//------------------------------------------------------------------ + case D2_CHCR: // dma2 - gif + DMA_LOG("GIFdma EXECUTE, value=0x%x", value); + DmaExec(dmaGIF, mem, value); + return; + + case D2_MADR: regName = "GIFdma MADR"; break; + case D2_QWC: regName = "GIFdma QWC"; break; + case D2_TADR: regName = "GIFdma TADDR"; break; + case D2_ASR0: regName = "GIFdma ASR0"; break; + case D2_ASR1: regName = "GIFdma ASR1"; break; + case D2_SADR: regName = "GIFdma SADDR"; break; + +//------------------------------------------------------------------ + case 0x1000c000: // dma5 - sif0 + DMA_LOG("SIF0dma EXECUTE, value=0x%x\n", value); + //if (value == 0) psxSu32(0x30) = 0x40000; + DmaExec(dmaSIF0, mem, value); + return; +//------------------------------------------------------------------ + case 0x1000c400: // dma6 - sif1 + DMA_LOG("SIF1dma EXECUTE, value=0x%x\n", value); + DmaExec(dmaSIF1, mem, value); + return; + + case 0x1000c420: regName = "SIF1dma QWC"; break; + case 0x1000c430: regName = "SIF1dma TADR"; break; + +//------------------------------------------------------------------ + case 0x1000c800: // dma7 - sif2 + DMA_LOG("SIF2dma EXECUTE, value=0x%x\n", value); + DmaExec(dmaSIF2, mem, value); + return; +//------------------------------------------------------------------ + case 0x1000d000: // dma8 - fromSPR + DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x\n", value); + DmaExec(dmaSPR0, mem, value); + return; +//------------------------------------------------------------------ + case 0x1000d400: // dma9 - toSPR + DMA_LOG("SPR0dma EXECUTE (toSPR), value=0x%x\n", value); + DmaExec(dmaSPR1, mem, value); + return; + } + HW_LOG( "Hardware Write32 at 0x%x (%s), value=0x%x\n", mem, regName, value ); + psHu32(mem) = value; +} + __forceinline void hwWrite64(u32 mem, u64 value) { u32 val32; int i; @@ -1328,3 +1315,460 @@ int hwDmacSrcChain(DMACh *dma, int id) { return -1; } + +// Original hwRead/Write32 functions .. left in for now, for troubleshooting purposes. +#if 1 +mem32_t __fastcall hwRead32(u32 mem) +{ + // *Performance Warning* This function is called -A-LOT. Be weary when making changes. It + // could impact FPS significantly. + + // Optimization Note: + // Shortcut for the INTC_STAT register, which is checked *very* frequently as part of the EE's + // vsynch timers. INTC_STAT has the disadvantage of being in the 0x1000f000 case, which has + // a lot of additional registers in it, and combined with it's call frequency is a bad thing. + + if(mem == INTC_STAT) + { + // This one is checked alot, so leave it commented out unless you love 600 meg logfiles. + //HW_LOG("DMAC_STAT Read 32bit %x\n", psHu32(0xe010)); + return psHu32(INTC_STAT); + } + + const u16 masked_mem = mem & 0xffff; + + // We optimize the hw register reads by breaking them into manageable 4k chunks (for a total of + // 16 cases spanning the 64k PS2 hw register memory map). It helps also that the EE is, for + // the most part, designed so that various classes of registers are sectioned off into these + // 4k segments. + + // Notes: Breaks from the switch statement will return a standard hw memory read. + // Special case handling of reads should use "return" directly. + + switch( masked_mem>>12 ) // switch out as according to the 4k page of the access. + { + // Counters Registers + // This code uses some optimized trickery to produce more compact output. + // See below for the "reference" block to get a better idea what this code does. :) + + case 0x0: // counters 0 and 1 + case 0x1: // counters 2 and 3 + { + const uint cntidx = masked_mem >> 11; // neat trick to scale the counter HW address into 0-3 range. + switch( (masked_mem>>4) & 0xf ) + { + case 0x0: return (u16)rcntRcount(cntidx); + case 0x1: return (u16)counters[cntidx].modeval; + case 0x2: return (u16)counters[cntidx].target; + case 0x3: return (u16)counters[cntidx].hold; + } + } + +#if 0 // Counters Reference Block (original case setup) + case 0x10000000: return (u16)rcntRcount(0); + case 0x10000010: return (u16)counters[0].modeval; + case 0x10000020: return (u16)counters[0].target; + case 0x10000030: return (u16)counters[0].hold; + + case 0x10000800: return (u16)rcntRcount(1); + case 0x10000810: return (u16)counters[1].modeval; + case 0x10000820: return (u16)counters[1].target; + case 0x10000830: return (u16)counters[1].hold; + + case 0x10001000: return (u16)rcntRcount(2); + case 0x10001010: return (u16)counters[2].modeval; + case 0x10001020: return (u16)counters[2].target; + + case 0x10001800: return (u16)rcntRcount(3); + case 0x10001810: return (u16)counters[3].modeval; + case 0x10001820: return (u16)counters[3].target; +#endif + + break; + + case 0x2: return ipuRead32( mem ); + + case 0xf: + switch( (masked_mem >> 4) & 0xff ) + { + case 0x01: + HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK)); + break; + + case 0x13: // 0x1000f130 + case 0x26: // 0x1000f260 SBUS? + case 0x41: // 0x1000f410 + case 0x43: // MCH_RICM + return 0; + + case 0x24: // 0x1000f240: SBUS + return psHu32(0xf240) | 0xF0000102; + + case 0x44: // 0x1000f440: MCH_DRD + + if( !((psHu32(0xf430) >> 6) & 0xF) ) + { + switch ((psHu32(0xf430)>>16) & 0xFFF) + { + //MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + + case 0x21://INIT + if(rdram_sdevid < rdram_devices) + { + rdram_sdevid++; + return 0x1F; + } + return 0; + + case 0x23://CNFGA + return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5 + + case 0x24://CNFGB + //0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0 + return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0 + + case 0x40://DEVID + return psHu32(0xf430) & 0x1F; // =SDEV + } + } + return 0; + } + break; + + /////////////////////////////////////////////////////// + // Most of the following case handlers are for developer builds only (logging). + // It'll all optimize to ziltch in public release builds. + + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x0a: + { + const char* regName = "Unknown"; + + switch( mem ) + { + case D2_CHCR: regName = "DMA2_CHCR"; break; + case D2_MADR: regName = "DMA2_MADR"; break; + case D2_QWC: regName = "DMA2_QWC"; break; + case D2_TADR: regName = "DMA2_TADDR"; break; + case D2_ASR0: regName = "DMA2_ASR0"; break; + case D2_ASR1: regName = "DMA2_ASR1"; break; + case D2_SADR: regName = "DMA2_SADDR"; break; + } + + HW_LOG( "Hardware Read32 at 0x%x (%s), value=0x%x\n", regName, mem, psHu32(mem) ); + } + break; + + case 0x0b: + if( mem == D4_CHCR ) + HW_LOG("Hardware Read32 at 0x%x (IPU1:DMA4_CHCR), value=0x%x\n", mem, psHu32(mem)); + break; + + case 0x0c: + case 0x0d: + case 0x0e: + if( mem == DMAC_STAT ) + HW_LOG("DMAC_STAT Read32, value=0x%x\n", psHu32(DMAC_STAT)); + break; + + jNO_DEFAULT; + } + + // Optimization note: We masked 'mem' earlier, so it's safe to access PS2MEM_HW directly. + // (checked disasm, and MSVC 2008 fails to optimize it on its own) + + //return psHu32(mem); + return *((u32*)&PS2MEM_HW[masked_mem]); +} + + +__forceinline void __fastcall hwWrite32(u32 mem, u32 value) +{ + + if ((mem>=0x10002000) && (mem<0x10003000)) { //IPU regs + ipuWrite32(mem,value); + return; + } + if ((mem>=0x10003800) && (mem<0x10003c00)) { + vif0Write32(mem, value); + return; + } + if ((mem>=0x10003c00) && (mem<0x10004000)) { + vif1Write32(mem, value); + return; + } + + switch (mem) { + case 0x10000000: rcntWcount(0, value); break; + case 0x10000010: rcntWmode(0, value); break; + case 0x10000020: rcntWtarget(0, value); break; + case 0x10000030: rcntWhold(0, value); break; + + case 0x10000800: rcntWcount(1, value); break; + case 0x10000810: rcntWmode(1, value); break; + case 0x10000820: rcntWtarget(1, value); break; + case 0x10000830: rcntWhold(1, value); break; + + case 0x10001000: rcntWcount(2, value); break; + case 0x10001010: rcntWmode(2, value); break; + case 0x10001020: rcntWtarget(2, value); break; + + case 0x10001800: rcntWcount(3, value); break; + case 0x10001810: rcntWmode(3, value); break; + case 0x10001820: rcntWtarget(3, value); break; + + case GIF_CTRL: + //SysPrintf("GIF_CTRL write %x\n", value); + psHu32(mem) = value & 0x8; + if (value & 0x1) gsGIFReset(); + else if( value & 8 ) psHu32(GIF_STAT) |= 8; + else psHu32(GIF_STAT) &= ~8; + return; + + case GIF_MODE: + // need to set GIF_MODE (hamster ball) + psHu32(GIF_MODE) = value; + if (value & 0x1) psHu32(GIF_STAT)|= 0x1; + else psHu32(GIF_STAT)&= ~0x1; + if (value & 0x4) psHu32(GIF_STAT)|= 0x4; + else psHu32(GIF_STAT)&= ~0x4; + break; + + case GIF_STAT: // stat is readonly + SysPrintf("Gifstat write value = %x\n", value); + return; + + case 0x10008000: // dma0 - vif0 + DMA_LOG("VIF0dma %lx\n", value); + DmaExec(dmaVIF0, mem, value); + break; +//------------------------------------------------------------------ + case 0x10009000: // dma1 - vif1 - chcr + DMA_LOG("VIF1dma CHCR %lx\n", value); + DmaExec(dmaVIF1, mem, value); + break; +#ifdef PCSX2_DEVBUILD + case 0x10009010: // dma1 - vif1 - madr + HW_LOG("VIF1dma Madr %lx\n", value); + psHu32(mem) = value;//dma1 madr + break; + case 0x10009020: // dma1 - vif1 - qwc + HW_LOG("VIF1dma QWC %lx\n", value); + psHu32(mem) = value;//dma1 qwc + break; + case 0x10009030: // dma1 - vif1 - tadr + HW_LOG("VIF1dma TADR %lx\n", value); + psHu32(mem) = value;//dma1 tadr + break; + case 0x10009040: // dma1 - vif1 - asr0 + HW_LOG("VIF1dma ASR0 %lx\n", value); + psHu32(mem) = value;//dma1 asr0 + break; + case 0x10009050: // dma1 - vif1 - asr1 + HW_LOG("VIF1dma ASR1 %lx\n", value); + psHu32(mem) = value;//dma1 asr1 + break; + case 0x10009080: // dma1 - vif1 - sadr + HW_LOG("VIF1dma SADR %lx\n", value); + psHu32(mem) = value;//dma1 sadr + break; +#endif +//------------------------------------------------------------------ + case 0x1000a000: // dma2 - gif + DMA_LOG("0x%8.8x hwWrite32: GSdma %lx\n", cpuRegs.cycle, value); + DmaExec(dmaGIF, mem, value); + break; +#ifdef PCSX2_DEVBUILD + case 0x1000a010: + psHu32(mem) = value;//dma2 madr + HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x\n",mem,value); + break; + case 0x1000a020: + psHu32(mem) = value;//dma2 qwc + HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x\n",mem,value); + break; + case 0x1000a030: + psHu32(mem) = value;//dma2 taddr + HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x\n",mem,value); + break; + case 0x1000a040: + psHu32(mem) = value;//dma2 asr0 + HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x\n",mem,value); + break; + case 0x1000a050: + psHu32(mem) = value;//dma2 asr1 + HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x\n",mem,value); + break; + case 0x1000a080: + psHu32(mem) = value;//dma2 saddr + HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x\n",mem,value); + break; +#endif +//------------------------------------------------------------------ + case 0x1000b000: // dma3 - fromIPU + DMA_LOG("IPU0dma %lx\n", value); + DmaExec(dmaIPU0, mem, value); + break; +//------------------------------------------------------------------ +#ifdef PCSX2_DEVBUILD + case 0x1000b010: + psHu32(mem) = value;//dma2 madr + HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x\n",mem,value); + break; + case 0x1000b020: + psHu32(mem) = value;//dma2 madr + HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x\n",mem,value); + break; + case 0x1000b030: + psHu32(mem) = value;//dma2 tadr + HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x\n",mem,value); + break; + case 0x1000b080: + psHu32(mem) = value;//dma2 saddr + HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x\n",mem,value); + break; +#endif +//------------------------------------------------------------------ + case 0x1000b400: // dma4 - toIPU + DMA_LOG("IPU1dma %lx\n", value); + DmaExec(dmaIPU1, mem, value); + break; +//------------------------------------------------------------------ +#ifdef PCSX2_DEVBUILD + case 0x1000b410: + psHu32(mem) = value;//dma2 madr + HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x\n",mem,value); + break; + case 0x1000b420: + psHu32(mem) = value;//dma2 madr + HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x\n",mem,value); + break; + case 0x1000b430: + psHu32(mem) = value;//dma2 tadr + HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x\n",mem,value); + break; + case 0x1000b480: + psHu32(mem) = value;//dma2 saddr + HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x\n",mem,value); + break; +#endif +//------------------------------------------------------------------ + case 0x1000c000: // dma5 - sif0 + DMA_LOG("SIF0dma %lx\n", value); + //if (value == 0) psxSu32(0x30) = 0x40000; + DmaExec(dmaSIF0, mem, value); + break; +//------------------------------------------------------------------ + case 0x1000c400: // dma6 - sif1 + DMA_LOG("SIF1dma %lx\n", value); + DmaExec(dmaSIF1, mem, value); + break; +#ifdef PCSX2_DEVBUILD + case 0x1000c420: // dma6 - sif1 - qwc + HW_LOG("SIF1dma QWC = %lx\n", value); + psHu32(mem) = value; + break; + case 0x1000c430: // dma6 - sif1 - tadr + HW_LOG("SIF1dma TADR = %lx\n", value); + psHu32(mem) = value; + break; +#endif +//------------------------------------------------------------------ + case 0x1000c800: // dma7 - sif2 + DMA_LOG("SIF2dma %lx\n", value); + DmaExec(dmaSIF2, mem, value); + break; +//------------------------------------------------------------------ + case 0x1000d000: // dma8 - fromSPR + DMA_LOG("fromSPRdma %lx\n", value); + DmaExec(dmaSPR0, mem, value); + break; +//------------------------------------------------------------------ + case 0x1000d400: // dma9 - toSPR + DMA_LOG("toSPRdma %lx\n", value); + DmaExec(dmaSPR1, mem, value); + break; +//------------------------------------------------------------------ + case 0x1000e000: // DMAC_CTRL + HW_LOG("DMAC_CTRL Write 32bit %x\n", value); + psHu32(0xe000) = value; + break; + + case 0x1000e010: // DMAC_STAT + HW_LOG("DMAC_STAT Write 32bit %x\n", value); + psHu16(0xe010)&= ~(value & 0xffff); // clear on 1 + psHu16(0xe012) ^= (u16)(value >> 16); + + cpuTestDMACInts(); + break; +//------------------------------------------------------------------ + case 0x1000f000: // INTC_STAT + HW_LOG("INTC_STAT Write 32bit %x\n", value); + psHu32(0xf000)&=~value; + //cpuTestINTCInts(); + break; + + case 0x1000f010: // INTC_MASK + HW_LOG("INTC_MASK Write 32bit %x\n", value); + psHu32(0xf010) ^= (u16)value; + cpuTestINTCInts(); + break; +//------------------------------------------------------------------ + case 0x1000f430://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5 + if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0 + rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid + psHu32(mem) = value & ~0x80000000; //kill the busy bit + break; + + case 0x1000f440://MCH_DRD: + psHu32(mem) = value; + break; +//------------------------------------------------------------------ + case 0x1000f590: // DMAC_ENABLEW + HW_LOG("DMAC_ENABLEW Write 32bit %lx\n", value); + psHu32(0xf590) = value; + psHu32(0xf520) = value; + return; +//------------------------------------------------------------------ + case 0x1000f200: + psHu32(mem) = value; + break; + case 0x1000f220: + psHu32(mem) |= value; + break; + case 0x1000f230: + psHu32(mem) &= ~value; + break; + case 0x1000f240: + if(!(value & 0x100)) + psHu32(mem) &= ~0x100; + else + psHu32(mem) |= 0x100; + break; + case 0x1000f260: + psHu32(mem) = 0; + break; +//------------------------------------------------------------------ + case 0x1000f130: + case 0x1000f410: + HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); + break; +//------------------------------------------------------------------ + default: +#ifndef PCSX2_VIRTUAL_MEM + if (mem < 0x10010000) +#endif + { + psHu32(mem) = value; + } + HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); + break; + } +} +#endif \ No newline at end of file diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index d294d3d435..b25ab47452 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -118,6 +118,9 @@ struct DMACh { #define D1_MADR 0x10009010 #define D1_QWC 0x10009020 #define D1_TADR 0x10009030 +#define D1_ASR0 0x10009040 +#define D1_ASR1 0x10009050 +#define D1_SADR 0x10009080 //GS #define D2_CHCR 0x1000A000 @@ -132,12 +135,15 @@ struct DMACh { #define D3_CHCR 0x1000B000 #define D3_MADR 0x1000B010 #define D3_QWC 0x1000B020 +#define D3_TADR 0x1000B030 +#define D3_SADR 0x1000B080 //toIPU #define D4_CHCR 0x1000B400 #define D4_MADR 0x1000B410 #define D4_QWC 0x1000B420 #define D4_TADR 0x1000B430 +#define D4_SADR 0x1000B480 //SIF0 #define D5_CHCR 0x1000C000 @@ -359,17 +365,34 @@ void hwShutdown(); // hw read functions extern u8 hwRead8 (u32 mem); extern u16 hwRead16(u32 mem); -extern u32 hwRead32(u32 mem); extern u64 hwRead64(u32 mem); extern void hwRead128(u32 mem, u64 *out); +extern mem32_t __fastcall hwRead32_page_00(u32 mem); +extern mem32_t __fastcall hwRead32_page_01(u32 mem); +extern mem32_t __fastcall hwRead32_page_02(u32 mem); +extern mem32_t __fastcall hwRead32_page_0F(u32 mem); +extern mem32_t __fastcall hwRead32_page_other(u32 mem); + +extern mem32_t __fastcall hwRead32(u32 mem); + // hw write functions extern void hwWrite8 (u32 mem, u8 value); extern void hwWrite16(u32 mem, u16 value); -extern void hwWrite32(u32 mem, u32 value); extern void hwWrite64(u32 mem, u64 value); extern void hwWrite128(u32 mem, const u64 *value); +extern void __fastcall hwWrite32_page_00( u32 mem, u32 value ); +extern void __fastcall hwWrite32_page_01( u32 mem, u32 value ); +extern void __fastcall hwWrite32_page_02( u32 mem, u32 value ); +extern void __fastcall hwWrite32_page_03( u32 mem, u32 value ); +extern void __fastcall hwWrite32_page_0B( u32 mem, u32 value ); +extern void __fastcall hwWrite32_page_0E( u32 mem, u32 value ); +extern void __fastcall hwWrite32_page_0F( u32 mem, u32 value ); +extern void __fastcall hwWrite32_page_other( u32 mem, u32 value ); + +extern void __fastcall hwWrite32(u32 mem, u32 value); + void hwIntcIrq(int n); void hwDmacIrq(int n); diff --git a/pcsx2/IPU/IPU.cpp b/pcsx2/IPU/IPU.cpp index 3e4e33f4c3..ebf9a75803 100644 --- a/pcsx2/IPU/IPU.cpp +++ b/pcsx2/IPU/IPU.cpp @@ -227,7 +227,7 @@ bool ipuCanFreeze() return ipuCurCmd == 0xffffffff; } -u32 ipuRead32(u32 mem) +__forceinline u32 ipuRead32(u32 mem) { IPUProcessInterrupt(); @@ -256,7 +256,7 @@ u32 ipuRead32(u32 mem) return *(u32*)(((u8*)ipuRegs)+(mem&0xff)); // ipu repeats every 0x100 } -u64 ipuRead64(u32 mem) +__forceinline u64 ipuRead64(u32 mem) { IPUProcessInterrupt(); @@ -326,7 +326,7 @@ void ipuSoftReset() g_nCmdPos[0] = 0; g_nCmdPos[1] = 0; } -void ipuWrite32(u32 mem,u32 value) +__forceinline void ipuWrite32(u32 mem,u32 value) { IPUProcessInterrupt(); @@ -355,7 +355,7 @@ void ipuWrite32(u32 mem,u32 value) } } -void ipuWrite64(u32 mem, u64 value) +__forceinline void ipuWrite64(u32 mem, u64 value) { IPUProcessInterrupt(); diff --git a/pcsx2/IPU/IPU.h b/pcsx2/IPU/IPU.h index ee960cc970..8bf5774e15 100644 --- a/pcsx2/IPU/IPU.h +++ b/pcsx2/IPU/IPU.h @@ -233,10 +233,10 @@ int ipuFreeze(gzFile f, int Mode); bool ipuCanFreeze(); -u32 ipuRead32(u32 mem); -u64 ipuRead64(u32 mem); -void ipuWrite32(u32 mem,u32 value); -void ipuWrite64(u32 mem,u64 value); +extern u32 ipuRead32(u32 mem); +extern u64 ipuRead64(u32 mem); +extern void ipuWrite32(u32 mem,u32 value); +extern void ipuWrite64(u32 mem,u64 value); int ipuConstRead32(u32 x86reg, u32 mem); void ipuConstRead64(u32 mem, int mmreg); diff --git a/pcsx2/Interpreter.cpp b/pcsx2/Interpreter.cpp index 26bfcf734f..618abc6cf0 100644 --- a/pcsx2/Interpreter.cpp +++ b/pcsx2/Interpreter.cpp @@ -49,7 +49,7 @@ static void debugI() {} static void execI() { #ifdef _DEBUG - if (memRead32(cpuRegs.pc, &cpuRegs.code) == -1) return; + memRead32(cpuRegs.pc, &cpuRegs.code); debugI(); #else cpuRegs.code = *(u32 *)PSM(cpuRegs.pc); diff --git a/pcsx2/Memory.cpp b/pcsx2/Memory.cpp index 68941f5d0d..a2c7d44406 100644 --- a/pcsx2/Memory.cpp +++ b/pcsx2/Memory.cpp @@ -166,6 +166,8 @@ vtlbHandler tlb_fallback_8; vtlbHandler vu0_micro_mem; vtlbHandler vu1_micro_mem; +vtlbHandler hw_by_page[0x10]; + void memMapPhy() { //Main mem @@ -204,6 +206,15 @@ void memMapPhy() vtlb_MapHandler(tlb_fallback_3,0x1f400000,0x10000); vtlb_MapHandler(tlb_fallback_2,0x1f800000,0x10000); vtlb_MapHandler(tlb_fallback_8,0x1f900000,0x10000); + + // map specific optimized page handlers for HW accesses + vtlb_MapHandler(hw_by_page[0x0], 0x10000000, 0x01000); + vtlb_MapHandler(hw_by_page[0x1], 0x10001000, 0x01000); + vtlb_MapHandler(hw_by_page[0x2], 0x10002000, 0x01000); + vtlb_MapHandler(hw_by_page[0x3], 0x10003000, 0x01000); + vtlb_MapHandler(hw_by_page[0xb], 0x1000b000, 0x01000); + vtlb_MapHandler(hw_by_page[0xe], 0x1000e000, 0x01000); + vtlb_MapHandler(hw_by_page[0xf], 0x1000f000, 0x01000); } //Why is this required ? @@ -227,117 +238,122 @@ void memMapUserMem() } template -int __fastcall _ext_memRead8 (u32 mem, u8 *out) { - +mem8_t __fastcall _ext_memRead8 (u32 mem) +{ switch (p) { case 1: // hwm - *out = hwRead8(mem); return 0; + return hwRead8(mem); case 2: // psh - *out = psxHwRead8(mem); return 0; + return psxHwRead8(mem); case 3: // psh4 - *out = psxHw4Read8(mem); return 0; + return psxHw4Read8(mem); case 6: // gsm - *out = gsRead8(mem); return 0; + return gsRead8(mem); case 7: // dev9 - *out = DEV9read8(mem & ~0xa4000000); - SysPrintf("DEV9 read8 %8.8lx: %2.2lx\n", mem & ~0xa4000000, *out); - return 0; + { + mem8_t retval = DEV9read8(mem & ~0xa4000000); + SysPrintf("DEV9 read8 %8.8lx: %2.2lx\n", mem & ~0xa4000000, retval); + return retval; + } } - MEM_LOG("Unknown Memory read32 from address %8.8x\n", mem); + MEM_LOG("Unknown Memory Read8 from address %8.8x\n", mem); cpuTlbMissR(mem, cpuRegs.branch); - - return -1; + return 0; } + template -int __fastcall _ext_memRead16(u32 mem, u16 *out) { - switch (p) { +mem16_t __fastcall _ext_memRead16(u32 mem) +{ + switch (p) + { case 1: // hwm - *out = hwRead16(mem); return 0; + return hwRead16(mem); case 2: // psh - *out = psxHwRead16(mem); return 0; + return psxHwRead16(mem); case 4: // b80 MEM_LOG("b800000 Memory read16 address %x\n", mem); - *out = 0; return 0; - case 5: // ba0 - *out = ba0R16(mem); return 0; - case 6: // gsm - *out = gsRead16(mem); return 0; - case 7: // dev9 - *out = DEV9read16(mem & ~0xa4000000); - SysPrintf("DEV9 read16 %8.8lx: %4.4lx\n", mem & ~0xa4000000, *out); return 0; + case 5: // ba0 + return ba0R16(mem); + case 6: // gsm + return gsRead16(mem); + + case 7: // dev9 + { + mem16_t retval = DEV9read16(mem & ~0xa4000000); + SysPrintf("DEV9 read16 %8.8lx: %4.4lx\n", mem & ~0xa4000000, retval); + return retval; + } + case 8: // spu2 - *out = SPU2read(mem); return 0; + return SPU2read(mem); } MEM_LOG("Unknown Memory read16 from address %8.8x\n", mem); cpuTlbMissR(mem, cpuRegs.branch); - - return -1; + return 0; } + template -int __fastcall _ext_memRead32(u32 mem, u32 *out) +mem32_t __fastcall _ext_memRead32(u32 mem) { - switch ((int)(uptr)p) { + switch (p) + { case 1: // hwm - *out = hwRead32(mem); return 0; + return hwRead32_page_other(mem); case 2: // psh - *out = psxHwRead32(mem); return 0; + return psxHwRead32(mem); case 6: // gsm - *out = gsRead32(mem); return 0; + return gsRead32(mem); case 7: // dev9 - *out = DEV9read32(mem & ~0xa4000000); - SysPrintf("DEV9 read32 %8.8lx: %8.8lx\n", mem & ~0xa4000000, *out); - return 0; + { + mem32_t retval = DEV9read32(mem & ~0xa4000000); + SysPrintf("DEV9 read32 %8.8lx: %8.8lx\n", mem & ~0xa4000000, retval); + return retval; + } } MEM_LOG("Unknown Memory read32 from address %8.8x (Status=%8.8x)\n", mem, cpuRegs.CP0.n.Status.val); cpuTlbMissR(mem, cpuRegs.branch); - - return -1; + return 0; } + template -int __fastcall _ext_memRead64(u32 mem, u64 *out) +void __fastcall _ext_memRead64(u32 mem, mem64_t *out) { - switch ((int)(uptr)p) { + switch (p) + { case 1: // hwm - *out = hwRead64(mem); return 0; + *out = hwRead64(mem); return; case 6: // gsm - *out = gsRead64(mem); return 0; + *out = gsRead64(mem); return; } -#ifdef MEM_LOG MEM_LOG("Unknown Memory read64 from address %8.8x\n", mem); -#endif cpuTlbMissR(mem, cpuRegs.branch); - - return -1; } template -int __fastcall _ext_memRead128(u32 mem, u64 *out) +void __fastcall _ext_memRead128(u32 mem, mem128_t *out) { - - switch ((int)(uptr)p) { + switch (p) + { case 1: // hwm - hwRead128(mem & ~0xa0000000, out); return 0; + hwRead128(mem & ~0xa0000000, out); return; case 6: // gsm - out[0] = gsRead64((mem )); - out[1] = gsRead64((mem+8)); return 0; + out[0] = gsRead64(mem ); + out[1] = gsRead64(mem+8); return; } MEM_LOG("Unknown Memory read128 from address %8.8x\n", mem); cpuTlbMissR(mem, cpuRegs.branch); - - return -1; } template void __fastcall _ext_memWrite8 (u32 mem, u8 value) { - - switch ((int)(uptr)p) { + switch (p) { case 1: // hwm hwWrite8(mem, value); return; @@ -359,7 +375,7 @@ void __fastcall _ext_memWrite8 (u32 mem, u8 value) template void __fastcall _ext_memWrite16(u32 mem, u16 value) { - switch ((int)(uptr)p) { + switch (p) { case 1: // hwm hwWrite16(mem, value); return; @@ -383,10 +399,9 @@ void __fastcall _ext_memWrite16(u32 mem, u16 value) template void __fastcall _ext_memWrite32(u32 mem, u32 value) { - switch ((int)(uptr)p) { + switch (p) { case 1: // hwm - hwWrite32(mem, value); - return; + hwWrite32_page_other(mem, value); return; case 2: // psh psxHwWrite32(mem, value); return; case 6: // gsm @@ -433,55 +448,51 @@ void __fastcall _ext_memWrite128(u32 mem, const u64 *value) #define vtlb_RegisterHandlerTempl1(nam,t) vtlb_RegisterHandler(nam##Read8,nam##Read16,nam##Read32,nam##Read64,nam##Read128, \ nam##Write8,nam##Write16,nam##Write32,nam##Write64,nam##Write128); + template -int __fastcall vuMicroRead8(u32 addr,mem8_t* data) +mem8_t __fastcall vuMicroRead8(u32 addr) { addr&=(vunum==0)?0xfff:0x3fff; VURegs* vu=(vunum==0)?&VU0:&VU1; - *data=vu->Micro[addr]; - return 0; + return vu->Micro[addr]; } template -int __fastcall vuMicroRead16(u32 addr,mem16_t* data) +mem16_t __fastcall vuMicroRead16(u32 addr) { addr&=(vunum==0)?0xfff:0x3fff; VURegs* vu=(vunum==0)?&VU0:&VU1; - *data=*(u16*)&vu->Micro[addr]; - return 0; + return *(u16*)&vu->Micro[addr]; } template -int __fastcall vuMicroRead32(u32 addr,mem32_t* data) +mem32_t __fastcall vuMicroRead32(u32 addr) { addr&=(vunum==0)?0xfff:0x3fff; VURegs* vu=(vunum==0)?&VU0:&VU1; - *data=*(u32*)&vu->Micro[addr]; - return 0; + return *(u32*)&vu->Micro[addr]; } template -int __fastcall vuMicroRead64(u32 addr,mem64_t* data) +void __fastcall vuMicroRead64(u32 addr,mem64_t* data) { addr&=(vunum==0)?0xfff:0x3fff; VURegs* vu=(vunum==0)?&VU0:&VU1; *data=*(u64*)&vu->Micro[addr]; - return 0; } template -int __fastcall vuMicroRead128(u32 addr,mem128_t* data) +void __fastcall vuMicroRead128(u32 addr,mem128_t* data) { addr&=(vunum==0)?0xfff:0x3fff; VURegs* vu=(vunum==0)?&VU0:&VU1; data[0]=*(u64*)&vu->Micro[addr]; data[1]=*(u64*)&vu->Micro[addr+8]; - return 0; } // [TODO] : Profile this code and see how often the VUs get written, and how @@ -687,7 +698,7 @@ void memReset() vtlb_Init(); tlb_fallback_0=vtlb_RegisterHandlerTempl1(_ext_mem,0); - tlb_fallback_1=vtlb_RegisterHandlerTempl1(_ext_mem,1); + //tlb_fallback_1=vtlb_RegisterHandlerTempl1(_ext_mem,1); tlb_fallback_2=vtlb_RegisterHandlerTempl1(_ext_mem,2); tlb_fallback_3=vtlb_RegisterHandlerTempl1(_ext_mem,3); tlb_fallback_4=vtlb_RegisterHandlerTempl1(_ext_mem,4); @@ -699,6 +710,52 @@ void memReset() vu0_micro_mem=vtlb_RegisterHandlerTempl1(vuMicro,0); vu1_micro_mem=vtlb_RegisterHandlerTempl1(vuMicro,1); + ////////////////////////////////////////////////////// + // psHw Optimized Mappings + // The HW Registers have been split into pages to improve optimization. + // Anything not explicitly mapped into one of the hw_by_page handlers will be handled + // by the default/generic tlb_fallback_1 handler. + + tlb_fallback_1 = vtlb_RegisterHandler( + _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_other, _ext_memRead64<1>, _ext_memRead128<1>, + _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_other, _ext_memWrite64<1>, _ext_memWrite128<1> + ); + + hw_by_page[0x0] = vtlb_RegisterHandler( + _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_00, _ext_memRead64<1>, _ext_memRead128<1>, + _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_00, _ext_memWrite64<1>, _ext_memWrite128<1> + ); + + hw_by_page[0x1] = vtlb_RegisterHandler( + _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_01, _ext_memRead64<1>, _ext_memRead128<1>, + _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_01, _ext_memWrite64<1>, _ext_memWrite128<1> + ); + + hw_by_page[0x2] = vtlb_RegisterHandler( + _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_02, _ext_memRead64<1>, _ext_memRead128<1>, + _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_02, _ext_memWrite64<1>, _ext_memWrite128<1> + ); + + hw_by_page[0x3] = vtlb_RegisterHandler( + _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_other, _ext_memRead64<1>, _ext_memRead128<1>, + _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_03, _ext_memWrite64<1>, _ext_memWrite128<1> + ); + + hw_by_page[0xb] = vtlb_RegisterHandler( + _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_other, _ext_memRead64<1>, _ext_memRead128<1>, + _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0B, _ext_memWrite64<1>, _ext_memWrite128<1> + ); + + hw_by_page[0xe] = vtlb_RegisterHandler( + _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_other, _ext_memRead64<1>, _ext_memRead128<1>, + _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, _ext_memWrite64<1>, _ext_memWrite128<1> + ); + + hw_by_page[0xf] = vtlb_RegisterHandler( + _ext_memRead8<1>, _ext_memRead16<1>, hwRead32_page_0F, _ext_memRead64<1>, _ext_memRead128<1>, + _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0F, _ext_memWrite64<1>, _ext_memWrite128<1> + ); + //vtlb_Reset(); // reset memLUT (?) diff --git a/pcsx2/Memory.h b/pcsx2/Memory.h index aa744d8d53..dd372f00d0 100644 --- a/pcsx2/Memory.h +++ b/pcsx2/Memory.h @@ -255,20 +255,17 @@ int mmap_GetRamPageInfo(void* ptr); void mmap_MarkCountedRamPage(void* ptr,u32 vaddr); void mmap_ResetBlockTracking(); -int __fastcall _memRead8(u32 mem, u8 *out); -int __fastcall _memRead16(u32 mem, u16 *out); -int __fastcall _memRead32(u32 mem, u32 *out); -int __fastcall _memRead64(u32 mem, u64 *out); +extern void __fastcall memRead8(u32 mem, u8 *out); +extern void __fastcall memRead16(u32 mem, u16 *out); +extern void __fastcall memRead32(u32 mem, u32 *out); +/*int __fastcall _memRead64(u32 mem, u64 *out); int __fastcall _memRead128(u32 mem, u64 *out); void __fastcall _memWrite8 (u32 mem, u8 value); void __fastcall _memWrite16(u32 mem, u16 value); void __fastcall _memWrite32(u32 mem, u32 value); void __fastcall _memWrite64(u32 mem, u64 value); -void __fastcall _memWrite128(u32 mem, u64 *value); +void __fastcall _memWrite128(u32 mem, u64 *value);*/ -#define memRead8 vtlb_memRead8 -#define memRead16 vtlb_memRead16 -#define memRead32 vtlb_memRead32 #define memRead64 vtlb_memRead64 #define memRead128 vtlb_memRead128 diff --git a/pcsx2/R5900OpcodeImpl.cpp b/pcsx2/R5900OpcodeImpl.cpp index 30164b0202..cc4d4624a8 100644 --- a/pcsx2/R5900OpcodeImpl.cpp +++ b/pcsx2/R5900OpcodeImpl.cpp @@ -237,7 +237,9 @@ void LB() { addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; u8 temp; const u32 rt=_Rt_; - if ((0==memRead8(addr, &temp)) && (rt!=0)) + + memRead8(addr, &temp); + if(rt!=0) { cpuRegs.GPR.r[rt].UD[0]=(s8)temp; } @@ -249,7 +251,8 @@ void LBU() { addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; u8 temp; const u32 rt=_Rt_; - if ((0==memRead8(addr, &temp)) && (rt!=0)) + memRead8(addr, &temp); + if(rt!=0) { cpuRegs.GPR.r[rt].UD[0]=temp; } @@ -261,7 +264,8 @@ void LH() { addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; u16 temp; const u32 rt=_Rt_; - if ((0==memRead16(addr, &temp)) && (rt!=0)) + memRead16(addr, &temp); + if(rt!=0) { cpuRegs.GPR.r[rt].UD[0]=(s16)temp; } @@ -273,7 +277,8 @@ void LHU() { addr = cpuRegs.GPR.r[_Rs_].UL[0] + _Imm_; u16 temp; const u32 rt=_Rt_; - if ((0==memRead16(addr, &temp)) && (rt!=0)) + memRead16(addr, &temp); + if(rt!=0) { cpuRegs.GPR.r[rt].UD[0]=temp; } @@ -287,7 +292,8 @@ void LW() { u32 temp; const u32 rt=_Rt_; - if ((0==memRead32(addr, &temp)) && (rt!=0)) + memRead32(addr, &temp); + if(rt!=0) { cpuRegs.GPR.r[rt].UD[0]=(s32)temp; } @@ -300,7 +306,8 @@ void LWU() { u32 temp; const u32 rt=_Rt_; - if ((0==memRead32(addr, &temp)) && (rt!=0)) + memRead32(addr, &temp); + if(rt!=0) { cpuRegs.GPR.r[rt].UD[0]=temp; } @@ -315,7 +322,7 @@ void LWL() { u32 mem; if (!_Rt_) return; - if (memRead32(addr & ~3, &mem) == -1) return; + memRead32(addr & ~3, &mem); cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UL[0] & LWL_MASK[shift]) | (mem << LWL_SHIFT[shift]); @@ -338,7 +345,7 @@ void LWR() { u32 mem; if (!_Rt_) return; - if (memRead32(addr & ~3, &mem) == -1) return; + memRead32(addr & ~3, &mem); cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UL[0] & LWR_MASK[shift]) | (mem >> LWR_SHIFT[shift]); @@ -374,7 +381,7 @@ void LDL() { u64 mem; if (!_Rt_) return; - if (memRead64(addr & ~7, &mem) == -1) return; + memRead64(addr & ~7, &mem); cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UD[0] & LDL_MASK[shift]) | (mem << LDL_SHIFT[shift]); } @@ -389,7 +396,7 @@ void LDR() { u64 mem; if (!_Rt_) return; - if (memRead64(addr & ~7, &mem) == -1) return; + memRead64(addr & ~7, &mem); cpuRegs.GPR.r[_Rt_].UD[0] = (cpuRegs.GPR.r[_Rt_].UD[0] & LDR_MASK[shift]) | (mem >> LDR_SHIFT[shift]); } @@ -437,7 +444,7 @@ void SWL() { u32 shift = addr & 3; u32 mem; - if (memRead32(addr & ~3, &mem) == -1) return; + memRead32(addr & ~3, &mem); memWrite32(addr & ~3, (cpuRegs.GPR.r[_Rt_].UL[0] >> SWL_SHIFT[shift]) | ( mem & SWL_MASK[shift]) ); @@ -459,7 +466,7 @@ void SWR() { u32 shift = addr & 3; u32 mem; - if (memRead32(addr & ~3, &mem) == -1) return; + memRead32(addr & ~3, &mem); memWrite32(addr & ~3, (cpuRegs.GPR.r[_Rt_].UL[0] << SWR_SHIFT[shift]) | ( mem & SWR_MASK[shift]) ); @@ -490,7 +497,7 @@ void SDL() { u32 shift = addr & 7; u64 mem; - if (memRead64(addr & ~7, &mem) == -1) return; + memRead64(addr & ~7, &mem); mem =(cpuRegs.GPR.r[_Rt_].UD[0] >> SDL_SHIFT[shift]) | ( mem & SDL_MASK[shift]); memWrite64(addr & ~7, &mem); @@ -505,7 +512,7 @@ void SDR() { u32 shift = addr & 7; u64 mem; - if (memRead64(addr & ~7, &mem) == -1) return; + memRead64(addr & ~7, &mem); mem=(cpuRegs.GPR.r[_Rt_].UD[0] << SDR_SHIFT[shift]) | ( mem & SDR_MASK[shift]); memWrite64(addr & ~7, &mem ); diff --git a/pcsx2/VU0.cpp b/pcsx2/VU0.cpp index 4970f7db74..e8b2b69824 100644 --- a/pcsx2/VU0.cpp +++ b/pcsx2/VU0.cpp @@ -357,7 +357,8 @@ void vu0Finish() } if(VU0.VI[REG_VPU_STAT].UL & 0x1) { VU0.VI[REG_VPU_STAT].UL &= ~1; - Console::Notice("vu0Finish > stall aborted by force."); + // this log tends to spam a lot (MGS3) + //Console::Notice("vu0Finish > stall aborted by force."); } } } diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index 748b4ff2b3..90619d29ae 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -41,10 +41,12 @@ static const uint VTLB_VMAP_ITEMS=(0x100000000ULL/VTLB_PAGE_SIZE); static s32 pmap[VTLB_PMAP_ITEMS]; //512KB static s32 vmap[VTLB_VMAP_ITEMS]; //4MB -//5 -> one for each size -//2 -> read/write -// -void* RWFT[5][2][128]; +// first indexer -- 8/16/32/64/128 bit tables [values 0-4] +// second indexer -- read/write [0 or 1] +// third indexer -- 128 pages of memory! +static void* RWFT[5][2][128]; + + vtlbHandler vtlbHandlerCount=0; vtlbHandler DefaultPhyHandler; @@ -79,9 +81,35 @@ callfunction: jmp [readfunctions8-0x800000+eax]; }*/ - +// For 8, 16, and 32 bit accesses template -__forceinline int __fastcall MemOp_r(u32 addr, DataType* data) +__forceinline DataType __fastcall MemOp_r0(u32 addr) +{ + u32 vmv=vmap[addr>>VTLB_PAGE_BITS]; + s32 ppf=addr+vmv; + + if (!(ppf<0)) + return *reinterpret_cast(ppf); + + //has to: translate, find function, call function + u32 hand=(u8)vmv; + u32 paddr=ppf-hand+0x80000000; + //SysPrintf("Translated 0x%08X to 0x%08X\n",addr,paddr); + //return reinterpret_cast::HandlerType*>(RWFT[TemplateHelper::sidx][0][hand])(paddr,data); + + switch( DataSize ) + { + case 8: return ((vltbMemR8FP*)RWFT[0][0][hand])(paddr); + case 16: return ((vltbMemR16FP*)RWFT[1][0][hand])(paddr); + case 32: return ((vltbMemR32FP*)RWFT[2][0][hand])(paddr); + + jNO_DEFAULT; + } +} + +// For 64 and 128 bit accesses. +template +__forceinline void __fastcall MemOp_r1(u32 addr, DataType* data) { u32 vmv=vmap[addr>>VTLB_PAGE_BITS]; s32 ppf=addr+vmv; @@ -91,30 +119,25 @@ __forceinline int __fastcall MemOp_r(u32 addr, DataType* data) data[0]=*reinterpret_cast(ppf); if (DataSize==128) data[1]=*reinterpret_cast(ppf+8); - return 0; } else { //has to: translate, find function, call function u32 hand=(u8)vmv; u32 paddr=ppf-hand+0x80000000; - //SysPrintf("Translted 0x%08X to 0x%08X\n",addr,paddr); + //SysPrintf("Translated 0x%08X to 0x%08X\n",addr,paddr); //return reinterpret_cast::HandlerType*>(RWFT[TemplateHelper::sidx][0][hand])(paddr,data); switch( DataSize ) { - case 8: return ((vltbMemRFP*)RWFT[0][0][hand])(paddr, data); - case 16: return ((vltbMemRFP*)RWFT[1][0][hand])(paddr, data); - case 32: return ((vltbMemRFP*)RWFT[2][0][hand])(paddr, data); - case 64: return ((vltbMemRFP*)RWFT[3][0][hand])(paddr, data); - case 128: return ((vltbMemRFP*)RWFT[4][0][hand])(paddr, data); + case 64: ((vltbMemR64FP*)RWFT[3][0][hand])(paddr, data); break; + case 128: ((vltbMemR128FP*)RWFT[4][0][hand])(paddr, data); break; jNO_DEFAULT; } } } - template __forceinline void __fastcall MemOp_w0(u32 addr, DataType data) { @@ -168,48 +191,55 @@ __forceinline void __fastcall MemOp_w1(u32 addr,const DataType* data) } } } -int __fastcall vtlb_memRead8(u32 mem, u8 *out) + +mem8_t __fastcall vtlb_memRead8(u32 mem) { - return MemOp_r<8,u8>(mem,out); + return MemOp_r0<8,mem8_t>(mem); } -int __fastcall vtlb_memRead16(u32 mem, u16 *out) +mem16_t __fastcall vtlb_memRead16(u32 mem) { - return MemOp_r<16,u16>(mem,out); + return MemOp_r0<16,mem16_t>(mem); } -int __fastcall vtlb_memRead32(u32 mem, u32 *out) +mem32_t __fastcall vtlb_memRead32(u32 mem) { - return MemOp_r<32,u32>(mem,out); + return MemOp_r0<32,mem32_t>(mem); } -int __fastcall vtlb_memRead64(u32 mem, u64 *out) +void __fastcall vtlb_memRead64(u32 mem, u64 *out) { - return MemOp_r<64,u64>(mem,out); + return MemOp_r1<64,mem64_t>(mem,out); } -int __fastcall vtlb_memRead128(u32 mem, u64 *out) +void __fastcall vtlb_memRead128(u32 mem, u64 *out) { - return MemOp_r<128,u64>(mem,out); + return MemOp_r1<128,mem128_t>(mem,out); } -void __fastcall vtlb_memWrite8 (u32 mem, u8 value) +void __fastcall vtlb_memWrite8 (u32 mem, mem8_t value) { - MemOp_w0<8,u8>(mem,value); + MemOp_w0<8,mem8_t>(mem,value); } -void __fastcall vtlb_memWrite16(u32 mem, u16 value) +void __fastcall vtlb_memWrite16(u32 mem, mem16_t value) { - MemOp_w0<16,u16>(mem,value); + MemOp_w0<16,mem16_t>(mem,value); } -void __fastcall vtlb_memWrite32(u32 mem, u32 value) +void __fastcall vtlb_memWrite32(u32 mem, mem32_t value) { - MemOp_w0<32,u32>(mem,value); + MemOp_w0<32,mem32_t>(mem,value); } -void __fastcall vtlb_memWrite64(u32 mem, const u64* value) +void __fastcall vtlb_memWrite64(u32 mem, const mem64_t* value) { - MemOp_w1<64,u64>(mem,value); + MemOp_w1<64,mem64_t>(mem,value); } -void __fastcall vtlb_memWrite128(u32 mem, const u64 *value) +void __fastcall vtlb_memWrite128(u32 mem, const mem128_t *value) { - MemOp_w1<128,u64>(mem,value); + MemOp_w1<128,mem128_t>(mem,value); } -static __forceinline int vtlb_Miss(u32 addr,u32 mode) +// Some functions used by interpreters and stuff... +void __fastcall memRead8(u32 mem, u8 *out) { *out = vtlb_memRead8( mem ); } +void __fastcall memRead16(u32 mem, u16 *out) { *out = vtlb_memRead16( mem ); } +void __fastcall memRead32(u32 mem, u32 *out) { *out = vtlb_memRead32( mem ); } + + +static __forceinline void vtlb_Miss(u32 addr,u32 mode) { SysPrintf("vtlb miss : addr 0x%X, mode %d\n",addr,mode); verify(false); @@ -217,26 +247,23 @@ static __forceinline int vtlb_Miss(u32 addr,u32 mode) cpuTlbMissR(addr, cpuRegs.branch); else cpuTlbMissW(addr, cpuRegs.branch); - - return -1; } -static __forceinline int vtlb_BusError(u32 addr,u32 mode) +static __forceinline void vtlb_BusError(u32 addr,u32 mode) { SysPrintf("vtlb bus error : addr 0x%X, mode %d\n",addr,mode); verify(false); - return -1; } ///// template -int __fastcall vtlbUnmappedVRead8(u32 addr,mem8_t* data) { return vtlb_Miss(addr|saddr,0); } +mem8_t __fastcall vtlbUnmappedVRead8(u32 addr) { vtlb_Miss(addr|saddr,0); return 0; } template -int __fastcall vtlbUnmappedVRead16(u32 addr,mem16_t* data) { return vtlb_Miss(addr|saddr,0); } +mem16_t __fastcall vtlbUnmappedVRead16(u32 addr) { vtlb_Miss(addr|saddr,0); return 0; } template -int __fastcall vtlbUnmappedVRead32(u32 addr,mem32_t* data) { return vtlb_Miss(addr|saddr,0); } +mem32_t __fastcall vtlbUnmappedVRead32(u32 addr) { vtlb_Miss(addr|saddr,0); return 0; } template -int __fastcall vtlbUnmappedVRead64(u32 addr,mem64_t* data) { return vtlb_Miss(addr|saddr,0); } +void __fastcall vtlbUnmappedVRead64(u32 addr,mem64_t* data) { vtlb_Miss(addr|saddr,0); } template -int __fastcall vtlbUnmappedVRead128(u32 addr,mem128_t* data) { return vtlb_Miss(addr|saddr,0); } +void __fastcall vtlbUnmappedVRead128(u32 addr,mem128_t* data) { vtlb_Miss(addr|saddr,0); } template void __fastcall vtlbUnmappedVWrite8(u32 addr,mem8_t data) { vtlb_Miss(addr|saddr,1); } template @@ -249,15 +276,15 @@ template void __fastcall vtlbUnmappedVWrite128(u32 addr,const mem128_t* data) { vtlb_Miss(addr|saddr,1); } ///// template -int __fastcall vtlbUnmappedPRead8(u32 addr,mem8_t* data) { return vtlb_BusError(addr|saddr,0); } +mem8_t __fastcall vtlbUnmappedPRead8(u32 addr) { vtlb_BusError(addr|saddr,0); return 0; } template -int __fastcall vtlbUnmappedPRead16(u32 addr,mem16_t* data) { return vtlb_BusError(addr|saddr,0); } +mem16_t __fastcall vtlbUnmappedPRead16(u32 addr) { vtlb_BusError(addr|saddr,0); return 0; } template -int __fastcall vtlbUnmappedPRead32(u32 addr,mem32_t* data) { return vtlb_BusError(addr|saddr,0); } +mem32_t __fastcall vtlbUnmappedPRead32(u32 addr) { vtlb_BusError(addr|saddr,0); return 0; } template -int __fastcall vtlbUnmappedPRead64(u32 addr,mem64_t* data) { return vtlb_BusError(addr|saddr,0); } +void __fastcall vtlbUnmappedPRead64(u32 addr,mem64_t* data) { vtlb_BusError(addr|saddr,0); } template -int __fastcall vtlbUnmappedPRead128(u32 addr,mem128_t* data) { return vtlb_BusError(addr|saddr,0); } +void __fastcall vtlbUnmappedPRead128(u32 addr,mem128_t* data) { vtlb_BusError(addr|saddr,0); } template void __fastcall vtlbUnmappedPWrite8(u32 addr,mem8_t data) { vtlb_BusError(addr|saddr,1); } template @@ -269,11 +296,11 @@ void __fastcall vtlbUnmappedPWrite64(u32 addr,const mem64_t* data) { vtlb_BusErr template void __fastcall vtlbUnmappedPWrite128(u32 addr,const mem128_t* data) { vtlb_BusError(addr|saddr,1); } ///// -int __fastcall vtlbDefaultPhyRead8(u32 addr,mem8_t* data) { SysPrintf("vtlbDefaultPhyRead8: 0x%X\n",addr); verify(false); return -1; } -int __fastcall vtlbDefaultPhyRead16(u32 addr,mem16_t* data) { SysPrintf("vtlbDefaultPhyRead16: 0x%X\n",addr); verify(false); return -1; } -int __fastcall vtlbDefaultPhyRead32(u32 addr,mem32_t* data) { SysPrintf("vtlbDefaultPhyRead32: 0x%X\n",addr); verify(false); return -1; } -int __fastcall vtlbDefaultPhyRead64(u32 addr,mem64_t* data) { SysPrintf("vtlbDefaultPhyRead64: 0x%X\n",addr); verify(false); return -1; } -int __fastcall vtlbDefaultPhyRead128(u32 addr,mem128_t* data) { SysPrintf("vtlbDefaultPhyRead128: 0x%X\n",addr); verify(false); return -1; } +mem8_t __fastcall vtlbDefaultPhyRead8(u32 addr) { SysPrintf("vtlbDefaultPhyRead8: 0x%X\n",addr); verify(false); return -1; } +mem16_t __fastcall vtlbDefaultPhyRead16(u32 addr) { SysPrintf("vtlbDefaultPhyRead16: 0x%X\n",addr); verify(false); return -1; } +mem32_t __fastcall vtlbDefaultPhyRead32(u32 addr) { SysPrintf("vtlbDefaultPhyRead32: 0x%X\n",addr); verify(false); return -1; } +void __fastcall vtlbDefaultPhyRead64(u32 addr,mem64_t* data) { SysPrintf("vtlbDefaultPhyRead64: 0x%X\n",addr); verify(false); } +void __fastcall vtlbDefaultPhyRead128(u32 addr,mem128_t* data) { SysPrintf("vtlbDefaultPhyRead128: 0x%X\n",addr); verify(false); } void __fastcall vtlbDefaultPhyWrite8(u32 addr,mem8_t data) { SysPrintf("vtlbDefaultPhyWrite8: 0x%X\n",addr); verify(false); } void __fastcall vtlbDefaultPhyWrite16(u32 addr,mem16_t data) { SysPrintf("vtlbDefaultPhyWrite16: 0x%X\n",addr); verify(false); } @@ -287,17 +314,17 @@ vtlbHandler vtlb_RegisterHandler( vltbMemR8FP* r8,vltbMemR16FP* r16,vltbMemR32FP //write the code :p vtlbHandler rv=vtlbHandlerCount++; - RWFT[0][0][rv]=r8!=0?r8:vtlbDefaultPhyRead8; - RWFT[1][0][rv]=r16!=0?r16:vtlbDefaultPhyRead16; - RWFT[2][0][rv]=r32!=0?r32:vtlbDefaultPhyRead32; - RWFT[3][0][rv]=r64!=0?r64:vtlbDefaultPhyRead64; - RWFT[4][0][rv]=r128!=0?r128:vtlbDefaultPhyRead128; + RWFT[0][0][rv] = (r8!=0) ? r8:vtlbDefaultPhyRead8; + RWFT[1][0][rv] = (r16!=0) ? r16:vtlbDefaultPhyRead16; + RWFT[2][0][rv] = (r32!=0) ? r32:vtlbDefaultPhyRead32; + RWFT[3][0][rv] = (r64!=0) ? r64:vtlbDefaultPhyRead64; + RWFT[4][0][rv] = (r128!=0) ? r128:vtlbDefaultPhyRead128; - RWFT[0][1][rv]=w8!=0?w8:vtlbDefaultPhyWrite8; - RWFT[1][1][rv]=w16!=0?w16:vtlbDefaultPhyWrite16; - RWFT[2][1][rv]=w32!=0?w32:vtlbDefaultPhyWrite32; - RWFT[3][1][rv]=w64!=0?w64:vtlbDefaultPhyWrite64; - RWFT[4][1][rv]=w128!=0?w128:vtlbDefaultPhyWrite128; + RWFT[0][1][rv] = (w8!=0) ? w8:vtlbDefaultPhyWrite8; + RWFT[1][1][rv] = (w16!=0) ? w16:vtlbDefaultPhyWrite16; + RWFT[2][1][rv] = (w32!=0) ? w32:vtlbDefaultPhyWrite32; + RWFT[3][1][rv] = (w64!=0) ? w64:vtlbDefaultPhyWrite64; + RWFT[4][1][rv] = (w128!=0) ? w128:vtlbDefaultPhyWrite128; return rv; } @@ -486,7 +513,7 @@ void vtlb_Term() //ecx = addr //edx = ptr -void vtlb_DynGenRead(u32 sz) +void vtlb_DynGenRead64(u32 bits) { /* u32 vmv=vmap[addr>>VTLB_PAGE_BITS]; @@ -539,21 +566,8 @@ void vtlb_DynGenRead(u32 sz) MOV32RmSOffsettoR(EAX,EAX,(int)vmap,2); ADD32RtoR(ECX,EAX); u8* _fullread=JS8(0); - switch(sz) + switch(bits) { - case 8: - MOVZX32Rm8toR(EAX,ECX); - MOV8RtoRm(EDX,EAX); - break; - case 16: - MOVZX32Rm16toR(EAX,ECX); - MOV16RtoRm(EDX,EAX); - break; - case 32: - MOV32RmtoR(EAX,ECX); - MOV32RtoRm(EDX,EAX); - break; - case 64: if( _hasFreeMMXreg() ) { @@ -595,30 +609,105 @@ void vtlb_DynGenRead(u32 sz) MOV32RtoRmOffset(EDX,EAX,12); } break; + + jNO_DEFAULT } u8* cont=JMP8(0); x86SetJ8(_fullread); - int szidx=0; + int szidx; - switch(sz) + switch(bits) { - case 8: szidx=0; break; - case 16: szidx=1; break; - case 32: szidx=2; break; - case 64: szidx=3; break; - case 128: szidx=4; break; + case 64: szidx=3; break; + case 128: szidx=4; break; + jNO_DEFAULT } + MOVZX32R8toR(EAX,EAX); SUB32RtoR(ECX,EAX); //eax=[funct+eax] - MOV32RmSOffsettoR(EAX,EAX,(int)&RWFT[szidx][0][0],2); + MOV32RmSOffsettoR(EAX,EAX,(int)RWFT[szidx][0],2); SUB32ItoR(ECX,0x80000000); CALL32R(EAX); x86SetJ8(cont); } +// ecx - source address to read from +// Returns read value in eax. +void vtlb_DynGenRead32(u32 bits, bool sign) +{ + jASSUME( bits <= 32 ); + + MOV32RtoR(EAX,ECX); + SHR32ItoR(EAX,VTLB_PAGE_BITS); + MOV32RmSOffsettoR(EAX,EAX,(int)vmap,2); + ADD32RtoR(ECX,EAX); + u8* _fullread=JS8(0); + + switch(bits) + { + case 8: + if( sign ) + MOVSX32Rm8toR(EAX,ECX); + else + MOVZX32Rm8toR(EAX,ECX); + break; + + case 16: + if( sign ) + MOVSX32Rm16toR(EAX,ECX); + else + MOVZX32Rm16toR(EAX,ECX); + break; + + case 32: + MOV32RmtoR(EAX,ECX); + break; + + jNO_DEFAULT + } + + u8* cont=JMP8(0); + x86SetJ8(_fullread); + int szidx; + + switch(bits) + { + case 8: szidx=0; break; + case 16: szidx=1; break; + case 32: szidx=2; break; + jNO_DEFAULT + } + + MOVZX32R8toR(EAX,EAX); + SUB32RtoR(ECX,EAX); + //eax=[funct+eax] + MOV32RmSOffsettoR(EAX,EAX,(int)RWFT[szidx][0],2); + SUB32ItoR(ECX,0x80000000); + CALL32R(EAX); + + // perform sign extension on the result: + + if( bits==8 ) + { + if( sign ) + MOVSX32R8toR(EAX,EAX); + else + MOVZX32R8toR(EAX,EAX); + } + else if( bits==16 ) + { + if( sign ) + MOVSX32R16toR(EAX,EAX); + else + MOVZX32R16toR(EAX,EAX); + } + + x86SetJ8(cont); +} + void vtlb_DynGenWrite(u32 sz) { MOV32RtoR(EAX,ECX); @@ -693,7 +782,7 @@ void vtlb_DynGenWrite(u32 sz) MOVZX32R8toR(EAX,EAX); SUB32RtoR(ECX,EAX); //eax=[funct+eax] - MOV32RmSOffsettoR(EAX,EAX,(int)&RWFT[szidx][1][0],2); + MOV32RmSOffsettoR(EAX,EAX,(int)RWFT[szidx][1],2); SUB32ItoR(ECX,0x80000000); CALL32R(EAX); diff --git a/pcsx2/vtlb.h b/pcsx2/vtlb.h index 708db65cd0..583a19b355 100644 --- a/pcsx2/vtlb.h +++ b/pcsx2/vtlb.h @@ -5,21 +5,20 @@ #ifndef PCSX2_VIRTUAL_MEM -#define mem8_t u8 -#define mem16_t u16 -#define mem32_t u32 -#define mem64_t u64 -#define mem128_t u64 +typedef u8 mem8_t; +typedef u16 mem16_t; +typedef u32 mem32_t; +typedef u64 mem64_t; +typedef u64 mem128_t; -// unsafe version needed to avoid template hell on gcc. :/ -typedef int __fastcall vltbMemRFP(u32 addr,void* data); - -typedef int __fastcall vltbMemR8FP(u32 addr,mem8_t* data); -typedef int __fastcall vltbMemR16FP(u32 addr,mem16_t* data); -typedef int __fastcall vltbMemR32FP(u32 addr,mem32_t* data); -typedef int __fastcall vltbMemR64FP(u32 addr,mem64_t* data); -typedef int __fastcall vltbMemR128FP(u32 addr,mem128_t* data); +// Specialized function pointers for each read type +typedef mem8_t __fastcall vltbMemR8FP(u32 addr); +typedef mem16_t __fastcall vltbMemR16FP(u32 addr); +typedef mem32_t __fastcall vltbMemR32FP(u32 addr); +typedef void __fastcall vltbMemR64FP(u32 addr,mem64_t* data); +typedef void __fastcall vltbMemR128FP(u32 addr,mem128_t* data); +// Specialized function pointers for each write type typedef void __fastcall vltbMemW8FP(u32 addr,mem8_t data); typedef void __fastcall vltbMemW16FP(u32 addr,mem16_t data); typedef void __fastcall vltbMemW32FP(u32 addr,mem32_t data); @@ -48,11 +47,11 @@ void vtlb_VMapUnmap(u32 vaddr,u32 sz); //Memory functions -int __fastcall vtlb_memRead8(u32 mem, u8 *out); -int __fastcall vtlb_memRead16(u32 mem, u16 *out); -int __fastcall vtlb_memRead32(u32 mem, u32 *out); -int __fastcall vtlb_memRead64(u32 mem, u64 *out); -int __fastcall vtlb_memRead128(u32 mem, u64 *out); +u8 __fastcall vtlb_memRead8(u32 mem); +u16 __fastcall vtlb_memRead16(u32 mem); +u32 __fastcall vtlb_memRead32(u32 mem); +void __fastcall vtlb_memRead64(u32 mem, u64 *out); +void __fastcall vtlb_memRead128(u32 mem, u64 *out); void __fastcall vtlb_memWrite8 (u32 mem, u8 value); void __fastcall vtlb_memWrite16(u32 mem, u16 value); void __fastcall vtlb_memWrite32(u32 mem, u32 value); @@ -60,7 +59,8 @@ void __fastcall vtlb_memWrite64(u32 mem, const u64* value); void __fastcall vtlb_memWrite128(u32 mem, const u64* value); extern void vtlb_DynGenWrite(u32 sz); -extern void vtlb_DynGenRead(u32 sz); +extern void vtlb_DynGenRead32(u32 bits, bool sign); +extern void vtlb_DynGenRead64(u32 sz); #endif diff --git a/pcsx2/windows/Debugger.cpp b/pcsx2/windows/Debugger.cpp index 20d88af237..11d72dcbe9 100644 --- a/pcsx2/windows/Debugger.cpp +++ b/pcsx2/windows/Debugger.cpp @@ -466,7 +466,9 @@ BOOL APIENTRY DebuggerProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam */ EnterRunningState(hDlg); - if (memRead32(cpuRegs.pc, &cpuRegs.code) != -1){ + memRead32(cpuRegs.pc, &cpuRegs.code); + + { u32 target_pc = 0; if (3 == (cpuRegs.code >> 26)){ /* it's a JAL instruction. */ @@ -483,7 +485,8 @@ BOOL APIENTRY DebuggerProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam Cpu->Step(); } } - DebuggerPC = 0; + + DebuggerPC = 0; DebuggerIOPPC=0; EnterHaltedState(hDlg); RefreshDebugAll(); diff --git a/pcsx2/x86/ix86-32/iR5900LoadStore.cpp b/pcsx2/x86/ix86-32/iR5900LoadStore.cpp index efc2da2672..ffb5cc92fe 100644 --- a/pcsx2/x86/ix86-32/iR5900LoadStore.cpp +++ b/pcsx2/x86/ix86-32/iR5900LoadStore.cpp @@ -2071,65 +2071,86 @@ void SetFastMemory(int bSetFast) // nothing } -void recLoad(u32 sz,bool sx) +void recLoad64( u32 bits, bool sign ) { + jASSUME( bits == 64 || bits == 128 ); + //no int 3? i love to get my hands dirty ;p - Raz //write8(0xCC); _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); - if (sz>=64) - EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension -> what does this really do ? + EEINST_RESETSIGNEXT(_Rt_); // remove the sign extension -> what does this really do ? _deleteEEreg(_Rt_, 0); + // Load ECX with the source memory address that we're reading from. MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); if ( _Imm_ != 0 ) ADD32ItoR( ECX, _Imm_ ); - - if (sz==128) + + if( bits == 128 ) // force 16 byte alignment on 128 bit reads AND32I8toR(ECX,0xF0); - if ( _Rt_ && sz>=64) + // Load EDX with the destination. 64/128 bit modes load the result directly into + // the cpuRegs.GPR struct. + + if ( _Rt_ ) MOV32ItoR(EDX, (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] ); else MOV32ItoR(EDX, (int)&dummyValue[0] ); - vtlb_DynGenRead(sz); + vtlb_DynGenRead64(bits); +} - /* - if (sz==8) - CALLFunc( (int)memRead8 ); - else if (sz==16) - CALLFunc( (int)memRead16 ); - else if (sz==32) - CALLFunc( (int)memRead32 ); - else if (sz==64) - CALLFunc( (int)memRead64 ); - else if (sz==128) - CALLFunc( (int)memRead128 ); - */ +void recLoad32(u32 bits,bool sign) +{ + jASSUME( bits <= 32 ); - if ( _Rt_ && sz<64) + //no int 3? i love to get my hands dirty ;p - Raz + //write8(0xCC); + + _deleteEEreg(_Rs_, 1); + _eeOnLoadWrite(_Rt_); + _deleteEEreg(_Rt_, 0); + + // Load ECX with the source memory address that we're reading from. + MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); + if ( _Imm_ != 0 ) + ADD32ItoR( ECX, _Imm_ ); + + // 8/16/32 bit modes return the loaded value in EAX. + //MOV32ItoR(EDX, (int)&dummyValue[0] ); + + vtlb_DynGenRead32(bits, sign); + + if ( _Rt_ ) { - MOV32MtoR( EAX, (int)&dummyValue[0] ); //ewww, lame ! movsx /zx has r/m forms too ... - if (sz==8) + // Perform sign extension if needed + + //MOV32MtoR( EAX, (int)&dummyValue[0] ); //ewww, lame ! movsx /zx has r/m forms too ... + /*if (bits==8) { - if (sx) + if (sign) + //MOVSX32M8toR( EAX, (int)&dummyValue[0] ); MOVSX32R8toR( EAX, EAX ); - else - MOVZX32R8toR( EAX, EAX ); + //else + //MOVZX32M8toR( EAX, (int)&dummyValue[0] ); + //MOVZX32R8toR( EAX, EAX ); } - else if (sz==16) + else if (bits==16) { - if (sx) + if (sign) + //MOVSX32M16toR( EAX, (int)&dummyValue[0] ); MOVSX32R16toR( EAX, EAX ); - else - MOVZX32R16toR( EAX, EAX ); - } - if (sx) - CDQ( ); + //else + //MOVZX32M16toR( EAX, (int)&dummyValue[0] ); + //MOVZX32R16toR( EAX, EAX ); + }*/ + + if (sign) + CDQ(); else XOR32RtoR(EDX,EDX); @@ -2137,10 +2158,11 @@ void recLoad(u32 sz,bool sx) MOV32RtoM( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 1 ], EDX ); } } + //////////////////////////////////////////////////// void recLB( void ) { - recLoad(8,true); + recLoad32(8,true); /* _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); @@ -2174,7 +2196,7 @@ void recLB( void ) //////////////////////////////////////////////////// void recLBU( void ) { - recLoad(8,false); + recLoad32(8,false); /* _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); @@ -2207,7 +2229,7 @@ void recLBU( void ) //////////////////////////////////////////////////// void recLH( void ) { - recLoad(16,true); + recLoad32(16,true); /* _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); @@ -2241,7 +2263,7 @@ void recLH( void ) //////////////////////////////////////////////////// void recLHU( void ) { - recLoad(16,false); + recLoad32(16,false); /* _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); @@ -2272,7 +2294,7 @@ void recLHU( void ) //////////////////////////////////////////////////// void recLW( void ) { - recLoad(32,true); + recLoad32(32,true); /* _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); @@ -2306,7 +2328,7 @@ void recLW( void ) //////////////////////////////////////////////////// void recLWU( void ) { - recLoad(32,false); + recLoad32(32,false); /* _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); @@ -2360,7 +2382,7 @@ extern void MOV64RmtoR( x86IntRegType to, x86IntRegType from ); void recLD( void ) { - recLoad(64,false); + recLoad64(64,false); /* _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); @@ -2414,7 +2436,7 @@ void recLDR( void ) //////////////////////////////////////////////////// void recLQ( void ) { - recLoad(128,false); + recLoad64(128,false); /* _deleteEEreg(_Rs_, 1); _eeOnLoadWrite(_Rt_); @@ -2641,13 +2663,12 @@ void recLWC1( void ) MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); if ( _Imm_ != 0 ) - { ADD32ItoR( ECX, _Imm_ ); - } - MOV32ItoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL ); //no 0 for fpu ? + //MOV32ItoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL ); //no 0 for fpu ? //CALLFunc( (int)memRead32 ); - vtlb_DynGenRead(32); + vtlb_DynGenRead32(32, false); + MOV32RtoM( (int)&fpuRegs.fpr[ _Rt_ ].UL, EAX ); } //////////////////////////////////////////////////// @@ -2658,9 +2679,7 @@ void recSWC1( void ) MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); if ( _Imm_ != 0 ) - { ADD32ItoR( ECX, _Imm_ ); - } MOV32MtoR(EDX, (int)&fpuRegs.fpr[ _Rt_ ].UL ); vtlb_DynGenWrite(32); @@ -2668,6 +2687,11 @@ void recSWC1( void ) //////////////////////////////////////////////////// +/********************************************************* +* Load and store for COP2 (VU0 unit) * +* Format: OP rt, offset(base) * +*********************************************************/ + #define _Ft_ _Rt_ #define _Fs_ _Rd_ #define _Fd_ _Sa_ @@ -2679,19 +2703,14 @@ void recLQC2( void ) MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); if ( _Imm_ != 0 ) - { ADD32ItoR( ECX, _Imm_); - } if ( _Rt_ ) - { MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] ); - } else - { MOV32ItoR(EDX, (int)&dummyValue[0] ); - } - vtlb_DynGenRead(128); + + vtlb_DynGenRead64(128); } //////////////////////////////////////////////////// @@ -2702,9 +2721,7 @@ void recSQC2( void ) MOV32MtoR( ECX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] ); if ( _Imm_ != 0 ) - { ADD32ItoR( ECX, _Imm_ ); - } MOV32ItoR(EDX, (int)&VU0.VF[_Ft_].UD[0] ); vtlb_DynGenWrite(128); diff --git a/pcsx2_2008.sln b/pcsx2_2008.sln index 65a36c3fc7..3f2798272b 100644 --- a/pcsx2_2008.sln +++ b/pcsx2_2008.sln @@ -10,36 +10,21 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pthreads", "pcsx2\windows\V EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug vm|Win32 = Debug vm|Win32 Debug vtlb|Win32 = Debug vtlb|Win32 - Devel vm|Win32 = Devel vm|Win32 Devel vtlb|Win32 = Devel vtlb|Win32 - Release vm|Win32 = Release vm|Win32 Release vtlb|Win32 = Release vtlb|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vm|Win32.ActiveCfg = Debug vm|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vm|Win32.Build.0 = Debug vm|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vtlb|Win32.ActiveCfg = Debug vtlb|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vtlb|Win32.Build.0 = Debug vtlb|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel vm|Win32.ActiveCfg = Devel vm|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel vm|Win32.Build.0 = Devel vm|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel vtlb|Win32.ActiveCfg = Devel vtlb|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel vtlb|Win32.Build.0 = Devel vtlb|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm|Win32.ActiveCfg = Release vm|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm|Win32.Build.0 = Release vm|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb|Win32.ActiveCfg = Release vtlb|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb|Win32.Build.0 = Release vtlb|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Debug vm|Win32.ActiveCfg = Debug|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Debug vm|Win32.Build.0 = Debug|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Debug vtlb|Win32.ActiveCfg = Debug|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Debug vtlb|Win32.Build.0 = Debug|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Devel vm|Win32.ActiveCfg = Release|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Devel vm|Win32.Build.0 = Release|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Devel vtlb|Win32.ActiveCfg = Release|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Devel vtlb|Win32.Build.0 = Release|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Release vm|Win32.ActiveCfg = Release|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Release vm|Win32.Build.0 = Release|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Release vtlb|Win32.ActiveCfg = Release|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Release vtlb|Win32.Build.0 = Release|Win32 EndGlobalSection diff --git a/pcsx2_suite_2008.sln b/pcsx2_suite_2008.sln index ab56caf55f..12c52fdcca 100644 --- a/pcsx2_suite_2008.sln +++ b/pcsx2_suite_2008.sln @@ -18,84 +18,45 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CDVDiso-Pg", "plugins\CDVDi EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug vm|Win32 = Debug vm|Win32 Debug vtlb|Win32 = Debug vtlb|Win32 - Devel vm|Win32 = Devel vm|Win32 Devel vtlb|Win32 = Devel vtlb|Win32 - Release vm|Win32 = Release vm|Win32 Release vtlb|Win32 = Release vtlb|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vm|Win32.ActiveCfg = Debug vm|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vm|Win32.Build.0 = Debug vm|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vtlb|Win32.ActiveCfg = Debug vtlb|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Debug vtlb|Win32.Build.0 = Debug vtlb|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel vm|Win32.ActiveCfg = Devel vm|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel vm|Win32.Build.0 = Devel vm|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel vtlb|Win32.ActiveCfg = Devel vtlb|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Devel vtlb|Win32.Build.0 = Devel vtlb|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm|Win32.ActiveCfg = Release vm|Win32 - {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vm|Win32.Build.0 = Release vm|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb|Win32.ActiveCfg = Release vtlb|Win32 {1CEFD830-2B76-4596-A4EE-BCD7280A60BD}.Release vtlb|Win32.Build.0 = Release vtlb|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Debug vm|Win32.ActiveCfg = Debug|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Debug vm|Win32.Build.0 = Debug|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Debug vtlb|Win32.ActiveCfg = Debug|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Debug vtlb|Win32.Build.0 = Debug|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Devel vm|Win32.ActiveCfg = Release|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Devel vm|Win32.Build.0 = Release|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Devel vtlb|Win32.ActiveCfg = Release|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Devel vtlb|Win32.Build.0 = Release|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Release vm|Win32.ActiveCfg = Release|Win32 - {26511268-2902-4997-8421-ECD7055F9E28}.Release vm|Win32.Build.0 = Release|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Release vtlb|Win32.ActiveCfg = Release|Win32 {26511268-2902-4997-8421-ECD7055F9E28}.Release vtlb|Win32.Build.0 = Release|Win32 - {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Debug vm|Win32.ActiveCfg = Debug|Win32 - {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Debug vm|Win32.Build.0 = Debug|Win32 {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Debug vtlb|Win32.ActiveCfg = Debug|Win32 {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Debug vtlb|Win32.Build.0 = Debug|Win32 - {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Devel vm|Win32.ActiveCfg = Devel|Win32 - {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Devel vm|Win32.Build.0 = Devel|Win32 {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Devel vtlb|Win32.ActiveCfg = Devel|Win32 {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Devel vtlb|Win32.Build.0 = Devel|Win32 - {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Release vm|Win32.ActiveCfg = Release|Win32 - {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Release vm|Win32.Build.0 = Release|Win32 {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Release vtlb|Win32.ActiveCfg = Release|Win32 {5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Release vtlb|Win32.Build.0 = Release|Win32 - {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Debug vm|Win32.ActiveCfg = Release|Win32 - {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Debug vm|Win32.Build.0 = Release|Win32 {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Debug vtlb|Win32.ActiveCfg = Debug|Win32 {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Debug vtlb|Win32.Build.0 = Debug|Win32 - {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Devel vm|Win32.ActiveCfg = Devel|Win32 - {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Devel vm|Win32.Build.0 = Devel|Win32 {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Devel vtlb|Win32.ActiveCfg = Devel|Win32 {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Devel vtlb|Win32.Build.0 = Devel|Win32 - {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Release vm|Win32.ActiveCfg = Release|Win32 - {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Release vm|Win32.Build.0 = Release|Win32 {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Release vtlb|Win32.ActiveCfg = Release|Win32 {5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}.Release vtlb|Win32.Build.0 = Release|Win32 - {7F059854-568D-4E08-9D00-1E78E203E4DC}.Debug vm|Win32.ActiveCfg = Debug|Win32 - {7F059854-568D-4E08-9D00-1E78E203E4DC}.Debug vm|Win32.Build.0 = Debug|Win32 {7F059854-568D-4E08-9D00-1E78E203E4DC}.Debug vtlb|Win32.ActiveCfg = Debug|Win32 {7F059854-568D-4E08-9D00-1E78E203E4DC}.Debug vtlb|Win32.Build.0 = Debug|Win32 - {7F059854-568D-4E08-9D00-1E78E203E4DC}.Devel vm|Win32.ActiveCfg = Release|Win32 - {7F059854-568D-4E08-9D00-1E78E203E4DC}.Devel vm|Win32.Build.0 = Release|Win32 {7F059854-568D-4E08-9D00-1E78E203E4DC}.Devel vtlb|Win32.ActiveCfg = Release|Win32 {7F059854-568D-4E08-9D00-1E78E203E4DC}.Devel vtlb|Win32.Build.0 = Release|Win32 - {7F059854-568D-4E08-9D00-1E78E203E4DC}.Release vm|Win32.ActiveCfg = Release|Win32 - {7F059854-568D-4E08-9D00-1E78E203E4DC}.Release vm|Win32.Build.0 = Release|Win32 {7F059854-568D-4E08-9D00-1E78E203E4DC}.Release vtlb|Win32.ActiveCfg = Release|Win32 {7F059854-568D-4E08-9D00-1E78E203E4DC}.Release vtlb|Win32.Build.0 = Release|Win32 - {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Debug vm|Win32.ActiveCfg = Debug|Win32 - {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Debug vm|Win32.Build.0 = Debug|Win32 {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Debug vtlb|Win32.ActiveCfg = Debug|Win32 {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Debug vtlb|Win32.Build.0 = Debug|Win32 - {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Devel vm|Win32.ActiveCfg = Release|Win32 - {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Devel vm|Win32.Build.0 = Release|Win32 {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Devel vtlb|Win32.ActiveCfg = Release|Win32 {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Devel vtlb|Win32.Build.0 = Release|Win32 - {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Release vm|Win32.ActiveCfg = Release|Win32 - {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Release vm|Win32.Build.0 = Release|Win32 {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Release vtlb|Win32.ActiveCfg = Release|Win32 {5F78E90B-BD22-47B1-9CA5-7A80F4DF5EF3}.Release vtlb|Win32.Build.0 = Release|Win32 EndGlobalSection