From 69dabb3c0205128599d740e82bb36131844b4da9 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 28 Apr 2009 03:30:50 +0000 Subject: [PATCH] more fixes to vram mapping. this time, for one particular test case, gpu accesses to unmapped memory return 0 like it is supposed to. I will wait for more test cases before I change it in other places. --- desmume/src/ARM9.h | 2 +- desmume/src/GPU.cpp | 24 +++++++++++++----------- desmume/src/MMU.cpp | 19 +++++++++++++++++++ desmume/src/MMU.h | 1 + desmume/src/mem.h | 4 ++-- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/desmume/src/ARM9.h b/desmume/src/ARM9.h index 0a9b6849d..06d0bf163 100644 --- a/desmume/src/ARM9.h +++ b/desmume/src/ARM9.h @@ -11,7 +11,7 @@ struct ALIGN(16) ARM9_struct { u8 ARM9_REG[0x1000000]; u8 ARM9_BIOS[0x8000]; u8 ARM9_VMEM[0x800]; - u8 ARM9_LCD[0xA4000]; + u8 ARM9_LCD[0xA4000+0x4000]; //an extra 16KB for blank memory u8 ARM9_OAM[0x800]; u8* ExtPal[2][4]; diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 48970660d..40e6a21fc 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -1592,8 +1592,9 @@ INLINE void renderline_textBG(GPU * gpu, u16 XBG, u16 YBG, u16 LG) u16 wmask = (lg-1); u16 hmask = (ht-1); u16 tmp = ((YBG & hmask) >> 3); - u8 *map = NULL; - u8 *tile, *pal, *line; + u32 map; + u8 *pal, *line; + u32 tile; u16 color; u16 xoff; u16 yoff; @@ -1601,18 +1602,19 @@ INLINE void renderline_textBG(GPU * gpu, u16 XBG, u16 YBG, u16 LG) u16 xfin; s8 line_dir = 1; - u8 * mapinfo; + u32 mapinfo; TILEENTRY tileentry; u32 tmp_map = gpu->BG_map_ram[num] + (tmp&31) * 64; if(tmp>31) tmp_map+= ADDRESS_STEP_512B << bgCnt->ScreenSize ; - map = (u8*)MMU_RenderMapToLCD(tmp_map); - if(!map) return; // no map + //map = (u8*)MMU_RenderMapToLCD(tmp_map); + map = tmp_map; + //if(!map) return; // no map - tile = (u8*) MMU_RenderMapToLCD(gpu->BG_tile_ram[num]); - if(!tile) return; // no tiles + tile = gpu->BG_tile_ram[num]; + //if(!tile) return; // no tiles xoff = XBG; pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB; @@ -1627,11 +1629,11 @@ INLINE void renderline_textBG(GPU * gpu, u16 XBG, u16 YBG, u16 LG) tmp = ((xoff&wmask)>>3); mapinfo = map + (tmp&0x1F) * 2; if(tmp>31) mapinfo += 32*32*2; - tileentry.val = T1ReadWord(mapinfo, 0); + tileentry.val = T1ReadWord(MMU_gpu_map(mapinfo), 0); tilePalette = (tileentry.bits.Palette*16); - line = (u8 * )tile + (tileentry.bits.TileNum * 0x20) + ((tileentry.bits.VFlip) ? (7*4)-yoff : yoff); + line = (u8*)MMU_gpu_map(tile + (tileentry.bits.TileNum * 0x20) + ((tileentry.bits.VFlip) ? (7*4)-yoff : yoff)); if(tileentry.bits.HFlip) { @@ -1690,9 +1692,9 @@ INLINE void renderline_textBG(GPU * gpu, u16 XBG, u16 YBG, u16 LG) tmp = (xoff & (lg-1))>>3; mapinfo = map + (tmp & 31) * 2; if(tmp > 31) mapinfo += 32*32*2; - tileentry.val = T1ReadWord(mapinfo, 0); + tileentry.val = T1ReadWord(MMU_gpu_map(mapinfo), 0); - line = (u8 * )tile + (tileentry.bits.TileNum*0x40) + ((tileentry.bits.VFlip) ? (7*8)-yoff : yoff); + line = (u8*)MMU_gpu_map(tile + (tileentry.bits.TileNum*0x40) + ((tileentry.bits.VFlip) ? (7*8)-yoff : yoff)); if(tileentry.bits.HFlip) { diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 9ec5e7253..4cd0c0edc 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -420,6 +420,25 @@ u8 *MMU_RenderMapToLCD(u32 vram_addr) } +FORCEINLINE void* MMU_gpu_map(u32 vram_addr) +{ + //THIS FUNCTION IS NOT AS DANGEROUS! + //as an alternative to the above, use this: + //it is supposed to map a single gpu vram address to emulator host memory + //but it returns a pointer to some zero memory in case of accesses to unmapped memory. + //this correctly handles the case with tile accesses to unmapped memory. + //it could also potentially go through a different LUT than vram_arm9_map in case we discover + //that it needs to be set up with different or no mirroring + //(I think it is a reasonable possibility that only the cpu has the nutty mirroring rules) + + u32 vram_page = (vram_addr>>14)&(VRAM_ARM9_PAGES-1); + u32 ofs = vram_addr & 0x3FFF; + vram_page = vram_arm9_map[vram_page]; + //blank pages are handled by the extra 16KB of blank memory at the end of ARM9_LCD + //and the fact that blank pages are mapped to appear at that location + return ARM9Mem.ARM9_LCD + (vram_page<<14) + ofs; +} + template void DMAtoVRAMmapping() { diff --git a/desmume/src/MMU.h b/desmume/src/MMU.h index cc23ac872..63cc5f33c 100644 --- a/desmume/src/MMU.h +++ b/desmume/src/MMU.h @@ -181,6 +181,7 @@ extern struct armcpu_memory_iface arm7_base_memory_iface; extern struct armcpu_memory_iface arm9_direct_memory_iface; extern u8 *MMU_RenderMapToLCD(u32 vram_addr); +extern void* MMU_gpu_map(u32 vram_addr); enum MMU_ACCESS_TYPE { diff --git a/desmume/src/mem.h b/desmume/src/mem.h index 62058a5f4..e94f6dfb5 100644 --- a/desmume/src/mem.h +++ b/desmume/src/mem.h @@ -31,12 +31,12 @@ static INLINE u8 T1ReadByte(u8 * mem, u32 addr) return mem[addr]; } -static INLINE u16 T1ReadWord(u8 * mem, u32 addr) +static INLINE u16 T1ReadWord(void * mem, u32 addr) { #ifdef WORDS_BIGENDIAN return (mem[addr + 1] << 8) | mem[addr]; #else - return *((u16 *) (mem + addr)); + return *((u16 *) ((u8*)mem + addr)); #endif }