Allow for more deterministic typing/stepping of CPU thread from debugger

This commit is contained in:
Aaron Culliney 2016-07-03 16:21:22 -07:00
parent 4ca642a715
commit d7413dae01
3 changed files with 25 additions and 14 deletions

View File

@ -35,6 +35,7 @@ typedef enum {
GOING GOING
} stepping_type_t; } stepping_type_t;
// FIXME TODO : make opaque type ...
typedef struct stepping_struct_t { typedef struct stepping_struct_t {
stepping_type_t step_type; stepping_type_t step_type;
uint16_t step_count; uint16_t step_count;
@ -43,6 +44,7 @@ typedef struct stepping_struct_t {
bool should_break; bool should_break;
time_t timeout; time_t timeout;
const char *step_text; const char *step_text;
const bool step_deterministically;
} stepping_struct_t; } stepping_struct_t;
#define DEBUGGER_BUF_X 39 #define DEBUGGER_BUF_X 39
@ -85,7 +87,7 @@ extern const struct opcode_struct *opcodes;
void c_interface_debugging(); void c_interface_debugging();
#endif #endif
void debugger_setInputText(const char *text); void debugger_setInputText(const char *text, const bool deterministically);
void c_debugger_go(void); void c_debugger_go(void);
bool c_debugger_should_break(void); bool c_debugger_should_break(void);
void c_debugger_set_timeout(const unsigned int secs); void c_debugger_set_timeout(const unsigned int secs);

View File

@ -33,6 +33,7 @@
const struct opcode_struct *opcodes; const struct opcode_struct *opcodes;
static char input_str[1024] = { 0 }; // ASCII values static char input_str[1024] = { 0 }; // ASCII values
static bool input_deterministically = false; // slows down testing ...
static stepping_struct_t stepping_struct = { 0 }; static stepping_struct_t stepping_struct = { 0 };
static unsigned int stepping_timeout = 0; static unsigned int stepping_timeout = 0;
@ -1126,15 +1127,13 @@ static int begin_cpu_stepping() {
cpu_altscale_factor = CPU_SCALE_FASTEST; cpu_altscale_factor = CPU_SCALE_FASTEST;
timing_initialize(); timing_initialize();
unsigned int idx = 0; if (stepping_struct.step_text && stepping_struct.step_text[0] == '\0') {
size_t textlen = 0; stepping_struct.step_text = NULL;
if (stepping_struct.step_text) {
textlen = strlen(stepping_struct.step_text);
} }
do { do {
if (textlen && !((apple_ii_64k[0][0xC000] & 0x80) || (apple_ii_64k[1][0xC000] & 0x80)) ) { if (stepping_struct.step_text && !((apple_ii_64k[0][0xC000] & 0x80) || (apple_ii_64k[1][0xC000] & 0x80)) ) {
uint8_t text_ch = (uint8_t)stepping_struct.step_text[idx]; uint8_t text_ch = (uint8_t)stepping_struct.step_text[0];
if (text_ch == '\n') { if (text_ch == '\n') {
text_ch = '\r'; text_ch = '\r';
} }
@ -1142,9 +1141,9 @@ static int begin_cpu_stepping() {
apple_ii_64k[0][0xC000] = text_ch | 0x80; apple_ii_64k[0][0xC000] = text_ch | 0x80;
apple_ii_64k[1][0xC000] = text_ch | 0x80; apple_ii_64k[1][0xC000] = text_ch | 0x80;
++idx; ++stepping_struct.step_text;
if (idx >= textlen) { if (stepping_struct.step_text[0] == '\0') {
textlen = 0; stepping_struct.step_text = NULL;
} }
} }
@ -1160,7 +1159,7 @@ static int begin_cpu_stepping() {
break; break;
} }
#endif #endif
if ( (stepping_struct.step_type == TYPING) && (idx > textlen) ) { if ( (stepping_struct.step_type == TYPING) && (!stepping_struct.step_text || stepping_struct.step_text[0] == '\0') ) {
break; // finished typing break; // finished typing
} }
if (stepping_timeout && (stepping_struct.timeout < time(NULL))) { if (stepping_timeout && (stepping_struct.timeout < time(NULL))) {
@ -1190,6 +1189,7 @@ bool c_debugger_should_break() {
RELEASE_BREAK(); RELEASE_BREAK();
} }
bool break_stepping = false;
if (at_haltpt()) { if (at_haltpt()) {
stepping_struct.should_break = true; stepping_struct.should_break = true;
} else { } else {
@ -1249,12 +1249,17 @@ bool c_debugger_should_break() {
case GOING: case GOING:
case TYPING: case TYPING:
// basically force CPU thread to execute one instruction at a time so we can feed characters to the emulator
// in a deterministic way
break_stepping = (stepping_struct.step_deterministically && stepping_struct.step_text && stepping_struct.step_text[0] != '\0');
break;
case LOADING: case LOADING:
break; break;
} }
} }
return stepping_struct.should_break; return break_stepping ?: stepping_struct.should_break;
} }
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
@ -1493,8 +1498,9 @@ void c_interface_debugging() {
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
debugger testing-driven API debugger testing-driven API
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void debugger_setInputText(const char *text) { void debugger_setInputText(const char *text, const bool deterministically) {
strcat(input_str, text); strcat(input_str, text);
input_deterministically = deterministically;
} }
void c_debugger_go(void) { void c_debugger_go(void) {
@ -1503,8 +1509,11 @@ void c_debugger_go(void) {
buf = STRDUP(input_str); buf = STRDUP(input_str);
input_str[0] = '\0'; input_str[0] = '\0';
} }
bool deterministically = input_deterministically;
input_deterministically = false;
stepping_struct_t s = (stepping_struct_t){ stepping_struct_t s = (stepping_struct_t){
.step_deterministically = deterministically,
.step_text = buf, .step_text = buf,
.step_type = GOING, .step_type = GOING,
.timeout = time(NULL) + stepping_timeout .timeout = time(NULL) + stepping_timeout

View File

@ -20,7 +20,7 @@ void test_common_setup(void) {
} }
void test_type_input(const char *input) { void test_type_input(const char *input) {
debugger_setInputText(input); debugger_setInputText(input, false);
} }
void test_breakpoint(void *arg) { void test_breakpoint(void *arg) {