Added a specific breakpoint for the M68K illegal instruction exception
[clinton/Virtual-Jaguar-Rx.git] / src / jaguar.cpp
index d3e3ec9..69a22d5 100644 (file)
@@ -8,13 +8,19 @@
 //       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...
@@ -112,8 +120,10 @@ bool startM68KTracing = false;
 // 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;
 
 
 //
@@ -1041,12 +1051,142 @@ void   M68K_Debughalt(void)
 #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();
+       }
 #endif
 
        // Musashi does this automagically for you, UAE core does not :-P
@@ -1069,22 +1209,51 @@ unsigned int m68k_read_memory_8(unsigned int address)
 
        // Note that the Jaguar only has 2M of RAM, not 4!
        if ((address >= 0x000000) && (address <= (vjs.DRAM_size - 1)))
+       {
                retVal = jaguarMainRAM[address];
+       }
 //     else if ((address >= 0x800000) && (address <= 0xDFFFFF))
-       else if ((address >= 0x800000) && (address <= 0xDFFEFF))
-               retVal = jaguarMainROM[address - 0x800000];
-       else if ((address >= 0xE00000) && (address <= 0xE3FFFF))
-//             retVal = jaguarBootROM[address - 0xE00000];
-//             retVal = jaguarDevBootROM1[address - 0xE00000];
-               retVal = jagMemSpace[address];
-       else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
-               retVal = CDROMReadByte(address);
-       else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
-               retVal = TOMReadByte(address, M68K);
-       else if ((address >= 0xF10000) && (address <= 0xF1FFFF))
-               retVal = JERRYReadByte(address, M68K);
        else
-               retVal = jaguar_unknown_readbyte(address, M68K);
+       {
+               if ((address >= 0x800000) && (address <= 0xDFFEFF))
+               {
+                       retVal = jaguarMainROM[address - 0x800000];
+               }
+               else
+               {
+                       if ((address >= 0xE00000) && (address <= 0xE3FFFF))
+                       {
+                               //              retVal = jaguarBootROM[address - 0xE00000];
+                               //              retVal = jaguarDevBootROM1[address - 0xE00000];
+                               retVal = jagMemSpace[address];
+                       }
+                       else
+                       {
+                               if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
+                               {
+                                       retVal = CDROMReadByte(address);
+                               }
+                               else
+                               {
+                                       if ((address >= 0xF00000) && (address <= 0xF0FFFF))
+                                       {
+                                               retVal = TOMReadByte(address, M68K);
+                                       }
+                                       else
+                                       {
+                                               if ((address >= 0xF10000) && (address <= 0xF1FFFF))
+                                               {
+                                                       retVal = JERRYReadByte(address, M68K);
+                                               }
+                                               else
+                                               {
+                                                       retVal = jaguar_unknown_readbyte(address, M68K);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
 
 //if (address >= 0x2800 && address <= 0x281F)
 //     WriteLog("M68K: Read byte $%02X at $%08X [PC=%08X]\n", retVal, address, m68k_get_reg(NULL, M68K_REG_PC));
@@ -1106,7 +1275,7 @@ unsigned int m68k_read_memory_16(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();
        }
@@ -1179,32 +1348,60 @@ unsigned int m68k_read_memory_16(unsigned int address)
 
        // Note that the Jaguar only has 2M of RAM, not 4!
        if ((address >= 0x000000) && (address <= (vjs.DRAM_size - 2)))
-//             retVal = (jaguar_mainRam[address] << 8) | jaguar_mainRam[address+1];
+       {
+               //              retVal = (jaguar_mainRam[address] << 8) | jaguar_mainRam[address+1];
                retVal = GET16(jaguarMainRAM, address);
+       }
 //     else if ((address >= 0x800000) && (address <= 0xDFFFFE))
-       else if ((address >= 0x800000) && (address <= 0xDFFEFE))
+       else
        {
-               // Memory Track reading...
-               if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47))
+               if ((address >= 0x800000) && (address <= 0xDFFEFE))
                {
-                       retVal = MTReadWord(address);
+                       // Memory Track reading...
+                       if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47))
+                       {
+                               retVal = MTReadWord(address);
+                       }
+                       else
+                       {
+                               retVal = (jaguarMainROM[address - 0x800000] << 8) | jaguarMainROM[address - 0x800000 + 1];
+                       }
                }
                else
-                       retVal = (jaguarMainROM[address - 0x800000] << 8)
-                               | jaguarMainROM[address - 0x800000 + 1];
-       }
-       else if ((address >= 0xE00000) && (address <= 0xE3FFFE))
-//             retVal = (jaguarBootROM[address - 0xE00000] << 8) | jaguarBootROM[address - 0xE00000 + 1];
-//             retVal = (jaguarDevBootROM1[address - 0xE00000] << 8) | jaguarDevBootROM1[address - 0xE00000 + 1];
-               retVal = (jagMemSpace[address] << 8) | jagMemSpace[address + 1];
-       else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
-               retVal = CDROMReadWord(address, M68K);
-       else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
-               retVal = TOMReadWord(address, M68K);
-       else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
-               retVal = JERRYReadWord(address, M68K);
-       else
-               retVal = jaguar_unknown_readword(address, M68K);
+               {
+                       if ((address >= 0xE00000) && (address <= 0xE3FFFE))
+                       {
+                               //              retVal = (jaguarBootROM[address - 0xE00000] << 8) | jaguarBootROM[address - 0xE00000 + 1];
+                               //              retVal = (jaguarDevBootROM1[address - 0xE00000] << 8) | jaguarDevBootROM1[address - 0xE00000 + 1];
+                               retVal = (jagMemSpace[address] << 8) | jagMemSpace[address + 1];
+                       }
+                       else
+                       {
+                               if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
+                               {
+                                       retVal = CDROMReadWord(address, M68K);
+                               }
+                               else
+                               {
+                                       if ((address >= 0xF00000) && (address <= 0xF0FFFE))
+                                       {
+                                               retVal = TOMReadWord(address, M68K);
+                                       }
+                                       else
+                                       {
+                                               if ((address >= 0xF10000) && (address <= 0xF1FFFE))
+                                               {
+                                                       retVal = JERRYReadWord(address, M68K);
+                                               }
+                                               else
+                                               {
+                                                       retVal = jaguar_unknown_readword(address, M68K);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
 
 //if (address >= 0xF1B000 && address <= 0xF1CFFF)
 //     WriteLog("M68K: Read word $%04X at $%08X [PC=%08X]\n", retVal, address, m68k_get_reg(NULL, M68K_REG_PC));
@@ -1221,12 +1418,30 @@ unsigned int m68k_read_memory_16(unsigned int address)
 }
 
 
+// Alert message in case of exception vector request
+bool m68k_read_exception_vector(unsigned int address, char *text)
+{
+       QString msg;
+       QMessageBox msgBox;
+
+       msg.sprintf("$%06x: %s", pcQueue[pcQPtr ? (pcQPtr - 1) : 0x3FF], text);
+       msgBox.setText(msg);
+       msgBox.setStandardButtons(QMessageBox::Abort);
+       msgBox.setDefaultButton(QMessageBox::Abort);
+       msgBox.exec();
+       return M68KDebugHalt();
+}
+
+
+// Read 4 bytes from memory
 unsigned int m68k_read_memory_32(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();
+       }
 #endif
 
        // Musashi does this automagically for you, UAE core does not :-P
@@ -1237,19 +1452,36 @@ unsigned int m68k_read_memory_32(unsigned int address)
 
 //WriteLog("--> [RM32]\n");
 #ifndef USE_NEW_MMU
-       uint32_t retVal = 0;
+       //uint32_t retVal = 0;
 
-       if ((address >= 0x800000) && (address <= 0xDFFEFE))
+       // check exception vectors access
+       if ((address >= 0x8) && (address <= 0x7c))
        {
-               // Memory Track reading...
-               if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47))
-                       retVal = MTReadLong(address);
-               else
-                       retVal = GET32(jaguarMainROM, address - 0x800000);
-
-               return retVal;
+               switch (address)
+               {
+               case 0x10:
+                       m68k_read_exception_vector(address, "Illegal instruction");
+                       break;
+               }
+       }
+       else
+       {
+               // check ROM or Memory Track access
+               if ((address >= 0x800000) && (address <= 0xDFFEFE))
+               {
+                       // Memory Track reading...
+                       if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47))
+                       {
+                               return MTReadLong(address);
+                       }
+                       else
+                       {
+                               return GET32(jaguarMainROM, address - 0x800000);
+                       }
+               }
        }
 
+       // return value from memory
        return (m68k_read_memory_16(address) << 16) | m68k_read_memory_16(address + 2);
 #else
        return MMURead32(address, M68K);
@@ -1257,273 +1489,344 @@ unsigned int m68k_read_memory_32(unsigned int address)
 }
 
 
-// 
-void m68k_write_memory_alert(unsigned int address, char *bits, unsigned int value)
+// Alert message in case of writing to unknown memory location
+bool m68k_write_unknown_alert(unsigned int address, char *bits, unsigned int value)
 {
        QString msg;
-       msg.sprintf("ROM cartridge writing detection, from $%06x, at $%06x with a (%s) value of $%0x", m68k_get_reg(NULL, M68K_REG_PC), address, bits, value);
-#if 1
        QMessageBox msgBox;
+
+       msg.sprintf("$%06x: Writing at this unknown memory location $%06x with a (%s bits) value of $%0x", pcQueue[pcQPtr ? (pcQPtr - 1) : 0x3FF], address, bits, value);
        msgBox.setText(msg);
+       msgBox.setStandardButtons(QMessageBox::Abort);
+       msgBox.setDefaultButton(QMessageBox::Abort);
+       msgBox.exec();
+       return M68KDebugHalt();
+}
+
 
-       if (!M68KDebugHaltStatus() && !strstr(bits, "32"))
+// Alert message in case of writing to cartridge/ROM memory location
+bool m68k_write_cartridge_alert(unsigned int address, char *bits, unsigned int value)
+{
+       if (!M68KDebugHaltStatus())
        {
+               QString msg;
+               QMessageBox msgBox;
+
+               msg.sprintf("$%06x: Writing at this ROM cartridge location $%06x with a (%s bits) value of $%0x", pcQueue[pcQPtr ? (pcQPtr - 1) : 0x3FF], address, bits, value);
+               msgBox.setText(msg);
+
                msgBox.setInformativeText("Do you want to continue?");
-               msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
-               msgBox.setDefaultButton(QMessageBox::Cancel);
-       }
-       else
-       {
-               msgBox.setStandardButtons(QMessageBox::Cancel);
-               msgBox.setDefaultButton(QMessageBox::Cancel);
-       }
+               msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+               msgBox.setDefaultButton(QMessageBox::No);
 
-       int retVal = msgBox.exec();
-#endif
-#if 0
-       QMessageBox::StandardButton retVal = QMessageBox::question(this, tr("Remove Mapping"), msg, QMessageBox::No | QMessageBox::Yes, QMessageBox::No);
-#endif
+               int retVal = msgBox.exec();
 
-       if (retVal == QMessageBox::Ok)
-       {
-               return;
+               if (retVal == QMessageBox::Yes)
+               {
+                       return false;
+               }
+               else
+               {
+                       return M68KDebugHalt();
+               }
        }
        else
        {
-               M68KDebugHalt();
+               return 1;
        }
 }
 
 
-void m68k_write_memory_8(unsigned int address, unsigned int value)
+// Check memory write location
+// BPM & cartridge/ROM detections
+bool m68k_write_memory_check(unsigned int address, char *bits, unsigned int value)
 {
+       unsigned int address1;
+
 #ifdef ALPINE_FUNCTIONS
        // Check if breakpoint on memory is active, and deal with it
-       if (bpmActive && (address == bpmAddress1))
+       if (!M68KDebugHaltStatus() && bpmActive && (address == bpmAddress1))
        {
-               M68KDebugHalt();
+               return M68KDebugHalt();
        }
        else
+#endif
        {
                // Rom writing authorisation detection
-               if (!vjs.allowWritesToROM && ((address >= 0x800000) && (address < 0xe00000)))
+               if (!vjs.allowWritesToROM)
                {
-                       m68k_write_memory_alert(address, "8 bits", value);
+                       // Calcul the end address
+                       if (strstr(bits, "32"))
+                       {
+                               address1 = address + 3;
+                       }
+                       else
+                       {
+                               if (strstr(bits, "16"))
+                               {
+                                       address1 = address + 1;
+                               }
+                               else
+                               {
+                                       address1 = address;
+                               }
+                       }
+
+                       // Rom writing detection
+                       if ((address >= 0x800000) && (address1 < 0xDFFF00))
+                       {
+                               return m68k_write_cartridge_alert(address, bits, value);
+                       }
                }
+
+               return false;
        }
-#endif
+}
 
-       // Musashi does this automagically for you, UAE core does not :-P
-       address &= 0x00FFFFFF;
+
+// Memory write location on 8 bits
+void m68k_write_memory_8(unsigned int address, unsigned int value)
+{
+       // Check memory write location on 8 bits
+       if (!m68k_write_memory_check(address, "8", value))
+       {
+               // Musashi does this automagically for you, UAE core does not :-P
+               //address &= 0x00FFFFFF;
 #ifdef CPU_DEBUG_MEMORY
        // Note that the Jaguar only has 2M of RAM, not 4!
-       if ((address >= 0x000000) && (address <= 0x1FFFFF))
-       {
-               if (startMemLog)
+               if ((address >= 0x000000) && (address <= 0x1FFFFF))
                {
-                       if (value > writeMemMax[address])
-                               writeMemMax[address] = value;
-                       if (value < writeMemMin[address])
-                               writeMemMin[address] = value;
+                       if (startMemLog)
+                       {
+                               if (value > writeMemMax[address])
+                                       writeMemMax[address] = value;
+                               if (value < writeMemMin[address])
+                                       writeMemMin[address] = value;
+                       }
                }
-       }
 #endif
-/*if (address == 0x4E00)
-       WriteLog("M68K: Writing %02X at %08X, PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
-//if ((address >= 0x1FF020 && address <= 0x1FF03F) || (address >= 0x1FF820 && address <= 0x1FF83F))
-//     WriteLog("M68K: Writing %02X at %08X\n", value, address);
-//WriteLog("[WM8  PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
-/*if (effect_start)
-       if (address >= 0x18FA70 && address < (0x18FA70 + 8000))
-               WriteLog("M68K: Byte %02X written at %08X by 68K\n", value, address);//*/
-//$53D0
-/*if (address >= 0x53D0 && address <= 0x53FF)
-       printf("M68K: Writing byte $%02X at $%08X, PC=$%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
-//Testing AvP on UAE core...
-//000075A0: FFFFF80E B6320220 (BITMAP)
-/*if (address == 0x75A0 && value == 0xFF)
-       printf("M68K: (8) Tripwire hit...\n");//*/
+               /*if (address == 0x4E00)
+                       WriteLog("M68K: Writing %02X at %08X, PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
+                       //if ((address >= 0x1FF020 && address <= 0x1FF03F) || (address >= 0x1FF820 && address <= 0x1FF83F))
+                       //      WriteLog("M68K: Writing %02X at %08X\n", value, address);
+                       //WriteLog("[WM8  PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
+                       /*if (effect_start)
+                               if (address >= 0x18FA70 && address < (0x18FA70 + 8000))
+                                       WriteLog("M68K: Byte %02X written at %08X by 68K\n", value, address);//*/
+                                       //$53D0
+                                       /*if (address >= 0x53D0 && address <= 0x53FF)
+                                               printf("M68K: Writing byte $%02X at $%08X, PC=$%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
+                                               //Testing AvP on UAE core...
+                                               //000075A0: FFFFF80E B6320220 (BITMAP)
+                                               /*if (address == 0x75A0 && value == 0xFF)
+                                                       printf("M68K: (8) Tripwire hit...\n");//*/
 
 #ifndef USE_NEW_MMU
-       // Note that the Jaguar only has 2M of RAM, not 4!
-       if ((address >= 0x000000) && (address <= (vjs.DRAM_size - 1)))
-               jaguarMainRAM[address] = value;
-       else if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
-               CDROMWriteByte(address, value, M68K);
-       else if ((address >= 0xF00000) && (address <= 0xF0FFFF))
-               TOMWriteByte(address, value, M68K);
-       else if ((address >= 0xF10000) && (address <= 0xF1FFFF))
-               JERRYWriteByte(address, value, M68K);
-       else
-               jaguar_unknown_writebyte(address, value, M68K);
+                                                       // Note that the Jaguar only has 2M of RAM, not 4!
+               if ((address >= 0x000000) && (address <= (vjs.DRAM_size - 1)))
+               {
+                       jaguarMainRAM[address] = value;
+               }
+               else
+               {
+                       if ((address >= 0xDFFF00) && (address <= 0xDFFFFF))
+                       {
+                               CDROMWriteByte(address, value, M68K);
+                       }
+                       else
+                       {
+                               if ((address >= 0xF00000) && (address <= 0xF0FFFF))
+                               {
+                                       TOMWriteByte(address, value, M68K);
+                               }
+                               else
+                               {
+                                       if ((address >= 0xF10000) && (address <= 0xF1FFFF))
+                                       {
+                                               JERRYWriteByte(address, value, M68K);
+                                       }
+                                       else
+                                       {
+                                               if ((address >= 0x800000) && (address <= 0xDFFEFF))
+                                               {
+                                                       jagMemSpace[address] = (uint8_t)value;
+                                               }
+                                               else
+                                               {
+                                                       jaguar_unknown_writebyte(address, value, M68K);
+                                               }
+                                       }
+                               }
+                       }
+               }
 #else
-       MMUWrite8(address, value, M68K);
+               MMUWrite8(address, value, M68K);
 #endif
+       }
 }
 
 
+// Memory write location on 16 bits
 void m68k_write_memory_16(unsigned int address, unsigned int value)
 {
-#ifdef ALPINE_FUNCTIONS
-       // Check if breakpoint on memory is active, and deal with it
-       if (bpmActive && address == bpmAddress1)
+       // Check memory write location on 16 bits
+       if (!m68k_write_memory_check(address, "16", value))
        {
-               M68KDebugHalt();
-       }
-       else
-       {
-               // Rom writing authorisation detection
-               if (!vjs.allowWritesToROM && ((address >= 0x800000) && (address < 0xe00000)))
-               {
-                       if (!M68KDebugHaltStatus())
-                       {
-                               m68k_write_memory_alert(address, "16 bits", value);
-                       }
-               }
-       }
-#endif
-
-       // Musashi does this automagically for you, UAE core does not :-P
-       address &= 0x00FFFFFF;
+               // Musashi does this automagically for you, UAE core does not :-P
+               //address &= 0x00FFFFFF;
 #ifdef CPU_DEBUG_MEMORY
        // Note that the Jaguar only has 2M of RAM, not 4!
-       if ((address >= 0x000000) && (address <= 0x1FFFFE))
-       {
-               if (startMemLog)
+               if ((address >= 0x000000) && (address <= 0x1FFFFE))
                {
-                       uint8_t hi = value >> 8, lo = value & 0xFF;
+                       if (startMemLog)
+                       {
+                               uint8_t hi = value >> 8, lo = value & 0xFF;
 
-                       if (hi > writeMemMax[address])
-                               writeMemMax[address] = hi;
-                       if (hi < writeMemMin[address])
-                               writeMemMin[address] = hi;
+                               if (hi > writeMemMax[address])
+                                       writeMemMax[address] = hi;
+                               if (hi < writeMemMin[address])
+                                       writeMemMin[address] = hi;
 
-                       if (lo > writeMemMax[address+1])
-                               writeMemMax[address+1] = lo;
-                       if (lo < writeMemMin[address+1])
-                               writeMemMin[address+1] = lo;
+                               if (lo > writeMemMax[address + 1])
+                                       writeMemMax[address + 1] = lo;
+                               if (lo < writeMemMin[address + 1])
+                                       writeMemMin[address + 1] = lo;
+                       }
                }
-       }
 #endif
-/*if (address == 0x4E00)
-       WriteLog("M68K: Writing %02X at %08X, PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
-//if ((address >= 0x1FF020 && address <= 0x1FF03F) || (address >= 0x1FF820 && address <= 0x1FF83F))
-//     WriteLog("M68K: Writing %04X at %08X\n", value, address);
-//WriteLog("[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
-//if (address >= 0xF02200 && address <= 0xF0229F)
-//     WriteLog("M68K: Writing to blitter --> %04X at %08X\n", value, address);
-//if (address >= 0x0E75D0 && address <= 0x0E75E7)
-//     WriteLog("M68K: Writing %04X at %08X, M68K PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));
-/*extern uint32_t totalFrames;
-if (address == 0xF02114)
-       WriteLog("M68K: Writing to GPU_CTRL (frame:%u)... [M68K PC:%08X]\n", totalFrames, m68k_get_reg(NULL, M68K_REG_PC));
-if (address == 0xF02110)
-       WriteLog("M68K: Writing to GPU_PC (frame:%u)... [M68K PC:%08X]\n", totalFrames, m68k_get_reg(NULL, M68K_REG_PC));//*/
-//if (address >= 0xF03B00 && address <= 0xF03DFF)
-//     WriteLog("M68K: Writing %04X to %08X...\n", value, address);
-
-/*if (address == 0x0100)//64*4)
-       WriteLog("M68K: Wrote word to VI vector value %04X...\n", value);//*/
-/*if (effect_start)
-       if (address >= 0x18FA70 && address < (0x18FA70 + 8000))
-               WriteLog("M68K: Word %04X written at %08X by 68K\n", value, address);//*/
-/*     if (address == 0x51136 || address == 0x51138 || address == 0xFB074 || address == 0xFB076
-               || address == 0x1AF05E)
-               WriteLog("[WM16  PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);//*/
-//$53D0
-/*if (address >= 0x53D0 && address <= 0x53FF)
-       printf("M68K: Writing word $%04X at $%08X, PC=$%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
-//Testing AvP on UAE core...
-//000075A0: FFFFF80E B6320220 (BITMAP)
-/*if (address == 0x75A0 && value == 0xFFFF)
-{
-       printf("\nM68K: (16) Tripwire hit...\n");
-       ShowM68KContext();
-}//*/
+               /*if (address == 0x4E00)
+                       WriteLog("M68K: Writing %02X at %08X, PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
+                       //if ((address >= 0x1FF020 && address <= 0x1FF03F) || (address >= 0x1FF820 && address <= 0x1FF83F))
+                       //      WriteLog("M68K: Writing %04X at %08X\n", value, address);
+                       //WriteLog("[WM16 PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);
+                       //if (address >= 0xF02200 && address <= 0xF0229F)
+                       //      WriteLog("M68K: Writing to blitter --> %04X at %08X\n", value, address);
+                       //if (address >= 0x0E75D0 && address <= 0x0E75E7)
+                       //      WriteLog("M68K: Writing %04X at %08X, M68K PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));
+                       /*extern uint32_t totalFrames;
+                       if (address == 0xF02114)
+                               WriteLog("M68K: Writing to GPU_CTRL (frame:%u)... [M68K PC:%08X]\n", totalFrames, m68k_get_reg(NULL, M68K_REG_PC));
+                       if (address == 0xF02110)
+                               WriteLog("M68K: Writing to GPU_PC (frame:%u)... [M68K PC:%08X]\n", totalFrames, m68k_get_reg(NULL, M68K_REG_PC));//*/
+                               //if (address >= 0xF03B00 && address <= 0xF03DFF)
+                               //      WriteLog("M68K: Writing %04X to %08X...\n", value, address);
+
+                               /*if (address == 0x0100)//64*4)
+                                       WriteLog("M68K: Wrote word to VI vector value %04X...\n", value);//*/
+                                       /*if (effect_start)
+                                               if (address >= 0x18FA70 && address < (0x18FA70 + 8000))
+                                                       WriteLog("M68K: Word %04X written at %08X by 68K\n", value, address);//*/
+                                                       /*      if (address == 0x51136 || address == 0x51138 || address == 0xFB074 || address == 0xFB076
+                                                                       || address == 0x1AF05E)
+                                                                       WriteLog("[WM16  PC=%08X] Addr: %08X, val: %04X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);//*/
+                                                                       //$53D0
+                                                                       /*if (address >= 0x53D0 && address <= 0x53FF)
+                                                                               printf("M68K: Writing word $%04X at $%08X, PC=$%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
+                                                                               //Testing AvP on UAE core...
+                                                                               //000075A0: FFFFF80E B6320220 (BITMAP)
+                                                                               /*if (address == 0x75A0 && value == 0xFFFF)
+                                                                               {
+                                                                                       printf("\nM68K: (16) Tripwire hit...\n");
+                                                                                       ShowM68KContext();
+                                                                               }//*/
 
 #ifndef USE_NEW_MMU
-       // Note that the Jaguar only has 2M of RAM, not 4!
-       if ((address >= 0x000000) && (address <= (vjs.DRAM_size - 2)))
-       {
-/*             jaguar_mainRam[address] = value >> 8;
-               jaguar_mainRam[address + 1] = value & 0xFF;*/
-               SET16(jaguarMainRAM, address, value);
-       }
-       // Memory Track device writes....
-       else if ((address >= 0x800000) && (address <= 0x87FFFE))
-       {
-               if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47))
-                       MTWriteWord(address, value);
-       }
-       else if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
-               CDROMWriteWord(address, value, M68K);
-       else if ((address >= 0xF00000) && (address <= 0xF0FFFE))
-               TOMWriteWord(address, value, M68K);
-       else if ((address >= 0xF10000) && (address <= 0xF1FFFE))
-               JERRYWriteWord(address, value, M68K);
-       else
-       {
-               jaguar_unknown_writeword(address, value, M68K);
+                                                                               // Note that the Jaguar only has 2M of RAM, not 4!
+               if ((address >= 0x000000) && (address <= (vjs.DRAM_size - 2)))
+               {
+                       /*              jaguar_mainRam[address] = value >> 8;
+                                       jaguar_mainRam[address + 1] = value & 0xFF;*/
+                       SET16(jaguarMainRAM, address, value);
+               }
+               else
+               {
+                       // Memory Track device writes....
+                       if ((address >= 0x800000) && (address <= 0x87FFFE))
+                       {
+                               if (((TOMGetMEMCON1() & 0x0006) == (2 << 1)) && (jaguarMainROMCRC32 == 0xFDF37F47))
+                               {
+                                       MTWriteWord(address, value);
+                                       return;
+                               }
+                       }
+
+                       if ((address >= 0xDFFF00) && (address <= 0xDFFFFE))
+                       {
+                               CDROMWriteWord(address, value, M68K);
+                       }
+                       else
+                       {
+                               if ((address >= 0xF00000) && (address <= 0xF0FFFE))
+                               {
+                                       TOMWriteWord(address, value, M68K);
+                               }
+                               else
+                               {
+                                       if ((address >= 0xF10000) && (address <= 0xF1FFFE))
+                                       {
+                                               JERRYWriteWord(address, value, M68K);
+                                       }
+                                       else
+                                       {
+                                               if ((address >= 0x800000) && (address <= 0xDFFEFE))
+                                               {
+                                                       SET16(jagMemSpace, address, value);
+                                               }
+                                               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));
+                                                       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
-       }
+                                               }
+                                       }
+                               }
+                       }
+               }
 #else
-       MMUWrite16(address, value, M68K);
+               MMUWrite16(address, value, M68K);
 #endif
+       }
 }
 
 
+// Memory write location on 32 bits
 void m68k_write_memory_32(unsigned int address, unsigned int value)
 {
-#ifdef ALPINE_FUNCTIONS
-       // Check if breakpoint on memory is active, and deal with it
-       if (bpmActive && address == bpmAddress1)
-       {
-               M68KDebugHalt();
-       }
-       else
-       {
-               // Rom writing authorisation detection
-               if (!vjs.allowWritesToROM && ((address >= 0x800000) && (address < 0xe00000)))
-               {
-                       m68k_write_memory_alert(address, "32 bits", value);
-               }
-       }
-#endif
-
-       // Musashi does this automagically for you, UAE core does not :-P
-       address &= 0x00FFFFFF;
-/*if (address == 0x4E00)
-       WriteLog("M68K: Writing %02X at %08X, PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
-//WriteLog("--> [WM32]\n");
-/*if (address == 0x0100)//64*4)
-       WriteLog("M68K: Wrote dword to VI vector value %08X...\n", value);//*/
-/*if (address >= 0xF03214 && address < 0xF0321F)
-       WriteLog("M68K: Writing DWORD (%08X) to GPU RAM (%08X)...\n", value, address);//*/
-//M68K: Writing DWORD (88E30047) to GPU RAM (00F03214)...
-/*extern bool doGPUDis;
-if (address == 0xF03214 && value == 0x88E30047)
-//     start = true;
-       doGPUDis = true;//*/
-/*     if (address == 0x51136 || address == 0xFB074)
-               WriteLog("[WM32  PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);//*/
-//Testing AvP on UAE core...
-//000075A0: FFFFF80E B6320220 (BITMAP)
-/*if (address == 0x75A0 && (value & 0xFFFF0000) == 0xFFFF0000)
-{
-       printf("\nM68K: (32) Tripwire hit...\n");
-       ShowM68KContext();
-}//*/
+       // Check memory write location on 32 bits
+       if (!m68k_write_memory_check(address, "32", value))
+       {
+               // Musashi does this automagically for you, UAE core does not :-P
+               //address &= 0x00FFFFFF;
+       /*if (address == 0x4E00)
+               WriteLog("M68K: Writing %02X at %08X, PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC));//*/
+               //WriteLog("--> [WM32]\n");
+               /*if (address == 0x0100)//64*4)
+                       WriteLog("M68K: Wrote dword to VI vector value %08X...\n", value);//*/
+                       /*if (address >= 0xF03214 && address < 0xF0321F)
+                               WriteLog("M68K: Writing DWORD (%08X) to GPU RAM (%08X)...\n", value, address);//*/
+                               //M68K: Writing DWORD (88E30047) to GPU RAM (00F03214)...
+                               /*extern bool doGPUDis;
+                               if (address == 0xF03214 && value == 0x88E30047)
+                               //      start = true;
+                                       doGPUDis = true;//*/
+                                       /*      if (address == 0x51136 || address == 0xFB074)
+                                                       WriteLog("[WM32  PC=%08X] Addr: %08X, val: %02X\n", m68k_get_reg(NULL, M68K_REG_PC), address, value);//*/
+                                                       //Testing AvP on UAE core...
+                                                       //000075A0: FFFFF80E B6320220 (BITMAP)
+                                                       /*if (address == 0x75A0 && (value & 0xFFFF0000) == 0xFFFF0000)
+                                                       {
+                                                               printf("\nM68K: (32) Tripwire hit...\n");
+                                                               ShowM68KContext();
+                                                       }//*/
 
 #ifndef USE_NEW_MMU
-       m68k_write_memory_16(address, value >> 16);
-       m68k_write_memory_16(address + 2, value & 0xFFFF);
+               m68k_write_memory_16(address, value >> 16);
+               m68k_write_memory_16(address + 2, value & 0xFFFF);
 #else
-       MMUWrite32(address, value, M68K);
+               MMUWrite32(address, value, M68K);
 #endif
+       }
 }
 
 
@@ -1617,6 +1920,7 @@ void M68K_show_context(void)
 
 void jaguar_unknown_writebyte(unsigned address, unsigned data, uint32_t who/*=UNKNOWN*/)
 {
+       m68k_write_unknown_alert(address, "8", data);
 #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
@@ -1632,6 +1936,7 @@ void jaguar_unknown_writebyte(unsigned address, unsigned data, uint32_t who/*=UN
 
 void jaguar_unknown_writeword(unsigned address, unsigned data, uint32_t who/*=UNKNOWN*/)
 {
+       m68k_write_unknown_alert(address, "16", data);
 #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
@@ -2033,6 +2338,7 @@ memset(jaguarMainRAM + 0x804, 0xFF, 4);
        TOMInit();
        JERRYInit();
        CDROMInit();
+       m68k_brk_init();
 }
 
 
@@ -2043,8 +2349,10 @@ void JaguarReset(void)
 {
        // 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();
@@ -2053,10 +2361,20 @@ void JaguarReset(void)
 //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();
@@ -2066,7 +2384,6 @@ void JaguarReset(void)
        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);
@@ -2176,6 +2493,7 @@ void JaguarDone(void)
        DSPDone();
        TOMDone();
        JERRYDone();
+       m68k_brk_close();
 
        // temp, until debugger is in place
 //00802016: jsr     $836F1A.l