// Originally by David Raingeard (Cal2)
// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
// Cleanups, endian wrongness, and bad ASM amelioration by James L. Hammons
+// (C) 2010 Underground Software
+//
+// JLH = James L. Hammons <jlhamm@acm.org>
+//
+// Who When What
+// --- ---------- -------------------------------------------------------------
+// JLH 01/16/2010 Created this log ;-)
+// JLH 11/26/2011 Added fixes for LOAD/STORE alignment issues
+
+//
// Note: Endian wrongness probably stems from the MAME origins of this emu and
// the braindead way in which MAME handles memory. :-)
//
#include "jaguar.h"
#include "log.h"
#include "m68k.h"
-#include "memory.h"
+//#include "memory.h"
#include "tom.h"
+
+// Seems alignment in loads & stores was off...
+#define GPU_CORRECT_ALIGNMENT
+//#define GPU_CORRECT_ALIGNMENT_STORE
//#define GPU_DEBUG
// For GPU dissasembly...
+#if 1
#define GPU_DIS_ABS
#define GPU_DIS_ADD
#define GPU_DIS_ADDC
#define GPU_DIS_SUBQT
#define GPU_DIS_XOR
-bool doGPUDis = false;
-//bool doGPUDis = true;
-//*/
+//bool doGPUDis = false;
+bool doGPUDis = true;
+#endif
+
/*
GPU opcodes use (BIOS flying ATARI logo):
+ add 357416
//WriteLog("GPU->CPU interrupt\n");
if (TOMIRQEnabled(IRQ_GPU))
{
- if ((TOMIRQEnabled(IRQ_GPU)) && (JaguarInterruptHandlerIsValid(64)))
+//This is the programmer's responsibility, to make sure the handler is valid, not ours!
+// if ((TOMIRQEnabled(IRQ_GPU))// && (JaguarInterruptHandlerIsValid(64)))
{
TOMSetPendingGPUInt();
- m68k_set_irq(7); // Set 68000 NMI
+ m68k_set_irq(2); // Set 68000 IPL 2
GPUReleaseTimeslice();
}
}
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R14+$%02X) [NCZ:%u%u%u, R%02u=%08X, R14+$%02X=%08X]\n", gpu_pc-2, IMM_2, gpu_convert_zero[IMM_1] << 2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, gpu_convert_zero[IMM_1] << 2, gpu_reg[14]+(gpu_convert_zero[IMM_1] << 2));
#endif
+#ifdef GPU_CORRECT_ALIGNMENT_STORE
+ GPUWriteLong((gpu_reg[14] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), RN, GPU);
+#else
GPUWriteLong(gpu_reg[14] + (gpu_convert_zero[IMM_1] << 2), RN, GPU);
+#endif
}
static void gpu_opcode_store_r15_indexed(void)
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R15+$%02X) [NCZ:%u%u%u, R%02u=%08X, R15+$%02X=%08X]\n", gpu_pc-2, IMM_2, gpu_convert_zero[IMM_1] << 2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, gpu_convert_zero[IMM_1] << 2, gpu_reg[15]+(gpu_convert_zero[IMM_1] << 2));
#endif
+#ifdef GPU_CORRECT_ALIGNMENT_STORE
+ GPUWriteLong((gpu_reg[15] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), RN, GPU);
+#else
GPUWriteLong(gpu_reg[15] + (gpu_convert_zero[IMM_1] << 2), RN, GPU);
+#endif
}
static void gpu_opcode_load_r14_ri(void)
if (doGPUDis)
WriteLog("%06X: LOAD (R14+R%02u), R%02u [NCZ:%u%u%u, R14+R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM+gpu_reg[14], IMM_2, RN);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT
+ RN = GPUReadLong((gpu_reg[14] + RM) & 0xFFFFFFFC, GPU);
+#else
RN = GPUReadLong(gpu_reg[14] + RM, GPU);
+#endif
#ifdef GPU_DIS_LOAD14R
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
if (doGPUDis)
WriteLog("%06X: LOAD (R15+R%02u), R%02u [NCZ:%u%u%u, R15+R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM+gpu_reg[15], IMM_2, RN);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT
+ RN = GPUReadLong((gpu_reg[15] + RM) & 0xFFFFFFFC, GPU);
+#else
RN = GPUReadLong(gpu_reg[15] + RM, GPU);
+#endif
#ifdef GPU_DIS_LOAD15R
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R14+R%02u) [NCZ:%u%u%u, R%02u=%08X, R14+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[14]);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT_STORE
+ GPUWriteLong((gpu_reg[14] + RM) & 0xFFFFFFFC, RN, GPU);
+#else
GPUWriteLong(gpu_reg[14] + RM, RN, GPU);
+#endif
}
static void gpu_opcode_store_r15_ri(void)
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R15+R%02u) [NCZ:%u%u%u, R%02u=%08X, R15+R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM+gpu_reg[15]);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT_STORE
+ GPUWriteLong((gpu_reg[15] + RM) & 0xFFFFFFFC, RN, GPU);
+#else
GPUWriteLong(gpu_reg[15] + RM, RN, GPU);
+#endif
}
static void gpu_opcode_nop(void)
if (doGPUDis)
WriteLog("%06X: STOREW R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT_STORE
+ if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
+ GPUWriteLong(RM & 0xFFFFFFFE, RN & 0xFFFF, GPU);
+ else
+ JaguarWriteWord(RM & 0xFFFFFFFE, RN, GPU);
+#else
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
GPUWriteLong(RM, RN & 0xFFFF, GPU);
else
JaguarWriteWord(RM, RN, GPU);
+#endif
}
static void gpu_opcode_store(void)
if (doGPUDis)
WriteLog("%06X: STORE R%02u, (R%02u) [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X]\n", gpu_pc-2, IMM_2, IMM_1, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN, IMM_1, RM);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT_STORE
+ GPUWriteLong(RM & 0xFFFFFFFC, RN, GPU);
+#else
GPUWriteLong(RM, RN, GPU);
+#endif
}
static void gpu_opcode_storep(void)
{
+#ifdef GPU_CORRECT_ALIGNMENT_STORE
+ GPUWriteLong((RM & 0xFFFFFFF8) + 0, gpu_hidata, GPU);
+ GPUWriteLong((RM & 0xFFFFFFF8) + 4, RN, GPU);
+#else
GPUWriteLong(RM + 0, gpu_hidata, GPU);
GPUWriteLong(RM + 4, RN, GPU);
+#endif
}
static void gpu_opcode_loadb(void)
if (doGPUDis)
WriteLog("%06X: LOADW (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT
+ if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
+ RN = GPUReadLong(RM & 0xFFFFFFFE, GPU) & 0xFFFF;
+ else
+ RN = JaguarReadWord(RM & 0xFFFFFFFE, GPU);
+#else
if ((RM >= 0xF03000) && (RM <= 0xF03FFF))
RN = GPUReadLong(RM, GPU) & 0xFFFF;
else
RN = JaguarReadWord(RM, GPU);
+#endif
#ifdef GPU_DIS_LOADW
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
#endif
}
+// According to the docs, & "Do The Same", this address is long aligned...
+// So let's try it:
+// And it works!!! Need to fix all instances...
static void gpu_opcode_load(void)
{
#ifdef GPU_DIS_LOAD
if (doGPUDis)
WriteLog("%06X: LOAD (R%02u), R%02u [NCZ:%u%u%u, R%02u=%08X, R%02u=%08X] -> ", gpu_pc-2, IMM_1, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_1, RM, IMM_2, RN);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT
+ RN = GPUReadLong(RM & 0xFFFFFFFC, GPU);
+#else
RN = GPUReadLong(RM, GPU);
+#endif
#ifdef GPU_DIS_LOAD
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
static void gpu_opcode_loadp(void)
{
+#ifdef GPU_CORRECT_ALIGNMENT
+ gpu_hidata = GPUReadLong((RM & 0xFFFFFFF8) + 0, GPU);
+ RN = GPUReadLong((RM & 0xFFFFFFF8) + 4, GPU);
+#else
gpu_hidata = GPUReadLong(RM + 0, GPU);
RN = GPUReadLong(RM + 4, GPU);
+#endif
}
static void gpu_opcode_load_r14_indexed(void)
if (doGPUDis)
WriteLog("%06X: LOAD (R14+$%02X), R%02u [NCZ:%u%u%u, R14+$%02X=%08X, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1] << 2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_convert_zero[IMM_1] << 2, gpu_reg[14]+(gpu_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT
+ RN = GPUReadLong((gpu_reg[14] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), GPU);
+#else
RN = GPUReadLong(gpu_reg[14] + (gpu_convert_zero[IMM_1] << 2), GPU);
+#endif
#ifdef GPU_DIS_LOAD14I
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);
if (doGPUDis)
WriteLog("%06X: LOAD (R15+$%02X), R%02u [NCZ:%u%u%u, R15+$%02X=%08X, R%02u=%08X] -> ", gpu_pc-2, gpu_convert_zero[IMM_1] << 2, IMM_2, gpu_flag_n, gpu_flag_c, gpu_flag_z, gpu_convert_zero[IMM_1] << 2, gpu_reg[15]+(gpu_convert_zero[IMM_1] << 2), IMM_2, RN);
#endif
+#ifdef GPU_CORRECT_ALIGNMENT
+ RN = GPUReadLong((gpu_reg[15] & 0xFFFFFFFC) + (gpu_convert_zero[IMM_1] << 2), GPU);
+#else
RN = GPUReadLong(gpu_reg[15] + (gpu_convert_zero[IMM_1] << 2), GPU);
+#endif
#ifdef GPU_DIS_LOAD15I
if (doGPUDis)
WriteLog("[NCZ:%u%u%u, R%02u=%08X]\n", gpu_flag_n, gpu_flag_c, gpu_flag_z, IMM_2, RN);