Made hwDmacSrcChain & hwDmacSrcChainWithStacks a bit easier to follow. Misc other changes, mainly register related, or making use of existing constants.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1992 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-10-09 05:50:10 +00:00
parent a4f180aa5d
commit 2a69c92067
7 changed files with 185 additions and 127 deletions

View File

@ -400,3 +400,5 @@ extern SessionOverrideFlags g_Session;
#endif
#define EE_CONST_PROP // rec2 - enables constant propagation (faster)
//#define NON_SSE_UNPACKS // Turns off SSE Unpacks (slower)

View File

@ -14,7 +14,6 @@
*/
#include "PrecompiledHeader.h"
#include "Common.h"
@ -36,7 +35,7 @@ using namespace R5900;
u8 *psH; // hw mem
int rdram_devices = 2; // put 8 for TOOL and 2 for PS2 and PSX
const int rdram_devices = 2; // put 8 for TOOL and 2 for PS2 and PSX
int rdram_sdevid = 0;
void hwInit()
@ -50,7 +49,8 @@ void hwInit()
ipuInit();
}
void hwShutdown() {
void hwShutdown()
{
ipuShutdown();
}
@ -61,10 +61,10 @@ void hwReset()
memzero_ptr<Ps2MemSize::Hardware>( PS2MEM_HW );
//memset(PS2MEM_HW+0x2000, 0, 0x0000e000);
psHu32(0xf520) = 0x1201;
psHu32(0xf260) = 0x1D000060;
psHu32(SBUS_F260) = 0x1D000060;
// i guess this is kinda a version, it's used by some bioses
psHu32(0xf590) = 0x1201;
psHu32(DMAC_ENABLEW) = 0x1201;
psHu32(DMAC_ENABLER) = 0x1201;
gsReset();
ipuReset();
@ -93,51 +93,54 @@ __forceinline void dmacInterrupt()
{
if ((cpuRegs.CP0.n.Status.val & 0x10807) != 0x10801) return;
if( ((psHu16(0xe012) & psHu16(0xe010)) == 0 ) &&
( psHu16(0xe010) & 0x8000) == 0 ) return;
if( ((psHu16(DMAC_STAT + 2) & psHu16(DMAC_STAT)) == 0 ) &&
( psHu16(DMAC_STAT) & 0x8000) == 0 ) return;
if (!(dmacRegs->ctrl.DMAE)) return;
HW_LOG("dmacInterrupt %x", (psHu16(0xe012) & psHu16(0xe010) ||
psHu16(0xe010) & 0x8000));
HW_LOG("dmacInterrupt %x", (psHu16(DMAC_STAT + 2) & psHu16(DMAC_STAT) ||
psHu16(DMAC_STAT) & 0x8000));
cpuException(0x800, cpuRegs.branch);
}
void hwIntcIrq(int n) {
psHu32(INTC_STAT)|= 1<<n;
void hwIntcIrq(int n)
{
psHu32(INTC_STAT) |= 1<<n;
cpuTestINTCInts();
}
void hwDmacIrq(int n) {
psHu32(DMAC_STAT)|= 1<<n;
void hwDmacIrq(int n)
{
psHu32(DMAC_STAT) |= 1<<n;
cpuTestDMACInts();
}
/* Write 'size' bytes to memory address 'addr' from 'data'. */
bool hwMFIFOWrite(u32 addr, u8 *data, u32 size) {
u32 msize = psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)+16;
// Write 'size' bytes to memory address 'addr' from 'data'.
bool hwMFIFOWrite(u32 addr, u8 *data, u32 size)
{
u32 msize = dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK + 16;
u8 *dst;
addr = dmacRegs->rbor.ADDR + (addr & dmacRegs->rbsr.RMSK);
addr = psHu32(DMAC_RBOR) + (addr & psHu32(DMAC_RBSR));
/* Check if the transfer should wrap around the ring buffer */
// Check if the transfer should wrap around the ring buffer
if ((addr+size) >= msize) {
int s1 = msize - addr;
int s2 = size - s1;
/* it does, so first copy 's1' bytes from 'data' to 'addr' */
// it does, so first copy 's1' bytes from 'data' to 'addr'
dst = (u8*)PSM(addr);
if (dst == NULL) return false;
memcpy_fast(dst, data, s1);
/* and second copy 's2' bytes from '&data[s1]' to 'maddr' */
dst = (u8*)PSM(psHu32(DMAC_RBOR));
// and second copy 's2' bytes from '&data[s1]' to 'maddr'
dst = (u8*)PSM(dmacRegs->rbor.ADDR);
if (dst == NULL) return false;
memcpy_fast(dst, &data[s1], s2);
}
else {
/* it doesn't, so just copy 'size' bytes from 'data' to 'addr' */
// it doesn't, so just copy 'size' bytes from 'data' to 'addr'
dst = (u8*)PSM(addr);
if (dst == NULL) return false;
memcpy_fast(dst, data, size);
@ -146,121 +149,142 @@ bool hwMFIFOWrite(u32 addr, u8 *data, u32 size) {
return true;
}
bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
switch (id) {
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
return true; //End Transfer
//End Transfer
return true;
case TAG_CNT: // CNT - Transfer QWC following the tag.
dma->madr = dma->tadr + 16; //Set MADR to QW after Tag
dma->tadr = dma->madr + (dma->qwc << 4); //Set TADR to QW following the data
// Set MADR to QW afer tag, and set TADR to QW following the data.
dma->madr = dma->tadr + 16;
dma->tadr = dma->madr + (dma->qwc << 4);
return false;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
{
u32 temp = dma->madr; //Temporarily Store ADDR
dma->madr = dma->tadr + 16; //Set MADR to QW following the tag
dma->tadr = temp; //Copy temporarily stored ADDR to Tag
// Set MADR to QW following the tag, and set TADR to the address formerly in MADR.
u32 temp = dma->madr;
dma->madr = dma->tadr + 16;
dma->tadr = temp;
return false;
}
case TAG_REF: // Ref - Transfer QWC from ADDR field
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
dma->tadr += 16; //Set TADR to next tag
//Set TADR to next tag
dma->tadr += 16;
return false;
case TAG_CALL: // Call - Transfer QWC following the tag, save succeeding tag
{
u32 temp = dma->madr; //Temporarily Store ADDR
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
// Store the address in MADR in temp, and set MADR to the data following the tag.
u32 temp = dma->madr;
dma->madr = dma->tadr + 16;
// Stash an address on the address stack pointer.
switch(dma->chcr.ASP)
{
case 0: { //Check if ASR0 is empty
dma->asr0 = dma->madr + (dma->qwc << 4); //If yes store Succeeding tag
dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x10; //1 Address in call stack
case 0: //Check if ASR0 is empty
// Store the succeeding tag in asr0, and mark chcr as having 1 address.
dma->asr0 = dma->madr + (dma->qwc << 4);
dma->chcr.ASP++;
break;
}
case 1: {
dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x20; //2 Addresses in call stack
dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1
case 1:
// Store the succeeding tag in asr1, and mark chcr as having 2 addresses.
dma->asr1 = dma->madr + (dma->qwc << 4);
dma->chcr.ASP++;
break;
}
default: {
default:
Console.Notice("Call Stack Overflow (report if it fixes/breaks anything)");
return true; //Return done
return true;
}
}
dma->tadr = temp; //Set TADR to temporarily stored ADDR
// Set TADR to the address from MADR we stored in temp.
dma->tadr = temp;
return false;
}
case TAG_RET: // Ret - Transfer QWC following the tag, load next tag
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
//Set MADR to data following the tag.
dma->madr = dma->tadr + 16;
// Snag an address from the address stack pointer.
switch(dma->chcr.ASP)
{
case 2: { //If ASR1 is NOT equal to 0 (Contains address)
dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x10; //1 Address left in call stack
dma->tadr = dma->asr1; //Read ASR1 as next tag
dma->asr1 = 0; //Clear ASR1
case 2:
// Pull asr1 from the stack, give it to TADR, and decrease the # of addresses.
dma->tadr = dma->asr1;
dma->asr1 = 0;
dma->chcr.ASP--;
break;
}
//If ASR1 is empty (No address held)
case 1:{ //Check if ASR0 is NOT equal to 0 (Contains address)
dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf); //No addresses left in call stack
dma->tadr = dma->asr0; //Read ASR0 as next tag
dma->asr0 = 0; //Clear ASR0
case 1:
// Pull asr0 from the stack, give it to TADR, and decrease the # of addresses.
dma->tadr = dma->asr0;
dma->asr0 = 0;
dma->chcr.ASP--;
break;
}
case 0: { //Else if ASR1 and ASR0 are empty
case 0:
// There aren't any addresses to pull, so end the transfer.
//dma->tadr += 16; //Clear tag address - Kills Klonoa 2
return true; //End Transfer
}
default: { //Else if ASR1 and ASR0 are messed up
return true;
default:
// If ASR1 and ASR0 are messed up, end the transfer.
//Console.Error("TAG_RET: ASR 1 & 0 == 1. This shouldn't happen!");
//dma->tadr += 16; //Clear tag address - Kills Klonoa 2
return true; //End Transfer
}
return true;
}
return false;
case TAG_END: // End - Transfer QWC following the tag
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
//Dont Increment tadr, breaks Soul Calibur II and III
return true; //End Transfer
//Set MADR to data following the tag, and end the transfer.
dma->madr = dma->tadr + 16;
//Don't Increment tadr; breaks Soul Calibur II and III
return true;
}
return false;
}
bool hwDmacSrcChain(DMACh *dma, int id) {
bool hwDmacSrcChain(DMACh *dma, int id)
{
u32 temp;
switch (id) {
switch (id)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
return true; //End Transfer
// End the transfer.
return true;
case TAG_CNT: // CNT - Transfer QWC following the tag.
dma->madr = dma->tadr + 16; //Set MADR to QW after Tag
dma->tadr = dma->madr + (dma->qwc << 4); //Set TADR to QW following the data
// Set MADR to QW after the tag, and TADR to QW following the data.
dma->madr = dma->tadr + 16;
dma->tadr = dma->madr + (dma->qwc << 4);
return false;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
temp = dma->madr; //Temporarily Store ADDR
dma->madr = dma->tadr + 16; //Set MADR to QW following the tag
dma->tadr = temp; //Copy temporarily stored ADDR to Tag
// Set MADR to QW following the tag, and set TADR to the address formerly in MADR.
temp = dma->madr;
dma->madr = dma->tadr + 16;
dma->tadr = temp;
return false;
case TAG_REF: // Ref - Transfer QWC from ADDR field
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
dma->tadr += 16; //Set TADR to next tag
//Set TADR to next tag
dma->tadr += 16;
return false;
case TAG_END: // End - Transfer QWC following the tag
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
//Dont Increment tadr, breaks Soul Calibur II and III
return true; //End Transfer
//Set MADR to data following the tag, and end the transfer.
dma->madr = dma->tadr + 16;
//Don't Increment tadr; breaks Soul Calibur II and III
return true;
}
return false;

View File

@ -269,7 +269,6 @@ enum EERegisterAddresses
DMAC_ENABLEW = 0x1000F590
};
enum GSRegisterAddresses
{
GS_PMODE = 0x12000000,
@ -338,9 +337,9 @@ enum DMACIrqs
DMAC_TO_SPR,
// We're setting error conditions through hwDmacIrq, so these correspond to the conditions above.
DMAC_STALL_SIS = 13,
DMAC_MFIFO_EMPTY = 14,
DMAC_BUS_ERROR = 15
DMAC_STALL_SIS = 13, // SIS
DMAC_MFIFO_EMPTY = 14, // MEIS
DMAC_BUS_ERROR = 15 // BEIS
};
//DMA interrupts & masks
@ -457,7 +456,36 @@ struct DMACregisters
tDMAC_STADR stadr;
};
// Currently guesswork.
union tINTC_STAT {
struct {
u32 interrupts : 10;
u32 placeholder : 22;
};
u32 _u32;
bool test(u32 flags) { return !!(_u32 & flags); }
void set(u32 flags) { _u32 |= flags; }
void clear(u32 flags) { _u32 &= ~flags; }
};
union tINTC_MASK {
struct {
u32 int_mask : 10;
u32 placeholder:22;
};
u32 _u32;
};
struct INTCregisters
{
tINTC_STAT stat;
u32 padding[3];
tINTC_MASK mask;
};
#define dmacRegs ((DMACregisters*)(PS2MEM_HW+0xE000))
#define intcRegs ((INTCregisters*)(PS2MEM_HW+0xF000))
#ifdef PCSX2_VIRTUAL_MEM
@ -522,10 +550,10 @@ static __forceinline u32 *_dmaGetAddr(DMACh *dma, u32 addr, u32 num)
if (ptr == NULL)
{
// DMA Error
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; /* BUS error */
dmacRegs->stat.BEIS = 1; // BUS Error
// DMA End
psHu32(DMAC_STAT) |= 1<<num;
dmacRegs->stat.set(1 << num);
dma->chcr.STR = 0;
}
@ -604,6 +632,7 @@ void hwConstWrite128(u32 mem, int xmmreg);
extern void intcInterrupt();
extern void dmacInterrupt();
extern int rdram_devices, rdram_sdevid;
extern const int rdram_devices;
extern int rdram_sdevid;
#endif /* __HW_H__ */

View File

@ -199,10 +199,10 @@ __forceinline void SIF0Dma()
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
SIF_LOG("----------- %lX of %lX", readSize << 2, size << 2);
ptag = _dmaGetAddr(sif0dma, sif0dma->madr, 5);
ptag = _dmaGetAddr(sif0dma, sif0dma->madr, DMAC_SIF0);
if (ptag == NULL) return;
//_dmaGetAddr(sif0dma, *ptag, sif0dma->madr, 5);
//_dmaGetAddr(sif0dma, *ptag, sif0dma->madr, DMAC_SIF0);
SIF0read((u32*)ptag, readSize << 2);
@ -283,10 +283,10 @@ __forceinline void SIF1Dma()
{
// Process DMA tag at sif1dma->tadr
done = false;
ptag = _dmaGetAddr(sif1dma, sif1dma->tadr, 6);
ptag = _dmaGetAddr(sif1dma, sif1dma->tadr, DMAC_SIF1);
if (ptag == NULL) return;
//_dmaGetAddr(sif1dma, *ptag, sif1dma->tadr, 6);
//_dmaGetAddr(sif1dma, *ptag, sif1dma->tadr, DMAC_SIF1);
sif1dma->chcr._u32 = (sif1dma->chcr._u32 & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag
@ -350,10 +350,10 @@ __forceinline void SIF1Dma()
int qwTransfer = sif1dma->qwc;
u32 *data;
data = _dmaGetAddr(sif1dma, sif1dma->madr, 6);
data = _dmaGetAddr(sif1dma, sif1dma->madr, DMAC_SIF1);
if (data == NULL) return;
//_dmaGetAddr(sif1dma, *data, sif1dma->madr, 6);
//_dmaGetAddr(sif1dma, *data, sif1dma->madr, DMAC_SIF1);
if (qwTransfer > (FIFO_SIF1_W - sif1.fifoSize) / 4) // Copy part of sif1dma into FIFO
qwTransfer = (FIFO_SIF1_W - sif1.fifoSize) / 4;

View File

@ -563,9 +563,12 @@ template<const u32 VIFdmanum> void VIFunpack(u32 *data, vifCode *v, u32 size)
}
else
{
tempsize = 0; //Commenting out this then
//tempsize = size; // -\_uncommenting these Two enables non-SSE unpacks
//size = 0; // -/
#ifndef NON_SSE_UNPACKS
tempsize = 0;
#else
tempsize = size;
size = 0;
#endif
}
if (size >= ft->gsize)

View File

@ -15,13 +15,6 @@
#ifndef __VIFDMA_H__
#define __VIFDMA_H__
enum VifModes
{
VIF_NORMAL_TO_MEM_MODE = 0,
VIF_NORMAL_FROM_MEM_MODE = 1,
VIF_CHAIN_MODE = 2
};
struct vifCode {
u32 addr;
u32 size;
@ -87,18 +80,18 @@ void __fastcall UNPACK_V4_8s( u32 *dest, u32 *data, int size );
void __fastcall UNPACK_V4_5( u32 *dest, u32 *data, int size );
void vifDmaInit();
void vif0Init();
void vif1Init();
extern void vifDmaInit();
extern void vif0Init();
extern void vif0Interrupt();
extern void vif0Write32(u32 mem, u32 value);
extern void vif0Reset();
extern void vif1Interrupt();
extern void vif1Init();
extern void Vif1MskPath3();
void vif0Write32(u32 mem, u32 value);
void vif1Write32(u32 mem, u32 value);
void vif0Reset();
void vif1Reset();
extern void vif1Write32(u32 mem, u32 value);
extern void vif1Reset();
__forceinline static int _limit(int a, int max)
{

View File

@ -16,6 +16,13 @@
#ifndef __VIFDMA_INTERNAL_H__
#define __VIFDMA_INTERNAL_H__
enum VifModes
{
VIF_NORMAL_TO_MEM_MODE = 0,
VIF_NORMAL_FROM_MEM_MODE = 1,
VIF_CHAIN_MODE = 2
};
// Generic constants
static const unsigned int VIF0intc = 4;
static const unsigned int VIF1intc = 5;
@ -35,11 +42,11 @@ struct VIFUnpackFuncTable
// will be decompressed from data for 1 cycle
};
extern int g_vifCycles;
extern u8 s_maskwrite[256];
extern const VIFUnpackFuncTable VIFfuncTable[16];
extern __aligned16 u32 g_vif0Masks[64], g_vif1Masks[64];
extern u32 g_vif0HasMask3[4], g_vif1HasMask3[4];
extern int g_vifCycles;
extern u8 s_maskwrite[256];
template<const u32 VIFdmanum> void ProcessMemSkip(u32 size, u32 unpackType);
template<const u32 VIFdmanum> u32 VIFalign(u32 *data, vifCode *v, u32 size);