moved GPU_ligne from header to source

added tabular functions for master brightness
This commit is contained in:
damdoum 2007-01-28 11:02:13 +00:00
parent 3c03be0deb
commit 2a5e45e6b3
4 changed files with 422 additions and 320 deletions

View File

@ -38,7 +38,7 @@
// SPRITE RENDERING
// SCREEN FUNCTIONS
// GRAPHICS CORE
// GPU_ligne
#include <string.h>
#include <stdlib.h>
@ -1238,9 +1238,11 @@ void sprite1D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
if (!compute_sprite_vars(spriteInfo, l, &sprSize, &sprX, &sprY, &x, &y, &lg, &xdir))
continue;
if (spriteInfo->RotScale & 1)
if (spriteInfo->RotScale & 1) {
compute_sprite_rotoscale(gpu, spriteInfo,
&rotScaleA, &rotScaleB, &rotScaleC, &rotScaleD);
//continue;
}
if (spriteInfo->Mode == 2) {
if (spriteInfo->Depth)
@ -1309,9 +1311,11 @@ void sprite2D(GPU * gpu, u16 l, u8 * dst, u8 * prioTab)
if (!compute_sprite_vars(spriteInfo, l, &sprSize, &sprX, &sprY, &x, &y, &lg, &xdir))
continue;
if (spriteInfo->RotScale & 1)
if (spriteInfo->RotScale & 1) {
compute_sprite_rotoscale(gpu, spriteInfo,
&rotScaleA, &rotScaleB, &rotScaleC, &rotScaleD);
//continue;
}
if (spriteInfo->Mode == 2) {
if (spriteInfo->Depth)
@ -1457,3 +1461,377 @@ void GFXDummyResize(int width, int height, BOOL fullscreen)
void GFXDummyOnScreenText(char *string, ...)
{
}
/*****************************************************************************/
// GPU_ligne
/*****************************************************************************/
void GPU_set_DISPCAPCNT(GPU * gpu, u32 val) {
gpu->dispCapCnt.val = val;
}
// trade off for speed is 1MB
u16 bright_more_colors[16][0x8000];
u16 bright_less_colors[16][0x8000];
BOOL bright_init=FALSE;
// comment this if want to use formulas instead
#define BRIGHT_TABLES
void calc_bright_colors() {
int base = /*gpu->masterBright.bits.FactorEx? 63:*/ 31 ;
int factor;
u16 red, green, blue;
COLOR color_more, color_less, color_ref;
#define FORMULA_MORE(x) x + ((base-x)*factor)/16
#define FORMULA_LESS(x) x - (x*factor)/16
if (bright_init) return;
for (factor=0; factor<16; factor++)
for (red =0; red <32; red++) {
color_ref.bits.red = red;
color_more.bits.red = FORMULA_MORE(red);
color_less.bits.red = FORMULA_LESS(red);
for (green=0; green<32; green++) {
color_ref.bits.green = green;
color_more.bits.green = FORMULA_MORE(green);
color_less.bits.green = FORMULA_LESS(green);
for (blue =0; blue <32; blue++) {
color_ref.bits.blue = blue;
color_more.bits.blue = FORMULA_MORE(blue);
color_less.bits.blue = FORMULA_LESS(blue);
bright_more_colors[factor][color_ref.bitx.bgr] = color_more.val;
bright_less_colors[factor][color_ref.bitx.bgr] = color_less.val;
}
}
}
bright_init=TRUE;
#undef FORMULA_MORE
#undef FORMULA_LESS
}
void GPU_ligne(Screen * screen, u16 l)
{
struct _DISPCAPCNT * capcnt;
GPU * gpu = screen->gpu;
u8 * dst = GPU_screen + (screen->offset + l) * 512;
u8 * mdst = GPU_screen + (MainScreen.offset + l) * 512;
u8 * sdst = GPU_screen + (SubScreen.offset + l) * 512;
itemsForPriority_t * item;
u8 spr[512];
u8 sprPrio[256];
u8 bgprio,prio;
int i;
int vram_bank;
u8 i8;
u16 i16;
u32 c;
u8 n,p;
u8 *dest;
/* initialize the scanline black */
/* not doing this causes invalid colors when all active BGs are prevented to draw at some place */
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 = gpu->dispCnt.bits.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)
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++;
}
return;
}
c = T1ReadWord(ARM9Mem.ARM9_VMEM, gpu->core * 0x400);
// init background color & priorities
for(i = 0; i< 256; ++i)
{
T2WriteWord(dst, i << 1, c);
T2WriteWord(spr, i << 1, c);
sprPrio[i]=0xFF;
gpu->sprWin[l][i]=0;
}
// init pixels priorities
for (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++) {
// assign them to the good priority item
prio = sprPrio[i];
if (prio >=4) continue;
item = &(gpu->itemsForPriority[prio]);
item->PixelsX[item->nbPixelsX]=i;
item->nbPixelsX++;
}
}
// paint lower priorities fist
// then higher priorities on top
for(prio=NB_PRIORITIES; prio > 0; )
{
prio--;
item = &(gpu->itemsForPriority[prio]);
// render BGs
for (i=0; i < item->nbBGs; i++) {
i16 = item->BGs[i];
if (gpu->LayersEnable[i16])
modeRender[gpu->dispCnt.bits.BG_Mode][i16](gpu, i16, l, dst);
}
// render sprite Pixels
for (i=0; i < item->nbPixelsX; i++) {
i16=item->PixelsX[i];
T2WriteWord(dst, i16 << 1, T2ReadWord(spr, i16 << 1));
}
}
// FIXME !!!
/* capture */
capcnt = &gpu->dispCapCnt.bits;
if (capcnt->Capture_Enable)
{
u16 * srcA, * srcB, *vram;
u32 c; u8 vram_bank;
COLOR color, colA, colB;
u16 ilast= 128;
if (capcnt->Capture_Size) ilast = 256;
vram = (u16*)(ARM9Mem.ARM9_ABG
+ MMU.vram_mode[capcnt->VRAM_Write_Block] * 0x20000
+ capcnt->VRAM_Write_Offset * 0x08000);
// I dunno yet how to do for 3D
if (!capcnt->Source_A)
srcA = (u16*)dst;
if (!capcnt->Source_B) {
vram_bank = gpu->dispCnt.bits.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];
}
}
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
}
break;
}
}
/* end of capture */
// Apply final brightness adjust (MASTER_BRIGHT)
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideo (Under MASTER_BRIGHTNESS)
/* Mightymax> it should be more effective if the windowmanager applies brightness when drawing */
/* it will most likly take acceleration, while we are stuck here with CPU power */
calc_bright_colors();
switch (gpu->masterBright.bits.Mode)
{
// Disabled
case 0:
break;
// Bright up
case 1:
{
COLOR dstColor;
unsigned int masterBrightFactor = gpu->masterBright.bits.Factor;
u16 * colors = bright_more_colors[masterBrightFactor];
if (gpu->masterBright.bits.FactorEx)
{
/* the formular would create only white, as (r + (31-r)) = 31 */
/* white = enable all bits */
memset(dst,0xFF, 256*2 /* sizeof(COLOR) */) ;
} else {
/* when we wont do anything, we dont need to loop */
if (!masterBrightFactor) break ;
for(i16 = 0; i16 < 256; ++i16)
{
#ifndef BRIGHT_TABLES
u8 base ;
u8 r,g,b; // get components, 5bit each
dstColor.val = T1ReadWord(dst, i16 << 1);
r = dstColor.bits.red;
g = dstColor.bits.green;
b = dstColor.bits.blue;
// Bright up and clamp to 5bit <-- automatic
base = /*gpu->masterBright.bits.FactorEx? 63:*/ 31 ;
dstColor.bits.red = r + ((base-r)*masterBrightFactor)/16;
dstColor.bits.green = g + ((base-g)*masterBrightFactor)/16;
dstColor.bits.blue = b + ((base-b)*masterBrightFactor)/16;
#else
dstColor.val = T1ReadWord(dst, i16 << 1);
dstColor.bitx.bgr = colors[dstColor.bitx.bgr];
#endif
T2WriteWord (dst, i16 << 1, dstColor.val);
}
}
break;
}
// Bright down
case 2:
{
/*
NOTE: gbatek (in the reference above) seems to expect 6bit values
per component, but as desmume works with 5bit per component,
we use 31 as top, instead of 63. Testing it on a few games,
using 63 seems to give severe color wraping, and 31 works
nicely, so for now we'll just that, until proven wrong.
i have seen pics of pokemon ranger getting white with 31, with 63 it is nice.
it could be pb of alpha or blending or...
MightyMax> created a test NDS to check how the brightness values work,
and 31 seems to be correct. FactorEx is a override for max brighten/darken
See: http://mightymax.org/gfx_test_brightness.nds
The Pokemon Problem could be a problem with 8/32 bit writes not recognized yet,
i'll add that so you can check back.
*/
COLOR dstColor;
unsigned int masterBrightFactor = gpu->masterBright.bits.Factor ;
u16 * colors = bright_less_colors[masterBrightFactor];
if (gpu->masterBright.bits.FactorEx)
{
/* the formular would create only black, as (r - r) = 0 */
/* black = disable all bits */
memset(dst,0, 256*2 /* sizeof(COLOR) */) ;
} else
{
/* when we wont do anything, we dont need to loop */
if (!masterBrightFactor) break ;
for(i16 = 0; i16 < 256; ++i16)
{
#ifndef BRIGHT_TABLES
u8 r,g,b;
r = dstColor.bits.red;
g = dstColor.bits.green;
b = dstColor.bits.blue;
// Bright up and clamp to 5bit <- automatic
dstColor.bits.red = r - (r*masterBrightFactor)/16;
dstColor.bits.green = g - (g*masterBrightFactor)/16;
dstColor.bits.blue = b - (b*masterBrightFactor)/16;
#else
dstColor.val = T1ReadWord(dst, i16 << 1);
dstColor.bitx.bgr = colors[dstColor.bitx.bgr];
#endif
T2WriteWord (dst, i16 << 1, dstColor.val);
}
}
break;
}
// Reserved
case 3:
break;
}
}

View File

@ -169,10 +169,15 @@ struct _COLOR { // abgr x555
unsigned blue:5;
unsigned alpha:1; // sometimes it is unused (pad)
};
struct _COLORx { // abgr x555
unsigned bgr:15;
unsigned alpha:1; // sometimes it is unused (pad)
};
typedef union
{
struct _COLOR bits;
struct _COLORx bitx;
u16 val;
} COLOR;
@ -480,322 +485,7 @@ void Screen_DeInit(void);
extern MMU_struct MMU;
static INLINE void GPU_set_DISPCAPCNT(GPU * gpu, u32 val) {
gpu->dispCapCnt.val = val;
}
static INLINE void GPU_ligne(Screen * screen, u16 l)
{
struct _DISPCAPCNT * capcnt;
GPU * gpu = screen->gpu;
u8 * dst = GPU_screen + (screen->offset + l) * 512;
u8 * mdst = GPU_screen + (MainScreen.offset + l) * 512;
u8 * sdst = GPU_screen + (SubScreen.offset + l) * 512;
itemsForPriority_t * item;
u8 spr[512];
u8 sprPrio[256];
u8 bgprio,prio;
int i;
int vram_bank;
u8 i8;
u16 i16;
u32 c;
u8 n,p;
u8 *dest;
/* initialize the scanline black */
/* not doing this causes invalid colors when all active BGs are prevented to draw at some place */
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 = gpu->dispCnt.bits.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)
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++;
}
return;
}
c = T1ReadWord(ARM9Mem.ARM9_VMEM, gpu->core * 0x400);
// init background color & priorities
for(i = 0; i< 256; ++i)
{
T2WriteWord(dst, i << 1, c);
T2WriteWord(spr, i << 1, c);
sprPrio[i]=0xFF;
gpu->sprWin[l][i]=0;
}
// init pixels priorities
for (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++) {
// assign them to the good priority item
prio = sprPrio[i];
if (prio >=4) continue;
item = &(gpu->itemsForPriority[prio]);
item->PixelsX[item->nbPixelsX]=i;
item->nbPixelsX++;
}
}
// paint lower priorities fist
// then higher priorities on top
for(prio=NB_PRIORITIES; prio > 0; )
{
prio--;
item = &(gpu->itemsForPriority[prio]);
// render BGs
for (i=0; i < item->nbBGs; i++) {
i16 = item->BGs[i];
if (gpu->LayersEnable[i16])
modeRender[gpu->dispCnt.bits.BG_Mode][i16](gpu, i16, l, dst);
}
// render sprite Pixels
for (i=0; i < item->nbPixelsX; i++) {
i16=item->PixelsX[i];
T2WriteWord(dst, i16 << 1, T2ReadWord(spr, i16 << 1));
}
}
// FIXME !!!
/* capture */
capcnt = &gpu->dispCapCnt.bits;
if (capcnt->Capture_Enable)
{
u16 * srcA, * srcB, *vram;
u32 c; u8 vram_bank;
COLOR color, colA, colB;
u16 ilast= 128;
if (capcnt->Capture_Size) ilast = 256;
vram = (u16*)(ARM9Mem.ARM9_ABG
+ MMU.vram_mode[capcnt->VRAM_Write_Block] * 0x20000
+ capcnt->VRAM_Write_Offset * 0x08000);
// I dunno yet how to do for 3D
if (!capcnt->Source_A)
srcA = (u16*)dst;
if (!capcnt->Source_B) {
vram_bank = gpu->dispCnt.bits.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];
}
}
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
}
break;
}
}
/* end of capture */
// Apply final brightness adjust (MASTER_BRIGHT)
// Reference: http://nocash.emubase.de/gbatek.htm#dsvideo (Under MASTER_BRIGHTNESS)
/* Mightymax> it should be more effective if the windowmanager applies brightness when drawing */
/* it will most likly take acceleration, while we are stuck here with CPU power */
switch (gpu->masterBright.bits.Mode)
{
// Disabled
case 0:
break;
// Bright up
case 1:
{
unsigned int masterBrightFactor = gpu->masterBright.bits.Factor;
if (gpu->masterBright.bits.FactorEx)
{
/* the formular would create only white, as (r + (31-r)) = 31 */
/* white = enable all bits */
/* damdoum : well, i think the formula was with 63!
so (r + (63-r)) = 63 & 31 = 31 = still white*/
memset(dst,0xFF, 256*2 /* sizeof(COLOR) */) ;
} else
{
if (!masterBrightFactor) break ; /* when we wont do anything, we dont need to loop */
for(i16 = 0; i16 < 256; ++i16)
{
COLOR dstColor;
u8 base ;
unsigned int r,g,b; // get components, 5bit each
dstColor.val = T1ReadWord(dst, i16 << 1);
r = dstColor.bits.red;
g = dstColor.bits.green;
b = dstColor.bits.blue;
// Bright up and clamp to 5bit <-- automatic
base = /*gpu->masterBright.bits.FactorEx? 63:*/ 31 ;
dstColor.bits.red = r + ((base-r)*masterBrightFactor)/16;
dstColor.bits.green = g + ((base-g)*masterBrightFactor)/16;
dstColor.bits.blue = b + ((base-b)*masterBrightFactor)/16;
T2WriteWord (dst, i16 << 1, dstColor.val);
}
}
break;
}
// Bright down
case 2:
{
/*
NOTE: gbatek (in the reference above) seems to expect 6bit values
per component, but as desmume works with 5bit per component,
we use 31 as top, instead of 63. Testing it on a few games,
using 63 seems to give severe color wraping, and 31 works
nicely, so for now we'll just that, until proven wrong.
i have seen pics of pokemon ranger getting white with 31, with 63 it is nice.
it could be pb of alpha or blending or...
MightyMax> created a test NDS to check how the brightness values work,
and 31 seems to be correct. FactorEx is a override for max brighten/darken
See: http://mightymax.org/gfx_test_brightness.nds
The Pokemon Problem could be a problem with 8/32 bit writes not recognized yet,
i'll add that so you can check back.
.
*/
unsigned int masterBrightFactor = gpu->masterBright.bits.Factor ;
if (gpu->masterBright.bits.FactorEx)
{
/* the formular would create only black, as (r - r) = 0 */
/* black = disable all bits */
memset(dst,0, 256*2 /* sizeof(COLOR) */) ;
} else
{
if (!masterBrightFactor) break ; /* when we wont do anything, we dont need to loop */
for(i16 = 0; i16 < 256; ++i16)
{
COLOR dstColor;
unsigned int r,g,b; // get components, 5bit each
dstColor.val = T1ReadWord(dst, i16 << 1);
r = dstColor.bits.red;
g = dstColor.bits.green;
b = dstColor.bits.blue;
// Bright up and clamp to 5bit <- automatic
dstColor.bits.red = r - (r*masterBrightFactor)/16;
dstColor.bits.green = g - (g*masterBrightFactor)/16;
dstColor.bits.blue = b - (b*masterBrightFactor)/16;
T2WriteWord (dst, i16 << 1, dstColor.val);
}
}
break;
}
// Reserved
case 3:
break;
}
}
#define GFXCORE_DEFAULT -1
#define GFXCORE_DUMMY 0
@ -856,6 +546,9 @@ void GPU_addBack(GPU *, u8 num);
int GPU_ChangeGraphicsCore(int coreid);
void GPU_set_DISPCAPCNT(GPU * gpu, u32 val) ;
void GPU_ligne(Screen * screen, u16 l) ;
#ifdef __cplusplus
}
#endif

View File

@ -208,6 +208,36 @@ u32 armcpu_prefetch(armcpu_t *armcpu)
return MMU.MMU_WAIT16[armcpu->proc_ID][(armcpu->instruct_adr>>24)&0xF];
}
static BOOL FASTCALL test_EQ(Status_Reg CPSR) { return ( CPSR.bits.Z); }
static BOOL FASTCALL test_NE(Status_Reg CPSR) { return (!CPSR.bits.Z); }
static BOOL FASTCALL test_CS(Status_Reg CPSR) { return ( CPSR.bits.C); }
static BOOL FASTCALL test_CC(Status_Reg CPSR) { return (!CPSR.bits.C); }
static BOOL FASTCALL test_MI(Status_Reg CPSR) { return ( CPSR.bits.N); }
static BOOL FASTCALL test_PL(Status_Reg CPSR) { return (!CPSR.bits.N); }
static BOOL FASTCALL test_VS(Status_Reg CPSR) { return ( CPSR.bits.V); }
static BOOL FASTCALL test_VC(Status_Reg CPSR) { return (!CPSR.bits.V); }
static BOOL FASTCALL test_HI(Status_Reg CPSR) { return (CPSR.bits.C) && (!CPSR.bits.Z); }
static BOOL FASTCALL test_LS(Status_Reg CPSR) { return (CPSR.bits.Z) || (!CPSR.bits.C); }
static BOOL FASTCALL test_GE(Status_Reg CPSR) { return (CPSR.bits.N==CPSR.bits.V); }
static BOOL FASTCALL test_LT(Status_Reg CPSR) { return (CPSR.bits.N!=CPSR.bits.V); }
static BOOL FASTCALL test_GT(Status_Reg CPSR) { return (!CPSR.bits.Z) && (CPSR.bits.N==CPSR.bits.V); }
static BOOL FASTCALL test_LE(Status_Reg CPSR) { return ( CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V); }
static BOOL FASTCALL test_AL(Status_Reg CPSR) { return 1; }
static BOOL (*FASTCALL test_conditions[])(Status_Reg CPSR)= {
test_EQ , test_NE ,
test_CS , test_CC ,
test_MI , test_PL ,
test_VS , test_VC ,
test_HI , test_LS ,
test_GE , test_LT ,
test_GT , test_LE ,
test_AL
};
#define TEST_COND2(cond, CPSR) \
(cond<15&&test_conditions[cond](CPSR))
u32 armcpu_exec(armcpu_t *armcpu)
{
u32 c = 1;

View File

@ -85,6 +85,7 @@ extern "C" {
(((cond)==GT) && (CPSR.bits.Z==0) && (CPSR.bits.N==CPSR.bits.V))||\
(((cond)==LE) && ((CPSR.bits.Z) || (CPSR.bits.N!=CPSR.bits.V))))
enum Mode
{
USR = 0x10,