// the braindead way in which MAME handled memory when this was written. :-)
//
// JLH = James Hammons
+// JPM = Jean-Paul Mari
//
// WHO WHEN WHAT
// --- ---------- -----------------------------------------------------------
// JLH 11/25/2009 Major rewrite of memory subsystem and handlers
+// JPM 09/04/2018 Added the new Models and BIOS handler
+// JPM 10/13/2018 Added breakpoints features
//
+#define NEWMODELSBIOSHANDLER // New Jaguar models and bios usage handler
+
+
#include "jaguar.h"
#include <QApplication>
#include <QMessageBox>
#include "mmu.h"
#include "settings.h"
#include "tom.h"
-//#include "debugger/brkWin.h"
-
+//#include "debugger/BreakpointsWin.h"
+#ifdef NEWMODELSBIOSHANDLER
+#include "modelsBIOS.h"
+#endif
#define CPU_DEBUG
//Do this in makefile??? Yes! Could, but it's easier to define here...
// Breakpoint on memory access vars (exported)
bool bpmActive = false;
bool bpmSaveActive = false;
+size_t bpmHitCounts;
uint32_t bpmAddress1;
-//BrkInfo bpm;
+S_BrkInfo *brkInfo;
+size_t brkNbr;
//
#endif
-//
+// M68000 breakpoints initialisations
+void m68k_brk_init(void)
+{
+ brkNbr = 0;
+ brkInfo = NULL;
+}
+
+
+// Reset the M68000 breakpoints structures
+void m68k_brk_reset(void)
+{
+ // Reset the breakpoints
+ free(brkInfo);
+ brkInfo = NULL;
+ brkNbr = 0;
+}
+
+
+// Delete a M68000 breakpoint (starting from 1)
+void m68k_brk_del(unsigned int NumBrk)
+{
+ // Remove the breakpoint
+ memset((void *)(brkInfo + (NumBrk - 1)), 0, sizeof(S_BrkInfo));
+}
+
+
+// Add a M68000 breakpoint
+// return true if breakpoint has been added, and false if breakpoint already exists
+unsigned int m68k_brk_add(void *PtrInfo)
+{
+ S_BrkInfo *Ptr = NULL;
+
+ // Check if breakpoint already exists
+ for (size_t i = 0; i < brkNbr; i++)
+ {
+ if (brkInfo[i].Used)
+ {
+ if (brkInfo[i].Adr == ((S_BrkInfo *)PtrInfo)->Adr)
+ {
+ return false;
+ }
+ }
+ }
+
+ // Look for an available breakpoint
+ for (size_t i = 0; i < brkNbr, Ptr; i++)
+ {
+ if (!brkInfo[i].Used)
+ {
+ Ptr = &brkInfo[i];
+ }
+ }
+
+ // Add a breakpoint
+ if (!Ptr)
+ {
+ brkInfo = (S_BrkInfo *)realloc(brkInfo, (++brkNbr * sizeof(S_BrkInfo)));
+ Ptr = &brkInfo[brkNbr - 1];
+ }
+
+ // Transfert the breakpoint information and init the activities
+ memcpy((void *)Ptr, PtrInfo, sizeof(S_BrkInfo));
+ Ptr->HitCounts = 0;
+ return (Ptr->Active = Ptr->Used = true);
+}
+
+
+// Check if breakpoint has been reached
+unsigned int m68k_brk_check(unsigned int adr)
+{
+ // Check if BPM has been reached
+ if ((adr == bpmAddress1) && bpmActive)
+ {
+ bpmHitCounts++;
+ return true;
+ }
+ else
+ {
+ // Check user breakpoints
+ for (size_t i = 0; i < brkNbr; i++)
+ {
+ if (brkInfo[i].Used && brkInfo[i].Active)
+ {
+ if (brkInfo[i].Adr == adr)
+ {
+ brkInfo[i].HitCounts++;
+ return true;
+ }
+ }
+ }
+ }
+
+ // No breakpoint found
+ return false;
+}
+
+
+// Disable the M68000 breakpoints
+void m68k_brk_disable(void)
+{
+ // reset active for the breakpoints
+ for (size_t i = 0; i < brkNbr; i++)
+ {
+ brkInfo[i].Active = 0;
+ }
+}
+
+
+// Reset the M68000 breakpoints
+void m68k_brk_hitcounts_reset(void)
+{
+ // reset hit counts for the breakpoints
+ for (size_t i = 0; i < brkNbr; i++)
+ {
+ brkInfo[i].HitCounts = 0;
+ }
+}
+
+
+// Close the M68000 breakpoints structures
+void m68k_brk_close(void)
+{
+ free(brkInfo);
+}
+
+
+// Read 1 byte from address
+// Check if address reaches a breakpoint
unsigned int m68k_read_memory_8(unsigned int address)
{
#ifdef ALPINE_FUNCTIONS
// Check if breakpoint on memory is active, and deal with it
- if (bpmActive && address == bpmAddress1)
+ if (!startM68KTracing && m68k_brk_check(address))
{
M68KDebugHalt();
}
{
#ifdef ALPINE_FUNCTIONS
// Check if breakpoint on memory is active, and deal with it
- if (bpmActive && (address == bpmAddress1))
+ if (!startM68KTracing && m68k_brk_check(address))
{
M68KDebugHalt();
}
{
#ifdef ALPINE_FUNCTIONS
// Check if breakpoint on memory is active, and deal with it
- if (bpmActive && address == bpmAddress1)
+ if (!startM68KTracing && m68k_brk_check(address))
{
M68KDebugHalt();
}
TOMInit();
JERRYInit();
CDROMInit();
+ m68k_brk_init();
}
{
// Only problem with this approach: It wipes out RAM loaded files...!
// Contents of local RAM are quasi-stable; we simulate this by randomizing RAM contents
- for(uint32_t i=8; i<vjs.DRAM_size; i+=4)
+ for (uint32_t i = 8; i < vjs.DRAM_size; i += 4)
+ {
*((uint32_t *)(&jaguarMainRAM[i])) = rand();
+ }
// New timer base code stuffola...
InitializeEventList();
//Also, have to change this here and in JaguarReadXX() currently
// Only use the system BIOS if it's available...! (it's always available now!)
// AND only if a jaguar cartridge has been inserted.
+#ifndef NEWMODELSBIOSHANDLER
if (vjs.useJaguarBIOS && jaguarCartInserted && !vjs.hardwareTypeAlpine && !vjs.softTypeDebugger)
+ {
memcpy(jaguarMainRAM, jagMemSpace + 0xE00000, 8);
+#else
+ if (vjs.useJaguarBIOS && jaguarCartInserted)
+ {
+ SetBIOS();
+#endif
+ }
else
+ {
SET32(jaguarMainRAM, 4, jaguarRunAddress);
+ }
// WriteLog("jaguar_reset():\n");
TOMReset();
CDROMReset();
m68k_pulse_reset(); // Reset the 68000
WriteLog("Jaguar: 68K reset. PC=%06X SP=%08X\n", m68k_get_reg(NULL, M68K_REG_PC), m68k_get_reg(NULL, M68K_REG_A7));
-
lowerField = false; // Reset the lower field flag
// SetCallbackTime(ScanlineCallback, 63.5555);
// SetCallbackTime(ScanlineCallback, 31.77775);
DSPDone();
TOMDone();
JERRYDone();
+ m68k_brk_close();
// temp, until debugger is in place
//00802016: jsr $836F1A.l