From 445c953371776363365c4c220743403d3131c16b Mon Sep 17 00:00:00 2001 From: mtabachenko Date: Mon, 8 Dec 2008 09:15:40 +0000 Subject: [PATCH] core: - fix VRAM bug (ex. NSMB fixed background missing on map) --- desmume/src/GPU.cpp | 77 +++++++++++++++++++++++++++------------------ desmume/src/MMU.cpp | 65 +++++++++++++++++++++++++++----------- 2 files changed, 92 insertions(+), 50 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index f2c672725..034d4b49a 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -50,7 +50,20 @@ #include "debug.h" #include "render3D.h" #include "GPU_osd.h" -#include "debug.h" +#include "debug.h" + +//#define CHECKSPRITES + +#ifdef CHECKSPRITES +#define CHECK_SPRITE(type) \ +if (!src) {\ + INFO("Sprite%s in mode %i %s\n", type==1?"1D":"2D", spriteInfo->Mode, (spriteInfo->RotScale & 1)?"(Rotoscaled)":"");\ +continue;\ +}; +#else +#define CHECK_SPRITE(type) if (!src) { continue; }; +#endif + ARM9_struct ARM9Mem; @@ -303,7 +316,7 @@ void GPU_setVideoProp(GPU * gpu, u32 p) break; case 2: // Display framebuffer // gpu->vramBlock = DISPCNT_VRAMBLOCK(p) ; - //gpu->vramBlock = cnt->VRAM_Block; + gpu->vramBlock = cnt->VRAM_Block; return; case 3: // Display from Main RAM // nothing to be done here @@ -743,7 +756,7 @@ INLINE void renderline_textBG(const GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG, u8 * mapinfo; TILEENTRY tileentry; - map = MMU_RenderMapToLCD(gpu->BG_map_ram[num] + (tmp&31) * 64); + map = (u8 *)MMU_RenderMapToLCD(gpu->BG_map_ram[num] + (tmp&31) * 64); if (!map) return; if(tmp>31) @@ -1062,12 +1075,14 @@ INLINE void extRotBG2(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16 PA, case 2 : // 256 colors map = (u8 *)MMU_RenderMapToLCD(gpu->BG_bmp_ram[num]); + if (!map) return; pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400; apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_256_map, map, NULL, pal); return; case 3 : // direct colors / BMP map = (u8 *)MMU_RenderMapToLCD(gpu->BG_bmp_ram[num]); + if (!map) return; apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_BMP_map, map, NULL, NULL); return; } @@ -1307,7 +1322,6 @@ INLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l, return TRUE; } - /*****************************************************************************/ // SPRITE RENDERING /*****************************************************************************/ @@ -1417,7 +1431,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) if(spriteInfo->Depth) { src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex << block)); - if (!src) continue; + CHECK_SPRITE(1); // If extended palettes are set, use them if (dispCnt->ExOBJPalette_Enable) @@ -1455,7 +1469,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) else if(spriteInfo->Mode == 3) { src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32); - if (!src) continue; + CHECK_SPRITE(1); for(j = 0; j < lg; ++j, ++sprX) { @@ -1488,7 +1502,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) { pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core*0x400 + (spriteInfo->PaletteIndex*32); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<sprBoundary)); - if (!src) continue; + CHECK_SPRITE(1); for(j = 0; j < lg; ++j, ++sprX) { @@ -1534,7 +1548,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*8) + ((y&0x7)*8)); else src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*4) + ((y&0x7)*4)); - if (!src) continue; + CHECK_SPRITE(1); render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir); continue; @@ -1543,11 +1557,12 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) if (spriteInfo->Mode == 3) /* sprite is in BMP format */ { // TODO: fix it for sprite1D - if (spriteInfo->Depth) + /*if (spriteInfo->Depth) src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1)); else - src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1)); - if (!src) continue; + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1));*/ + src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<4) + (y<sprBMPBoundary)); + CHECK_SPRITE(1); render_sprite_BMP (gpu, l, dst, (u16*)src, prioTab, prio, lg, sprX, x, xdir); continue; @@ -1556,7 +1571,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) if(spriteInfo->Depth) /* 256 colors */ { src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*8) + ((y&0x7)*8)); - if (!src) continue; + CHECK_SPRITE(1); if (dispCnt->ExOBJPalette_Enable) pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200)); @@ -1569,7 +1584,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) } /* 16 colors */ src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*4) + ((y&0x7)*4)); - if (!src) continue; + CHECK_SPRITE(1); pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400); pal += (spriteInfo->PaletteIndex<<4); @@ -1687,7 +1702,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) if(spriteInfo->Depth) { src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex) << 5)); - if (!src) continue; + CHECK_SPRITE(2); // If extended palettes are set, use them if (dispCnt->ExOBJPalette_Enable) @@ -1725,7 +1740,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) else if(spriteInfo->Mode == 3) { src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x03E0) * 8) + (spriteInfo->TileIndex&0x001F))*16); - if (!src) continue; + CHECK_SPRITE(2); for(j = 0; j < lg; ++j, ++sprX) { @@ -1757,7 +1772,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) else { src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<5)); - if (!src) continue; + CHECK_SPRITE(2); pal = ARM9Mem.ARM9_VMEM + 0x200 + (gpu->core*0x400 + (spriteInfo->PaletteIndex*32)); for(j = 0; j < lg; ++j, ++sprX) @@ -1802,7 +1817,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); else src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); - if (!src) continue; + CHECK_SPRITE(2); render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir); continue; @@ -1814,7 +1829,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1)); else // 256*256 src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1)); - if (!src) continue; + CHECK_SPRITE(2); render_sprite_BMP (gpu, l, dst, (u16*)src, prioTab, prio, lg, sprX, x, xdir); @@ -1824,7 +1839,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) if(spriteInfo->Depth) /* 256 colors */ { src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); - if (!src) continue; + CHECK_SPRITE(2); pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400); render_sprite_256 (gpu, l, dst, src, pal, @@ -1835,7 +1850,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab) /* 16 colors */ src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); - if (!src) continue; + CHECK_SPRITE(2); pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400); pal += (spriteInfo->PaletteIndex<<4); @@ -1999,7 +2014,7 @@ void GPU_set_DISPCAPCNT(u32 val) case 2: gpu->dispCapCnt.capx = 256; gpu->dispCapCnt.capy = 128; - break; + break; case 3: gpu->dispCapCnt.capx = 256; gpu->dispCapCnt.capy = 192; @@ -2019,8 +2034,8 @@ BOOL bright_init=FALSE; // comment this if want to use formulas instead // #define BRIGHT_TABLES - -#ifdef BRIGHT_TABLES + +#ifdef BRIGHT_TABLES static void calc_bright_colors() { int base = 31 ; int factor; @@ -2053,8 +2068,8 @@ static void calc_bright_colors() { #undef FORMULA_MORE #undef FORMULA_LESS -} -#endif +} +#endif static INLINE void GPU_ligne_layer(NDS_Screen * screen, u16 l) { GPU * gpu = screen->gpu; @@ -2125,13 +2140,13 @@ static INLINE void GPU_ligne_layer(NDS_Screen * screen, u16 l) T2WriteWord(dst, i16 << 1, T2ReadWord(spr, i16 << 1)); } } -} - +} + // TODO: capture emulated not fully static INLINE void GPU_ligne_DispCapture(u16 l) { - GPU * gpu = MainScreen.gpu; - struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits; + GPU * gpu = MainScreen.gpu; + struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits; if (l == 0) { @@ -2364,7 +2379,7 @@ void GPU_ligne(NDS_Screen * screen, u16 l) #if 1 for (int i=0; i<256;) { - u32 c = FIFOget(&MMU.fifos[0]); // TODO: this is incorrect + u32 c = FIFOget(&MMU.fifos[gpu->core]); // TODO: this is incorrect T2WriteWord(dst, i << 1, c&0xFFFF); i++; T2WriteWord(dst, i << 1, c>>16); i++; } @@ -2388,4 +2403,4 @@ bool gpu_loadstate(std::istream* is) { is->read((char*)GPU_screen,sizeof(GPU_screen)); return !is->fail(); -} \ No newline at end of file +} diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 5de081a43..b5a2a6918 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -234,6 +234,7 @@ TWaitState MMU_struct::MMU_WAIT32[2][16] = { u32 gxIRQ = 0; // VRAM mapping +static u8 last_engine_offset[4] = {0x00, 0x00, 0x00, 0x00}; u8 *LCDdst[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const static u32 LCDdata[10][2]= { {0x6800000, 8}, // Bank A @@ -415,23 +416,49 @@ u8 *MMU_RenderMapToLCD(u32 vram_addr) return NULL; } -static FORCEINLINE bool MMU_LCDmap(u32 &addr) +static FORCEINLINE u32 MMU_LCDmap(u8 proc, u32 addr) { - u32 vram_addr = addr; - if ((vram_addr >= 0x6000000) && (vram_addr <= 0x67FFFFF)) + if (proc == ARMCPU_ARM7) return addr; + + if ((addr >= 0x6000000) && (addr <= 0x67FFFFF)) { - vram_addr &= 0x0FFFFFF; - u8 engine = (vram_addr >> 21); - vram_addr &= 0x01FFFFF; - u8 engine_offset = (vram_addr >> 14); + u32 save_addr = addr; + + addr &= 0x0FFFFFF; + u8 engine = (addr >> 21); + addr &= 0x01FFFFF; + u8 engine_offset = (addr >> 14); u8 block = MMU.VRAM_MAP[engine][engine_offset]; - if (block == 7) return true; - //INFO("VRAM %i: engine=%i (offset=%i), map address = 0x%X, MMU address = 0x%X\n", block, engine, engine_offset, vram_addr, *addr); - vram_addr -= MMU.LCD_VRAM_ADDR[block]; - vram_addr += LCDdata[block][0]; - addr = vram_addr; + + if (block == 7) // corrections VRAM mapping + { + block = MMU.VRAM_MAP[engine][last_engine_offset[engine]]; + + //LOG("Engine offset = %i/%i in block %i (size %i, offs %i): \n", + //engine_offset, last_engine_offset[engine], block, + //LCDdata[block][1], engine_offset+LCDdata[block][1]); + + for (int i = 0; i < LCDdata[block][1]; i++) + { + if (MMU.VRAM_MAP[engine][engine_offset + i] != 7) + LOG("\nVRAM already mapping %i\n", i); + MMU.VRAM_MAP[engine][engine_offset + i] = (u8)block; + } + } + //LOG("VRAM %i: engine=%i (offset=%i), map address = 0x%X, MMU address = 0x%X\n", block, engine, engine_offset, vram_addr, *addr); + last_engine_offset[engine] = engine_offset; + + //u32 tmp02 = addr; + addr -= MMU.LCD_VRAM_ADDR[block]; + addr += LCDdata[block][0]; + + if ((addr < 0x6800000) || (addr> 0x68A3FFF)) // FIXME: this is hack + { + //LOG("Address is out range 0x%X in block %i\n", addr, block); + addr = save_addr; + } } - return false; + return (addr); } static inline void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt) @@ -651,7 +678,7 @@ u8 FASTCALL _MMU_read8(u32 adr) } #endif - if (MMU_LCDmap(adr)) return (0); + adr = MMU_LCDmap(proc, adr); mmu_log_debug(adr, proc, "read08"); @@ -685,7 +712,7 @@ u16 FASTCALL _MMU_read16(u32 adr) adr &= 0x0FFFFFFF; - if (MMU_LCDmap(adr)) return (0); + adr = MMU_LCDmap(proc, adr); if(adr&0x04000000) { @@ -758,7 +785,7 @@ u32 FASTCALL _MMU_read32(u32 adr) return (unsigned long)cflash_read(adr); adr &= 0x0FFFFFFF; - if (MMU_LCDmap(adr)) return (0); + adr = MMU_LCDmap(proc, adr); if((adr >> 24) == 4) { @@ -942,7 +969,7 @@ void FASTCALL _MMU_write8(u32 adr, u8 val) return ; } - if (MMU_LCDmap(adr)) return; + adr = MMU_LCDmap(proc, adr); switch(adr) { @@ -1163,7 +1190,7 @@ void FASTCALL _MMU_write16(u32 adr, u16 val) } } - if (MMU_LCDmap(adr)) return; + adr = MMU_LCDmap(proc, adr); if((adr >> 24) == 4) { @@ -1834,7 +1861,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val) } } - if (MMU_LCDmap(adr)) return; + adr = MMU_LCDmap(proc, adr); if ((adr & 0xFF800000) == 0x04800000) { /* access to non regular hw registers */