]> Shamusworld >> Repos - virtualjaguar/commitdiff
Added breakpoint on memory access to Alpine mode.
authorShamus Hammons <jlhamm@acm.org>
Fri, 6 Dec 2013 17:31:01 +0000 (11:31 -0600)
committerShamus Hammons <jlhamm@acm.org>
Fri, 6 Dec 2013 17:31:01 +0000 (11:31 -0600)
src/gui/debug/cpubrowser.cpp
src/gui/debug/cpubrowser.h
src/jaguar.cpp
src/jaguar.h
src/m68000/m68kinterface.c
src/m68000/m68kinterface.h

index daabbf30be9ecb33f3c08648de8f05756e066aa6..2f478ce2eb3090952ed2f219e54caf75a1e7971d 100644 (file)
 #include "m68000/m68kinterface.h"
 #include "dsp.h"
 #include "gpu.h"
+#include "jaguar.h"
 
 
 CPUBrowserWindow::CPUBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog),
-//     layout(new QVBoxLayout), text(new QTextBrowser),
        layout(new QVBoxLayout), text(new QLabel),
        refresh(new QPushButton(tr("Refresh"))),
-       memBase(0)
+       bpm(new QCheckBox(tr("BPM"))), bpmAddress(new QLineEdit)
 {
        setWindowTitle(tr("CPU Browser"));
 
        // Need to set the size as well...
 //     resize(560, 480);
 
+       // Limit input to 6 hex digits
+       bpmAddress->setInputMask("hhhhhh");
+       QHBoxLayout * hbox1 = new QHBoxLayout;
+       hbox1->addWidget(bpm);
+       hbox1->addWidget(bpmAddress);
+
 //     QFont fixedFont("Lucida Console", 8, QFont::Normal);
        QFont fixedFont("", 8, QFont::Normal);
        fixedFont.setStyleHint(QFont::TypeWriter);
@@ -40,9 +46,12 @@ CPUBrowserWindow::CPUBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt:
        setLayout(layout);
 
        layout->addWidget(text);
+       layout->addLayout(hbox1);
        layout->addWidget(refresh);
 
        connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));
+       connect(bpm, SIGNAL(clicked(bool)), this, SLOT(HandleBPM(bool)));
+       connect(bpmAddress, SIGNAL(textChanged(const QString &)), this, SLOT(HandleBPMAddress(const QString &)));
 }
 
 
@@ -236,10 +245,26 @@ DSP Control:
 }
 
 
+void CPUBrowserWindow::HandleBPM(bool state)
+{
+       bpmActive = state;
+if (bpmActive)
+       printf("BPM Set: $%06X\n", bpmAddress1);
+}
+
+
+void CPUBrowserWindow::HandleBPMAddress(const QString & newText)
+{
+       bool ok;
+       bpmAddress1 = newText.toUInt(&ok, 16);
+}
+
+
 void CPUBrowserWindow::keyPressEvent(QKeyEvent * e)
 {
        if (e->key() == Qt::Key_Escape)
                hide();
+#if 0
        else if (e->key() == Qt::Key_PageUp)
        {
                memBase -= 480;
@@ -276,4 +301,5 @@ void CPUBrowserWindow::keyPressEvent(QKeyEvent * e)
 
                RefreshContents();
        }
+#endif
 }
index 0ea0cdae99f3563f547db54b848eb6eb9390695c..e6518724df8824a1052e6a5e8b5e52ea3629e8d8 100644 (file)
@@ -22,6 +22,8 @@ class CPUBrowserWindow: public QWidget
        public slots:
 //             void DefineAllKeys(void);
                void RefreshContents(void);
+               void HandleBPM(bool);
+               void HandleBPMAddress(const QString &);
 
        protected:
                void keyPressEvent(QKeyEvent *);
@@ -31,8 +33,10 @@ class CPUBrowserWindow: public QWidget
 //             QTextBrowser * text;
                QLabel * text;
                QPushButton * refresh;
+               QCheckBox * bpm;
+               QLineEdit * bpmAddress;
 
-               int32_t memBase;
+//             int32_t memBase;
 };
 
 #endif // __CPUBROWSER_H__
index b92b2215e4cdd650b9c48dfedf8a340041a492a7..cfbf3ef134ae8861070b4fc0f88895407108b331 100644 (file)
@@ -45,6 +45,7 @@
 #define CPU_DEBUG_MEMORY
 //#define LOG_CD_BIOS_CALLS
 #define CPU_DEBUG_TRACING
+#define ALPINE_FUNCTIONS
 
 // Private function prototypes
 
@@ -99,6 +100,11 @@ uint32_t d7Queue[0x400];
 uint32_t pcQPtr = 0;
 bool startM68KTracing = false;
 
+// Breakpoint on memory access vars (exported)
+bool bpmActive = false;
+uint32_t bpmAddress1;
+
+
 //
 // Callback function to detect illegal instructions
 //
@@ -860,27 +866,33 @@ WriteLog("JERRY: (68K int en/lat - Unhandled!) Tried to write $%02X to $%08X!\n"
                ;       // Do nothing
 }
 
+
 void WriteWord(uint32_t adddress, uint16_t word)
 {
 }
 
+
 void WriteDWord(uint32_t adddress, uint32_t dword)
 {
 }
 
+
 uint8_t ReadByte(uint32_t adddress)
 {
 }
 
+
 uint16_t ReadWord(uint32_t adddress)
 {
 }
 
+
 uint32_t ReadDWord(uint32_t adddress)
 {
 }
 #endif
 
+
 void ShowM68KContext(void)
 {
        printf("\t68K PC=%06X\n", m68k_get_reg(NULL, M68K_REG_PC));
@@ -914,6 +926,7 @@ void ShowM68KContext(void)
        while (disPC < (currpc + 10));
 }
 
+
 //
 // Custom UAE 68000 read/write/IRQ functions
 //
@@ -1005,10 +1018,17 @@ int irq_ack_handler(int level)
        return M68K_INT_ACK_AUTOVECTOR;
 }
 
+
 //#define USE_NEW_MMU
 
 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)
+               M68KSetHalt();
+#endif
+
        // Musashi does this automagically for you, UAE core does not :-P
        address &= 0x00FFFFFF;
 #ifdef CPU_DEBUG_MEMORY
@@ -1056,11 +1076,18 @@ unsigned int m68k_read_memory_8(unsigned int address)
 #endif
 }
 
+
 void gpu_dump_disassembly(void);
 void gpu_dump_registers(void);
 
 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)
+               M68KSetHalt();
+#endif
+
        // Musashi does this automagically for you, UAE core does not :-P
        address &= 0x00FFFFFF;
 #ifdef CPU_DEBUG_MEMORY
@@ -1160,8 +1187,15 @@ unsigned int m68k_read_memory_16(unsigned int address)
 #endif
 }
 
+
 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)
+               M68KSetHalt();
+#endif
+
        // Musashi does this automagically for you, UAE core does not :-P
        address &= 0x00FFFFFF;
 //; So, it seems that it stores the returned DWORD at $51136 and $FB074.
@@ -1176,8 +1210,15 @@ unsigned int m68k_read_memory_32(unsigned int address)
 #endif
 }
 
+
 void m68k_write_memory_8(unsigned int address, unsigned int value)
 {
+#ifdef ALPINE_FUNCTIONS
+       // Check if breakpoint on memory is active, and deal with it
+       if (bpmActive && address == bpmAddress1)
+               M68KSetHalt();
+#endif
+
        // Musashi does this automagically for you, UAE core does not :-P
        address &= 0x00FFFFFF;
 #ifdef CPU_DEBUG_MEMORY
@@ -1226,8 +1267,15 @@ void m68k_write_memory_8(unsigned int address, unsigned int value)
 #endif
 }
 
+
 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)
+               M68KSetHalt();
+#endif
+
        // Musashi does this automagically for you, UAE core does not :-P
        address &= 0x00FFFFFF;
 #ifdef CPU_DEBUG_MEMORY
@@ -1314,8 +1362,15 @@ if (address == 0xF02110)
 #endif
 }
 
+
 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)
+               M68KSetHalt();
+#endif
+
        // Musashi does this automagically for you, UAE core does not :-P
        address &= 0x00FFFFFF;
 /*if (address == 0x4E00)
@@ -1354,12 +1409,14 @@ uint32_t JaguarGetHandler(uint32_t i)
        return JaguarReadLong(i * 4);
 }
 
+
 bool JaguarInterruptHandlerIsValid(uint32_t i) // Debug use only...
 {
        uint32_t handler = JaguarGetHandler(i);
        return (handler && (handler != 0xFFFFFFFF) ? true : false);
 }
 
+
 void M68K_show_context(void)
 {
        WriteLog("68K PC=%06X\n", m68k_get_reg(NULL, M68K_REG_PC));
@@ -1412,6 +1469,7 @@ void M68K_show_context(void)
        }
 }
 
+
 //
 // Unknown read/write byte/word routines
 //
@@ -1446,6 +1504,7 @@ void jaguar_unknown_writebyte(unsigned address, unsigned data, uint32_t who/*=UN
 #endif
 }
 
+
 void jaguar_unknown_writeword(unsigned address, unsigned data, uint32_t who/*=UNKNOWN*/)
 {
 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
@@ -1460,6 +1519,7 @@ void jaguar_unknown_writeword(unsigned address, unsigned data, uint32_t who/*=UN
 #endif
 }
 
+
 unsigned jaguar_unknown_readbyte(unsigned address, uint32_t who/*=UNKNOWN*/)
 {
 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
@@ -1475,6 +1535,7 @@ unsigned jaguar_unknown_readbyte(unsigned address, uint32_t who/*=UNKNOWN*/)
     return 0xFF;
 }
 
+
 unsigned jaguar_unknown_readword(unsigned address, uint32_t who/*=UNKNOWN*/)
 {
 #ifdef LOG_UNMAPPED_MEMORY_ACCESSES
@@ -1490,6 +1551,7 @@ unsigned jaguar_unknown_readword(unsigned address, uint32_t who/*=UNKNOWN*/)
     return 0xFFFF;
 }
 
+
 //
 // Disassemble M68K instructions at the given offset
 //
@@ -1499,16 +1561,19 @@ unsigned int m68k_read_disassembler_8(unsigned int address)
        return m68k_read_memory_8(address);
 }
 
+
 unsigned int m68k_read_disassembler_16(unsigned int address)
 {
        return m68k_read_memory_16(address);
 }
 
+
 unsigned int m68k_read_disassembler_32(unsigned int address)
 {
        return m68k_read_memory_32(address);
 }
 
+
 void JaguarDasm(uint32_t offset, uint32_t qt)
 {
 #ifdef CPU_DEBUG
@@ -1530,6 +1595,7 @@ void JaguarDasm(uint32_t offset, uint32_t qt)
 #endif
 }
 
+
 uint8_t JaguarReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/)
 {
        uint8_t data = 0x00;
@@ -1556,6 +1622,7 @@ uint8_t JaguarReadByte(uint32_t offset, uint32_t who/*=UNKNOWN*/)
        return data;
 }
 
+
 uint16_t JaguarReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/)
 {
        offset &= 0xFFFFFF;
@@ -1585,6 +1652,7 @@ uint16_t JaguarReadWord(uint32_t offset, uint32_t who/*=UNKNOWN*/)
        return jaguar_unknown_readword(offset, who);
 }
 
+
 void JaguarWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/)
 {
 /*     if (offset >= 0x4E00 && offset < 0x4E04)
@@ -1621,6 +1689,7 @@ void JaguarWriteByte(uint32_t offset, uint8_t data, uint32_t who/*=UNKNOWN*/)
        jaguar_unknown_writebyte(offset, data, who);
 }
 
+
 uint32_t starCount;
 void JaguarWriteWord(uint32_t offset, uint16_t data, uint32_t who/*=UNKNOWN*/)
 {
@@ -1756,12 +1825,14 @@ if (offset == 0x11D31A + 0x48000 || offset == 0x11D31A)
        jaguar_unknown_writeword(offset, data, who);
 }
 
+
 // We really should re-do this so that it does *real* 32-bit access... !!! FIX !!!
 uint32_t JaguarReadLong(uint32_t offset, uint32_t who/*=UNKNOWN*/)
 {
        return (JaguarReadWord(offset, who) << 16) | JaguarReadWord(offset+2, who);
 }
 
+
 // We really should re-do this so that it does *real* 32-bit access... !!! FIX !!!
 void JaguarWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/)
 {
@@ -1778,18 +1849,21 @@ void JaguarWriteLong(uint32_t offset, uint32_t data, uint32_t who/*=UNKNOWN*/)
        JaguarWriteWord(offset+2, data & 0xFFFF, who);
 }
 
+
 void JaguarSetScreenBuffer(uint32_t * buffer)
 {
        // This is in TOM, but we set it here...
        screenBuffer = buffer;
 }
 
+
 void JaguarSetScreenPitch(uint32_t pitch)
 {
        // This is in TOM, but we set it here...
        screenPitch = pitch;
 }
 
+
 //
 // Jaguar console initialization
 //
index 54e25aeacd7760abf5b6ed612fded3099ab11758..63e6de6238ca4876b0859b451754f2eaafe93c16 100644 (file)
@@ -28,6 +28,8 @@ extern int32_t jaguarCPUInExec;
 extern uint32_t jaguarMainROMCRC32, jaguarROMSize, jaguarRunAddress;
 extern char * jaguarEepromsPath;
 extern bool jaguarCartInserted;
+extern bool bpmActive;
+extern uint32_t bpmAddress1;
 
 // Various clock rates
 
index dd5dfc1e74f1b7aea3880294f3621b9bdf2807a2..13015d0558bf72d70d449c70d1a702c9b1f73ce1 100644 (file)
@@ -127,6 +127,18 @@ void DumpRegisters(void)
 #endif
 
 
+void M68KSetHalt(void)
+{
+       regs.stopped = 1;
+}
+
+
+void M68KClearHalt(void)
+{
+       regs.stopped = 0;
+}
+
+
 void m68k_set_cpu_type(unsigned int type)
 {
 }
@@ -327,6 +339,16 @@ if (inRoutine)
 
 //printf("Executed opcode $%04X (%i cycles)...\n", opcode, cycles);
 #endif
+               // This is so our debugging code can break in on a dime.
+               // Otherwise, this is just extra slow down :-P
+               if (regs.stopped)
+               {
+                       num_cycles = initialCycles - regs.remainingCycles;
+                       regs.remainingCycles = 0;       // int32_t
+                       regs.interruptCycles = 0;       // uint32_t
+
+                       return num_cycles;
+               }
        }
        while (regs.remainingCycles > 0);
 
@@ -466,11 +488,14 @@ void m68ki_exception_interrupt(uint32_t intLevel)
 #endif /* M68K_EMULATE_INT_ACK */
 #else
        // Turn off the stopped state
-       regs.stopped = 0;
+// Needed?
+//     regs.stopped = 0;
 
 //JLH: need to add halt state?
+// prolly, for debugging/alpine mode... :-/
+// but then again, this should be handled already by the main execution loop :-P
        // If we are halted, don't do anything
-//     if (CPU_STOPPED)
+//     if (regs.stopped)
 //             return;
 
        // Acknowledge the interrupt (NOTE: This is a user supplied function!)
index 613bb11c68baed8ad0ddec5d46ed58b2da415656..a3c6e3c73262abd691379a1055b5a6d93b917095 100644 (file)
@@ -97,6 +97,10 @@ int irq_ack_handler(int);
 void M68KInstructionHook(void);
 #endif
 
+// Functions to allow debugging
+void M68KSetHalt(void);
+void M68KClearHalt(void);
+
 /* Peek at the internals of a CPU context.  This can either be a context
  * retrieved using m68k_get_context() or the currently running context.
  * If context is NULL, the currently running CPU context will be used.