parent
4a73940926
commit
7c9a646e52
|
@ -20,6 +20,7 @@
|
|||
- Change SPU to run two spus in parallel. SPU_core is the official one. SPU_user produces output.
|
||||
This lets us do inaccurate things with SPU_user which might sound better while being more accurate with SPU_core. [zeromus]
|
||||
- Add RTC implementations (not fully) [CrazyMax]
|
||||
- Rewrite VRAM mapping control and render [CrazyMax]
|
||||
Mac OS X port:
|
||||
- Fixed: Filenames and paths with unicode characters now work. [Jeff]
|
||||
- Fixed: Load state from file button works again. [Jeff]
|
||||
|
|
|
@ -20,7 +20,7 @@ typedef struct {
|
|||
|
||||
u8 * ExtPal[2][4];
|
||||
u8 * ObjExtPal[2][2];
|
||||
u8 * texPalSlot[4];
|
||||
u8 * texPalSlot[6];
|
||||
|
||||
u8 *textureSlotAddr[4];
|
||||
|
||||
|
|
|
@ -173,23 +173,17 @@ void GPU_Reset(GPU *g, u8 l)
|
|||
|
||||
g->setFinalColorBck = setFinalColorSpecialNone;
|
||||
g->setFinalColorSpr = setFinalColorSpecialNone;
|
||||
g->lcd = l;
|
||||
g->core = l;
|
||||
g->BGSize[0][0] = g->BGSize[1][0] = g->BGSize[2][0] = g->BGSize[3][0] = 256;
|
||||
g->BGSize[0][1] = g->BGSize[1][1] = g->BGSize[2][1] = g->BGSize[3][1] = 256;
|
||||
g->dispOBJ = g->dispBG[0] = g->dispBG[1] = g->dispBG[2] = g->dispBG[3] = TRUE;
|
||||
|
||||
MMU.vram_mode[0] = 4 ;
|
||||
MMU.vram_mode[1] = 5 ;
|
||||
MMU.vram_mode[2] = 6 ;
|
||||
MMU.vram_mode[3] = 7 ;
|
||||
|
||||
g->spriteRender = sprite1D;
|
||||
|
||||
if(g->core == GPU_SUB)
|
||||
{
|
||||
g->oam = (OAM *)(ARM9Mem.ARM9_OAM + ADDRESS_STEP_1KB);
|
||||
g->sprMem = ARM9Mem.ARM9_BOBJ;
|
||||
g->sprMem = ARM9MEM_BOBJ;
|
||||
// GPU core B
|
||||
g->dispx_st = (REG_DISPx*)(&ARM9Mem.ARM9_REG[REG_DISPB]);
|
||||
delete osdB;
|
||||
|
@ -198,7 +192,7 @@ void GPU_Reset(GPU *g, u8 l)
|
|||
else
|
||||
{
|
||||
g->oam = (OAM *)(ARM9Mem.ARM9_OAM);
|
||||
g->sprMem = ARM9Mem.ARM9_AOBJ;
|
||||
g->sprMem = ARM9MEM_AOBJ;
|
||||
// GPU core A
|
||||
g->dispx_st = (REG_DISPx*)(&ARM9Mem.ARM9_REG[0]);
|
||||
delete osdA;
|
||||
|
@ -285,7 +279,6 @@ void SetupFinalPixelBlitter (GPU *gpu)
|
|||
gpu->setFinalColorBck = pixelBlitters[windowUsed*4 + blendMode];
|
||||
}
|
||||
|
||||
|
||||
/* Sets up LCD control variables for Display Engines A and B for quick reading */
|
||||
void GPU_setVideoProp(GPU * gpu, u32 p)
|
||||
{
|
||||
|
@ -310,7 +303,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
|
||||
|
@ -368,14 +361,17 @@ void GPU_setBGProp(GPU * gpu, u16 num, u16 p)
|
|||
|
||||
GPU_resortBGs(gpu);
|
||||
|
||||
if(gpu->core == GPU_SUB) {
|
||||
gpu->BG_tile_ram[num] = ((u8 *)ARM9Mem.ARM9_BBG);
|
||||
gpu->BG_bmp_ram[num] = ((u8 *)ARM9Mem.ARM9_BBG);
|
||||
gpu->BG_map_ram[num] = ARM9Mem.ARM9_BBG;
|
||||
} else {
|
||||
gpu->BG_tile_ram[num] = ((u8 *)ARM9Mem.ARM9_ABG) + dispCnt->CharacBase_Block * ADDRESS_STEP_64kB ;
|
||||
gpu->BG_bmp_ram[num] = ((u8 *)ARM9Mem.ARM9_ABG);
|
||||
gpu->BG_map_ram[num] = ARM9Mem.ARM9_ABG + dispCnt->ScreenBase_Block * ADDRESS_STEP_64kB;
|
||||
if(gpu->core == GPU_SUB)
|
||||
{
|
||||
gpu->BG_tile_ram[num] = ARM9MEM_BBG;
|
||||
gpu->BG_bmp_ram[num] = ARM9MEM_BBG;
|
||||
gpu->BG_map_ram[num] = ARM9MEM_BBG;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpu->BG_tile_ram[num] = ARM9MEM_ABG + dispCnt->CharacBase_Block * ADDRESS_STEP_64kB ;
|
||||
gpu->BG_bmp_ram[num] = ARM9MEM_ABG;
|
||||
gpu->BG_map_ram[num] = ARM9MEM_ABG + dispCnt->ScreenBase_Block * ADDRESS_STEP_64kB;
|
||||
}
|
||||
|
||||
gpu->BG_tile_ram[num] += (cnt->CharacBase_Block * ADDRESS_STEP_16KB);
|
||||
|
@ -426,15 +422,21 @@ void GPU_addBack(GPU * gpu, u8 num)
|
|||
/* check whether (x,y) is within the rectangle (including wraparounds) */
|
||||
static INLINE BOOL withinRect (u8 x,u8 y, u16 startX, u16 startY, u16 endX, u16 endY)
|
||||
{
|
||||
BOOL wrapx, wrapy;
|
||||
wrapx = startX > endX;
|
||||
wrapy = startY > endY;
|
||||
// when the start > end,
|
||||
// all points between start & end are outside the window,
|
||||
// otherwise
|
||||
// they are inside
|
||||
return ((wrapx? ((startX <= x)||(x <= endX)):((startX <= x)&&(x <= endX))) &&
|
||||
(wrapy? ((startY <= y)||(y <= endY)):((startY <= y)&&(y <= endY))));
|
||||
|
||||
if (startX > endX) return 0;
|
||||
if (startY > endY) return 0;
|
||||
|
||||
if (x < startX) return 0;
|
||||
if (x > endX) return 0;
|
||||
|
||||
if (y < startY) return 0;
|
||||
if (y > endY) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -718,8 +720,7 @@ static BOOL setFinalColorSpecialDecreaseWnd (const GPU *gpu, u32 passing, u8 bgn
|
|||
/*****************************************************************************/
|
||||
// BACKGROUND RENDERING -TEXT-
|
||||
/*****************************************************************************/
|
||||
|
||||
/* render a text background to the combined pixelbuffer */
|
||||
// render a text background to the combined pixelbuffer
|
||||
INLINE void renderline_textBG(const GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG, u16 YBG, u16 LG)
|
||||
{
|
||||
struct _BGxCNT * bgCnt = &(gpu->dispx_st)->dispx_BGxCNT[num].bits;
|
||||
|
@ -727,9 +728,8 @@ INLINE void renderline_textBG(const GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG,
|
|||
u16 lg = gpu->BGSize[num][0];
|
||||
u16 ht = gpu->BGSize[num][1];
|
||||
u16 tmp = ((YBG&(ht-1))>>3);
|
||||
u8 *map = gpu->BG_map_ram[num] + (tmp&31) * 64;
|
||||
u8 *map = NULL;
|
||||
u8 *tile, *pal, *line;
|
||||
|
||||
u16 color;
|
||||
u16 xoff = XBG;
|
||||
u16 yoff;
|
||||
|
@ -743,25 +743,28 @@ 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);
|
||||
if (!map) return;
|
||||
|
||||
if(tmp>31)
|
||||
{
|
||||
map+= ADDRESS_STEP_512B << bgCnt->ScreenSize ;
|
||||
}
|
||||
|
||||
tile = (u8*) gpu->BG_tile_ram[num];
|
||||
if((!tile) || (!gpu->BG_map_ram[num])) return; /* no tiles or no map*/
|
||||
tile = (u8*) MMU_RenderMapToLCD(gpu->BG_tile_ram[num]);
|
||||
if(!tile) return; // no tiles
|
||||
|
||||
xoff = XBG;
|
||||
pal = ARM9Mem.ARM9_VMEM + gpu->core * ADDRESS_STEP_1KB ;
|
||||
|
||||
if(!bgCnt->Palette_256) /* color: 16 palette entries */
|
||||
if(!bgCnt->Palette_256) // color: 16 palette entries
|
||||
{
|
||||
if (bgCnt->Mosaic_Enable){
|
||||
/* test NDS: #2 of
|
||||
http://desmume.sourceforge.net/forums/index.php?action=vthread&forum=2&topic=50&page=0#msg192 */
|
||||
//test NDS: #2 of http://desmume.sourceforge.net/forums/index.php?action=vthread&forum=2&topic=50&page=0#msg192
|
||||
|
||||
u8 mw = (mosaic & 0xF) +1 ; /* horizontal granularity of the mosaic */
|
||||
u8 mh = ((mosaic>>4) & 0xF) +1 ; /* vertical granularity of the mosaic */
|
||||
YBG = (YBG / mh) * mh ; /* align y by vertical granularity */
|
||||
u8 mw = (mosaic & 0xF) +1 ; // horizontal granularity of the mosaic
|
||||
u8 mh = ((mosaic>>4) & 0xF) +1 ; // vertical granularity of the mosaic
|
||||
YBG = (YBG / mh) * mh ; // align y by vertical granularity
|
||||
yoff = ((YBG&7)<<2);
|
||||
|
||||
xfin = 8 - (xoff&7);
|
||||
|
@ -787,7 +790,7 @@ INLINE void renderline_textBG(const GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG,
|
|||
}
|
||||
// XXX
|
||||
for(; x < xfin; ) {
|
||||
if (!(pt % mw)) { /* only update the color we draw every n mw pixels */
|
||||
if (!(pt % mw)) { // only update the color we draw every n mw pixels
|
||||
if ((pt & 1)^pt_xor) {
|
||||
save = (*line) & 0xF ;
|
||||
} else {
|
||||
|
@ -803,7 +806,7 @@ INLINE void renderline_textBG(const GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG,
|
|||
xoff++;
|
||||
|
||||
pt++ ;
|
||||
if (!(pt % mw)) { /* next pixel next possible color update */
|
||||
if (!(pt % mw)) { // next pixel next possible color update
|
||||
if ((pt & 1)^pt_xor) {
|
||||
save = (*line) & 0xF ;
|
||||
} else {
|
||||
|
@ -821,7 +824,7 @@ INLINE void renderline_textBG(const GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG,
|
|||
line+=line_dir; pt++ ;
|
||||
}
|
||||
}
|
||||
} else { /* no mosaic mode */
|
||||
} else { // no mosaic mode
|
||||
yoff = ((YBG&7)<<2);
|
||||
xfin = 8 - (xoff&7);
|
||||
for(x = 0; x < LG; xfin = std::min<u16>(x+8, LG))
|
||||
|
@ -884,8 +887,8 @@ INLINE void renderline_textBG(const GPU * gpu, u8 num, u8 * dst, u32 Y, u16 XBG,
|
|||
return;
|
||||
}
|
||||
|
||||
palette_size=0; /* color: no extended palette */
|
||||
if(dispCnt->ExBGxPalette_Enable) /* color: extended palette */
|
||||
palette_size=0; // color: no extended palette
|
||||
if(dispCnt->ExBGxPalette_Enable) // color: extended palette
|
||||
{
|
||||
palette_size=0x100;
|
||||
pal = ARM9Mem.ExtPal[gpu->core][gpu->BGExtPalSlot[num]];
|
||||
|
@ -1025,9 +1028,10 @@ INLINE void apply_rot_fun(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16
|
|||
}
|
||||
|
||||
|
||||
INLINE void rotBG2(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16 PA, s16 PB, s16 PC, s16 PD, u16 LG) {
|
||||
u8 * map = gpu->BG_map_ram[num];
|
||||
u8 * tile = (u8 *)gpu->BG_tile_ram[num];
|
||||
INLINE void rotBG2(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16 PA, s16 PB, s16 PC, s16 PD, u16 LG)
|
||||
{
|
||||
u8 * map = (u8 *)MMU_RenderMapToLCD(gpu->BG_map_ram[num]);
|
||||
u8 * tile = (u8 *)MMU_RenderMapToLCD(gpu->BG_tile_ram[num]);
|
||||
u8 * pal = ARM9Mem.ARM9_VMEM + gpu->core * 0x400;
|
||||
// printf("rot mode\n");
|
||||
apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_tiled_8bit_entry, map, tile, pal);
|
||||
|
@ -1047,8 +1051,8 @@ INLINE void extRotBG2(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16 PA,
|
|||
{
|
||||
case 0 :
|
||||
case 1 :
|
||||
map = gpu->BG_map_ram[num];
|
||||
tile = gpu->BG_tile_ram[num];
|
||||
map = (u8 *)MMU_RenderMapToLCD(gpu->BG_map_ram[num]);
|
||||
tile = (u8 *)MMU_RenderMapToLCD(gpu->BG_tile_ram[num]);
|
||||
pal = ARM9Mem.ExtPal[gpu->core][gpu->BGExtPalSlot[num]];
|
||||
if (!pal) return;
|
||||
|
||||
|
@ -1057,13 +1061,13 @@ INLINE void extRotBG2(GPU * gpu, u8 num, u8 * dst, u16 H, s32 X, s32 Y, s16 PA,
|
|||
return;
|
||||
case 2 :
|
||||
// 256 colors
|
||||
map = gpu->BG_bmp_ram[num];
|
||||
map = (u8 *)MMU_RenderMapToLCD(gpu->BG_bmp_ram[num]);
|
||||
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 = gpu->BG_bmp_ram[num];
|
||||
map = (u8 *)MMU_RenderMapToLCD(gpu->BG_bmp_ram[num]);
|
||||
apply_rot_fun(gpu, num, dst, H,X,Y,PA,PB,PC,PD,LG, rot_BMP_map, map, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
@ -1138,10 +1142,6 @@ void extRotBG(GPU * gpu, u8 num, u8 * DST)
|
|||
extRotBG2(gpu, num, DST + i*gpu->BGSize[num][0]*2, i, 0, 0, 256, 0, 0, 256, gpu->BGSize[num][0]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
// SPRITE RENDERING -HELPER FUNCTIONS-
|
||||
/*****************************************************************************/
|
||||
|
@ -1169,7 +1169,6 @@ INLINE void render_sprite_BMP (GPU * gpu, u16 l, u8 * dst, u16 * src, u8 * prioT
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
INLINE void render_sprite_256 ( GPU * gpu, u16 l, u8 * dst, u8 * src, u16 * pal,
|
||||
u8 * prioTab, u8 prio, int lg, int sprX, int x, int xdir, u8 alpha)
|
||||
{
|
||||
|
@ -1258,7 +1257,6 @@ INLINE void render_sprite_Win (GPU * gpu, u16 l, u8 * src,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// return val means if the sprite is to be drawn or not
|
||||
INLINE BOOL compute_sprite_vars(_OAM_ * spriteInfo, u16 l,
|
||||
size *sprSize, s32 *sprX, s32 *sprY, s32 *x, s32 *y, s32 *lg, int *xdir) {
|
||||
|
@ -1418,7 +1416,8 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
// If we are using 1 palette of 256 colours
|
||||
if(spriteInfo->Depth)
|
||||
{
|
||||
src = gpu->sprMem + (spriteInfo->TileIndex << block);
|
||||
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex << block));
|
||||
if (!src) continue;
|
||||
|
||||
// If extended palettes are set, use them
|
||||
if (dispCnt->ExOBJPalette_Enable)
|
||||
|
@ -1455,7 +1454,8 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
// Rotozoomed direct color
|
||||
else if(spriteInfo->Mode == 3)
|
||||
{
|
||||
src = gpu->sprMem + (spriteInfo->TileIndex)*32;
|
||||
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex)*32);
|
||||
if (!src) continue;
|
||||
|
||||
for(j = 0; j < lg; ++j, ++sprX)
|
||||
{
|
||||
|
@ -1487,7 +1487,8 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
else
|
||||
{
|
||||
pal = ARM9Mem.ARM9_VMEM + 0x200 + gpu->core*0x400 + (spriteInfo->PaletteIndex*32);
|
||||
src = gpu->sprMem + (spriteInfo->TileIndex<<gpu->sprBoundary);
|
||||
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<gpu->sprBoundary));
|
||||
if (!src) continue;
|
||||
|
||||
for(j = 0; j < lg; ++j, ++sprX)
|
||||
{
|
||||
|
@ -1530,9 +1531,10 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
if (spriteInfo->Mode == 2)
|
||||
{
|
||||
if (spriteInfo->Depth)
|
||||
src = 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
|
||||
src = 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;
|
||||
|
||||
render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir);
|
||||
continue;
|
||||
|
@ -1540,18 +1542,21 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
|
||||
if (spriteInfo->Mode == 3) /* sprite is in BMP format */
|
||||
{
|
||||
/* sprMemory + sprBoundary + 16Bytes per line (8pixels a 2 bytes) */
|
||||
//src = (gpu->sprMem) + (spriteInfo->TileIndex<<4) + (y<<gpu->sprBMPBoundary);
|
||||
// FIXME:this no correct, but work ???
|
||||
src = (gpu->sprMem) + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1);
|
||||
render_sprite_BMP (gpu, l, dst, (u16*)src, prioTab, prio, lg, sprX, x, xdir);
|
||||
// TODO: fix it for sprite1D
|
||||
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;
|
||||
|
||||
render_sprite_BMP (gpu, l, dst, (u16*)src, prioTab, prio, lg, sprX, x, xdir);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(spriteInfo->Depth) /* 256 colors */
|
||||
{
|
||||
src = 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;
|
||||
|
||||
if (dispCnt->ExOBJPalette_Enable)
|
||||
pal = (u16*)(ARM9Mem.ObjExtPal[gpu->core][0]+(spriteInfo->PaletteIndex*0x200));
|
||||
|
@ -1563,7 +1568,8 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
continue;
|
||||
}
|
||||
/* 16 colors */
|
||||
src = 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;
|
||||
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400);
|
||||
|
||||
pal += (spriteInfo->PaletteIndex<<4);
|
||||
|
@ -1680,7 +1686,8 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
// If we are using 1 palette of 256 colours
|
||||
if(spriteInfo->Depth)
|
||||
{
|
||||
src = gpu->sprMem + ((spriteInfo->TileIndex) << 5);
|
||||
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex) << 5));
|
||||
if (!src) continue;
|
||||
|
||||
// If extended palettes are set, use them
|
||||
if (dispCnt->ExOBJPalette_Enable)
|
||||
|
@ -1717,7 +1724,8 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
// Rotozoomed direct color
|
||||
else if(spriteInfo->Mode == 3)
|
||||
{
|
||||
src = 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;
|
||||
|
||||
for(j = 0; j < lg; ++j, ++sprX)
|
||||
{
|
||||
|
@ -1748,7 +1756,8 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
// Rotozoomed 16/16 palette
|
||||
else
|
||||
{
|
||||
src = gpu->sprMem + (spriteInfo->TileIndex<<5);
|
||||
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + (spriteInfo->TileIndex<<5));
|
||||
if (!src) continue;
|
||||
pal = ARM9Mem.ARM9_VMEM + 0x200 + (gpu->core*0x400 + (spriteInfo->PaletteIndex*32));
|
||||
|
||||
for(j = 0; j < lg; ++j, ++sprX)
|
||||
|
@ -1790,20 +1799,22 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
|
||||
if (spriteInfo->Mode == 2) {
|
||||
if (spriteInfo->Depth)
|
||||
src = 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
|
||||
src = gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4);
|
||||
render_sprite_Win (gpu, l, src,
|
||||
spriteInfo->Depth, lg, sprX, x, xdir);
|
||||
src = (u8 *)MMU_RenderMapToLCD(gpu->sprMem + ((spriteInfo->TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4));
|
||||
if (!src) continue;
|
||||
|
||||
render_sprite_Win (gpu, l, src, spriteInfo->Depth, lg, sprX, x, xdir);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (spriteInfo->Mode == 3) /* sprite is in BMP format */
|
||||
{
|
||||
if (dispCnt->OBJ_BMP_2D_dim) // 256*256
|
||||
src = (gpu->sprMem) + (((spriteInfo->TileIndex&0x3E0) * 64 + (spriteInfo->TileIndex&0x1F) *8 + ( y << 8)) << 1);
|
||||
else // 128 * 512
|
||||
src = (gpu->sprMem) + (((spriteInfo->TileIndex&0x3F0) * 64 + (spriteInfo->TileIndex&0x0F) *8 + ( y << 8)) << 1);
|
||||
if (spriteInfo->Depth) // 128 * 512
|
||||
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;
|
||||
|
||||
render_sprite_BMP (gpu, l, dst, (u16*)src, prioTab, prio, lg, sprX, x, xdir);
|
||||
|
||||
|
@ -1812,7 +1823,8 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
|
||||
if(spriteInfo->Depth) /* 256 colors */
|
||||
{
|
||||
src = 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;
|
||||
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core *0x400);
|
||||
|
||||
render_sprite_256 (gpu, l, dst, src, pal,
|
||||
|
@ -1822,7 +1834,8 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
|
|||
}
|
||||
|
||||
/* 16 colors */
|
||||
src = 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;
|
||||
pal = (u16*)(ARM9Mem.ARM9_VMEM + 0x200 + gpu->core * 0x400);
|
||||
|
||||
pal += (spriteInfo->PaletteIndex<<4);
|
||||
|
@ -1943,8 +1956,60 @@ void GFXDummyOnScreenText(char *string, ...)
|
|||
// GPU_ligne
|
||||
/*****************************************************************************/
|
||||
|
||||
void GPU_set_DISPCAPCNT(GPU * gpu, u32 val) {
|
||||
void GPU_set_DISPCAPCNT(u32 val)
|
||||
{
|
||||
GPU * gpu = MainScreen.gpu;
|
||||
struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits;
|
||||
|
||||
gpu->dispCapCnt.val = val;
|
||||
gpu->dispCapCnt.EVA = val & 0x1F;
|
||||
gpu->dispCapCnt.EVB = (val >> 8) & 0x1F;
|
||||
gpu->dispCapCnt.writeBlock = (val >> 16) & 0x03;
|
||||
gpu->dispCapCnt.writeOffset = (val >> 18) & 0x03;
|
||||
gpu->dispCapCnt.readBlock = dispCnt->VRAM_Block;
|
||||
|
||||
if (dispCnt->DisplayMode == 2)
|
||||
gpu->dispCapCnt.readOffset = 0;
|
||||
else
|
||||
gpu->dispCapCnt.readOffset = (val >> 26) & 0x03;
|
||||
|
||||
gpu->dispCapCnt.srcA = (val >> 24) & 0x01;
|
||||
gpu->dispCapCnt.srcB = (val >> 25) & 0x01;
|
||||
gpu->dispCapCnt.capSrc = (val >> 29) & 0x03;
|
||||
|
||||
gpu->dispCapCnt.dst = (ARM9Mem.ARM9_LCD +
|
||||
(gpu->dispCapCnt.writeBlock * 0x20000) +
|
||||
(gpu->dispCapCnt.writeOffset * 0x8000)
|
||||
);
|
||||
gpu->dispCapCnt.src = (ARM9Mem.ARM9_LCD +
|
||||
(gpu->dispCapCnt.readBlock * 0x20000) +
|
||||
(gpu->dispCapCnt.readOffset * 0x8000)
|
||||
);
|
||||
|
||||
switch((val >> 20) & 0x03)
|
||||
{
|
||||
case 0:
|
||||
gpu->dispCapCnt.capx = 128;
|
||||
gpu->dispCapCnt.capy = 128;
|
||||
break;
|
||||
case 1:
|
||||
gpu->dispCapCnt.capx = 256;
|
||||
gpu->dispCapCnt.capy = 64;
|
||||
break;
|
||||
case 2:
|
||||
gpu->dispCapCnt.capx = 256;
|
||||
gpu->dispCapCnt.capy = 128;
|
||||
break;
|
||||
case 3:
|
||||
gpu->dispCapCnt.capx = 256;
|
||||
gpu->dispCapCnt.capy = 192;
|
||||
break;
|
||||
}
|
||||
|
||||
/*INFO("Capture 0x%X:\n EVA=%i, EVB=%i, wBlock=%i, wOffset=%i, capX=%i, capY=%i\n rBlock=%i, rOffset=%i, srcCap=%i, dst=0x%X, src=0x%X\n\n",
|
||||
val, gpu->dispCapCnt.EVA, gpu->dispCapCnt.EVB, gpu->dispCapCnt.writeBlock, gpu->dispCapCnt.writeOffset,
|
||||
gpu->dispCapCnt.capx, gpu->dispCapCnt.capy, gpu->dispCapCnt.readBlock, gpu->dispCapCnt.readOffset,
|
||||
gpu->dispCapCnt.capSrc, gpu->dispCapCnt.dst - ARM9Mem.ARM9_LCD, gpu->dispCapCnt.src - ARM9Mem.ARM9_LCD);*/
|
||||
}
|
||||
|
||||
// trade off for speed is 1MB
|
||||
|
@ -1990,78 +2055,24 @@ static void calc_bright_colors() {
|
|||
#undef FORMULA_LESS
|
||||
}
|
||||
#endif
|
||||
extern u16 NDS_3D_GetPixel(int line, int offset);
|
||||
|
||||
void GPU_ligne(NDS_Screen * screen, u16 l)
|
||||
static INLINE void GPU_ligne_layer(NDS_Screen * screen, u16 l)
|
||||
{
|
||||
GPU * gpu = screen->gpu;
|
||||
struct _DISPCAPCNT * capcnt;
|
||||
struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits;
|
||||
u8 * dst = GPU_screen + (screen->offset + l) * 512;
|
||||
u8 * dst = (u8 *)(GPU_screen) + (screen->offset + l) * 512;
|
||||
itemsForPriority_t * item;
|
||||
u8 spr[512];
|
||||
u8 sprPrio[256];
|
||||
u8 prio;
|
||||
int i;
|
||||
int vram_bank;
|
||||
u16 i16;
|
||||
u32 c;
|
||||
|
||||
/* initialize the scanline black */
|
||||
/* not doing this causes invalid colors when all active BGs are prevented to draw at some place */
|
||||
//ZERO TODO - shouldnt this be BG palette color 0?
|
||||
memset(dst,0,256*2) ;
|
||||
|
||||
// This could almost be changed to use function pointers
|
||||
switch (gpu->dispMode)
|
||||
{
|
||||
case 1: // Display BG and OBJ layers
|
||||
break;
|
||||
case 0: // Display Off(Display white)
|
||||
for (i=0; i<256; i++)
|
||||
T2WriteWord(dst, i << 1, 0x7FFF);
|
||||
return;
|
||||
case 2: // Display framebuffer
|
||||
{
|
||||
int ii = l * 256 * 2;
|
||||
u8 * vram;
|
||||
|
||||
/* we only draw one of the VRAM blocks */
|
||||
vram_bank = dispCnt->VRAM_Block ;
|
||||
|
||||
// This probably only needs to be calculated once per frame, but at least it's better than before >_<
|
||||
if (MMU.vram_mode[vram_bank] & 4)
|
||||
vram = ARM9Mem.ARM9_LCD + (MMU.vram_mode[vram_bank] & 3) * 0x20000;
|
||||
else
|
||||
vram = ARM9Mem.ARM9_ABG + MMU.vram_mode[vram_bank] * 0x20000;
|
||||
|
||||
for (i=0; i<(256 * 2); i+=2)
|
||||
{
|
||||
T2WriteWord(dst, i, T1ReadWord(vram, ii));
|
||||
ii+=2;
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 3:
|
||||
// Read from FIFO MAIN_MEMORY_DISP_FIFO, two pixels at once format is x555, bit15 unused
|
||||
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
|
||||
// (under DISP_MMEM_FIFO)
|
||||
#if 0
|
||||
for (i=0; i<256;) {
|
||||
c = FIFOValue(MMU.fifos + MAIN_MEMORY_DISP_FIFO);
|
||||
T2WriteWord(dst, i << 1, c&0xFFFF); i++;
|
||||
T2WriteWord(dst, i << 1, c>>16); i++;
|
||||
}
|
||||
#else
|
||||
INFO("FIFO MAIN_MEMORY_DISP_FIFO\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
c = T1ReadWord(ARM9Mem.ARM9_VMEM, gpu->core * 0x400);
|
||||
|
||||
// init background color & priorities
|
||||
for(i = 0; i< 256; ++i)
|
||||
for(int i = 0; i< 256; ++i)
|
||||
{
|
||||
T2WriteWord(dst, i << 1, c);
|
||||
T2WriteWord(spr, i << 1, c);
|
||||
|
@ -2070,14 +2081,14 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
|
|||
}
|
||||
|
||||
// init pixels priorities
|
||||
for (i=0;i<NB_PRIORITIES;i++) {
|
||||
for (int i=0; i<NB_PRIORITIES; i++) {
|
||||
gpu->itemsForPriority[i].nbPixelsX = 0;
|
||||
}
|
||||
|
||||
// for all the pixels in the line
|
||||
if (gpu->LayersEnable[4]) {
|
||||
gpu->spriteRender(gpu, l, spr, sprPrio);
|
||||
for(i= 0; i<256; i++) {
|
||||
for(int i = 0; i<256; i++) {
|
||||
// assign them to the good priority item
|
||||
prio = sprPrio[i];
|
||||
if (prio >=4) continue;
|
||||
|
@ -2095,7 +2106,7 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
|
|||
prio--;
|
||||
item = &(gpu->itemsForPriority[prio]);
|
||||
// render BGs
|
||||
for (i=0; i < item->nbBGs; i++)
|
||||
for (int i=0; i < item->nbBGs; i++)
|
||||
{
|
||||
i16 = item->BGs[i];
|
||||
|
||||
|
@ -2111,201 +2122,104 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
|
|||
}
|
||||
}
|
||||
// render sprite Pixels
|
||||
for (i=0; i < item->nbPixelsX; i++) {
|
||||
for (int i=0; i < item->nbPixelsX; i++) {
|
||||
i16=item->PixelsX[i];
|
||||
T2WriteWord(dst, i16 << 1, T2ReadWord(spr, i16 << 1));
|
||||
}
|
||||
}
|
||||
|
||||
/* DISPCAP */
|
||||
/* TODO: Capture source B and A+B */
|
||||
if(gpu->core == GPU_MAIN) /* capture only for main gpu */
|
||||
{
|
||||
capcnt = &gpu->dispCapCnt.bits;
|
||||
if (capcnt->Capture_Enable)
|
||||
{
|
||||
int capx, capy;
|
||||
u8 *capDst;
|
||||
|
||||
/* find the dimensions of the capture */
|
||||
switch(capcnt->Capture_Size) /* TODO: it could be done only once, when writting to dispcap register */
|
||||
{
|
||||
case 0:
|
||||
capx = 128;
|
||||
capy = 128;
|
||||
break;
|
||||
case 1:
|
||||
capx = 256;
|
||||
capy = 64;
|
||||
break;
|
||||
case 2:
|
||||
capx = 256;
|
||||
capy = 128;
|
||||
break;
|
||||
case 3:
|
||||
capx = 256;
|
||||
capy = 192;
|
||||
break;
|
||||
default:
|
||||
capx = 0;
|
||||
capy = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(l < capy) /* check if our line is in cature area */
|
||||
// TODO: capture emulated not fully
|
||||
static INLINE void GPU_ligne_DispCapture(u16 l)
|
||||
{
|
||||
/* calculate VRAM destination address */
|
||||
capDst = (ARM9Mem.ARM9_LCD
|
||||
+ (capcnt->VRAM_Write_Block * 0x20000)
|
||||
+ ((dispCnt->BG_Mode != 2) ? (capcnt->VRAM_Write_Offset * 0x8000) : 0)
|
||||
+ l * (capx<<1)); /* read offset ignored in VRAM display mode*/
|
||||
GPU * gpu = MainScreen.gpu;
|
||||
struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits;
|
||||
|
||||
// LOG("Capture line %d (%X) [dst: %X]...\n", l, gpu->dispCapCnt.val, capDst - ARM9Mem.ARM9_LCD);
|
||||
|
||||
switch(capcnt->Capture_Source)
|
||||
if (l == 0)
|
||||
{
|
||||
case 0: /* source A only */
|
||||
if(capcnt->Source_A == 1) /* capture 3D only */
|
||||
if (gpu->dispCapCnt.val & 0x80000000)
|
||||
{
|
||||
u16 cap3DLine[256]; /* temp buffer for 3D line reading */
|
||||
gpu3D->NDS_3D_GetLine (l, cap3DLine); /*FIXME: not sure it's good, since I hadn't seen how 3D works in desmume */
|
||||
for(i = 0; i < (capx<<1); i++) T1WriteWord(capDst, i, cap3DLine[i]); /* copy this line to buffer */
|
||||
}
|
||||
else /* capture all screen (BG + OBJ + 3D) */
|
||||
{
|
||||
for(i = 0; i < (capx<<1); i++) T1WriteWord(capDst, i, T2ReadWord(dst, i)); /* plain copy from screen to buffer */
|
||||
}
|
||||
|
||||
break;
|
||||
case 1: /* source B only */
|
||||
if(capcnt->Source_B == 1) /* capture from display FIFO */
|
||||
{
|
||||
/* TODO ... */
|
||||
}
|
||||
else /* capture from VRAM */
|
||||
{
|
||||
/* calculate vram source address */
|
||||
u8 *capSrc = (ARM9Mem.ARM9_LCD
|
||||
+ (dispCnt->VRAM_Block * 0x20000)
|
||||
+ ((dispCnt->BG_Mode != 2) ? (capcnt->VRAM_Write_Offset * 0x8000) : 0)
|
||||
+ l * capx * 2); /* write offset ignored in VRAM display mode*/
|
||||
|
||||
for(i = 0; i < (capx<<1); i++) T1WriteWord(capDst, i, T2ReadWord(capSrc, i)); /* plain copy from source to dest */
|
||||
}
|
||||
|
||||
break;
|
||||
case 2: /* source A + B (using blending) */
|
||||
case 3:
|
||||
|
||||
/* TODO... (the above code will need modifications in order to avoid redudance) */
|
||||
GPULOG("Unhandled capture source: %d\n", capcnt->Capture_Source); /* TODO */
|
||||
}
|
||||
|
||||
if(l + 1 == capy) /* if it was the last line, we're done !*/
|
||||
{
|
||||
capcnt->Capture_Enable = 0; /* done, now capture is disabled */
|
||||
gpu->dispCapCnt.enabled = TRUE;
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0x64, gpu->dispCapCnt.val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME !!!
|
||||
/* capture */
|
||||
#if 0
|
||||
// to be done with opengl
|
||||
capcnt = &gpu->dispCapCnt.bits;
|
||||
if (capcnt->Capture_Enable)
|
||||
if (gpu->dispCapCnt.enabled)
|
||||
{
|
||||
u16 * srcA, * srcB, *vram;
|
||||
u32 c; u8 vram_bank;
|
||||
COLOR color, colA, colB;
|
||||
u16 ilast= 128;
|
||||
if (capcnt->Capture_Size) ilast = 256;
|
||||
u8 *cap_dst = (u8 *)(gpu->dispCapCnt.dst) + (l * 512);
|
||||
|
||||
vram = (u16*)(ARM9Mem.ARM9_ABG
|
||||
+ MMU.vram_mode[capcnt->VRAM_Write_Block] * 0x20000
|
||||
+ capcnt->VRAM_Write_Offset * 0x08000);
|
||||
if (l < gpu->dispCapCnt.capy)
|
||||
{
|
||||
// TODO: Read/Write block wrap to 00000h when exceeding 1FFFFh (128k)
|
||||
|
||||
// I dunno yet how to do for 3D
|
||||
if (!capcnt->Source_A)
|
||||
srcA = (u16*)dst;
|
||||
|
||||
if (!capcnt->Source_B) {
|
||||
vram_bank = dispCnt->VRAM_Block ;
|
||||
if (MMU.vram_mode[vram_bank] & 4) {
|
||||
srcB = (u16*)(ARM9Mem.ARM9_LCD
|
||||
+ (MMU.vram_mode[vram_bank] & 3) * 0x20000
|
||||
+ capcnt->VRAM_Read_Offset * 0x08000);
|
||||
} else {
|
||||
srcB = (u16*)(ARM9Mem.ARM9_ABG
|
||||
+ MMU.vram_mode[vram_bank] * 0x20000
|
||||
+ capcnt->VRAM_Read_Offset * 0x08000);
|
||||
}
|
||||
}
|
||||
|
||||
printf("capture source %d\n",capcnt->Capture_Source);
|
||||
|
||||
switch(capcnt->Capture_Source) {
|
||||
case 0: // only source A
|
||||
if (!capcnt->Source_A) {
|
||||
srcA = (u16*)dst;
|
||||
for (i=0; i<ilast; i++) {
|
||||
vram[i] = srcA[i];
|
||||
}
|
||||
switch (gpu->dispCapCnt.capSrc)
|
||||
{
|
||||
case 0: // Capture source is SourceA
|
||||
{
|
||||
//INFO("Capture source is SourceA\n");
|
||||
switch (gpu->dispCapCnt.srcA)
|
||||
{
|
||||
case 0: // Capture screen (BG + OBJ + 3D)
|
||||
{
|
||||
//INFO("Capture screen (BG + OBJ + 3D)\n");
|
||||
u8 *src = (u8 *)(GPU_screen) + (MainScreen.offset + l) * 512;
|
||||
memcpy(cap_dst, src, (gpu->dispCapCnt.capx<<1));
|
||||
}
|
||||
break;
|
||||
case 1: // only source B
|
||||
if (capcnt->Source_B) {
|
||||
for (i=0; i<ilast;) {
|
||||
c = FIFOValue(MMU.fifos + MAIN_MEMORY_DISP_FIFO);
|
||||
vram[i] = c&0xFFFF; i++;
|
||||
vram[i] = c>>16; i++;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<ilast; i++) {
|
||||
vram[i] = srcB[i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // blend A + B
|
||||
if (capcnt->Source_B) {
|
||||
for (i=0; i<ilast;) {
|
||||
c = FIFOValue(MMU.fifos + MAIN_MEMORY_DISP_FIFO);
|
||||
colA.val = c&0xFFFF;
|
||||
colB.val = srcB[i];
|
||||
#define FORMULA(field) \
|
||||
color.bits.field = ((colA.bits.field * colA.bits.alpha * capcnt->BlendFactor_A) + (colB.bits.field * colB.bits.alpha * capcnt->BlendFactor_B)) / 16;
|
||||
FORMULA(red)
|
||||
FORMULA(green)
|
||||
FORMULA(blue)
|
||||
vram[i] = color.val;
|
||||
i++;
|
||||
colA.val = c >> 16;
|
||||
colB.val = srcB[i];
|
||||
FORMULA(red)
|
||||
FORMULA(green)
|
||||
FORMULA(blue)
|
||||
vram[i] = color.val;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<ilast; i++) {
|
||||
colA.val = srcA[i];
|
||||
colB.val = srcB[i];
|
||||
FORMULA(red)
|
||||
FORMULA(green)
|
||||
FORMULA(blue)
|
||||
vram[i] = color.val;
|
||||
}
|
||||
#undef FORMULA
|
||||
case 1: // Capture 3D
|
||||
{
|
||||
u16 cap3DLine[256];
|
||||
//INFO("Capture 3D\n");
|
||||
gpu3D->NDS_3D_GetLine (l, (u16*)cap3DLine);
|
||||
memcpy(cap_dst, cap3DLine, (gpu->dispCapCnt.capx<<1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: // Capture source is SourceB
|
||||
{
|
||||
//INFO("Capture source is SourceB\n");
|
||||
switch (gpu->dispCapCnt.srcB)
|
||||
{
|
||||
case 0: // Capture VRAM
|
||||
{
|
||||
//INFO("Capture VRAM\n");
|
||||
u8 *src = (u8 *)(gpu->dispCapCnt.src) + (MainScreen.offset + l) * 512;
|
||||
memcpy(cap_dst, src, (gpu->dispCapCnt.capx<<1));
|
||||
}
|
||||
break;
|
||||
case 1: // Capture Main Memory Display FIFO
|
||||
{
|
||||
//INFO("Capture Main Memory Display FIFO\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: // Capture source is SourceA+B blended
|
||||
{
|
||||
//INFO("Capture source is SourceA+B blended\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* end of capture */
|
||||
|
||||
if (l>=191)
|
||||
{
|
||||
gpu->dispCapCnt.enabled = FALSE;
|
||||
gpu->dispCapCnt.val &= 0x7FFFFFFF;
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0x64, gpu->dispCapCnt.val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void GPU_ligne_Brightness(NDS_Screen * screen, u16 l)
|
||||
{
|
||||
GPU * gpu = screen->gpu;
|
||||
u8 * dst = GPU_screen + (screen->offset + l) * 512;
|
||||
u16 i16;
|
||||
#ifndef HAVE_LIBGDKGLEXT_X11_1_0
|
||||
// damdoum :
|
||||
// brightness done with opengl
|
||||
|
@ -2416,6 +2330,57 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
|
|||
#endif
|
||||
}
|
||||
|
||||
void GPU_ligne(NDS_Screen * screen, u16 l)
|
||||
{
|
||||
GPU * gpu = screen->gpu;
|
||||
u8 * dst = GPU_screen + (screen->offset + l) * 512;
|
||||
|
||||
// initialize the scanline black
|
||||
// not doing this causes invalid colors when all active BGs are prevented to draw at some place
|
||||
// ZERO TODO - shouldnt this be BG palette color 0?
|
||||
//memset(dst,0,256*2) ;
|
||||
|
||||
// This could almost be changed to use function pointers
|
||||
switch (gpu->dispMode)
|
||||
{
|
||||
case 0: // Display Off(Display white)
|
||||
for (int i=0; i<256; i++)
|
||||
T2WriteWord(dst, i << 1, 0x7FFF);
|
||||
break;
|
||||
|
||||
case 1: // Display BG and OBJ layers
|
||||
GPU_ligne_layer(screen, l);
|
||||
break;
|
||||
|
||||
case 2: // Display framebuffer
|
||||
{
|
||||
struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits;
|
||||
u8 * vram = ARM9Mem.ARM9_LCD + (dispCnt->VRAM_Block * 0x20000) + (l*512);
|
||||
memcpy(dst, vram, 512);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
// Read from FIFO MAIN_MEMORY_DISP_FIFO, two pixels at once format is x555, bit15 unused
|
||||
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
|
||||
// (under DISP_MMEM_FIFO)
|
||||
#if 1
|
||||
for (int i=0; i<256;)
|
||||
{
|
||||
u32 c = FIFOget(&MMU.fifos[0]); // TODO: this is incorrect
|
||||
T2WriteWord(dst, i << 1, c&0xFFFF); i++;
|
||||
T2WriteWord(dst, i << 1, c>>16); i++;
|
||||
}
|
||||
#else
|
||||
INFO("FIFO MAIN_MEMORY_DISP_FIFO\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
if (gpu->core == GPU_MAIN)
|
||||
GPU_ligne_DispCapture(l);
|
||||
GPU_ligne_Brightness(screen, l);
|
||||
}
|
||||
|
||||
void gpu_savestate(std::ostream* os)
|
||||
{
|
||||
os->write((char*)GPU_screen,sizeof(GPU_screen));
|
||||
|
|
|
@ -341,32 +341,25 @@ typedef union
|
|||
source:
|
||||
http://nocash.emubase.de/gbatek.htm#dsvideocaptureandmainmemorydisplaymode
|
||||
*******************************************************************************/
|
||||
|
||||
struct _DISPCAPCNT
|
||||
typedef struct
|
||||
{
|
||||
/* 0*/ u8 BlendFactor_A:5; // 0..16 = Blending Factor for Source A
|
||||
/* 5*/ u8 :3; //
|
||||
/* 8*/ u8 BlendFactor_B:5; // 0..16 = Blending Factor for Source B
|
||||
/*13*/ u8 :3; //
|
||||
/*16*/ u8 VRAM_Write_Block:2; // 0..3 = VRAM A..D
|
||||
/*18*/ u8 VRAM_Write_Offset:2; // n x 0x08000
|
||||
/*20*/ u8 Capture_Size:2; // 0=128x128, 1=256x64, 2=256x128, 3=256x192 dots
|
||||
/*22*/ u8 :2; //
|
||||
/*24*/ u8 Source_A:1; // 0=Graphics Screen BG+3D+OBJ, 1=3D Screen
|
||||
/*25*/ u8 Source_B:1; // 0=VRAM, 1=Main Memory Display FIFO
|
||||
/*26*/ u8 VRAM_Read_Offset:2; // n x 0x08000
|
||||
/*28*/ u8 :1; //
|
||||
/*29*/ u8 Capture_Source:2; // 0=Source A, 1=Source B, 2/3=Sources A+B blended
|
||||
/*31*/ u8 Capture_Enable:1; // 0=Disable/Ready, 1=Enable/Busy
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct _DISPCAPCNT bits;
|
||||
u32 val;
|
||||
BOOL enabled;
|
||||
u8 EVA;
|
||||
u8 EVB;
|
||||
u8 writeBlock;
|
||||
u8 writeOffset;
|
||||
u16 capx;
|
||||
u16 capy;
|
||||
u8 srcA;
|
||||
u8 srcB;
|
||||
u8 readBlock;
|
||||
u8 readOffset;
|
||||
u8 capSrc;
|
||||
u8 *dst;
|
||||
u8 *src;
|
||||
} DISPCAPCNT;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
this structure holds everything and should be mapped to
|
||||
* core A : 0x04000000
|
||||
|
@ -590,7 +583,10 @@ typedef struct
|
|||
// doh ! yoda says : 256 pixels we can have...
|
||||
u16 nbPixelsX;
|
||||
} itemsForPriority_t;
|
||||
|
||||
#define ARM9MEM_ABG 0x06000000
|
||||
#define ARM9MEM_BBG 0x06200000
|
||||
#define ARM9MEM_AOBJ 0x06400000
|
||||
#define ARM9MEM_BOBJ 0x06600000
|
||||
|
||||
typedef struct _GPU GPU;
|
||||
|
||||
|
@ -608,14 +604,13 @@ struct _GPU
|
|||
#define BGBmpBB BG_bmp_ram
|
||||
#define BGChBB BG_tile_ram
|
||||
|
||||
u8 *(BG_bmp_ram[4]);
|
||||
u8 *(BG_tile_ram[4]);
|
||||
u8 *(BG_map_ram[4]);
|
||||
u32 BG_bmp_ram[4];
|
||||
u32 BG_tile_ram[4];
|
||||
u32 BG_map_ram[4];
|
||||
|
||||
u8 BGExtPalSlot[4];
|
||||
u32 BGSize[4][2];
|
||||
|
||||
u8 lcd;
|
||||
u8 core;
|
||||
|
||||
u8 dispMode;
|
||||
|
@ -625,7 +620,7 @@ struct _GPU
|
|||
BOOL dispOBJ;
|
||||
|
||||
OAM * oam;
|
||||
u8 * sprMem;
|
||||
u32 sprMem;
|
||||
u8 sprBoundary;
|
||||
u8 sprBMPBoundary;
|
||||
u8 sprBMPMode;
|
||||
|
@ -753,7 +748,7 @@ void GPU_addBack(GPU *, u8 num);
|
|||
|
||||
int GPU_ChangeGraphicsCore(int coreid);
|
||||
|
||||
void GPU_set_DISPCAPCNT(GPU * gpu, u32 val) ;
|
||||
void GPU_set_DISPCAPCNT(u32 val) ;
|
||||
void GPU_ligne(NDS_Screen * screen, u16 l) ;
|
||||
void GPU_setMasterBrightness (GPU *gpu, u16 val);
|
||||
|
||||
|
|
|
@ -227,12 +227,24 @@ u32 MMU_ARM7_WAIT32[16]={
|
|||
1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 5, 1, 1, 1, 1, 1,
|
||||
};
|
||||
|
||||
static u8 MMU_VRAMcntSaved[10];
|
||||
// VRAM mapping
|
||||
u8 *LCDdst[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
const static u32 LCDdata[10][2]= {
|
||||
{0x6800000, 8}, // Bank A
|
||||
{0x6820000, 8}, // Bank B
|
||||
{0x6840000, 8}, // Bank C
|
||||
{0x6860000, 8}, // Bank D
|
||||
{0x6880000, 4}, // Bank E
|
||||
{0x6890000, 1}, // Bank F
|
||||
{0x6894000, 1}, // Bank G
|
||||
{0, 0},
|
||||
{0x6898000, 2}, // Bank H
|
||||
{0x68A0000, 1}}; // Bank I
|
||||
|
||||
void MMU_Init(void) {
|
||||
int i;
|
||||
|
||||
INFO("MMU init\n");
|
||||
LOG("MMU init\n");
|
||||
|
||||
memset(&MMU, 0, sizeof(MMU_struct));
|
||||
|
||||
|
@ -257,8 +269,6 @@ void MMU_Init(void) {
|
|||
MMU.MMU_WAIT32[0] = MMU_ARM9_WAIT32;
|
||||
MMU.MMU_WAIT32[1] = MMU_ARM7_WAIT32;
|
||||
|
||||
memset(MMU_VRAMcntSaved, 0, sizeof(MMU_VRAMcntSaved[0])*10);
|
||||
|
||||
FIFOclear(&MMU.fifos[0]);
|
||||
FIFOclear(&MMU.fifos[1]);
|
||||
|
||||
|
@ -271,11 +281,10 @@ void MMU_Init(void) {
|
|||
mc_alloc(&MMU.bupmem, 1);
|
||||
MMU.bupmem.fp = NULL;
|
||||
rtcInit();
|
||||
|
||||
}
|
||||
|
||||
void MMU_DeInit(void) {
|
||||
INFO("MMU deinit\n");
|
||||
LOG("MMU deinit\n");
|
||||
if (MMU.fw.fp)
|
||||
fclose(MMU.fw.fp);
|
||||
mc_free(&MMU.fw);
|
||||
|
@ -298,10 +307,11 @@ u32 DMADst[2][4] = {{0, 0, 0, 0}, {0, 0, 0, 0}};
|
|||
|
||||
void MMU_clearMem()
|
||||
{
|
||||
memset(ARM9Mem.ARM9_ABG, 0, 0x080000);
|
||||
memset(ARM9Mem.ARM9_AOBJ, 0, 0x040000);
|
||||
memset(ARM9Mem.ARM9_BBG, 0, 0x020000);
|
||||
memset(ARM9Mem.ARM9_BOBJ, 0, 0x020000);
|
||||
memset(ARM9Mem.ARM9_ABG, 0, 0x080000); // TODO: remove this
|
||||
memset(ARM9Mem.ARM9_AOBJ, 0, 0x040000); // don't need now
|
||||
memset(ARM9Mem.ARM9_BBG, 0, 0x020000); //
|
||||
memset(ARM9Mem.ARM9_BOBJ, 0, 0x020000); // ----------------|
|
||||
|
||||
memset(ARM9Mem.ARM9_DTCM, 0, 0x4000);
|
||||
memset(ARM9Mem.ARM9_ITCM, 0, 0x8000);
|
||||
memset(ARM9Mem.ARM9_LCD, 0, 0x0A4000);
|
||||
|
@ -315,8 +325,6 @@ void MMU_clearMem()
|
|||
memset(MMU.ARM7_ERAM, 0, 0x010000);
|
||||
memset(MMU.ARM7_REG, 0, 0x010000);
|
||||
|
||||
memset(MMU_VRAMcntSaved, 0, sizeof(MMU_VRAMcntSaved[0])*10);
|
||||
|
||||
FIFOclear(&MMU.fifos[0]);
|
||||
FIFOclear(&MMU.fifos[1]);
|
||||
|
||||
|
@ -357,349 +365,237 @@ void MMU_clearMem()
|
|||
ARM9Mem.textureSlotAddr[2] = &ARM9Mem.ARM9_LCD[0x20000 * 2];
|
||||
ARM9Mem.textureSlotAddr[3] = &ARM9Mem.ARM9_LCD[0x20000 * 3];
|
||||
#endif
|
||||
|
||||
LCDdst[0] = ARM9Mem.ARM9_LCD; // Bank A
|
||||
LCDdst[1] = ARM9Mem.ARM9_LCD + 0x20000; // Bank B
|
||||
LCDdst[2] = ARM9Mem.ARM9_LCD + 0x40000; // Bank C
|
||||
LCDdst[3] = ARM9Mem.ARM9_LCD + 0x60000; // Bank D
|
||||
LCDdst[4] = ARM9Mem.ARM9_LCD + 0x80000; // Bank E
|
||||
LCDdst[5] = ARM9Mem.ARM9_LCD + 0x90000; // Bank F
|
||||
LCDdst[6] = ARM9Mem.ARM9_LCD + 0x94000; // Bank G
|
||||
LCDdst[7] = NULL;
|
||||
LCDdst[8] = ARM9Mem.ARM9_LCD + 0x98000; // Bank H
|
||||
LCDdst[9] = ARM9Mem.ARM9_LCD + 0xA0000; // Bank I
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
ARM9Mem.ExtPal[0][i] = ARM9Mem.ARM9_LCD;
|
||||
ARM9Mem.ExtPal[1][i] = ARM9Mem.ARM9_LCD;
|
||||
}
|
||||
ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD;
|
||||
ARM9Mem.ObjExtPal[0][2] = ARM9Mem.ARM9_LCD;
|
||||
ARM9Mem.ObjExtPal[1][1] = ARM9Mem.ARM9_LCD;
|
||||
ARM9Mem.ObjExtPal[1][2] = ARM9Mem.ARM9_LCD;
|
||||
|
||||
ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD;
|
||||
ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD;
|
||||
ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD;
|
||||
ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD;
|
||||
|
||||
for (int i =0; i < 9; i++)
|
||||
{
|
||||
MMU.LCD_VRAM_ADDR[i] = 0xFFFFFFFF;
|
||||
for (int t = 0; t < 32; t++)
|
||||
MMU.VRAM_MAP[i][t] = 7;
|
||||
}
|
||||
rtcInit();
|
||||
}
|
||||
|
||||
// temporary implementations for clearing VRAM (garbage on screen)
|
||||
// TODO: rewrite VRAM control
|
||||
static u8 MMU_checkVRAM(u8 block, u8 val)
|
||||
// VRAM mapping control
|
||||
u8 *MMU_RenderMapToLCD(u32 vram_addr)
|
||||
{
|
||||
u32 size = 0;
|
||||
u8 *destination = NULL;
|
||||
|
||||
if ((val & 0x80))
|
||||
if ((vram_addr >= 0x6000000) && (vram_addr <= 0x67FFFFF))
|
||||
{
|
||||
MMU_VRAMcntSaved[block] = val;
|
||||
return 1;
|
||||
vram_addr &= 0x0FFFFFF;
|
||||
u8 engine = (vram_addr >> 21);
|
||||
vram_addr &= 0x01FFFFF;
|
||||
u8 engine_offset = (vram_addr >> 14);
|
||||
u8 block = MMU.VRAM_MAP[engine][engine_offset];
|
||||
if (block == 7) return NULL;
|
||||
if (!MMU.LCDCenable[block]) return NULL;
|
||||
if (MMU.LCD_VRAM_ADDR[block] == 0xFFFFFFFF) return NULL;
|
||||
vram_addr -= MMU.LCD_VRAM_ADDR[block];
|
||||
u8 *tmp_addr = LCDdst[block] + vram_addr;
|
||||
return (tmp_addr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (MMU_VRAMcntSaved[block] == 0) return 2;
|
||||
|
||||
switch (MMU_VRAMcntSaved[block] & 0x07)
|
||||
static INLINE BOOL MMU_LCDmap(u32 *addr)
|
||||
{
|
||||
u32 vram_addr = (u32)*addr;
|
||||
|
||||
if ((vram_addr >= 0x6000000) && (vram_addr <= 0x67FFFFF))
|
||||
{
|
||||
vram_addr &= 0x0FFFFFF;
|
||||
u8 engine = (vram_addr >> 21);
|
||||
vram_addr &= 0x01FFFFF;
|
||||
u8 engine_offset = (vram_addr >> 14);
|
||||
u8 block = MMU.VRAM_MAP[engine][engine_offset];
|
||||
if (block == 7) return TRUE;
|
||||
if (!MMU.LCDCenable[block]) return TRUE;
|
||||
if (MMU.LCD_VRAM_ADDR[block] == 0xFFFFFFFF) 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;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static INLINE void MMU_VRAMmapControl(u8 block, u8 VRAMBankCnt)
|
||||
{
|
||||
if (!(VRAMBankCnt & 0x80)) return;
|
||||
if (!(VRAMBankCnt & 0x07)) return;
|
||||
|
||||
u32 vram_map_addr = 0xFFFFFFFF;
|
||||
BOOL isMapped = FALSE;
|
||||
u8 *LCD_addr = LCDdst[block];
|
||||
|
||||
switch (VRAMBankCnt & 0x07)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
switch(block)
|
||||
{
|
||||
case 0: // A
|
||||
case 1: // B
|
||||
case 2: // C
|
||||
case 3: // D
|
||||
size = 0x20000 ;
|
||||
destination = ARM9Mem.ARM9_ABG + ((MMU_VRAMcntSaved[block] >> 3) & 3) * 0x20000 ;
|
||||
case 3: // D Engine A, BG
|
||||
vram_map_addr = ((VRAMBankCnt >> 3) & 3) * 0x20000;
|
||||
break ;
|
||||
case 4: // E Engine A, BG
|
||||
vram_map_addr = 0x0000000;
|
||||
break;
|
||||
case 5: // F
|
||||
case 6: // G Engine A, BG
|
||||
vram_map_addr = (((VRAMBankCnt>>3)&1)*0x4000)+(((VRAMBankCnt>>4)&1)*0x10000);
|
||||
break;
|
||||
case 8: // H Engine B, BG
|
||||
vram_map_addr = 0x0200000;
|
||||
break ;
|
||||
case 9: // I Engine B, BG
|
||||
vram_map_addr = 0x0208000;
|
||||
break;
|
||||
}
|
||||
break ;
|
||||
|
||||
case 2:
|
||||
switch(block)
|
||||
{
|
||||
case 0: // A
|
||||
case 1: // B Engine A, OBJ
|
||||
vram_map_addr = 0x0400000 + (((VRAMBankCnt>>3)&1)*0x20000);
|
||||
break;
|
||||
case 4: // E Engine A, OBJ
|
||||
vram_map_addr = 0x0400000;
|
||||
break;
|
||||
case 5: // F
|
||||
case 6: // G Engine A, OBJ
|
||||
vram_map_addr = 0x0400000 + (((VRAMBankCnt>>3)&1)*0x4000)+(((VRAMBankCnt>>4)&1)*0x10000);
|
||||
break;
|
||||
case 8: // H Engine B, BG
|
||||
ARM9Mem.ExtPal[1][0] = LCD_addr;
|
||||
ARM9Mem.ExtPal[1][1] = LCD_addr+0x2000;
|
||||
ARM9Mem.ExtPal[1][2] = LCD_addr+0x4000;
|
||||
ARM9Mem.ExtPal[1][3] = LCD_addr+0x6000;
|
||||
break;
|
||||
case 9: // I Engine B, OBJ
|
||||
vram_map_addr = 0x0600000;
|
||||
break;
|
||||
}
|
||||
break ;
|
||||
|
||||
case 3:
|
||||
switch (block)
|
||||
{
|
||||
case 0: // A
|
||||
case 1: // B
|
||||
case 2: // C
|
||||
case 3: // D
|
||||
// Textures
|
||||
{
|
||||
int slot_index = (VRAMBankCnt >> 3) & 0x3;
|
||||
ARM9Mem.textureSlotAddr[slot_index] = LCD_addr;
|
||||
gpu3D->NDS_3D_VramReconfigureSignal();
|
||||
}
|
||||
return;
|
||||
case 4: // E
|
||||
size = 0x10000;
|
||||
destination = ARM9Mem.ARM9_ABG ;
|
||||
ARM9Mem.texPalSlot[0] = LCD_addr;
|
||||
ARM9Mem.texPalSlot[1] = LCD_addr+0x2000;
|
||||
ARM9Mem.texPalSlot[2] = LCD_addr+0x4000;
|
||||
ARM9Mem.texPalSlot[3] = LCD_addr+0x6000;
|
||||
break;
|
||||
case 5: // F
|
||||
case 6: // G
|
||||
size = 0x4000;
|
||||
destination = ARM9Mem.ARM9_ABG +
|
||||
(((MMU_VRAMcntSaved[block] >> 3) & 0x01) * 0x4000) +
|
||||
(((MMU_VRAMcntSaved[block] >> 4) & 0x1) * 0x10000) ;
|
||||
break;
|
||||
case 8: // H
|
||||
size = 0x8000;
|
||||
destination = ARM9Mem.ARM9_BBG ;
|
||||
break;
|
||||
case 9: // I
|
||||
size = 0x4000;
|
||||
destination = ARM9Mem.ARM9_BBG + 0x8000;
|
||||
break ;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch(block)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
// banks A,B are in use for OBJ at AOBJ + ofs * 0x20000
|
||||
size = 0x20000;
|
||||
destination = ARM9Mem.ARM9_AOBJ+(((MMU_VRAMcntSaved[block]>>3)&1)*0x20000);
|
||||
u8 tmp_slot = ((VRAMBankCnt >> 3) & 0x01) + (((VRAMBankCnt >> 4) & 0x01)*4);
|
||||
ARM9Mem.texPalSlot[tmp_slot] = LCD_addr;
|
||||
}
|
||||
break;
|
||||
case 4: // E
|
||||
size = 0x10000;
|
||||
destination = ARM9Mem.ARM9_AOBJ;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
size = 0x4000;
|
||||
destination = ARM9Mem.ARM9_AOBJ+
|
||||
(((MMU_VRAMcntSaved[block]>>3)&1)*0x4000)+
|
||||
(((MMU_VRAMcntSaved[block]>>4)&1)*0x10000);
|
||||
case 9: // I Engine B, OBJ
|
||||
ARM9Mem.ObjExtPal[1][0] = LCD_addr;
|
||||
ARM9Mem.ObjExtPal[1][1] = LCD_addr+0x2000;
|
||||
break;
|
||||
}
|
||||
break ;
|
||||
|
||||
case 4:
|
||||
switch(block)
|
||||
{
|
||||
case 2: // C
|
||||
size = 0x20000;
|
||||
destination = ARM9Mem.ARM9_BBG ;
|
||||
case 2: // C Engine B, BG
|
||||
vram_map_addr = 0x0200000;
|
||||
break ;
|
||||
case 3: // D
|
||||
size = 0x20000;
|
||||
case 3: // D Engine B, OBJ
|
||||
vram_map_addr = 0x0600000;
|
||||
break ;
|
||||
case 4: // E Engine A, BG
|
||||
ARM9Mem.ExtPal[0][0] = LCD_addr;
|
||||
ARM9Mem.ExtPal[0][1] = LCD_addr+0x2000;
|
||||
ARM9Mem.ExtPal[0][2] = LCD_addr+0x4000;
|
||||
ARM9Mem.ExtPal[0][3] = LCD_addr+0x6000;
|
||||
break;
|
||||
case 5: // F
|
||||
case 6: // G Engine A, BG
|
||||
u8 tmp_slot = (VRAMBankCnt >> 2) & 0x02;
|
||||
ARM9Mem.ExtPal[0][tmp_slot] = LCD_addr;
|
||||
ARM9Mem.ExtPal[0][tmp_slot+1] = LCD_addr+0x2000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!destination) return 3;
|
||||
memset(destination, 0, size) ;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* the VRAM blocks keep their content even when not blended in */
|
||||
/* to ensure that we write the content back to the LCD ram */
|
||||
/* FIXME: VRAM Bank E,F,G,H,I missing */
|
||||
static void MMU_VRAMWriteBackToLCD(u8 block)
|
||||
case 5:
|
||||
if ((block == 5) || (block == 6)) // F, G Engine A, OBJ
|
||||
{
|
||||
u8 *destination;
|
||||
u8 *source;
|
||||
u32 size ;
|
||||
u8 VRAMBankCnt;
|
||||
ARM9Mem.ObjExtPal[0][0] = LCD_addr;
|
||||
ARM9Mem.ObjExtPal[0][1] = LCD_addr + 0x2000;
|
||||
|
||||
destination = 0 ;
|
||||
source = 0;
|
||||
VRAMBankCnt = MMU_read8(ARMCPU_ARM9,REG_VRAMCNTA+block);
|
||||
if(!(VRAMBankCnt&0x80))return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch (block)
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
case 0: // Bank A
|
||||
destination = ARM9Mem.ARM9_LCD ;
|
||||
size = 0x20000 ;
|
||||
break ;
|
||||
case 1: // Bank B
|
||||
destination = ARM9Mem.ARM9_LCD + 0x20000 ;
|
||||
size = 0x20000 ;
|
||||
break ;
|
||||
case 2: // Bank C
|
||||
destination = ARM9Mem.ARM9_LCD + 0x40000 ;
|
||||
size = 0x20000 ;
|
||||
break ;
|
||||
case 3: // Bank D
|
||||
destination = ARM9Mem.ARM9_LCD + 0x60000 ;
|
||||
size = 0x20000 ;
|
||||
break ;
|
||||
case 4: // Bank E
|
||||
destination = ARM9Mem.ARM9_LCD + 0x80000 ;
|
||||
size = 0x10000 ;
|
||||
break ;
|
||||
case 5: // Bank F
|
||||
destination = ARM9Mem.ARM9_LCD + 0x90000 ;
|
||||
size = 0x4000 ;
|
||||
break ;
|
||||
case 6: // Bank G
|
||||
destination = ARM9Mem.ARM9_LCD + 0x94000 ;
|
||||
size = 0x4000 ;
|
||||
break ;
|
||||
case 8: // Bank H
|
||||
destination = ARM9Mem.ARM9_LCD + 0x98000 ;
|
||||
size = 0x8000 ;
|
||||
break ;
|
||||
case 9: // Bank I
|
||||
destination = ARM9Mem.ARM9_LCD + 0xA0000 ;
|
||||
size = 0x4000 ;
|
||||
break ;
|
||||
default:
|
||||
for (int t = 0; t < 32; t++)
|
||||
if (MMU.VRAM_MAP[i][t] == block)
|
||||
MMU.VRAM_MAP[i][t] = 7;
|
||||
}
|
||||
|
||||
if (vram_map_addr != 0xFFFFFFFF)
|
||||
{
|
||||
u8 engine = (vram_map_addr >> 21);
|
||||
vram_map_addr &= 0x001FFFFF;
|
||||
u8 engine_offset = (vram_map_addr >> 14);
|
||||
MMU.LCD_VRAM_ADDR[block] = vram_map_addr;
|
||||
MMU.LCDCenable[block] = TRUE;
|
||||
|
||||
for (int i = 0; i < LCDdata[block][1]; i++)
|
||||
MMU.VRAM_MAP[engine][engine_offset + i] = (u8)block;
|
||||
|
||||
//INFO("VRAM %i mapping: engine=%i (offset=%i), address = 0x%X, MST=%i\n", block, engine, engine_offset, MMU.LCD_VRAM_ADDR[block], VRAMBankCnt & 0x07);
|
||||
return;
|
||||
}
|
||||
switch (VRAMBankCnt & 7) {
|
||||
case 0:
|
||||
/* vram is allready stored at LCD, we dont need to write it back */
|
||||
break ;
|
||||
case 1:
|
||||
switch(block){
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
/* banks are in use for BG at ABG + ofs * 0x20000 */
|
||||
source = ARM9Mem.ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ;
|
||||
break ;
|
||||
case 4:
|
||||
/* bank E is in use at ABG */
|
||||
source = ARM9Mem.ARM9_ABG ;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
/* banks are in use for BG at ABG + (0x4000*OFS.0)+(0x10000*OFS.1)*/
|
||||
source = ARM9Mem.ARM9_ABG + (((VRAMBankCnt >> 3) & 1) * 0x4000) + (((VRAMBankCnt >> 2) & 1) * 0x10000) ;
|
||||
break;
|
||||
case 8:
|
||||
/* bank H is in use at BBG */
|
||||
source = ARM9Mem.ARM9_BBG ;
|
||||
break ;
|
||||
case 9:
|
||||
/* bank I is in use at BBG */
|
||||
source = ARM9Mem.ARM9_BBG + 0x8000 ;
|
||||
break;
|
||||
default: return ;
|
||||
}
|
||||
break ;
|
||||
case 2:
|
||||
switch(block)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
// banks A,B are in use for OBJ at AOBJ + ofs * 0x20000
|
||||
source=ARM9Mem.ARM9_AOBJ+(((VRAMBankCnt>>3)&1)*0x20000);
|
||||
break;
|
||||
case 4:
|
||||
source=ARM9Mem.ARM9_AOBJ;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
source=ARM9Mem.ARM9_AOBJ+(((VRAMBankCnt>>3)&1)*0x4000)+(((VRAMBankCnt>>4)&1)*0x10000);
|
||||
break;
|
||||
case 9:
|
||||
// source=ARM9Mem.ARM9_BOBJ;
|
||||
break;
|
||||
}
|
||||
break ;
|
||||
case 3: break;
|
||||
case 4:
|
||||
switch(block)
|
||||
{
|
||||
case 2:
|
||||
/* bank C is in use at BBG */
|
||||
source = ARM9Mem.ARM9_BBG ;
|
||||
break ;
|
||||
case 3:
|
||||
/* bank D is in use at BOBJ */
|
||||
source = ARM9Mem.ARM9_BOBJ ;
|
||||
break ;
|
||||
default: return ;
|
||||
}
|
||||
break ;
|
||||
default:
|
||||
return ;
|
||||
}
|
||||
if (!destination) return ;
|
||||
if (!source) return ;
|
||||
memcpy(destination,source,size) ;
|
||||
}
|
||||
|
||||
static void MMU_VRAMReloadFromLCD(u8 block,u8 VRAMBankCnt)
|
||||
{
|
||||
u8 *destination;
|
||||
u8 *source;
|
||||
u32 size;
|
||||
|
||||
if(!(VRAMBankCnt&0x80))return;
|
||||
destination = 0;
|
||||
source = 0;
|
||||
size = 0;
|
||||
switch (block)
|
||||
{
|
||||
case 0: // Bank A
|
||||
source = ARM9Mem.ARM9_LCD ;
|
||||
size = 0x20000 ;
|
||||
break ;
|
||||
case 1: // Bank B
|
||||
source = ARM9Mem.ARM9_LCD + 0x20000 ;
|
||||
size = 0x20000 ;
|
||||
break ;
|
||||
case 2: // Bank C
|
||||
source = ARM9Mem.ARM9_LCD + 0x40000 ;
|
||||
size = 0x20000 ;
|
||||
break ;
|
||||
case 3: // Bank D
|
||||
source = ARM9Mem.ARM9_LCD + 0x60000 ;
|
||||
size = 0x20000 ;
|
||||
break ;
|
||||
case 4: // Bank E
|
||||
source = ARM9Mem.ARM9_LCD + 0x80000 ;
|
||||
size = 0x10000 ;
|
||||
break ;
|
||||
case 5: // Bank F
|
||||
source = ARM9Mem.ARM9_LCD + 0x90000 ;
|
||||
size = 0x4000 ;
|
||||
break ;
|
||||
case 6: // Bank G
|
||||
source = ARM9Mem.ARM9_LCD + 0x94000 ;
|
||||
size = 0x4000 ;
|
||||
break ;
|
||||
case 8: // Bank H
|
||||
source = ARM9Mem.ARM9_LCD + 0x98000 ;
|
||||
size = 0x8000 ;
|
||||
break ;
|
||||
case 9: // Bank I
|
||||
source = ARM9Mem.ARM9_LCD + 0xA0000 ;
|
||||
size = 0x4000 ;
|
||||
break ;
|
||||
default:
|
||||
return ;
|
||||
}
|
||||
switch (VRAMBankCnt & 7) {
|
||||
case 0: // vram is allready stored at LCD, we dont need to write it back
|
||||
break ;
|
||||
case 1:
|
||||
switch(block){
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: // banks are in use for BG at ABG + ofs * 0x20000
|
||||
destination = ARM9Mem.ARM9_ABG + ((VRAMBankCnt >> 3) & 3) * 0x20000 ;
|
||||
break ;
|
||||
case 4: // bank E is in use at ABG
|
||||
destination = ARM9Mem.ARM9_ABG ;
|
||||
break;
|
||||
case 5:
|
||||
case 6: // banks are in use for BG at ABG + (0x4000*OFS.0)+(0x10000*OFS.1)
|
||||
destination = ARM9Mem.ARM9_ABG + (((VRAMBankCnt >> 3) & 1) * 0x4000) + (((VRAMBankCnt >> 4) & 1) * 0x10000) ;
|
||||
break;
|
||||
case 7:
|
||||
case 8: // bank H is in use at BBG
|
||||
//destination = ARM9Mem.ARM9_BBG ;
|
||||
break ;
|
||||
case 9: // bank I is in use at BBG
|
||||
//destination = ARM9Mem.ARM9_BBG + 0x8000 ;
|
||||
break;
|
||||
//default: return ;
|
||||
}
|
||||
break ;
|
||||
case 2:
|
||||
switch(block)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
destination=ARM9Mem.ARM9_AOBJ+(((VRAMBankCnt>>3)&3)*0x20000);
|
||||
break;
|
||||
case 4:
|
||||
destination=ARM9Mem.ARM9_AOBJ;
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
destination=ARM9Mem.ARM9_AOBJ+(((VRAMBankCnt>>3)&1)*0x4000)+(((VRAMBankCnt>>4)&1)*0x10000);
|
||||
break;
|
||||
case 9:
|
||||
// destination=ARM9Mem.ARM9_BOBJ;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
//case 3: break;
|
||||
case 4:
|
||||
switch(block){
|
||||
case 2: // bank C is in use at BBG
|
||||
destination = ARM9Mem.ARM9_BBG ;
|
||||
break ;
|
||||
case 3:
|
||||
// bank D is in use at BOBJ
|
||||
destination = ARM9Mem.ARM9_BOBJ ;
|
||||
break ;
|
||||
default: return ;
|
||||
}
|
||||
break ;
|
||||
default:
|
||||
return ;
|
||||
}
|
||||
if (!destination) return ;
|
||||
if (!source) return ;
|
||||
memcpy(destination,source,size) ;
|
||||
MMU.LCDCenable[block] = FALSE;
|
||||
}
|
||||
|
||||
void MMU_setRom(u8 * rom, u32 mask)
|
||||
|
@ -766,6 +662,8 @@ u8 FASTCALL _MMU_read8(u32 adr)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (MMU_LCDmap(&adr)) return (0);
|
||||
|
||||
mmu_log_debug(adr, proc, "read08");
|
||||
|
||||
return MMU.MMU_MEM[proc][(adr>>20)&0xFF][adr&MMU.MMU_MASK[proc][(adr>>20)&0xFF]];
|
||||
|
@ -798,6 +696,8 @@ u16 FASTCALL _MMU_read16(u32 adr)
|
|||
|
||||
adr &= 0x0FFFFFFF;
|
||||
|
||||
if (MMU_LCDmap(&adr)) return (0);
|
||||
|
||||
if(adr&0x04000000)
|
||||
{
|
||||
/* Address is an IO register */
|
||||
|
@ -869,6 +769,8 @@ u32 FASTCALL _MMU_read32(u32 adr)
|
|||
return (unsigned long)cflash_read(adr);
|
||||
adr &= 0x0FFFFFFF;
|
||||
|
||||
if (MMU_LCDmap(&adr)) return (0);
|
||||
|
||||
if((adr >> 24) == 4)
|
||||
{
|
||||
/* Address is an IO register */
|
||||
|
@ -1049,6 +951,8 @@ void FASTCALL _MMU_write8(u32 adr, u8 val)
|
|||
return ;
|
||||
}
|
||||
|
||||
if (MMU_LCDmap(&adr)) return;
|
||||
|
||||
switch(adr)
|
||||
{
|
||||
case REG_DISPA_WIN0H:
|
||||
|
@ -1165,214 +1069,29 @@ void FASTCALL _MMU_write8(u32 adr, u8 val)
|
|||
if(proc == ARMCPU_ARM9) GPU_setBLDY_EVY(SubScreen.gpu,val) ;
|
||||
break;
|
||||
|
||||
/* TODO: EEEK ! Controls for VRAMs A, B, C, D are missing ! */
|
||||
/* TODO: Not all mappings of VRAMs are handled... (especially BG and OBJ modes) */
|
||||
case REG_VRAMCNTA:
|
||||
case REG_VRAMCNTB:
|
||||
case REG_VRAMCNTC:
|
||||
case REG_VRAMCNTD:
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
//
|
||||
// FIXME: simply texture slot handling
|
||||
// This is a first stab and is not correct. It does
|
||||
// not handle a VRAM texture slot becoming
|
||||
// unconfigured.
|
||||
// Revisit all of VRAM control handling for future
|
||||
// release?
|
||||
//
|
||||
if ( val & 0x80) {
|
||||
if ( (val & 0x7) == 3) {
|
||||
int slot_index = (val >> 3) & 0x3;
|
||||
|
||||
ARM9Mem.textureSlotAddr[slot_index] =
|
||||
&ARM9Mem.ARM9_LCD[0x20000 * (adr - REG_VRAMCNTA)];
|
||||
|
||||
gpu3D->NDS_3D_VramReconfigureSignal();
|
||||
}
|
||||
}
|
||||
if (MMU_checkVRAM(adr-REG_VRAMCNTA, val) == 1) break;
|
||||
|
||||
MMU_VRAMWriteBackToLCD(adr-REG_VRAMCNTA) ;
|
||||
switch(val & 0x1F)
|
||||
{
|
||||
case 1 :
|
||||
MMU.vram_mode[adr-REG_VRAMCNTA] = 0; // BG-VRAM
|
||||
//memset(ARM9Mem.ARM9_ABG,0,0x20000);
|
||||
//MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*0); // BG-VRAM
|
||||
break;
|
||||
case 1 | (1 << 3) :
|
||||
MMU.vram_mode[adr-REG_VRAMCNTA] = 1; // BG-VRAM
|
||||
//memset(ARM9Mem.ARM9_ABG+0x20000,0,0x20000);
|
||||
//MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*1); // BG-VRAM
|
||||
break;
|
||||
case 1 | (2 << 3) :
|
||||
MMU.vram_mode[adr-REG_VRAMCNTA] = 2; // BG-VRAM
|
||||
//memset(ARM9Mem.ARM9_ABG+0x40000,0,0x20000);
|
||||
//MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*2); // BG-VRAM
|
||||
break;
|
||||
case 1 | (3 << 3) :
|
||||
MMU.vram_mode[adr-REG_VRAMCNTA] = 3; // BG-VRAM
|
||||
//memset(ARM9Mem.ARM9_ABG+0x60000,0,0x20000);
|
||||
//MMU.vram_offset[0] = ARM9Mem.ARM9_ABG+(0x20000*3); // BG-VRAM
|
||||
break;
|
||||
case 0: // mapped to lcd
|
||||
MMU.vram_mode[adr-REG_VRAMCNTA] = 4 | (adr-REG_VRAMCNTA) ;
|
||||
break ;
|
||||
}
|
||||
MMU_VRAMReloadFromLCD(adr-REG_VRAMCNTA,val) ;
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_VRAMCNTE:
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
MMU_VRAMWriteBackToLCD(4);
|
||||
if((val & 7) == 5)
|
||||
{
|
||||
ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x80000;
|
||||
ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x82000;
|
||||
ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x84000;
|
||||
ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x86000;
|
||||
}
|
||||
else if((val & 7) == 3)
|
||||
{
|
||||
ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x80000;
|
||||
ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x82000;
|
||||
ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x84000;
|
||||
ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x86000;
|
||||
}
|
||||
else if((val & 7) == 4)
|
||||
{
|
||||
ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x80000;
|
||||
ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x82000;
|
||||
ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x84000;
|
||||
ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x86000;
|
||||
}
|
||||
|
||||
MMU_VRAMReloadFromLCD(4,val) ;
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_VRAMCNTF:
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
MMU_VRAMWriteBackToLCD(5);
|
||||
switch(val & 0x1F)
|
||||
{
|
||||
case 4 :
|
||||
ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x90000;
|
||||
ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x92000;
|
||||
break;
|
||||
|
||||
case 4 | (1 << 3) :
|
||||
ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x90000;
|
||||
ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x92000;
|
||||
break;
|
||||
|
||||
case 3 :
|
||||
ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x90000;
|
||||
break;
|
||||
|
||||
case 3 | (1 << 3) :
|
||||
ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x90000;
|
||||
break;
|
||||
|
||||
case 3 | (2 << 3) :
|
||||
ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x90000;
|
||||
break;
|
||||
|
||||
case 3 | (3 << 3) :
|
||||
ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x90000;
|
||||
break;
|
||||
|
||||
case 5 :
|
||||
case 5 | (1 << 3) :
|
||||
case 5 | (2 << 3) :
|
||||
case 5 | (3 << 3) :
|
||||
ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x90000;
|
||||
ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x92000;
|
||||
break;
|
||||
}
|
||||
MMU_VRAMReloadFromLCD(5,val);
|
||||
}
|
||||
break;
|
||||
case REG_VRAMCNTG:
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
MMU_VRAMWriteBackToLCD(6);
|
||||
switch(val & 0x1F)
|
||||
{
|
||||
case 4 :
|
||||
ARM9Mem.ExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x94000;
|
||||
ARM9Mem.ExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x96000;
|
||||
break;
|
||||
|
||||
case 4 | (1 << 3) :
|
||||
ARM9Mem.ExtPal[0][2] = ARM9Mem.ARM9_LCD + 0x94000;
|
||||
ARM9Mem.ExtPal[0][3] = ARM9Mem.ARM9_LCD + 0x96000;
|
||||
break;
|
||||
|
||||
case 3 :
|
||||
ARM9Mem.texPalSlot[0] = ARM9Mem.ARM9_LCD + 0x94000;
|
||||
break;
|
||||
|
||||
case 3 | (1 << 3) :
|
||||
ARM9Mem.texPalSlot[1] = ARM9Mem.ARM9_LCD + 0x94000;
|
||||
break;
|
||||
|
||||
case 3 | (2 << 3) :
|
||||
ARM9Mem.texPalSlot[2] = ARM9Mem.ARM9_LCD + 0x94000;
|
||||
break;
|
||||
|
||||
case 3 | (3 << 3) :
|
||||
ARM9Mem.texPalSlot[3] = ARM9Mem.ARM9_LCD + 0x94000;
|
||||
break;
|
||||
|
||||
case 5 :
|
||||
case 5 | (1 << 3) :
|
||||
case 5 | (2 << 3) :
|
||||
case 5 | (3 << 3) :
|
||||
ARM9Mem.ObjExtPal[0][0] = ARM9Mem.ARM9_LCD + 0x94000;
|
||||
ARM9Mem.ObjExtPal[0][1] = ARM9Mem.ARM9_LCD + 0x96000;
|
||||
break;
|
||||
}
|
||||
MMU_VRAMReloadFromLCD(6,val);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_VRAMCNTH:
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
MMU_VRAMWriteBackToLCD(7);
|
||||
|
||||
if((val & 7) == 2)
|
||||
{
|
||||
ARM9Mem.ExtPal[1][0] = ARM9Mem.ARM9_LCD + 0x98000;
|
||||
ARM9Mem.ExtPal[1][1] = ARM9Mem.ARM9_LCD + 0x9A000;
|
||||
ARM9Mem.ExtPal[1][2] = ARM9Mem.ARM9_LCD + 0x9C000;
|
||||
ARM9Mem.ExtPal[1][3] = ARM9Mem.ARM9_LCD + 0x9E000;
|
||||
}
|
||||
|
||||
MMU_VRAMReloadFromLCD(7,val);
|
||||
}
|
||||
break;
|
||||
|
||||
case REG_VRAMCNTI:
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
MMU_VRAMWriteBackToLCD(8);
|
||||
MMU_VRAMmapControl(adr-REG_VRAMCNTA, val);
|
||||
else
|
||||
INFO("VRAM in Plain ARM7-CPU access\n");
|
||||
|
||||
if((val & 7) == 3)
|
||||
break;
|
||||
case REG_DISPA_DISPCAPCNT :
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
ARM9Mem.ObjExtPal[1][0] = ARM9Mem.ARM9_LCD + 0xA0000;
|
||||
ARM9Mem.ObjExtPal[1][1] = ARM9Mem.ARM9_LCD + 0xA2000;
|
||||
}
|
||||
|
||||
MMU_VRAMReloadFromLCD(8,val);
|
||||
//INFO("MMU write8: REG_DISPA_DISPCAPCNT 0x%X\n", val);
|
||||
GPU_set_DISPCAPCNT(val);
|
||||
T1WriteByte(ARM9Mem.ARM9_REG, 0x64, val);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef LOG_CARD
|
||||
case 0x040001A0 : /* TODO (clear): ??? */
|
||||
case 0x040001A1 :
|
||||
|
@ -1453,6 +1172,8 @@ void FASTCALL _MMU_write16(u32 adr, u16 val)
|
|||
}
|
||||
}
|
||||
|
||||
if (MMU_LCDmap(&adr)) return;
|
||||
|
||||
if((adr >> 24) == 4)
|
||||
{
|
||||
if(adr >= 0x04000380 && adr <= 0x040003BE)
|
||||
|
@ -1590,8 +1311,8 @@ void FASTCALL _MMU_write16(u32 adr, u16 val)
|
|||
}
|
||||
osdA->setOffset(MainScreen.offset);
|
||||
osdB->setOffset(SubScreen.offset);
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x304, val);
|
||||
}
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x304, val);
|
||||
|
||||
return;
|
||||
|
||||
|
@ -1796,6 +1517,7 @@ void FASTCALL _MMU_write16(u32 adr, u16 val)
|
|||
return;
|
||||
}
|
||||
case REG_VRAMCNTA:
|
||||
|
||||
MMU_write8(proc,adr,val & 0xFF) ;
|
||||
MMU_write8(proc,adr+1,val >> 8) ;
|
||||
return ;
|
||||
|
@ -1952,9 +1674,22 @@ void FASTCALL _MMU_write16(u32 adr, u16 val)
|
|||
case REG_DISPA_DISPCAPCNT :
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
GPU_set_DISPCAPCNT(MainScreen.gpu,val);
|
||||
// TODO
|
||||
//INFO("MMU write16: REG_DISPA_DISPCAPCNT 0x%X\n", val);
|
||||
//GPU_set_DISPCAPCNT(MainScreen.gpu,val);
|
||||
T1WriteWord(ARM9Mem.ARM9_REG, 0x64, val);
|
||||
}
|
||||
return;
|
||||
case REG_DISPA_DISPCAPCNT + 2:
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
// TODO
|
||||
//INFO("MMU write16: REG_DISPA_DISPCAPCNT + 2 0x%X\n", val);
|
||||
//GPU_set_DISPCAPCNT(MainScreen.gpu,val);
|
||||
//T1WriteByte(ARM9Mem.ARM9_REG, 0x64, val);
|
||||
}
|
||||
return;
|
||||
|
||||
case REG_DISPB_DISPCNT+2 :
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
|
@ -2108,6 +1843,8 @@ void FASTCALL _MMU_write32(u32 adr, u32 val)
|
|||
}
|
||||
}
|
||||
|
||||
if (MMU_LCDmap(&adr)) return;
|
||||
|
||||
if ((adr & 0xFF800000) == 0x04800000) {
|
||||
/* access to non regular hw registers */
|
||||
/* return to not overwrite valid data */
|
||||
|
@ -2875,32 +2612,29 @@ void FASTCALL _MMU_write32(u32 adr, u32 val)
|
|||
return;
|
||||
case REG_IPCFIFOCNT :
|
||||
{
|
||||
#if 0
|
||||
u32 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184) ;
|
||||
u32 cnt_r = T1ReadWord(MMU.MMU_MEM[(proc+1) & 1][0x40], 0x184) ;
|
||||
u32 cnt_r = T1ReadWord(MMU.MMU_MEM[proc^1][0x40], 0x184) ;
|
||||
if ((val & 0x8000) && !(cnt_l & 0x8000))
|
||||
{
|
||||
/* this is the first init, the other side didnt init yet */
|
||||
/* so do a complete init */
|
||||
FIFOInit(MMU.fifos + (IPCFIFO+proc));
|
||||
FIFOclear(&MMU.fifos[proc]);
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184,0x8101) ;
|
||||
/* and then handle it as usual */
|
||||
}
|
||||
if(val & 0x4008)
|
||||
{
|
||||
FIFOInit(MMU.fifos + (IPCFIFO+((proc+1)&1)));
|
||||
FIFOclear(&MMU.fifos[proc^1]);
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, (cnt_l & 0x0301) | (val & 0x8404) | 1);
|
||||
T1WriteWord(MMU.MMU_MEM[proc^1][0x40], 0x184, (cnt_r & 0xC507) | 0x100);
|
||||
MMU.reg_IF[proc] |= ((val & 4)<<15);// & (MMU.reg_IME[proc]<<17);// & (MMU.reg_IE[proc]&0x20000);//
|
||||
return;
|
||||
}
|
||||
T1WriteWord(MMU.MMU_MEM[proc][0x40], 0x184, val & 0xBFF4);
|
||||
#else
|
||||
LOG("MMU write32: REG_IPCFIFOCNT\n");
|
||||
#endif
|
||||
//execute = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
case REG_IPCFIFOSEND :
|
||||
{
|
||||
u16 cnt_l = T1ReadWord(MMU.MMU_MEM[proc][0x40], 0x184);
|
||||
|
@ -3047,7 +2781,8 @@ void FASTCALL _MMU_write32(u32 adr, u32 val)
|
|||
case REG_DISPA_DISPCAPCNT :
|
||||
if(proc == ARMCPU_ARM9)
|
||||
{
|
||||
GPU_set_DISPCAPCNT(MainScreen.gpu,val);
|
||||
//INFO("MMU write32: REG_DISPA_DISPCAPCNT 0x%X\n", val);
|
||||
GPU_set_DISPCAPCNT(val);
|
||||
T1WriteLong(ARM9Mem.ARM9_REG, 0x64, val);
|
||||
}
|
||||
return;
|
||||
|
@ -3089,9 +2824,7 @@ void FASTCALL _MMU_write32(u32 adr, u32 val)
|
|||
{
|
||||
// NOTE: right now, the capture unit is not taken into account,
|
||||
// I don't know is it should be handled here or
|
||||
#if 0
|
||||
FIFOAdd(MMU.fifos + MAIN_MEMORY_DISP_FIFO, val);
|
||||
#else
|
||||
FIFOadd(&MMU.fifos[proc], val);
|
||||
//4000068h - NDS9 - DISP_MMEM_FIFO - 32bit - Main Memory Display FIFO (R?/W)
|
||||
//Intended to send 256x192 pixel 32K color bitmaps by DMA directly
|
||||
//- to Screen A (set DISPCNT to Main Memory Display mode), or
|
||||
|
@ -3101,9 +2834,6 @@ void FASTCALL _MMU_write32(u32 adr, u32 val)
|
|||
//Set DMA to Main Memory mode, 32bit transfer width, word count set to 4, destination address to DISP_MMEM_FIFO, source address must be in Main Memory.
|
||||
//Transfer starts at next frame.
|
||||
//Main Memory Display/Capture is supported for Display Engine A only.
|
||||
|
||||
LOG("MMU write32: REG_DISPA_DISPMMEMFIFO\n");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
//case 0x21FDFF0 : if(val==0) execute = FALSE;
|
||||
|
|
|
@ -49,7 +49,10 @@ typedef struct {
|
|||
u8 ARM7_REG[0x10000];
|
||||
u8 ARM7_WIRAM[0x10000];
|
||||
|
||||
u8 vram_mode[9];
|
||||
// VRAM mapping
|
||||
u8 VRAM_MAP[4][32];
|
||||
u32 LCD_VRAM_ADDR[10];
|
||||
u8 LCDCenable[10];
|
||||
|
||||
//Shared ram
|
||||
u8 SWIRAM[0x8000];
|
||||
|
@ -188,4 +191,6 @@ extern struct armcpu_memory_iface arm9_base_memory_iface;
|
|||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1250,7 +1250,7 @@ int SNDFileInit(int buffersize)
|
|||
|
||||
void SNDFileDeInit()
|
||||
{
|
||||
size_t elems_written;
|
||||
size_t elems_written = 0;
|
||||
if (spufp)
|
||||
{
|
||||
long length = ftell(spufp);
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/* Copyright (C) 2006 yopyop
|
||||
yopyop156@ifrance.com
|
||||
yopyop156.ifrance.com
|
||||
|
||||
Copyright (C) 2006-2008 The DeSmuME Team
|
||||
|
||||
This file is part of DeSmuME
|
||||
|
||||
DeSmuME is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DeSmuME is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DeSmuME; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
CFLASH.C
|
||||
CompactFlash/FAT emulation routines for DeSmuME
|
||||
|
@ -636,7 +659,7 @@ static u16 fread_buffered(int dirent,u32 cluster,u32 offset) {
|
|||
unsigned int
|
||||
cflash_read(unsigned int address) {
|
||||
unsigned int ret_value = 0;
|
||||
size_t elems_read;
|
||||
size_t elems_read = 0;
|
||||
#if 0 /* used by next if 0 block */
|
||||
#define BUFFERED_BLOCK_SIZE 512
|
||||
static u8 block_buffer[BUFFERED_BLOCK_SIZE];
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
savestates_t savestates[NB_STATES];
|
||||
|
||||
#define SAVESTATE_VERSION 10
|
||||
#define SAVESTATE_VERSION 11
|
||||
static const char* magic = "DeSmuME SState\0";
|
||||
|
||||
#ifndef MAX_PATH
|
||||
|
@ -168,7 +168,9 @@ SFORMAT SF_MMU[]={
|
|||
{ "M7ER", 1, 0x10000, MMU.ARM7_ERAM},
|
||||
{ "M7RG", 1, 0x10000, MMU.ARM7_REG},
|
||||
{ "M7WI", 1, 0x10000, MMU.ARM7_WIRAM},
|
||||
{ "MVRM", 1, 9, MMU.vram_mode},
|
||||
{ "MVRM", 1, 4, MMU.VRAM_MAP},
|
||||
{ "MVRM", 4, 9, MMU.LCD_VRAM_ADDR},
|
||||
{ "MVRM", 1, 9, MMU.LCDCenable},
|
||||
{ "MSWI", 1, 0x8000, MMU.SWIRAM},
|
||||
{ "MCRA", 1, 0x10000, MMU.CART_RAM},
|
||||
{ "M9RW", 1, 1, &MMU.ARM9_RW_MODE},
|
||||
|
|
|
@ -322,7 +322,7 @@ BOOL CALLBACK InputConfigDlgProc( HWND hDlg,
|
|||
}
|
||||
|
||||
if (!inputCfg->Init(hDlg, &InputConfigDIProc))
|
||||
LOG("Input config: Error initialize DirectInput\n");
|
||||
INFO("Input config: Error initialize DirectInput\n");
|
||||
SetTimer(hDlg, IDD_INPUT_TIMER, 100, NULL);
|
||||
return true;
|
||||
|
||||
|
@ -514,8 +514,8 @@ BOOL INPUTCLASS::Init(HWND hParentWnd, INPUTPROC inputProc)
|
|||
this->inputProc = inputProc;
|
||||
|
||||
#if 1
|
||||
if (pKeyboard != NULL) LOG("DirectX Input: keyboard is initialised\n");
|
||||
if (pJoystick != NULL) LOG("DirectX Input: joystick is initialised\n");
|
||||
if (pKeyboard != NULL) INFO("DirectX Input: keyboard is initialised\n");
|
||||
if (pJoystick != NULL) INFO("DirectX Input: joystick is initialised\n");
|
||||
#endif
|
||||
paused = FALSE;
|
||||
|
||||
|
@ -539,7 +539,7 @@ void INPUTCLASS::process()
|
|||
hr=IDirectInputDevice8_GetDeviceState(pKeyboard,256,cDIBuf);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
//INFO("DInput: keyboard acquire\n");
|
||||
//LOG("DInput: keyboard acquire\n");
|
||||
IDirectInputDevice8_Acquire(pKeyboard);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -333,7 +333,7 @@ void ResizingLimit(int wParam, RECT *rc)
|
|||
u32 minX = 256;
|
||||
u32 minY = 414;
|
||||
|
||||
//INFO("width=%i; height=%i\n", width, height);
|
||||
//LOG("width=%i; height=%i\n", width, height);
|
||||
|
||||
if (GPU_rotation == 90 || GPU_rotation == 270)
|
||||
{
|
||||
|
@ -543,7 +543,7 @@ void UpdateRecentRomsMenu()
|
|||
moo.fType = 0;
|
||||
moo.wID = baseid + x;
|
||||
moo.dwTypeData = (LPSTR)tmp.c_str();
|
||||
//INFO("Inserting: %s\n",tmp.c_str()); //Debug
|
||||
//LOG("Inserting: %s\n",tmp.c_str()); //Debug
|
||||
InsertMenuItem(recentromsmenu, 0, 1, &moo);
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
|
@ -585,7 +585,7 @@ void UpdateRecentRoms(char* filename)
|
|||
|
||||
//Debug
|
||||
//for (int x = 0; x < RecentRoms.size(); x++)
|
||||
// INFO("Recent ROM: %s\n",RecentRoms[x].c_str());
|
||||
// LOG("Recent ROM: %s\n",RecentRoms[x].c_str());
|
||||
|
||||
UpdateRecentRomsMenu();
|
||||
}
|
||||
|
@ -748,7 +748,7 @@ void Display()
|
|||
}
|
||||
}
|
||||
else
|
||||
LOG("16bit depth color not supported");
|
||||
INFO("16bit depth color not supported");
|
||||
IDirectDrawSurface7_Unlock(lpBackSurface,(LPRECT)ddsd.lpSurface);
|
||||
|
||||
if (IDirectDrawSurface7_Blt(lpPrimarySurface,&MainWindowRect,lpBackSurface,0, DDBLT_WAIT,0)==DDERR_SURFACELOST)
|
||||
|
@ -995,7 +995,7 @@ void NDS_Pause()
|
|||
paused = TRUE;
|
||||
SPU_Pause(1);
|
||||
while (!paused) {}
|
||||
INFO("Paused\n");
|
||||
INFO("Emulation paused\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1006,7 @@ void NDS_UnPause()
|
|||
paused = FALSE;
|
||||
execute = TRUE;
|
||||
SPU_Pause(0);
|
||||
INFO("Unpaused\n");
|
||||
INFO("Emulation unpaused\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1042,16 +1042,16 @@ void StateLoadSlot(int num)
|
|||
BOOL LoadROM(char * filename, const char *cflash_disk_image)
|
||||
{
|
||||
NDS_Pause();
|
||||
if (strcmp(filename,"")!=0) LOG("Attempting to load ROM: %s\n",filename);
|
||||
//if (strcmp(filename,"")!=0) INFO("Attempting to load ROM: %s\n",filename);
|
||||
|
||||
if (NDS_LoadROM(filename, backupmemorytype, backupmemorysize, cflash_disk_image) > 0)
|
||||
{
|
||||
LOG("Loading %s was successful\n",filename);
|
||||
INFO("Loading %s was successful\n",filename);
|
||||
frameCounter=0;
|
||||
UpdateRecentRoms(filename);
|
||||
return TRUE;
|
||||
}
|
||||
LOG("Loading %s FAILED.\n",filename);
|
||||
INFO("Loading %s FAILED.\n",filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1573,7 +1573,7 @@ void OpenRecentROM(int listNum)
|
|||
if (listNum > MAX_RECENT_ROMS) return; //Just in case
|
||||
char filename[MAX_PATH];
|
||||
strcpy(filename, RecentRoms[listNum].c_str());
|
||||
LOG("Attempting to load %s\n",filename);
|
||||
//LOG("Attempting to load %s\n",filename);
|
||||
if(LoadROM(filename, bad_glob_cflash_disk_image_file))
|
||||
{
|
||||
EnableMenuItem(menu, IDM_PAUSE, MF_ENABLED);
|
||||
|
@ -1675,7 +1675,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
ResizingLimit(wParam, rc);
|
||||
if (ForceRatio)
|
||||
ScaleScreen(hwnd, wParam, rc);
|
||||
//INFO("sizing: width=%i; height=%i\n", rc->right - rc->left, rc->bottom - rc->top);
|
||||
//LOG("sizing: width=%i; height=%i\n", rc->right - rc->left, rc->bottom - rc->top);
|
||||
}
|
||||
break;
|
||||
case WM_SIZE:
|
||||
|
@ -1808,7 +1808,7 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
return 0;
|
||||
}
|
||||
|
||||
LOG("%s\r\n", filename);
|
||||
//LOG("%s\r\n", filename);
|
||||
|
||||
if(LoadROM(filename, bad_glob_cflash_disk_image_file))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue