mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-22 13:31:08 +00:00
Merge pull request #129 from rickyzhang82/pr-cxmon-break-point
[Revised] Add break point functions to Basilisk II
This commit is contained in:
commit
e273bb1a0b
@ -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 (IS_BREAK_POINT(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 (IS_BREAK_POINT(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 IS_BREAK_POINT(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,256 @@ void binary_dump(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add Break Point
|
||||||
|
*/
|
||||||
|
void break_point_add(void)
|
||||||
|
{
|
||||||
|
uintptr address;
|
||||||
|
|
||||||
|
if (mon_token == T_END || !mon_expression(&address)) {
|
||||||
|
mon_error("Expect break point in hexadecimal.");
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool validate_index(uintptr *index_ptr, const BREAK_POINT_SET& break_point_set)
|
||||||
|
{
|
||||||
|
if (mon_token == T_END || !mon_expression(index_ptr)) {
|
||||||
|
mon_error("Expect index number of break point in hexadecimal.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mon_token != T_END) {
|
||||||
|
mon_error("Too many arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*index_ptr > break_point_set.size()) {
|
||||||
|
mon_error("Illegal index number!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove Break Point
|
||||||
|
*/
|
||||||
|
void break_point_remove(void)
|
||||||
|
{
|
||||||
|
uintptr index;
|
||||||
|
|
||||||
|
if (!validate_index(&index, active_break_points))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (0 == index) {
|
||||||
|
active_break_points.clear();
|
||||||
|
printf("Removed all break points!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BREAK_POINT_SET::iterator it = active_break_points.begin();
|
||||||
|
std::advance(it, index - 1);
|
||||||
|
// 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 (!validate_index(&index, active_break_points))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (0 == index) {
|
||||||
|
for (BREAK_POINT_SET::iterator 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
BREAK_POINT_SET::iterator it = active_break_points.begin();
|
||||||
|
std::advance(it, index - 1);
|
||||||
|
// 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 (!validate_index(&index, disabled_break_points))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (0 == index) {
|
||||||
|
active_break_points.insert(disabled_break_points.begin(), disabled_break_points.end());
|
||||||
|
disabled_break_points.clear();
|
||||||
|
printf("Enabled all break points!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BREAK_POINT_SET::iterator it = disabled_break_points.begin();
|
||||||
|
std::advance(it, index - 1);
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
if (!active_break_points.empty()) {
|
||||||
|
int 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);
|
||||||
|
int 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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *file;
|
||||||
|
if (!(file = fopen(mon_string, "w"))) {
|
||||||
|
mon_error("Unable to create file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *file;
|
||||||
|
if (!(file = fopen(mon_string, "r"))) {
|
||||||
|
mon_error("Unable to create file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char line_buff[1024];
|
||||||
|
bool is_disabled_break_points = 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!");
|
||||||
|
fclose(file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (fgets(line_buff, sizeof(line_buff), file) != NULL) {
|
||||||
|
if (strcmp(line_buff, STR_DISABLED_BREAK_POINTS) == 0) {
|
||||||
|
is_disabled_break_points = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uintptr address;
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << std::hex << line_buff;
|
||||||
|
ss >> address;
|
||||||
|
if (is_disabled_break_points)
|
||||||
|
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);
|
||||||
|
22
cxmon/utils/README.md
Normal file
22
cxmon/utils/README.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# What
|
||||||
|
suspend.bin is a MacBinary file which should be unpacked and run in M68k Macintosh only. It runs emul_op `0x7138` and trigger BasiliskII into cxmon so that you can add break points there.
|
||||||
|
|
||||||
|
# How
|
||||||
|
1. You must build Basilisk II `--with-mon=YES` options.
|
||||||
|
1. Copy suspend.bin into Macintosh guest OS.
|
||||||
|
1. Unpack it with MacBinary.
|
||||||
|
1. Run the program when you want to add break points.
|
||||||
|
1. Once you are in cxmon, type `h` and you can see the new break point commands.
|
||||||
|
1. Once you are done, type `x` to return back to emulation.
|
||||||
|
|
||||||
|
# Break point commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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
|
||||||
|
```
|
BIN
cxmon/utils/suspend.bin
Normal file
BIN
cxmon/utils/suspend.bin
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user