X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fgpu.cpp;h=d5e9054c13716717ce47cce6b86be120920fb268;hb=725caa0f8bb826a73edef366906ccb41a3197819;hp=1f1bef9351cbe14eb6ab5ba18a1c94d00d5fa7e8;hpb=5d76d651dfc3aa0a2e810e6b6db2ae8a2e34c53e;p=virtualjaguar diff --git a/src/gpu.cpp b/src/gpu.cpp index 1f1bef9..d5e9054 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -99,8 +99,8 @@ #define GPU_DIS_SUBQT #define GPU_DIS_XOR -//bool doGPUDis = false; -bool doGPUDis = true; +bool doGPUDis = false; +//bool doGPUDis = true; #endif /* @@ -1192,6 +1192,10 @@ if (gpu_ram_8[0x054] == 0x98 && gpu_ram_8[0x055] == 0x0A && gpu_ram_8[0x056] == /* gpu_flag_c = (gpu_flag_c ? 1 : 0); gpu_flag_z = (gpu_flag_z ? 1 : 0); gpu_flag_n = (gpu_flag_n ? 1 : 0);*/ +#if 0 +if (gpu_pc == 0xF03200) + doGPUDis = true; +#endif uint16_t opcode = GPUReadWord(gpu_pc, GPU); uint32_t index = opcode >> 10; @@ -1372,6 +1376,7 @@ GPU opcodes use (offset punch--vertically below bad guy): nop 41362 */ + static void gpu_opcode_jump(void) { #ifdef GPU_DIS_JUMP @@ -1415,6 +1420,7 @@ if (gpu_start_log) #endif } + static void gpu_opcode_jr(void) { #ifdef GPU_DIS_JR @@ -1470,6 +1476,7 @@ if (gpu_start_log) #endif } + static void gpu_opcode_add(void) { #ifdef GPU_DIS_ADD @@ -1485,6 +1492,7 @@ static void gpu_opcode_add(void) #endif } + static void gpu_opcode_addc(void) { #ifdef GPU_DIS_ADDC @@ -1510,6 +1518,7 @@ static void gpu_opcode_addc(void) #endif } + static void gpu_opcode_addq(void) { #ifdef GPU_DIS_ADDQ @@ -1526,6 +1535,7 @@ static void gpu_opcode_addq(void) #endif } + static void gpu_opcode_addqt(void) { #ifdef GPU_DIS_ADDQT @@ -1539,6 +1549,7 @@ static void gpu_opcode_addqt(void) #endif } + static void gpu_opcode_sub(void) { #ifdef GPU_DIS_SUB @@ -1554,34 +1565,26 @@ static void gpu_opcode_sub(void) #endif } + static void gpu_opcode_subc(void) { #ifdef GPU_DIS_SUBC if (doGPUDis) WriteLog("%06X: SUBC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); #endif - uint32_t res = RN - RM - gpu_flag_c; - uint32_t borrow = gpu_flag_c; -// SET_ZNC_SUB(RN, RM, res); //???BUG??? YES!!! -//No matter how you do it, there is a problem. With below, it's 0-0 with carry, -//and the one below it it's FFFFFFFF - FFFFFFFF with carry... !!! FIX !!! -// SET_ZNC_SUB(RN - borrow, RM, res); - SET_ZNC_SUB(RN, RM + borrow, res); - RN = res; + // This is how the GPU ALU does it--Two's complement with inverted carry + uint64_t res = (uint64_t)RN + (uint64_t)(RM ^ 0xFFFFFFFF) + (gpu_flag_c ^ 1); + // Carry out of the result is inverted too + gpu_flag_c = ((res >> 32) & 0x01) ^ 1; + RN = (res & 0xFFFFFFFF); + SET_ZN(RN); #ifdef GPU_DIS_SUBC if (doGPUDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); #endif } -/* -N = 5, M = 3, 3 - 5 = -2, C = 1... Or, in our case: -N = 0, M = 1, 0 - 1 = -1, C = 0! -#define SET_C_SUB(a,b) (gpu_flag_c = ((uint32_t)(b) > (uint32_t)(a))) -#define SET_ZN(r) SET_N(r); SET_Z(r) -#define SET_ZNC_ADD(a,b,r) SET_N(r); SET_Z(r); SET_C_ADD(a,b) -#define SET_ZNC_SUB(a,b,r) SET_N(r); SET_Z(r); SET_C_SUB(a,b) -*/ + static void gpu_opcode_subq(void) { #ifdef GPU_DIS_SUBQ @@ -1598,6 +1601,7 @@ static void gpu_opcode_subq(void) #endif } + static void gpu_opcode_subqt(void) { #ifdef GPU_DIS_SUBQT @@ -1611,6 +1615,7 @@ static void gpu_opcode_subqt(void) #endif } + static void gpu_opcode_cmp(void) { #ifdef GPU_DIS_CMP @@ -1625,6 +1630,7 @@ static void gpu_opcode_cmp(void) #endif } + static void gpu_opcode_cmpq(void) { static int32_t sqtable[32] = @@ -1642,6 +1648,7 @@ static void gpu_opcode_cmpq(void) #endif } + static void gpu_opcode_and(void) { #ifdef GPU_DIS_AND @@ -1656,6 +1663,7 @@ static void gpu_opcode_and(void) #endif } + static void gpu_opcode_or(void) { #ifdef GPU_DIS_OR @@ -1670,6 +1678,7 @@ static void gpu_opcode_or(void) #endif } + static void gpu_opcode_xor(void) { #ifdef GPU_DIS_XOR @@ -1684,6 +1693,7 @@ static void gpu_opcode_xor(void) #endif } + static void gpu_opcode_not(void) { #ifdef GPU_DIS_NOT @@ -1698,6 +1708,7 @@ static void gpu_opcode_not(void) #endif } + static void gpu_opcode_move_pc(void) { #ifdef GPU_DIS_MOVEPC @@ -1713,6 +1724,7 @@ static void gpu_opcode_move_pc(void) #endif } + static void gpu_opcode_sat8(void) { #ifdef GPU_DIS_SAT8 @@ -1727,6 +1739,7 @@ static void gpu_opcode_sat8(void) #endif } + static void gpu_opcode_sat16(void) { RN = ((int32_t)RN < 0 ? 0 : (RN > 0xFFFF ? 0xFFFF : RN)); @@ -1739,6 +1752,7 @@ static void gpu_opcode_sat24(void) SET_ZN(RN); } + static void gpu_opcode_store_r14_indexed(void) { #ifdef GPU_DIS_STORE14I @@ -1757,6 +1771,7 @@ static void gpu_opcode_store_r14_indexed(void) #endif } + static void gpu_opcode_store_r15_indexed(void) { #ifdef GPU_DIS_STORE15I @@ -1775,6 +1790,7 @@ static void gpu_opcode_store_r15_indexed(void) #endif } + static void gpu_opcode_load_r14_ri(void) { #ifdef GPU_DIS_LOAD14R @@ -1797,6 +1813,7 @@ static void gpu_opcode_load_r14_ri(void) #endif } + static void gpu_opcode_load_r15_ri(void) { #ifdef GPU_DIS_LOAD15R @@ -1819,6 +1836,7 @@ static void gpu_opcode_load_r15_ri(void) #endif } + static void gpu_opcode_store_r14_ri(void) { #ifdef GPU_DIS_STORE14R @@ -1837,6 +1855,7 @@ static void gpu_opcode_store_r14_ri(void) #endif } + static void gpu_opcode_store_r15_ri(void) { #ifdef GPU_DIS_STORE15R @@ -1855,6 +1874,7 @@ static void gpu_opcode_store_r15_ri(void) #endif } + static void gpu_opcode_nop(void) { #ifdef GPU_DIS_NOP @@ -1863,6 +1883,7 @@ static void gpu_opcode_nop(void) #endif } + static void gpu_opcode_pack(void) { #ifdef GPU_DIS_PACK @@ -1882,6 +1903,7 @@ static void gpu_opcode_pack(void) #endif } + static void gpu_opcode_storeb(void) { #ifdef GPU_DIS_STOREB @@ -1896,6 +1918,7 @@ static void gpu_opcode_storeb(void) JaguarWriteByte(RM, RN, GPU); } + static void gpu_opcode_storew(void) { #ifdef GPU_DIS_STOREW @@ -1915,6 +1938,7 @@ static void gpu_opcode_storew(void) #endif } + static void gpu_opcode_store(void) { #ifdef GPU_DIS_STORE @@ -1931,6 +1955,7 @@ static void gpu_opcode_store(void) #endif } + static void gpu_opcode_storep(void) { #ifdef GPU_CORRECT_ALIGNMENT @@ -1966,6 +1991,7 @@ static void gpu_opcode_loadb(void) #endif } + static void gpu_opcode_loadw(void) { #ifdef GPU_DIS_LOADW @@ -1989,6 +2015,7 @@ static void gpu_opcode_loadw(void) #endif } + // According to the docs, & "Do The Same", this address is long aligned... // So let's try it: // And it works!!! Need to fix all instances... @@ -2032,6 +2059,7 @@ static void gpu_opcode_load(void) #endif } + static void gpu_opcode_loadp(void) { #ifdef GPU_CORRECT_ALIGNMENT @@ -2051,6 +2079,7 @@ static void gpu_opcode_loadp(void) #endif } + static void gpu_opcode_load_r14_indexed(void) { #ifdef GPU_DIS_LOAD14I @@ -2073,6 +2102,7 @@ static void gpu_opcode_load_r14_indexed(void) #endif } + static void gpu_opcode_load_r15_indexed(void) { #ifdef GPU_DIS_LOAD15I @@ -2095,6 +2125,7 @@ static void gpu_opcode_load_r15_indexed(void) #endif } + static void gpu_opcode_movei(void) { #ifdef GPU_DIS_MOVEI @@ -2110,6 +2141,7 @@ static void gpu_opcode_movei(void) #endif } + static void gpu_opcode_moveta(void) { #ifdef GPU_DIS_MOVETA @@ -2123,6 +2155,7 @@ static void gpu_opcode_moveta(void) #endif } + static void gpu_opcode_movefa(void) { #ifdef GPU_DIS_MOVEFA @@ -2136,6 +2169,7 @@ static void gpu_opcode_movefa(void) #endif } + static void gpu_opcode_move(void) { #ifdef GPU_DIS_MOVE @@ -2149,6 +2183,7 @@ static void gpu_opcode_move(void) #endif } + static void gpu_opcode_moveq(void) { #ifdef GPU_DIS_MOVEQ @@ -2162,11 +2197,13 @@ static void gpu_opcode_moveq(void) #endif } + static void gpu_opcode_resmac(void) { RN = gpu_acc; } + static void gpu_opcode_imult(void) { #ifdef GPU_DIS_IMULT @@ -2181,6 +2218,7 @@ static void gpu_opcode_imult(void) #endif } + static void gpu_opcode_mult(void) { #ifdef GPU_DIS_MULT @@ -2188,6 +2226,7 @@ static void gpu_opcode_mult(void) WriteLog("%06X: MULT R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN); #endif RN = (uint16_t)RM * (uint16_t)RN; +// RN = (RM & 0xFFFF) * (RN & 0xFFFF); SET_ZN(RN); #ifdef GPU_DIS_MULT if (doGPUDis) @@ -2195,6 +2234,7 @@ static void gpu_opcode_mult(void) #endif } + static void gpu_opcode_bclr(void) { #ifdef GPU_DIS_BCLR @@ -2210,6 +2250,7 @@ static void gpu_opcode_bclr(void) #endif } + static void gpu_opcode_btst(void) { #ifdef GPU_DIS_BTST @@ -2223,6 +2264,7 @@ static void gpu_opcode_btst(void) #endif } + static void gpu_opcode_bset(void) { #ifdef GPU_DIS_BSET @@ -2238,12 +2280,14 @@ static void gpu_opcode_bset(void) #endif } + static void gpu_opcode_imacn(void) { uint32_t res = (int16_t)RM * (int16_t)(RN); gpu_acc += res; } + static void gpu_opcode_mtoi(void) { uint32_t _RM = RM; @@ -2251,6 +2295,7 @@ static void gpu_opcode_mtoi(void) SET_ZN(res); } + static void gpu_opcode_normi(void) { uint32_t _RM = RM; @@ -2315,6 +2360,7 @@ static void gpu_opcode_mmult(void) SET_ZN(res); } + static void gpu_opcode_abs(void) { #ifdef GPU_DIS_ABS @@ -2337,6 +2383,7 @@ static void gpu_opcode_abs(void) #endif } + static void gpu_opcode_div(void) // RN / RM { #ifdef GPU_DIS_DIV @@ -2347,54 +2394,41 @@ static void gpu_opcode_div(void) // RN / RM // The original tried to get it right by checking to see if the // remainder was negative, but that's too late... // The code there should do it now, but I'm not 100% sure... +// [Now it should be correct, but not displaying correct behavior of the actual +// hardware. A step in the right direction.] if (RM) { if (gpu_div_control & 0x01) // 16.16 division { - RN = ((uint64_t)RN << 16) / RM; gpu_remain = ((uint64_t)RN << 16) % RM; + RN = ((uint64_t)RN << 16) / RM; } else { - RN = RN / RM; + // We calculate the remainder first because we destroy RN after + // this by assigning it to itself. gpu_remain = RN % RM; + RN = RN / RM; } +// What we really should do here is figure out why this condition +// happens in the real divide unit and emulate *that* behavior. +#if 0 if ((gpu_remain - RM) & 0x80000000) // If the result would have been negative... gpu_remain -= RM; // Then make it negative! +#endif } else RN = 0xFFFFFFFF; -/* uint32_t _RM=RM; - uint32_t _RN=RN; - - if (_RM) - { - if (gpu_div_control & 1) - { - gpu_remain = (((uint64_t)_RN) << 16) % _RM; - if (gpu_remain&0x80000000) - gpu_remain-=_RM; - RN = (((uint64_t)_RN) << 16) / _RM; - } - else - { - gpu_remain = _RN % _RM; - if (gpu_remain&0x80000000) - gpu_remain-=_RM; - RN/=_RM; - } - } - else - RN=0xffffffff;*/ #ifdef GPU_DIS_DIV if (doGPUDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] Remainder: %08X\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN, gpu_remain); #endif } + static void gpu_opcode_imultn(void) { uint32_t res = (int32_t)((int16_t)RN * (int16_t)RM); @@ -2403,6 +2437,7 @@ static void gpu_opcode_imultn(void) SET_FLAG_N(res); } + static void gpu_opcode_neg(void) { #ifdef GPU_DIS_NEG @@ -2418,6 +2453,7 @@ static void gpu_opcode_neg(void) #endif } + static void gpu_opcode_shlq(void) { #ifdef GPU_DIS_SHLQ @@ -2436,6 +2472,7 @@ static void gpu_opcode_shlq(void) #endif } + static void gpu_opcode_shrq(void) { #ifdef GPU_DIS_SHRQ @@ -2452,6 +2489,7 @@ static void gpu_opcode_shrq(void) #endif } + static void gpu_opcode_ror(void) { #ifdef GPU_DIS_ROR @@ -2468,6 +2506,7 @@ static void gpu_opcode_ror(void) #endif } + static void gpu_opcode_rorq(void) { #ifdef GPU_DIS_RORQ @@ -2485,6 +2524,7 @@ static void gpu_opcode_rorq(void) #endif } + static void gpu_opcode_sha(void) { /* int dreg = jaguar.op & 31; @@ -2559,6 +2599,7 @@ static void gpu_opcode_sha(void) SET_FLAG_N(_RN);*/ } + static void gpu_opcode_sharq(void) { #ifdef GPU_DIS_SHARQ @@ -2574,6 +2615,7 @@ static void gpu_opcode_sharq(void) #endif } + static void gpu_opcode_sh(void) { #ifdef GPU_DIS_SH @@ -2597,12 +2639,14 @@ static void gpu_opcode_sh(void) #endif } + //Temporary: Testing only! //#include "gpu2.cpp" //#include "gpu3.cpp" #else + // New thread-safe GPU core int GPUCore(void * data) @@ -2610,3 +2654,4 @@ int GPUCore(void * data) } #endif +