//
// JAGUAR.CPP
//
-// by Cal2
-// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS)
+// Originally by David Raingeard (Cal2)
+// GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Carwin Jones (BeOS)
// Cleanups and endian wrongness amelioration by James L. Hammons
// Note: Endian wrongness probably stems from the MAME origins of this emu and
// the braindead way in which MAME handles memory. :-)
#define CPU_DEBUG
//Do this in makefile??? Yes! Could, but it's easier to define here...
-#define LOG_UNMAPPED_MEMORY_ACCESSES
+//#define LOG_UNMAPPED_MEMORY_ACCESSES
+//#define ABORT_ON_UNMAPPED_MEMORY_ACCESS
+#define ABORT_ON_ILLEGAL_INSTRUCTIONS
+//#define ABORT_ON_OFFICIAL_ILLEGAL_INSTRUCTION
#define CPU_DEBUG_MEMORY
// Private function prototypes
uint32 jaguar_active_memory_dumps = 0;
-uint32 jaguar_mainRom_crc32;
+uint32 jaguar_mainRom_crc32, jaguarRomSize, jaguarRunAddress;
/*static*/ uint8 * jaguar_mainRam = NULL;
/*static*/ uint8 * jaguar_bootRom = NULL;
WriteLog("\tA%i = %08X\n", i-M68K_REG_A0, m68k_get_reg(NULL, (m68k_register_t)i));
}*/
+#ifdef ABORT_ON_ILLEGAL_INSTRUCTIONS
if (!m68k_is_valid_instruction(m68k_read_memory_16(m68kPC), M68K_CPU_TYPE_68000))
{
+#ifndef ABORT_ON_OFFICIAL_ILLEGAL_INSTRUCTION
+ if (m68k_read_memory_16(m68kPC) == 0x4AFC)
+ {
+ // This is a kludge to let homebrew programs work properly (i.e., let the other processors
+ // keep going even when the 68K dumped back to the debugger or what have you).
+//dis no wok right!
+// m68k_set_reg(M68K_REG_PC, m68kPC - 2);
+// Try setting the vector to the illegal instruction...
+//This doesn't work right either! Do something else! Quick!
+// SET32(jaguar_mainRam, 0x10, m68kPC);
+
+ return;
+ }
+#endif
+
WriteLog("\nM68K encountered an illegal instruction at %08X!!!\n\nAborting!\n", m68kPC);
uint32 topOfStack = m68k_get_reg(NULL, M68K_REG_A7);
WriteLog("M68K: Top of stack: %08X. Stack trace:\n", JaguarReadLong(topOfStack));
WriteLog("%06X: %08X\n", topOfStack - (i * 4), JaguarReadLong(topOfStack - (i * 4)));
WriteLog("Jaguar: VBL interrupt is %s\n", ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64))) ? "enabled" : "disabled");
M68K_show_context();
+
+//temp
+// WriteLog("\n\n68K disasm\n\n");
+// jaguar_dasm(0x802000, 0x50C);
+// WriteLog("\n\n");
+//endoftemp
+
log_done();
exit(0);
}//*/
+#endif
}
//
else
{
jaguar_unknown_writeword(address, value, M68K);
+#ifdef LOG_UNMAPPED_MEMORY_ACCESSES
WriteLog("\tA0=%08X, A1=%08X, D0=%08X, D1=%08X\n",
m68k_get_reg(NULL, M68K_REG_A0), m68k_get_reg(NULL, M68K_REG_A1),
m68k_get_reg(NULL, M68K_REG_D0), m68k_get_reg(NULL, M68K_REG_D1));
+#endif
}
}
{
#ifdef LOG_UNMAPPED_MEMORY_ACCESSES
WriteLog("Jaguar: Unknown byte %02X written at %08X by %s (M68K PC=%06X)\n", data, address, whoName[who], m68k_get_reg(NULL, M68K_REG_PC));
+#endif
+#ifdef ABORT_ON_UNMAPPED_MEMORY_ACCESS
extern bool finished;
finished = true;
extern bool doDSPDis;
{
#ifdef LOG_UNMAPPED_MEMORY_ACCESSES
WriteLog("Jaguar: Unknown word %04X written at %08X by %s (M68K PC=%06X)\n", data, address, whoName[who], m68k_get_reg(NULL, M68K_REG_PC));
+#endif
+#ifdef ABORT_ON_UNMAPPED_MEMORY_ACCESS
extern bool finished;
finished = true;
extern bool doDSPDis;
{
#ifdef LOG_UNMAPPED_MEMORY_ACCESSES
WriteLog("Jaguar: Unknown byte read at %08X by %s (M68K PC=%06X)\n", address, whoName[who], m68k_get_reg(NULL, M68K_REG_PC));
+#endif
+#ifdef ABORT_ON_UNMAPPED_MEMORY_ACCESS
extern bool finished;
finished = true;
extern bool doDSPDis;
{
#ifdef LOG_UNMAPPED_MEMORY_ACCESSES
WriteLog("Jaguar: Unknown word read at %08X by %s (M68K PC=%06X)\n", address, whoName[who], m68k_get_reg(NULL, M68K_REG_PC));
+#endif
+#ifdef ABORT_ON_UNMAPPED_MEMORY_ACCESS
extern bool finished;
finished = true;
extern bool doDSPDis;
memcpy(jaguar_mainRam, jaguar_bootRom, 8);
else
{
- SET32(jaguar_mainRam, 4, 0x00802000);
+// Should also make a run address global as well, for when we reset the jag (PD mainly)
+/* SET32(jaguar_mainRam, 4, 0x00802000);
// Handle PD stuff...
// This should definitely go elsewhere (like in the cart load section)!
+//NOTE: The bytes 'JAGR' should also be at position $1C...
if (jaguar_mainRom[0] == 0x60 && jaguar_mainRom[1] == 0x1A)
{
- uint32 runAddress = GET32(jaguar_mainRom, 0x2A);
- uint32 progLength = GET32(jaguar_mainRom, 0x02);
- WriteLog("Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, progLength);
- memcpy(jaguar_mainRam + runAddress, jaguar_mainRom + 0x2E, progLength);
+ uint32 loadAddress = GET32(jaguar_mainRom, 0x22), runAddress = GET32(jaguar_mainRom, 0x2A);
+//This is not always right! Especially when converted via bin2jag1!!!
+//We should have access to the length of the furshlumiger file that was loaded anyway!
+//Now, we do! ;-)
+// uint32 progLength = GET32(jaguar_mainRom, 0x02);
+//jaguarRomSize
+//jaguarRunAddress
+// WriteLog("Jaguar: Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, progLength);
+// memcpy(jaguar_mainRam + loadAddress, jaguar_mainRom + 0x2E, progLength);
+ WriteLog("Jaguar: Setting up PD ROM... Run address: %08X, length: %08X\n", runAddress, jaguarRomSize - 0x2E);
+ memcpy(jaguar_mainRam + loadAddress, jaguar_mainRom + 0x2E, jaguarRomSize - 0x2E);
SET32(jaguar_mainRam, 4, runAddress);
- }
+ }//*/
+ SET32(jaguar_mainRam, 4, jaguarRunAddress);
}
// WriteLog("jaguar_reset():\n");
WriteLog("JagExe: VP=%u, VI=%u, VDB=%u, VBB=%u CPU CPS=%u, GPU CPS=%u\n", vp, vi, vdb, vbb, M68KCyclesPerScanline, RISCCyclesPerScanline);
}//*/
+//extern int start_logging;
for(uint16 i=0; i<vp; i++)
{
// Increment the horizontal count (why? RNG?)
TOMWriteWord(0xF00006, i); // Write the VC
- if (i == vi) // Time for Vertical Interrupt?
+// if (i == vi) // Time for Vertical Interrupt?
+//Not sure if this is correct...
+//Seems to be, kinda. According to the JTRM, this should only fire on odd lines in non-interlace mode...
+//Which means that it normally wouldn't go when it's zero.
+ if (i == vi && i > 0) // Time for Vertical Interrupt?
{
if (tom_irq_enabled(IRQ_VBLANK))// && jaguar_interrupt_handler_is_valid(64))
{
// uint32 invalid_instruction_address = s68000exec(M68KCyclesPerScanline);
// if (invalid_instruction_address != 0x80000000)
// cd_bios_process(invalid_instruction_address);
+//if (start_logging)
+// WriteLog("About to execute M68K (%u)...\n", i);
m68k_execute(M68KCyclesPerScanline);
// No CD handling... !!! FIX !!!
+//if (start_logging)
+// WriteLog("About to execute CD BIOS (%u)...\n", i);
cd_bios_exec(i); // NOTE: Ignores parameter...
+//if (start_logging)
+// WriteLog("About to execute TOM's PIT (%u)...\n", i);
TOMExecPIT(RISCCyclesPerScanline);
+//if (start_logging)
+// WriteLog("About to execute JERRY's PIT (%u)...\n", i);
jerry_pit_exec(RISCCyclesPerScanline);
+//if (start_logging)
+// WriteLog("About to execute JERRY's SSI (%u)...\n", i);
jerry_i2s_exec(RISCCyclesPerScanline);
+//if (start_logging)
+// WriteLog("About to execute GPU (%u)...\n", i);
gpu_exec(RISCCyclesPerScanline);
if (vjs.DSPEnabled)
DSPExec(RISCCyclesPerScanline); // Ordinary non-pipelined DSP
// DSPExecComp(RISCCyclesPerScanline); // Comparison core
+//if (start_logging)
+// WriteLog("About to execute OP (%u)...\n", i);
TOMExecScanline(i, render);
}
}