diff --git a/core/hw/mem/_vmem.cpp b/core/hw/mem/_vmem.cpp index 5decc9da5..a899d2bfe 100644 --- a/core/hw/mem/_vmem.cpp +++ b/core/hw/mem/_vmem.cpp @@ -103,7 +103,7 @@ void* _vmem_write_const(u32 addr,bool& ismem,u32 sz) template 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 ] @@ -154,7 +154,7 @@ template u64 DYNACALL _vmem_readt(u32 addr); template 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]; @@ -214,8 +214,7 @@ void DYNACALL _vmem_WriteMem16(u32 Address,u16 data) { _vmem_writet(Address void DYNACALL _vmem_WriteMem32(u32 Address,u32 data) { _vmem_writet(Address,data); } void DYNACALL _vmem_WriteMem64(u32 Address,u64 data) { _vmem_writet(Address,data); } -//0xDEADC0D3 or 0 -#define MEM_ERROR_RETURN_VALUE 0xDEADC0D3 +#define MEM_ERROR_RETURN_VALUE 0 //default read handlers static u8 DYNACALL _vmem_ReadMem8_not_mapped(u32 addresss) @@ -378,6 +377,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() @@ -410,6 +411,7 @@ bool BM_LockedWrite(u8* address) { } return false; } +#endif static void _vmem_set_p0_mappings() { @@ -481,7 +483,9 @@ void _vmem_init_mappings() // 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); @@ -726,7 +730,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; } diff --git a/core/hw/mem/vmem32.cpp b/core/hw/mem/vmem32.cpp index a986944b1..e0472210f 100644 --- a/core/hw/mem/vmem32.cpp +++ b/core/hw/mem/vmem32.cpp @@ -279,6 +279,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; @@ -297,6 +298,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 diff --git a/core/hw/sh4/modules/fastmmu.cpp b/core/hw/sh4/modules/fastmmu.cpp index c12c989ba..e72a762db 100644 --- a/core/hw/sh4/modules/fastmmu.cpp +++ b/core/hw/sh4/modules/fastmmu.cpp @@ -299,8 +299,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; } @@ -313,7 +314,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) { diff --git a/core/hw/sh4/modules/mmu.cpp b/core/hw/sh4/modules/mmu.cpp index 3c1d75346..37789595a 100644 --- a/core/hw/sh4/modules/mmu.cpp +++ b/core/hw/sh4/modules/mmu.cpp @@ -486,9 +486,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; } @@ -537,6 +537,10 @@ 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(u32 va, u32& rv); diff --git a/core/hw/sh4/modules/mmu.h b/core/hw/sh4/modules/mmu.h index a9ea15573..30d7a323e 100644 --- a/core/hw/sh4/modules/mmu.h +++ b/core/hw/sh4/modules/mmu.h @@ -98,17 +98,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; diff --git a/core/hw/sh4/sh4_cache.h b/core/hw/sh4/sh4_cache.h index 91eb10ea1..6dcb67a49 100644 --- a/core/hw/sh4/sh4_cache.h +++ b/core/hw/sh4/sh4_cache.h @@ -198,8 +198,8 @@ 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)) + // 7C000000 to 7FFFFFFF in P0/U0 not translated + || (address & 0xFC000000) == 0x7C000000) { physAddr = address; } @@ -531,8 +531,8 @@ private: 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)) + // 7C000000 to 7FFFFFFF in P0/U0 not translated + || (address & 0xFC000000) == 0x7C000000) { physAddr = address; } @@ -563,6 +563,10 @@ 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; } diff --git a/core/hw/sh4/sh4_mmr.cpp b/core/hw/sh4/sh4_mmr.cpp index 24c295b44..830a92fb1 100644 --- a/core/hw/sh4/sh4_mmr.cpp +++ b/core/hw/sh4/sh4_mmr.cpp @@ -389,10 +389,11 @@ void DYNACALL WriteMem_P4(u32 addr,T data) //*********** #define OUT_OF_RANGE(reg) INFO_LOG(SH4, "Out of range on register %s index %x", reg, addr) +#define A7_REG_HASH(addr) (((addr) >> 16) & 0x1FFF) -//Read Area7 +//Read P4 memory-mapped registers template -T DYNACALL ReadMem_area7(u32 addr) +T DYNACALL ReadMem_p4mmr(u32 addr) { constexpr size_t sz = sizeof(T); /* @@ -415,7 +416,7 @@ T DYNACALL ReadMem_area7(u32 addr) addr&=0x1FFFFFFF; u32 map_base=addr>>16; - switch (map_base) + switch (expected(map_base, A7_REG_HASH(TMU_BASE_addr))) { case A7_REG_HASH(CCN_BASE_addr): if (addr<=0x1F000044) @@ -562,13 +563,13 @@ T DYNACALL ReadMem_area7(u32 addr) break; } - INFO_LOG(SH4, "Unknown Read from Area7 - addr=%x", addr); + INFO_LOG(SH4, "Unknown Read from P4 mmr - addr=%x", addr); return 0; } -//Write Area7 +//Write P4 memory-mapped registers template -void DYNACALL WriteMem_area7(u32 addr,T data) +void DYNACALL WriteMem_p4mmr(u32 addr,T data) { constexpr size_t sz = sizeof(T); if (likely(addr==0xFF000038)) @@ -720,59 +721,30 @@ void DYNACALL WriteMem_area7(u32 addr,T data) break; } - INFO_LOG(SH4, "Write to Area7 not implemented, addr=%x, data=%x", addr, data); + INFO_LOG(SH4, "Write to P4 mmr not implemented, addr=%x, data=%x", addr, data); } //*********** //On Chip Ram //*********** -//Read OCR template -T DYNACALL ReadMem_area7_OCR_T(u32 addr) +T DYNACALL ReadMem_area7_OCR(u32 addr) { - if (CCN_CCR.ORA) - { - if (sizeof(T) == 1) - return (T)OnChipRAM[addr&OnChipRAM_MASK]; - else if (sizeof(T) == 2) - return (T)*(u16*)&OnChipRAM[addr&OnChipRAM_MASK]; - else if (sizeof(T) == 4) - return (T)*(u32*)&OnChipRAM[addr&OnChipRAM_MASK]; - else - { - ERROR_LOG(SH4, "ReadMem_area7_OCR_T: template SZ is wrong = %zd", sizeof(T)); - return 0xDE; - } - } - else - { - INFO_LOG(SH4, "On Chip Ram Read, but OCR is disabled. addr %x", addr); - return 0xDE; - } + if (CCN_CCR.ORA == 1) + return *(T *)&OnChipRAM[addr & OnChipRAM_MASK]; + + INFO_LOG(SH4, "On Chip Ram Read, but OCR is disabled. addr %x", addr); + return 0; } -//Write OCR template -void DYNACALL WriteMem_area7_OCR_T(u32 addr,T data) +void DYNACALL WriteMem_area7_OCR(u32 addr, T data) { - if (CCN_CCR.ORA) - { - if (sizeof(T) == 1) - OnChipRAM[addr&OnChipRAM_MASK]=(u8)data; - else if (sizeof(T) == 2) - *(u16*)&OnChipRAM[addr&OnChipRAM_MASK]=(u16)data; - else if (sizeof(T) == 4) - *(u32*)&OnChipRAM[addr&OnChipRAM_MASK]=data; - else - { - ERROR_LOG(SH4, "WriteMem_area7_OCR_T: template SZ is wrong = %zd", sizeof(T)); - } - } + if (CCN_CCR.ORA == 1) + *(T *)&OnChipRAM[addr & OnChipRAM_MASK] = data; else - { INFO_LOG(SH4, "On Chip Ram Write, but OCR is disabled. addr %x", addr); - } } template @@ -863,42 +835,31 @@ void sh4_mmr_term() ccn_term(); bsc_term(); } -//Mem map :) -//AREA 7--Sh4 Regs -_vmem_handler area7_handler; - -_vmem_handler area7_orc_handler; +// AREA 7--Sh4 Regs +static _vmem_handler p4mmr_handler; +static _vmem_handler area7_ocr_handler; void map_area7_init() { - //=_vmem_register_handler(ReadMem8_area7,ReadMem16_area7,ReadMem32_area7, - // WriteMem8_area7,WriteMem16_area7,WriteMem32_area7); - - //default area7 handler - area7_handler= _vmem_register_handler_Template(ReadMem_area7,WriteMem_area7); - - area7_orc_handler= _vmem_register_handler_Template(ReadMem_area7_OCR_T,WriteMem_area7_OCR_T); + p4mmr_handler = _vmem_register_handler_Template(ReadMem_p4mmr, WriteMem_p4mmr); + area7_ocr_handler = _vmem_register_handler_Template(ReadMem_area7_OCR, WriteMem_area7_OCR); } + void map_area7(u32 base) { - //OCR @ - //((addr>=0x7C000000) && (addr<=0x7FFFFFFF)) - if (base==0x60) - _vmem_map_handler(area7_orc_handler,0x1C | base , 0x1F| base); - else - { - _vmem_map_handler(area7_handler,0x1C | base , 0x1F| base); - } + // on-chip RAM: 7C000000-7FFFFFFF + if (base == 0x60) + _vmem_map_handler(area7_ocr_handler, 0x7C, 0x7F); } //P4 void map_p4() { //P4 Region : - _vmem_handler p4_handler = _vmem_register_handler_Template(ReadMem_P4,WriteMem_P4); + _vmem_handler p4_handler = _vmem_register_handler_Template(ReadMem_P4, WriteMem_P4); - //register this before area7 and SQ , so they overwrite it and handle em :) + //register this before mmr and SQ so they overwrite it and handle em //default P4 handler //0xE0000000-0xFFFFFFFF _vmem_map_handler(p4_handler,0xE0,0xFF); @@ -909,5 +870,5 @@ void map_p4() _vmem_map_block(sq_both,0xE2,0xE2,63); _vmem_map_block(sq_both,0xE3,0xE3,63); - map_area7(0xE0); + _vmem_map_handler(p4mmr_handler, 0xFF, 0xFF); } diff --git a/core/hw/sh4/sh4_mmr.h b/core/hw/sh4/sh4_mmr.h index bd070dd7e..d276ba43a 100644 --- a/core/hw/sh4/sh4_mmr.h +++ b/core/hw/sh4/sh4_mmr.h @@ -31,8 +31,6 @@ void sh4_mmr_term(); template void sh4_rio_reg(T& arr, u32 addr, RegIO flags, u32 sz, RegReadAddrFP* rf=0, RegWriteAddrFP* wf=0); -#define A7_REG_HASH(addr) (((addr) >> 16) & 0x1FFF) - #define SH4IO_REGN(mod, addr, size) ((mod)[((addr) & 255) / 4].data##size) #define SH4IO_REG(mod, name, size) SH4IO_REGN(mod, mod##_##name##_addr, size) #define SH4IO_REG_T(mod, name, size) ((mod##_##name##_type&)SH4IO_REG(mod, name, size))