- fix VRAM bug (ex. NSMB fixed background missing on map)
This commit is contained in:
mtabachenko 2008-12-08 09:15:40 +00:00
parent 339727fab1
commit 445c953371
2 changed files with 92 additions and 50 deletions

View File

@ -52,6 +52,19 @@
#include "GPU_osd.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; ARM9_struct ARM9Mem;
extern BOOL click; extern BOOL click;
@ -303,7 +316,7 @@ void GPU_setVideoProp(GPU * gpu, u32 p)
break; break;
case 2: // Display framebuffer case 2: // Display framebuffer
// gpu->vramBlock = DISPCNT_VRAMBLOCK(p) ; // gpu->vramBlock = DISPCNT_VRAMBLOCK(p) ;
//gpu->vramBlock = cnt->VRAM_Block; gpu->vramBlock = cnt->VRAM_Block;
return; return;
case 3: // Display from Main RAM case 3: // Display from Main RAM
// nothing to be done here // 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; u8 * mapinfo;
TILEENTRY tileentry; 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 (!map) return;
if(tmp>31) 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 : case 2 :
// 256 colors // 256 colors
map = (u8 *)MMU_RenderMapToLCD(gpu->BG_bmp_ram[num]); map = (u8 *)MMU_RenderMapToLCD(gpu->BG_bmp_ram[num]);
if (!map) return;
pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400; 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); apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_256_map, map, NULL, pal);
return; return;
case 3 : case 3 :
// direct colors / BMP // direct colors / BMP
map = (u8 *)MMU_RenderMapToLCD(gpu->BG_bmp_ram[num]); 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); apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_BMP_map, map, NULL, NULL);
return; return;
} }
@ -1307,7 +1322,6 @@ INLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l,
return TRUE; return TRUE;
} }
/*****************************************************************************/ /*****************************************************************************/
// SPRITE RENDERING // SPRITE RENDERING
/*****************************************************************************/ /*****************************************************************************/
@ -1417,7 +1431,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
if(spriteInfo->Depth) if(spriteInfo->Depth)
{ {
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex << block)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex << block));
if (!src) continue; CHECK_SPRITE(1);
// If extended palettes are set, use them // If extended palettes are set, use them
if (dispCnt->ExOBJPalette_Enable) if (dispCnt->ExOBJPalette_Enable)
@ -1455,7 +1469,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
else if(spriteInfo->Mode == 3) else if(spriteInfo->Mode == 3)
{ {
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32);
if (!src) continue; CHECK_SPRITE(1);
for(j = 0; j < lg; ++j, ++sprX) 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); pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core*0x400 + (spriteInfo->PaletteIndex*32);
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<gpu->sprBoundary)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<gpu->sprBoundary));
if (!src) continue; CHECK_SPRITE(1);
for(j = 0; j < lg; ++j, ++sprX) 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<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8));
else else
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>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); render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir);
continue; continue;
@ -1543,11 +1557,12 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
if (spriteInfo->Mode == 3) /* sprite is in BMP format */ if (spriteInfo->Mode == 3) /* sprite is in BMP format */
{ {
// TODO: fix it for sprite1D // 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)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1));
else else
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&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1));*/
if (!src) continue; src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<4) + (y<<gpu->sprBMPBoundary));
CHECK_SPRITE(1);
render_sprite_BMP (gpu, l, dst, (u16*)src, prioTab, prio, lg, sprX, x, xdir); render_sprite_BMP (gpu, l, dst, (u16*)src, prioTab, prio, lg, sprX, x, xdir);
continue; continue;
@ -1556,7 +1571,7 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
if(spriteInfo->Depth) /* 256 colors */ if(spriteInfo->Depth) /* 256 colors */
{ {
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8));
if (!src) continue; CHECK_SPRITE(1);
if (dispCnt->ExOBJPalette_Enable) if (dispCnt->ExOBJPalette_Enable)
pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200)); 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 */ /* 16 colors */
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<block) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4));
if (!src) continue; CHECK_SPRITE(1);
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400); pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400);
pal += (spriteInfo->PaletteIndex<<4); pal += (spriteInfo->PaletteIndex<<4);
@ -1687,7 +1702,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
if(spriteInfo->Depth) if(spriteInfo->Depth)
{ {
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex) << 5)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex) << 5));
if (!src) continue; CHECK_SPRITE(2);
// If extended palettes are set, use them // If extended palettes are set, use them
if (dispCnt->ExOBJPalette_Enable) if (dispCnt->ExOBJPalette_Enable)
@ -1725,7 +1740,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
else if(spriteInfo->Mode == 3) else if(spriteInfo->Mode == 3)
{ {
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x03E0) * 8) + (spriteInfo->TileIndex&0x001F))*16); 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) for(j = 0; j < lg; ++j, ++sprX)
{ {
@ -1757,7 +1772,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
else else
{ {
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<5)); 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)); pal = ARM9Mem.ARM9_VMEM + 0x200 + (gpu->core*0x400 + (spriteInfo->PaletteIndex*32));
for(j = 0; j < lg; ++j, ++sprX) 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)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8));
else else
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); 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); render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir);
continue; 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)); src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1));
else // 256*256 else // 256*256
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&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); 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 */ if(spriteInfo->Depth) /* 256 colors */
{ {
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); 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); pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400);
render_sprite_256 (gpu, l, dst, src, pal, render_sprite_256 (gpu, l, dst, src, pal,
@ -1835,7 +1850,7 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
/* 16 colors */ /* 16 colors */
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); 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 = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400);
pal += (spriteInfo->PaletteIndex<<4); pal += (spriteInfo->PaletteIndex<<4);
@ -2364,7 +2379,7 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
#if 1 #if 1
for (int i=0; i<256;) 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&0xFFFF); i++;
T2WriteWord(dst, i << 1, c>>16); i++; T2WriteWord(dst, i << 1, c>>16); i++;
} }

View File

@ -234,6 +234,7 @@ TWaitState MMU_struct::MMU_WAIT32[2][16] = {
u32 gxIRQ = 0; u32 gxIRQ = 0;
// VRAM mapping // VRAM mapping
static u8 last_engine_offset[4] = {0x00, 0x00, 0x00, 0x00};
u8 *LCDdst[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; u8 *LCDdst[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
const static u32 LCDdata[10][2]= { const static u32 LCDdata[10][2]= {
{0x6800000, 8}, // Bank A {0x6800000, 8}, // Bank A
@ -415,23 +416,49 @@ u8 *MMU_RenderMapToLCD(u32 vram_addr)
return NULL; return NULL;
} }
static FORCEINLINE bool MMU_LCDmap(u32 &addr) static FORCEINLINE u32 MMU_LCDmap(u8 proc, u32 addr)
{ {
u32 vram_addr = addr; if (proc == ARMCPU_ARM7) return addr;
if ((vram_addr >= 0x6000000) && (vram_addr <= 0x67FFFFF))
if ((addr >= 0x6000000) && (addr <= 0x67FFFFF))
{ {
vram_addr &= 0x0FFFFFF; u32 save_addr = addr;
u8 engine = (vram_addr >> 21);
vram_addr &= 0x01FFFFF; addr &= 0x0FFFFFF;
u8 engine_offset = (vram_addr >> 14); u8 engine = (addr >> 21);
addr &= 0x01FFFFF;
u8 engine_offset = (addr >> 14);
u8 block = MMU.VRAM_MAP[engine][engine_offset]; 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); if (block == 7) // corrections VRAM mapping
vram_addr -= MMU.LCD_VRAM_ADDR[block]; {
vram_addr += LCDdata[block][0]; block = MMU.VRAM_MAP[engine][last_engine_offset[engine]];
addr = vram_addr;
//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) static inline void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt)
@ -651,7 +678,7 @@ u8 FASTCALL _MMU_read8(u32 adr)
} }
#endif #endif
if (MMU_LCDmap(adr)) return (0); adr = MMU_LCDmap(proc, adr);
mmu_log_debug(adr, proc, "read08"); mmu_log_debug(adr, proc, "read08");
@ -685,7 +712,7 @@ u16 FASTCALL _MMU_read16(u32 adr)
adr &= 0x0FFFFFFF; adr &= 0x0FFFFFFF;
if (MMU_LCDmap(adr)) return (0); adr = MMU_LCDmap(proc, adr);
if(adr&0x04000000) if(adr&0x04000000)
{ {
@ -758,7 +785,7 @@ u32 FASTCALL _MMU_read32(u32 adr)
return (unsigned long)cflash_read(adr); return (unsigned long)cflash_read(adr);
adr &= 0x0FFFFFFF; adr &= 0x0FFFFFFF;
if (MMU_LCDmap(adr)) return (0); adr = MMU_LCDmap(proc, adr);
if((adr >> 24) == 4) if((adr >> 24) == 4)
{ {
@ -942,7 +969,7 @@ void FASTCALL _MMU_write8(u32 adr, u8 val)
return ; return ;
} }
if (MMU_LCDmap(adr)) return; adr = MMU_LCDmap(proc, adr);
switch(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) 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) { if ((adr & 0xFF800000) == 0x04800000) {
/* access to non regular hw registers */ /* access to non regular hw registers */