Unverified Commit 37f0dc56 authored by Libretro-Admin's avatar Libretro-Admin Committed by GitHub
Browse files
parent 302344c1
Pipeline #19941 failed with stages
in 3 minutes and 15 seconds
......@@ -28,19 +28,6 @@ static _vmem_WriteMem32FP* _vmem_WF32[HANDLER_COUNT];
//upper 8b of the address
static void* _vmem_MemInfo_ptr[0x100];
void* _vmem_get_ptr2(u32 addr,u32& mask)
{
u32 page=addr>>24;
size_t iirf=(size_t)_vmem_MemInfo_ptr[page];
void* ptr=(void*)(iirf&~HANDLER_MAX);
if (ptr==0)
return 0;
mask=0xFFFFFFFF>>iirf;
return ptr;
}
void* _vmem_read_const(u32 addr,bool& ismem,u32 sz)
{
u32 page=addr>>24;
......@@ -53,19 +40,20 @@ void* _vmem_read_const(u32 addr,bool& ismem,u32 sz)
const unat id=iirf;
if (sz==1)
{
return (void*)_vmem_RF8[id/4];
return (void*)_vmem_RF8[id];
}
else if (sz==2)
{
return (void*)_vmem_RF16[id/4];
return (void*)_vmem_RF16[id];
}
else if (sz==4)
{
return (void*)_vmem_RF32[id/4];
return (void*)_vmem_RF32[id];
}
else
{
die("Invalid size");
return nullptr;
}
}
else
......@@ -76,7 +64,6 @@ void* _vmem_read_const(u32 addr,bool& ismem,u32 sz)
return &(((u8*)ptr)[addr]);
}
die("Invalid memory size");
return 0;
}
......@@ -93,19 +80,20 @@ void* _vmem_write_const(u32 addr,bool& ismem,u32 sz)
const unat id=iirf;
if (sz==1)
{
return (void*)_vmem_WF8[id/4];
return (void*)_vmem_WF8[id];
}
else if (sz==2)
{
return (void*)_vmem_WF16[id/4];
return (void*)_vmem_WF16[id];
}
else if (sz==4)
{
return (void*)_vmem_WF32[id/4];
return (void*)_vmem_WF32[id];
}
else
{
die("Invalid size");
return nullptr;
}
}
else
......@@ -116,7 +104,6 @@ void* _vmem_write_const(u32 addr,bool& ismem,u32 sz)
return &(((u8*)ptr)[addr]);
}
die("Invalid memory size");
return 0;
}
......@@ -124,7 +111,7 @@ void* _vmem_write_const(u32 addr,bool& ismem,u32 sz)
template<typename T,typename Trv>
INLINE Trv DYNACALL _vmem_readt(u32 addr)
{
const u32 sz=sizeof(T);
constexpr u32 sz = sizeof(T);
u32 page=addr>>24; //1 op, shift/extract
unat iirf=(unat)_vmem_MemInfo_ptr[page]; //2 ops, insert + read [vmem table will be on reg ]
......@@ -143,20 +130,20 @@ INLINE Trv DYNACALL _vmem_readt(u32 addr)
const u32 id=iirf;
if (sz==1)
{
return (T)_vmem_RF8[id/4](addr);
return (T)_vmem_RF8[id](addr);
}
else if (sz==2)
{
return (T)_vmem_RF16[id/4](addr);
return (T)_vmem_RF16[id](addr);
}
else if (sz==4)
{
return _vmem_RF32[id/4](addr);
return _vmem_RF32[id](addr);
}
else if (sz==8)
{
T rv=_vmem_RF32[id/4](addr);
rv|=(T)((u64)_vmem_RF32[id/4](addr+4)<<32);
T rv=_vmem_RF32[id](addr);
rv|=(T)((u64)_vmem_RF32[id](addr+4)<<32);
return rv;
}
......@@ -165,6 +152,7 @@ INLINE Trv DYNACALL _vmem_readt(u32 addr)
die("Invalid size");
}
}
return 0;
}
template u8 DYNACALL _vmem_readt<u8, u8>(u32 addr);
template u16 DYNACALL _vmem_readt<u16, u16>(u32 addr);
......@@ -174,7 +162,7 @@ template u64 DYNACALL _vmem_readt<u64, u64>(u32 addr);
template<typename T>
INLINE void DYNACALL _vmem_writet(u32 addr,T data)
{
const u32 sz=sizeof(T);
constexpr u32 sz = sizeof(T);
u32 page=addr>>24;
unat iirf=(unat)_vmem_MemInfo_ptr[page];
......@@ -192,20 +180,20 @@ INLINE void DYNACALL _vmem_writet(u32 addr,T data)
const u32 id=iirf;
if (sz==1)
{
_vmem_WF8[id/4](addr,data);
_vmem_WF8[id](addr,data);
}
else if (sz==2)
{
_vmem_WF16[id/4](addr,data);
_vmem_WF16[id](addr,data);
}
else if (sz==4)
{
_vmem_WF32[id/4](addr,data);
_vmem_WF32[id](addr,data);
}
else if (sz==8)
{
_vmem_WF32[id/4](addr,(u32)data);
_vmem_WF32[id/4](addr+4,(u32)((u64)data>>32));
_vmem_WF32[id](addr,(u32)data);
_vmem_WF32[id](addr+4,(u32)((u64)data>>32));
}
else
{
......@@ -234,11 +222,8 @@ void DYNACALL _vmem_WriteMem16(u32 Address,u16 data) { _vmem_writet<u16>(Address
void DYNACALL _vmem_WriteMem32(u32 Address,u32 data) { _vmem_writet<u32>(Address,data); }
void DYNACALL _vmem_WriteMem64(u32 Address,u64 data) { _vmem_writet<u64>(Address,data); }
//0xDEADC0D3 or 0
#define MEM_ERROR_RETURN_VALUE 0xDEADC0D3
#define MEM_ERROR_RETURN_VALUE 0
//phew .. that was lota asm code ;) lets go back to C :D
//default mem handlers ;)
//default read handlers
static u8 DYNACALL _vmem_ReadMem8_not_mapped(u32 addresss)
{
......@@ -314,7 +299,7 @@ void _vmem_map_handler(_vmem_handler Handler,u32 start,u32 end)
verify(start<=end);
for (u32 i=start;i<=end;i++)
{
_vmem_MemInfo_ptr[i]=((u8*)0)+(0x00000000 + Handler*4);
_vmem_MemInfo_ptr[i] = (u8*)nullptr + Handler;
}
}
......@@ -402,6 +387,8 @@ static void* malloc_pages(size_t size) {
#endif
}
#if FEAT_SHREC != DYNAREC_NONE
// Resets the FPCB table (by either clearing it to the default val
// or by flushing it and making it fault on access again.
void _vmem_bm_reset(void)
......@@ -434,6 +421,7 @@ bool BM_LockedWrite(u8* address) {
}
return false;
}
#endif
static void _vmem_set_p0_mappings()
{
......@@ -477,7 +465,9 @@ bool _vmem_reserve(void)
// Allocate it all and initialize it.
p_sh4rcb = (Sh4RCB*)malloc_pages(sizeof(Sh4RCB));
#if FEAT_SHREC != DYNAREC_NONE
bm_vmem_pagefill((void**)p_sh4rcb->fpcb, sizeof(p_sh4rcb->fpcb));
#endif
mem_b.size = RAM_SIZE;
mem_b.data = (u8*)malloc_pages(RAM_SIZE);
......@@ -720,9 +710,9 @@ u32 _vmem_get_vram_offset(void *addr)
}
if ((offset >> 24) != 4)
return -1;
verify((((u8*)addr - virt_ram_base) >> 29) == 0
|| (((u8*)addr - virt_ram_base) >> 29) == 4
|| (((u8*)addr - virt_ram_base) >> 29) == 5); // others areas aren't mapped atm
if ((((u8*)addr - virt_ram_base) >> 29) != 0 && (((u8*)addr - virt_ram_base) >> 29) != 4 && (((u8*)addr - virt_ram_base) >> 29) != 5)
// other areas aren't mapped atm
return -1;
return offset & VRAM_MASK;
}
......
......@@ -93,7 +93,6 @@ bool _vmem_reserve();
void _vmem_release();
//dynarec helpers
void* _vmem_get_ptr2(u32 addr,u32& mask);
void* _vmem_read_const(u32 addr,bool& ismem,u32 sz);
void* _vmem_write_const(u32 addr,bool& ismem,u32 sz);
......
......@@ -289,6 +289,7 @@ static u32 vmem32_map_mmu(u32 address, bool write)
}
else if (offset >= MAP_RAM_START_OFFSET && offset < MAP_RAM_START_OFFSET + RAM_SIZE)
{
#if FEAT_SHREC != DYNAREC_NONE
// Check system RAM protected pages
u32 start = offset - MAP_RAM_START_OFFSET;
......@@ -307,6 +308,7 @@ static u32 vmem32_map_mmu(u32 address, bool write)
}
}
else
#endif
verify(vmem32_map_buffer(vpn, page_size, offset, page_size, allow_write) != NULL);
}
else
......
......@@ -183,50 +183,36 @@ void YUV_data(u32* data , u32 count)
verify(count==0);
}
//Regs
//vram 32-64b
//read
u8 DYNACALL pvr_read_area1_8(u32 addr)
{
return vram[pvr_map32(addr)];
}
u16 DYNACALL pvr_read_area1_16(u32 addr)
{
return *(u16*)&vram.data[pvr_map32(addr)];
}
u32 DYNACALL pvr_read_area1_32(u32 addr)
template<typename T>
T DYNACALL pvr_read_area1(u32 addr)
{
return *(u32*)&vram.data[pvr_map32(addr)];
return *(T *)&vram[pvr_map32(addr)];
}
template u8 pvr_read_area1<u8>(u32 addr);
template u16 pvr_read_area1<u16>(u32 addr);
template u32 pvr_read_area1<u32>(u32 addr);
//write
void DYNACALL pvr_write_area1_8(u32 addr,u8 data)
template<typename T>
void DYNACALL pvr_write_area1(u32 addr, T data)
{
INFO_LOG(MEMORY, "%08x: 8-bit VRAM writes are not possible", addr);
}
void DYNACALL pvr_write_area1_16(u32 addr,u16 data)
{
u32 vaddr = addr & VRAM_MASK;
if (vaddr >= fb_watch_addr_start && vaddr < fb_watch_addr_end)
{
fb_dirty = true;
}
*(u16*)&vram.data[pvr_map32(addr)]=data;
}
if (sizeof(T) == 1)
{
INFO_LOG(MEMORY, "%08x: 8-bit VRAM writes are not possible", addr);
return;
}
u32 vaddr = addr & VRAM_MASK;
if (vaddr >= fb_watch_addr_start && vaddr < fb_watch_addr_end)
fb_dirty = true;
void DYNACALL pvr_write_area1_32(u32 addr,u32 data)
{
u32 vaddr = addr & VRAM_MASK;
if (vaddr >= fb_watch_addr_start && vaddr < fb_watch_addr_end)
{
fb_dirty = true;
}
*(u32*)&vram.data[pvr_map32(addr)] = data;
*(T *)&vram[pvr_map32(addr)] = data;
}
template void pvr_write_area1<u8>(u32 addr, u8 data);
template void pvr_write_area1<u16>(u32 addr, u16 data);
template void pvr_write_area1<u32>(u32 addr, u32 data);
void TAWrite(u32 address, u32* data, u32 count)
{
......@@ -246,7 +232,7 @@ void NOINLINE MemWrite32(void* dst, void* src)
#if HOST_CPU!=CPU_ARM
extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb)
{
u32 address_w = address & 0x1FFFFE0;
u32 address_w = address & 0x01FFFFE0;
u8* sq = &sqb[address & 0x20];
if (likely(address_w < 0x800000))//TA poly
......@@ -261,7 +247,8 @@ extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb)
{
// Used by WinCE
DEBUG_LOG(MEMORY, "Vram TAWriteSQ 0x%X SB_LMMODE0 %d", address, SB_LMMODE0);
if (SB_LMMODE0 == 0)
bool path64b = (address & 0x02000000 ? SB_LMMODE1 : SB_LMMODE0) == 0;
if (path64b)
{
// 64b path
memcpy(&vram[address_w & VRAM_MASK], sq, 32);
......@@ -270,7 +257,7 @@ extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb)
{
// 32b path
for (int i = 0; i < 8; i++, address_w += 4)
pvr_write_area1_32(address_w, ((u32 *)sq)[i]);
pvr_write_area1<u32>(address_w, ((u32 *)sq)[i]);
}
}
}
......@@ -302,3 +289,35 @@ u32 vri(u32 addr)
{
return *(u32*)&vram.data[pvr_map32(addr)];
}
template<typename T, bool upper>
T pvr_read_area4(u32 addr)
{
bool access32 = (upper ? SB_LMMODE1 : SB_LMMODE0) == 1;
if (access32)
return pvr_read_area1<T>(addr);
else
return *(T*)&vram[addr & VRAM_MASK];
}
template u8 pvr_read_area4<u8, false>(u32 addr);
template u16 pvr_read_area4<u16, false>(u32 addr);
template u32 pvr_read_area4<u32, false>(u32 addr);
template u8 pvr_read_area4<u8, true>(u32 addr);
template u16 pvr_read_area4<u16, true>(u32 addr);
template u32 pvr_read_area4<u32, true>(u32 addr);
template<typename T, bool upper>
void pvr_write_area4(u32 addr, T data)
{
bool access32 = (upper ? SB_LMMODE1 : SB_LMMODE0) == 1;
if (access32)
pvr_write_area1(addr, data);
else
*(T*)&vram[addr & VRAM_MASK] = data;
}
template void pvr_write_area4<u8, false>(u32 addr, u8 data);
template void pvr_write_area4<u16, false>(u32 addr, u16 data);
template void pvr_write_area4<u32, false>(u32 addr, u32 data);
template void pvr_write_area4<u8, true>(u32 addr, u8 data);
template void pvr_write_area4<u16, true>(u32 addr, u16 data);
template void pvr_write_area4<u32, true>(u32 addr, u32 data);
......@@ -6,19 +6,17 @@ u32 vri(u32 addr);
//vram 32-64b
extern VArray2 vram;
//read
u8 DYNACALL pvr_read_area1_8(u32 addr);
u16 DYNACALL pvr_read_area1_16(u32 addr);
u32 DYNACALL pvr_read_area1_32(u32 addr);
//write
void DYNACALL pvr_write_area1_8(u32 addr,u8 data);
void DYNACALL pvr_write_area1_16(u32 addr,u16 data);
void DYNACALL pvr_write_area1_32(u32 addr,u32 data);
//regs
u32 pvr_ReadReg(u32 addr);
void pvr_WriteReg(u32 paddr,u32 data);
void TAWrite(u32 address,u32* data,u32 count);
extern "C" void DYNACALL TAWriteSQ(u32 address,u8* sqb);
void YUV_init();
template<typename T> T DYNACALL pvr_read_area1(u32 addr);
template<typename T> void DYNACALL pvr_write_area1(u32 addr, T data);
template<typename T, bool upper> T pvr_read_area4(u32 addr);
template<typename T, bool upper> void pvr_write_area4(u32 addr, T data);
......@@ -54,7 +54,9 @@ void DMAC_Ch2St()
// 13000000 - 13FFFFE0
else
{
if (SB_LMMODE0 == 0)
bool path64b = SB_C2DSTAT & 0x02000000 ? SB_LMMODE1 == 0 : SB_LMMODE0 == 0;
if (path64b)
{
// 64-bit path
dst = (dst & 0x00FFFFFF) | 0xa4000000;
......@@ -77,7 +79,7 @@ void DMAC_Ch2St()
while (len > 0)
{
u32 v = ReadMem32_nommu(src);
pvr_write_area1_32(dst, v);
pvr_write_area1<u32>(dst, v);
len -= 4;
src += 4;
dst += 4;
......@@ -103,7 +105,11 @@ static const InterruptID dmac_itr[] = { sh4_DMAC_DMTE0, sh4_DMAC_DMTE1, sh4_DMAC
template<u32 ch>
void WriteCHCR(u32 addr, u32 data)
{
DMAC_CHCR(ch).full=data;
if (ch == 0 || ch == 1)
DMAC_CHCR(ch).full = data & 0xff0ffff7;
else
// no AL or RL on channels 2 and 3
DMAC_CHCR(ch).full = data & 0xff0afff7;
if (DMAC_CHCR(ch).TE == 0 && DMAC_CHCR(ch).DE && DMAC_DMAOR.DME)
{
......@@ -111,8 +117,9 @@ 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,
DEBUG_LOG(SH4, "DMAC: Manual DMA ch:%d TS:%d src: %08X dst: %08X len: %08X SM: %d, DM: %d", ch, DMAC_CHCR(ch).TS,
DMAC_SAR(ch), DMAC_DAR(ch), DMAC_DMATCR(ch), DMAC_CHCR(ch).SM, DMAC_CHCR(ch).DM);
verify(DMAC_CHCR(ch).TS == 4);
for (u32 ofs = 0; ofs < len; ofs += 4)
{
u32 data = ReadMem32_nommu(DMAC_SAR(ch) + ofs);
......@@ -120,6 +127,14 @@ void WriteCHCR(u32 addr, u32 data)
}
DMAC_CHCR(ch).TE = 1;
if (DMAC_CHCR(ch).SM == 1)
DMAC_SAR(ch) += len;
else if (DMAC_CHCR(ch).SM == 2)
DMAC_SAR(ch) -= len;
if (DMAC_CHCR(ch).DM == 1)
DMAC_DAR(ch) += len;
else if (DMAC_CHCR(ch).DM == 2)
DMAC_DAR(ch) -= len;
}
InterruptPend(dmac_itr[ch], DMAC_CHCR(ch).TE);
......
......@@ -297,8 +297,9 @@ u32 mmu_data_translation(u32 va, u32& rv)
}
}
if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000))
if ((va & 0xFC000000) == 0x7C000000)
{
// On-chip RAM area isn't translated
rv = va;
return MMU_ERROR_NONE;
}
......@@ -311,7 +312,9 @@ u32 mmu_data_translation(u32 va, u32& rv)
const TLB_Entry *entry;
u32 lookup = mmu_full_lookup(va, &entry, rv);
if (lookup == MMU_ERROR_NONE && (rv & 0x1C000000) == 0x1C000000)
// map 1C000000-1FFFFFFF to P4 memory-mapped registers
rv |= 0xF0000000;
#ifdef TRACE_WINCE_SYSCALLS
if (unresolved_unicode_string != 0 && lookup == MMU_ERROR_NONE)
{
......
......@@ -470,9 +470,9 @@ u32 mmu_data_translation(u32 va, u32& rv)
return MMU_ERROR_BADADDR;
}
if (sr.MD == 1 && ((va & 0xFC000000) == 0x7C000000))
if ((va & 0xFC000000) == 0x7C000000)
{
// 7C000000 to 7FFFFFFF in P0 not translated in supervisor mode
// 7C000000 to 7FFFFFFF in P0/U0 not translated
rv = va;
return MMU_ERROR_NONE;
}
......@@ -510,6 +510,9 @@ u32 mmu_data_translation(u32 va, u32& rv)
else if (entry->Data.D == 0)
return MMU_ERROR_FIRSTWRITE;
}
if ((rv & 0x1C000000) == 0x1C000000)
// map 1C000000-1FFFFFFF to P4 memory-mapped registers
rv |= 0xF0000000;
return MMU_ERROR_NONE;
}
template u32 mmu_data_translation<MMU_TT_DREAD, u8>(u32 va, u32& rv);
......
......@@ -97,17 +97,9 @@ bool mmu_is_translated(u32 va, u32 size)
//SQ writes are not translated, only write backs are.
return false;
}
#ifndef sr
// This is why the preprocessor sucks
#define sr Sh4cntx.sr
#define undef_sr
#endif
if (sr.MD == 1 && (va & 0xFC000000) == 0x7C000000)
if ((va & 0xFC000000) == 0x7C000000)
// On-chip RAM area isn't translated
return false;
#ifdef undef_sr
#undef sr
#undef undef_sr
#endif
if (fast_reg_lut[va >> 29] != 0)
return false;
......
......@@ -197,9 +197,9 @@ private:
}
cached = CCN_CCR.ICE == 1 && cachedArea(area);
if (CCN_MMUCR.AT == 0 || !translatedArea(area)
// 7C000000 to 7FFFFFFF in P0 not translated in supervisor mode
|| (!userMode && (address & 0xFC000000) == 0x7C000000))
if (CCN_MMUCR.AT == 0 || !translatedArea(area)
// 7C000000 to 7FFFFFFF in P0/U0 not translated
|| (address & 0xFC000000) == 0x7C000000)
{
physAddr = address;
}
......@@ -530,9 +530,9 @@ private:
// Use CCR.CB if P1 otherwise use !CCR.WT
copyBack = area == 4 ? CCN_CCR.CB : !CCN_CCR.WT;
if (CCN_MMUCR.AT == 0 || !translatedArea(area)
// 7C000000 to 7FFFFFFF in P0 not translated in supervisor mode
|| (!userMode && (address & 0xFC000000) == 0x7C000000))
if (CCN_MMUCR.AT == 0 || !translatedArea(area)
// 7C000000 to 7FFFFFFF in P0/U0 not translated
|| (address & 0xFC000000) == 0x7C000000)
{
physAddr = address;
}
......@@ -563,6 +563,9 @@ private:
copyBack = copyBack && entry->Data.WT == 0;
}
cached = cached && entry->Data.C == 1;
if ((physAddr & 0x1C000000) == 0x1C000000)
// map 1C000000-1FFFFFFF to P4 memory-mapped registers
physAddr |= 0xF0000000;
}
return MMU_ERROR_NONE;
}
......
......@@ -35,30 +35,27 @@ void _vmem_init();
void _vmem_reset();
void _vmem_term();
//MEM MAPPINNGG
//AREA 1
static _vmem_handler area1_32b;
static void map_area1_init()
{
area1_32b = _vmem_register_handler(pvr_read_area1_8,pvr_read_area1_16,pvr_read_area1_32,
pvr_write_area1_8,pvr_write_area1_16,pvr_write_area1_32);
area1_32b = _vmem_register_handler_Template(pvr_read_area1, pvr_write_area1);
}
static void map_area1(u32 base)
{
//map vram
//VRAM
//Lower 32 mb map
//Lower 32 mb map
//64b interface
_vmem_map_block(vram.data,0x04 | base,0x04 | base,VRAM_SIZE-1);
_vmem_map_block(vram.data, 0x04 | base, 0x04 | base, VRAM_MASK);
//32b interface
_vmem_map_handler(area1_32b,0x05 | base,0x05 | base);
_vmem_map_handler(area1_32b, 0x05 | base, 0x05 | base);
//Upper 32 mb mirror
//0x0600 to 0x07FF
_vmem_mirror_mapping(0x06|base,0x04|base,0x02);
_vmem_mirror_mapping(0x06 | base, 0x04 | base, 0x02);
}
//AREA 2
......@@ -80,22 +77,28 @@ static void map_area3_init()
static void map_area3(u32 base)
{
//32x2 or 16x4
_vmem_map_block_mirror(mem_b.data,0x0C | base,0x0F | base,RAM_SIZE);
//System RAM
_vmem_map_block_mirror(mem_b.data, 0x0C | base,0x0F | base, RAM_SIZE);
}
//AREA 4
static _vmem_handler area4_handler_lower;
static _vmem_handler area4_handler_upper;
static void map_area4_init()