Merge const qualifiers and cleanups from ReorderingMTGS: Includes the VIF DIRECT changes, which seem to be stable this time. ;)

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3549 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-07-22 12:20:11 +00:00
parent 095e46246d
commit bc849cc042
27 changed files with 346 additions and 327 deletions

View File

@ -71,7 +71,7 @@ wxString DiagnosticOrigin::ToString( const wxChar* msg ) const
bool pxAssertImpl_LogIt( const DiagnosticOrigin& origin, const wxChar *msg )
{
wxLogError( L"%s", origin.ToString( msg ) );
wxLogError( L"%s", origin.ToString( msg ).c_str() );
return false;
}

View File

@ -324,7 +324,6 @@ u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize)
pxAssert( (cmpsize&7) == 0 );
__asm {
push esi
mov ecx, cmpsize
mov edx, src1
mov esi, src2
@ -486,7 +485,6 @@ Done:
xor eax, eax
End:
pop esi
emms
}
}

View File

@ -19,9 +19,9 @@
#include "System.h"
#include "Memory.h"
#include "R5900.h"
#include "Hw.h"
#include "Dmac.h"
#include "R5900.h"
#include "SaveState.h"
#include "DebugTools/Debug.h"

View File

@ -13,9 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __DMAC_H__
#define __DMAC_H__
#pragma once
extern u8 *psH; // hw mem
@ -66,7 +64,7 @@ enum std_type
STD_SIF1
};
enum TransferMode
enum LogicalTransferMode
{
NORMAL_MODE = 0,
CHAIN_MODE,
@ -85,7 +83,7 @@ enum TransferMode
union tDMA_TAG {
struct {
u32 QWC : 16;
u32 reserved2 : 10;
u32 _reserved2 : 10;
u32 PCE : 2;
u32 ID : 3;
u32 IRQ : 1;
@ -121,14 +119,14 @@ union tDMA_TAG {
union tDMA_CHCR {
struct {
u32 DIR : 1; // Direction: 0 - to memory, 1 - from memory. VIF1 & SIF2 only.
u32 reserved1 : 1;
u32 MOD : 2;
u32 _reserved1 : 1;
u32 MOD : 2; // Logical transfer mode. Normal, Chain, or Interleave (see LogicalTransferMode enum)
u32 ASP : 2; // ASP1 & ASP2; Address stack pointer. 0, 1, or 2 addresses.
u32 TTE : 1; // Tag Transfer Enable. 0 - Disable / 1 - Enable.
u32 TIE : 1; // Tag Interrupt Enable. 0 - Disable / 1 - Enable.
u32 STR : 1; // Start. 0 while stopping DMA, 1 while it's running.
u32 reserved2 : 7;
u32 TAG : 16;
u32 _reserved2 : 7;
u32 TAG : 16; // Maintains upper 16 bits of the most recently read DMAtag.
};
u32 _u32;
@ -189,7 +187,8 @@ union tDMA_TADR {
tDMA_TAG tag() { return (tDMA_TAG)_u32; }
};
union tDMA_ASR { // The Address Stack Register
// The Address Stack Register
union tDMA_ASR {
struct {
u32 ADDR : 31; // Tag memory address
u32 SPR : 1; // Memory/SPR Address
@ -206,7 +205,7 @@ union tDMA_ASR { // The Address Stack Register
union tDMA_QWC {
struct {
u32 QWC : 16;
u32 reserved2 : 16;
u32 _reserved2 : 16;
};
u32 _u32;
@ -222,17 +221,17 @@ static __forceinline void throwBusError(const char *s);
struct DMACh {
tDMA_CHCR chcr;
u32 null0[3];
u32 _null0[3];
u32 madr;
u32 null1[3];
u32 _null1[3];
u16 qwc; u16 pad;
u32 null2[3];
u32 _null2[3];
u32 tadr;
u32 null3[3];
u32 _null3[3];
u32 asr0;
u32 null4[3];
u32 _null4[3];
u32 asr1;
u32 null5[11];
u32 _null5[11];
u32 sadr;
void chcrTransfer(tDMA_TAG* ptag)
@ -332,25 +331,6 @@ enum dmac_conditions
DMAC_STAT_MEIM = (1<<30) // mfifo mask
};
enum DMACIrqs
{
DMAC_VIF0 = 0,
DMAC_VIF1,
DMAC_GIF,
DMAC_FROM_IPU,
DMAC_TO_IPU,
DMAC_SIF0,
DMAC_SIF1,
DMAC_SIF2,
DMAC_FROM_SPR,
DMAC_TO_SPR,
// We're setting error conditions through hwDmacIrq, so these correspond to the conditions above.
DMAC_STALL_SIS = 13, // SIS
DMAC_MFIFO_EMPTY = 14, // MEIS
DMAC_BUS_ERROR = 15 // BEIS
};
//DMA interrupts & masks
enum DMAInter
{
@ -429,7 +409,7 @@ static __forceinline int ChannelNumber(u32 addr)
case D9_CHCR: return 9;
default:
{
DevCon.Warning("Invalid DMA channel number");
pxFailDev("Invalid DMA channel number");
return 51; // some value
}
}
@ -443,7 +423,7 @@ union tDMAC_CTRL {
u32 STS : 2; // Stall Control source channel (sts type)
u32 STD : 2; // Stall Control drain channel (std_type)
u32 RCYC : 3; // Release cycle (8/16/32/64/128/256)
u32 reserved1 : 21;
u32 _reserved1 : 21;
};
u32 _u32;
@ -459,15 +439,15 @@ union tDMAC_CTRL {
union tDMAC_STAT {
struct {
u32 CIS : 10;
u32 reserved1 : 3;
u32 _reserved1 : 3;
u32 SIS : 1;
u32 MEIS : 1;
u32 BEIS : 1;
u32 CIM : 10;
u32 reserved2 : 3;
u32 _reserved2 : 3;
u32 SIM : 1;
u32 MEIM : 1;
u32 reserved3 : 1;
u32 _reserved3 : 1;
};
u32 _u32;
@ -483,9 +463,9 @@ union tDMAC_STAT {
union tDMAC_PCR {
struct {
u32 CPC : 10;
u32 reserved1 : 6;
u32 _reserved1 : 6;
u32 CDE : 10;
u32 reserved2 : 5;
u32 _reserved2 : 5;
u32 PCE : 1;
};
u32 _u32;
@ -502,9 +482,9 @@ union tDMAC_PCR {
union tDMAC_SQWC {
struct {
u32 SQWC : 8;
u32 reserved1 : 8;
u32 _reserved1 : 8;
u32 TQWC : 8;
u32 reserved2 : 8;
u32 _reserved2 : 8;
};
u32 _u32;
@ -520,7 +500,7 @@ union tDMAC_SQWC {
union tDMAC_RBSR {
struct {
u32 RMSK : 31;
u32 reserved1 : 1;
u32 _reserved1 : 1;
};
u32 _u32;
@ -533,7 +513,7 @@ union tDMAC_RBSR {
union tDMAC_RBOR {
struct {
u32 ADDR : 31;
u32 reserved1 : 1;
u32 _reserved1 : 1;
};
u32 _u32;
@ -560,18 +540,18 @@ union tDMAC_STADR {
struct DMACregisters
{
tDMAC_CTRL ctrl;
u32 padding[3];
u32 _padding[3];
tDMAC_STAT stat;
u32 padding1[3];
u32 _padding1[3];
tDMAC_PCR pcr;
u32 padding2[3];
u32 _padding2[3];
tDMAC_SQWC sqwc;
u32 padding3[3];
u32 _padding3[3];
tDMAC_RBSR rbsr;
u32 padding4[3];
u32 _padding4[3];
tDMAC_RBOR rbor;
u32 padding5[3];
u32 _padding5[3];
tDMAC_STADR stadr;
};
@ -579,7 +559,7 @@ struct DMACregisters
union tINTC_STAT {
struct {
u32 interrupts : 10;
u32 placeholder : 22;
u32 _placeholder : 22;
};
u32 _u32;
@ -595,7 +575,7 @@ union tINTC_STAT {
union tINTC_MASK {
struct {
u32 int_mask : 10;
u32 placeholder:22;
u32 _placeholder:22;
};
u32 _u32;
@ -611,7 +591,7 @@ union tINTC_MASK {
struct INTCregisters
{
tINTC_STAT stat;
u32 padding[3];
u32 _padding[3];
tINTC_MASK mask;
};
@ -700,7 +680,3 @@ extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
extern bool hwDmacSrcChainWithStack(DMACh *dma, int id);
extern bool hwDmacSrcChain(DMACh *dma, int id);
extern void intcInterrupt();
extern void dmacInterrupt();
#endif

View File

@ -533,7 +533,7 @@ void mfifoGIFtransfer(int qwc)
if (gifRegs->ctrl.PSE) // temporarily stop
{
Console.WriteLn("Gif dma temp paused?");
CPU_INT(11, 16);
CPU_INT(DMAC_MFIFO_GIF, 16);
return;
}
@ -611,7 +611,7 @@ void mfifoGIFtransfer(int qwc)
}
if ((gif->qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate = GIF_STATE_STALL;
CPU_INT(11,mfifocycles);
CPU_INT(DMAC_MFIFO_GIF,mfifocycles);
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
}
@ -624,7 +624,7 @@ void gifMFIFOInterrupt()
if(SIGNAL_IMR_Pending == true)
{
//DevCon.Warning("Path 3 Paused");
CPU_INT(11, 128);
CPU_INT(DMAC_MFIFO_GIF, 128);
return;
}

View File

@ -13,8 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HARDWARE_H__
#define __HARDWARE_H__
#pragma once
// The full suite of hardware APIs:
#include "Counters.h"
@ -26,5 +25,3 @@
#include "Sif.h"
#include "Vif.h"
#include "Vif_Dma.h"
#endif

View File

@ -17,8 +17,6 @@
#ifndef __HW_H__
#define __HW_H__
extern void CPU_INT( u32 n, s32 ecycle );
//////////////////////////////////////////////////////////////////////////
// Hardware FIFOs (128 bit access only!)
//

View File

@ -291,10 +291,10 @@ static __forceinline void _cpuTestInterrupts()
/* These are 'pcsx2 interrupts', they handle asynchronous stuff
that depends on the cycle timings */
TESTINT(1, vif1Interrupt);
TESTINT(2, gsInterrupt);
TESTINT(5, EEsif0Interrupt);
TESTINT(6, EEsif1Interrupt);
TESTINT(DMAC_VIF1, vif1Interrupt);
TESTINT(DMAC_GIF, gsInterrupt);
TESTINT(DMAC_SIF0, EEsif0Interrupt);
TESTINT(DMAC_SIF1, EEsif1Interrupt);
// Profile-guided Optimization (sorta)
// The following ints are rarely called. Encasing them in a conditional
@ -302,16 +302,16 @@ static __forceinline void _cpuTestInterrupts()
if( cpuRegs.interrupt & 0xF19 ) // Bits 0 3 4 8 9 10 11 ( 111100011001 )
{
TESTINT(0, vif0Interrupt);
TESTINT(DMAC_VIF0, vif0Interrupt);
TESTINT(3, ipu0Interrupt);
TESTINT(4, ipu1Interrupt);
TESTINT(DMAC_FROM_IPU, ipu0Interrupt);
TESTINT(DMAC_TO_IPU, ipu1Interrupt);
TESTINT(8, SPRFROMinterrupt);
TESTINT(9, SPRTOinterrupt);
TESTINT(DMAC_FROM_SPR, SPRFROMinterrupt);
TESTINT(DMAC_TO_SPR, SPRTOinterrupt);
TESTINT(10, vifMFIFOInterrupt);
TESTINT(11, gifMFIFOInterrupt);
TESTINT(DMAC_MFIFO_VIF, vifMFIFOInterrupt);
TESTINT(DMAC_MFIFO_GIF, gifMFIFOInterrupt);
}
}
@ -547,7 +547,7 @@ __forceinline void cpuTestHwInts() {
cpuTestTIMRInts();
}
__forceinline void CPU_INT( u32 n, s32 ecycle)
__forceinline void CPU_INT( EE_EventType n, s32 ecycle)
{
if( n != 2 && cpuRegs.interrupt & (1<<n) ){ //2 is Gif, and every path 3 masking game triggers this :/
DevCon.Warning( "***** EE > Twice-thrown int on IRQ %d", n );

View File

@ -378,6 +378,33 @@ extern R5900cpu *Cpu;
extern R5900cpu intCpu;
extern R5900cpu recCpu;
enum EE_EventType
{
DMAC_VIF0 = 0,
DMAC_VIF1,
DMAC_GIF,
DMAC_FROM_IPU,
DMAC_TO_IPU,
DMAC_SIF0,
DMAC_SIF1,
DMAC_SIF2,
DMAC_FROM_SPR,
DMAC_TO_SPR,
DMAC_MFIFO_VIF,
DMAC_MFIFO_GIF,
// We're setting error conditions through hwDmacIrq, so these correspond to the conditions above.
DMAC_STALL_SIS = 13, // SIS
DMAC_MFIFO_EMPTY = 14, // MEIS
DMAC_BUS_ERROR = 15 // BEIS
};
extern void CPU_INT( EE_EventType n, s32 ecycle );
extern void intcInterrupt();
extern void dmacInterrupt();
extern void cpuInit();
extern void cpuReset(); // can throw Exception::FileNotFound.
extern void cpuException(u32 code, u32 bd);

View File

@ -141,7 +141,7 @@ _f void vif0FBRST(u32 value) {
// loop necessary for spiderman
//vif0ch->chcr.STR = true;
if(vif0ch->chcr.STR == true) CPU_INT(DMAC_VIF0, 0); // Gets the timing right - Flatout
if(vif0ch->chcr.STR) CPU_INT(DMAC_VIF0, 0); // Gets the timing right - Flatout
}
}
}
@ -224,7 +224,7 @@ _f void vif1FBRST(u32 value) {
{
case MFD_VIF1:
//Console.WriteLn("MFIFO Stall");
if(vif1ch->chcr.STR == true) CPU_INT(10, 0);
if(vif1ch->chcr.STR == true) CPU_INT(DMAC_MFIFO_VIF, 0);
break;
case NO_MFD:

View File

@ -15,6 +15,8 @@
#pragma once
#include "R5900.h"
enum vif0_stat_flags
{
VIF0_STAT_VPS_W = (1),
@ -88,7 +90,7 @@ union tVIF_STAT {
u32 VPS : 2; // Vif(0/1) status; 00 - idle, 01 - waiting for data following vifcode, 10 - decoding vifcode, 11 - decompressing/trasferring data follwing vifcode.
u32 VEW : 1; // E-bit wait (1 - wait, 0 - don't wait)
u32 VGW : 1; // Status waiting for the end of gif transfer (Vif1 only)
u32 reserved : 2;
u32 _reserved : 2;
u32 MRK : 1; // Mark Detect
u32 DBF : 1; // Double Buffer Flag
u32 VSS : 1; // Stopped by STOP
@ -97,7 +99,7 @@ union tVIF_STAT {
u32 INT : 1; // Intereupt by the i bit.
u32 ER0 : 1; // DmaTag Mismatch error.
u32 ER1 : 1; // VifCode error
u32 reserved2 : 9;
u32 _reserved2 : 9;
u32 FDR : 1; // VIF/FIFO transfer direction. (false - memory -> Vif, true - Vif -> memory)
u32 FQC : 5; // Amount of data. Up to 8 qwords on Vif0, 16 on Vif1.
};
@ -119,7 +121,7 @@ union tVIF_FBRST {
u32 FBK : 1; // Causes a Forcebreak to Vif((0/1) when true. (Stall)
u32 STP : 1; // Stops after the end of the Vifcode in progress when true. (Stall)
u32 STC : 1; // Cancels the Vif(0/1) stall and clears Vif Stats VSS, VFS, VIS, INT, ER0 & ER1.
u32 reserved : 28;
u32 _reserved : 28;
};
u32 _u32;
@ -138,7 +140,7 @@ union tVIF_ERR {
u32 MII : 1; // Masks Stat INT.
u32 ME0 : 1; // Masks Stat Err0.
u32 ME1 : 1; // Masks Stat Err1.
u32 reserved : 29;
u32 _reserved : 29;
};
u32 _u32;
@ -159,53 +161,53 @@ struct vifCycle
struct VIFregisters {
tVIF_STAT stat;
u32 pad0[3];
u32 _pad0[3];
u32 fbrst;
u32 pad1[3];
u32 _pad1[3];
tVIF_ERR err;
u32 pad2[3];
u32 _pad2[3];
u32 mark;
u32 pad3[3];
u32 _pad3[3];
vifCycle cycle; //data write cycle
u32 pad4[3];
u32 _pad4[3];
u32 mode;
u32 pad5[3];
u32 _pad5[3];
u32 num;
u32 pad6[3];
u32 _pad6[3];
u32 mask;
u32 pad7[3];
u32 _pad7[3];
u32 code;
u32 pad8[3];
u32 _pad8[3];
u32 itops;
u32 pad9[3];
u32 _pad9[3];
u32 base; // Not used in VIF0
u32 pad10[3];
u32 _pad10[3];
u32 ofst; // Not used in VIF0
u32 pad11[3];
u32 _pad11[3];
u32 tops; // Not used in VIF0
u32 pad12[3];
u32 _pad12[3];
u32 itop;
u32 pad13[3];
u32 _pad13[3];
u32 top; // Not used in VIF0
u32 pad14[3];
u32 _pad14[3];
u32 mskpath3;
u32 pad15[3];
u32 _pad15[3];
u32 r0; // row0 register
u32 pad16[3];
u32 _pad16[3];
u32 r1; // row1 register
u32 pad17[3];
u32 _pad17[3];
u32 r2; // row2 register
u32 pad18[3];
u32 _pad18[3];
u32 r3; // row3 register
u32 pad19[3];
u32 _pad19[3];
u32 c0; // col0 register
u32 pad20[3];
u32 _pad20[3];
u32 c1; // col1 register
u32 pad21[3];
u32 _pad21[3];
u32 c2; // col2 register
u32 pad22[3];
u32 _pad22[3];
u32 c3; // col3 register
u32 pad23[3];
u32 _pad23[3];
u32 offset; // internal UNPACK offset
u32 addr;
};
@ -218,10 +220,9 @@ extern VIFregisters *vifRegs;
#define vif1Regs (&vif1RegsRef)
#define _vifT template <int idx>
#define vifX (idx ? (vif1) : (vif0))
#define GetVifX (idx ? (vif1) : (vif0))
#define vifXch (idx ? (vif1ch) : (vif0ch))
#define vifXRegs (idx ? (vif1Regs) : (vif0Regs))
#define vifXCode (idx ? (vif1Code) : (vif0Code))
#define _f __forceinline
#define _ri __releaseinline
@ -231,4 +232,4 @@ extern void mfifoVIF1transfer(int qwc);
extern bool VIF0transfer(u32 *data, int size);
extern bool VIF1transfer(u32 *data, int size);
extern void vifMFIFOInterrupt();
extern bool CheckPath2GIF(int channel);
extern bool CheckPath2GIF(EE_EventType channel);

View File

@ -46,7 +46,7 @@ __forceinline void vif1FLUSH()
//DevCon.Warning("VIF1 adding %x cycles", (VU1.cycle - _cycles) * BIAS);
g_vifCycles += (VU1.cycle - _cycles) * BIAS;
}
if(gifRegs->stat.P1Q == true && (vif1.cmd & 0x7f) != 0x14 && (vif1.cmd & 0x7f) != 0x17)
if(gifRegs->stat.P1Q && ((vif1.cmd & 0x7f) != 0x14) && ((vif1.cmd & 0x7f) != 0x17))
{
vif1.vifstalled = true;
vif1Regs->stat.VGW = true;
@ -183,6 +183,7 @@ bool _VIF1chain()
__forceinline void vif1SetupTransfer()
{
tDMA_TAG *ptag;
DMACh& vif1c = (DMACh&)PS2MEM_HW[0x9000];
switch (vif1.dmamode)
{
@ -194,22 +195,20 @@ __forceinline void vif1SetupTransfer()
break;
case VIF_CHAIN_MODE:
ptag = dmaGetAddr(vif1ch->tadr, false); //Set memory pointer to TADR
ptag = dmaGetAddr(vif1c.tadr, false); //Set memory pointer to TADR
if (!(vif1ch->transfer("Vif1 Tag", ptag))) return;
if (!(vif1c.transfer("Vif1 Tag", ptag))) return;
vif1ch->madr = ptag[1]._u32; //MADR = ADDR field + SPR
vif1c.madr = ptag[1]._u32; //MADR = ADDR field + SPR
g_vifCycles += 1; // Add 1 g_vifCycles from the QW read for the tag
// Transfer dma tag if tte is set
VIF_LOG("VIF1 Tag %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx\n",
ptag[1]._u32, ptag[0]._u32, vif1ch->qwc, ptag->ID, vif1ch->madr, vif1ch->tadr);
ptag[1]._u32, ptag[0]._u32, vif1c.qwc, ptag->ID, vif1c.madr, vif1c.tadr);
if (!vif1.done && ((dmacRegs->ctrl.STD == STD_VIF1) && (ptag->ID == TAG_REFS))) // STD == VIF1
{
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
if ((vif1ch->madr + vif1ch->qwc * 16) >= dmacRegs->stadr.ADDR)
if ((vif1c.madr + vif1c.qwc * 16) >= dmacRegs->stadr.ADDR)
{
// stalled
hwDmacIrq(DMAC_STALL_SIS);
@ -220,16 +219,20 @@ __forceinline void vif1SetupTransfer()
vif1.inprogress = 0;
if (vif1ch->chcr.TTE)
if (vif1c.chcr.TTE)
{
// Transfer dma tag if tte is set
bool ret;
if (vif1.vifstalled)
{
ret = VIF1transfer((u32*)ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset); //Transfer Tag on stall
}
else
ret = VIF1transfer((u32*)ptag + 2, 2); //Transfer Tag
if ((ret == false) && vif1.irqoffset < 2)
if (!ret && vif1.irqoffset < 2)
{
vif1.inprogress = 0; //Better clear this so it has to do it again (Jak 1)
return; //IRQ set by VIFTransfer
@ -240,10 +243,10 @@ __forceinline void vif1SetupTransfer()
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
if(vif1ch->qwc > 0) vif1.inprogress = 1;
if(vif1c.qwc > 0) vif1.inprogress = 1;
//Check TIE bit of CHCR and IRQ bit of tag
if (vif1ch->chcr.TIE && ptag->IRQ)
if (vif1c.chcr.TIE && ptag->IRQ)
{
VIF_LOG("dmaIrq Set");
@ -257,13 +260,13 @@ __forceinline void vif1SetupTransfer()
extern bool SIGNAL_IMR_Pending;
bool CheckPath2GIF(int channel)
bool CheckPath2GIF(EE_EventType channel)
{
if ((vif1Regs->stat.VGW))
{
if( vif1.GifWaitState == 0 ) //DIRECT/HL Check
{
if(GSTransferStatus.PTH3 < IDLE_MODE || gifRegs->stat.P1Q == true)
if(GSTransferStatus.PTH3 < IDLE_MODE || gifRegs->stat.P1Q)
{
if(gifRegs->stat.IMT && GSTransferStatus.PTH3 <= IMAGE_MODE && (vif1.cmd & 0x7f) == 0x50 && gifRegs->stat.P1Q == false)
{
@ -366,7 +369,7 @@ __forceinline void vif1Interrupt()
return;
}
//We need to check the direction, if it is downloading from the GS, we handle that seperately (KH2 for testing)
//We need to check the direction, if it is downloading from the GS, we handle that separately (KH2 for testing)
if (vif1ch->chcr.DIR)
{
if (!CheckPath2GIF(DMAC_VIF1)) return;
@ -375,11 +378,11 @@ __forceinline void vif1Interrupt()
//Simulated GS transfer time done, clear the flags
}
if (!(vif1ch->chcr.STR)) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch->chcr._u32);
if (!vif1ch->chcr.STR) Console.WriteLn("Vif1 running when CHCR == %x", vif1ch->chcr._u32);
if (vif1.cmd)
{
if (vif1.done == true && vif1ch->qwc == 0) vif1Regs->stat.VPS = VPS_WAITING;
if (vif1.done && (vif1ch->qwc == 0)) vif1Regs->stat.VPS = VPS_WAITING;
}
else
{
@ -395,7 +398,7 @@ __forceinline void vif1Interrupt()
{
//vif1Regs->stat.FQC = 0;
//NFSHPS stalls when the whole packet has gone across (it stalls int he last 32bit cmd)
//NFSHPS stalls when the whole packet has gone across (it stalls in the last 32bit cmd)
//In this case VIF will end
if(vif1ch->qwc > 0 || !vif1.done) return;
}

View File

@ -142,9 +142,9 @@ void mfifoVIF1transfer(int qwc)
if (vif1.inprogress & 0x10)
{
if (vif1ch->madr >= dmacRegs->rbor.ADDR && vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
CPU_INT(10, 0);
CPU_INT(DMAC_MFIFO_VIF, 0);
else
CPU_INT(10, vif1ch->qwc * BIAS);
CPU_INT(DMAC_MFIFO_VIF, vif1ch->qwc * BIAS);
vif1Regs->stat.FQC = 0x10; // FQC=16
}
@ -247,7 +247,7 @@ void vifMFIFOInterrupt()
if (schedulepath3msk & 0x10) Vif1MskPath3();
if(vif1ch->chcr.DIR && CheckPath2GIF(10) == false) return;
if(vif1ch->chcr.DIR && CheckPath2GIF(DMAC_MFIFO_VIF) == false) return;
//We need to check the direction, if it is downloading from the GS, we handle that seperately (KH2 for testing)
//Simulated GS transfer time done, clear the flags
@ -292,15 +292,15 @@ void vifMFIFOInterrupt()
mfifoVIF1transfer(0);
if ((vif1ch->madr >= dmacRegs->rbor.ADDR) && (vif1ch->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK)))
CPU_INT(10, 0);
CPU_INT(DMAC_MFIFO_VIF, 0);
else
CPU_INT(10, vif1ch->qwc * BIAS);
CPU_INT(DMAC_MFIFO_VIF, vif1ch->qwc * BIAS);
return;
case 1: //Transfer data
mfifo_VIF1chain();
CPU_INT(10, 0);
CPU_INT(DMAC_MFIFO_VIF, 0);
return;
}
return;

View File

@ -21,7 +21,7 @@
#include "newVif.h"
#include "VUmicro.h"
#define vifOp(vifCodeName) _vifT int __fastcall vifCodeName(int pass, u32 *data)
#define vifOp(vifCodeName) _vifT int __fastcall vifCodeName(int pass, const u32 *data)
#define pass1 if (pass == 0)
#define pass2 if (pass == 1)
#define pass3 if (pass == 2)
@ -77,7 +77,7 @@ static _f void vuExecMicro(int idx, u32 addr) {
if(!idx) { g_vu0Cycles += (VU0.cycle-startcycles) * BIAS; g_packetsizeonvu = vif0.vifpacketsize; }
else { g_vu1Cycles += (VU1.cycle-startcycles) * BIAS; g_packetsizeonvu = vif1.vifpacketsize; }
//DevCon.Warning("Ran VU%x, VU0 Cycles %x, VU1 Cycles %x", idx, g_vu0Cycles, g_vu1Cycles);
vifX.vifstalled = true;
GetVifX.vifstalled = true;
}
u8 schedulepath3msk = 0;
@ -116,7 +116,7 @@ vifOp(vifCode_Base) {
extern bool SIGNAL_IMR_Pending;
template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
template<int idx> _f int _vifCode_Direct(int pass, const u8* data, bool isDirectHL) {
pass1 {
vif1Only();
int vifImm = (u16)vif1Regs->code;
@ -172,78 +172,65 @@ template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
// should be checked, handled, and cleared from the EOP check in GIFPath only. --air
gifRegs->stat.clear_flags(GIF_STAT_P2Q);
// the tag size should ALWAYS be 128 bits (qwc). If it isn't, it means there's a serious bug
// somewhere in the VIF (likely relating to +/-'ing the tag.size during processing).
// NOTE: ICO [PAL] exploits this during bootup. Needs investigation. --air
//pxAssumeMsg( (vif1.tag.size & 3) == 0, "Invalid Vif1 DIRECT packet size detected!" );
uint minSize = aMin(vif1.vifpacketsize, vif1.tag.size);
uint ret;
nVifStruct& v = nVif[1];
const int ret = aMin(vif1.vifpacketsize, vif1.tag.size);
u32 size = ret << 2;
//gifRegs->stat.APATH = GIF_APATH2; //Flag is cleared in vif1interrupt to simulate it being in progress.
//In the original code we were saving this data, it seems if it does happen, its just blank, so we ignore it.
if (!size) { DevCon.WriteLn("Path2: No Data Transfer?"); }
if(vif1.vifpacketsize < 4 && v.bSize < 16)
if(minSize < 4)
{
memcpy(&v.buffer[v.bPtr], data, vif1.vifpacketsize << 2);
v.bSize += vif1.vifpacketsize << 2;
v.bPtr += vif1.vifpacketsize << 2;
vif1.tag.size -= vif1.vifpacketsize;
if(vif1.tag.size == 0)
// When TTE==1, the VIF might end up sending us 8-byte packets instead of the usual 16-byte
// variety, if DIRECT tags cross chain dma boundaries. The actual behavior of real hardware
// is unknown at this time, but it seems that games *only* ever try to upload zero'd data
// in this situation.
//
// Games that use TTE==1 and DIRECT in this fashion: ICO
//
// Because DIRECT normally has a strict QWC alignment requirement, and this funky behavior
// only seems to happen on TTE mode transfers with their split-64-bit packets, there shouldn't
// be any need to worry about queuing more than 16 bytes of data,
//
static __aligned16 u32 partial_write[4];
static uint partial_count = 0;
for( uint i=0; i<(minSize & 3); ++i)
partial_write[partial_count++] = ((u32*)data)[i];
pxAssume( partial_count <= 4 );
ret = 0;
if (partial_count == 4)
{
DevCon.Warning("Missaligned packet on DIRECT end!");
vif1.cmd = 0;
GetMTGS().PrepDataPacket(GIF_PATH_2, 1);
GIFPath_CopyTag(GIF_PATH_2, (u128*)partial_write, 1);
GetMTGS().SendDataPacket();
partial_count = 0;
ret = 4;
}
return vif1.vifpacketsize;
}
else
{
if(v.bSize)
{
int ret = 0;
if (!minSize)
DevCon.Warning("VIF DIRECT (PATH2): No Data Transfer?");
if(v.bSize < 16)
{
if(((16 - v.bSize) >> 2) > vif1.vifpacketsize) DevCon.Warning("Not Enough Data!");
ret = (16 - v.bSize) >> 2;
memcpy(&v.buffer[v.bPtr], data, ret << 2);
vif1.tag.size -= ret;
v.bSize = 0;
v.bPtr = 0;
}
GetMTGS().PrepDataPacket(GIF_PATH_2, 1);
GIFPath_CopyTag(GIF_PATH_2, (u128*)v.buffer, 1);
// TTE=1 mode is the only time we should be getting DIRECT packet sizes that are
// not a multiple of QWC, and those are assured to be under 128 bits in size.
// So if this assert is triggered then it probably means something else is amiss.
pxAssertMsg((minSize & 3) == 0, "DIRECT packet size is not a multiple of QWC." );
GetMTGS().PrepDataPacket(GIF_PATH_2, minSize/4);
ret = GIFPath_CopyTag(GIF_PATH_2, (u128*)data, minSize/4)*4;
GetMTGS().SendDataPacket();
}
vif1.tag.size -= ret;
if(vif1.tag.size == 0)
{
vif1.cmd = 0;
gifRegs->stat.clear_flags(GIF_STAT_APATH2 | GIF_STAT_OPH);
}
vif1.vifstalled = true;
return ret;
}
else
{
GetMTGS().PrepDataPacket(GIF_PATH_2, size/16);
uint count = GIFPath_CopyTag(GIF_PATH_2, (u128*)data, size/16) * 4;
GetMTGS().SendDataPacket();
vif1.tag.size -= count;
if(vif1.tag.size == 0)
{
vif1.cmd = 0;
}
vif1.vifstalled = true;
return count;
}
}
}
return 0;
}
@ -260,6 +247,7 @@ vifOp(vifCode_DirectHL) {
// ToDo: FixMe
vifOp(vifCode_Flush) {
vif1Only();
vifStruct& vifX = GetVifX;
pass1 { vifFlush(idx); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_Flush"); }
return 0;
@ -268,40 +256,42 @@ vifOp(vifCode_Flush) {
// ToDo: FixMe
vifOp(vifCode_FlushA) {
vif1Only();
vifStruct& vifX = GetVifX;
pass1 {
vifFlush(idx);
// Gif is already transferring so wait for it.
if (gifRegs->stat.P1Q == true || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) {
if (gifRegs->stat.P1Q || GSTransferStatus.PTH3 <= PENDINGSTOP_MODE) {
//DevCon.Warning("VIF FlushA Wait MSK = %x", vif1Regs->mskpath3);
//
//DevCon.WriteLn("FlushA path3 Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
vif1Regs->stat.VGW = true;
vif1.GifWaitState = 1;
vifX.GifWaitState = 1;
vifX.vifstalled = true;
} // else DevCon.WriteLn("FlushA path3 no Wait! PTH3 MD %x STR %x", GSTransferStatus.PTH3, gif->chcr.STR);
vifX.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_FlushA"); }
vifX.cmd = 0;
return 0;
}
// ToDo: FixMe
vifOp(vifCode_FlushE) {
vifStruct& vifX = GetVifX;
pass1 { vifFlush(idx); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_FlushE"); }
return 0;
}
vifOp(vifCode_ITop) {
pass1 { vifXRegs->itops = vifXRegs->code & 0x3ff; vifX.cmd = 0; }
pass1 { vifXRegs->itops = vifXRegs->code & 0x3ff; GetVifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_ITop"); }
return 0;
}
vifOp(vifCode_Mark) {
vifStruct& vifX = GetVifX;
pass1 {
vifXRegs->mark = (u16)vifXRegs->code;
vifXRegs->stat.MRK = true;
@ -311,18 +301,21 @@ vifOp(vifCode_Mark) {
return 0;
}
_f void _vifCode_MPG(int idx, u32 addr, u32 *data, int size) {
static _f void _vifCode_MPG(int idx, u32 addr, const u32 *data, int size) {
VURegs& VUx = idx ? VU1 : VU0;
pxAssume(VUx.Micro > 0);
if (memcmp(VUx.Micro + addr, data, size << 2)) {
if (!idx) CpuVU0->Clear(addr, size << 2); // Clear before writing!
else CpuVU1->Clear(addr, size << 2); // Clear before writing!
memcpy_fast(VUx.Micro + addr, data, size << 2);
if (memcmp_mmx(VUx.Micro + addr, data, size*4)) {
// Clear VU memory before writing!
// (VUs expect size to be 32-bit scale, same as VIF's internal working sizes)
if (!idx) CpuVU0->Clear(addr, size);
else CpuVU1->Clear(addr, size);
memcpy_fast(VUx.Micro + addr, data, size*4);
}
}
vifOp(vifCode_MPG) {
vifStruct& vifX = GetVifX;
pass1 {
int vifNum = (u8)(vifXRegs->code >> 16);
vifX.tag.addr = (u16)(vifXRegs->code << 3) & (idx ? 0x3fff : 0xfff);
@ -332,16 +325,16 @@ vifOp(vifCode_MPG) {
}
pass2 {
if (vifX.vifpacketsize < vifX.tag.size) { // Partial Transfer
if((vifX.tag.addr + vifX.vifpacketsize) > (idx ? 0x4000 : 0x1000)) {
if((vifX.tag.addr + vifX.vifpacketsize*4) > (idx ? 0x4000 : 0x1000)) {
DevCon.Warning("Vif%d MPG Split Overflow", idx);
}
_vifCode_MPG(idx, vifX.tag.addr, data, vifX.vifpacketsize);
vifX.tag.addr += vifX.vifpacketsize << 2;
vifX.tag.addr += vifX.vifpacketsize * 4;
vifX.tag.size -= vifX.vifpacketsize;
return vifX.vifpacketsize;
}
else { // Full Transfer
if((vifX.tag.addr + vifX.tag.size) > (idx ? 0x4000 : 0x1000)) {
if((vifX.tag.addr + vifX.tag.size*4) > (idx ? 0x4000 : 0x1000)) {
DevCon.Warning("Vif%d MPG Split Overflow", idx);
}
_vifCode_MPG(idx, vifX.tag.addr, data, vifX.tag.size);
@ -356,18 +349,21 @@ vifOp(vifCode_MPG) {
}
vifOp(vifCode_MSCAL) {
vifStruct& vifX = GetVifX;
pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0;}
pass3 { DevCon.WriteLn("vifCode_MSCAL"); }
return 0;
}
vifOp(vifCode_MSCALF) {
vifStruct& vifX = GetVifX;
pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_MSCALF"); }
return 0;
}
vifOp(vifCode_MSCNT) {
vifStruct& vifX = GetVifX;
pass1 { vifFlush(idx); vuExecMicro(idx, -1); vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_MSCNT"); }
return 0;
@ -377,7 +373,7 @@ vifOp(vifCode_MSCNT) {
vifOp(vifCode_MskPath3) {
vif1Only();
pass1 {
if (vif1ch->chcr.STR && vifX.lastcmd != 0x13) {
if (vif1ch->chcr.STR && vif1.lastcmd != 0x13) {
schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1);
vif1.vifstalled = true;
}
@ -385,20 +381,21 @@ vifOp(vifCode_MskPath3) {
schedulepath3msk = (vif1Regs->code >> 15) & 0x1;
Vif1MskPath3();
}
vifX.cmd = 0;
vif1.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_MskPath3"); }
return 0;
}
vifOp(vifCode_Nop) {
pass1 { vifX.cmd = 0; }
pass1 { GetVifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_Nop"); }
return 0;
}
// ToDo: Review Flags
vifOp(vifCode_Null) {
vifStruct& vifX = GetVifX;
pass1 {
// if ME1, then force the vif to interrupt
if (!(vifXRegs->err.ME1)) { // Ignore vifcode and tag mismatch error
@ -420,15 +417,16 @@ vifOp(vifCode_Offset) {
vif1Regs->stat.DBF = false;
vif1Regs->ofst = vif1Regs->code & 0x3ff;
vif1Regs->tops = vif1Regs->base;
vifX.cmd = 0;
vif1.cmd = 0;
}
pass3 { DevCon.WriteLn("vifCode_Offset"); }
return 0;
}
template<int idx> _f int _vifCode_STColRow(u32* data, u32* pmem1, u32* pmem2) {
int ret;
ret = min(4 - vifX.tag.addr, vifX.vifpacketsize);
template<int idx> static _f int _vifCode_STColRow(const u32* data, u32* pmem1, u32* pmem2) {
vifStruct& vifX = GetVifX;
int ret = min(4 - vifX.tag.addr, vifX.vifpacketsize);
pxAssume(vifX.tag.addr < 4);
pxAssume(ret > 0);
@ -457,6 +455,7 @@ template<int idx> _f int _vifCode_STColRow(u32* data, u32* pmem1, u32* pmem2) {
}
vifOp(vifCode_STCol) {
vifStruct& vifX = GetVifX;
pass1 {
vifX.tag.addr = 0;
vifX.tag.size = 4;
@ -473,6 +472,8 @@ vifOp(vifCode_STCol) {
}
vifOp(vifCode_STRow) {
vifStruct& vifX = GetVifX;
pass1 {
vifX.tag.addr = 0;
vifX.tag.size = 4;
@ -489,6 +490,7 @@ vifOp(vifCode_STRow) {
}
vifOp(vifCode_STCycl) {
vifStruct& vifX = GetVifX;
pass1 {
vifXRegs->cycle.cl = (u8)(vifXRegs->code);
vifXRegs->cycle.wl = (u8)(vifXRegs->code >> 8);
@ -499,6 +501,7 @@ vifOp(vifCode_STCycl) {
}
vifOp(vifCode_STMask) {
vifStruct& vifX = GetVifX;
pass1 { vifX.tag.size = 1; }
pass2 { vifXRegs->mask = data[0]; vifX.tag.size = 0; vifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_STMask"); }
@ -506,15 +509,15 @@ vifOp(vifCode_STMask) {
}
vifOp(vifCode_STMod) {
pass1 { vifXRegs->mode = vifXRegs->code & 0x3; vifX.cmd = 0; }
pass1 { vifXRegs->mode = vifXRegs->code & 0x3; GetVifX.cmd = 0; }
pass3 { DevCon.WriteLn("vifCode_STMod"); }
return 0;
}
vifOp(vifCode_Unpack) {
pass1 {
if (!idx) vif0UnpackSetup(data);
else vif1UnpackSetup(data);
if (!idx) vifUnpackSetup<0>(data);
else vifUnpackSetup<1>(data);
return 1;
}
pass2 { return nVifUnpack(idx, (u8*)data); }
@ -526,7 +529,9 @@ vifOp(vifCode_Unpack) {
// Vif0/Vif1 Code Tables
//------------------------------------------------------------------
int (__fastcall *vif0Code[128])(int pass, u32 *data) = {
__aligned16 FnType_VifCmdHandler* const vifCmdHandler[2][128] =
{
{
vifCode_Nop<0> , vifCode_STCycl<0> , vifCode_Offset<0> , vifCode_Base<0> , vifCode_ITop<0> , vifCode_STMod<0> , vifCode_MskPath3<0>, vifCode_Mark<0>, /*0x00*/
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x08*/
vifCode_FlushE<0> , vifCode_Flush<0> , vifCode_Null<0> , vifCode_FlushA<0> , vifCode_MSCAL<0> , vifCode_MSCALF<0> , vifCode_Null<0> , vifCode_MSCNT<0>, /*0x10*/
@ -543,9 +548,8 @@ int (__fastcall *vif0Code[128])(int pass, u32 *data) = {
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0>, /*0x68*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0>, /*0x70*/
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> /*0x78*/
};
int (__fastcall *vif1Code[128])(int pass, u32 *data) = {
},
{
vifCode_Nop<1> , vifCode_STCycl<1> , vifCode_Offset<1> , vifCode_Base<1> , vifCode_ITop<1> , vifCode_STMod<1> , vifCode_MskPath3<1>, vifCode_Mark<1>, /*0x00*/
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x08*/
vifCode_FlushE<1> , vifCode_Flush<1> , vifCode_Null<1> , vifCode_FlushA<1> , vifCode_MSCAL<1> , vifCode_MSCALF<1> , vifCode_Null<1> , vifCode_MSCNT<1>, /*0x10*/
@ -562,4 +566,5 @@ int (__fastcall *vif1Code[128])(int pass, u32 *data) = {
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1>, /*0x68*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1>, /*0x70*/
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> /*0x78*/
}
};

View File

@ -28,17 +28,17 @@ union tBITBLTBUF {
u64 _u64;
struct {
u32 SBP : 14;
u32 pad14 : 2;
u32 _pad14 : 2;
u32 SBW : 6;
u32 pad22 : 2;
u32 _pad22 : 2;
u32 SPSM : 6;
u32 pad30 : 2;
u32 _pad30 : 2;
u32 DBP : 14;
u32 pad46 : 2;
u32 _pad46 : 2;
u32 DBW : 6;
u32 pad54 : 2;
u32 _pad54 : 2;
u32 DPSM : 6;
u32 pad62 : 2;
u32 _pad62 : 2;
};
};
@ -46,9 +46,9 @@ union tTRXREG {
u64 _u64;
struct {
u32 RRW : 12;
u32 pad12 : 20;
u32 _pad12 : 20;
u32 RRH : 12;
u32 pad44 : 20;
u32 _pad44 : 20;
};
};
@ -93,8 +93,10 @@ extern void Vif1MskPath3();
extern void vif1Write32(u32 mem, u32 value);
extern void vif1Reset();
extern int (__fastcall *vif0Code[128])(int pass, u32 *data);
extern int (__fastcall *vif1Code[128])(int pass, u32 *data);
typedef int __fastcall FnType_VifCmdHandler(int pass, const u32 *data);
typedef FnType_VifCmdHandler* Fnptr_VifCmdHandler;
extern const __aligned16 Fnptr_VifCmdHandler vifCmdHandler[2][128];
__forceinline static int _limit(int a, int max)
{

View File

@ -33,6 +33,7 @@ _vifT bool runMark(u32* &data) {
// Returns 1 if i-bit && finished vifcode && i-bit not masked
_vifT bool analyzeIbit(u32* &data, int iBit) {
vifStruct& vifX = GetVifX;
if (iBit && !vifX.cmd && !vifXRegs->err.MII) {
//DevCon.WriteLn("Vif I-Bit IRQ");
vifX.irq++;
@ -69,6 +70,8 @@ _vifT bool analyzeIbit(u32* &data, int iBit) {
// Interprets packet
_vifT void vifTransferLoop(u32* &data) {
vifStruct& vifX = GetVifX;
u32& pSize = vifX.vifpacketsize;
int iBit = vifX.cmd >> 7;
@ -83,13 +86,13 @@ _vifT void vifTransferLoop(u32* &data) {
vifX.cmd = data[0] >> 24;
iBit = data[0] >> 31;
VIF_LOG("New VifCMD %x tagsize %x", vifX.cmd, vifX.tag.size);
vifXCode[vifX.cmd & 0x7f](0, data);
vifCmdHandler[idx][vifX.cmd & 0x7f](0, data);
data++; pSize--;
if (analyzeIbit<idx>(data, iBit)) break;
continue;
}
int ret = vifXCode[vifX.cmd & 0x7f](1, data);
int ret = vifCmdHandler[idx][vifX.cmd & 0x7f](1, data);
data += ret;
pSize -= ret;
if (analyzeIbit<idx>(data, iBit)) break;
@ -99,6 +102,8 @@ _vifT void vifTransferLoop(u32* &data) {
}
_vifT _f bool vifTransfer(u32 *data, int size) {
vifStruct& vifX = GetVifX;
// irqoffset necessary to add up the right qws, or else will spin (spiderman)
int transferred = vifX.vifstalled ? vifX.irqoffset : 0;
@ -125,7 +130,6 @@ _vifT _f bool vifTransfer(u32 *data, int size) {
else if(g_vifCycles >= g_vu1Cycles)g_vu1Cycles = 0;
}
vifX.irqoffset = transferred % 4; // cannot lose the offset
transferred = transferred >> 2;

View File

@ -89,7 +89,7 @@ static __releaseinline void writeXYZW(u32 offnum, u32 &dest, u32 data) {
}
template < bool doMask, class T >
static __forceinline void __fastcall UNPACK_S(u32 *dest, T *data, int size)
static __forceinline void __fastcall UNPACK_S(u32 *dest, const T *data, int size)
{
//S-# will always be a complete packet, no matter what. So we can skip the offset bits
writeXYZW<doMask>(OFFSET_X, *dest++, *data);
@ -99,7 +99,7 @@ static __forceinline void __fastcall UNPACK_S(u32 *dest, T *data, int size)
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V2(u32 *dest, T *data, int size)
static __forceinline void __fastcall UNPACK_V2(u32 *dest, const T *data, int size)
{
if (vifRegs->offset == OFFSET_X)
{
@ -135,7 +135,7 @@ static __forceinline void __fastcall UNPACK_V2(u32 *dest, T *data, int size)
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V3(u32 *dest, T *data, int size)
static __forceinline void __fastcall UNPACK_V3(u32 *dest, const T *data, int size)
{
if(vifRegs->offset == OFFSET_X)
{
@ -177,7 +177,7 @@ static __forceinline void __fastcall UNPACK_V3(u32 *dest, T *data, int size)
}
template <bool doMask, class T>
static __forceinline void __fastcall UNPACK_V4(u32 *dest, T *data , int size)
static __forceinline void __fastcall UNPACK_V4(u32 *dest, const T *data , int size)
{
while (size > 0)
{
@ -190,7 +190,7 @@ static __forceinline void __fastcall UNPACK_V4(u32 *dest, T *data , int size)
}
template< bool doMask >
static __releaseinline void __fastcall UNPACK_V4_5(u32 *dest, u32 *data, int size)
static __releaseinline void __fastcall UNPACK_V4_5(u32 *dest, const u32 *data, int size)
{
//As with S-#, this will always be a complete packet
writeXYZW<doMask>(OFFSET_X, *dest++, ((*data & 0x001f) << 3));
@ -202,31 +202,31 @@ static __releaseinline void __fastcall UNPACK_V4_5(u32 *dest, u32 *data, int siz
// =====================================================================================================
template < bool doMask, int size, class T >
static void __fastcall fUNPACK_S(u32 *dest, T *data)
static void __fastcall fUNPACK_S(u32 *dest, const T *data)
{
UNPACK_S<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V2(u32 *dest, T *data)
static void __fastcall fUNPACK_V2(u32 *dest, const T *data)
{
UNPACK_V2<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V3(u32 *dest, T *data)
static void __fastcall fUNPACK_V3(u32 *dest, const T *data)
{
UNPACK_V3<doMask>( dest, data, size );
}
template <bool doMask, int size, class T>
static void __fastcall fUNPACK_V4(u32 *dest, T *data)
static void __fastcall fUNPACK_V4(u32 *dest, const T *data)
{
UNPACK_V4<doMask>( dest, data, size );
}
template< bool doMask >
static void __fastcall fUNPACK_V4_5(u32 *dest, u32 *data)
static void __fastcall fUNPACK_V4_5(u32 *dest, const u32 *data)
{
UNPACK_V4_5<doMask>(dest, data, 0); // size is ignored.
}
@ -298,7 +298,9 @@ const __aligned16 VIFUnpackFuncTable VIFfuncTable[32] =
// Unpack Setup Code
//----------------------------------------------------------------------------
_vifT void vifUnpackSetup(u32 *data) {
_vifT void vifUnpackSetup(const u32 *data) {
vifStruct& vifX = GetVifX;
if ((vifXRegs->cycle.wl == 0) && (vifXRegs->cycle.wl < vifXRegs->cycle.cl)) {
Console.WriteLn("Vif%d CL %d, WL %d", idx, vifXRegs->cycle.cl, vifXRegs->cycle.wl);
@ -338,5 +340,5 @@ _vifT void vifUnpackSetup(u32 *data) {
vifXRegs->offset = 0;
}
void vif0UnpackSetup(u32 *data) { vifUnpackSetup<0>(data); }
void vif1UnpackSetup(u32 *data) { vifUnpackSetup<1>(data); }
template void vifUnpackSetup<0>(const u32 *data);
template void vifUnpackSetup<1>(const u32 *data);

View File

@ -15,14 +15,14 @@
#pragma once
typedef void (__fastcall *UNPACKFUNCTYPE)(u32 *dest, u32 *data);
typedef void (__fastcall *UNPACKFUNCTYPE_ODD)(u32 *dest, u32 *data, int size);
typedef int (*UNPACKPARTFUNCTYPESSE)(u32 *dest, u32 *data, int size);
typedef void (__fastcall *UNPACKFUNCTYPE)(u32 *dest, const u32 *data);
typedef void (__fastcall *UNPACKFUNCTYPE_ODD)(u32 *dest, const u32 *data, int size);
typedef int (*UNPACKPARTFUNCTYPESSE)(u32 *dest, const u32 *data, int size);
#define create_unpack_u_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_U##bits)(u32 *dest, u##bits *data);
#define create_unpack_odd_u_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_ODD_U##bits)(u32 *dest, u##bits *data, int size);
#define create_unpack_s_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_S##bits)(u32 *dest, s##bits *data);
#define create_unpack_odd_s_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_ODD_S##bits)(u32 *dest, s##bits *data, int size);
#define create_unpack_u_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_U##bits)(u32 *dest, const u##bits *data);
#define create_unpack_odd_u_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_ODD_U##bits)(u32 *dest, const u##bits *data, int size);
#define create_unpack_s_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_S##bits)(u32 *dest, const s##bits *data);
#define create_unpack_odd_s_type(bits) typedef void (__fastcall *UNPACKFUNCTYPE_ODD_S##bits)(u32 *dest, const s##bits *data, int size);
#define create_some_unpacks(bits) \
create_unpack_u_type(bits); \
@ -51,8 +51,8 @@ struct VIFUnpackFuncTable
extern const __aligned16 VIFUnpackFuncTable VIFfuncTable[32];
extern int nVifUnpack (int idx, u8 *data);
extern int nVifUnpack (int idx, const u8 *data);
extern void resetNewVif(int idx);
extern __forceinline void vif0UnpackSetup(u32 *data);
extern __forceinline void vif1UnpackSetup(u32 *data);
template< int idx >
extern void vifUnpackSetup(const u32 *data);

View File

@ -134,10 +134,10 @@ bool AppDoAssert( const DiagnosticOrigin& origin, const wxChar *msg )
wxString trace( pxGetStackTrace(origin.function) );
wxString dbgmsg( origin.ToString( msg ) );
wxMessageOutputDebug().Printf( L"%s", dbgmsg );
wxMessageOutputDebug().Printf( L"%s", dbgmsg.c_str() );
Console.Error( L"%s", dbgmsg );
Console.WriteLn( L"%s", trace );
Console.Error( L"%s", dbgmsg.c_str() );
Console.WriteLn( L"%s", trace.c_str() );
wxString windowmsg( L"Assertion failed: " );
if( msg != NULL )

View File

@ -17,7 +17,7 @@
#define _PCSX2_CORE_RECOMPILER_
#include "x86emitter/x86emitter.h"
#include "sVU_Micro.h"
#include "VUmicro.h"
// Namespace Note : iCore32 contains all of the Register Allocation logic, in addition to a handful
// of utility functions for emitting frequent code.

View File

@ -20,6 +20,7 @@
#include "R5900OpcodeTables.h"
#include "iR5900.h"
#include "iFPU.h"
#include "sVU_Micro.h"
using namespace x86Emitter;

View File

@ -21,6 +21,7 @@
#include "x86emitter/x86emitter.h"
#include "iR5900.h"
#include "iFPU.h"
#include "sVU_Micro.h"
/* This is a version of the FPU that emulates an exponent of 0xff and overflow/underflow flags */

View File

@ -30,7 +30,6 @@
#endif
#include "IopCommon.h"
#include "VU.h"
#include "iCore.h"
#include "SamplProf.h"

View File

@ -1607,6 +1607,10 @@ StartRecomp:
g_pCurInstInfo = s_pInstCache;
for(i = startpc; i < s_nEndBlock; i += 4) {
// superVU hack: it needs vucycles, for some reason. >_<
extern int vucycle;
g_pCurInstInfo++;
cpuRegs.code = *(u32*)PSM(i);

View File

@ -27,15 +27,15 @@ static const s64 _1mb = 0x100000;
#define _f __forceinline
// newVif_HashBucket.h uses this typedef, so it has to be declared first.
typedef u32 (__fastcall *nVifCall)(void*, void*);
typedef u32 (__fastcall *nVifCall)(void*, const void*);
typedef void (__fastcall *nVifrecCall)(uptr dest, uptr src);
#include "newVif_BlockBuffer.h"
#include "newVif_HashBucket.h"
extern void mVUmergeRegs(const xRegisterSSE& dest, const xRegisterSSE& src, int xyzw, bool modXYZW = 0);
extern void _nVifUnpack (int idx, u8 *data, u32 size, bool isFill);
extern void dVifUnpack (int idx, u8 *data, u32 size, bool isFill);
extern void _nVifUnpack (int idx, const u8 *data, u32 size, bool isFill);
extern void dVifUnpack (int idx, const u8 *data, u32 size, bool isFill);
extern void dVifReset (int idx);
extern void dVifClose (int idx);
extern void VifUnpackSSE_Init();

View File

@ -227,7 +227,7 @@ static _f void dVifRecLimit(int idx) {
}
// Gcc complains about recursive functions being inlined.
void dVifUnpack(int idx, u8 *data, u32 size, bool isFill) {
void dVifUnpack(int idx, const u8 *data, u32 size, bool isFill) {
const nVifStruct& v = nVif[idx];
const u8 upkType = v.vif->cmd & 0x1f | ((!!v.vif->usn) << 5);

View File

@ -48,9 +48,10 @@ __aligned16 const u8 nVifT[16] = {
// ----------------------------------------------------------------------------
template< int idx, bool doMode, bool isFill, bool singleUnpack >
__releaseinline void __fastcall _nVifUnpackLoop(u8 *data, u32 size);
__releaseinline void __fastcall _nVifUnpackLoop(const u8 *data, u32 size);
typedef void (__fastcall* Fnptr_VifUnpackLoop)(u8 *data, u32 size);
typedef void __fastcall FnType_VifUnpackLoop(const u8 *data, u32 size);
typedef FnType_VifUnpackLoop* Fnptr_VifUnpackLoop;
// Unpacks Until 'Num' is 0
static const __aligned16 Fnptr_VifUnpackLoop UnpackLoopTable[2][2][2] = {
@ -113,7 +114,7 @@ static _f void incVUptrBy16(int vuidx, u8* &ptr, const u8* vuMemBase) {
}
}
int nVifUnpack(int idx, u8* data) {
int nVifUnpack(int idx, const u8* data) {
nVifStruct& v = nVif[idx];
vif = v.vif;
vifRegs = v.vifRegs;
@ -196,7 +197,7 @@ static void setMasks(int idx, const VIFregisters& v) {
// "slow" games that need it most). --air
template< int idx, bool doMode, bool isFill, bool singleUnpack >
__releaseinline void __fastcall _nVifUnpackLoop(u8 *data, u32 size) {
__releaseinline void __fastcall _nVifUnpackLoop(const u8 *data, u32 size) {
const int cycleSize = isFill ? vifRegs->cycle.cl : vifRegs->cycle.wl;
const int blockSize = isFill ? vifRegs->cycle.wl : vifRegs->cycle.cl;
@ -249,7 +250,7 @@ __releaseinline void __fastcall _nVifUnpackLoop(u8 *data, u32 size) {
}
}
_f void _nVifUnpack(int idx, u8 *data, u32 size, bool isFill) {
_f void _nVifUnpack(int idx, const u8 *data, u32 size, bool isFill) {
if (useOldUnpack) {
if (!idx) VIFunpack<0>((u32*)data, &vif0.tag, size>>2);