]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/dsp.cpp
Changed key grabber to grab controller buttons/axes on button down.
[virtualjaguar] / src / dsp.cpp
index 0218a7d92bbfa2db1f8f49bb58a9971cace38728..e255cdef6ba64f4104a6e4b8655ffbcf4f2a9213 100644 (file)
@@ -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;
@@ -2455,29 +2471,6 @@ static void dsp_opcode_abs(void)
 static void dsp_opcode_div(void)
 {
 #if 0
-       uint32_t _Rm=RM;
-       uint32_t _Rn=RN;
-
-       if (_Rm)
-       {
-               if (dsp_div_control & 1)
-               {
-                       dsp_remain = (((uint64_t)_Rn) << 16) % _Rm;
-                       if (dsp_remain&0x80000000)
-                               dsp_remain-=_Rm;
-                       RN = (((uint64_t)_Rn) << 16) / _Rm;
-               }
-               else
-               {
-                       dsp_remain = _Rn % _Rm;
-                       if (dsp_remain&0x80000000)
-                               dsp_remain-=_Rm;
-                       RN/=_Rm;
-               }
-       }
-       else
-               RN=0xffffffff;
-#else
        if (RM)
        {
                if (dsp_div_control & 0x01)             // 16.16 division
@@ -2493,15 +2486,34 @@ static void dsp_opcode_div(void)
                        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
+       {
+               // 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
 }