]> Shamusworld >> Repos - virtualjaguar/blobdiff - src/dsp.cpp
Initial fixes for audio subsystem. Fragile; may break in unexpected ways.
[virtualjaguar] / src / dsp.cpp
index 1034f3c27ccafb45cb1b59e6f018c7f107c39356..74839cc4b7eee9b6708d02c8e56a5573ca724ad2 100644 (file)
@@ -3,10 +3,10 @@
 //
 // Originally by David Raingeard
 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
-// Extensive cleanups/rewrites by James L. Hammons
+// Extensive cleanups/rewrites by James Hammons
 // (C) 2010 Underground Software
 //
-// JLH = James L. Hammons <jlhamm@acm.org>
+// JLH = James Hammons <jlhamm@acm.org>
 //
 // Who  When        What
 // ---  ----------  -------------------------------------------------------------
@@ -18,6 +18,7 @@
 
 #include <SDL.h>                                                               // Used only for SDL_GetTicks...
 #include <stdlib.h>
+#include "dac.h"
 #include "gpu.h"
 #include "jagdasm.h"
 #include "jaguar.h"
@@ -29,6 +30,7 @@
 
 // Seems alignment in loads & stores was off...
 #define DSP_CORRECT_ALIGNMENT
+//#define DSP_CORRECT_ALIGNMENT_STORE
 
 //#define DSP_DEBUG
 //#define DSP_DEBUG_IRQ
@@ -664,7 +666,7 @@ void DSPWriteByte(uint32 offset, uint8 data, uint32 who/*=UNKNOWN*/)
 /*             if (dsp_in_exec == 0)
                {
                        m68k_end_timeslice();
-                       gpu_releaseTimeslice();
+                       dsp_releaseTimeslice();
                }*/
                return;
        }
@@ -714,7 +716,7 @@ void DSPWriteWord(uint32 offset, uint16 data, uint32 who/*=UNKNOWN*/)
                {
 //                     WriteLog("dsp: writing %.4x at 0x%.8x\n",data,offset+DSP_WORK_RAM_BASE);
                        m68k_end_timeslice();
-                       gpu_releaseTimeslice();
+                       dsp_releaseTimeslice();
                }*/
 //CC only!
 #ifdef DSP_DEBUG_CC
@@ -795,6 +797,28 @@ SET32(ram2, offset, data);
                        DSPUpdateRegisterBanks();
                        dsp_control &= ~((dsp_flags & CINT04FLAGS) >> 3);
                        dsp_control &= ~((dsp_flags & CINT5FLAG) >> 1);
+
+// NB: This is just a wild hairy-assed guess as to what the playback frequency is.
+//     It can be timed to anything really, anything that writes to L/RTXD at a regular
+//     interval. Most things seem to use either the I2S interrupt or the TIMER 0
+//     interrupt, so that's what we check for here. Just know that this approach
+//     can be easily fooled!
+//     Note also that if both interrupts are enabled, the I2S freq will win. :-P
+                       if (data & INT_ENA1) // I2S interrupt
+                       {
+                               int freq = GetCalculatedFrequency();
+//This happens too often to be useful...
+//                             WriteLog("DSP: Setting audio freqency to %u Hz...\n", freq);
+                               DACSetNewFrequency(freq);
+                       }
+                       else if (data & INT_ENA2) // TIMER 0 interrupt
+                       {
+                               int freq = JERRYGetPIT1Frequency();
+//This happens too often to be useful...
+//                             WriteLog("DSP: Setting audio freqency to %u Hz...\n", freq);
+                               DACSetNewFrequency(freq);
+                       }
+
 /*                     if (IMASKCleared)                                               // If IMASK was cleared,
 #ifdef DSP_DEBUG_IRQ
                        {
@@ -883,7 +907,7 @@ WriteLog("Write to DSP CTRL by %s: %08X\n", whoName[who], data);
                                WriteLog("DSP: CPU -> DSP interrupt\n");
 #endif
                                m68k_end_timeslice();
-                               GPUReleaseTimeslice();
+                               DSPReleaseTimeslice();
                                DSPSetIRQLine(DSPIRQ_CPU, ASSERT_LINE);
                                data &= ~DSPINT0;
                        }
@@ -923,14 +947,14 @@ else
        WriteLog(" --> Stopped by %s! (DSP PC: %08X)", whoName[who], dsp_pc);
 WriteLog("\n");
 #endif // DSP_DEBUG
-//This isn't exactly right either--we don't know if it was the M68K or the GPU writing here...
+//This isn't exactly right either--we don't know if it was the M68K or the DSP writing here...
 // !!! FIX !!! [DONE]
                        if (DSP_RUNNING)
                        {
                                if (who == M68K)
                                        m68k_end_timeslice();
-                               else if (who == GPU)
-                                       GPUReleaseTimeslice();
+                               else if (who == DSP)
+                                       DSPReleaseTimeslice();
 
                                if (!wasRunning)
                                        FlushDSPPipeline();
@@ -1332,7 +1356,10 @@ void DSPDone(void)
        // get the interrupt mask
        int mask = ((dsp_flags >> 11) & 0x20) | ((dsp_flags >> 4) & 0x1F);
 
-       WriteLog("DSP: pending=%08X enabled=%08X\n", bits, mask);
+       WriteLog("DSP: pending=$%X enabled=$%X (%s%s%s%s%s%s)\n", bits, mask,
+               (mask & 0x01 ? "CPU " : ""), (mask & 0x02 ? "I2S " : ""),
+               (mask & 0x04 ? "Timer0 " : ""), (mask & 0x08 ? "Timer1 " : ""),
+               (mask & 0x10 ? "Ext0 " : ""), (mask & 0x20 ? "Ext1" : ""));
        WriteLog("\nRegisters bank 0\n");
        for(int j=0; j<8; j++)
        {
@@ -1955,7 +1982,7 @@ static void dsp_opcode_store_r14_indexed(void)
        if (doDSPDis)
                WriteLog("%06X: STORE  R%02u, (R14+$%02X) [NCZ:%u%u%u, R%02u=%08X, R14+$%02X=%08X]\n", dsp_pc-2, IMM_2, dsp_convert_zero[IMM_1] << 2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN, dsp_convert_zero[IMM_1] << 2, dsp_reg[14]+(dsp_convert_zero[IMM_1] << 2));
 #endif
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        DSPWriteLong((dsp_reg[14] & 0xFFFFFFFC) + (dsp_convert_zero[IMM_1] << 2), RN, DSP);
 #else
        DSPWriteLong(dsp_reg[14] + (dsp_convert_zero[IMM_1] << 2), RN, DSP);
@@ -1968,7 +1995,7 @@ static void dsp_opcode_store_r15_indexed(void)
        if (doDSPDis)
                WriteLog("%06X: STORE  R%02u, (R15+$%02X) [NCZ:%u%u%u, R%02u=%08X, R15+$%02X=%08X]\n", dsp_pc-2, IMM_2, dsp_convert_zero[IMM_1] << 2, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN, dsp_convert_zero[IMM_1] << 2, dsp_reg[15]+(dsp_convert_zero[IMM_1] << 2));
 #endif
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        DSPWriteLong((dsp_reg[15] & 0xFFFFFFFC) + (dsp_convert_zero[IMM_1] << 2), RN, DSP);
 #else
        DSPWriteLong(dsp_reg[15] + (dsp_convert_zero[IMM_1] << 2), RN, DSP);
@@ -2045,7 +2072,7 @@ static void dsp_opcode_storew(void)
        if (doDSPDis)
                WriteLog("%06X: STOREW R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", dsp_pc-2, IMM_2, IMM_1, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN, IMM_1, RM);
 #endif
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF))
                DSPWriteLong(RM & 0xFFFFFFFE, RN & 0xFFFF, DSP);
        else
@@ -2064,7 +2091,7 @@ static void dsp_opcode_store(void)
        if (doDSPDis)
                WriteLog("%06X: STORE  R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", dsp_pc-2, IMM_2, IMM_1, dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN, IMM_1, RM);
 #endif
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        DSPWriteLong(RM & 0xFFFFFFFC, RN, DSP);
 #else
        DSPWriteLong(RM, RN, DSP);
@@ -2384,7 +2411,7 @@ static void dsp_opcode_normi(void)
 static void dsp_opcode_mmult(void)
 {
        int count       = dsp_matrix_control&0x0f;
-       uint32 addr = dsp_pointer_to_matrix; // in the gpu ram
+       uint32 addr = dsp_pointer_to_matrix; // in the dsp ram
        int64 accum = 0;
        uint32 res;
 
@@ -4106,7 +4133,7 @@ static void DSP_mirror(void)
 static void DSP_mmult(void)
 {
        int count       = dsp_matrix_control&0x0f;
-       uint32 addr = dsp_pointer_to_matrix; // in the gpu ram
+       uint32 addr = dsp_pointer_to_matrix; // in the dsp ram
        int64 accum = 0;
        uint32 res;
 
@@ -4527,7 +4554,7 @@ static void DSP_store(void)
 #endif
 //     DSPWriteLong(PRM, PRN, DSP);
 //     NO_WRITEBACK;
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        pipeline[plPtrExec].address = PRM & 0xFFFFFFFC;
 #else
        pipeline[plPtrExec].address = PRM;
@@ -4577,7 +4604,7 @@ static void DSP_storew(void)
 //             JaguarWriteWord(PRM, PRN, DSP);
 //
 //     NO_WRITEBACK;
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        pipeline[plPtrExec].address = PRM & 0xFFFFFFFE;
 #else
        pipeline[plPtrExec].address = PRM;
@@ -4604,7 +4631,7 @@ static void DSP_store_r14_i(void)
 #endif
 //     DSPWriteLong(dsp_reg[14] + (dsp_convert_zero[PIMM1] << 2), PRN, DSP);
 //     NO_WRITEBACK;
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        pipeline[plPtrExec].address = (dsp_reg[14] & 0xFFFFFFFC) + (dsp_convert_zero[PIMM1] << 2);
 #else
        pipeline[plPtrExec].address = dsp_reg[14] + (dsp_convert_zero[PIMM1] << 2);
@@ -4618,7 +4645,7 @@ static void DSP_store_r14_r(void)
 {
 //     DSPWriteLong(dsp_reg[14] + PRM, PRN, DSP);
 //     NO_WRITEBACK;
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        pipeline[plPtrExec].address = (dsp_reg[14] + PRM) & 0xFFFFFFFC;
 #else
        pipeline[plPtrExec].address = dsp_reg[14] + PRM;
@@ -4636,7 +4663,7 @@ static void DSP_store_r15_i(void)
 #endif
 //     DSPWriteLong(dsp_reg[15] + (dsp_convert_zero[PIMM1] << 2), PRN, DSP);
 //     NO_WRITEBACK;
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        pipeline[plPtrExec].address = (dsp_reg[15] & 0xFFFFFFFC) + (dsp_convert_zero[PIMM1] << 2);
 #else
        pipeline[plPtrExec].address = dsp_reg[15] + (dsp_convert_zero[PIMM1] << 2);
@@ -4650,7 +4677,7 @@ static void DSP_store_r15_r(void)
 {
 //     DSPWriteLong(dsp_reg[15] + PRM, PRN, DSP);
 //     NO_WRITEBACK;
-#ifdef DSP_CORRECT_ALIGNMENT
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
        pipeline[plPtrExec].address = (dsp_reg[15] + PRM) & 0xFFFFFFFC;
 #else
        pipeline[plPtrExec].address = dsp_reg[15] + PRM;