sh4: clean dmac module, correct address/len mask, add missing mirror
fix infinite loop
This commit is contained in:
parent
4ca0b56106
commit
0d81c9fb0b
|
@ -219,33 +219,18 @@ void DYNACALL pvr_write_area1_32(u32 addr,u32 data)
|
|||
|
||||
void TAWrite(u32 address, u32* data, u32 count)
|
||||
{
|
||||
u32 address_w=address&0x1FFFFFF;//correct ?
|
||||
if (address_w<0x800000)//TA poly
|
||||
{
|
||||
if ((address & 0x800000) == 0)
|
||||
// TA poly
|
||||
ta_vtx_data(data, count);
|
||||
}
|
||||
else if(address_w<0x1000000) //Yuv Converter
|
||||
{
|
||||
else
|
||||
// YUV Converter
|
||||
YUV_data(data, count);
|
||||
}
|
||||
else //Vram Writef
|
||||
{
|
||||
//shouldn't really get here (?) -> works on dc :D need to handle lmmodes
|
||||
DEBUG_LOG(MEMORY, "Vram TAWrite 0x%X , bkls %d\n", address, count);
|
||||
verify(SB_LMMODE0 == 0);
|
||||
memcpy(&vram.data[address&VRAM_MASK],data,count*32);
|
||||
}
|
||||
}
|
||||
|
||||
void NOINLINE MemWrite32(void* dst, void* src)
|
||||
{
|
||||
memcpy((u64*)dst,(u64*)src,32);
|
||||
}
|
||||
|
||||
#if HOST_CPU!=CPU_ARM
|
||||
extern "C" void DYNACALL TAWriteSQ(u32 address, u8* sqb)
|
||||
{
|
||||
u32 address_w=address&0x1FFFFFF;//correct ?
|
||||
u32 address_w = address & 0x1FFFFE0;
|
||||
u8* sq = &sqb[address & 0x20];
|
||||
|
||||
if (likely(address_w < 0x800000))//TA poly
|
||||
|
@ -263,18 +248,16 @@ extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb)
|
|||
if (SB_LMMODE0 == 0)
|
||||
{
|
||||
// 64b path
|
||||
MemWrite32(&vram[address_w&(VRAM_MASK-0x1F)],sq);
|
||||
memcpy(&vram[address_w & VRAM_MASK], sq, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 32b path
|
||||
for (int i = 0; i < 8; i++, address_w += 4)
|
||||
{
|
||||
pvr_write_area1_32(address_w, ((u32 *)sq)[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//Misc interface
|
||||
|
|
|
@ -13,25 +13,13 @@
|
|||
#include "hw/sh4/sh4_interrupts.h"
|
||||
#include "hw/holly/holly_intc.h"
|
||||
|
||||
/*
|
||||
u32 DMAC_SAR[4];
|
||||
u32 DMAC_DAR[4];
|
||||
u32 DMAC_DMATCR[4];
|
||||
DMAC_CHCR_type DMAC_CHCR[4];
|
||||
|
||||
DMAC_DMAOR_type DMAC_DMAOR;
|
||||
|
||||
*/
|
||||
|
||||
void DMAC_Ch2St()
|
||||
{
|
||||
u32 chcr = DMAC_CHCR(2).full;
|
||||
u32 dmaor = DMAC_DMAOR.full;
|
||||
u32 dmatcr = DMAC_DMATCR(2);
|
||||
|
||||
u32 src = DMAC_SAR(2);
|
||||
u32 dst = SB_C2DSTAT;
|
||||
u32 len = SB_C2DLEN ;
|
||||
u32 dst = SB_C2DSTAT & 0x01ffffe0;
|
||||
u32 len = SB_C2DLEN & 0x00ffffe0;
|
||||
|
||||
if (0x8201 != (dmaor & DMAOR_MASK))
|
||||
{
|
||||
|
@ -39,69 +27,47 @@ void DMAC_Ch2St()
|
|||
return;
|
||||
}
|
||||
|
||||
if (len & 0x1F)
|
||||
{
|
||||
INFO_LOG(SH4, "DMAC: SB_C2DLEN has invalid size (%X) !", len);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(SH4, ">> DMAC: Ch2 DMA SRC=%X DST=%X LEN=%X", src, dst, len);
|
||||
DEBUG_LOG(SH4, ">> DMAC: Ch2 DMA SRC=%X DST=%X LEN=%X", src, SB_C2DSTAT, SB_C2DLEN);
|
||||
|
||||
// Direct DList DMA (Ch2)
|
||||
|
||||
// Texture DMA
|
||||
if((dst >= 0x10000000) && (dst <= 0x10FFFFFF))
|
||||
// TA FIFO - Polygon and YUV converter paths and mirror
|
||||
// 10000000 - 10FFFFE0
|
||||
// 12000000 - 12FFFFE0
|
||||
if ((dst & 0x01000000) == 0)
|
||||
{
|
||||
u32 p_addr=src & RAM_MASK;
|
||||
//GetMemPtr perhaps ? it's not good to use the mem arrays directly
|
||||
while(len)
|
||||
u32 *sys_buf = (u32 *)GetMemPtr(src, len);
|
||||
if ((src & RAM_MASK) + len > RAM_SIZE)
|
||||
{
|
||||
if ((p_addr+len)>RAM_SIZE)
|
||||
{
|
||||
u32 *sys_buf=(u32 *)GetMemPtr(src,len);//(&mem_b[src&RAM_MASK]);
|
||||
u32 new_len=RAM_SIZE-p_addr;
|
||||
TAWrite(dst,sys_buf,(new_len/32));
|
||||
len-=new_len;
|
||||
src+=new_len;
|
||||
//dst+=new_len;
|
||||
u32 newLen = RAM_SIZE - (src & RAM_MASK);
|
||||
TAWrite(dst, sys_buf, newLen / 32);
|
||||
len -= newLen;
|
||||
src += newLen;
|
||||
sys_buf = (u32 *)GetMemPtr(src, len);
|
||||
}
|
||||
TAWrite(dst, sys_buf, len / 32);
|
||||
src += len;
|
||||
}
|
||||
// Direct Texture path and mirror
|
||||
// 11000000 - 11FFFFE0
|
||||
// 13000000 - 13FFFFE0
|
||||
else
|
||||
{
|
||||
u32 *sys_buf=(u32 *)GetMemPtr(src,len);//(&mem_b[src&RAM_MASK]);
|
||||
TAWrite(dst,sys_buf,(len/32));
|
||||
src+=len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//libPvr_TADma(dst,sys_buf,(len/32));
|
||||
}
|
||||
// If SB_C2DSTAT reg is inrange from 0x11000000 to 0x11FFFFE0, set 1 in SB_LMMODE0 reg.
|
||||
else if((dst >= 0x11000000) && (dst <= 0x11FFFFE0))
|
||||
{
|
||||
//printf(">>\tDMAC: TEX LNMODE0 Ch2 DMA SRC=%X DST=%X LEN=%X SB_LMMODE0 %d\n", src, dst, len, SB_LMMODE0);
|
||||
|
||||
if (SB_LMMODE0 == 0)
|
||||
{
|
||||
// 64-bit path
|
||||
dst=(dst&0xFFFFFF) |0xa4000000;
|
||||
u32 p_addr=src & RAM_MASK;
|
||||
while(len)
|
||||
dst = (dst & 0x00FFFFFF) | 0xa4000000;
|
||||
if ((src & RAM_MASK) + len > RAM_SIZE)
|
||||
{
|
||||
if ((p_addr+len)>RAM_SIZE)
|
||||
{
|
||||
u32 new_len=RAM_SIZE-p_addr;
|
||||
WriteMemBlock_nommu_dma(dst,src,new_len);
|
||||
len-=new_len;
|
||||
src+=new_len;
|
||||
dst+=new_len;
|
||||
u32 newLen = RAM_SIZE - (src & RAM_MASK);
|
||||
WriteMemBlock_nommu_dma(dst, src, newLen);
|
||||
len -= newLen;
|
||||
src += newLen;
|
||||
dst += newLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteMemBlock_nommu_dma(dst, src, len);
|
||||
src += len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dst += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -118,67 +84,16 @@ void DMAC_Ch2St()
|
|||
}
|
||||
SB_C2DSTAT = dst;
|
||||
}
|
||||
// If SB_C2DSTAT reg is in range from 0x13000000 to 0x13FFFFE0, set 1 in SB_LMMODE1 reg.
|
||||
else if((dst >= 0x13000000) && (dst <= 0x13FFFFE0))
|
||||
{
|
||||
//printf(">>\tDMAC: PVR DList Ch2 DMA SRC=%X DST=%X LEN=%X SB_LMMODE0 %d\n", src, dst, len, SB_LMMODE0);
|
||||
SB_C2DSTAT += len;
|
||||
|
||||
if (SB_LMMODE1 == 0)
|
||||
{
|
||||
// 64-bit path
|
||||
dst = (dst & 0xFFFFFF) | 0xa4000000;
|
||||
u32 p_addr = src & RAM_MASK;
|
||||
while (len)
|
||||
{
|
||||
if ((p_addr + len) > RAM_SIZE)
|
||||
{
|
||||
u32 new_len = RAM_SIZE - p_addr;
|
||||
WriteMemBlock_nommu_dma(dst, src, new_len);
|
||||
len -= new_len;
|
||||
src += new_len;
|
||||
dst += new_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteMemBlock_nommu_dma(dst, src, len);
|
||||
src += len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 32-bit path
|
||||
dst = (dst & 0xFFFFFF) | 0xa5000000;
|
||||
while (len > 0)
|
||||
{
|
||||
u32 v = ReadMem32_nommu(src);
|
||||
pvr_write_area1_32(dst, v);
|
||||
len -= 4;
|
||||
src += 4;
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(SH4, "DMAC: SB_C2DSTAT has invalid address (%X) !", dst);
|
||||
src+=len;
|
||||
}
|
||||
|
||||
|
||||
// Setup some of the regs so it thinks we've finished DMA
|
||||
|
||||
DMAC_SAR(2) = (src);
|
||||
DMAC_SAR(2) = src;
|
||||
DMAC_CHCR(2).TE = 1;
|
||||
DMAC_DMATCR(2) = 0;
|
||||
|
||||
SB_C2DST = 0;
|
||||
SB_C2DLEN = 0;
|
||||
|
||||
// The DMA end interrupt flag (SB_ISTNRM - bit 19: DTDE2INT) is set to "1."
|
||||
//-> fixed , holly_PVR_DMA is for different use now (fixed the interrupts enum too)
|
||||
asic_RaiseInterrupt(holly_CH2_DMA);
|
||||
}
|
||||
|
||||
|
@ -195,7 +110,8 @@ void WriteCHCR(u32 addr, u32 data)
|
|||
{
|
||||
u32 len = DMAC_DMATCR(ch) * 32;
|
||||
|
||||
DEBUG_LOG(SH4, "DMAC: Manual DMA ch:%d rs:%d src: %08X dst: %08X len: %08X SM: %d, DM: %d", ch, DMAC_CHCR(ch).RS, DMAC_SAR(ch), DMAC_DAR(ch), DMAC_DMATCR(ch), DMAC_CHCR(ch).SM, DMAC_CHCR(ch).DM);
|
||||
DEBUG_LOG(SH4, "DMAC: Manual DMA ch:%d rs:%d src: %08X dst: %08X len: %08X SM: %d, DM: %d", ch, DMAC_CHCR(ch).RS,
|
||||
DMAC_SAR(ch), DMAC_DAR(ch), DMAC_DMATCR(ch), DMAC_CHCR(ch).SM, DMAC_CHCR(ch).DM);
|
||||
for (u32 ofs = 0; ofs < len; ofs += 4)
|
||||
{
|
||||
u32 data = ReadMem32_nommu(DMAC_SAR(ch) + ofs);
|
||||
|
@ -208,14 +124,11 @@ void WriteCHCR(u32 addr, u32 data)
|
|||
InterruptPend(dmac_itr[ch], DMAC_CHCR(ch).TE);
|
||||
InterruptMask(dmac_itr[ch], DMAC_CHCR(ch).IE);
|
||||
}
|
||||
|
||||
//printf("Write to CHCR%d = 0x%X\n",ch,data);
|
||||
}
|
||||
|
||||
void WriteDMAOR(u32 addr, u32 data)
|
||||
{
|
||||
DMAC_DMAOR.full = data;
|
||||
//printf("Write to DMAOR = 0x%X\n",data);
|
||||
}
|
||||
|
||||
//Init term res
|
||||
|
|
Loading…
Reference in New Issue