Index: debugger/breakpoints.c
===================================================================
--- debugger/breakpoints.c (revision 338)
+++ debugger/breakpoints.c (working copy)
@@ -42,6 +42,8 @@
return -1;
}
g_Breakpoints[g_NumBreakpoints].address=address;
+ g_Breakpoints[g_NumBreakpoints].endaddr=address;
+ BPT_SET_FLAG(g_Breakpoints[g_NumBreakpoints], BPT_FLAG_WRITE);
enable_breakpoint(g_NumBreakpoints);
@@ -49,6 +51,17 @@
}
+int add_breakpoint_struct(breakpoint* newbp)
+{
+ if( g_NumBreakpoints == BREAKPOINTS_MAX_NUMBER ) {
+ printf("BREAKPOINTS_MAX_NUMBER have been reached.\n");//REMOVE ME
+ return -1;
+ }
+ memcpy(&g_Breakpoints[g_NumBreakpoints], newbp, sizeof(breakpoint));
+ printf("newbp %08X - %08X\n", g_Breakpoints[g_NumBreakpoints].address, g_Breakpoints[g_NumBreakpoints].endaddr);
+ return g_NumBreakpoints++;
+}
+
void enable_breakpoint( int breakpoint )
{
BPT_SET_FLAG(g_Breakpoints[breakpoint], BPT_FLAG_ENABLED);
@@ -68,7 +81,7 @@
void remove_breakpoint_by_address( uint32 address )
{
- int bpt = lookup_breakpoint( address );
+ int bpt = lookup_breakpoint( address, 0 );
if(bpt==-1)
{
printf("Tried to remove Nonexistant breakpoint %x!", address);
@@ -77,13 +90,17 @@
remove_breakpoint_by_num( bpt );
}
-int lookup_breakpoint( uint32 address )
+int lookup_breakpoint( uint32 address, uint32 flags)
{
int i=0;
while( i != g_NumBreakpoints )
{
- if( g_Breakpoints[i].address==address )
+ if((address >= g_Breakpoints[i].address) && (address <= g_Breakpoints[i].endaddr) && (!flags || ((g_Breakpoints[i].flags & flags) == flags)))
+ {
+ printf("Bpt %d (0x%08X - 0x%08X) matches 0x%08X\n", i, g_Breakpoints[i].address,
+ g_Breakpoints[i].endaddr, address);
return i;
+ }
else
i++;
}
@@ -92,8 +109,36 @@
int check_breakpoints( uint32 address )
{
- int bpt=lookup_breakpoint( address );
- if( (bpt != -1) && BPT_CHECK_FLAG(g_Breakpoints[bpt], BPT_FLAG_ENABLED) )
+ int bpt=lookup_breakpoint( address, BPT_FLAG_ENABLED | BPT_FLAG_EXEC );
+ //if( (bpt != -1) && BPT_CHECK_FLAG(g_Breakpoints[bpt], BPT_FLAG_ENABLED))
return bpt;
+ //return -1;
+}
+
+
+int check_breakpoints_on_mem_access( uint32 address, uint32 size, uint32 flags )
+{
+ //This function handles memory read/write breakpoints. size specifies the address
+ //range to check, flags specifies the flags that all need to be set.
+ //It automatically stops and updates the debugger on hit, so the memory access
+ //functions only need to call it and can discard the result.
+
+ int i, bpt;
+ for(i=address; i<=(address + size); i++)
+ {
+ bpt=lookup_breakpoint( address, flags );
+ if(bpt != -1)
+ {
+ run = 0;
+ switch_button_to_run();
+ update_debugger_frontend();
+
+ previousPC = PC->addr;
+ // Emulation thread is blocked until a button is clicked.
+ pthread_cond_wait(&debugger_done_cond, &mutex);
+
+ return bpt;
+ }
+ }
return -1;
}
Index: debugger/debugger.c
===================================================================
--- debugger/debugger.c (revision 338)
+++ debugger/debugger.c (working copy)
@@ -63,7 +63,7 @@
{
if(run==2) {
- if( check_breakpoints(PC->addr)==-1 ) {
+ if( check_breakpoints(PC->addr)==-1 ) {
previousPC = PC->addr;
return;
}
Index: debugger/breakpoints.h
===================================================================
--- debugger/breakpoints.h (revision 338)
+++ debugger/breakpoints.h (working copy)
@@ -39,7 +39,10 @@
#define BPT_FLAG_ENABLED 0x01
#define BPT_FLAG_CONDITIONAL 0x02
-#define BPT_FLAG_COUNTER 0x04
+#define BPT_FLAG_COUNTER 0x04
+#define BPT_FLAG_READ 0x08
+#define BPT_FLAG_WRITE 0x10
+#define BPT_FLAG_EXEC 0x20
#define BPT_CHECK_FLAG(a, b) ((a.flags & b) == b)
#define BPT_SET_FLAG(a, b) a.flags = (a.flags | b);
@@ -47,7 +50,8 @@
#define BPT_TOGGLE_FLAG(a, b) a.flags = (a.flags ^ b);
typedef struct _breakpoint {
- uint32 address;
+ uint32 address;
+ uint32 endaddr;
uint32 flags;
//uint32 condition; //Placeholder for breakpoint condition
} breakpoint;
@@ -57,10 +61,12 @@
int add_breakpoint( uint32 address );
+int add_breakpoint_struct(breakpoint* newbp);
void remove_breakpoint_by_address( uint32 address );
void enable_breakpoint( int breakpoint );
void disable_breakpoint( int breakpoint );
int check_breakpoints( uint32 address );
-int lookup_breakpoint( uint32 address );
+int check_breakpoints_on_mem_access( uint32 address, uint32 size, uint32 flags );
+int lookup_breakpoint( uint32 address, uint32 flags );
#endif // BREAKPOINTS_H
Index: memory/memory.c
===================================================================
--- memory/memory.c (revision 338)
+++ memory/memory.c (working copy)
@@ -48,6 +48,10 @@
#include "../main/plugin.h"
#include "../main/vcr.h"
+#if DBG
+#include "../debugger/breakpoints.h"
+#endif
+
/* definitions of the rcp's structures and memory area */
RDRAM_register rdram_register;
mips_register MI_register;
@@ -1421,22 +1425,34 @@
}
void read_rdram()
-{;
+{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned int *)(rdramb + (address & 0xFFFFFF)));
}
void read_rdramb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *(rdramb + ((address & 0xFFFFFF)^S8));
}
void read_rdramh()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short *)(rdramb + ((address & 0xFFFFFF)^S16)));
}
void read_rdramd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long int)(*(unsigned int *)(rdramb + (address & 0xFFFFFF))) << 32) |
((*(unsigned int *)(rdramb + (address & 0xFFFFFF) + 4)));
}
@@ -1531,21 +1547,33 @@
void write_rdram()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((unsigned int *)(rdramb + (address & 0xFFFFFF))) = word;
}
void write_rdramb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((rdramb + ((address & 0xFFFFFF)^S8))) = byte;
}
void write_rdramh()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*(unsigned short *)((rdramb + ((address & 0xFFFFFF)^S16))) = hword;
}
void write_rdramd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((unsigned int *)(rdramb + (address & 0xFFFFFF))) = dword >> 32;
*((unsigned int *)(rdramb + (address & 0xFFFFFF) + 4 )) = dword & 0xFFFFFFFF;
}
@@ -1945,75 +1973,114 @@
void read_rsp()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ); //FIXME: access breakpoints not tested in these functions; possibly should be using address_low here
+ #endif
*rdword = *(readrsp[*address_low]);
}
void read_rspb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned char*)readrsp[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_rsph()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_rspd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long int)(*readrsp[*address_low])<<32) |
*readrsp[*address_low+4];
}
void write_rsp()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*readrsp[*address_low] = word;
}
void write_rspb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((unsigned char*)readrsp[*address_low & 0xfffc]
+ ((*address_low&3)^S8) ) = byte;
}
void write_rsph()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((unsigned short*)((unsigned char*)readrsp[*address_low & 0xfffc]
+ ((*address_low&3)^S16) )) = hword;
}
void write_rspd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*readrsp[*address_low] = dword >> 32;
*readrsp[*address_low+4] = dword & 0xFFFFFFFF;
}
void read_dp()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *(readdp[*address_low]);
}
void read_dpb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned char*)readdp[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_dph()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short*)((unsigned char*)readdp[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_dpd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long int)(*readdp[*address_low])<<32) |
*readdp[*address_low+4];
}
void write_dp()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0xc:
@@ -2043,6 +2110,9 @@
void write_dpb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0xc:
@@ -2098,6 +2168,9 @@
void write_dph()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0xc:
@@ -2137,6 +2210,9 @@
void write_dpd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x8:
@@ -2164,75 +2240,114 @@
void read_dps()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *(readdps[*address_low]);
}
void read_dpsb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned char*)readdps[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_dpsh()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_dpsd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long int)(*readdps[*address_low])<<32) |
*readdps[*address_low+4];
}
void write_dps()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*readdps[*address_low] = word;
}
void write_dpsb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((unsigned char*)readdps[*address_low & 0xfffc]
+ ((*address_low&3)^S8) ) = byte;
}
void write_dpsh()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((unsigned short*)((unsigned char*)readdps[*address_low & 0xfffc]
+ ((*address_low&3)^S16) )) = hword;
}
void write_dpsd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*readdps[*address_low] = dword >> 32;
*readdps[*address_low+4] = dword & 0xFFFFFFFF;
}
void read_mi()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *(readmi[*address_low]);
}
void read_mib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned char*)readmi[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_mih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short*)((unsigned char*)readmi[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_mid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long int)(*readmi[*address_low])<<32) |
*readmi[*address_low+4];
}
void write_mi()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -2252,6 +2367,9 @@
void write_mib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -2279,6 +2397,9 @@
void write_mih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -2302,6 +2423,9 @@
void write_mid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -2321,6 +2445,9 @@
void read_vi()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
switch(*address_low)
{
case 0x10:
@@ -2334,6 +2461,9 @@
void read_vib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
switch(*address_low)
{
case 0x10:
@@ -2351,6 +2481,9 @@
void read_vih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
switch(*address_low)
{
case 0x10:
@@ -2366,6 +2499,9 @@
void read_vid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
switch(*address_low)
{
case 0x10:
@@ -2380,6 +2516,9 @@
void write_vi()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -2409,6 +2548,9 @@
void write_vib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
int temp;
switch(*address_low)
{
@@ -2455,6 +2597,9 @@
void write_vih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
int temp;
switch(*address_low)
{
@@ -2495,6 +2640,9 @@
void write_vid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -2528,6 +2676,9 @@
void read_ai()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
switch(*address_low)
{
case 0x4:
@@ -2545,6 +2696,9 @@
void read_aib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
unsigned int len;
switch(*address_low)
{
@@ -2568,6 +2722,9 @@
void read_aih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
unsigned int len;
switch(*address_low)
{
@@ -2590,6 +2747,9 @@
void read_aid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -2609,6 +2769,9 @@
void write_ai()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
unsigned int delay=0;
switch(*address_low)
{
@@ -2710,6 +2873,9 @@
void write_aib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
int temp;
unsigned int delay=0;
switch(*address_low)
@@ -2820,6 +2986,9 @@
void write_aih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
int temp;
unsigned int delay=0;
switch(*address_low)
@@ -2924,6 +3093,9 @@
void write_aid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
unsigned int delay=0;
switch(*address_low)
{
@@ -3021,29 +3193,44 @@
void read_pi()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *(readpi[*address_low]);
}
void read_pib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned char*)readpi[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_pih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short*)((unsigned char*)readpi[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_pid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long int)(*readpi[*address_low])<<32) |
*readpi[*address_low+4];
}
void write_pi()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x8:
@@ -3078,6 +3265,9 @@
void write_pib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x8:
@@ -3139,6 +3329,9 @@
void write_pih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x8:
@@ -3190,6 +3383,9 @@
void write_pid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x8:
@@ -3220,75 +3416,114 @@
void read_ri()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *(readri[*address_low]);
}
void read_rib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned char*)readri[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_rih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_rid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long int)(*readri[*address_low])<<32) |
*readri[*address_low+4];
}
void write_ri()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*readri[*address_low] = word;
}
void write_rib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((unsigned char*)readri[*address_low & 0xfffc]
+ ((*address_low&3)^S8) ) = byte;
}
void write_rih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*((unsigned short*)((unsigned char*)readri[*address_low & 0xfffc]
+ ((*address_low&3)^S16) )) = hword;
}
void write_rid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
*readri[*address_low] = dword >> 32;
*readri[*address_low+4] = dword & 0xFFFFFFFF;
}
void read_si()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *(readsi[*address_low]);
}
void read_sib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned char*)readsi[*address_low & 0xfffc]
+ ((*address_low&3)^S8) );
}
void read_sih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short*)((unsigned char*)readsi[*address_low & 0xfffc]
+ ((*address_low&3)^S16) ));
}
void read_sid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long int)(*readsi[*address_low])<<32) |
*readsi[*address_low+4];
}
void write_si()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -3316,6 +3551,9 @@
void write_sib()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -3358,6 +3596,9 @@
void write_sih()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -3392,6 +3633,9 @@
void write_sid()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
switch(*address_low)
{
case 0x0:
@@ -3486,6 +3730,9 @@
void read_rom()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
if (lastwrite)
{
*rdword = lastwrite;
@@ -3497,27 +3744,42 @@
void read_romb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *(rom + ((address^S8) & 0x03FFFFFF));
}
void read_romh()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = *((unsigned short *)(rom + ((address^S16) & 0x03FFFFFF)));
}
void read_romd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
*rdword = ((unsigned long long)(*((unsigned int *)(rom+(address&0x03FFFFFF))))<<32)|
*((unsigned int *)(rom + ((address+4)&0x03FFFFFF)));
}
void write_rom()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
lastwrite = word;
}
void read_pif()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
#ifdef EMU64_DEBUG
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
@@ -3531,6 +3793,9 @@
void read_pifb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
#ifdef EMU64_DEBUG
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
@@ -3544,6 +3809,9 @@
void read_pifh()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
#ifdef EMU64_DEBUG
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
@@ -3558,6 +3826,9 @@
void read_pifd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_READ);
+ #endif
#ifdef EMU64_DEBUG
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
@@ -3572,6 +3843,9 @@
void write_pif()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 4, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
#ifdef EMU64_DEBUG
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
@@ -3595,6 +3869,9 @@
void write_pifb()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 1, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
#ifdef EMU64_DEBUG
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
@@ -3618,6 +3895,9 @@
void write_pifh()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 2, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
#ifdef EMU64_DEBUG
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
@@ -3642,6 +3922,9 @@
void write_pifd()
{
+ #if DBG
+ check_breakpoints_on_mem_access(address, 8, BPT_FLAG_ENABLED | BPT_FLAG_WRITE);
+ #endif
#ifdef EMU64_DEBUG
if ((*address_low > 0x7FF) || (*address_low < 0x7C0))
{
Index: main/gui_gtk/debugger/desasm.c
===================================================================
--- main/gui_gtk/debugger/desasm.c (revision 338)
+++ main/gui_gtk/debugger/desasm.c (working copy)
@@ -317,7 +317,7 @@
clicked_address =(uint32) gtk_clist_get_row_data( GTK_CLIST(clist), clicked_row);
printf( "[DASM] click on row: %d\t address: 0x%lX\n", clicked_row, clicked_address );
- break_number = lookup_breakpoint(clicked_address);
+ break_number = lookup_breakpoint(clicked_address, BPT_FLAG_EXEC);
if( break_number==-1 ) {
add_breakpoint( clicked_address );
gtk_clist_set_background( GTK_CLIST(clist), clicked_row, &color_BP);
Index: main/gui_gtk/debugger/breakpoints.c
===================================================================
--- main/gui_gtk/debugger/breakpoints.c (revision 338)
+++ main/gui_gtk/debugger/breakpoints.c (working copy)
@@ -41,6 +41,11 @@
static void on_row_unselection(GtkCList *clist, gint row);
static void on_add();
static void on_remove();
+static void on_enable();
+static void on_disable();
+static void on_toggle();
+static void _toggle(int flag);
+static void on_edit();
static void on_close();
static GtkWidget *clBreakpoints;
@@ -55,7 +60,8 @@
GtkWidget *boxH1,
*scrolledwindow1,
*boxV1,
- *buAdd, *buRemove;
+ *buAdd, *buRemove, *buEnable, *buDisable, *buToggle,
+ *buEdit;
breakpoints_opened = 1;
@@ -84,7 +90,7 @@
clBreakpoints = gtk_clist_new( 1 );
gtk_container_add( GTK_CONTAINER(scrolledwindow1), clBreakpoints );
gtk_clist_set_selection_mode( GTK_CLIST(clBreakpoints), GTK_SELECTION_EXTENDED );
- gtk_clist_set_column_width( GTK_CLIST(clBreakpoints), 0, 80 );
+ gtk_clist_set_column_width( GTK_CLIST(clBreakpoints), 0, 160 );
gtk_clist_set_auto_sort( GTK_CLIST(clBreakpoints), TRUE );
//=== Creation of the Buttons ======================/
@@ -93,8 +99,23 @@
buAdd = gtk_button_new_with_label("Add");
gtk_box_pack_start( GTK_BOX(boxV1), buAdd, FALSE, FALSE, 0 );
+
buRemove = gtk_button_new_with_label( "Remove" );
gtk_box_pack_start( GTK_BOX(boxV1), buRemove, FALSE, FALSE, 0 );
+
+ buEnable = gtk_button_new_with_label( "Enable" );
+ gtk_box_pack_start( GTK_BOX(boxV1), buEnable, FALSE, FALSE, 0 );
+
+ buDisable = gtk_button_new_with_label( "Disable" );
+ gtk_box_pack_start( GTK_BOX(boxV1), buDisable, FALSE, FALSE, 0 );
+
+ buToggle = gtk_button_new_with_label( "Toggle" );
+ gtk_box_pack_start( GTK_BOX(boxV1), buToggle, FALSE, FALSE, 0 );
+
+ buEdit = gtk_button_new_with_label( "Edit" );
+ gtk_box_pack_start( GTK_BOX(boxV1), buEdit, FALSE, FALSE, 0 );
+
+ gtk_widget_set_sensitive(buEdit, FALSE); //not yet implemented
gtk_widget_show_all(winBreakpoints);
@@ -103,6 +124,10 @@
gtk_signal_connect( GTK_OBJECT(clBreakpoints), "unselect-row", on_row_unselection, NULL );
gtk_signal_connect( GTK_OBJECT(buAdd), "clicked", on_add, NULL );
gtk_signal_connect( GTK_OBJECT(buRemove), "clicked", on_remove, NULL );
+ gtk_signal_connect( GTK_OBJECT(buEnable), "clicked", on_enable, NULL );
+ gtk_signal_connect( GTK_OBJECT(buDisable), "clicked", on_disable, NULL );
+ gtk_signal_connect( GTK_OBJECT(buToggle), "clicked", on_toggle, NULL );
+ gtk_signal_connect( GTK_OBJECT(buEdit), "clicked", on_edit, NULL );
gtk_signal_connect( GTK_OBJECT(winBreakpoints), "destroy", on_close, NULL );
color_BPEnabled.red=0xFFFF;
@@ -119,13 +144,34 @@
//]=-=-=-=-=-=-=-=-=-=-=-=[ Update Breakpoints Display ]=-=-=-=-=-=-=-=-=-=-=-=[
+void get_breakpoint_display_string(char* buf, breakpoint* bpt)
+{
+ if(bpt->address == bpt->endaddr)
+ {
+ sprintf(buf, "%c%c%c 0x%08X",
+ (bpt->flags & BPT_FLAG_READ) ? 'R' : '-',
+ (bpt->flags & BPT_FLAG_WRITE) ? 'W' : '-',
+ (bpt->flags & BPT_FLAG_EXEC) ? 'X' : '-',
+ bpt->address);
+ }
+ else
+ {
+ sprintf(buf, "%c%c%c 0x%08X - 0x%08X",
+ (bpt->flags & BPT_FLAG_READ) ? 'R' : '-',
+ (bpt->flags & BPT_FLAG_WRITE) ? 'W' : '-',
+ (bpt->flags & BPT_FLAG_EXEC) ? 'X' : '-',
+ bpt->address, bpt->endaddr);
+ }
+}
+
void update_breakpoints( )
{
int num_rows=0;
- char line[1][16];
+ char line[1][64];
line[0][0] = 0;
+ printf("update_breakpoints()\n");
gtk_clist_freeze( GTK_CLIST(clBreakpoints) );
gtk_clist_clear( GTK_CLIST(clBreakpoints) );
int i;
@@ -134,7 +180,8 @@
for( i=0; i < g_NumBreakpoints; i++ )
{
- sprintf( line, "0x%lX", g_Breakpoints[i].address);
+ get_breakpoint_display_string(line, &g_Breakpoints[i]);
+ printf("%s\n", line);
gtk_clist_set_text( GTK_CLIST(clBreakpoints), i, 0, line );
if(BPT_CHECK_FLAG(g_Breakpoints[i], BPT_FLAG_ENABLED))
gtk_clist_set_background( GTK_CLIST(clBreakpoints), i, &color_BPEnabled);
@@ -152,8 +199,8 @@
//int i = lookup_breakpoint( address );
- remove_breakpoint_by_num( row );
-
+ remove_breakpoint_by_num( row );
+
//gtk_clist_remove( GTK_CLIST(clBreakpoints), row);
update_breakpoints();
}
@@ -175,17 +222,63 @@
static gint modify_address(ClistEditData *ced, const gchar *old, const gchar *new, gpointer data)
{
- uint32 address;
+ breakpoint newbp; //New breakpoint to be added
+ int i;
- if( sscanf(new, "%lX", &address) != 1)
+ //printf( "modify_address %lX \"%s\"\n", address, new);
+
+ //Input format: "[*][r][w][x] address [endaddr]"
+ //*: if present, disabled by default
+ //r: if present, break on read
+ //w: if present, break on write
+ //x: if present, break on execute (if none of r, w, x is specified execute is the default)
+ //address: where to break
+ //endaddr: if specified, break on all addresses address <= x <= endaddr
+
+ //Enabled by default
+ newbp.flags = BPT_FLAG_ENABLED;
+ newbp.address = 0;
+ newbp.endaddr = 0;
+
+ //Read flags
+ for(i=0; new[i]; i++)
{
- return FALSE;
- }
- printf( "%lX\n", address);
- gtk_clist_set_row_data( GTK_CLIST(ced->clist), ced->row, (gpointer) address );
-
- g_Breakpoints[g_NumBreakpoints-1].address=address;
- return TRUE;
+ if((new[i] == ' ') //if space,
+ || ((new[i] >= '0') && (new[i] <= '9')) //number,
+ || ((new[i] >= 'A') && (new[i] <= 'F')) //A-F,
+ || ((new[i] >= 'a') && (new[i] <= 'f'))) break; //or a-f, address begins here.
+ else if(new[i] == '*') newbp.flags &= ~BPT_FLAG_ENABLED;
+ else if((new[i] == 'r') || (new[i] == 'R')) newbp.flags |= BPT_FLAG_READ;
+ else if((new[i] == 'w') || (new[i] == 'w')) newbp.flags |= BPT_FLAG_WRITE;
+ else if((new[i] == 'x') || (new[i] == 'x')) newbp.flags |= BPT_FLAG_EXEC;
+ }
+
+ //If none of r/w/x specified, default to exec
+ if(!(newbp.flags & (BPT_FLAG_EXEC | BPT_FLAG_READ | BPT_FLAG_WRITE)))
+ BPT_SET_FLAG(newbp, BPT_FLAG_EXEC);
+
+ //Read address
+ printf("Address \"%s\"\n", &new[i]);
+ i = sscanf(&new[i], "%lX %lx", &newbp.address, &newbp.endaddr);
+ if(!i)
+ {
+ //fixme: better way to display error message
+ printf("Invalid address\n");
+ return FALSE;
+ }
+ else if(i == 1) newbp.endaddr = newbp.address;
+
+ printf("Adding breakpoint on 0x%08X - 0x%08X flags 0x%08X\n", newbp.address, newbp.endaddr, newbp.flags);
+ if(add_breakpoint_struct(&newbp) == -1)
+ {
+ //fixme: warning message
+ return FALSE;
+ }
+
+ gtk_clist_set_row_data( GTK_CLIST(ced->clist), ced->row, (gpointer) newbp.address );
+
+ update_breakpoints();
+ return FALSE; //don't add the typed string, update_breakpoints() handles it
}
static void on_add()
@@ -193,23 +286,40 @@
int new_row; //index of the appended row.
char **line;
- if(add_breakpoint(address) == -1)
+ //fixme: hacks ahoy!
+ line = malloc(1*sizeof(char*));
+ line[0] = malloc(64*sizeof(char));
+
+ line[0] = (char*)malloc(64);
+ //sprintf( line[0], "0x%lX", address);
+ line[0] = 0;
+ new_row = gtk_clist_append( GTK_CLIST(clBreakpoints), line );
+ gtk_clist_set_text( GTK_CLIST(clBreakpoints), new_row, 0, (gpointer) line[0] );
+
+ clist_edit_by_row(GTK_CLIST(clBreakpoints), new_row, 0, modify_address, NULL);
+ free(line[0]);
+ free(line);
+
+/*
+ if(add_breakpoint(address) == -1)
{
//TODO: warn max number of breakpoints reached
return;
}
-
- line = malloc(1*sizeof(char*)); // new breakpoint:
- line[0] = malloc(16*sizeof(char)); // - address
+
+ line = malloc(1*sizeof(char*)); // new breakpoint:
+ line[0] = malloc(64*sizeof(char)); // - address
// TODO: line[1] = malloc(16*sizeof(char)); // - enabled/disabled
sprintf( line[0], "0x%lX", address);
new_row = gtk_clist_append( GTK_CLIST(clBreakpoints), line );
- gtk_clist_set_text( GTK_CLIST(clBreakpoints), new_row, 0, (gpointer) address );
+ gtk_clist_set_text( GTK_CLIST(clBreakpoints), new_row, 0, (gpointer) line[0] );
clist_edit_by_row(GTK_CLIST(clBreakpoints), new_row, 0, modify_address, NULL);
+ update_breakpoints();
//FIXME:color are not updated +everything
+ */
}
@@ -218,10 +328,11 @@
int i;
uint32 address;
- gtk_clist_freeze( GTK_CLIST(clBreakpoints) );
+ if(!g_NumBreakpoints) return;
+ gtk_clist_freeze( GTK_CLIST(clBreakpoints) );
for( i=BREAKPOINTS_MAX_NUMBER-1; i>=0; i-- )
{
- if( selected[i] == 1 ) {
+ if( selected[i] == 1 ) {
address = (uint32) gtk_clist_get_row_data( GTK_CLIST(clBreakpoints), i);
remove_breakpoint_by_row( i );
update_desasm_color( address );
@@ -233,6 +344,51 @@
}
+static void on_enable()
+{
+ _toggle(1);
+}
+
+static void on_disable()
+{
+ _toggle(0);
+}
+
+
+static void on_toggle()
+{
+ _toggle(-1);
+}
+
+//flag is 1 for enable, 0 for disable, -1 for toggle
+static void _toggle(int flag)
+{
+ int i;
+
+ if(!g_NumBreakpoints) return;
+ for( i=BREAKPOINTS_MAX_NUMBER-1; i>=0; i-- )
+ {
+ if( selected[i] == 1 )
+ {
+ if(flag == 1) enable_breakpoint(i);
+ else if(flag == 0) disable_breakpoint(i);
+ else if(BPT_CHECK_FLAG(g_Breakpoints[i], BPT_FLAG_ENABLED)) disable_breakpoint(i);
+ else enable_breakpoint(i);
+ selected[i] = 0;
+ }
+ }
+ update_breakpoints();
+}
+
+
+static void on_edit()
+{
+ //FIXME: not yet implemented. should display the textbox again as if we were entering
+ //a new breakpoint, and update the selected one. probably disable the button if more
+ //than one or none selected.
+}
+
+
static void on_close()
{
breakpoints_opened = 0;
Index: main/gui_gtk/debugger/breakpoints.h
===================================================================
--- main/gui_gtk/debugger/breakpoints.h (revision 338)
+++ main/gui_gtk/debugger/breakpoints.h (working copy)
@@ -45,6 +45,7 @@
GtkWidget *winBreakpoints;
void init_breakpoints();
+void get_breakpoint_display_string(char* buf, breakpoint* bpt);
int add_breakpoint( uint32 address );
//int check_breakpoints( uint32 address );
void update_breakpoints();