diff --git a/desmume/src/GPU.c b/desmume/src/GPU.c index 6172143f3..7933908dd 100644 --- a/desmume/src/GPU.c +++ b/desmume/src/GPU.c @@ -38,7 +38,7 @@ // SPRITE RENDERING // SCREEN FUNCTIONS // GRAPHICS CORE - +// GPU_ligne #include #include @@ -1238,10 +1238,12 @@ 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) src = gpu->sprMem + (spriteInfo->TileIndex<>3)*sprSize.x*8) + ((y&0x7)*8); @@ -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) - compute_sprite_rotoscale(gpu, spriteInfo, + 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;iitemsForPriority[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; iSource_B) { + for (i=0; i>16; i++; + } + } else { + for (i=0; iSource_B) { + for (i=0; iBlendFactor_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 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; + } +} diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index d0e8d22c6..e5add1f77 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -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;iitemsForPriority[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; iSource_B) { - for (i=0; i>16; i++; - } - } else { - for (i=0; iSource_B) { - for (i=0; iBlendFactor_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 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 diff --git a/desmume/src/armcpu.c b/desmume/src/armcpu.c index 79266883b..58ea41a5e 100644 --- a/desmume/src/armcpu.c +++ b/desmume/src/armcpu.c @@ -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; diff --git a/desmume/src/armcpu.h b/desmume/src/armcpu.h index 756420743..dcdeb9893 100644 --- a/desmume/src/armcpu.h +++ b/desmume/src/armcpu.h @@ -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,