/[pcsx2_0.9.7]/trunk/pcsx2/Dmac.h
ViewVC logotype

Diff of /trunk/pcsx2/Dmac.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

--- trunk/pcsx2/Dmac.h	2010/09/07 03:24:11	31
+++ trunk/pcsx2/Dmac.h	2010/09/07 11:08:22	62
@@ -13,11 +13,7 @@
  *  If not, see <http://www.gnu.org/licenses/>.
  */
 
-
-#ifndef __DMAC_H__
-#define __DMAC_H__
-
-extern u8  *psH; // hw mem
+#pragma once
 
 // Useful enums for some of the fields.
 enum pce_values
@@ -66,7 +62,7 @@
 	STD_SIF1
 };
 
-enum TransferMode
+enum LogicalTransferMode
 {
 	NORMAL_MODE = 0,
 	CHAIN_MODE,
@@ -85,7 +81,7 @@
 union tDMA_TAG {
 	struct {
 		u32 QWC : 16;
-		u32 reserved2 : 10;
+		u32 _reserved2 : 10;
 		u32 PCE : 2;
 		u32 ID : 3;
 		u32 IRQ : 1;
@@ -121,14 +117,14 @@
 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;
 
@@ -142,6 +138,7 @@
 	u16 upper() const { return (_u32 >> 16); }
 	u16 lower() const { return (u16)_u32; }
 	wxString desc() const { return wxsFormat(L"Chcr: 0x%x", _u32); }
+	tDMA_TAG tag() { return (tDMA_TAG)_u32; }
 };
 
 #define CHCR(value) ((tDMA_CHCR)(value))
@@ -157,76 +154,36 @@
 
 	void reset() { _u32 = 0; }
 	wxString desc() const { return wxsFormat(L"Sadr: 0x%x", _u32); }
-};
-
-union tDMA_MADR {
-	struct {
-		u32 ADDR : 31; // Transfer memory address
-		u32 SPR : 1; // Memory/SPR Address
-	};
-	u32 _u32;
-
-	tDMA_MADR(u32 val) { _u32 = val; }
-
-	void reset() { _u32 = 0; }
-	wxString desc() const { return wxsFormat(L"Madr: 0x%x", _u32); }
-};
-
-union tDMA_TADR {
-	struct {
-		u32 ADDR : 31; // Next Tag address
-		u32 SPR : 1; // Memory/SPR Address
-	};
-	u32 _u32;
-
-	tDMA_TADR(u32 val) { _u32 = val; }
-
-	void reset() { _u32 = 0; }
-	wxString desc() const { return wxsFormat(L"Tadr: 0x%x", _u32); }
-};
-
-union tDMA_ASR { // The Address Stack Register
-	struct {
-		u32 ADDR : 31; // Tag memory address
-		u32 SPR : 1; // Memory/SPR Address
-	};
-	u32 _u32;
-
-	tDMA_ASR(u32 val) { _u32 = val; }
-
-	void reset() { _u32 = 0; }
-	wxString desc() const { return wxsFormat(L"Asr: 0x%x", _u32); }
+	tDMA_TAG tag() const { return (tDMA_TAG)_u32; }
 };
 
 union tDMA_QWC {
 	struct {
-		u32 QWC : 16;
-		u32 reserved2 : 16;
+		u16 QWC;
+		u16 _unused;
 	};
 	u32 _u32;
 
 	tDMA_QWC(u32 val) { _u32 = val; }
 
 	void reset() { _u32 = 0; }
-	wxString desc() const { return wxsFormat(L"QWC: 0x%x", _u32); }
+	wxString desc() const { return wxsFormat(L"QWC: 0x%04x", QWC); }
+	tDMA_TAG tag() const { return (tDMA_TAG)_u32; }
 };
-static __forceinline void setDmacStat(u32 num);
-static __forceinline tDMA_TAG *dmaGetAddr(u32 addr, bool write);
-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)
@@ -239,63 +196,14 @@
 	    qwc = ptag[0].QWC;
 	}
 
-	bool transfer(const char *s, tDMA_TAG* ptag)
-	{
-		if (ptag == NULL)  					 // Is ptag empty?
-		{
-			throwBusError(s);
-			return false;
-		}
-	    chcrTransfer(ptag);
-
-        qwcTransfer(ptag);
-        return true;
-	}
-
-	void unsafeTransfer(tDMA_TAG* ptag)
-	{
-        chcrTransfer(ptag);
-        qwcTransfer(ptag);
-	}
+	bool transfer(const char *s, tDMA_TAG* ptag);
+	void unsafeTransfer(tDMA_TAG* ptag);
+	tDMA_TAG *getAddr(u32 addr, u32 num, bool write);
+	tDMA_TAG *DMAtransfer(u32 addr, u32 num);
+	tDMA_TAG dma_tag();
 
-	tDMA_TAG *getAddr(u32 addr, u32 num, bool write)
-	{
-		tDMA_TAG *ptr = dmaGetAddr(addr, write);
-		if (ptr == NULL)
-		{
-			throwBusError("dmaGetAddr");
-			setDmacStat(num);
-			chcr.STR = false;
-		}
-
-		return ptr;
-	}
-
-	tDMA_TAG *DMAtransfer(u32 addr, u32 num)
-	{
-		tDMA_TAG *tag = getAddr(addr, num, false);
-
-		if (tag == NULL) return NULL;
-
-	    chcrTransfer(tag);
-        qwcTransfer(tag);
-        return tag;
-	}
-
-	tDMA_TAG dma_tag() const
-	{
-		return DMA_TAG(chcr._u32);
-	}
-
-	wxString cmq_to_str() const
-	{
-		return wxsFormat(L"chcr = %lx, madr = %lx, qwc  = %lx", chcr._u32, madr, qwc);
-	}
-
-	wxString cmqt_to_str() const
-	{
-		return wxsFormat(L"chcr = %lx, madr = %lx, qwc  = %lx, tadr = %1x", chcr._u32, madr, qwc, tadr);
-	}
+	wxString cmq_to_str() const;
+	wxString cmqt_to_str() const;
 };
 
 enum INTCIrqs
@@ -326,25 +234,6 @@
 	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
 {
@@ -388,7 +277,7 @@
 	bool empty() const { return (_u16 == 0); }
 };
 
-static __forceinline const wxChar* ChcrName(u32 addr)
+static __fi const wxChar* ChcrName(u32 addr)
 {
     switch (addr)
     {
@@ -407,7 +296,7 @@
 }
 
 // Believe it or not, making this const can generate compiler warnings in gcc.
-static __forceinline int ChannelNumber(u32 addr)
+static __fi int ChannelNumber(u32 addr)
 {
     switch (addr)
     {
@@ -423,7 +312,7 @@
         case D9_CHCR: return 9;
 		default:
 		{
-			DevCon.Warning("Invalid DMA channel number");
+			pxFailDev("Invalid DMA channel number");
 			return 51; // some value
 		}
     }
@@ -437,7 +326,7 @@
 		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;
 
@@ -453,17 +342,18 @@
 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;
+	u16 _u16[2];
 
 	tDMAC_STAT(u32 val) { _u32 = val; }
 
@@ -472,14 +362,19 @@
 	void clear_flags(u32 flags) { _u32 &= ~flags; }
 	void reset() { _u32 = 0; }
 	wxString desc() const { return wxsFormat(L"Stat: 0x%x", _u32); }
+
+	bool TestForInterrupt() const
+	{
+		return ((_u16[0] & _u16[1]) != 0) || BEIS;
+	}
 };
 
 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;
@@ -496,9 +391,9 @@
 union tDMAC_SQWC {
 	struct {
 		u32 SQWC : 8;
-		u32 reserved1 : 8;
+		u32 _reserved1 : 8;
 		u32 TQWC : 8;
-		u32 reserved2 : 8;
+		u32 _reserved2 : 8;
 	};
 	u32 _u32;
 
@@ -514,7 +409,7 @@
 union tDMAC_RBSR {
 	struct {
 		u32 RMSK : 31;
-		u32 reserved1 : 1;
+		u32 _reserved1 : 1;
 	};
 	u32 _u32;
 
@@ -527,7 +422,7 @@
 union tDMAC_RBOR {
 	struct {
 		u32 ADDR : 31;
-		u32 reserved1 : 1;
+		u32 _reserved1 : 1;
 	};
 	u32 _u32;
 
@@ -537,43 +432,73 @@
 	wxString desc() const { return wxsFormat(L"Rbor: 0x%x", _u32); }
 };
 
-union tDMAC_STADR {
+// --------------------------------------------------------------------------------------
+//  tDMAC_ADDR
+// --------------------------------------------------------------------------------------
+// This struct is used for several DMA address types, including some that do not have
+// effective SPR bit (the bit is ignored for all addresses that are not "allowed" to access
+// the scratchpad, including STADR, toSPR.MADR, fromSPR.MADR, etc.).
+//
+union tDMAC_ADDR
+{
 	struct {
-		u32 ADDR : 31;
-		u32 reserved1 : 1;
+		u32 ADDR : 31;	// Transfer memory address
+		u32 SPR : 1;	// Memory/SPR Address (only effective for MADR and TADR of non-SPR DMAs)
 	};
 	u32 _u32;
 
-	tDMAC_STADR(u32 val) { _u32 = val; }
+	tDMAC_ADDR() {}
+	tDMAC_ADDR(u32 val) { _u32 = val; }
 
-	void reset() { _u32 = 0; }
-	wxString desc() const { return wxsFormat(L"Stadr: 0x%x", _u32); }
-};
+	void clear() { _u32 = 0; }
+
+	void AssignADDR(uint addr)
+	{
+		ADDR = addr;
+		if (SPR) ADDR &= (Ps2MemSize::Scratch-1);
+	}
+
+	void IncrementQWC(uint incval = 1)
+	{
+		ADDR += incval;
+		if (SPR) ADDR &= (Ps2MemSize::Scratch-1);
+	}
 
+	wxString ToString(bool sprIsValid=true) const
+	{
+		return pxsFmt((sprIsValid && SPR) ? L"0x%04X(SPR)" : L"0x%08X", ADDR);
+	}
+
+	wxCharBuffer ToUTF8(bool sprIsValid=true) const
+	{
+		return FastFormatAscii().Write((sprIsValid && SPR) ? "0x%04X(SPR)" : "0x%08X", ADDR).c_str();
+	}
+};
 
 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];
-	tDMAC_STADR	stadr;
+	u32 _padding5[3];
+	tDMAC_ADDR	stadr;
+	u32 _padding6[3];
 };
 
 // Currently guesswork.
 union tINTC_STAT {
 	struct {
 		u32 interrupts : 10;
-	    u32 placeholder : 22;
+	    u32 _placeholder : 22;
 	};
 	u32 _u32;
 
@@ -589,7 +514,7 @@
 union tINTC_MASK {
 	struct {
 	    u32 int_mask : 10;
-	    u32 placeholder:22;
+	    u32 _placeholder:22;
 	};
 	u32 _u32;
 
@@ -605,90 +530,33 @@
 struct INTCregisters
 {
 	tINTC_STAT  stat;
-	u32 padding[3];
+	u32 _padding1[3];
 	tINTC_MASK  mask;
+	u32 _padding2[3];
 };
 
-#define dmacRegs ((DMACregisters*)(PS2MEM_HW+0xE000))
-#define intcRegs ((INTCregisters*)(PS2MEM_HW+0xF000))
+#define intcRegs ((INTCregisters*)(eeHw+0xF000))
 
-static __forceinline void throwBusError(const char *s)
-{
-    Console.Error("%s BUSERR", s);
-    dmacRegs->stat.BEIS = true;
-}
+static DMACregisters& dmacRegs	= (DMACregisters&)eeHw[0xE000];
 
-static __forceinline void setDmacStat(u32 num)
-{
-	dmacRegs->stat.set_flags(1 << num);
-}
-
-// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits)
-static __forceinline tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write)
-{
-	// if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); }
-
-	// FIXME: Why??? DMA uses physical addresses
-	addr &= 0x1ffffff0;
-
-	if (addr < Ps2MemSize::Base)
-	{
-		return (tDMA_TAG*)&psM[addr];
-	}
-
-	if (addr >= 0x11004000 && addr < 0x11010000)
-	{
-		//Access for VU Memory
-		return (tDMA_TAG*)vtlb_GetPhyPtr(addr & 0x1FFFFFF0);
-	}
-
-	if (addr >= Ps2MemSize::Base && addr < 0x10000000)
-	{
-		return (tDMA_TAG*)(write ? psMHW : psMHR);
-	}
-
-	Console.Error( "*PCSX2*: DMA error: %8.8x", addr);
-	return NULL;
-}
-
-// Note: Dma addresses are guaranteed to be aligned to 16 bytes (128 bits)
-static __forceinline tDMA_TAG *dmaGetAddr(u32 addr, bool write)
-{
-	// if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); }
-
-	if (DMA_TAG(addr).SPR) return (tDMA_TAG*)&psS[addr & 0x3ff0];
-
-	// FIXME: Why??? DMA uses physical addresses
-	addr &= 0x1ffffff0;
-
-	if (addr < Ps2MemSize::Base)
-	{
-		return (tDMA_TAG*)&psM[addr];
-	}
-
-	// Secret scratchpad address for DMA = end of maximum main memory?
-	if (addr >= 0x10000000 && addr < 0x10004000)
-	{
-		//Console.Warning("Writing to the scratchpad without the SPR flag set!");
-		return (tDMA_TAG*)&psS[addr & 0x3ff0];
-	}
-
-	if (addr >= Ps2MemSize::Base && addr < 0x10000000)
-	{
-		return (tDMA_TAG*)(write ? psMHW : psMHR);
-	}
-
-	Console.Error( "*PCSX2*: DMA error: %8.8x", addr);
-	return NULL;
-}
+// Various useful locations
+static DMACh& vif0ch	= (DMACh&)eeHw[0x8000];
+static DMACh& vif1ch	= (DMACh&)eeHw[0x9000];
+static DMACh& gifch		= (DMACh&)eeHw[0xA000];
+static DMACh& spr0ch	= (DMACh&)eeHw[0xD000];
+static DMACh& spr1ch	= (DMACh&)eeHw[0xD400];
 
-void hwIntcIrq(int n);
-void hwDmacIrq(int n);
+extern void throwBusError(const char *s);
+extern void setDmacStat(u32 num);
+extern tDMA_TAG *SPRdmaGetAddr(u32 addr, bool write);
+extern tDMA_TAG *dmaGetAddr(u32 addr, bool write);
 
-bool hwDmacSrcChainWithStack(DMACh *dma, int id);
-bool hwDmacSrcChain(DMACh *dma, int id);
+extern void hwIntcIrq(int n);
+extern void hwDmacIrq(int n);
 
-extern void intcInterrupt();
-extern void dmacInterrupt();
+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);
 
-#endif
+template< uint page > u32 dmacRead32( u32 mem );
+template< uint page > extern bool dmacWrite32( u32 mem, mem32_t& value );

 

  ViewVC Help
Powered by ViewVC 1.1.22