#include <SDL.h> // Used only for SDL_GetTicks...
#include <stdlib.h>
+#include <time.h>
#include "dac.h"
#include "gpu.h"
#include "jagdasm.h"
#include "jaguar.h"
#include "jerry.h"
#include "log.h"
-#include "m68k.h"
+#include "m68000/m68kinterface.h"
//#include "memory.h"
offset &= 0x3F;
switch (offset)
{
- case 0x00: /*dsp_flag_c?(dsp_flag_c=1):(dsp_flag_c=0);
- dsp_flag_z?(dsp_flag_z=1):(dsp_flag_z=0);
- dsp_flag_n?(dsp_flag_n=1):(dsp_flag_n=0);*/
-
- dsp_flags = (dsp_flags & 0xFFFFFFF8) | (dsp_flag_n << 2) | (dsp_flag_c << 1) | dsp_flag_z;
- return dsp_flags & 0xFFFFC1FF;
+ case 0x00:
+ dsp_flags = (dsp_flags & 0xFFFFFFF8) | (dsp_flag_n << 2) | (dsp_flag_c << 1) | dsp_flag_z;
+ return dsp_flags & 0xFFFFC1FF;
case 0x04: return dsp_matrix_control;
case 0x08: return dsp_pointer_to_matrix;
case 0x0C: return dsp_data_organization;
if ((offset & 0x1C) == 0x1C)
{
if (offset & 0x03)
- dsp_div_control = (dsp_div_control&0xffff0000)|(data&0xffff);
+ dsp_div_control = (dsp_div_control & 0xFFFF0000) | (data & 0xFFFF);
else
- dsp_div_control = (dsp_div_control&0xffff)|((data&0xffff)<<16);
+ dsp_div_control = (dsp_div_control & 0xFFFF) | ((data & 0xFFFF) << 16);
}
else
{
- uint32 old_data = DSPReadLong(offset & 0xffffffc, who);
+ uint32 old_data = DSPReadLong(offset & 0xFFFFFFC, who);
+
if (offset & 0x03)
- old_data = (old_data&0xffff0000)|(data&0xffff);
+ old_data = (old_data & 0xFFFF0000) | (data & 0xFFFF);
else
- old_data = (old_data&0xffff)|((data&0xffff)<<16);
- DSPWriteLong(offset & 0xffffffc, old_data, who);
+ old_data = (old_data & 0xFFFF) | ((data & 0xFFFF) << 16);
+
+ DSPWriteLong(offset & 0xFFFFFFC, old_data, who);
}
+
return;
}
case 0x00:
{
#ifdef DSP_DEBUG
- WriteLog("DSP: Writing %08X to DSP_FLAGS by %s (REGPAGE is %s)...\n", data, whoName[who], (dsp_flags & REGPAGE ? "set" : "not set"));
+ WriteLog("DSP: Writing %08X to DSP_FLAGS by %s (REGPAGE is %sset)...\n", data, whoName[who], (dsp_flags & REGPAGE ? "" : "not "));
#endif
// bool IMASKCleared = (dsp_flags & IMASK) && !(data & IMASK);
IMASKCleared = (dsp_flags & IMASK) && !(data & IMASK);
- dsp_flags = data;
+ // NOTE: According to the JTRM, writing a 1 to IMASK has no effect; only the
+ // IRQ logic can set it. So we mask it out here to prevent problems...
+ dsp_flags = data & (~IMASK);
dsp_flag_z = dsp_flags & 0x01;
dsp_flag_c = (dsp_flags >> 1) & 0x01;
dsp_flag_n = (dsp_flags >> 2) & 0x01;
// 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
+
+// Further Note:
+// The impetus for this "fix" was Cybermorph, which sets the SCLK to 7 which is an
+// audio frequency > 48 KHz. However, it stuffs the L/RTXD registers using TIMER0.
+// So, while this works, it's a by-product of the lame way in which audio is currently
+// handled. Hopefully, once we run the DSP in the host audio IRQ, this problem will
+// go away of its own accord. :-P
+// Or does it? It seems the I2S interrupt isn't on with Cybermorph, so something
+// weird is going on here...
+// Maybe it works like this: It acknowledges the 1st interrupt, but never clears it.
+// So subsequent interrupts come into the chip, but they're never serviced but the
+// I2S subsystem keeps going.
+// After some testing on real hardware, it seems that if you enable TIMER0 and EXTERNAL
+// IRQs on J_INT ($F10020), you don't have to run an I2S interrupt on the DSP. Also,
+// It seems that it's only stable for values of SCLK <= 9.
+
+// All of the preceeding is moot now; we run the DSP in the host audio IRQ. This means
+// that we don't actually need this stuff anymore. :-D
+#if 0
if (data & INT_ENA1) // I2S interrupt
{
int freq = GetCalculatedFrequency();
// WriteLog("DSP: Setting audio freqency to %u Hz...\n", freq);
DACSetNewFrequency(freq);
}
+#endif
/* if (IMASKCleared) // If IMASK was cleared,
#ifdef DSP_DEBUG_IRQ
case 0x14:
{
//#ifdef DSP_DEBUG
-WriteLog("Write to DSP CTRL by %s: %08X\n", whoName[who], data);
+WriteLog("Write to DSP CTRL by %s: %08X (DSP PC=$%08X)\n", whoName[who], data, dsp_pc);
//#endif
bool wasRunning = DSP_RUNNING;
// uint32 dsp_was_running = DSP_RUNNING;
// 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");
dsp_build_branch_condition_table();
DSPReset();
+ srand(time(NULL)); // For randomizing local RAM
}
void DSPReset(void)
IMASKCleared = false;
FlushDSPPipeline();
dsp_reset_stats();
- memset(dsp_ram_8, 0xFF, 0x2000);
+// memset(dsp_ram_8, 0xFF, 0x2000);
+ // Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents
+ for(uint32 i=0; i<8192; i+=4)
+ {
+ *((uint32 *)(&dsp_ram_8[i])) = rand();
+ }
}
void DSPDumpDisassembly(void)
(j << 2) + 1, dsp_reg_bank_1[(j << 2) + 1],
(j << 2) + 2, dsp_reg_bank_1[(j << 2) + 2],
(j << 2) + 3, dsp_reg_bank_1[(j << 2) + 3]);
-
}
+ WriteLog("\n");
+
static char buffer[512];
j = DSP_WORK_RAM_BASE;
- while (j <= 0xF1BFFF)
+ while (j <= 0xF1CFFF)
{
uint32 oldj = j;
j += dasmjag(JAGUAR_DSP, buffer, j);