mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-06-04 12:29:58 +00:00
Add break point function for Basilisk II in cxmon.
To enter break point, you need to run a m68k program in Macintosh guest OS. The program executes a new emul_op instruction 0x7138. The program will be provided in cxmon/utils folder in a separate commit. Once emulation is suspended, you can enter below new cxmon command to manipluate break points: ba [address] Add a break point br [breakpoints#] Remove a break point. If # is 0, remove all break points. bd [breakpoints#] Disable a break point. If # is 0, disable all break points. be [breakpoints#] Enable a break point. If # is 0, enable all break points. bi List all break points bs "file" Save all break points to a file bl "file" Load break points from a file Once emulation PC reach break point address, it automatically suspends and traps into cxmon. Signed-off-by: Ricky Zhang <rickyzhang@gmail.com>
This commit is contained in:
parent
723bedd55a
commit
f3895493ae
|
@ -564,6 +564,23 @@ void EmulOp(uint16 opcode, M68kRegisters *r)
|
||||||
r->a[0] = ReadMacInt32(0x2b6);
|
r->a[0] = ReadMacInt32(0x2b6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case M68K_EMUL_OP_SUSPEND: {
|
||||||
|
printf("*** Suspend\n");
|
||||||
|
printf("d0 %08x d1 %08x d2 %08x d3 %08x\n"
|
||||||
|
"d4 %08x d5 %08x d6 %08x d7 %08x\n"
|
||||||
|
"a0 %08x a1 %08x a2 %08x a3 %08x\n"
|
||||||
|
"a4 %08x a5 %08x a6 %08x a7 %08x\n"
|
||||||
|
"sr %04x\n",
|
||||||
|
r->d[0], r->d[1], r->d[2], r->d[3], r->d[4], r->d[5], r->d[6], r->d[7],
|
||||||
|
r->a[0], r->a[1], r->a[2], r->a[3], r->a[4], r->a[5], r->a[6], r->a[7],
|
||||||
|
r->sr);
|
||||||
|
#ifdef ENABLE_MON
|
||||||
|
char *arg[4] = {"mon", "-m", "-r", NULL};
|
||||||
|
mon(3, arg);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("FATAL: EMUL_OP called with bogus opcode %08x\n", opcode);
|
printf("FATAL: EMUL_OP called with bogus opcode %08x\n", opcode);
|
||||||
printf("d0 %08x d1 %08x d2 %08x d3 %08x\n"
|
printf("d0 %08x d1 %08x d2 %08x d3 %08x\n"
|
||||||
|
|
|
@ -90,6 +90,7 @@ enum {
|
||||||
M68K_EMUL_OP_SOUNDIN_CLOSE,
|
M68K_EMUL_OP_SOUNDIN_CLOSE,
|
||||||
M68K_EMUL_OP_DEBUGUTIL,
|
M68K_EMUL_OP_DEBUGUTIL,
|
||||||
M68K_EMUL_OP_IDLE_TIME,
|
M68K_EMUL_OP_IDLE_TIME,
|
||||||
|
M68K_EMUL_OP_SUSPEND,
|
||||||
M68K_EMUL_OP_MAX // highest number
|
M68K_EMUL_OP_MAX // highest number
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -43,11 +43,6 @@ extern int intlev(void); // From baisilisk_glue.cpp
|
||||||
B2_mutex *spcflags_lock = NULL;
|
B2_mutex *spcflags_lock = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLE_MON
|
|
||||||
#include "mon.h"
|
|
||||||
#include "mon_disass.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool quit_program = false;
|
bool quit_program = false;
|
||||||
struct flag_struct regflags;
|
struct flag_struct regflags;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,13 @@
|
||||||
#include "m68k.h"
|
#include "m68k.h"
|
||||||
#include "readcpu.h"
|
#include "readcpu.h"
|
||||||
#include "spcflags.h"
|
#include "spcflags.h"
|
||||||
|
|
||||||
|
#if ENABLE_MON
|
||||||
|
#include "mon.h"
|
||||||
|
#include "mon_disass.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
extern int areg_byteinc[];
|
extern int areg_byteinc[];
|
||||||
extern int imm8_table[];
|
extern int imm8_table[];
|
||||||
|
|
||||||
|
@ -74,6 +80,7 @@ struct comptbl {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void REGPARAM2 op_illg (uae_u32) REGPARAM;
|
extern void REGPARAM2 op_illg (uae_u32) REGPARAM;
|
||||||
|
extern void m68k_dumpstate(uaecptr *nextpc);
|
||||||
|
|
||||||
typedef char flagtype;
|
typedef char flagtype;
|
||||||
|
|
||||||
|
@ -147,8 +154,6 @@ static __inline__ uae_u32 get_ilong_prefetch (uae_s32 o)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define m68k_incpc(o) (regs.pc_p += (o))
|
|
||||||
|
|
||||||
static __inline__ void fill_prefetch_0 (void)
|
static __inline__ void fill_prefetch_0 (void)
|
||||||
{
|
{
|
||||||
#if USE_PREFETCH_BUFFER
|
#if USE_PREFETCH_BUFFER
|
||||||
|
@ -175,6 +180,55 @@ static __inline__ void fill_prefetch_2 (void)
|
||||||
#define fill_prefetch_2 fill_prefetch_0
|
#define fill_prefetch_2 fill_prefetch_0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static __inline__ uaecptr m68k_getpc (void)
|
||||||
|
{
|
||||||
|
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
||||||
|
return get_virtual_address(regs.pc_p);
|
||||||
|
#else
|
||||||
|
return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void m68k_setpc (uaecptr newpc)
|
||||||
|
{
|
||||||
|
#if ENABLE_MON
|
||||||
|
uae_u32 previous_pc = m68k_getpc();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
||||||
|
regs.pc_p = get_real_address(newpc);
|
||||||
|
#else
|
||||||
|
regs.pc_p = regs.pc_oldp = get_real_address(newpc);
|
||||||
|
regs.pc = newpc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLE_MON
|
||||||
|
if(isBreakPoint(newpc)) {
|
||||||
|
printf("Stopped at break point address: %08lx. Last PC: %08lx\n", newpc, previous_pc);
|
||||||
|
m68k_dumpstate(NULL);
|
||||||
|
char *arg[4] = {"mon", "-m", "-r", NULL};
|
||||||
|
mon(3, arg);
|
||||||
|
}
|
||||||
|
#endif // end of #if ENABLE_MON
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline__ void m68k_incpc (uae_s32 delta)
|
||||||
|
{
|
||||||
|
#if ENABLE_MON
|
||||||
|
uae_u32 previous_pc = m68k_getpc();
|
||||||
|
#endif
|
||||||
|
regs.pc_p += (delta);
|
||||||
|
#if ENABLE_MON
|
||||||
|
uaecptr next_pc = m68k_getpc();
|
||||||
|
if(isBreakPoint(next_pc)) {
|
||||||
|
printf("Stopped at break point address: %08lx. Last PC: %08lx\n", next_pc, previous_pc);
|
||||||
|
m68k_dumpstate(NULL);
|
||||||
|
char *arg[4] = {"mon", "-m", "-r", NULL};
|
||||||
|
mon(3, arg);
|
||||||
|
}
|
||||||
|
#endif // end of #if ENABLE_MON
|
||||||
|
}
|
||||||
|
|
||||||
/* These are only used by the 68020/68881 code, and therefore don't
|
/* These are only used by the 68020/68881 code, and therefore don't
|
||||||
* need to handle prefetch. */
|
* need to handle prefetch. */
|
||||||
static __inline__ uae_u32 next_ibyte (void)
|
static __inline__ uae_u32 next_ibyte (void)
|
||||||
|
@ -198,25 +252,6 @@ static __inline__ uae_u32 next_ilong (void)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline__ void m68k_setpc (uaecptr newpc)
|
|
||||||
{
|
|
||||||
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
|
||||||
regs.pc_p = get_real_address(newpc);
|
|
||||||
#else
|
|
||||||
regs.pc_p = regs.pc_oldp = get_real_address(newpc);
|
|
||||||
regs.pc = newpc;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static __inline__ uaecptr m68k_getpc (void)
|
|
||||||
{
|
|
||||||
#if REAL_ADDRESSING || DIRECT_ADDRESSING
|
|
||||||
return get_virtual_address(regs.pc_p);
|
|
||||||
#else
|
|
||||||
return regs.pc + ((char *)regs.pc_p - (char *)regs.pc_oldp);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define m68k_setpc_fast m68k_setpc
|
#define m68k_setpc_fast m68k_setpc
|
||||||
#define m68k_setpc_bcc m68k_setpc
|
#define m68k_setpc_bcc m68k_setpc
|
||||||
#define m68k_setpc_rte m68k_setpc
|
#define m68k_setpc_rte m68k_setpc
|
||||||
|
|
|
@ -55,6 +55,9 @@ extern "C" {
|
||||||
#define VERSION "3"
|
#define VERSION "3"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Break points
|
||||||
|
BREAK_POINT_SET active_break_points;
|
||||||
|
BREAK_POINT_SET disabled_break_points;
|
||||||
|
|
||||||
// Buffer we're operating on
|
// Buffer we're operating on
|
||||||
bool mon_use_real_mem = false;
|
bool mon_use_real_mem = false;
|
||||||
|
@ -1043,6 +1046,13 @@ void mon_init()
|
||||||
mon_add_command("i", ascii_dump, "i [start [end]] ASCII memory dump\n");
|
mon_add_command("i", ascii_dump, "i [start [end]] ASCII memory dump\n");
|
||||||
mon_add_command("m", memory_dump, "m [start [end]] Hex/ASCII memory dump\n");
|
mon_add_command("m", memory_dump, "m [start [end]] Hex/ASCII memory dump\n");
|
||||||
mon_add_command("b", binary_dump, "b [start [end]] Binary memory dump\n");
|
mon_add_command("b", binary_dump, "b [start [end]] Binary memory dump\n");
|
||||||
|
mon_add_command("ba", break_point_add, "ba [address] Add a break point\n");
|
||||||
|
mon_add_command("br", break_point_remove, "br [breakpoints#] Remove a break point. If # is 0, remove all break points.\n");
|
||||||
|
mon_add_command("bd", break_point_disable, "bd [breakpoints#] Disable a break point. If # is 0, disable all break points.\n");
|
||||||
|
mon_add_command("be", break_point_enable, "be [breakpoints#] Enable a break point. If # is 0, enable all break points.\n");
|
||||||
|
mon_add_command("bi", break_point_info, "bi List all break points\n");
|
||||||
|
mon_add_command("bs", break_point_save, "bs \"file\" Save all break points to a file\n");
|
||||||
|
mon_add_command("bl", break_point_load, "bl \"file\" Load break points from a file\n");
|
||||||
mon_add_command("d", disassemble_ppc, "d [start [end]] Disassemble PowerPC code\n");
|
mon_add_command("d", disassemble_ppc, "d [start [end]] Disassemble PowerPC code\n");
|
||||||
mon_add_command("d65", disassemble_6502, "d65 [start [end]] Disassemble 6502 code\n");
|
mon_add_command("d65", disassemble_6502, "d65 [start [end]] Disassemble 6502 code\n");
|
||||||
mon_add_command("d68", disassemble_680x0, "d68 [start [end]] Disassemble 680x0 code\n");
|
mon_add_command("d68", disassemble_680x0, "d68 [start [end]] Disassemble 680x0 code\n");
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define MON_H
|
#define MON_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -80,6 +81,10 @@ extern uint32 mon_mem_size; // Size of mon buffer (if mon_use_real_mem = fals
|
||||||
|
|
||||||
extern bool mon_macos_mode; // Flag: enable features in the disassembler for working with MacOS code
|
extern bool mon_macos_mode; // Flag: enable features in the disassembler for working with MacOS code
|
||||||
|
|
||||||
|
typedef std::set<uintptr> BREAK_POINT_SET;
|
||||||
|
extern BREAK_POINT_SET active_break_points;
|
||||||
|
extern BREAK_POINT_SET disabled_break_points;
|
||||||
|
|
||||||
// Add command to mon
|
// Add command to mon
|
||||||
extern void mon_add_command(const char *name, void (*func)(), const char *help_text);
|
extern void mon_add_command(const char *name, void (*func)(), const char *help_text);
|
||||||
|
|
||||||
|
@ -97,4 +102,7 @@ extern void mon_write_half(uintptr adr, uint32 w);
|
||||||
extern uint32 mon_read_word(uintptr adr);
|
extern uint32 mon_read_word(uintptr adr);
|
||||||
extern void mon_write_word(uintptr adr, uint32 l);
|
extern void mon_write_word(uintptr adr, uint32 l);
|
||||||
|
|
||||||
|
// Check if break point is set
|
||||||
|
#define isBreakPoint(address) (active_break_points.find(address) != active_break_points.end())
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "mon.h"
|
#include "mon.h"
|
||||||
#include "mon_cmd.h"
|
#include "mon_cmd.h"
|
||||||
|
@ -32,6 +33,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static const char* STR_ACTIVE_BREAK_POINTS = "Active Break Points:\n";
|
||||||
|
static const char* STR_DISABLED_BREAK_POINTS = "Disabled Break Points:\n";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* range_args = [expression] [[COMMA] expression] END
|
* range_args = [expression] [[COMMA] expression] END
|
||||||
*
|
*
|
||||||
|
@ -302,6 +306,288 @@ void binary_dump(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add Break Point
|
||||||
|
*/
|
||||||
|
void break_point_add(void)
|
||||||
|
{
|
||||||
|
uintptr address;
|
||||||
|
|
||||||
|
if (mon_token == T_END ||
|
||||||
|
!mon_expression(&address)) {
|
||||||
|
fprintf(monerr, "Expect break point in hexadecimal.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mon_token != T_END) {
|
||||||
|
mon_error("Too many arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BREAK_POINT_SET::iterator it;
|
||||||
|
// Save break point
|
||||||
|
if((it = disabled_break_points.find(address)) == disabled_break_points.end())
|
||||||
|
active_break_points.insert(address);
|
||||||
|
else {
|
||||||
|
disabled_break_points.erase(it);
|
||||||
|
active_break_points.insert(address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove Break Point
|
||||||
|
*/
|
||||||
|
void break_point_remove(void)
|
||||||
|
{
|
||||||
|
uintptr index;
|
||||||
|
|
||||||
|
if (mon_token == T_END ||
|
||||||
|
!mon_expression(&index)) {
|
||||||
|
fprintf(monerr, "Expect index number of break point in hexadecimal.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mon_token != T_END) {
|
||||||
|
mon_error("Too many arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > active_break_points.size()) {
|
||||||
|
mon_error("Illegal Index Number!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BREAK_POINT_SET::iterator it;
|
||||||
|
|
||||||
|
if (0 == index) {
|
||||||
|
active_break_points.clear();
|
||||||
|
printf("Removed all break points!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = 1;
|
||||||
|
for (it = active_break_points.begin(); it != active_break_points.end(); it++)
|
||||||
|
if (pos++ == index)
|
||||||
|
break;
|
||||||
|
// Remove break point
|
||||||
|
printf("Removed break point %4x at address %08lx\n", index, *it);
|
||||||
|
active_break_points.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable Break Point
|
||||||
|
*/
|
||||||
|
void break_point_disable(void)
|
||||||
|
{
|
||||||
|
uintptr index;
|
||||||
|
|
||||||
|
if (mon_token == T_END ||
|
||||||
|
!mon_expression(&index)) {
|
||||||
|
fprintf(monerr, "Expect index number of break point in hexadecimal.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mon_token != T_END) {
|
||||||
|
mon_error("Too many arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > active_break_points.size()) {
|
||||||
|
mon_error("Illegal Index Number!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BREAK_POINT_SET::iterator it;
|
||||||
|
|
||||||
|
if (0 == index) {
|
||||||
|
for (it = active_break_points.begin(); it != active_break_points.end(); it++)
|
||||||
|
disabled_break_points.insert(*it);
|
||||||
|
active_break_points.clear();
|
||||||
|
printf("Disabled all break points!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = 1;
|
||||||
|
for (it = active_break_points.begin(); it != active_break_points.end(); it++)
|
||||||
|
if (pos++ == index)
|
||||||
|
break;
|
||||||
|
// Add to disable break points
|
||||||
|
printf("Disabled break point %4x at address %08lx\n", index, *it);
|
||||||
|
disabled_break_points.insert(*it);
|
||||||
|
// Remove break point
|
||||||
|
active_break_points.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable Break Point
|
||||||
|
*/
|
||||||
|
void break_point_enable(void)
|
||||||
|
{
|
||||||
|
uintptr index;
|
||||||
|
|
||||||
|
if (mon_token == T_END ||
|
||||||
|
!mon_expression(&index)) {
|
||||||
|
fprintf(monerr, "Expect index number of break point in hexadecimal.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mon_token != T_END) {
|
||||||
|
mon_error("Too many arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > disabled_break_points.size()) {
|
||||||
|
mon_error("Illegal Index Number!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BREAK_POINT_SET::iterator it;
|
||||||
|
|
||||||
|
if (0 == index) {
|
||||||
|
for (it = disabled_break_points.begin(); it != disabled_break_points.end(); it++)
|
||||||
|
active_break_points.insert(*it);
|
||||||
|
disabled_break_points.clear();
|
||||||
|
printf("Enabled all break points!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = 1;
|
||||||
|
for (it = disabled_break_points.begin(); it != disabled_break_points.end(); it++)
|
||||||
|
if (pos++ == index)
|
||||||
|
break;
|
||||||
|
// Add to active break points
|
||||||
|
printf("Disabled break point %4x at address %08lx\n", index, *it);
|
||||||
|
active_break_points.insert(*it);
|
||||||
|
// Remove break point
|
||||||
|
disabled_break_points.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List all Active Break Points
|
||||||
|
*/
|
||||||
|
void break_point_info(void)
|
||||||
|
{
|
||||||
|
if (mon_token != T_END) {
|
||||||
|
mon_error("Too many arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BREAK_POINT_SET::iterator it;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
if (!active_break_points.empty()) {
|
||||||
|
pos = 1;
|
||||||
|
printf(STR_ACTIVE_BREAK_POINTS);
|
||||||
|
for (it = active_break_points.begin(); it != active_break_points.end(); it++)
|
||||||
|
printf("\tBreak point %4x at address %08lx\n", pos++, *it);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!disabled_break_points.empty()) {
|
||||||
|
putchar('\n');
|
||||||
|
printf(STR_DISABLED_BREAK_POINTS);
|
||||||
|
pos = 1;
|
||||||
|
for (it = disabled_break_points.begin(); it != disabled_break_points.end(); it++)
|
||||||
|
printf("\tBreak point %4x at address %08lx\n", pos++, *it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save all Active Break Points to a file
|
||||||
|
*/
|
||||||
|
void break_point_save(void)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
if (mon_token == T_END) {
|
||||||
|
mon_error("Missing file name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mon_token != T_STRING) {
|
||||||
|
mon_error("'\"' around file name expected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mon_get_token();
|
||||||
|
if (mon_token != T_END) {
|
||||||
|
mon_error("Too many arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(file = fopen(mon_string, "w")))
|
||||||
|
mon_error("Unable to create file");
|
||||||
|
else {
|
||||||
|
BREAK_POINT_SET::iterator it;
|
||||||
|
|
||||||
|
fprintf(file, STR_ACTIVE_BREAK_POINTS);
|
||||||
|
for (it = active_break_points.begin(); it != active_break_points.end(); it++)
|
||||||
|
fprintf(file, "%x\n", *it);
|
||||||
|
|
||||||
|
fprintf(file, STR_DISABLED_BREAK_POINTS);
|
||||||
|
for (it = disabled_break_points.begin(); it != disabled_break_points.end(); it++)
|
||||||
|
fprintf(file, "%x\n", *it);
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load Break Point from a file
|
||||||
|
*/
|
||||||
|
void break_point_load(void)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
|
||||||
|
if (mon_token == T_END) {
|
||||||
|
mon_error("Missing file name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mon_token != T_STRING) {
|
||||||
|
mon_error("'\"' around file name expected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mon_get_token();
|
||||||
|
if (mon_token != T_END) {
|
||||||
|
mon_error("Too many arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(file = fopen(mon_string, "r")))
|
||||||
|
mon_error("Unable to create file");
|
||||||
|
else{
|
||||||
|
char line_buff[1024];
|
||||||
|
bool isDisabledBreakPoints = false;;
|
||||||
|
|
||||||
|
if(fgets(line_buff, sizeof(line_buff), file) == NULL ||
|
||||||
|
strcmp(line_buff, STR_ACTIVE_BREAK_POINTS) != 0) {
|
||||||
|
mon_error("Invalid break point file format!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(fgets(line_buff, sizeof(line_buff), file) != NULL) {
|
||||||
|
if(strcmp(line_buff, STR_DISABLED_BREAK_POINTS) == 0) {
|
||||||
|
isDisabledBreakPoints = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uintptr address;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::hex << line_buff;
|
||||||
|
ss >> address;
|
||||||
|
if(isDisabledBreakPoints)
|
||||||
|
disabled_break_points.insert(address);
|
||||||
|
else
|
||||||
|
active_break_points.insert(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disassemble
|
* Disassemble
|
||||||
* d [start [end]]
|
* d [start [end]]
|
||||||
|
|
|
@ -28,6 +28,13 @@ extern void shell_command(void);
|
||||||
extern void memory_dump(void);
|
extern void memory_dump(void);
|
||||||
extern void ascii_dump(void);
|
extern void ascii_dump(void);
|
||||||
extern void binary_dump(void);
|
extern void binary_dump(void);
|
||||||
|
extern void break_point_add(void);
|
||||||
|
extern void break_point_remove(void);
|
||||||
|
extern void break_point_disable(void);
|
||||||
|
extern void break_point_enable(void);
|
||||||
|
extern void break_point_info(void);
|
||||||
|
extern void break_point_save(void);
|
||||||
|
extern void break_point_load(void);
|
||||||
extern void disassemble_ppc(void);
|
extern void disassemble_ppc(void);
|
||||||
extern void disassemble_6502(void);
|
extern void disassemble_6502(void);
|
||||||
extern void disassemble_680x0(void);
|
extern void disassemble_680x0(void);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user