// Who When What
// --- ---------- -------------------------------------------------------------
// JLH 01/16/2010 Created this log ;-)
+// JLH 11/26/2011 Added fixes for LOAD/STORE alignment issues
//
#include "dsp.h"
#include "m68k.h"
//#include "memory.h"
+
+// Seems alignment in loads & stores was off...
+#define DSP_CORRECT_ALIGNMENT
+//#define DSP_CORRECT_ALIGNMENT_STORE
+
//#define DSP_DEBUG
//#define DSP_DEBUG_IRQ
//#define DSP_DEBUG_PL2
// Disassembly definitions
+#if 0
#define DSP_DIS_ABS
#define DSP_DIS_ADD
#define DSP_DIS_ADDC
//*/
bool doDSPDis = false;
//bool doDSPDis = true;
-
+#endif
/*
No dis yet:
/* if (dsp_in_exec == 0)
{
m68k_end_timeslice();
- gpu_releaseTimeslice();
+ dsp_releaseTimeslice();
}*/
return;
}
{
// 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
WriteLog("DSP: CPU -> DSP interrupt\n");
#endif
m68k_end_timeslice();
- GPUReleaseTimeslice();
+ DSPReleaseTimeslice();
DSPSetIRQLine(DSPIRQ_CPU, ASSERT_LINE);
data &= ~DSPINT0;
}
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();
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_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);
+#endif
}
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_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);
+#endif
}
static void dsp_opcode_load_r14_ri(void)
if (doDSPDis)
WriteLog("%06X: LOAD (R14+R%02u), R%02u [NCZ:%u%u%u, R14+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+dsp_reg[14], IMM_2, RN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ RN = DSPReadLong((dsp_reg[14] + RM) & 0xFFFFFFFC, DSP);
+#else
RN = DSPReadLong(dsp_reg[14] + RM, DSP);
+#endif
#ifdef DSP_DIS_LOAD14R
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
if (doDSPDis)
WriteLog("%06X: LOAD (R15+R%02u), R%02u [NCZ:%u%u%u, R15+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+dsp_reg[15], IMM_2, RN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ RN = DSPReadLong((dsp_reg[15] + RM) & 0xFFFFFFFC, DSP);
+#else
RN = DSPReadLong(dsp_reg[15] + RM, DSP);
+#endif
#ifdef DSP_DIS_LOAD15R
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
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_STORE
+ if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF))
+ DSPWriteLong(RM & 0xFFFFFFFE, RN & 0xFFFF, DSP);
+ else
+ JaguarWriteWord(RM & 0xFFFFFFFE, RN, DSP);
+#else
if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF))
DSPWriteLong(RM, RN & 0xFFFF, DSP);
else
JaguarWriteWord(RM, RN, DSP);
+#endif
}
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_STORE
+ DSPWriteLong(RM & 0xFFFFFFFC, RN, DSP);
+#else
DSPWriteLong(RM, RN, DSP);
+#endif
}
static void dsp_opcode_loadb(void)
if (doDSPDis)
WriteLog("%06X: LOADW (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
+#ifdef DSP_CORRECT_ALIGNMENT
+ if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF))
+ RN = DSPReadLong(RM & 0xFFFFFFFE, DSP) & 0xFFFF;
+ else
+ RN = JaguarReadWord(RM & 0xFFFFFFFE, DSP);
+#else
if (RM >= DSP_WORK_RAM_BASE && RM <= (DSP_WORK_RAM_BASE + 0x1FFF))
RN = DSPReadLong(RM, DSP) & 0xFFFF;
else
RN = JaguarReadWord(RM, DSP);
+#endif
#ifdef DSP_DIS_LOADW
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
if (doDSPDis)
WriteLog("%06X: LOAD (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
+#ifdef DSP_CORRECT_ALIGNMENT
+ RN = DSPReadLong(RM & 0xFFFFFFFC, DSP);
+#else
RN = DSPReadLong(RM, DSP);
+#endif
#ifdef DSP_DIS_LOAD
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
if (doDSPDis)
WriteLog("%06X: LOAD (R14+$%02X), R%02u [NCZ:%u%u%u, R14+$%02X=%08X, R%02u=%08X] -> ", dsp_pc-2, dsp_convert_zero[IMM_1] << 2, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, dsp_convert_zero[IMM_1] << 2, dsp_reg[14]+(dsp_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ RN = DSPReadLong((dsp_reg[14] & 0xFFFFFFFC) + (dsp_convert_zero[IMM_1] << 2), DSP);
+#else
RN = DSPReadLong(dsp_reg[14] + (dsp_convert_zero[IMM_1] << 2), DSP);
+#endif
#ifdef DSP_DIS_LOAD14I
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
if (doDSPDis)
WriteLog("%06X: LOAD (R15+$%02X), R%02u [NCZ:%u%u%u, R15+$%02X=%08X, R%02u=%08X] -> ", dsp_pc-2, dsp_convert_zero[IMM_1] << 2, IMM_2, dsp_flag_n, dsp_flag_c, dsp_flag_z, dsp_convert_zero[IMM_1] << 2, dsp_reg[15]+(dsp_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ RN = DSPReadLong((dsp_reg[15] & 0xFFFFFFFC) + (dsp_convert_zero[IMM_1] << 2), DSP);
+#else
RN = DSPReadLong(dsp_reg[15] + (dsp_convert_zero[IMM_1] << 2), DSP);
+#endif
#ifdef DSP_DIS_LOAD15I
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, IMM_2, RN);
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;
pcQueue1[pcQPtr1++] = dsp_pc;
pcQPtr1 &= 0x3FF;
+#ifdef DSP_DEBUG_PL2
if ((dsp_pc < 0xF1B000 || dsp_pc > 0xF1CFFF) && !doDSPDis)
{
WriteLog("DSP: PC has stepped out of bounds...\n\nBacktrace:\n\n");
}
WriteLog("\n");
}//*/
+#endif
+
if (IMASKCleared) // If IMASK was cleared,
{
#ifdef DSP_DEBUG_IRQ
// Stage 2: Execute
if (pipeline[plPtrExec].opcode != PIPELINE_STALL)
{
+#ifdef DSP_DEBUG_PL2
if (doDSPDis)
WriteLog("\t[inst=%02u][R28=%08X, alt R28=%08X, REGPAGE=%s]\n", pipeline[plPtrExec].opcode, dsp_reg[28], dsp_alternate_reg[28], (dsp_flags & REGPAGE ? "set" : "not set"));
-#ifdef DSP_DEBUG_PL2
+
if (doDSPDis)
{
WriteLog("DSPExecP: About to execute opcode %s...\n", dsp_opcode_str[pipeline[plPtrExec].opcode]);
if (doDSPDis)
WriteLog("%06X: LOAD (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", DSP_PPC, PIMM1, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM, PIMM2, PRN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ PRES = DSPReadLong(PRM & 0xFFFFFFFC, DSP);
+#else
PRES = DSPReadLong(PRM, DSP);
+#endif
#ifdef DSP_DIS_LOAD
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
if (doDSPDis)
WriteLog("%06X: LOADW (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", DSP_PPC, PIMM1, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM, PIMM2, PRN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ if (PRM >= DSP_WORK_RAM_BASE && PRM <= (DSP_WORK_RAM_BASE + 0x1FFF))
+ PRES = DSPReadLong(PRM & 0xFFFFFFFE, DSP) & 0xFFFF;
+ else
+ PRES = JaguarReadWord(PRM & 0xFFFFFFFE, DSP);
+#else
if (PRM >= DSP_WORK_RAM_BASE && PRM <= (DSP_WORK_RAM_BASE + 0x1FFF))
PRES = DSPReadLong(PRM, DSP) & 0xFFFF;
else
PRES = JaguarReadWord(PRM, DSP);
+#endif
#ifdef DSP_DIS_LOADW
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
if (doDSPDis)
WriteLog("%06X: LOAD (R14+$%02X), R%02u [NCZ:%u%u%u, R14+$%02X=%08X, R%02u=%08X] -> ", DSP_PPC, dsp_convert_zero[PIMM1] << 2, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, dsp_convert_zero[PIMM1] << 2, dsp_reg[14]+(dsp_convert_zero[PIMM1] << 2), PIMM2, PRN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ PRES = DSPReadLong((dsp_reg[14] & 0xFFFFFFFC) + (dsp_convert_zero[PIMM1] << 2), DSP);
+#else
PRES = DSPReadLong(dsp_reg[14] + (dsp_convert_zero[PIMM1] << 2), DSP);
+#endif
#ifdef DSP_DIS_LOAD14I
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
if (doDSPDis)
WriteLog("%06X: LOAD (R14+R%02u), R%02u [NCZ:%u%u%u, R14+R%02u=%08X, R%02u=%08X] -> ", DSP_PPC, PIMM1, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM+dsp_reg[14], PIMM2, PRES);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ PRES = DSPReadLong((dsp_reg[14] + PRM) & 0xFFFFFFFC, DSP);
+#else
PRES = DSPReadLong(dsp_reg[14] + PRM, DSP);
+#endif
#ifdef DSP_DIS_LOAD14R
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
if (doDSPDis)
WriteLog("%06X: LOAD (R15+$%02X), R%02u [NCZ:%u%u%u, R15+$%02X=%08X, R%02u=%08X] -> ", DSP_PPC, dsp_convert_zero[PIMM1] << 2, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, dsp_convert_zero[PIMM1] << 2, dsp_reg[15]+(dsp_convert_zero[PIMM1] << 2), PIMM2, PRN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ PRES = DSPReadLong((dsp_reg[15] &0xFFFFFFFC) + (dsp_convert_zero[PIMM1] << 2), DSP);
+#else
PRES = DSPReadLong(dsp_reg[15] + (dsp_convert_zero[PIMM1] << 2), DSP);
+#endif
#ifdef DSP_DIS_LOAD15I
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
if (doDSPDis)
WriteLog("%06X: LOAD (R15+R%02u), R%02u [NCZ:%u%u%u, R15+R%02u=%08X, R%02u=%08X] -> ", DSP_PPC, PIMM1, PIMM2, dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM1, PRM+dsp_reg[15], PIMM2, PRN);
#endif
+#ifdef DSP_CORRECT_ALIGNMENT
+ PRES = DSPReadLong((dsp_reg[15] + PRM) & 0xFFFFFFFC, DSP);
+#else
PRES = DSPReadLong(dsp_reg[15] + PRM, DSP);
+#endif
#ifdef DSP_DIS_LOAD15R
if (doDSPDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", dsp_flag_n, dsp_flag_c, dsp_flag_z, PIMM2, PRES);
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;
#endif
// DSPWriteLong(PRM, PRN, DSP);
// NO_WRITEBACK;
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
+ pipeline[plPtrExec].address = PRM & 0xFFFFFFFC;
+#else
pipeline[plPtrExec].address = PRM;
+#endif
pipeline[plPtrExec].value = PRN;
pipeline[plPtrExec].type = TYPE_DWORD;
WRITEBACK_ADDR;
// JaguarWriteWord(PRM, PRN, DSP);
//
// NO_WRITEBACK;
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
+ pipeline[plPtrExec].address = PRM & 0xFFFFFFFE;
+#else
pipeline[plPtrExec].address = PRM;
+#endif
if (PRM >= DSP_WORK_RAM_BASE && PRM <= (DSP_WORK_RAM_BASE + 0x1FFF))
{
#endif
// DSPWriteLong(dsp_reg[14] + (dsp_convert_zero[PIMM1] << 2), PRN, DSP);
// NO_WRITEBACK;
+#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);
+#endif
pipeline[plPtrExec].value = PRN;
pipeline[plPtrExec].type = TYPE_DWORD;
WRITEBACK_ADDR;
{
// DSPWriteLong(dsp_reg[14] + PRM, PRN, DSP);
// NO_WRITEBACK;
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
+ pipeline[plPtrExec].address = (dsp_reg[14] + PRM) & 0xFFFFFFFC;
+#else
pipeline[plPtrExec].address = dsp_reg[14] + PRM;
+#endif
pipeline[plPtrExec].value = PRN;
pipeline[plPtrExec].type = TYPE_DWORD;
WRITEBACK_ADDR;
#endif
// DSPWriteLong(dsp_reg[15] + (dsp_convert_zero[PIMM1] << 2), PRN, DSP);
// NO_WRITEBACK;
+#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);
+#endif
pipeline[plPtrExec].value = PRN;
pipeline[plPtrExec].type = TYPE_DWORD;
WRITEBACK_ADDR;
{
// DSPWriteLong(dsp_reg[15] + PRM, PRN, DSP);
// NO_WRITEBACK;
+#ifdef DSP_CORRECT_ALIGNMENT_STORE
+ pipeline[plPtrExec].address = (dsp_reg[15] + PRM) & 0xFFFFFFFC;
+#else
pipeline[plPtrExec].address = dsp_reg[15] + PRM;
+#endif
pipeline[plPtrExec].value = PRN;
pipeline[plPtrExec].type = TYPE_DWORD;
WRITEBACK_ADDR;