comparison debug.c @ 2188:e17d99c96c89

Make blocks an explicitly supported concept in the debugger rather than a one-off for the commands command
author Michael Pavone <pavone@retrodev.com>
date Sat, 20 Aug 2022 11:40:41 -0700
parents d0129f19ca52
children 6b33ce6bc740
comparison
equal deleted inserted replaced
2187:d0129f19ca52 2188:e17d99c96c89
901 command_arg *args = NULL; 901 command_arg *args = NULL;
902 if (*cur && *cur != '\n') { 902 if (*cur && *cur != '\n') {
903 ++cur; 903 ++cur;
904 } 904 }
905 text = cur; 905 text = cur;
906 if (def->raw_impl) { 906 if (def->raw_args) {
907 while (*cur && *cur != '\n') 907 while (*cur && *cur != '\n')
908 { 908 {
909 ++cur; 909 ++cur;
910 } 910 }
911 char *raw_param = NULL; 911 char *raw_param = NULL;
975 cleanup_name: 975 cleanup_name:
976 free(name); 976 free(name);
977 return ret; 977 return ret;
978 } 978 }
979 979
980 static void free_parsed_command(parsed_command *cmd);
981 static void free_command_block(command_block *block)
982 {
983 for (int i = 0; i < block->num_commands; i++)
984 {
985 free_parsed_command(block->commands + i);
986 }
987 free(block->commands);
988 }
989
980 static void free_parsed_command(parsed_command *cmd) 990 static void free_parsed_command(parsed_command *cmd)
981 { 991 {
982 free(cmd->format); 992 free(cmd->format);
983 free(cmd->raw); 993 free(cmd->raw);
984 for (int i = 0; i < cmd->num_args; i++) 994 for (int i = 0; i < cmd->num_args; i++)
985 { 995 {
986 free(cmd->args[i].raw); 996 free(cmd->args[i].raw);
987 free_expr(cmd->args[i].parsed); 997 free_expr(cmd->args[i].parsed);
988 } 998 }
999 free_command_block(&cmd->block);
1000 free_command_block(&cmd->else_block);
989 free(cmd->args); 1001 free(cmd->args);
990 } 1002 }
991 1003
992 static uint8_t cmd_quit(debug_root *root, char *format, int num_args, command_arg *args) 1004 enum {
1005 READ_FAILED = 0,
1006 NORMAL,
1007 EMPTY,
1008 ELSE,
1009 END
1010 };
1011
1012 static uint8_t read_parse_command(debug_root *root, parsed_command *out, int indent_level)
1013 {
1014 ++indent_level;
1015 for (int i = 0; i < indent_level; i++)
1016 {
1017 putchar('>');
1018 }
1019 putchar(' ');
1020 fflush(stdout);
1021 #ifdef _WIN32
1022 #define wait 0
1023 #else
1024 int wait = 1;
1025 fd_set read_fds;
1026 FD_ZERO(&read_fds);
1027 struct timeval timeout;
1028 #endif
1029 do {
1030 process_events();
1031 #ifndef _WIN32
1032 timeout.tv_sec = 0;
1033 timeout.tv_usec = 16667;
1034 FD_SET(fileno(stdin), &read_fds);
1035 if(select(fileno(stdin) + 1, &read_fds, NULL, NULL, &timeout) >= 1) {
1036 wait = 0;
1037 }
1038 #endif
1039 } while (wait);
1040
1041 char input_buf[1024];
1042 if (!fgets(input_buf, sizeof(input_buf), stdin)) {
1043 fputs("fgets failed", stderr);
1044 return READ_FAILED;
1045 }
1046 char *stripped = strip_ws(input_buf);
1047 if (!stripped[0]) {
1048 return EMPTY;
1049 }
1050 if (indent_level > 1) {
1051 if (!strcmp(stripped, "else")) {
1052 return ELSE;
1053 }
1054 if (!strcmp(stripped, "end")) {
1055 return END;
1056 }
1057 }
1058 if (parse_command(root, input_buf, out)) {
1059 if (!out->def->has_block) {
1060 return NORMAL;
1061 }
1062 int command_storage = 4;
1063 command_block *block = &out->block;
1064 block->commands = calloc(command_storage, sizeof(parsed_command));
1065 block->num_commands = 0;
1066 for (;;)
1067 {
1068 if (block->num_commands == command_storage) {
1069 command_storage *= 2;
1070 block->commands = realloc(block->commands, command_storage * sizeof(parsed_command));
1071 }
1072 switch (read_parse_command(root, block->commands + block->num_commands, indent_level))
1073 {
1074 case READ_FAILED:
1075 return READ_FAILED;
1076 case NORMAL:
1077 block->num_commands++;
1078 break;
1079 case END:
1080 return NORMAL;
1081 case ELSE:
1082 if (block == &out->else_block) {
1083 fprintf(stderr, "Too many else blocks for command %s\n", out->def->names[0]);
1084 return READ_FAILED;
1085 }
1086 if (!out->def->accepts_else) {
1087 fprintf(stderr, "Command %s does not take an else block\n", out->def->names[0]);
1088 return READ_FAILED;
1089 }
1090 block = &out->else_block;
1091 block->commands = calloc(command_storage, sizeof(parsed_command));
1092 block->num_commands = 0;
1093 break;
1094 }
1095 }
1096 }
1097 return READ_FAILED;
1098 }
1099
1100 static uint8_t run_command(debug_root *root, parsed_command *cmd)
1101 {
1102 if (!cmd->def->raw_args && !cmd->def->skip_eval) {
1103 for (int i = 0; i < cmd->num_args; i++)
1104 {
1105 if (!eval_expr(root, cmd->args[i].parsed, &cmd->args[i].value)) {
1106 fprintf(stderr, "Failed to eval %s\n", cmd->args[i].raw);
1107 return 1;
1108 }
1109 }
1110 }
1111 return cmd->def->impl(root, cmd);
1112 }
1113
1114 static void debugger_repl(debug_root *root)
1115 {
1116
1117 int debugging = 1;
1118 parsed_command cmds[2] = {0};
1119 int cur = 0;
1120 uint8_t has_last = 0;
1121 while(debugging) {
1122 switch (read_parse_command(root, cmds + cur, 0))
1123 {
1124 case NORMAL:
1125 debugging = run_command(root, cmds + cur);
1126 if (debugging && has_last) {
1127 cur = !cur;
1128 free_parsed_command(cmds + cur);
1129 memset(cmds + cur, 0, sizeof(cmds[cur]));
1130 }
1131 break;
1132 case EMPTY:
1133 debugging = run_command(root, cmds + !cur);
1134 break;
1135 }
1136 }
1137 free_parsed_command(cmds);
1138 free_parsed_command(cmds + 1);
1139 }
1140
1141 static uint8_t cmd_quit(debug_root *root, parsed_command *cmd)
993 { 1142 {
994 exit(0); 1143 exit(0);
995 } 1144 }
996 1145
997 typedef struct { 1146 typedef struct {
1082 fputs(extra_desc, stdout); 1231 fputs(extra_desc, stdout);
1083 } 1232 }
1084 putchar('\n'); 1233 putchar('\n');
1085 } 1234 }
1086 1235
1087 static uint8_t cmd_help(debug_root *root, char *format, char *param) 1236 static uint8_t cmd_help(debug_root *root, parsed_command *cmd)
1088 { 1237 {
1089 help_state state = {0,0}; 1238 help_state state = {0,0};
1090 tern_foreach(root->commands, help_first_pass, &state); 1239 tern_foreach(root->commands, help_first_pass, &state);
1091 tern_foreach(root->commands, help_reset_visited, &state); 1240 tern_foreach(root->commands, help_reset_visited, &state);
1092 tern_foreach(root->commands, help_second_pass, &state); 1241 tern_foreach(root->commands, help_second_pass, &state);
1093 tern_foreach(root->commands, help_reset_visited, &state); 1242 tern_foreach(root->commands, help_reset_visited, &state);
1094 return 1; 1243 return 1;
1095 } 1244 }
1096 1245
1097 static uint8_t cmd_continue(debug_root *root, char *format, int num_args, command_arg *args) 1246 static uint8_t cmd_continue(debug_root *root, parsed_command *cmd)
1098 { 1247 {
1099 return 0; 1248 return 0;
1100 } 1249 }
1101 1250
1102 static uint8_t cmd_print(debug_root *root, char *format, int num_args, command_arg *args) 1251 static void make_format_str(char *format_str, char *format)
1103 { 1252 {
1104 char format_str[8];
1105 strcpy(format_str, "%s: %d\n"); 1253 strcpy(format_str, "%s: %d\n");
1106 if (format) { 1254 if (format) {
1107 switch (format[0]) 1255 switch (format[0])
1108 { 1256 {
1109 case 'x': 1257 case 'x':
1115 break; 1263 break;
1116 default: 1264 default:
1117 fprintf(stderr, "Unrecognized format character: %c\n", format[0]); 1265 fprintf(stderr, "Unrecognized format character: %c\n", format[0]);
1118 } 1266 }
1119 } 1267 }
1120 for (int i = 0; i < num_args; i++) 1268 }
1121 { 1269
1122 if (format && format[0] == 's') { 1270 static void do_print(debug_root *root, char *format_str, char *raw, uint32_t value)
1123 char tmp[128]; 1271 {
1124 int j; 1272 if (format_str[5] == 's') {
1125 uint32_t addr = args[i].value; 1273 char tmp[128];
1126 for (j = 0; j < sizeof(tmp)-1; j++, addr++) 1274 int j;
1127 { 1275 uint32_t addr = value;
1128 uint32_t tmp_addr = addr; 1276 for (j = 0; j < sizeof(tmp)-1; j++, addr++)
1129 root->read_mem(root, &tmp_addr, 'b'); 1277 {
1130 char c = tmp_addr; 1278 uint32_t tmp_addr = addr;
1131 if (c < 0x20 || c > 0x7F) { 1279 root->read_mem(root, &tmp_addr, 'b');
1132 break; 1280 char c = tmp_addr;
1133 } 1281 if (c < 0x20 || c > 0x7F) {
1134 tmp[j] = c; 1282 break;
1135 } 1283 }
1136 tmp[j] = 0; 1284 tmp[j] = c;
1137 printf(format_str, args[i].raw, tmp); 1285 }
1138 } else { 1286 tmp[j] = 0;
1139 printf(format_str, args[i].raw, args[i].value); 1287 printf(format_str, raw, tmp);
1140 } 1288 } else {
1289 printf(format_str, raw, value);
1290 }
1291 }
1292
1293 static uint8_t cmd_print(debug_root *root, parsed_command *cmd)
1294 {
1295 char format_str[8];
1296 make_format_str(format_str, cmd->format);
1297 for (int i = 0; i < cmd->num_args; i++)
1298 {
1299 do_print(root, format_str, cmd->args[i].raw, cmd->args[i].value);
1141 } 1300 }
1142 return 1; 1301 return 1;
1143 } 1302 }
1144 1303
1145 static uint8_t cmd_printf(debug_root *root, char *format, char *param) 1304 static uint8_t cmd_printf(debug_root *root, parsed_command *cmd)
1146 { 1305 {
1306 char *param = cmd->raw;
1147 if (!param) { 1307 if (!param) {
1148 fputs("printf requires at least one parameter\n", stderr); 1308 fputs("printf requires at least one parameter\n", stderr);
1149 return 1; 1309 return 1;
1150 } 1310 }
1151 while (isblank(*param)) 1311 while (isblank(*param))
1243 } 1403 }
1244 } 1404 }
1245 return 1; 1405 return 1;
1246 } 1406 }
1247 1407
1248 static uint8_t cmd_display(debug_root *root, char *format, int num_args, command_arg *args) 1408 static uint8_t cmd_display(debug_root *root, parsed_command *cmd)
1249 { 1409 {
1250 cmd_print(root, format, num_args, args); 1410 cmd_print(root, cmd);
1251 disp_def *ndisp = calloc(1, sizeof(*ndisp)); 1411 disp_def *ndisp = calloc(1, sizeof(*ndisp));
1252 ndisp->next = root->displays; 1412 ndisp->next = root->displays;
1253 ndisp->index = root->disp_index++; 1413 ndisp->index = root->disp_index++;
1254 ndisp->format = format ? strdup(format) : NULL; 1414 ndisp->format = cmd->format ? strdup(cmd->format) : NULL;
1255 ndisp->num_args = num_args; 1415 ndisp->num_args = cmd->num_args;
1256 ndisp->args = calloc(num_args, sizeof(command_arg)); 1416 ndisp->args = cmd->args;
1257 memcpy(ndisp->args, args, num_args * sizeof(command_arg)); 1417 cmd->args = NULL;
1258 memset(args, 0, num_args * sizeof(command_arg)); 1418 cmd->num_args = 0;
1259 root->displays = ndisp; 1419 root->displays = ndisp;
1260 printf("Added display %d\n", ndisp->index); 1420 printf("Added display %d\n", ndisp->index);
1261 return 1; 1421 return 1;
1262 } 1422 }
1263 1423
1264 static uint8_t cmd_delete_display(debug_root *root, char *format, int num_args, command_arg *args) 1424 static uint8_t cmd_delete_display(debug_root *root, parsed_command *cmd)
1265 { 1425 {
1266 disp_def **cur = &root->displays; 1426 disp_def **cur = &root->displays;
1267 while (*cur) 1427 while (*cur)
1268 { 1428 {
1269 if ((*cur)->index == args[0].value) { 1429 if ((*cur)->index == cmd->args[0].value) {
1270 disp_def *del_disp = *cur; 1430 disp_def *del_disp = *cur;
1271 *cur = del_disp->next; 1431 *cur = del_disp->next;
1272 free(del_disp->format); 1432 free(del_disp->format);
1273 for (int i = 0; i < del_disp->num_args; i++) 1433 for (int i = 0; i < del_disp->num_args; i++)
1274 { 1434 {
1283 } 1443 }
1284 } 1444 }
1285 return 1; 1445 return 1;
1286 } 1446 }
1287 1447
1288 static uint8_t cmd_softreset(debug_root *root, char *format, int num_args, command_arg *args) 1448 static uint8_t cmd_softreset(debug_root *root, parsed_command *cmd)
1289 { 1449 {
1290 if (current_system->soft_reset) { 1450 if (current_system->soft_reset) {
1291 current_system->soft_reset(current_system); 1451 current_system->soft_reset(current_system);
1292 return 0; 1452 return 0;
1293 } else { 1453 } else {
1294 fputs("Current system does not support soft reset", stderr); 1454 fputs("Current system does not support soft reset", stderr);
1295 return 1; 1455 return 1;
1296 } 1456 }
1297 } 1457 }
1298 1458
1299 static uint8_t cmd_command(debug_root *root, char *format, int num_args, command_arg *args) 1459 static uint8_t cmd_command(debug_root *root, parsed_command *cmd)
1300 { 1460 {
1301 bp_def **target = find_breakpoint_idx(&root->breakpoints, args[0].value); 1461 bp_def **target = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value);
1302 if (!target) { 1462 if (!target) {
1303 fprintf(stderr, "Breakpoint %d does not exist!\n", args[0].value); 1463 fprintf(stderr, "Breakpoint %d does not exist!\n", cmd->args[0].value);
1304 return 1; 1464 return 1;
1305 } 1465 }
1306 printf("Enter commands for breakpoing %d, type end when done\n", args[0].value);
1307 char cmd_buf[1024];
1308 char *commands = NULL;
1309 uint32_t cmd_storage = 4;
1310 for (uint32_t i = 0; i < (*target)->num_commands; i++) 1466 for (uint32_t i = 0; i < (*target)->num_commands; i++)
1311 { 1467 {
1312 free_parsed_command((*target)->commands + i); 1468 free_parsed_command((*target)->commands + i);
1313 } 1469 }
1314 free((*target)->commands); 1470 free((*target)->commands);
1315 (*target)->commands = calloc(cmd_storage, sizeof(parsed_command)); 1471 (*target)->commands = cmd->block.commands;
1316 for (;;) 1472 (*target)->num_commands = cmd->block.num_commands;
1317 { 1473 cmd->block.commands = NULL;
1318 fputs(">>", stdout); 1474 cmd->block.num_commands = 0;
1319 fflush(stdout); 1475 return 1;
1320 fgets(cmd_buf, sizeof(cmd_buf), stdin);
1321 if (!strcmp(cmd_buf, "end\n")) {
1322 return 1;
1323 } else {
1324 if ((*target)->num_commands == cmd_storage) {
1325 cmd_storage *= 2;
1326 (*target)->commands = realloc((*target)->commands, cmd_storage * sizeof(parsed_command));
1327 }
1328 if (parse_command(root, cmd_buf, (*target)->commands + (*target)->num_commands)) {
1329 ++(*target)->num_commands;
1330 }
1331 }
1332 }
1333 } 1476 }
1334 1477
1335 const char *expr_type_names[] = { 1478 const char *expr_type_names[] = {
1336 "EXPR_NONE", 1479 "EXPR_NONE",
1337 "EXPR_SCALAR", 1480 "EXPR_SCALAR",
1339 "EXPR_BINARY", 1482 "EXPR_BINARY",
1340 "EXPR_SIZE", 1483 "EXPR_SIZE",
1341 "EXPR_MEM" 1484 "EXPR_MEM"
1342 }; 1485 };
1343 1486
1344 static uint8_t run_command(debug_root *root, parsed_command *cmd) 1487 static uint8_t cmd_set(debug_root *root, parsed_command *cmd)
1345 {
1346 if (cmd->def->raw_impl) {
1347 return cmd->def->raw_impl(root, cmd->format, cmd->raw);
1348 } else {
1349 for (int i = 0; i < cmd->num_args; i++)
1350 {
1351 if (!eval_expr(root, cmd->args[i].parsed, &cmd->args[i].value)) {
1352 fprintf(stderr, "Failed to eval %s\n", cmd->args[i].raw);
1353 return 1;
1354 }
1355 }
1356 return cmd->def->impl(root, cmd->format, cmd->num_args, cmd->args);
1357 }
1358 }
1359
1360 static uint8_t cmd_set(debug_root *root, char *format, int num_args, command_arg *args)
1361 { 1488 {
1362 char *name = NULL; 1489 char *name = NULL;
1363 char size = 0; 1490 char size = 0;
1364 uint32_t address; 1491 uint32_t address;
1365 switch (args[0].parsed->type) 1492 switch (cmd->args[0].parsed->type)
1366 { 1493 {
1367 case EXPR_SCALAR: 1494 case EXPR_SCALAR:
1368 if (args[0].parsed->op.type == TOKEN_NAME) { 1495 if (cmd->args[0].parsed->op.type == TOKEN_NAME) {
1369 name = args[0].parsed->op.v.str; 1496 name = cmd->args[0].parsed->op.v.str;
1370 } else { 1497 } else {
1371 fputs("First argument to set must be a name or memory expression, not a number", stderr); 1498 fputs("First argument to set must be a name or memory expression, not a number", stderr);
1372 return 1; 1499 return 1;
1373 } 1500 }
1374 break; 1501 break;
1375 case EXPR_SIZE: 1502 case EXPR_SIZE:
1376 size = args[0].parsed->op.v.op[0]; 1503 size = cmd->args[0].parsed->op.v.op[0];
1377 if (args[0].parsed->left->op.type == TOKEN_NAME) { 1504 if (cmd->args[0].parsed->left->op.type == TOKEN_NAME) {
1378 name = args[0].parsed->left->op.v.str; 1505 name = cmd->args[0].parsed->left->op.v.str;
1379 } else { 1506 } else {
1380 fputs("First argument to set must be a name or memory expression, not a number", stderr); 1507 fputs("First argument to set must be a name or memory expression, not a number", stderr);
1381 return 1; 1508 return 1;
1382 } 1509 }
1383 break; 1510 break;
1384 case EXPR_MEM: 1511 case EXPR_MEM:
1385 size = args[0].parsed->op.v.op[0]; 1512 size = cmd->args[0].parsed->op.v.op[0];
1386 if (!eval_expr(root, args[0].parsed->left, &address)) { 1513 if (!eval_expr(root, cmd->args[0].parsed->left, &address)) {
1387 fprintf(stderr, "Failed to eval %s\n", args[0].raw); 1514 fprintf(stderr, "Failed to eval %s\n", cmd->args[0].raw);
1388 return 1; 1515 return 1;
1389 } 1516 }
1390 break; 1517 break;
1391 default: 1518 default:
1392 fprintf(stderr, "First argument to set must be a name or memory expression, got %s\n", expr_type_names[args[0].parsed->type]); 1519 fprintf(stderr, "First argument to set must be a name or memory expression, got %s\n", expr_type_names[cmd->args[0].parsed->type]);
1393 return 1; 1520 return 1;
1394 } 1521 }
1395 if (!eval_expr(root, args[1].parsed, &args[1].value)) { 1522 if (!eval_expr(root, cmd->args[1].parsed, &cmd->args[1].value)) {
1396 fprintf(stderr, "Failed to eval %s\n", args[1].raw); 1523 fprintf(stderr, "Failed to eval %s\n", cmd->args[1].raw);
1397 return 1; 1524 return 1;
1398 } 1525 }
1399 uint32_t value = args[1].value; 1526 uint32_t value = cmd->args[1].value;
1400 if (name && size && size != 'l') { 1527 if (name && size && size != 'l') {
1401 uint32_t old; 1528 uint32_t old;
1402 if (!root->resolve(root, name, &old)) { 1529 if (!root->resolve(root, name, &old)) {
1403 fprintf(stderr, "Failed to eval %s\n", name); 1530 fprintf(stderr, "Failed to eval %s\n", name);
1404 return 1; 1531 return 1;
1421 fprintf(stderr, "Failed to write to address %X\n", address); 1548 fprintf(stderr, "Failed to write to address %X\n", address);
1422 } 1549 }
1423 return 1; 1550 return 1;
1424 } 1551 }
1425 1552
1426 static uint8_t cmd_frames(debug_root *root, char *format, int num_args, command_arg *args) 1553 static uint8_t cmd_frames(debug_root *root, parsed_command *cmd)
1427 { 1554 {
1428 current_system->enter_debugger_frames = args[0].value; 1555 current_system->enter_debugger_frames = cmd->args[0].value;
1429 return 0; 1556 return 0;
1430 } 1557 }
1431 1558
1432 static uint8_t cmd_bindup(debug_root *root, char *format, char *param) 1559 static uint8_t cmd_bindup(debug_root *root, parsed_command *cmd)
1433 { 1560 {
1434 if (!bind_up(param)) { 1561 if (!bind_up(cmd->raw)) {
1435 fprintf(stderr, "%s is not a valid binding name\n", param); 1562 fprintf(stderr, "%s is not a valid binding name\n", cmd->raw);
1436 } 1563 }
1437 return 1; 1564 return 1;
1438 } 1565 }
1439 1566
1440 static uint8_t cmd_binddown(debug_root *root, char *format, char *param) 1567 static uint8_t cmd_binddown(debug_root *root, parsed_command *cmd)
1441 { 1568 {
1442 if (!bind_down(param)) { 1569 if (!bind_down(cmd->raw)) {
1443 fprintf(stderr, "%s is not a valid binding name\n", param); 1570 fprintf(stderr, "%s is not a valid binding name\n", cmd->raw);
1444 } 1571 }
1445 return 1; 1572 return 1;
1446 } 1573 }
1447 1574
1448 static uint8_t cmd_condition(debug_root *root, char *format, int num_args, command_arg *args) 1575 static uint8_t cmd_condition(debug_root *root, parsed_command *cmd)
1449 { 1576 {
1450 if (!eval_expr(root, args[0].parsed, &args[0].value)) { 1577 if (!eval_expr(root, cmd->args[0].parsed, &cmd->args[0].value)) {
1451 fprintf(stderr, "Failed to evaluate breakpoint number: %s\n", args[0].raw); 1578 fprintf(stderr, "Failed to evaluate breakpoint number: %s\n", cmd->args[0].raw);
1452 return 1; 1579 return 1;
1453 } 1580 }
1454 bp_def **target = find_breakpoint_idx(&root->breakpoints, args[0].value); 1581 bp_def **target = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value);
1455 if (!*target) { 1582 if (!*target) {
1456 fprintf(stderr, "Failed to find breakpoint %u\n", args[0].value); 1583 fprintf(stderr, "Failed to find breakpoint %u\n", cmd->args[0].value);
1457 return 1; 1584 return 1;
1458 } 1585 }
1459 free_expr((*target)->condition); 1586 free_expr((*target)->condition);
1460 if (num_args > 1 && args[1].parsed) { 1587 if (cmd->num_args > 1 && cmd->args[1].parsed) {
1461 (*target)->condition = args[1].parsed; 1588 (*target)->condition = cmd->args[1].parsed;
1462 args[1].parsed = NULL; 1589 cmd->args[1].parsed = NULL;
1463 } else { 1590 } else {
1464 (*target)->condition = NULL; 1591 (*target)->condition = NULL;
1465 } 1592 }
1466 return 1; 1593 return 1;
1467 } 1594 }
1468 1595
1469 static uint8_t cmd_delete_m68k(debug_root *root, char *format, int num_args, command_arg *args) 1596 static uint8_t cmd_delete_m68k(debug_root *root, parsed_command *cmd)
1470 { 1597 {
1471 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, args[0].value); 1598 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value);
1472 if (!*this_bp) { 1599 if (!*this_bp) {
1473 fprintf(stderr, "Breakpoint %d does not exist\n", args[0].value); 1600 fprintf(stderr, "Breakpoint %d does not exist\n", cmd->args[0].value);
1474 return 1; 1601 return 1;
1475 } 1602 }
1476 bp_def *tmp = *this_bp; 1603 bp_def *tmp = *this_bp;
1477 remove_breakpoint(root->cpu_context, tmp->address); 1604 remove_breakpoint(root->cpu_context, tmp->address);
1478 *this_bp = (*this_bp)->next; 1605 *this_bp = (*this_bp)->next;
1485 } 1612 }
1486 free(tmp); 1613 free(tmp);
1487 return 1; 1614 return 1;
1488 } 1615 }
1489 1616
1490 static uint8_t cmd_breakpoint_m68k(debug_root *root, char *format, int num_args, command_arg *args) 1617 static uint8_t cmd_breakpoint_m68k(debug_root *root, parsed_command *cmd)
1491 { 1618 {
1492 insert_breakpoint(root->cpu_context, args[0].value, debugger); 1619 insert_breakpoint(root->cpu_context, cmd->args[0].value, debugger);
1493 bp_def *new_bp = calloc(1, sizeof(bp_def)); 1620 bp_def *new_bp = calloc(1, sizeof(bp_def));
1494 new_bp->next = root->breakpoints; 1621 new_bp->next = root->breakpoints;
1495 new_bp->address = args[0].value; 1622 new_bp->address = cmd->args[0].value;
1496 new_bp->index = root->bp_index++; 1623 new_bp->index = root->bp_index++;
1497 root->breakpoints = new_bp; 1624 root->breakpoints = new_bp;
1498 printf("68K Breakpoint %d set at %X\n", new_bp->index, args[0].value); 1625 printf("68K Breakpoint %d set at %X\n", new_bp->index, cmd->args[0].value);
1499 return 1; 1626 return 1;
1500 } 1627 }
1501 1628
1502 static uint8_t cmd_advance_m68k(debug_root *root, char *format, int num_args, command_arg *args) 1629 static uint8_t cmd_advance_m68k(debug_root *root, parsed_command *cmd)
1503 { 1630 {
1504 insert_breakpoint(root->cpu_context, args[0].value, debugger); 1631 insert_breakpoint(root->cpu_context, cmd->args[0].value, debugger);
1505 return 0; 1632 return 0;
1506 } 1633 }
1507 1634
1508 static uint8_t cmd_step_m68k(debug_root *root, char *format, int num_args, command_arg *args) 1635 static uint8_t cmd_step_m68k(debug_root *root, parsed_command *cmd)
1509 { 1636 {
1510 m68kinst *inst = root->inst; 1637 m68kinst *inst = root->inst;
1511 m68k_context *context = root->cpu_context; 1638 m68k_context *context = root->cpu_context;
1512 uint32_t after = root->after; 1639 uint32_t after = root->after;
1513 if (inst->op == M68K_RTS) { 1640 if (inst->op == M68K_RTS) {
1535 } 1662 }
1536 insert_breakpoint(root->cpu_context, after, debugger); 1663 insert_breakpoint(root->cpu_context, after, debugger);
1537 return 0; 1664 return 0;
1538 } 1665 }
1539 1666
1540 static uint8_t cmd_over_m68k(debug_root *root, char *format, int num_args, command_arg *args) 1667 static uint8_t cmd_over_m68k(debug_root *root, parsed_command *cmd)
1541 { 1668 {
1542 m68kinst *inst = root->inst; 1669 m68kinst *inst = root->inst;
1543 m68k_context *context = root->cpu_context; 1670 m68k_context *context = root->cpu_context;
1544 uint32_t after = root->after; 1671 uint32_t after = root->after;
1545 if (inst->op == M68K_RTS) { 1672 if (inst->op == M68K_RTS) {
1572 } 1699 }
1573 insert_breakpoint(root->cpu_context, after, debugger); 1700 insert_breakpoint(root->cpu_context, after, debugger);
1574 return 0; 1701 return 0;
1575 } 1702 }
1576 1703
1577 static uint8_t cmd_next_m68k(debug_root *root, char *format, int num_args, command_arg *args) 1704 static uint8_t cmd_next_m68k(debug_root *root, parsed_command *cmd)
1578 { 1705 {
1579 m68kinst *inst = root->inst; 1706 m68kinst *inst = root->inst;
1580 m68k_context *context = root->cpu_context; 1707 m68k_context *context = root->cpu_context;
1581 uint32_t after = root->after; 1708 uint32_t after = root->after;
1582 if (inst->op == M68K_RTS) { 1709 if (inst->op == M68K_RTS) {
1604 } 1731 }
1605 insert_breakpoint(root->cpu_context, after, debugger); 1732 insert_breakpoint(root->cpu_context, after, debugger);
1606 return 0; 1733 return 0;
1607 } 1734 }
1608 1735
1609 static uint8_t cmd_backtrace_m68k(debug_root *root, char *format, int num_args, command_arg *args) 1736 static uint8_t cmd_backtrace_m68k(debug_root *root, parsed_command *cmd)
1610 { 1737 {
1611 m68k_context *context = root->cpu_context; 1738 m68k_context *context = root->cpu_context;
1612 uint32_t stack = context->aregs[7]; 1739 uint32_t stack = context->aregs[7];
1613 uint8_t non_adr_count = 0; 1740 uint8_t non_adr_count = 0;
1614 do { 1741 do {
1630 //TODO: Make sure we don't wander into an invalid memory region 1757 //TODO: Make sure we don't wander into an invalid memory region
1631 } while (stack && non_adr_count < 6); 1758 } while (stack && non_adr_count < 6);
1632 return 1; 1759 return 1;
1633 } 1760 }
1634 1761
1635 static uint8_t cmd_vdp_sprites(debug_root *root, char *format, int num_args, command_arg *args) 1762 static uint8_t cmd_vdp_sprites(debug_root *root, parsed_command *cmd)
1636 { 1763 {
1637 m68k_context *context = root->cpu_context; 1764 m68k_context *context = root->cpu_context;
1638 genesis_context * gen = context->system; 1765 genesis_context * gen = context->system;
1639 vdp_print_sprite_table(gen->vdp); 1766 vdp_print_sprite_table(gen->vdp);
1640 return 1; 1767 return 1;
1641 } 1768 }
1642 1769
1643 static uint8_t cmd_vdp_regs(debug_root *root, char *format, int num_args, command_arg *args) 1770 static uint8_t cmd_vdp_regs(debug_root *root, parsed_command *cmd)
1644 { 1771 {
1645 m68k_context *context = root->cpu_context; 1772 m68k_context *context = root->cpu_context;
1646 genesis_context * gen = context->system; 1773 genesis_context * gen = context->system;
1647 vdp_print_reg_explain(gen->vdp); 1774 vdp_print_reg_explain(gen->vdp);
1648 return 1; 1775 return 1;
1649 } 1776 }
1650 1777
1651 static uint8_t cmd_ym_channel(debug_root *root, char *format, int num_args, command_arg *args) 1778 static uint8_t cmd_ym_channel(debug_root *root, parsed_command *cmd)
1652 { 1779 {
1653 m68k_context *context = root->cpu_context; 1780 m68k_context *context = root->cpu_context;
1654 genesis_context * gen = context->system; 1781 genesis_context * gen = context->system;
1655 if (num_args) { 1782 if (cmd->num_args) {
1656 ym_print_channel_info(gen->ym, args[0].value - 1); 1783 ym_print_channel_info(gen->ym, cmd->args[0].value - 1);
1657 } else { 1784 } else {
1658 for (int i = 0; i < 6; i++) { 1785 for (int i = 0; i < 6; i++) {
1659 ym_print_channel_info(gen->ym, i); 1786 ym_print_channel_info(gen->ym, i);
1660 } 1787 }
1661 } 1788 }
1662 return 1; 1789 return 1;
1663 } 1790 }
1664 1791
1665 static uint8_t cmd_ym_timer(debug_root *root, char *format, int num_args, command_arg *args) 1792 static uint8_t cmd_ym_timer(debug_root *root, parsed_command *cmd)
1666 { 1793 {
1667 m68k_context *context = root->cpu_context; 1794 m68k_context *context = root->cpu_context;
1668 genesis_context * gen = context->system; 1795 genesis_context * gen = context->system;
1669 ym_print_timer_info(gen->ym); 1796 ym_print_timer_info(gen->ym);
1670 return 1; 1797 return 1;
1671 } 1798 }
1672 1799
1673 static uint8_t cmd_sub(debug_root *root, char *format, char *param) 1800 static uint8_t cmd_sub(debug_root *root, parsed_command *cmd)
1674 { 1801 {
1802 char *param = cmd->raw;
1675 while (param && *param && isblank(*param)) 1803 while (param && *param && isblank(*param))
1676 { 1804 {
1677 ++param; 1805 ++param;
1678 } 1806 }
1679 m68k_context *m68k = root->cpu_context; 1807 m68k_context *m68k = root->cpu_context;
1696 cd->enter_debugger = 1; 1824 cd->enter_debugger = 1;
1697 return 0; 1825 return 0;
1698 } 1826 }
1699 } 1827 }
1700 1828
1701 static uint8_t cmd_main(debug_root *root, char *format, char *param) 1829 static uint8_t cmd_main(debug_root *root, parsed_command *cmd)
1702 { 1830 {
1831 char *param = cmd->raw;
1703 while (param && *param && isblank(*param)) 1832 while (param && *param && isblank(*param))
1704 { 1833 {
1705 ++param; 1834 ++param;
1706 } 1835 }
1707 m68k_context *m68k = root->cpu_context; 1836 m68k_context *m68k = root->cpu_context;
1724 cd->genesis->header.enter_debugger = 1; 1853 cd->genesis->header.enter_debugger = 1;
1725 return 0; 1854 return 0;
1726 } 1855 }
1727 } 1856 }
1728 1857
1729 static uint8_t cmd_gen_z80(debug_root *root, char *format, char *param) 1858 static uint8_t cmd_gen_z80(debug_root *root, parsed_command *cmd)
1730 { 1859 {
1860 char *param = cmd->raw;
1731 while (param && *param && isblank(*param)) 1861 while (param && *param && isblank(*param))
1732 { 1862 {
1733 ++param; 1863 ++param;
1734 } 1864 }
1735 m68k_context *m68k = root->cpu_context; 1865 m68k_context *m68k = root->cpu_context;
1769 .names = (const char *[]){ 1899 .names = (const char *[]){
1770 "help", "?", NULL 1900 "help", "?", NULL
1771 }, 1901 },
1772 .usage = "help", 1902 .usage = "help",
1773 .desc = "Print a list of available commands for the current debug context", 1903 .desc = "Print a list of available commands for the current debug context",
1774 .raw_impl = cmd_help, 1904 .impl = cmd_help,
1775 .min_args = 0, 1905 .min_args = 0,
1776 .max_args = 1 1906 .max_args = 1,
1907 .raw_args = 1
1777 }, 1908 },
1778 { 1909 {
1779 .names = (const char *[]){ 1910 .names = (const char *[]){
1780 "continue", "c", NULL 1911 "continue", "c", NULL
1781 }, 1912 },
1799 .names = (const char *[]){ 1930 .names = (const char *[]){
1800 "printf", NULL 1931 "printf", NULL
1801 }, 1932 },
1802 .usage = "printf FORMAT EXPRESSION...", 1933 .usage = "printf FORMAT EXPRESSION...",
1803 .desc = "Print a string with C-style formatting specifiers replaced with the value of the remaining arguments", 1934 .desc = "Print a string with C-style formatting specifiers replaced with the value of the remaining arguments",
1804 .raw_impl = cmd_printf, 1935 .impl = cmd_printf,
1805 .min_args = 1, 1936 .min_args = 1,
1806 .max_args = -1 1937 .max_args = -1,
1938 .raw_args = 1
1807 }, 1939 },
1808 { 1940 {
1809 .names = (const char *[]){ 1941 .names = (const char *[]){
1810 "softreset", "sr", NULL 1942 "softreset", "sr", NULL
1811 }, 1943 },
1841 }, 1973 },
1842 .usage = "command BREAKPOINT", 1974 .usage = "command BREAKPOINT",
1843 .desc = "Set a list of debugger commands to be executed when the given breakpoint is hit", 1975 .desc = "Set a list of debugger commands to be executed when the given breakpoint is hit",
1844 .impl = cmd_command, 1976 .impl = cmd_command,
1845 .min_args = 1, 1977 .min_args = 1,
1846 .max_args = 1 1978 .max_args = 1,
1979 .has_block = 1
1847 }, 1980 },
1848 { 1981 {
1849 .names = (const char *[]){ 1982 .names = (const char *[]){
1850 "set", NULL 1983 "set", NULL
1851 }, 1984 },
1870 .names = (const char *[]){ 2003 .names = (const char *[]){
1871 "bindup", NULL 2004 "bindup", NULL
1872 }, 2005 },
1873 .usage = "bindup NAME", 2006 .usage = "bindup NAME",
1874 .desc = "Simulate a keyup for binding NAME", 2007 .desc = "Simulate a keyup for binding NAME",
1875 .raw_impl = cmd_bindup, 2008 .impl = cmd_bindup,
1876 .min_args = 1, 2009 .min_args = 1,
1877 .max_args = 1 2010 .max_args = 1,
2011 .raw_args = 1
1878 }, 2012 },
1879 { 2013 {
1880 .names = (const char *[]){ 2014 .names = (const char *[]){
1881 "binddown", NULL 2015 "binddown", NULL
1882 }, 2016 },
1883 .usage = "bindown NAME", 2017 .usage = "bindown NAME",
1884 .desc = "Simulate a keydown for binding NAME", 2018 .desc = "Simulate a keydown for binding NAME",
1885 .raw_impl = cmd_binddown, 2019 .impl = cmd_binddown,
1886 .min_args = 1, 2020 .min_args = 1,
1887 .max_args = 1 2021 .max_args = 1,
2022 .raw_args = 1
1888 }, 2023 },
1889 { 2024 {
1890 .names = (const char *[]){ 2025 .names = (const char *[]){
1891 "condition", NULL 2026 "condition", NULL
1892 }, 2027 },
1893 .usage = "condition BREAKPOINT [EXPRESSION]", 2028 .usage = "condition BREAKPOINT [EXPRESSION]",
1894 .desc = "Makes breakpoint BREAKPOINT conditional on the value of EXPRESSION or removes a condition if EXPRESSION is omitted", 2029 .desc = "Makes breakpoint BREAKPOINT conditional on the value of EXPRESSION or removes a condition if EXPRESSION is omitted",
1895 .impl = cmd_condition, 2030 .impl = cmd_condition,
1896 .min_args = 1, 2031 .min_args = 1,
1897 .max_args = 2 2032 .max_args = 2,
2033 .skip_eval = 1
1898 } 2034 }
1899 }; 2035 };
1900 #define NUM_COMMON (sizeof(common_commands)/sizeof(*common_commands)) 2036 #define NUM_COMMON (sizeof(common_commands)/sizeof(*common_commands))
1901 2037
1902 command_def m68k_commands[] = { 2038 command_def m68k_commands[] = {
2000 .names = (const char *[]){ 2136 .names = (const char *[]){
2001 "z80", NULL 2137 "z80", NULL
2002 }, 2138 },
2003 .usage = "z80 [COMMAND]", 2139 .usage = "z80 [COMMAND]",
2004 .desc = "Run a Z80 debugger command or switch to Z80 context when no command is given", 2140 .desc = "Run a Z80 debugger command or switch to Z80 context when no command is given",
2005 .raw_impl = cmd_gen_z80, 2141 .impl = cmd_gen_z80,
2006 .min_args = 0, 2142 .min_args = 0,
2007 .max_args = -1 2143 .max_args = -1,
2144 .raw_args = 1
2008 }, 2145 },
2009 #endif 2146 #endif
2010 { 2147 {
2011 .names = (const char *[]){ 2148 .names = (const char *[]){
2012 "ymchannel", "yc", NULL 2149 "ymchannel", "yc", NULL
2036 .names = (const char *[]){ 2173 .names = (const char *[]){
2037 "subcpu", NULL 2174 "subcpu", NULL
2038 }, 2175 },
2039 .usage = "subcpu [COMMAND]", 2176 .usage = "subcpu [COMMAND]",
2040 .desc = "Run a Sub-CPU debugger command or switch to Sub-CPU context when no command is given", 2177 .desc = "Run a Sub-CPU debugger command or switch to Sub-CPU context when no command is given",
2041 .raw_impl = cmd_sub, 2178 .impl = cmd_sub,
2042 .min_args = 0, 2179 .min_args = 0,
2043 .max_args = -1 2180 .max_args = -1,
2181 .raw_args = 1
2044 } 2182 }
2045 }; 2183 };
2046 2184
2047 #define NUM_SCD_MAIN (sizeof(scd_main_commands)/sizeof(*scd_main_commands)) 2185 #define NUM_SCD_MAIN (sizeof(scd_main_commands)/sizeof(*scd_main_commands))
2048 2186
2051 .names = (const char *[]){ 2189 .names = (const char *[]){
2052 "maincpu", NULL 2190 "maincpu", NULL
2053 }, 2191 },
2054 .usage = "maincpu [COMMAND]", 2192 .usage = "maincpu [COMMAND]",
2055 .desc = "Run a Main-CPU debugger command or switch to Main-CPU context when no command is given", 2193 .desc = "Run a Main-CPU debugger command or switch to Main-CPU context when no command is given",
2056 .raw_impl = cmd_main, 2194 .impl = cmd_main,
2057 .min_args = 0, 2195 .min_args = 0,
2058 .max_args = -1 2196 .max_args = -1,
2197 .raw_args = 1
2059 } 2198 }
2060 }; 2199 };
2061 2200
2062 #define NUM_SCD_SUB (sizeof(scd_main_commands)/sizeof(*scd_main_commands)) 2201 #define NUM_SCD_SUB (sizeof(scd_main_commands)/sizeof(*scd_main_commands))
2063 2202
2064 #ifndef NO_Z80 2203 #ifndef NO_Z80
2065 2204
2066 static uint8_t cmd_delete_z80(debug_root *root, char *format, int num_args, command_arg *args) 2205 static uint8_t cmd_delete_z80(debug_root *root, parsed_command *cmd)
2067 { 2206 {
2068 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, args[0].value); 2207 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value);
2069 if (!*this_bp) { 2208 if (!*this_bp) {
2070 fprintf(stderr, "Breakpoint %d does not exist\n", args[0].value); 2209 fprintf(stderr, "Breakpoint %d does not exist\n", cmd->args[0].value);
2071 return 1; 2210 return 1;
2072 } 2211 }
2073 bp_def *tmp = *this_bp; 2212 bp_def *tmp = *this_bp;
2074 zremove_breakpoint(root->cpu_context, tmp->address); 2213 zremove_breakpoint(root->cpu_context, tmp->address);
2075 *this_bp = (*this_bp)->next; 2214 *this_bp = (*this_bp)->next;
2082 } 2221 }
2083 free(tmp); 2222 free(tmp);
2084 return 1; 2223 return 1;
2085 } 2224 }
2086 2225
2087 static uint8_t cmd_breakpoint_z80(debug_root *root, char *format, int num_args, command_arg *args) 2226 static uint8_t cmd_breakpoint_z80(debug_root *root, parsed_command *cmd)
2088 { 2227 {
2089 zinsert_breakpoint(root->cpu_context, args[0].value, (uint8_t *)zdebugger); 2228 zinsert_breakpoint(root->cpu_context, cmd->args[0].value, (uint8_t *)zdebugger);
2090 bp_def *new_bp = calloc(1, sizeof(bp_def)); 2229 bp_def *new_bp = calloc(1, sizeof(bp_def));
2091 new_bp->next = root->breakpoints; 2230 new_bp->next = root->breakpoints;
2092 new_bp->address = args[0].value; 2231 new_bp->address = cmd->args[0].value;
2093 new_bp->index = root->bp_index++; 2232 new_bp->index = root->bp_index++;
2094 root->breakpoints = new_bp; 2233 root->breakpoints = new_bp;
2095 printf("Z80 Breakpoint %d set at %X\n", new_bp->index, args[0].value); 2234 printf("Z80 Breakpoint %d set at %X\n", new_bp->index, cmd->args[0].value);
2096 return 1; 2235 return 1;
2097 } 2236 }
2098 2237
2099 static uint8_t cmd_advance_z80(debug_root *root, char *format, int num_args, command_arg *args) 2238 static uint8_t cmd_advance_z80(debug_root *root, parsed_command *cmd)
2100 { 2239 {
2101 zinsert_breakpoint(root->cpu_context, args[0].value, (uint8_t *)zdebugger); 2240 zinsert_breakpoint(root->cpu_context, cmd->args[0].value, (uint8_t *)zdebugger);
2102 return 0; 2241 return 0;
2103 } 2242 }
2104 2243
2105 static uint8_t cmd_step_z80(debug_root *root, char *format, int num_args, command_arg *args) 2244 static uint8_t cmd_step_z80(debug_root *root, parsed_command *cmd)
2106 { 2245 {
2107 z80inst *inst = root->inst; 2246 z80inst *inst = root->inst;
2108 z80_context *context = root->cpu_context; 2247 z80_context *context = root->cpu_context;
2109 uint32_t after = root->after; 2248 uint32_t after = root->after;
2110 //TODO: handle conditional branches 2249 //TODO: handle conditional branches
2134 } 2273 }
2135 zinsert_breakpoint(context, after, (uint8_t *)zdebugger); 2274 zinsert_breakpoint(context, after, (uint8_t *)zdebugger);
2136 return 0; 2275 return 0;
2137 } 2276 }
2138 2277
2139 static uint8_t cmd_over_z80(debug_root *root, char *format, int num_args, command_arg *args) 2278 static uint8_t cmd_over_z80(debug_root *root, parsed_command *cmd)
2140 { 2279 {
2141 fputs("not implemented yet\n", stderr); 2280 fputs("not implemented yet\n", stderr);
2142 return 1; 2281 return 1;
2143 } 2282 }
2144 2283
2145 static uint8_t cmd_next_z80(debug_root *root, char *format, int num_args, command_arg *args) 2284 static uint8_t cmd_next_z80(debug_root *root, parsed_command *cmd)
2146 { 2285 {
2147 z80inst *inst = root->inst; 2286 z80inst *inst = root->inst;
2148 z80_context *context = root->cpu_context; 2287 z80_context *context = root->cpu_context;
2149 uint32_t after = root->after; 2288 uint32_t after = root->after;
2150 //TODO: handle conditional branches 2289 //TODO: handle conditional branches
2174 } 2313 }
2175 zinsert_breakpoint(context, after, (uint8_t *)zdebugger); 2314 zinsert_breakpoint(context, after, (uint8_t *)zdebugger);
2176 return 0; 2315 return 0;
2177 } 2316 }
2178 2317
2179 static uint8_t cmd_backtrace_z80(debug_root *root, char *format, int num_args, command_arg *args) 2318 static uint8_t cmd_backtrace_z80(debug_root *root, parsed_command *cmd)
2180 { 2319 {
2181 z80_context *context = root->cpu_context; 2320 z80_context *context = root->cpu_context;
2182 uint32_t stack = context->sp; 2321 uint32_t stack = context->sp;
2183 uint8_t non_adr_count = 0; 2322 uint8_t non_adr_count = 0;
2184 do { 2323 do {
2204 //TODO: Make sure we don't wander into an invalid memory region 2343 //TODO: Make sure we don't wander into an invalid memory region
2205 } while (stack && non_adr_count < 6); 2344 } while (stack && non_adr_count < 6);
2206 return 1; 2345 return 1;
2207 } 2346 }
2208 2347
2209 static uint8_t cmd_gen_m68k(debug_root *root, char *format, char *param) 2348 static uint8_t cmd_gen_m68k(debug_root *root, parsed_command *cmd)
2210 { 2349 {
2350 char *param = cmd->raw;
2211 while (param && *param && isblank(*param)) 2351 while (param && *param && isblank(*param))
2212 { 2352 {
2213 ++param; 2353 ++param;
2214 } 2354 }
2215 genesis_context *gen = (genesis_context *)current_system; 2355 genesis_context *gen = (genesis_context *)current_system;
2313 .names = (const char *[]){ 2453 .names = (const char *[]){
2314 "m68k", NULL 2454 "m68k", NULL
2315 }, 2455 },
2316 .usage = "m68k [COMMAND]", 2456 .usage = "m68k [COMMAND]",
2317 .desc = "Run a M68K debugger command or switch to M68K context when no command is given", 2457 .desc = "Run a M68K debugger command or switch to M68K context when no command is given",
2318 .raw_impl = cmd_gen_m68k, 2458 .impl = cmd_gen_m68k,
2319 .min_args = 0, 2459 .min_args = 0,
2320 .max_args = -1 2460 .max_args = -1,
2461 .raw_args = 1
2321 } 2462 }
2322 }; 2463 };
2323 2464
2324 #define NUM_GEN_Z80 (sizeof(gen_z80_commands)/sizeof(*gen_z80_commands)) 2465 #define NUM_GEN_Z80 (sizeof(gen_z80_commands)/sizeof(*gen_z80_commands))
2325 2466
2869 init_terminal(); 3010 init_terminal();
2870 debug_root *root = find_z80_root(context); 3011 debug_root *root = find_z80_root(context);
2871 if (!root) { 3012 if (!root) {
2872 return context; 3013 return context;
2873 } 3014 }
3015 root->address = address;
2874 //Check if this is a user set breakpoint, or just a temporary one 3016 //Check if this is a user set breakpoint, or just a temporary one
2875 bp_def ** this_bp = find_breakpoint(&root->breakpoints, address); 3017 bp_def ** this_bp = find_breakpoint(&root->breakpoints, address);
2876 if (*this_bp) { 3018 if (*this_bp) {
2877 if ((*this_bp)->condition) { 3019 if ((*this_bp)->condition) {
2878 uint32_t condres; 3020 uint32_t condres;
2892 } 3034 }
2893 uint8_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->Z80_OPTS->gen); 3035 uint8_t * pc = get_native_pointer(address, (void **)context->mem_pointers, &context->Z80_OPTS->gen);
2894 if (!pc) { 3036 if (!pc) {
2895 fatal_error("Failed to get native pointer on entering Z80 debugger at address %X\n", address); 3037 fatal_error("Failed to get native pointer on entering Z80 debugger at address %X\n", address);
2896 } 3038 }
3039 uint8_t * after_pc = z80_decode(pc, &inst);
3040 uint16_t after = address + (after_pc-pc);
3041 root->after = after;
3042 root->inst = &inst;
2897 for (disp_def * cur = root->displays; cur; cur = cur->next) { 3043 for (disp_def * cur = root->displays; cur; cur = cur->next) {
3044 char format_str[8];
3045 make_format_str(format_str, cur->format);
2898 for (int i = 0; i < cur->num_args; i++) 3046 for (int i = 0; i < cur->num_args; i++)
2899 { 3047 {
2900 eval_expr(root, cur->args[i].parsed, &cur->args[i].value); 3048 eval_expr(root, cur->args[i].parsed, &cur->args[i].value);
2901 } 3049 do_print(root, format_str, cur->args[i].raw, cur->args[i].value);
2902 cmd_print(root, cur->format, cur->num_args, cur->args); 3050 }
2903 } 3051 }
2904 uint8_t * after_pc = z80_decode(pc, &inst); 3052
2905 z80_disasm(&inst, input_buf, address); 3053 z80_disasm(&inst, input_buf, address);
2906 printf("%X:\t%s\n", address, input_buf); 3054 printf("%X:\t%s\n", address, input_buf);
2907 uint16_t after = address + (after_pc-pc); 3055 debugger_repl(root);
2908 root->address = address;
2909 root->after = after;
2910 root->inst = &inst;
2911 int debugging = 1;
2912 while(debugging) {
2913 fputs(">", stdout);
2914 if (!fgets(input_buf, sizeof(input_buf), stdin)) {
2915 fputs("fgets failed", stderr);
2916 break;
2917 }
2918 strip_nl(input_buf);
2919 //hitting enter repeats last command
2920 if (input_buf[0]) {
2921 strcpy(last_cmd, input_buf);
2922 } else {
2923 strcpy(input_buf, last_cmd);
2924 }
2925 parsed_command cmd;
2926 if (parse_command(root, input_buf, &cmd)) {
2927 debugging = run_command(root, &cmd);
2928 free_parsed_command(&cmd);
2929 }
2930 }
2931 return context; 3056 return context;
2932 } 3057 }
2933 3058
2934 #endif 3059 #endif
2935 3060
2997 } 3122 }
2998 uint32_t after = m68k_decode(m68k_instruction_fetch, context, &inst, address); 3123 uint32_t after = m68k_decode(m68k_instruction_fetch, context, &inst, address);
2999 root->after = after; 3124 root->after = after;
3000 root->inst = &inst; 3125 root->inst = &inst;
3001 for (disp_def * cur = root->displays; cur; cur = cur->next) { 3126 for (disp_def * cur = root->displays; cur; cur = cur->next) {
3127 char format_str[8];
3128 make_format_str(format_str, cur->format);
3002 for (int i = 0; i < cur->num_args; i++) 3129 for (int i = 0; i < cur->num_args; i++)
3003 { 3130 {
3004 eval_expr(root, cur->args[i].parsed, &cur->args[i].value); 3131 eval_expr(root, cur->args[i].parsed, &cur->args[i].value);
3005 } 3132 do_print(root, format_str, cur->args[i].raw, cur->args[i].value);
3006 cmd_print(root, cur->format, cur->num_args, cur->args); 3133 }
3007 } 3134 }
3008 m68k_disasm(&inst, input_buf); 3135 m68k_disasm(&inst, input_buf);
3009 printf("%X: %s\n", address, input_buf); 3136 printf("%X: %s\n", address, input_buf);
3010 #ifdef _WIN32 3137 debugger_repl(root);
3011 #define prompt 1
3012 #else
3013 int prompt = 1;
3014 fd_set read_fds;
3015 FD_ZERO(&read_fds);
3016 struct timeval timeout;
3017 #endif
3018 while (debugging) {
3019 if (prompt) {
3020 fputs(">", stdout);
3021 fflush(stdout);
3022 }
3023 process_events();
3024 #ifndef _WIN32
3025 timeout.tv_sec = 0;
3026 timeout.tv_usec = 16667;
3027 FD_SET(fileno(stdin), &read_fds);
3028 if(select(fileno(stdin) + 1, &read_fds, NULL, NULL, &timeout) < 1) {
3029 prompt = 0;
3030 continue;
3031 } else {
3032 prompt = 1;
3033 }
3034 #endif
3035 if (!fgets(input_buf, sizeof(input_buf), stdin)) {
3036 fputs("fgets failed", stderr);
3037 break;
3038 }
3039 strip_nl(input_buf);
3040 //hitting enter repeats last command
3041 if (input_buf[0]) {
3042 strcpy(last_cmd, input_buf);
3043 } else {
3044 strcpy(input_buf, last_cmd);
3045 }
3046 parsed_command cmd;
3047 if (parse_command(root, input_buf, &cmd)) {
3048 debugging = run_command(root, &cmd);
3049 free_parsed_command(&cmd);
3050 }
3051 }
3052 return; 3138 return;
3053 } 3139 }