mirror of https://github.com/PCSX2/pcsx2.git
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:
parent
095e46246d
commit
bc849cc042
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
96
pcsx2/Dmac.h
96
pcsx2/Dmac.h
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
#ifndef __HW_H__
|
||||
#define __HW_H__
|
||||
|
||||
extern void CPU_INT( u32 n, s32 ecycle );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Hardware FIFOs (128 bit access only!)
|
||||
//
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
63
pcsx2/Vif.h
63
pcsx2/Vif.h
|
@ -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);
|
||||
|
|
|
@ -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,7 +183,8 @@ bool _VIF1chain()
|
|||
__forceinline void vif1SetupTransfer()
|
||||
{
|
||||
tDMA_TAG *ptag;
|
||||
|
||||
DMACh& vif1c = (DMACh&)PS2MEM_HW[0x9000];
|
||||
|
||||
switch (vif1.dmamode)
|
||||
{
|
||||
case VIF_NORMAL_TO_MEM_MODE:
|
||||
|
@ -191,25 +192,23 @@ __forceinline void vif1SetupTransfer()
|
|||
vif1.inprogress = 1;
|
||||
vif1.done = true;
|
||||
g_vifCycles = 2;
|
||||
break;
|
||||
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
|
||||
|
@ -237,13 +240,13 @@ __forceinline void vif1SetupTransfer()
|
|||
} //else vif1.vifstalled = false;
|
||||
}
|
||||
vif1.irqoffset = 0;
|
||||
|
||||
|
||||
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");
|
||||
|
||||
|
@ -251,19 +254,19 @@ __forceinline void vif1SetupTransfer()
|
|||
vif1.done = true;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -134,7 +134,7 @@ template<int idx> _f int _vifCode_Direct(int pass, u8* data, bool isDirectHL) {
|
|||
}
|
||||
pass2 {
|
||||
vif1Only();
|
||||
|
||||
|
||||
if (GSTransferStatus.PTH3 < IDLE_MODE || gifRegs->stat.P1Q == true)
|
||||
{
|
||||
if(gifRegs->stat.APATH == GIF_APATH2 || ((GSTransferStatus.PTH3 <= IMAGE_MODE && gifRegs->stat.IMT && (vif1.cmd & 0x7f) == 0x50)) && gifRegs->stat.P1Q == false)
|
||||
|
@ -172,77 +172,64 @@ 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;
|
||||
if(minSize < 4)
|
||||
{
|
||||
// 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,
|
||||
//
|
||||
|
||||
//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?"); }
|
||||
|
||||
static __aligned16 u32 partial_write[4];
|
||||
static uint partial_count = 0;
|
||||
|
||||
if(vif1.vifpacketsize < 4 && v.bSize < 16)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
DevCon.Warning("Missaligned packet on DIRECT end!");
|
||||
vif1.cmd = 0;
|
||||
}
|
||||
return vif1.vifpacketsize;
|
||||
GetMTGS().PrepDataPacket(GIF_PATH_2, 1);
|
||||
GIFPath_CopyTag(GIF_PATH_2, (u128*)partial_write, 1);
|
||||
GetMTGS().SendDataPacket();
|
||||
partial_count = 0;
|
||||
ret = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(v.bSize)
|
||||
{
|
||||
int ret = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
GetMTGS().SendDataPacket();
|
||||
// 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." );
|
||||
|
||||
if(vif1.tag.size == 0)
|
||||
{
|
||||
vif1.cmd = 0;
|
||||
}
|
||||
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();
|
||||
GetMTGS().PrepDataPacket(GIF_PATH_2, minSize/4);
|
||||
ret = GIFPath_CopyTag(GIF_PATH_2, (u128*)data, minSize/4)*4;
|
||||
GetMTGS().SendDataPacket();
|
||||
}
|
||||
|
||||
vif1.tag.size -= count;
|
||||
if(vif1.tag.size == 0)
|
||||
{
|
||||
vif1.cmd = 0;
|
||||
}
|
||||
vif1.vifstalled = true;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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,19 +349,22 @@ vifOp(vifCode_MPG) {
|
|||
}
|
||||
|
||||
vifOp(vifCode_MSCAL) {
|
||||
pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0;}
|
||||
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) {
|
||||
pass1 { vifFlush(idx); vuExecMicro(idx, (u16)(vifXRegs->code) << 3); vifX.cmd = 0; }
|
||||
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) {
|
||||
pass1 { vifFlush(idx); vuExecMicro(idx, -1); vifX.cmd = 0; }
|
||||
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,26 +381,27 @@ 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
|
||||
Console.WriteLn("Vif%d: Unknown VifCmd! [%x]", idx, vifX.cmd);
|
||||
vifXRegs->stat.ER1 = true;
|
||||
vifX.vifstalled = true;
|
||||
vifX.vifstalled = true;
|
||||
//vifX.irq++;
|
||||
}
|
||||
vifX.cmd = 0;
|
||||
|
@ -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,40 +529,42 @@ vifOp(vifCode_Unpack) {
|
|||
// Vif0/Vif1 Code Tables
|
||||
//------------------------------------------------------------------
|
||||
|
||||
int (__fastcall *vif0Code[128])(int pass, u32 *data) = {
|
||||
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*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x18*/
|
||||
vifCode_STMask<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x20*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x28*/
|
||||
vifCode_STRow<0> , vifCode_STCol<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x30*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x38*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x40*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_MPG<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x48*/
|
||||
vifCode_Direct<0> , vifCode_DirectHL<0>, vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x50*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x58*/
|
||||
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0>, /*0x60*/
|
||||
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*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x18*/
|
||||
vifCode_STMask<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x20*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x28*/
|
||||
vifCode_STRow<1> , vifCode_STCol<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x30*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x38*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x40*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_MPG<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x48*/
|
||||
vifCode_Direct<1> , vifCode_DirectHL<1>, vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x50*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x58*/
|
||||
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1>, /*0x60*/
|
||||
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*/
|
||||
__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*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x18*/
|
||||
vifCode_STMask<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x20*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x28*/
|
||||
vifCode_STRow<0> , vifCode_STCol<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x30*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x38*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x40*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_MPG<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x48*/
|
||||
vifCode_Direct<0> , vifCode_DirectHL<0>, vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x50*/
|
||||
vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0> , vifCode_Null<0>, /*0x58*/
|
||||
vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Unpack<0> , vifCode_Null<0>, /*0x60*/
|
||||
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*/
|
||||
},
|
||||
{
|
||||
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*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x18*/
|
||||
vifCode_STMask<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x20*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x28*/
|
||||
vifCode_STRow<1> , vifCode_STCol<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x30*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x38*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x40*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_MPG<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x48*/
|
||||
vifCode_Direct<1> , vifCode_DirectHL<1>, vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x50*/
|
||||
vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1> , vifCode_Null<1>, /*0x58*/
|
||||
vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Unpack<1> , vifCode_Null<1>, /*0x60*/
|
||||
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*/
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -109,7 +114,7 @@ _vifT _f bool vifTransfer(u32 *data, int size) {
|
|||
g_packetsizeonvu = size;
|
||||
vifTransferLoop<idx>(data);
|
||||
|
||||
|
||||
|
||||
transferred += size - vifX.vifpacketsize;
|
||||
|
||||
g_vifCycles +=((transferred * BIAS) >> 2) ; /* guessing */
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "R5900OpcodeTables.h"
|
||||
#include "iR5900.h"
|
||||
#include "iFPU.h"
|
||||
#include "sVU_Micro.h"
|
||||
|
||||
using namespace x86Emitter;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#endif
|
||||
|
||||
#include "IopCommon.h"
|
||||
#include "VU.h"
|
||||
#include "iCore.h"
|
||||
|
||||
#include "SamplProf.h"
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue