From: Shamus Hammons Date: Tue, 28 May 2013 20:49:40 +0000 (-0500) Subject: Fix for RISC SUBC opcode, more tweaks to controller config. X-Git-Tag: 2.1.1~28 X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=virtualjaguar;a=commitdiff_plain;h=d1e404e2f488610a99f844783dca15a7525c3813 Fix for RISC SUBC opcode, more tweaks to controller config. --- diff --git a/src/dsp.cpp b/src/dsp.cpp index 2dab23c..0218a7d 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -1639,6 +1639,7 @@ if ((dsp_pc < 0xF1B000 || dsp_pc > 0xF1CFFE) && !tripwire) dsp_in_exec--; } + // // DSP opcode handlers // @@ -1681,6 +1682,7 @@ const char * condition[32] = #endif } + static void dsp_opcode_jr(void) { #ifdef DSP_DIS_JR @@ -1717,6 +1719,7 @@ const char * condition[32] = #endif } + static void dsp_opcode_add(void) { #ifdef DSP_DIS_ADD @@ -1732,6 +1735,7 @@ static void dsp_opcode_add(void) #endif } + static void dsp_opcode_addc(void) { #ifdef DSP_DIS_ADDC @@ -1750,6 +1754,7 @@ static void dsp_opcode_addc(void) #endif } + static void dsp_opcode_addq(void) { #ifdef DSP_DIS_ADDQ @@ -1766,6 +1771,7 @@ static void dsp_opcode_addq(void) #endif } + static void dsp_opcode_sub(void) { #ifdef DSP_DIS_SUB @@ -1781,22 +1787,26 @@ static void dsp_opcode_sub(void) #endif } + static void dsp_opcode_subc(void) { #ifdef DSP_DIS_SUBC if (doDSPDis) WriteLog("%06X: SUBC R%02u, R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", dsp_pc-2, IMM_1, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM, IMM_2, RN); #endif - uint32_t res = RN - RM - dsp_flag_c; - uint32_t borrow = dsp_flag_c; - SET_ZNC_SUB(RN - borrow, RM, res); - RN = res; + // This is how the DSP ALU does it--Two's complement with inverted carry + uint64_t res = (uint64_t)RN + (uint64_t)(RM ^ 0xFFFFFFFF) + (dsp_flag_c ^ 1); + // Carry out of the result is inverted too + dsp_flag_c = ((res >> 32) & 0x01) ^ 1; + RN = (res & 0xFFFFFFFF); + SET_ZN(RN); #ifdef DSP_DIS_SUBC if (doDSPDis) WriteLog("[NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_1, RM, IMM_2, RN); #endif } + static void dsp_opcode_subq(void) { #ifdef DSP_DIS_SUBQ @@ -1813,6 +1823,7 @@ static void dsp_opcode_subq(void) #endif } + static void dsp_opcode_cmp(void) { #ifdef DSP_DIS_CMP @@ -1827,6 +1838,7 @@ static void dsp_opcode_cmp(void) #endif } + static void dsp_opcode_cmpq(void) { static int32_t sqtable[32] = @@ -1844,6 +1856,7 @@ static void dsp_opcode_cmpq(void) #endif } + static void dsp_opcode_and(void) { #ifdef DSP_DIS_AND @@ -1858,6 +1871,7 @@ static void dsp_opcode_and(void) #endif } + static void dsp_opcode_or(void) { #ifdef DSP_DIS_OR @@ -1872,6 +1886,7 @@ static void dsp_opcode_or(void) #endif } + static void dsp_opcode_xor(void) { #ifdef DSP_DIS_XOR @@ -1886,6 +1901,7 @@ static void dsp_opcode_xor(void) #endif } + static void dsp_opcode_not(void) { #ifdef DSP_DIS_NOT @@ -1900,11 +1916,13 @@ static void dsp_opcode_not(void) #endif } + static void dsp_opcode_move_pc(void) { RN = dsp_pc - 2; } + static void dsp_opcode_store_r14_indexed(void) { #ifdef DSP_DIS_STORE14I @@ -1918,6 +1936,7 @@ static void dsp_opcode_store_r14_indexed(void) #endif } + static void dsp_opcode_store_r15_indexed(void) { #ifdef DSP_DIS_STORE15I @@ -1931,6 +1950,7 @@ static void dsp_opcode_store_r15_indexed(void) #endif } + static void dsp_opcode_load_r14_ri(void) { #ifdef DSP_DIS_LOAD14R @@ -1948,6 +1968,7 @@ static void dsp_opcode_load_r14_ri(void) #endif } + static void dsp_opcode_load_r15_ri(void) { #ifdef DSP_DIS_LOAD15R @@ -1965,16 +1986,19 @@ static void dsp_opcode_load_r15_ri(void) #endif } + static void dsp_opcode_store_r14_ri(void) { DSPWriteLong(dsp_reg[14] + RM, RN, DSP); } + static void dsp_opcode_store_r15_ri(void) { DSPWriteLong(dsp_reg[15] + RM, RN, DSP); } + static void dsp_opcode_nop(void) { #ifdef DSP_DIS_NOP @@ -1983,6 +2007,7 @@ static void dsp_opcode_nop(void) #endif } + static void dsp_opcode_storeb(void) { #ifdef DSP_DIS_STOREB @@ -1995,6 +2020,7 @@ static void dsp_opcode_storeb(void) JaguarWriteByte(RM, RN, DSP); } + static void dsp_opcode_storew(void) { #ifdef DSP_DIS_STOREW @@ -2014,6 +2040,7 @@ static void dsp_opcode_storew(void) #endif } + static void dsp_opcode_store(void) { #ifdef DSP_DIS_STORE @@ -2027,6 +2054,7 @@ static void dsp_opcode_store(void) #endif } + static void dsp_opcode_loadb(void) { #ifdef DSP_DIS_LOADB @@ -2043,6 +2071,7 @@ static void dsp_opcode_loadb(void) #endif } + static void dsp_opcode_loadw(void) { #ifdef DSP_DIS_LOADW @@ -2066,6 +2095,7 @@ static void dsp_opcode_loadw(void) #endif } + static void dsp_opcode_load(void) { #ifdef DSP_DIS_LOAD @@ -2083,6 +2113,7 @@ static void dsp_opcode_load(void) #endif } + static void dsp_opcode_load_r14_indexed(void) { #ifdef DSP_DIS_LOAD14I @@ -2100,6 +2131,7 @@ static void dsp_opcode_load_r14_indexed(void) #endif } + static void dsp_opcode_load_r15_indexed(void) { #ifdef DSP_DIS_LOAD15I @@ -2117,6 +2149,7 @@ static void dsp_opcode_load_r15_indexed(void) #endif } + static void dsp_opcode_movei(void) { #ifdef DSP_DIS_MOVEI @@ -2132,6 +2165,7 @@ static void dsp_opcode_movei(void) #endif } + static void dsp_opcode_moveta(void) { #ifdef DSP_DIS_MOVETA @@ -2145,6 +2179,7 @@ static void dsp_opcode_moveta(void) #endif } + static void dsp_opcode_movefa(void) { #ifdef DSP_DIS_MOVEFA @@ -2158,6 +2193,7 @@ static void dsp_opcode_movefa(void) #endif } + static void dsp_opcode_move(void) { #ifdef DSP_DIS_MOVE @@ -2171,6 +2207,7 @@ static void dsp_opcode_move(void) #endif } + static void dsp_opcode_moveq(void) { #ifdef DSP_DIS_MOVEQ @@ -2184,6 +2221,7 @@ static void dsp_opcode_moveq(void) #endif } + static void dsp_opcode_resmac(void) { #ifdef DSP_DIS_RESMAC @@ -2197,6 +2235,7 @@ static void dsp_opcode_resmac(void) #endif } + static void dsp_opcode_imult(void) { #ifdef DSP_DIS_IMULT @@ -2211,6 +2250,7 @@ static void dsp_opcode_imult(void) #endif } + static void dsp_opcode_mult(void) { #ifdef DSP_DIS_MULT @@ -2225,6 +2265,7 @@ static void dsp_opcode_mult(void) #endif } + static void dsp_opcode_bclr(void) { #ifdef DSP_DIS_BCLR @@ -2240,6 +2281,7 @@ static void dsp_opcode_bclr(void) #endif } + static void dsp_opcode_btst(void) { #ifdef DSP_DIS_BTST @@ -2253,6 +2295,7 @@ static void dsp_opcode_btst(void) #endif } + static void dsp_opcode_bset(void) { #ifdef DSP_DIS_BSET @@ -2268,6 +2311,7 @@ static void dsp_opcode_bset(void) #endif } + static void dsp_opcode_subqt(void) { #ifdef DSP_DIS_SUBQT @@ -2281,6 +2325,7 @@ static void dsp_opcode_subqt(void) #endif } + static void dsp_opcode_addqt(void) { #ifdef DSP_DIS_ADDQT @@ -2294,6 +2339,7 @@ static void dsp_opcode_addqt(void) #endif } + static void dsp_opcode_imacn(void) { #ifdef DSP_DIS_IMACN @@ -2309,12 +2355,14 @@ static void dsp_opcode_imacn(void) #endif } + static void dsp_opcode_mtoi(void) { RN = (((int32_t)RM >> 8) & 0xFF800000) | (RM & 0x007FFFFF); SET_ZN(RN); } + static void dsp_opcode_normi(void) { uint32_t _Rm = RM; @@ -2337,6 +2385,7 @@ static void dsp_opcode_normi(void) SET_ZN(RN); } + static void dsp_opcode_mmult(void) { int count = dsp_matrix_control&0x0f; @@ -2378,6 +2427,7 @@ static void dsp_opcode_mmult(void) SET_ZN(RN); } + static void dsp_opcode_abs(void) { #ifdef DSP_DIS_ABS @@ -2401,6 +2451,7 @@ static void dsp_opcode_abs(void) #endif } + static void dsp_opcode_div(void) { #if 0 @@ -2454,6 +2505,7 @@ static void dsp_opcode_div(void) #endif } + static void dsp_opcode_imultn(void) { #ifdef DSP_DIS_IMULTN @@ -2470,6 +2522,7 @@ static void dsp_opcode_imultn(void) #endif } + static void dsp_opcode_neg(void) { #ifdef DSP_DIS_NEG @@ -2485,6 +2538,7 @@ static void dsp_opcode_neg(void) #endif } + static void dsp_opcode_shlq(void) { #ifdef DSP_DIS_SHLQ @@ -2502,6 +2556,7 @@ static void dsp_opcode_shlq(void) #endif } + static void dsp_opcode_shrq(void) { #ifdef DSP_DIS_SHRQ @@ -2518,6 +2573,7 @@ static void dsp_opcode_shrq(void) #endif } + static void dsp_opcode_ror(void) { #ifdef DSP_DIS_ROR @@ -2534,6 +2590,7 @@ static void dsp_opcode_ror(void) #endif } + static void dsp_opcode_rorq(void) { #ifdef DSP_DIS_RORQ @@ -2551,6 +2608,7 @@ static void dsp_opcode_rorq(void) #endif } + static void dsp_opcode_sha(void) { int32_t sRm=(int32_t)RM; @@ -2582,6 +2640,7 @@ static void dsp_opcode_sha(void) SET_ZN(RN); } + static void dsp_opcode_sharq(void) { #ifdef DSP_DIS_SHARQ @@ -2597,6 +2656,7 @@ static void dsp_opcode_sharq(void) #endif } + static void dsp_opcode_sh(void) { int32_t sRm=(int32_t)RM; diff --git a/src/gpu.cpp b/src/gpu.cpp index 49a862a..d5e9054 100644 --- a/src/gpu.cpp +++ b/src/gpu.cpp @@ -1376,6 +1376,7 @@ GPU opcodes use (offset punch--vertically below bad guy): nop 41362 */ + static void gpu_opcode_jump(void) { #ifdef GPU_DIS_JUMP @@ -1419,6 +1420,7 @@ if (gpu_start_log) #endif } + static void gpu_opcode_jr(void) { #ifdef GPU_DIS_JR @@ -1474,6 +1476,7 @@ if (gpu_start_log) #endif } + static void gpu_opcode_add(void) { #ifdef GPU_DIS_ADD @@ -1489,6 +1492,7 @@ static void gpu_opcode_add(void) #endif } + static void gpu_opcode_addc(void) { #ifdef GPU_DIS_ADDC @@ -1514,6 +1518,7 @@ static void gpu_opcode_addc(void) #endif } + static void gpu_opcode_addq(void) { #ifdef GPU_DIS_ADDQ @@ -1530,6 +1535,7 @@ static void gpu_opcode_addq(void) #endif } + static void gpu_opcode_addqt(void) { #ifdef GPU_DIS_ADDQT @@ -1543,6 +1549,7 @@ static void gpu_opcode_addqt(void) #endif } + static void gpu_opcode_sub(void) { #ifdef GPU_DIS_SUB @@ -1558,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 @@ -1602,6 +1601,7 @@ static void gpu_opcode_subq(void) #endif } + static void gpu_opcode_subqt(void) { #ifdef GPU_DIS_SUBQT @@ -1615,6 +1615,7 @@ static void gpu_opcode_subqt(void) #endif } + static void gpu_opcode_cmp(void) { #ifdef GPU_DIS_CMP @@ -1629,6 +1630,7 @@ static void gpu_opcode_cmp(void) #endif } + static void gpu_opcode_cmpq(void) { static int32_t sqtable[32] = @@ -1646,6 +1648,7 @@ static void gpu_opcode_cmpq(void) #endif } + static void gpu_opcode_and(void) { #ifdef GPU_DIS_AND @@ -1660,6 +1663,7 @@ static void gpu_opcode_and(void) #endif } + static void gpu_opcode_or(void) { #ifdef GPU_DIS_OR @@ -1674,6 +1678,7 @@ static void gpu_opcode_or(void) #endif } + static void gpu_opcode_xor(void) { #ifdef GPU_DIS_XOR @@ -1688,6 +1693,7 @@ static void gpu_opcode_xor(void) #endif } + static void gpu_opcode_not(void) { #ifdef GPU_DIS_NOT @@ -1702,6 +1708,7 @@ static void gpu_opcode_not(void) #endif } + static void gpu_opcode_move_pc(void) { #ifdef GPU_DIS_MOVEPC @@ -1717,6 +1724,7 @@ static void gpu_opcode_move_pc(void) #endif } + static void gpu_opcode_sat8(void) { #ifdef GPU_DIS_SAT8 @@ -1731,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)); @@ -1743,6 +1752,7 @@ static void gpu_opcode_sat24(void) SET_ZN(RN); } + static void gpu_opcode_store_r14_indexed(void) { #ifdef GPU_DIS_STORE14I @@ -1761,6 +1771,7 @@ static void gpu_opcode_store_r14_indexed(void) #endif } + static void gpu_opcode_store_r15_indexed(void) { #ifdef GPU_DIS_STORE15I @@ -1779,6 +1790,7 @@ static void gpu_opcode_store_r15_indexed(void) #endif } + static void gpu_opcode_load_r14_ri(void) { #ifdef GPU_DIS_LOAD14R @@ -1801,6 +1813,7 @@ static void gpu_opcode_load_r14_ri(void) #endif } + static void gpu_opcode_load_r15_ri(void) { #ifdef GPU_DIS_LOAD15R @@ -1823,6 +1836,7 @@ static void gpu_opcode_load_r15_ri(void) #endif } + static void gpu_opcode_store_r14_ri(void) { #ifdef GPU_DIS_STORE14R @@ -1841,6 +1855,7 @@ static void gpu_opcode_store_r14_ri(void) #endif } + static void gpu_opcode_store_r15_ri(void) { #ifdef GPU_DIS_STORE15R @@ -1859,6 +1874,7 @@ static void gpu_opcode_store_r15_ri(void) #endif } + static void gpu_opcode_nop(void) { #ifdef GPU_DIS_NOP @@ -1867,6 +1883,7 @@ static void gpu_opcode_nop(void) #endif } + static void gpu_opcode_pack(void) { #ifdef GPU_DIS_PACK @@ -1886,6 +1903,7 @@ static void gpu_opcode_pack(void) #endif } + static void gpu_opcode_storeb(void) { #ifdef GPU_DIS_STOREB @@ -1900,6 +1918,7 @@ static void gpu_opcode_storeb(void) JaguarWriteByte(RM, RN, GPU); } + static void gpu_opcode_storew(void) { #ifdef GPU_DIS_STOREW @@ -1919,6 +1938,7 @@ static void gpu_opcode_storew(void) #endif } + static void gpu_opcode_store(void) { #ifdef GPU_DIS_STORE @@ -1935,6 +1955,7 @@ static void gpu_opcode_store(void) #endif } + static void gpu_opcode_storep(void) { #ifdef GPU_CORRECT_ALIGNMENT @@ -1970,6 +1991,7 @@ static void gpu_opcode_loadb(void) #endif } + static void gpu_opcode_loadw(void) { #ifdef GPU_DIS_LOADW @@ -1993,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... @@ -2036,6 +2059,7 @@ static void gpu_opcode_load(void) #endif } + static void gpu_opcode_loadp(void) { #ifdef GPU_CORRECT_ALIGNMENT @@ -2055,6 +2079,7 @@ static void gpu_opcode_loadp(void) #endif } + static void gpu_opcode_load_r14_indexed(void) { #ifdef GPU_DIS_LOAD14I @@ -2077,6 +2102,7 @@ static void gpu_opcode_load_r14_indexed(void) #endif } + static void gpu_opcode_load_r15_indexed(void) { #ifdef GPU_DIS_LOAD15I @@ -2099,6 +2125,7 @@ static void gpu_opcode_load_r15_indexed(void) #endif } + static void gpu_opcode_movei(void) { #ifdef GPU_DIS_MOVEI @@ -2114,6 +2141,7 @@ static void gpu_opcode_movei(void) #endif } + static void gpu_opcode_moveta(void) { #ifdef GPU_DIS_MOVETA @@ -2127,6 +2155,7 @@ static void gpu_opcode_moveta(void) #endif } + static void gpu_opcode_movefa(void) { #ifdef GPU_DIS_MOVEFA @@ -2140,6 +2169,7 @@ static void gpu_opcode_movefa(void) #endif } + static void gpu_opcode_move(void) { #ifdef GPU_DIS_MOVE @@ -2153,6 +2183,7 @@ static void gpu_opcode_move(void) #endif } + static void gpu_opcode_moveq(void) { #ifdef GPU_DIS_MOVEQ @@ -2166,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 @@ -2185,6 +2218,7 @@ static void gpu_opcode_imult(void) #endif } + static void gpu_opcode_mult(void) { #ifdef GPU_DIS_MULT @@ -2200,6 +2234,7 @@ static void gpu_opcode_mult(void) #endif } + static void gpu_opcode_bclr(void) { #ifdef GPU_DIS_BCLR @@ -2215,6 +2250,7 @@ static void gpu_opcode_bclr(void) #endif } + static void gpu_opcode_btst(void) { #ifdef GPU_DIS_BTST @@ -2228,6 +2264,7 @@ static void gpu_opcode_btst(void) #endif } + static void gpu_opcode_bset(void) { #ifdef GPU_DIS_BSET @@ -2243,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; @@ -2256,6 +2295,7 @@ static void gpu_opcode_mtoi(void) SET_ZN(res); } + static void gpu_opcode_normi(void) { uint32_t _RM = RM; @@ -2320,6 +2360,7 @@ static void gpu_opcode_mmult(void) SET_ZN(res); } + static void gpu_opcode_abs(void) { #ifdef GPU_DIS_ABS @@ -2342,6 +2383,7 @@ static void gpu_opcode_abs(void) #endif } + static void gpu_opcode_div(void) // RN / RM { #ifdef GPU_DIS_DIV @@ -2386,6 +2428,7 @@ static void gpu_opcode_div(void) // RN / RM #endif } + static void gpu_opcode_imultn(void) { uint32_t res = (int32_t)((int16_t)RN * (int16_t)RM); @@ -2394,6 +2437,7 @@ static void gpu_opcode_imultn(void) SET_FLAG_N(res); } + static void gpu_opcode_neg(void) { #ifdef GPU_DIS_NEG @@ -2409,6 +2453,7 @@ static void gpu_opcode_neg(void) #endif } + static void gpu_opcode_shlq(void) { #ifdef GPU_DIS_SHLQ @@ -2427,6 +2472,7 @@ static void gpu_opcode_shlq(void) #endif } + static void gpu_opcode_shrq(void) { #ifdef GPU_DIS_SHRQ @@ -2443,6 +2489,7 @@ static void gpu_opcode_shrq(void) #endif } + static void gpu_opcode_ror(void) { #ifdef GPU_DIS_ROR @@ -2459,6 +2506,7 @@ static void gpu_opcode_ror(void) #endif } + static void gpu_opcode_rorq(void) { #ifdef GPU_DIS_RORQ @@ -2476,6 +2524,7 @@ static void gpu_opcode_rorq(void) #endif } + static void gpu_opcode_sha(void) { /* int dreg = jaguar.op & 31; @@ -2550,6 +2599,7 @@ static void gpu_opcode_sha(void) SET_FLAG_N(_RN);*/ } + static void gpu_opcode_sharq(void) { #ifdef GPU_DIS_SHARQ @@ -2565,6 +2615,7 @@ static void gpu_opcode_sharq(void) #endif } + static void gpu_opcode_sh(void) { #ifdef GPU_DIS_SH @@ -2588,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) @@ -2601,3 +2654,4 @@ int GPUCore(void * data) } #endif + diff --git a/src/gui/controllertab.cpp b/src/gui/controllertab.cpp index b9145f6..bc8274f 100644 --- a/src/gui/controllertab.cpp +++ b/src/gui/controllertab.cpp @@ -28,15 +28,12 @@ ControllerTab::ControllerTab(QWidget * parent/*= 0*/): QWidget(parent), label3(new QLabel(tr("Maps to:"))), deviceList(new QComboBox(this)), mapNameList(new QComboBox(this)), - controller1(new QCheckBox(tr("Jaguar Controller #1"))), - controller2(new QCheckBox(tr("Jaguar Controller #2"))), + mapToList(new QComboBox(this)), addMapName(new QPushButton(tr("+"))), deleteMapName(new QPushButton(tr("-"))), redefineAll(new QPushButton(tr("Define All Inputs"))), controllerWidget(new ControllerWidget(this)) { -// mapNameList->setEditable(true); - QVBoxLayout * layout = new QVBoxLayout; QHBoxLayout * top = new QHBoxLayout; QVBoxLayout * left = new QVBoxLayout; @@ -48,17 +45,14 @@ ControllerTab::ControllerTab(QWidget * parent/*= 0*/): QWidget(parent), left->addWidget(label1, 0, Qt::AlignRight); left->addWidget(label2, 0, Qt::AlignRight); left->addWidget(label3, 0, Qt::AlignRight); - left->addWidget(new QLabel); right->addWidget(deviceList); right->addLayout(middle); middle->addWidget(mapNameList, 1); middle->addWidget(addMapName, 0); middle->addWidget(deleteMapName, 0); -// right->addWidget(mapNameList); - right->addWidget(controller1); - right->addWidget(controller2); + right->addWidget(mapToList); layout->addWidget(controllerWidget); layout->addWidget(redefineAll, 0, Qt::AlignHCenter); setLayout(layout); @@ -67,25 +61,28 @@ ControllerTab::ControllerTab(QWidget * parent/*= 0*/): QWidget(parent), setFixedWidth(sizeHint().width()); connect(redefineAll, SIGNAL(clicked()), this, SLOT(DefineAllKeys())); - connect(deviceList, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeDevice(int))); - connect(mapNameList, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeMapName(int))); + connect(deviceList, SIGNAL(activaed(int)), this, SLOT(ChangeDevice(int))); + connect(mapNameList, SIGNAL(activated(int)), this, SLOT(ChangeMapName(int))); connect(addMapName, SIGNAL(clicked()), this, SLOT(AddMapName())); connect(deleteMapName, SIGNAL(clicked()), this, SLOT(DeleteMapName())); connect(controllerWidget, SIGNAL(KeyDefined(int, uint32_t)), this, SLOT(UpdateProfileKeys(int, uint32_t))); - connect(controller1, SIGNAL(clicked()), this, SLOT(UpdateProfileConnections())); - connect(controller2, SIGNAL(clicked()), this, SLOT(UpdateProfileConnections())); + connect(mapToList, SIGNAL(activated(int)), this, SLOT(UpdateProfileConnections(int))); // Set up the device combobox (Keyboard is the default, and always // present) deviceList->addItem(tr("Keyboard"), 0); - // Set up map name combobox (Default is default, and always present) -// mapNameList->addItem(tr("Default")); for(int i=0; iaddItem(Gamepad::GetJoystickName(i), deviceNum); } + + // Set up "Map To" combobox + mapToList->addItem(tr("None"), 0); + mapToList->addItem(tr("Controller #1"), CONTROLLER1); + mapToList->addItem(tr("Controller #2"), CONTROLLER2); + mapToList->addItem(tr("Either one that's free"), CONTROLLER1 | CONTROLLER2); } /* So now we come to implementation. When changing devices, could have a helper function @@ -118,6 +115,10 @@ limit of profiles (MAX_PROFILES). Now the main window passes in/removes the last edited profile #. From here, when starting up, we need to pull that number from the profile store and populate all our boxes. + +------------------------------- + +Need to do AutoConnectProfiles from here, and detect any conflicts */ @@ -128,14 +129,31 @@ ControllerTab::~ControllerTab() void ControllerTab::SetupLastUsedProfile(void) { - int deviceNum = deviceList->findData(profile[profileNum].device); - int mapNum = mapNameList->findText(profile[profileNum].mapName); + int deviceNumIndex = deviceList->findData(profile[profileNum].device); + int mapNumIndex = mapNameList->findText(profile[profileNum].mapName); - if (deviceNum == -1 || mapNum == -1) - return; + if (deviceNumIndex == -1 || mapNumIndex == -1) + { + // We're doing the default, so set it up... +// mapToList->setCurrentIndex(mapToList->findData(profile[0].preferredController)); +//printf("ControllerTab::SetupLastUsedProfile: [FAILED] profileNum=%i, controllerIndex=%i, preferredController=%i\n", profileNum, controllerIndex, profile[0].preferredController); +// return; + deviceNumIndex = 0; + mapNumIndex = 0; + profileNum = 0; + } - ChangeDevice(deviceNum); - ChangeMapName(mapNum); + deviceList->setCurrentIndex(deviceNumIndex); + mapNameList->setCurrentIndex(mapNumIndex); +//no more: #warning "!!! bug in here where it doesn't save your preferred controller !!!" + + int controllerIndex = mapToList->findData(profile[profileNum].preferredController); + mapToList->setCurrentIndex(controllerIndex); +//printf("ControllerTab::SetupLastUsedProfile: profileNum=%i, controllerIndex=%i, preferredController=%i\n", profileNum, controllerIndex, profile[profileNum].preferredController); + + // We have to do this manually, since it's no longer done automagically... + ChangeDevice(deviceNumIndex); + ChangeMapName(mapNumIndex); } @@ -170,14 +188,17 @@ void ControllerTab::UpdateProfileKeys(int mapPosition, uint32_t key) } -void ControllerTab::UpdateProfileConnections(void) +void ControllerTab::UpdateProfileConnections(int selection) { - profile[profileNum].preferredController = (controller1->isChecked() ? CONTROLLER1 : 0) | (controller2->isChecked() ? CONTROLLER2 : 0); +// profile[profileNum].preferredController = (controller1->isChecked() ? CONTROLLER1 : 0) | (controller2->isChecked() ? CONTROLLER2 : 0); + profile[profileNum].preferredController = mapToList->itemData(selection).toInt(); +//printf("Setting profile #%i 'Maps To' to %i...\n", profileNum, mapToList->itemData(selection).toInt()); } void ControllerTab::ChangeDevice(int selection) { +//printf("ControllerTab::ChangeDevice\n"); int deviceNum = deviceList->itemData(selection).toInt(); mapNameList->clear(); int numberOfMappings = FindMappingsForDevice(deviceNum, mapNameList); @@ -188,6 +209,7 @@ void ControllerTab::ChangeDevice(int selection) void ControllerTab::ChangeMapName(int selection) { +//printf("ControllerTab::ChangeMapName\n"); profileNum = mapNameList->itemData(selection).toInt(); //printf("You selected mapping: %s (profile #%u)\n", (mapNameList->itemText(selection)).toAscii().data(), profileNum); @@ -195,20 +217,69 @@ void ControllerTab::ChangeMapName(int selection) controllerWidget->keys[i] = profile[profileNum].map[i]; controllerWidget->update(); - controller1->setChecked(profile[profileNum].preferredController & CONTROLLER1); - controller2->setChecked(profile[profileNum].preferredController & CONTROLLER2); +// controller1->setChecked(profile[profileNum].preferredController & CONTROLLER1); +// controller2->setChecked(profile[profileNum].preferredController & CONTROLLER2); + mapToList->setCurrentIndex(mapToList->findData(profile[profileNum].preferredController)); } void ControllerTab::AddMapName(void) { -printf("Add new mapping (TODO)...\n"); + int freeProfile = GetFreeProfile(); + + if (freeProfile == -1) + { + // Oh crap, we're out of room! Alert the media! + // (Really, tho, we should pop this up *before* asking for user input. + // Which we now do!) +#if 0 + QMessageBox msg; + msg.setText(QString(tr("Can't create any more profiles!"))); + msg.setIcon(QMessageBox::Warning); + msg.exec(); +#else + QMessageBox::warning(this, tr("Houston, we have a problem..."), tr("Can't create any more profiles!")); +#endif + + return; + } + + QString text = QInputDialog::getText(this, tr("Add Map Name"), tr("Map name:"), QLineEdit::Normal); + + if (text.isEmpty()) + return; + + // Add mapping... + profileNum = freeProfile; + profile[profileNum].device = deviceList->itemData(deviceList->currentIndex()).toInt(); + strncpy(profile[profileNum].mapName, text.toAscii().data(), 31); + profile[profileNum].mapName[31] = 0; + profile[profileNum].preferredController = CONTROLLER1; + + for(int i=BUTTON_FIRST; iaddItem(text, profileNum); + mapNameList->setCurrentIndex(mapNameList->count() - 1); } void ControllerTab::DeleteMapName(void) { -printf("Delete current mapping (TODO)...\n"); +//printf("Delete current mapping (TODO)...\n"); + + // hmm, don't need to check this... Because presumably, it's already been checked for. +// if (mapNameList->count() == 1) ; + + QMessageBox::StandardButton retVal = QMessageBox::question(this, tr("Remove Mapping"), tr("Are you sure you want to remove this mapping?"), QMessageBox::No | QMessageBox::Yes, QMessageBox::No); + + if (retVal == QMessageBox::No) + return; + + int index = mapNameList->currentIndex(); + int profileToRemove = profileNum; + mapNameList->removeItem(index); + DeleteProfile(profileToRemove); } diff --git a/src/gui/controllertab.h b/src/gui/controllertab.h index d0749d2..c72507d 100644 --- a/src/gui/controllertab.h +++ b/src/gui/controllertab.h @@ -19,7 +19,7 @@ class ControllerTab: public QWidget protected slots: void DefineAllKeys(void); void UpdateProfileKeys(int, uint32_t); - void UpdateProfileConnections(void); + void UpdateProfileConnections(int); void ChangeDevice(int); void ChangeMapName(int); void AddMapName(void); @@ -31,6 +31,7 @@ class ControllerTab: public QWidget QLabel * label3; QComboBox * deviceList; QComboBox * mapNameList; + QComboBox * mapToList; QCheckBox * controller1; QCheckBox * controller2; QPushButton * addMapName; diff --git a/src/gui/profile.cpp b/src/gui/profile.cpp index 05d173d..71e6946 100644 --- a/src/gui/profile.cpp +++ b/src/gui/profile.cpp @@ -15,6 +15,7 @@ #include "profile.h" #include #include "gamepad.h" +#include "log.h" #include "settings.h" @@ -36,6 +37,10 @@ uint32_t defaultMap[21] = { '3', 'L', 'K', 'J', 'O', 'P' }; +// Function Prototypes +int ConnectProfileToDevice(int deviceNum); +int FindProfileForDevice(int deviceNum, int preferred, int * found); + void ReadProfiles(QSettings * set) { @@ -131,6 +136,37 @@ void WriteProfiles(QSettings * set) } +int GetFreeProfile(void) +{ + // Check for too many, return -1 if so + if (numberOfProfiles == MAX_PROFILES) + return -1; + + int profileNum = numberOfProfiles; + numberOfProfiles++; + return profileNum; +} + + +void DeleteProfile(int profileToDelete) +{ + // Sanity check + if (profileToDelete >= numberOfProfiles) + return; + + // Trivial case: Profile at end of the array + if (profileToDelete == (numberOfProfiles - 1)) + { + numberOfProfiles--; + return; + } + +// memmove(dest, src, bytesToMove); + memmove(&profile[profileToDelete], &profile[profileToDelete + 1], ((numberOfProfiles - 1) - profileToDelete) * sizeof(Profile)); + numberOfProfiles--; +} + + int FindDeviceNumberForName(const char * name) { for(int i=0; iaddItem(QString("Keyboard::%1").arg(profile[j].mapName), j); + found++; + } + } + + // Check for connected host devices next + for(int i=0; iaddItem(QString("%1::%2").arg(Gamepad::GetJoystickName(i)).arg(profile[j].mapName), j); + found++; + } + } + } + + return found; +} + + bool ConnectProfileToController(int profileNum, int controllerNum) { if (profile[profileNum].device == -1) @@ -200,7 +271,7 @@ bool ConnectProfileToController(int profileNum, int controllerNum) for(int i=0; i<21; i++) dest[i] = profile[profileNum].map[i]; -printf("Successfully mapped device '%s' (%s) to controller #%u...\n", deviceNames[profile[profileNum].device], profile[profileNum].mapName, controllerNum); + WriteLog("PROFILE: Successfully mapped device '%s' (%s) to controller #%u...\n", deviceNames[profile[profileNum].device], profile[profileNum].mapName, controllerNum); return true; } @@ -215,6 +286,13 @@ printf("Successfully mapped device '%s' (%s) to controller #%u...\n", deviceName // should be ATM... :-P // /* +Here's the rules: If preferred Jaguar controller is not checked, the profile is +skipped. If one or the other is checked, it's put into that slot. If *both* are +checked, it will take over any slot that isn't claimed by another gamepad. If +there are ties, present it to the user *once* and ask them which gamepad should +be #1; don't ask again unless a), they change the profiles and b), the +situation warrants it. + Also, there is a problem with this approach and having multiple devices that are the same. Currently, if two of the same device are plugged in and the profile is set to both controllers, it will broadcast buttons @@ -234,51 +312,94 @@ different, but we still run into problems with the handling in the MainWin because it's hardwired to take pad 0 in slot 0 and pad 1 in slot 1. If you have them configured other than this, you won't get anything. So we need to also map the physical devices to their respective slots. + + +Steps: + +1) Make a list of all devices attached to the system. + +2) Make a list of all profiles belonging to those devices, as long as they have + one or more Jaguar controllers that are "mapped to". + +3) See if there are any conflicts. If there are, see if the user has already + been asked to resolve and chosen a resolution; otherwise, ask the user to + resolve. + + a) Loop through all found profiles. If they are set to a single controller, + set it in the appropriate list (one list for controller 1, another for + controller 2). + + b) Loop through all found profiles. If they are set to both controllers, + ... (first stab at it:) + Check for list #1. If nothing there, assign it to list #1. + Else, check for List #2. If nothing there, assign to list #2. + [But the wording of it implies that it will assign it to both. + Does that mean we should make another combobox will all the possible + combinations laid out? Probably. Not many people will understand that + checking both means "assign to either one that's free".] + +4) Connect profiles to controllers, and set gamepad slots (for the MainWin + handler). + */ void AutoConnectProfiles(void) { + int foundProfiles[MAX_PROFILES]; int controller1Profile = -1; int controller2Profile = -1; - // Nothing plugged in, we fall back to the default keyboard device profiles -// if (Gamepad::numJoysticks == 0) + // Check for Keyboard device profiles first, if anything else is plugged in + // it will default to it instead. +#if 0 + for(int i=0; i> 4) & 0x0F; - -// This is bad--we're assuming that a bit is set in the last case. Might not be so! -// NOTE: values $7, B, D, & E are only legal ones for pad 0, (rows 3 to 0, in both cases) -// $E, D, B, & 7 are only legal ones for pad 1 -// So the following code is WRONG! (now fixed! ;-) -// Also: we should explicitly check for those bit patterns, as other patterns -// are legal and yield other controllers... !!! FIX !!! -#warning "!!! Need to explicitly check for the proper bit combinations! !!!" - - if (!(pad0Index & 0x01)) - pad0Index = 0; - else if (!(pad0Index & 0x02)) - pad0Index = 1; - else if (!(pad0Index & 0x04)) - pad0Index = 2; - else if (!(pad0Index & 0x08)) - pad0Index = 3; - - if (!(pad1Index & 0x01)) - pad1Index = 3; - else if (!(pad1Index & 0x02)) - pad1Index = 2; - else if (!(pad1Index & 0x04)) - pad1Index = 1; - else if (!(pad1Index & 0x08)) - pad1Index = 0; - - if (joypad0Buttons[(pad0Index << 2) + 0]) data |= 0x01; - if (joypad0Buttons[(pad0Index << 2) + 1]) data |= 0x02; - if (joypad0Buttons[(pad0Index << 2) + 2]) data |= 0x04; - if (joypad0Buttons[(pad0Index << 2) + 3]) data |= 0x08; - if (joypad1Buttons[(pad1Index << 2) + 0]) data |= 0x10; - if (joypad1Buttons[(pad1Index << 2) + 1]) data |= 0x20; - if (joypad1Buttons[(pad1Index << 2) + 2]) data |= 0x40; - if (joypad1Buttons[(pad1Index << 2) + 3]) data |= 0x80; - - return ~data; -#else if (!joysticksEnabled) return 0xFFFF; @@ -147,7 +104,7 @@ uint16_t JoystickReadWord(uint32_t offset) if (offset0 != 0xFF) { uint16_t mask[4] = { 0xFEFF, 0xFDFF, 0xFBFF, 0xF7FF }; -// uint16_t mask[4] = { 0xFFFE, 0xFFFD, 0xFFFB, 0xFFF7 }; +//No! uint16_t mask[4] = { 0xFFFE, 0xFFFD, 0xFFFB, 0xFFF7 }; for(uint8_t i=0; i<4; i++) data &= (joypad0Buttons[offset0 + i] ? mask[i] : 0xFFFF); @@ -156,16 +113,14 @@ uint16_t JoystickReadWord(uint32_t offset) if (offset1 != 0xFF) { uint16_t mask[4] = { 0xEFFF, 0xDFFF, 0xBFFF, 0x7FFF }; -// uint16_t mask[4] = { 0xFFEF, 0xFFDF, 0xFFBF, 0xFF7F }; +//No! uint16_t mask[4] = { 0xFFEF, 0xFFDF, 0xFFBF, 0xFF7F }; for(uint8_t i=0; i<4; i++) data &= (joypad1Buttons[offset1 + i] ? mask[i] : 0xFFFF); } return data; -#endif } -// else if (offset == 3) else if (offset == 2) { // Hardware ID returns NTSC/PAL identification bit here @@ -173,59 +128,7 @@ uint16_t JoystickReadWord(uint32_t offset) if (!joysticksEnabled) return data; -#if 0 - int pad0Index = joystick_ram[1] & 0x0F; - int pad1Index = (joystick_ram[1] >> 4) & 0x0F; - -//This is more stuff to add to the button reading, as the preceeding only -//yields 16 buttons... -#warning "!!! This reports TeamTap incorrectly when PAUSE pressed on controller #1 or #2 !!!" - if (!(pad0Index & 0x01)) - { - if (joypad0Buttons[BUTTON_PAUSE]) - data ^= 0x01; - if (joypad0Buttons[BUTTON_A]) - data ^= 0x02; - } - else if (!(pad0Index & 0x02)) - { - if (joypad0Buttons[BUTTON_B]) - data ^= 0x02; - } - else if (!(pad0Index & 0x04)) - { - if (joypad0Buttons[BUTTON_C]) - data ^= 0x02; - } - else if (!(pad0Index & 0x08)) - { - if (joypad0Buttons[BUTTON_OPTION]) - data ^= 0x02; - } - if (!(pad1Index & 0x08)) - { - if (joypad1Buttons[BUTTON_PAUSE]) - data ^= 0x04; - if (joypad1Buttons[BUTTON_A]) - data ^= 0x08; - } - else if (!(pad1Index & 0x04)) - { - if (joypad1Buttons[BUTTON_B]) - data ^= 0x08; - } - else if (!(pad1Index & 0x02)) - { - if (joypad1Buttons[BUTTON_C]) - data ^= 0x08; - } - else if (!(pad1Index & 0x01)) - { - if (joypad1Buttons[BUTTON_OPTION]) - data ^= 0x08; - } -#else // Joystick data returns active low for buttons pressed, high for non- // pressed. uint8_t offset0 = joypad0Offset[joystick_ram[1] & 0x0F] / 4; @@ -248,32 +151,14 @@ uint16_t JoystickReadWord(uint32_t offset) if (mask[offset1][1] != -1) data &= (joypad1Buttons[mask[offset1][1]] ? 0xFFFB : 0xFFFF); } -#endif return data; } -// return joystick_ram[offset]; return 0xFFFF; } -#if 0 -uint16_t JoystickReadWord(uint32_t offset) -{ - return ((uint16_t)JoystickReadByte((offset + 0) & 0x03) << 8) | JoystickReadByte((offset + 1) & 0x03); -} -#endif - - -#if 0 -void JoystickWriteByte(uint32_t offset, uint8_t data) -{ - joystick_ram[offset & 0x03] = data; -} -#endif - - void JoystickWriteWord(uint32_t offset, uint16_t data) { #warning "No bounds checking done for JoystickWriteWord!"