More work on Gif.cpp & IPU.cpp. Got fed up with straightening IPU.cpp up by hand, so I ran Artistic Style on it, and then strightened the results out.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@857 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-03-29 11:10:44 +00:00
parent 74dcf7d8a9
commit c8ee95b39f
10 changed files with 669 additions and 698 deletions

View File

@ -571,7 +571,7 @@ int loadElfFile(const char *filename)
} }
#include "VU.h" #include "VU.h"
extern int path3hack; extern bool path3hack;
int g_VUGameFixes = 0; int g_VUGameFixes = 0;
// fixme - this should be moved to patches or eliminated // fixme - this should be moved to patches or eliminated
@ -586,7 +586,7 @@ void LoadGameSpecificSettings()
break; break;
//case 0xa08c4057: //Sprint Cars (SLUS) //case 0xa08c4057: //Sprint Cars (SLUS)
//case 0x8b0725d5: //Flinstones Bedrock Racing (SLES) //case 0x8b0725d5: //Flinstones Bedrock Racing (SLES)
//path3hack = 1; // We can move this to patch files right now //path3hack = TRUE; // We can move this to patch files right now
//break; //break;
} }
} }

View File

@ -253,7 +253,7 @@ void gsReset()
memzero_obj(g_RealGSMem); memzero_obj(g_RealGSMem);
Path3transfer = 0; Path3transfer = FALSE;
GSCSRr = 0x551B400F; // Set the FINISH bit to 1 for now GSCSRr = 0x551B400F; // Set the FINISH bit to 1 for now
GSIMR = 0x7f00; GSIMR = 0x7f00;

View File

@ -29,6 +29,7 @@
using std::min; using std::min;
#define gif ((DMACh*)&psH[0xA000]) #define gif ((DMACh*)&psH[0xA000])
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
enum gifstate_t enum gifstate_t
{ {
@ -40,13 +41,15 @@ enum gifstate_t
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished). // A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
static gifstate_t gifstate = GIF_STATE_EMPTY; static gifstate_t gifstate = GIF_STATE_EMPTY;
//int gscount = 0;
static u64 s_gstag = 0; // used for querying the last tag static u64 s_gstag = 0; // used for querying the last tag
// This should be a bool, as should the return value of hwDmacSrcChainWithStack.
// Next time I feel like breaking the save state, it will be. --arcum42
static int gspath3done = 0; static int gspath3done = 0;
static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0; static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0;
static u32 gifqwc = 0; static u32 gifqwc = 0;
__forceinline void gsInterrupt() { __forceinline void gsInterrupt() {
GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle); GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle);
@ -75,11 +78,10 @@ __forceinline void gsInterrupt() {
gspath3done = 0; gspath3done = 0;
gscycles = 0; gscycles = 0;
Path3transfer = 0; Path3transfer = FALSE;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff
GSCSRr |= 0x4000; //FIFO empty GSCSRr |= 0x4000; //FIFO empty
//psHu32(GIF_MODE)&= ~0x4;
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0 psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
@ -90,8 +92,8 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
{ {
psHu32(GIF_STAT) |= 0xE00; psHu32(GIF_STAT) |= 0xE00;
// Path3 transfer will be set to zero by the GIFtag handler. // Path3 transfer will be set to false by the GIFtag handler.
Path3transfer = 1; Path3transfer = TRUE;
if( mtgsThread != NULL ) if( mtgsThread != NULL )
{ {
@ -118,14 +120,14 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
if (GSgetLastTag != NULL) if (GSgetLastTag != NULL)
{ {
GSgetLastTag(&s_gstag); GSgetLastTag(&s_gstag);
if (s_gstag == 1) Path3transfer = 0; /* fixes SRS and others */ if (s_gstag == 1) Path3transfer = FALSE; /* fixes SRS and others */
} }
} }
} }
int _GIFchain() { int _GIFchain() {
#ifdef GSPATH3FIX #ifdef GSPATH3FIX
u32 qwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc; u32 qwc = ((psHu32(GIF_MODE) & 0x4) && (vif1Regs->mskpath3)) ? min(8, (int)gif->qwc) : gif->qwc;
#else #else
u32 qwc = gif->qwc; u32 qwc = gif->qwc;
#endif #endif
@ -152,20 +154,16 @@ int _GIFchain() {
__forceinline void GIFchain() __forceinline void GIFchain()
{ {
FreezeRegs(1); FreezeRegs(1);
if (gif->qwc) gscycles+= _GIFchain(); /* guessing */ \ if (gif->qwc) gscycles+= _GIFchain(); /* guessing */
FreezeRegs(0); FreezeRegs(0);
} }
static __forceinline void dmaGIFend() static __forceinline void dmaGIFend()
{ {
if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
{
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
}
else else
{
CPU_INT(2, gif->qwc /** BIAS*/); CPU_INT(2, gif->qwc /** BIAS*/);
}
} }
// These could probably be consolidated into one function, // These could probably be consolidated into one function,
@ -174,13 +172,9 @@ static __forceinline void dmaGIFend()
static __forceinline void GIFdmaEnd() static __forceinline void GIFdmaEnd()
{ {
if (psHu32(GIF_MODE) & 0x4) if (psHu32(GIF_MODE) & 0x4)
{
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
}
else else
{
CPU_INT(2, gif->qwc /** BIAS*/); CPU_INT(2, gif->qwc /** BIAS*/);
}
} }
void GIFdma() void GIFdma()
@ -190,7 +184,7 @@ void GIFdma()
gscycles= prevcycles ? prevcycles: gscycles; gscycles= prevcycles ? prevcycles: gscycles;
if( (psHu32(GIF_CTRL) & 8) ) { // temporarily stop if ((psHu32(GIF_CTRL) & 8)) { // temporarily stop
Console::WriteLn("Gif dma temp paused?"); Console::WriteLn("Gif dma temp paused?");
return; return;
} }
@ -225,7 +219,7 @@ void GIFdma()
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3] psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [ used to be 0xE00; // OPH=1 | APATH=3]
#ifdef GSPATH3FIX #ifdef GSPATH3FIX
if (vif1Regs->mskpath3 || psHu32(GIF_MODE) & 0x1) { if (vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1)) {
if(gif->qwc == 0) { if(gif->qwc == 0) {
if((gif->chcr & 0x10e) == 0x104) { if((gif->chcr & 0x10e) == 0x104) {
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
@ -255,14 +249,13 @@ void GIFdma()
GIFchain(); GIFchain();
// Theres a comment below that says not to unfreeze the xmm regs, so not sure about freezing and unfreezing in GIFchain. // Theres a comment below that says not to unfreeze the xmm regs, so not sure about freezing and unfreezing in GIFchain.
if((gspath3done == 1 || (gif->chcr & 0xc) == 0) && gif->qwc == 0){ if((gif->qwc == 0) && ((gspath3done == 1) || (gif->chcr & 0xc) == 0)){
if(gif->qwc > 0) Console::WriteLn("Hurray!"); //if(gif->qwc > 0) Console::WriteLn("Hurray!"); // We *know* it is 0!
gspath3done = 0; gspath3done = 0;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
//psHu32(GIF_MODE)&= ~0x4;
GSCSRr &= ~0xC000; GSCSRr &= ~0xC000;
GSCSRr |= 0x4000; GSCSRr |= 0x4000;
Path3transfer = 0; Path3transfer = FALSE;
psHu32(GIF_STAT)&= ~0x1F000E00; // OPH=0 | APATH=0 | QFC=0 psHu32(GIF_STAT)&= ~0x1F000E00; // OPH=0 | APATH=0 | QFC=0
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
} }
@ -272,23 +265,21 @@ void GIFdma()
#endif #endif
// Transfer Dn_QWC from Dn_MADR to GIF // Transfer Dn_QWC from Dn_MADR to GIF
if ((gif->chcr & 0xc) == 0 || gif->qwc > 0) { // Normal Mode if ((gif->chcr & 0xc) == 0 || gif->qwc > 0) { // Normal Mode
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80 && (gif->chcr & 0xc) == 0) { if ((((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && ((gif->chcr & 0xc) == 0))) {
Console::WriteLn("DMA Stall Control on GIF normal"); Console::WriteLn("DMA Stall Control on GIF normal");
} }
GIFchain(); //Transfers the data set by the switch GIFchain(); //Transfers the data set by the switch
if (gif->qwc == 0 && (gif->chcr & 0xc) == 0)
{ if (((gif->qwc == 0) && (gif->chcr & 0xc) == 0))
gspath3done = 1; gspath3done = 1;
}
else else
{
GIFdmaEnd(); GIFdmaEnd();
}
return; return;
} }
else { else {
// Chain Mode // Chain Mode
while (gspath3done == 0 && gif->qwc == 0) { //Loop if the transfers aren't intermittent while ((gspath3done == 0) && (gif->qwc == 0)) { //Loop if the transfers aren't intermittent
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
if (ptag == NULL) { //Is ptag empty? if (ptag == NULL) { //Is ptag empty?
psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register
@ -298,7 +289,7 @@ void GIFdma()
// We used to transfer dma tags if tte is set here // We used to transfer dma tags if tte is set here
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 gif->chcr = ( gif->chcr & 0xFFFF ) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
@ -331,9 +322,9 @@ void GIFdma()
prevcycles = 0; prevcycles = 0;
if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) { if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) {
if(gspath3done == 0) if (gspath3done == 0)
{ {
if((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
{ {
CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/); CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/);
} }
@ -368,7 +359,7 @@ void dmaGIF() {
GSCSRr |= 0x8000; //FIFO full GSCSRr |= 0x8000; //FIFO full
psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3] psHu32(GIF_STAT)|= 0x10000000; // FQC=31, hack ;) [used to be 0xE00; // OPH=1 | APATH=3]
if ((gif->chcr & 0xc) != 0 && gif->qwc == 0){ if ((gif->qwc == 0) && ((gif->chcr & 0xc) != 0)){
u32 *ptag; u32 *ptag;
ptag = (u32*)dmaGetAddr(gif->tadr); ptag = (u32*)dmaGetAddr(gif->tadr);
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
@ -379,20 +370,12 @@ void dmaGIF() {
return; return;
} }
if(gif->qwc > 0 && (gif->chcr & 0x4) == 0x4) { //Halflife sets a QWC amount in chain mode, no tadr set.
gspath3done = 1; //Halflife sets a QWC amount in chain mode, no tadr set. if((gif->qwc > 0) && ((gif->chcr & 0x4) == 0x4)) gspath3done = 1;
// Since this is all that's done after this if statement ends, anyways no need to have
// this code in here.
//dmaGIFend();
//return;
}
dmaGIFend(); dmaGIFend();
} }
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
// called from only one location, so forceinline it: // called from only one location, so forceinline it:
static __forceinline int mfifoGIFrbTransfer() { static __forceinline int mfifoGIFrbTransfer() {
u32 qwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc; u32 qwc = (psHu32(GIF_MODE) & 0x4 && vif1Regs->mskpath3) ? min(8, (int)gif->qwc) : gif->qwc;
@ -433,7 +416,6 @@ static __forceinline int mfifoGIFrbTransfer() {
gif->qwc -= mfifoqwc; gif->qwc -= mfifoqwc;
gif->madr+= mfifoqwc*16; gif->madr+= mfifoqwc*16;
mfifocycles+= (mfifoqwc) * 2; /* guessing */ mfifocycles+= (mfifoqwc) * 2; /* guessing */
return 0; return 0;
} }
@ -584,7 +566,6 @@ void gifMFIFOInterrupt()
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff
GSCSRr |= 0x4000; //FIFO empty GSCSRr |= 0x4000; //FIFO empty
//psHu32(GIF_MODE)&= ~0x4;
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0 psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
} }

File diff suppressed because it is too large Load Diff

View File

@ -41,36 +41,33 @@ coroutine* g_pCurrentRoutine;
coroutine_t so_create(void (*func)(void *), void *data, void *stack, int size) coroutine_t so_create(void (*func)(void *), void *data, void *stack, int size)
{ {
void* endstack; void* endstack;
int alloc = 0; // r = CO_STK_COROSIZE; int alloc = 0; // r = CO_STK_COROSIZE;
coroutine *co; coroutine *co;
if ((size &= ~(sizeof(long) - 1)) < CO_MIN_SIZE) if ((size &= ~(sizeof(long) - 1)) < CO_MIN_SIZE) return NULL;
return NULL;
if (!stack) { if (!stack) {
size = (size + sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1); size = (size + sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1);
stack = malloc(size); stack = malloc(size);
if (!stack) if (!stack) return NULL;
return NULL;
alloc = size; alloc = size;
} }
endstack = (char*)stack + size - 64; endstack = (char*)stack + size - 64;
co = (coroutine*)stack; co = (coroutine*)stack;
stack = (char *) stack + CO_STK_COROSIZE; stack = (char *) stack + CO_STK_COROSIZE;
*(void**)endstack = NULL; *(void**)endstack = NULL;
*(void**)((char*)endstack+sizeof(void*)) = data; *(void**)((char*)endstack+sizeof(void*)) = data;
co->alloc = alloc; co->alloc = alloc;
co->pcalladdr = (void*)func; co->pcalladdr = (void*)func;
co->pcurstack = endstack; co->pcurstack = endstack;
return co; return co;
} }
void so_delete(coroutine_t coro) void so_delete(coroutine_t coro)
{ {
coroutine *co = (coroutine *) coro; coroutine *co = (coroutine *) coro;
assert( co != NULL ); assert( co != NULL );
if (co->alloc) if (co->alloc) free(co);
free(co);
} }
// see acoroutines.S and acoroutines.asm for other asm implementations // see acoroutines.S and acoroutines.asm for other asm implementations

View File

@ -290,7 +290,7 @@ __forceinline u32 mtgsThreadObject::_gifTransferDummy( GIF_PATH pathidx, const u
--size; --size;
if(pathidx == 2 && path.tag.eop) if(pathidx == 2 && path.tag.eop)
Path3transfer = 0; Path3transfer = FALSE;
if( pathidx == 0 ) if( pathidx == 0 )
{ {

View File

@ -675,7 +675,7 @@ void patchFunc_vunanmode( char * cmd, char * param )
void patchFunc_path3hack( char * cmd, char * param ) void patchFunc_path3hack( char * cmd, char * param )
{ {
path3hack = 1; path3hack = TRUE;
} }
void patchFunc_roundmode( char * cmd, char * param ) void patchFunc_roundmode( char * cmd, char * param )

View File

@ -109,7 +109,7 @@ int AddPatch(int Mode, int Place, int Address, int Size, u64 data);
extern void SetFastMemory(int); // iR5900LoadStore.c extern void SetFastMemory(int); // iR5900LoadStore.c
extern int path3hack; extern bool path3hack;
//extern int g_VUGameFixes; //extern int g_VUGameFixes;
extern int g_ZeroGSOptions; extern int g_ZeroGSOptions;
extern u32 g_sseMXCSR; extern u32 g_sseMXCSR;

View File

@ -66,7 +66,7 @@ static const unsigned int VIF0dmanum = 0;
static const unsigned int VIF1dmanum = 1; static const unsigned int VIF1dmanum = 1;
int g_vifCycles = 0; int g_vifCycles = 0;
int path3hack = 0; bool path3hack = FALSE;
typedef void (__fastcall *UNPACKFUNCTYPE)( u32 *dest, u32 *data, int size ); typedef void (__fastcall *UNPACKFUNCTYPE)( u32 *dest, u32 *data, int size );
typedef int (*UNPACKPARTFUNCTYPESSE)( u32 *dest, u32 *data, int size ); typedef int (*UNPACKPARTFUNCTYPESSE)( u32 *dest, u32 *data, int size );
@ -1630,7 +1630,7 @@ static int __fastcall Vif1TransUnpack(u32 *data){
// Vif1 CMD Base Commands // Vif1 CMD Base Commands
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int transferred = 0; int transferred = 0;
int Path3transfer=0; bool Path3transfer = FALSE;
static void Vif1CMDNop(){ // NOP static void Vif1CMDNop(){ // NOP
vif1.cmd &= ~0x7f; vif1.cmd &= ~0x7f;
} }
@ -1669,11 +1669,11 @@ static void Vif1CMDMskPath3(){ // MSKPATH3
{ {
while((gif->chcr & 0x100)) //Can be done 2 different ways, depends on the game/company while((gif->chcr & 0x100)) //Can be done 2 different ways, depends on the game/company
{ {
if ((path3hack == 0) && (Path3transfer == 0) && (gif->qwc == 0)) break; if (!path3hack && !Path3transfer && (gif->qwc == 0)) break;
gsInterrupt(); gsInterrupt();
if ((path3hack == 1) && (gif->qwc == 0)) break; //add games not working with it to elfheader.c to enable this instead if (path3hack && (gif->qwc == 0)) break; //add games not working with it to elfheader.c to enable this instead
} }
//while(gif->chcr & 0x100) gsInterrupt(); // Finish the transfer first //while(gif->chcr & 0x100) gsInterrupt(); // Finish the transfer first
psHu32(GIF_STAT) |= 0x2; psHu32(GIF_STAT) |= 0x2;
@ -1709,7 +1709,7 @@ static void Vif1CMDFlush(){ // FLUSH/E/A
if((vif1.cmd & 0x7f) == 0x13) { if((vif1.cmd & 0x7f) == 0x13) {
while((gif->chcr & 0x100)){ while((gif->chcr & 0x100)){
if(Path3transfer == 0 && gif->qwc == 0) break; if (!Path3transfer && gif->qwc == 0) break;
gsInterrupt(); gsInterrupt();
} }
} }

View File

@ -34,9 +34,12 @@ struct vifStruct {
int cl; int cl;
int wl; int wl;
u8 usn; u8 usn;
// The next three should be boolean, and will be next time I break savestate compatability. --arcum42
u8 done; u8 done;
u8 vifstalled; u8 vifstalled;
u8 stallontag; u8 stallontag;
u8 irqoffset; // 32bit offset where next vif code is u8 irqoffset; // 32bit offset where next vif code is
u32 savedtag; // need this for backwards compat with save states u32 savedtag; // need this for backwards compat with save states
u32 vifpacketsize; u32 vifpacketsize;
@ -45,7 +48,7 @@ struct vifStruct {
}; };
extern vifStruct vif0, vif1; extern vifStruct vif0, vif1;
extern int Path3transfer; extern bool Path3transfer;
#define vif0ch ((DMACh*)&PS2MEM_HW[0x8000]) #define vif0ch ((DMACh*)&PS2MEM_HW[0x8000])
#define vif1ch ((DMACh*)&PS2MEM_HW[0x9000]) #define vif1ch ((DMACh*)&PS2MEM_HW[0x9000])