# HG changeset patch # User Michael Pavone # Date 1701930349 28800 # Node ID 340299a76db73177c9f9aeebf92987e401388510 # Parent 5f4917b9ecfac5a840b0d812de658c647d7d859d Add debugger load command diff -r 5f4917b9ecfa -r 340299a76db7 debug.c --- a/debug.c Tue Dec 05 21:29:21 2023 -0800 +++ b/debug.c Wed Dec 06 22:25:49 2023 -0800 @@ -150,7 +150,7 @@ array->append = user_array_append; array->size = size; array->storage = size ? size : 4; - array->base = calloc(size, sizeof(debug_val)); + array->base = calloc(array->storage, sizeof(debug_val)); debug_val ret; ret.type = DBG_VAL_ARRAY; ret.v.u32 = array - arrays; @@ -543,7 +543,7 @@ } else { free_expr(e->right); } - if (e->op.type == TOKEN_NAME) { + if (e->op.type == TOKEN_NAME || e->op.type == TOKEN_ARRAY) { free(e->op.v.str); } } @@ -3156,6 +3156,170 @@ return 1; } +static uint8_t cmd_load(debug_root *root, parsed_command *cmd) +{ + char size = cmd->format ? cmd->format[0] : 'b'; + if (size != 'b' && size != 'w' && size != 'l') { + fprintf(stderr, "Invalid size %s\n", cmd->format); + return 1; + } + FILE *f = fopen(cmd->args[0].raw, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading\n", cmd->args[0].raw); + return 1; + } + uint32_t start = 0; + debug_val val; + debug_array * arr = NULL; + if (cmd->args[1].parsed->type == EXPR_MEM) { + + if (!eval_expr(root, cmd->args[1].parsed->left, &val)) { + fprintf(stderr, "Failed to eval start index\n"); + goto cleanup; + } + if (!debug_cast_int(val, &start)) { + fprintf(stderr, "Start index must evaluate to integer\n"); + goto cleanup; + } + if (cmd->args[1].parsed->right) { + if (!eval_expr(root, cmd->args[1].parsed->right, &val)) { + fprintf(stderr, "Failed to eval array name in argument %s\n", cmd->args[1].raw); + goto cleanup; + } + arr = get_array(val); + if (!arr) { + fprintf(stderr, "Name in argument %s did not evaluate to an array\n", cmd->args[1].raw); + goto cleanup; + } + } + } else { + if (!eval_expr(root, cmd->args[1].parsed, &val)) { + fprintf(stderr, "Failed to eval %s\n", cmd->args[1].raw); + goto cleanup; + } + arr = get_array(val); + if (!arr) { + fprintf(stderr, "Argument %s did not evaluate to an array\n", cmd->args[1].raw); + goto cleanup; + } + } + uint32_t count = 0; + uint8_t has_count = 0; + if (cmd->num_args > 2) { + if (!eval_expr(root, cmd->args[2].parsed, &val)) { + fprintf(stderr, "Failed to eval %s\n", cmd->args[2].raw); + goto cleanup; + } + if (!debug_cast_int(val, &count)) { + fprintf(stderr, "Count must evaluate to integer\n"); + goto cleanup; + } + has_count = 1; + } + union { + uint8_t b[1024]; + uint16_t w[512]; + uint32_t l[256]; + } buffer; + uint32_t cur = start; + if (size == 'l') { + while (count || !has_count) + { + uint32_t n = (has_count && count < 256) ? count : 256; + count -= n; + n = fread(buffer.l, sizeof(uint32_t), n, f); + if (!n) { + break; + } + for (uint32_t i = 0; i < n ; i++) + { + if (arr) { + val = debug_int(buffer.l[i]); + if (cur >= arr->size) { + if (arr->append) { + arr->append(arr, val); + } else { + goto cleanup; + } + } else { + arr->set(arr, cur, val); + } + cur++; + } else { + if (!root->write_mem(root, cur, buffer.l[i], 'l')) { + goto cleanup; + } + cur += 4; + } + } + } + } else if (size == 'w') { + while (count || !has_count) + { + uint32_t n = (has_count && count < 512) ? count : 512; + count -= n; + n = fread(buffer.w, sizeof(uint16_t), n, f); + if (!n) { + break; + } + for (uint32_t i = 0; i < n ; i++) + { + if (arr) { + val = debug_int(buffer.w[i]); + if (cur >= arr->size) { + if (arr->append) { + arr->append(arr, val); + } else { + goto cleanup; + } + } else { + arr->set(arr, cur, val); + } + cur++; + } else { + if (!root->write_mem(root, cur, buffer.w[i], 'w')) { + goto cleanup; + } + cur += 2; + } + } + } + } else { + while (count || !has_count) + { + uint32_t n = (has_count && count < 1024) ? count : 1024; + count -= n; + n = fread(buffer.b, sizeof(uint8_t), n, f); + if (!n) { + break; + } + for (uint32_t i = 0; i < n ; i++) + { + if (arr) { + val = debug_int(buffer.b[i]); + if (cur >= arr->size) { + if (arr->append) { + arr->append(arr, val); + } else { + goto cleanup; + } + } else { + arr->set(arr, cur, val); + } + } else { + if (!root->write_mem(root, cur, buffer.b[i], 'b')) { + goto cleanup; + } + } + cur++; + } + } + } +cleanup: + fclose(f); + return 1; +} + static uint8_t cmd_delete_m68k(debug_root *root, parsed_command *cmd) { uint32_t index; @@ -3809,6 +3973,17 @@ .min_args = 2, .max_args = 3, .skip_eval = 1 + }, + { + .names = (const char *[]){ + "load", NULL + }, + .usage = "load[/SIZE] FILENAME ARRAY [COUNT]", + .desc = "Loads COUNT elements of size SIZE from a file to the array or memory region specified by ARRAY", + .impl = cmd_load, + .min_args = 2, + .max_args = 3, + .skip_eval = 1 } }; #define NUM_COMMON (sizeof(common_commands)/sizeof(*common_commands))