Enhance ROM break point feature.

1. Change --break input option format. Too much typing by taking decimal address. Change to hexadecimal input.
2. Allow ROM break point to continue to execution. The original ROM break point just replace instruction in ROM break point address with emul_op M68K_EMUL_BREAK. This just halts emulation right at the break point. The patch is less invasive than the original approach. It allows emulation to continue to run by pressing 'x' to exit from cxmon.
3. Add option --loadbreak which load break point from file before emulation start.

Signed-off-by: Ricky Zhang <rickyzhang@gmail.com>
This commit is contained in:
Ricky Zhang 2017-09-15 21:35:27 -04:00
parent e273bb1a0b
commit 175fbfde43
5 changed files with 93 additions and 49 deletions

View File

@ -24,6 +24,7 @@
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sstream>
#ifdef USE_SDL
# include <SDL.h>
@ -371,7 +372,8 @@ static void usage(const char *prg_name)
"\nUnix options:\n"
" --config FILE\n read/write configuration from/to FILE\n"
" --display STRING\n X display to use\n"
" --break ADDRESS\n set ROM breakpoint\n"
" --break ADDRESS\n set ROM breakpoint in hexadecimal\n"
" --loadbreak FILE\n load breakpoint from FILE\n"
" --rominfo\n dump ROM information\n", prg_name
);
LoadPrefs(NULL); // read the prefs file so PrefsPrintUsage() will print the correct default values
@ -413,9 +415,17 @@ int main(int argc, char **argv)
} else if (strcmp(argv[i], "--break") == 0) {
argv[i++] = NULL;
if (i < argc) {
ROMBreakpoint = strtol(argv[i], NULL, 0);
std::stringstream ss;
ss << std::hex << argv[i];
ss >> ROMBreakpoint;
argv[i] = NULL;
}
#ifdef ENABLE_MON
} else if (strcmp(argv[i], "--loadbreak") == 0) {
argv[i++] = NULL;
if (i < argc)
mon_load_break_point(argv[i]);
#endif
} else if (strcmp(argv[i], "--config") == 0) {
argv[i++] = NULL;
if (i < argc) {

View File

@ -32,6 +32,11 @@
#include "video.h"
#include "extfs.h"
#include "prefs.h"
#if ENABLE_MON
#include "mon.h"
#endif
#include "rom_patches.h"
#define DEBUG 0
@ -1678,8 +1683,14 @@ bool PatchROM(void)
// Install breakpoint
if (ROMBreakpoint) {
#if ENABLE_MON
mon_add_break_point(ROMBaseMac + ROMBreakpoint);
printf("ROM start address at %08lx\n", ROMBaseMac);
printf("Set ROM break point at %08lx\n", ROMBaseMac + ROMBreakpoint);
#else
uint16 *wp = (uint16 *)(ROMBaseHost + ROMBreakpoint);
*wp = htons(M68K_EMUL_BREAK);
#endif
}
// Clear caches as we loaded and patched code

View File

@ -26,6 +26,7 @@
#include <ctype.h>
#include <string>
#include <map>
#include <sstream>
#if defined(HAVE_READLINE_H)
extern "C" {
@ -66,7 +67,7 @@ static uint8 *mem;
// Streams for input, output and error messages
FILE *monin, *monout, *monerr;
FILE *monin, *monout, *monerr = NULL;
// Input line
static char *input;
@ -153,7 +154,7 @@ void mon_add_command(const char *name, void (*func)(), const char *help_text)
void mon_error(const char *s)
{
fprintf(monerr, "*** %s\n", s);
fprintf(monerr == NULL? stdout: monerr, "*** %s\n", s);
}
@ -1029,6 +1030,63 @@ void mon_change_dir()
}
/*
* Add break point
*/
void mon_add_break_point(uintptr adr)
{
BREAK_POINT_SET::iterator it;
// Save break point
if ((it = disabled_break_points.find(adr)) == disabled_break_points.end())
active_break_points.insert(adr);
else {
disabled_break_points.erase(it);
active_break_points.insert(adr);
}
}
/*
* Load break point from file
*/
void mon_load_break_point(char* file_path)
{
FILE *file;
if (!(file = fopen(file_path, "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);
}
/*
* Initialize mon
*/

View File

@ -33,6 +33,9 @@ void mon_init();
void mon_exit();
void mon(int argc, char **argv);
// Break points prompt
const char STR_ACTIVE_BREAK_POINTS[] = "Active Break Points:\n";
const char STR_DISABLED_BREAK_POINTS[] = "Disabled Break Points:\n";
/*
* Definitions for adding commands to mon
@ -104,5 +107,8 @@ 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())
// Add break point
extern void mon_add_break_point(uintptr adr);
extern void mon_load_break_point(char* file_path);
#endif

View File

@ -1,4 +1,4 @@
/*
/*
* mon_cmd.cpp - cxmon standard commands
*
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
@ -22,7 +22,6 @@
#include <stdlib.h>
#include <assert.h>
#include <sstream>
#include "mon.h"
#include "mon_cmd.h"
@ -33,9 +32,6 @@
#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
*
@ -323,14 +319,7 @@ void break_point_add(void)
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);
}
mon_add_break_point(address);
}
@ -521,38 +510,8 @@ void break_point_load(void)
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);
// load from file
mon_load_break_point(mon_string);
}