From f3895493ae16a38dbf6d9309bcc93da812ad69cf Mon Sep 17 00:00:00 2001 From: Ricky Zhang Date: Fri, 1 Sep 2017 10:47:22 -0400 Subject: [PATCH 1/6] 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 --- BasiliskII/src/emul_op.cpp | 17 ++ BasiliskII/src/include/emul_op.h | 1 + BasiliskII/src/uae_cpu/newcpu.cpp | 5 - BasiliskII/src/uae_cpu/newcpu.h | 79 ++++++--- cxmon/src/mon.cpp | 10 ++ cxmon/src/mon.h | 8 + cxmon/src/mon_cmd.cpp | 286 ++++++++++++++++++++++++++++++ cxmon/src/mon_cmd.h | 7 + 8 files changed, 386 insertions(+), 27 deletions(-) diff --git a/BasiliskII/src/emul_op.cpp b/BasiliskII/src/emul_op.cpp index f6b91dde..6051f9e2 100644 --- a/BasiliskII/src/emul_op.cpp +++ b/BasiliskII/src/emul_op.cpp @@ -564,6 +564,23 @@ void EmulOp(uint16 opcode, M68kRegisters *r) r->a[0] = ReadMacInt32(0x2b6); 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: printf("FATAL: EMUL_OP called with bogus opcode %08x\n", opcode); printf("d0 %08x d1 %08x d2 %08x d3 %08x\n" diff --git a/BasiliskII/src/include/emul_op.h b/BasiliskII/src/include/emul_op.h index b6d3a1e6..e7684127 100644 --- a/BasiliskII/src/include/emul_op.h +++ b/BasiliskII/src/include/emul_op.h @@ -90,6 +90,7 @@ enum { M68K_EMUL_OP_SOUNDIN_CLOSE, M68K_EMUL_OP_DEBUGUTIL, M68K_EMUL_OP_IDLE_TIME, + M68K_EMUL_OP_SUSPEND, M68K_EMUL_OP_MAX // highest number }; diff --git a/BasiliskII/src/uae_cpu/newcpu.cpp b/BasiliskII/src/uae_cpu/newcpu.cpp index 71aa89fb..eb14efd6 100644 --- a/BasiliskII/src/uae_cpu/newcpu.cpp +++ b/BasiliskII/src/uae_cpu/newcpu.cpp @@ -43,11 +43,6 @@ extern int intlev(void); // From baisilisk_glue.cpp B2_mutex *spcflags_lock = NULL; #endif -#if ENABLE_MON -#include "mon.h" -#include "mon_disass.h" -#endif - bool quit_program = false; struct flag_struct regflags; diff --git a/BasiliskII/src/uae_cpu/newcpu.h b/BasiliskII/src/uae_cpu/newcpu.h index 1d07c36b..0359e7b7 100644 --- a/BasiliskII/src/uae_cpu/newcpu.h +++ b/BasiliskII/src/uae_cpu/newcpu.h @@ -30,7 +30,13 @@ #include "m68k.h" #include "readcpu.h" #include "spcflags.h" - + +#if ENABLE_MON +#include "mon.h" +#include "mon_disass.h" +#endif + + extern int areg_byteinc[]; extern int imm8_table[]; @@ -74,6 +80,7 @@ struct comptbl { #endif extern void REGPARAM2 op_illg (uae_u32) REGPARAM; +extern void m68k_dumpstate(uaecptr *nextpc); typedef char flagtype; @@ -147,8 +154,6 @@ static __inline__ uae_u32 get_ilong_prefetch (uae_s32 o) } #endif -#define m68k_incpc(o) (regs.pc_p += (o)) - static __inline__ void fill_prefetch_0 (void) { #if USE_PREFETCH_BUFFER @@ -175,6 +180,55 @@ static __inline__ void fill_prefetch_2 (void) #define fill_prefetch_2 fill_prefetch_0 #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 * need to handle prefetch. */ static __inline__ uae_u32 next_ibyte (void) @@ -198,25 +252,6 @@ static __inline__ uae_u32 next_ilong (void) 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_bcc m68k_setpc #define m68k_setpc_rte m68k_setpc diff --git a/cxmon/src/mon.cpp b/cxmon/src/mon.cpp index f3c6c4e7..7b2b8700 100644 --- a/cxmon/src/mon.cpp +++ b/cxmon/src/mon.cpp @@ -55,6 +55,9 @@ extern "C" { #define VERSION "3" #endif +// Break points +BREAK_POINT_SET active_break_points; +BREAK_POINT_SET disabled_break_points; // Buffer we're operating on 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("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("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("d65", disassemble_6502, "d65 [start [end]] Disassemble 6502 code\n"); mon_add_command("d68", disassemble_680x0, "d68 [start [end]] Disassemble 680x0 code\n"); diff --git a/cxmon/src/mon.h b/cxmon/src/mon.h index becc8a86..5970ccbb 100644 --- a/cxmon/src/mon.h +++ b/cxmon/src/mon.h @@ -22,6 +22,7 @@ #define MON_H #include +#include /* @@ -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 +typedef std::set BREAK_POINT_SET; +extern BREAK_POINT_SET active_break_points; +extern BREAK_POINT_SET disabled_break_points; + // Add command to mon 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 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 diff --git a/cxmon/src/mon_cmd.cpp b/cxmon/src/mon_cmd.cpp index 4cb6a92b..d5eb5ee8 100644 --- a/cxmon/src/mon_cmd.cpp +++ b/cxmon/src/mon_cmd.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "mon.h" #include "mon_cmd.h" @@ -32,6 +33,9 @@ #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 * @@ -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 * d [start [end]] diff --git a/cxmon/src/mon_cmd.h b/cxmon/src/mon_cmd.h index d50d90eb..b9c344ba 100644 --- a/cxmon/src/mon_cmd.h +++ b/cxmon/src/mon_cmd.h @@ -28,6 +28,13 @@ extern void shell_command(void); extern void memory_dump(void); extern void ascii_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_6502(void); extern void disassemble_680x0(void); From 93b22b890229e817643c661d1f753858e3de6e26 Mon Sep 17 00:00:00 2001 From: Ricky Zhang Date: Sat, 2 Sep 2017 19:11:45 -0400 Subject: [PATCH 2/6] Add Macintosh M68k suspend program and user guide. Signed-off-by: Ricky Zhang --- cxmon/utils/README.md | 22 ++++++++++++++++++++++ cxmon/utils/suspend.bin | Bin 0 -> 768 bytes 2 files changed, 22 insertions(+) create mode 100644 cxmon/utils/README.md create mode 100644 cxmon/utils/suspend.bin diff --git a/cxmon/utils/README.md b/cxmon/utils/README.md new file mode 100644 index 00000000..eb7b59cc --- /dev/null +++ b/cxmon/utils/README.md @@ -0,0 +1,22 @@ +# What +suspend.bin is a MacBinary file which supposes to upack 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` 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 +``` diff --git a/cxmon/utils/suspend.bin b/cxmon/utils/suspend.bin new file mode 100644 index 0000000000000000000000000000000000000000..e3cac41d317f2d6fa2e08a82ef1264253a3d1448 GIT binary patch literal 768 zcmc&xPe>GT82x6~{t!r127-}`gat(d(IIea#+~19cd=q7SSb%dLp#`_j=EzVycuPI z)g^*1p+(?KwUxDH|Fc^AfAAut*x4?D2kR8QzM(`|I(6y6o8R}|<6|Ctw9Gr|bvbU9 z{t=CqwMSzpW&4rn1rNk`Jd_o9Bx~?kZow0|6HlduXR-~? zIMrzs>Kcm)v Date: Mon, 4 Sep 2017 06:31:36 -0400 Subject: [PATCH 3/6] Fix all suggestions from asvitkine Signed-off-by: Ricky Zhang --- BasiliskII/src/uae_cpu/newcpu.h | 4 +- cxmon/src/mon.h | 2 +- cxmon/src/mon_cmd.cpp | 110 +++++++++++--------------------- cxmon/utils/README.md | 4 +- 4 files changed, 44 insertions(+), 76 deletions(-) diff --git a/BasiliskII/src/uae_cpu/newcpu.h b/BasiliskII/src/uae_cpu/newcpu.h index 0359e7b7..6ba6dd96 100644 --- a/BasiliskII/src/uae_cpu/newcpu.h +++ b/BasiliskII/src/uae_cpu/newcpu.h @@ -203,7 +203,7 @@ static __inline__ void m68k_setpc (uaecptr newpc) #endif #if ENABLE_MON - if(isBreakPoint(newpc)) { + 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}; @@ -220,7 +220,7 @@ static __inline__ void m68k_incpc (uae_s32 delta) regs.pc_p += (delta); #if ENABLE_MON uaecptr next_pc = m68k_getpc(); - if(isBreakPoint(next_pc)) { + 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}; diff --git a/cxmon/src/mon.h b/cxmon/src/mon.h index 5970ccbb..0ce0bdef 100644 --- a/cxmon/src/mon.h +++ b/cxmon/src/mon.h @@ -103,6 +103,6 @@ extern uint32 mon_read_word(uintptr adr); 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()) +#define IS_BREAK_POINT(address) (active_break_points.find(address) != active_break_points.end()) #endif diff --git a/cxmon/src/mon_cmd.cpp b/cxmon/src/mon_cmd.cpp index d5eb5ee8..ed335740 100644 --- a/cxmon/src/mon_cmd.cpp +++ b/cxmon/src/mon_cmd.cpp @@ -313,9 +313,8 @@ void break_point_add(void) { uintptr address; - if (mon_token == T_END || - !mon_expression(&address)) { - fprintf(monerr, "Expect break point in hexadecimal.\n"); + if (mon_token == T_END || !mon_expression(&address)) { + mon_error("Expect break point in hexadecimal."); return; } @@ -335,6 +334,27 @@ void break_point_add(void) } +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 */ @@ -342,23 +362,8 @@ 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"); + if (!validate_index(&index, active_break_points)) 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(); @@ -366,10 +371,8 @@ void break_point_remove(void) return; } - int pos = 1; - for (it = active_break_points.begin(); it != active_break_points.end(); it++) - if (pos++ == index) - break; + 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); @@ -383,36 +386,19 @@ 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"); + if(!validate_index(&index, active_break_points)) 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++) + 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; } - int pos = 1; - for (it = active_break_points.begin(); it != active_break_points.end(); it++) - if (pos++ == index) - break; + 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); @@ -428,36 +414,19 @@ 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"); + if(!validate_index(&index, disabled_break_points)) 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++) + for (BREAK_POINT_SET::iterator 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; + 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); @@ -477,10 +446,9 @@ void break_point_info(void) } BREAK_POINT_SET::iterator it; - int pos; if (!active_break_points.empty()) { - pos = 1; + 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); @@ -489,7 +457,7 @@ void break_point_info(void) if (!disabled_break_points.empty()) { putchar('\n'); printf(STR_DISABLED_BREAK_POINTS); - pos = 1; + 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); } @@ -560,7 +528,7 @@ void break_point_load(void) mon_error("Unable to create file"); else{ char line_buff[1024]; - bool isDisabledBreakPoints = false;; + bool is_disabled_break_points = false;; if(fgets(line_buff, sizeof(line_buff), file) == NULL || strcmp(line_buff, STR_ACTIVE_BREAK_POINTS) != 0) { @@ -570,14 +538,14 @@ void break_point_load(void) while(fgets(line_buff, sizeof(line_buff), file) != NULL) { if(strcmp(line_buff, STR_DISABLED_BREAK_POINTS) == 0) { - isDisabledBreakPoints = true; + is_disabled_break_points = true; continue; } uintptr address; std::stringstream ss; ss << std::hex << line_buff; ss >> address; - if(isDisabledBreakPoints) + if(is_disabled_break_points) disabled_break_points.insert(address); else active_break_points.insert(address); diff --git a/cxmon/utils/README.md b/cxmon/utils/README.md index eb7b59cc..bad64218 100644 --- a/cxmon/utils/README.md +++ b/cxmon/utils/README.md @@ -1,8 +1,8 @@ # What -suspend.bin is a MacBinary file which supposes to upack and run in M68k Macintosh only. It runs emul_op `0x7138` and trigger BasiliskII into cxmon so that you can add break points there. +suspend.bin is a MacBinary file which should be upacked 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` options. +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. From 597ff0666c5fb1aa33a5b25e738272e0edc72671 Mon Sep 17 00:00:00 2001 From: Ricky Zhang Date: Mon, 4 Sep 2017 08:00:45 -0400 Subject: [PATCH 4/6] Fix code style. Signed-off-by: Ricky Zhang --- cxmon/src/mon_cmd.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cxmon/src/mon_cmd.cpp b/cxmon/src/mon_cmd.cpp index ed335740..fdc5e3c7 100644 --- a/cxmon/src/mon_cmd.cpp +++ b/cxmon/src/mon_cmd.cpp @@ -325,7 +325,7 @@ void break_point_add(void) BREAK_POINT_SET::iterator it; // Save break point - if((it = disabled_break_points.find(address)) == disabled_break_points.end()) + if ((it = disabled_break_points.find(address)) == disabled_break_points.end()) active_break_points.insert(address); else { disabled_break_points.erase(it); @@ -386,7 +386,7 @@ void break_point_disable(void) { uintptr index; - if(!validate_index(&index, active_break_points)) + if (!validate_index(&index, active_break_points)) return; if (0 == index) { @@ -414,7 +414,7 @@ void break_point_enable(void) { uintptr index; - if(!validate_index(&index, disabled_break_points)) + if (!validate_index(&index, disabled_break_points)) return; if (0 == index) { @@ -526,7 +526,7 @@ void break_point_load(void) if (!(file = fopen(mon_string, "r"))) mon_error("Unable to create file"); - else{ + else { char line_buff[1024]; bool is_disabled_break_points = false;; From 93e800ffc71d68f7ef8bfe8ee3e35651efd70c80 Mon Sep 17 00:00:00 2001 From: Ricky Zhang Date: Mon, 4 Sep 2017 14:21:16 -0400 Subject: [PATCH 5/6] Fix another round of suggestions. Signed-off-by: Ricky Zhang --- BasiliskII/src/uae_cpu/newcpu.h | 4 +- cxmon/src/mon_cmd.cpp | 94 ++++++++++++++++----------------- cxmon/utils/README.md | 2 +- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/BasiliskII/src/uae_cpu/newcpu.h b/BasiliskII/src/uae_cpu/newcpu.h index 6ba6dd96..305b242e 100644 --- a/BasiliskII/src/uae_cpu/newcpu.h +++ b/BasiliskII/src/uae_cpu/newcpu.h @@ -203,7 +203,7 @@ static __inline__ void m68k_setpc (uaecptr newpc) #endif #if ENABLE_MON - if(IS_BREAK_POINT(newpc)) { + 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}; @@ -220,7 +220,7 @@ static __inline__ void m68k_incpc (uae_s32 delta) regs.pc_p += (delta); #if ENABLE_MON uaecptr next_pc = m68k_getpc(); - if(IS_BREAK_POINT(next_pc)) { + 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}; diff --git a/cxmon/src/mon_cmd.cpp b/cxmon/src/mon_cmd.cpp index fdc5e3c7..59391bb3 100644 --- a/cxmon/src/mon_cmd.cpp +++ b/cxmon/src/mon_cmd.cpp @@ -33,8 +33,8 @@ #endif -static const char* STR_ACTIVE_BREAK_POINTS = "Active Break Points:\n"; -static const char* STR_DISABLED_BREAK_POINTS = "Disabled Break Points:\n"; +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 @@ -347,7 +347,7 @@ bool validate_index(uintptr *index_ptr, const BREAK_POINT_SET& break_point_set) } if (*index_ptr > break_point_set.size()) { - mon_error("Illegal Index Number!"); + mon_error("Illegal index number!"); return false; } @@ -418,8 +418,7 @@ void break_point_enable(void) return; if (0 == index) { - for (BREAK_POINT_SET::iterator it = disabled_break_points.begin(); it != disabled_break_points.end(); it++) - active_break_points.insert(*it); + active_break_points.insert(disabled_break_points.begin(), disabled_break_points.end()); disabled_break_points.clear(); printf("Enabled all break points!\n"); return; @@ -469,8 +468,6 @@ void break_point_info(void) */ void break_point_save(void) { - FILE *file; - if (mon_token == T_END) { mon_error("Missing file name"); return; @@ -485,21 +482,23 @@ void break_point_save(void) return; } - if (!(file = fopen(mon_string, "w"))) + FILE *file; + if (!(file = fopen(mon_string, "w"))) { mon_error("Unable to create file"); - else { - BREAK_POINT_SET::iterator it; + return; + } - fprintf(file, STR_ACTIVE_BREAK_POINTS); - for (it = active_break_points.begin(); it != active_break_points.end(); it++) + 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); - 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); - } + fclose(file); } @@ -508,8 +507,6 @@ void break_point_save(void) */ void break_point_load(void) { - FILE *file; - if (mon_token == T_END) { mon_error("Missing file name"); return; @@ -524,35 +521,38 @@ void break_point_load(void) return; } - if (!(file = fopen(mon_string, "r"))) + FILE *file; + if (!(file = fopen(mon_string, "r"))) { mon_error("Unable to create file"); - else { - 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!"); - 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); + 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); } diff --git a/cxmon/utils/README.md b/cxmon/utils/README.md index bad64218..9345d805 100644 --- a/cxmon/utils/README.md +++ b/cxmon/utils/README.md @@ -1,5 +1,5 @@ # What -suspend.bin is a MacBinary file which should be upacked and run in M68k Macintosh only. It runs emul_op `0x7138` and trigger BasiliskII into cxmon so that you can add break points there. +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. From 34cf1b0940feecce8850917ee08713b4a46b6338 Mon Sep 17 00:00:00 2001 From: Ricky Zhang Date: Mon, 4 Sep 2017 14:35:50 -0400 Subject: [PATCH 6/6] Fix indentation and a typo. Signed-off-by: Ricky Zhang --- cxmon/src/mon_cmd.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cxmon/src/mon_cmd.cpp b/cxmon/src/mon_cmd.cpp index 59391bb3..0731c9de 100644 --- a/cxmon/src/mon_cmd.cpp +++ b/cxmon/src/mon_cmd.cpp @@ -496,7 +496,7 @@ void break_point_save(void) fprintf(file, STR_DISABLED_BREAK_POINTS); for (it = disabled_break_points.begin(); it != disabled_break_points.end(); it++) - fprintf(file, "%x\n", *it); + fprintf(file, "%x\n", *it); fclose(file); } @@ -528,7 +528,7 @@ void break_point_load(void) } char line_buff[1024]; - bool is_disabled_break_points = false;; + bool is_disabled_break_points = false; if (fgets(line_buff, sizeof(line_buff), file) == NULL || strcmp(line_buff, STR_ACTIVE_BREAK_POINTS) != 0) {