X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdsp.cpp;h=e255cdef6ba64f4104a6e4b8655ffbcf4f2a9213;hb=0d7e70c5e34e691b15365901951700f43242065f;hp=748c4ab01750a4f1c4a2bf509fe1a957fc701a1a;hpb=7228359373eb7602c26f7b098d6b2271ff5727a1;p=virtualjaguar diff --git a/src/dsp.cpp b/src/dsp.cpp index 748c4ab..e255cde 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -457,12 +457,14 @@ void dsp_reset_stats(void) dsp_opcode_use[i] = 0; } + void DSPReleaseTimeslice(void) { //This does absolutely nothing!!! !!! FIX !!! dsp_releaseTimeSlice_flag = 1; } + void dsp_build_branch_condition_table(void) { // Fill in the mirror table @@ -502,6 +504,7 @@ void dsp_build_branch_condition_table(void) } } + uint8_t DSPReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -522,22 +525,20 @@ uint8_t DSPReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/) { uint32_t data = DSPReadLong(offset & 0xFFFFFFFC, who); - if ((offset&0x03)==0) - return(data>>24); - else - if ((offset&0x03)==1) - return((data>>16)&0xff); - else - if ((offset&0x03)==2) - return((data>>8)&0xff); - else - if ((offset&0x03)==3) - return(data&0xff); + if ((offset & 0x03) == 0) + return (data >> 24); + else if ((offset & 0x03) == 1) + return ((data >> 16) & 0xFF); + else if ((offset & 0x03) == 2) + return ((data >> 8) & 0xFF); + else if ((offset & 0x03) == 3) + return (data & 0xFF); } return JaguarReadByte(offset, who); } + uint16_t DSPReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -565,6 +566,7 @@ uint16_t DSPReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/) return JaguarReadWord(offset, who); } + uint32_t DSPReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -609,12 +611,13 @@ uint32_t DSPReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/) return JaguarReadLong(offset, who); } + void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) WriteLog("DSP: WriteByte--Attempt to write to DSP register file by %s!\n", whoName[who]); - if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE+0x2000)) + if ((offset >= DSP_WORK_RAM_BASE) && (offset < DSP_WORK_RAM_BASE + 0x2000)) { offset -= DSP_WORK_RAM_BASE; dsp_ram_8[offset] = data; @@ -626,7 +629,7 @@ void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) }*/ return; } - if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE+0x20)) + if ((offset >= DSP_CONTROL_RAM_BASE) && (offset < DSP_CONTROL_RAM_BASE + 0x20)) { uint32_t reg = offset & 0x1C; int bytenum = offset & 0x03; @@ -645,9 +648,11 @@ void DSPWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/) } // WriteLog("dsp: writing %.2x at 0x%.8x\n",data,offset); //Should this *ever* happen??? Shouldn't we be saying "unknown" here??? +// Well, yes, it can. There are 3 MMU users after all: 68K, GPU & DSP...! JaguarWriteByte(offset, data, who); } + void DSPWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/) { if (offset >= 0xF1A000 && offset <= 0xF1A0FF) @@ -709,6 +714,7 @@ SET16(ram2, offset, data); JaguarWriteWord(offset, data, who); } + //bool badWrite = false; void DSPWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/) { @@ -889,6 +895,7 @@ WriteLog("DSP: Modulo data %08X written by %s.\n", data, whoName[who]); JaguarWriteLong(offset, data, who); } + // // Update the DSP register file pointers depending on REGPAGE bit // @@ -909,6 +916,7 @@ void DSPUpdateRegisterBanks(void) #endif } + // // Check for and handle any asserted DSP IRQs // @@ -1054,6 +1062,7 @@ ctrl2[0] = regs2[30] = dsp_pc; FlushDSPPipeline(); } + // // Non-pipelined version... // @@ -1159,6 +1168,7 @@ ctrl1[0] = regs1[30] = dsp_pc; //!!!!!!!! } + // // Set the specified DSP IRQ line to a given state // @@ -1193,11 +1203,13 @@ DSPHandleIRQsNP(); // GPUSetIRQLine(GPUIRQ_DSP, ASSERT_LINE); } + bool DSPIsRunning(void) { return (DSP_RUNNING ? true : false); } + void DSPInit(void) { // memory_malloc_secure((void **)&dsp_ram_8, 0x2000, "DSP work RAM"); @@ -1208,6 +1220,7 @@ void DSPInit(void) DSPReset(); } + void DSPReset(void) { dsp_pc = 0x00F1B000; @@ -1238,6 +1251,7 @@ void DSPReset(void) *((uint32_t *)(&dsp_ram_8[i])) = rand(); } + void DSPDumpDisassembly(void) { char buffer[512]; @@ -1253,6 +1267,7 @@ void DSPDumpDisassembly(void) } } + void DSPDumpRegisters(void) { //Shoud add modulus, etc to dump here... @@ -1280,6 +1295,7 @@ void DSPDumpRegisters(void) } } + void DSPDone(void) { int i, j; @@ -1639,6 +1655,7 @@ if ((dsp_pc < 0xF1B000 || dsp_pc > 0xF1CFFE) && !tripwire) dsp_in_exec--; } + // // DSP opcode handlers // @@ -1681,6 +1698,7 @@ const char * condition[32] = #endif } + static void dsp_opcode_jr(void) { #ifdef DSP_DIS_JR @@ -1717,6 +1735,7 @@ const char * condition[32] = #endif } + static void dsp_opcode_add(void) { #ifdef DSP_DIS_ADD @@ -1732,6 +1751,7 @@ static void dsp_opcode_add(void) #endif } + static void dsp_opcode_addc(void) { #ifdef DSP_DIS_ADDC @@ -1750,6 +1770,7 @@ static void dsp_opcode_addc(void) #endif } + static void dsp_opcode_addq(void) { #ifdef DSP_DIS_ADDQ @@ -1766,6 +1787,7 @@ static void dsp_opcode_addq(void) #endif } + static void dsp_opcode_sub(void) { #ifdef DSP_DIS_SUB @@ -1781,22 +1803,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 +1839,7 @@ static void dsp_opcode_subq(void) #endif } + static void dsp_opcode_cmp(void) { #ifdef DSP_DIS_CMP @@ -1827,6 +1854,7 @@ static void dsp_opcode_cmp(void) #endif } + static void dsp_opcode_cmpq(void) { static int32_t sqtable[32] = @@ -1844,6 +1872,7 @@ static void dsp_opcode_cmpq(void) #endif } + static void dsp_opcode_and(void) { #ifdef DSP_DIS_AND @@ -1858,6 +1887,7 @@ static void dsp_opcode_and(void) #endif } + static void dsp_opcode_or(void) { #ifdef DSP_DIS_OR @@ -1872,6 +1902,7 @@ static void dsp_opcode_or(void) #endif } + static void dsp_opcode_xor(void) { #ifdef DSP_DIS_XOR @@ -1886,6 +1917,7 @@ static void dsp_opcode_xor(void) #endif } + static void dsp_opcode_not(void) { #ifdef DSP_DIS_NOT @@ -1900,11 +1932,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 +1952,7 @@ static void dsp_opcode_store_r14_indexed(void) #endif } + static void dsp_opcode_store_r15_indexed(void) { #ifdef DSP_DIS_STORE15I @@ -1931,6 +1966,7 @@ static void dsp_opcode_store_r15_indexed(void) #endif } + static void dsp_opcode_load_r14_ri(void) { #ifdef DSP_DIS_LOAD14R @@ -1948,6 +1984,7 @@ static void dsp_opcode_load_r14_ri(void) #endif } + static void dsp_opcode_load_r15_ri(void) { #ifdef DSP_DIS_LOAD15R @@ -1965,16 +2002,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 +2023,7 @@ static void dsp_opcode_nop(void) #endif } + static void dsp_opcode_storeb(void) { #ifdef DSP_DIS_STOREB @@ -1995,6 +2036,7 @@ static void dsp_opcode_storeb(void) JaguarWriteByte(RM, RN, DSP); } + static void dsp_opcode_storew(void) { #ifdef DSP_DIS_STOREW @@ -2014,6 +2056,7 @@ static void dsp_opcode_storew(void) #endif } + static void dsp_opcode_store(void) { #ifdef DSP_DIS_STORE @@ -2027,6 +2070,7 @@ static void dsp_opcode_store(void) #endif } + static void dsp_opcode_loadb(void) { #ifdef DSP_DIS_LOADB @@ -2043,6 +2087,7 @@ static void dsp_opcode_loadb(void) #endif } + static void dsp_opcode_loadw(void) { #ifdef DSP_DIS_LOADW @@ -2066,6 +2111,7 @@ static void dsp_opcode_loadw(void) #endif } + static void dsp_opcode_load(void) { #ifdef DSP_DIS_LOAD @@ -2083,6 +2129,7 @@ static void dsp_opcode_load(void) #endif } + static void dsp_opcode_load_r14_indexed(void) { #ifdef DSP_DIS_LOAD14I @@ -2100,6 +2147,7 @@ static void dsp_opcode_load_r14_indexed(void) #endif } + static void dsp_opcode_load_r15_indexed(void) { #ifdef DSP_DIS_LOAD15I @@ -2117,6 +2165,7 @@ static void dsp_opcode_load_r15_indexed(void) #endif } + static void dsp_opcode_movei(void) { #ifdef DSP_DIS_MOVEI @@ -2132,6 +2181,7 @@ static void dsp_opcode_movei(void) #endif } + static void dsp_opcode_moveta(void) { #ifdef DSP_DIS_MOVETA @@ -2145,6 +2195,7 @@ static void dsp_opcode_moveta(void) #endif } + static void dsp_opcode_movefa(void) { #ifdef DSP_DIS_MOVEFA @@ -2158,6 +2209,7 @@ static void dsp_opcode_movefa(void) #endif } + static void dsp_opcode_move(void) { #ifdef DSP_DIS_MOVE @@ -2171,6 +2223,7 @@ static void dsp_opcode_move(void) #endif } + static void dsp_opcode_moveq(void) { #ifdef DSP_DIS_MOVEQ @@ -2184,6 +2237,7 @@ static void dsp_opcode_moveq(void) #endif } + static void dsp_opcode_resmac(void) { #ifdef DSP_DIS_RESMAC @@ -2197,6 +2251,7 @@ static void dsp_opcode_resmac(void) #endif } + static void dsp_opcode_imult(void) { #ifdef DSP_DIS_IMULT @@ -2211,6 +2266,7 @@ static void dsp_opcode_imult(void) #endif } + static void dsp_opcode_mult(void) { #ifdef DSP_DIS_MULT @@ -2225,6 +2281,7 @@ static void dsp_opcode_mult(void) #endif } + static void dsp_opcode_bclr(void) { #ifdef DSP_DIS_BCLR @@ -2240,6 +2297,7 @@ static void dsp_opcode_bclr(void) #endif } + static void dsp_opcode_btst(void) { #ifdef DSP_DIS_BTST @@ -2253,6 +2311,7 @@ static void dsp_opcode_btst(void) #endif } + static void dsp_opcode_bset(void) { #ifdef DSP_DIS_BSET @@ -2268,6 +2327,7 @@ static void dsp_opcode_bset(void) #endif } + static void dsp_opcode_subqt(void) { #ifdef DSP_DIS_SUBQT @@ -2281,6 +2341,7 @@ static void dsp_opcode_subqt(void) #endif } + static void dsp_opcode_addqt(void) { #ifdef DSP_DIS_ADDQT @@ -2294,6 +2355,7 @@ static void dsp_opcode_addqt(void) #endif } + static void dsp_opcode_imacn(void) { #ifdef DSP_DIS_IMACN @@ -2309,12 +2371,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 +2401,7 @@ static void dsp_opcode_normi(void) SET_ZN(RN); } + static void dsp_opcode_mmult(void) { int count = dsp_matrix_control&0x0f; @@ -2378,6 +2443,7 @@ static void dsp_opcode_mmult(void) SET_ZN(RN); } + static void dsp_opcode_abs(void) { #ifdef DSP_DIS_ABS @@ -2401,32 +2467,57 @@ static void dsp_opcode_abs(void) #endif } + static void dsp_opcode_div(void) { - uint32_t _Rm=RM; - uint32_t _Rn=RN; - - if (_Rm) +#if 0 + if (RM) { - if (dsp_div_control & 1) + if (dsp_div_control & 0x01) // 16.16 division { - dsp_remain = (((uint64_t)_Rn) << 16) % _Rm; - if (dsp_remain&0x80000000) - dsp_remain-=_Rm; - RN = (((uint64_t)_Rn) << 16) / _Rm; + dsp_remain = ((uint64_t)RN << 16) % RM; + RN = ((uint64_t)RN << 16) / RM; } else { - dsp_remain = _Rn % _Rm; - if (dsp_remain&0x80000000) - dsp_remain-=_Rm; - RN/=_Rm; + // We calculate the remainder first because we destroy RN after + // this by assigning it to itself. + dsp_remain = RN % RM; + RN = RN / RM; } + } else - RN=0xffffffff; + { + // This is what happens according to SCPCD. NYAN! + RN = 0xFFFFFFFF; + dsp_remain = 0; + } +#else + // Real algorithm, courtesy of SCPCD: NYAN! + uint32_t q = RN; + uint32_t r = 0; + + // If 16.16 division, stuff top 16 bits of RN into remainder and put the + // bottom 16 of RN in top 16 of quotient + if (dsp_div_control & 0x01) + q <<= 16, r = RN >> 16; + + for(int i=0; i<32; i++) + { +// uint32_t sign = (r >> 31) & 0x01; + uint32_t sign = r & 0x80000000; + r = (r << 1) | ((q >> 31) & 0x01); + r += (sign ? RM : -RM); + q = (q << 1) | (((~r) >> 31) & 0x01); + } + + RN = q; + dsp_remain = r; +#endif } + static void dsp_opcode_imultn(void) { #ifdef DSP_DIS_IMULTN @@ -2443,6 +2534,7 @@ static void dsp_opcode_imultn(void) #endif } + static void dsp_opcode_neg(void) { #ifdef DSP_DIS_NEG @@ -2458,6 +2550,7 @@ static void dsp_opcode_neg(void) #endif } + static void dsp_opcode_shlq(void) { #ifdef DSP_DIS_SHLQ @@ -2475,6 +2568,7 @@ static void dsp_opcode_shlq(void) #endif } + static void dsp_opcode_shrq(void) { #ifdef DSP_DIS_SHRQ @@ -2491,6 +2585,7 @@ static void dsp_opcode_shrq(void) #endif } + static void dsp_opcode_ror(void) { #ifdef DSP_DIS_ROR @@ -2507,6 +2602,7 @@ static void dsp_opcode_ror(void) #endif } + static void dsp_opcode_rorq(void) { #ifdef DSP_DIS_RORQ @@ -2524,6 +2620,7 @@ static void dsp_opcode_rorq(void) #endif } + static void dsp_opcode_sha(void) { int32_t sRm=(int32_t)RM; @@ -2555,6 +2652,7 @@ static void dsp_opcode_sha(void) SET_ZN(RN); } + static void dsp_opcode_sharq(void) { #ifdef DSP_DIS_SHARQ @@ -2570,6 +2668,7 @@ static void dsp_opcode_sharq(void) #endif } + static void dsp_opcode_sh(void) { int32_t sRm=(int32_t)RM;