From 2a69c9206785e24a1d6ba567d6d2ecb700191268 Mon Sep 17 00:00:00 2001 From: arcum42 Date: Fri, 9 Oct 2009 05:50:10 +0000 Subject: [PATCH] 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 --- pcsx2/Config.h | 2 + pcsx2/Hw.cpp | 210 ++++++++++++++++++++++------------------ pcsx2/Hw.h | 43 ++++++-- pcsx2/Sif.cpp | 12 +-- pcsx2/VifDma.cpp | 9 +- pcsx2/VifDma.h | 25 ++--- pcsx2/VifDma_internal.h | 11 ++- 7 files changed, 185 insertions(+), 127 deletions(-) diff --git a/pcsx2/Config.h b/pcsx2/Config.h index 1d11bc7e15..d911594005 100644 --- a/pcsx2/Config.h +++ b/pcsx2/Config.h @@ -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) + diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 71de79a9c7..8e05c3dd61 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -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,16 +61,16 @@ void hwReset() memzero_ptr( 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(); } -__forceinline void intcInterrupt() +__forceinline void intcInterrupt() { if ((cpuRegs.CP0.n.Status.val & 0x400) != 0x400) return; @@ -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<rbor.ADDR + dmacRegs->rbsr.RMSK + 16; u8 *dst; - - addr = psHu32(DMAC_RBOR) + (addr & psHu32(DMAC_RBSR)); - /* Check if the transfer should wrap around the ring buffer */ + addr = dmacRegs->rbor.ADDR + (addr & dmacRegs->rbsr.RMSK); + + // 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 - break; + { + 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: + // 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: + Console.Notice("Call Stack Overflow (report if it fixes/breaks anything)"); + return true; } - 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 - break; - } - default: { - Console.Notice("Call Stack Overflow (report if it fixes/breaks anything)"); - return true; //Return done - } - } - 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 - 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 - break; - } - case 0: { //Else if ASR1 and ASR0 are empty - //dma->tadr += 16; //Clear tag address - Kills Klonoa 2 - return true; //End Transfer - } - default: { //Else if ASR1 and ASR0 are messed up - //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 - } - } + { + 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; + + 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: + // There aren't any addresses to pull, so end the transfer. + //dma->tadr += 16; //Clear tag address - Kills Klonoa 2 + 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; + } 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 + case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control) + //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; diff --git a/pcsx2/Hw.h b/pcsx2/Hw.h index 6d26a1e2a3..e7f9caa811 100644 --- a/pcsx2/Hw.h +++ b/pcsx2/Hw.h @@ -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<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__ */ diff --git a/pcsx2/Sif.cpp b/pcsx2/Sif.cpp index 984f540f97..a0f577cea7 100644 --- a/pcsx2/Sif.cpp +++ b/pcsx2/Sif.cpp @@ -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; diff --git a/pcsx2/VifDma.cpp b/pcsx2/VifDma.cpp index c5aee94bfa..c7e1a4a96b 100644 --- a/pcsx2/VifDma.cpp +++ b/pcsx2/VifDma.cpp @@ -563,9 +563,12 @@ template 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) diff --git a/pcsx2/VifDma.h b/pcsx2/VifDma.h index 8cfe194505..477d368a73 100644 --- a/pcsx2/VifDma.h +++ b/pcsx2/VifDma.h @@ -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) { diff --git a/pcsx2/VifDma_internal.h b/pcsx2/VifDma_internal.h index 11366a14b4..49b6b38f0e 100644 --- a/pcsx2/VifDma_internal.h +++ b/pcsx2/VifDma_internal.h @@ -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 void ProcessMemSkip(u32 size, u32 unpackType); template u32 VIFalign(u32 *data, vifCode *v, u32 size);