Mercurial > repos > blastem
comparison debug.c @ 2359:04d29635d238
Support for arrays in debugger language
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 28 Oct 2023 14:39:19 -0700 |
parents | 4b2ac43c106e |
children | 053ba4551c62 |
comparison
equal
deleted
inserted
replaced
2358:4b2ac43c106e | 2359:04d29635d238 |
---|---|
165 return (token) { | 165 return (token) { |
166 .type = TOKEN_RPAREN | 166 .type = TOKEN_RPAREN |
167 }; | 167 }; |
168 } | 168 } |
169 *end = start + 1; | 169 *end = start + 1; |
170 token_type type = TOKEN_NAME; | |
170 while (**end && !isspace(**end)) | 171 while (**end && !isspace(**end)) |
171 { | 172 { |
172 uint8_t done = 0; | 173 uint8_t done = 0; |
173 switch (**end) | 174 switch (**end) |
174 { | 175 { |
176 case '[': | |
177 type = TOKEN_ARRAY; | |
175 case '+': | 178 case '+': |
176 case '-': | 179 case '-': |
177 case '*': | 180 case '*': |
178 case '/': | 181 case '/': |
179 case '&': | 182 case '&': |
183 case '=': | 186 case '=': |
184 case '!': | 187 case '!': |
185 case '>': | 188 case '>': |
186 case '<': | 189 case '<': |
187 case '.': | 190 case '.': |
188 case '[': | |
189 case ']': | 191 case ']': |
190 case '(': | 192 case '(': |
191 case ')': | 193 case ')': |
192 done = 1; | 194 done = 1; |
193 break; | 195 break; |
200 } | 202 } |
201 char *name = malloc(*end - start + 1); | 203 char *name = malloc(*end - start + 1); |
202 memcpy(name, start, *end - start); | 204 memcpy(name, start, *end - start); |
203 name[*end-start] = 0; | 205 name[*end-start] = 0; |
204 return (token) { | 206 return (token) { |
205 .type = TOKEN_NAME, | 207 .type = type, |
206 .v = { | 208 .v = { |
207 .str = name | 209 .str = name |
208 } | 210 } |
209 }; | 211 }; |
210 } | 212 } |
247 ret->op = first; | 249 ret->op = first; |
248 ret->left = target; | 250 ret->left = target; |
249 *end = after_first; | 251 *end = after_first; |
250 return ret; | 252 return ret; |
251 } | 253 } |
252 if (first.type == TOKEN_LBRACKET) { | 254 if (first.type == TOKEN_LBRACKET || first.type == TOKEN_ARRAY) { |
253 expr *ret = calloc(1, sizeof(expr)); | 255 expr *ret = calloc(1, sizeof(expr)); |
254 ret->type = EXPR_MEM; | 256 ret->type = EXPR_MEM; |
257 if (first.type == TOKEN_ARRAY) { | |
258 //current token is the array name | |
259 //consume the bracket token | |
260 parse_token(after_first, &after_first); | |
261 ret->right = calloc(1, sizeof(expr)); | |
262 ret->right->type = EXPR_SCALAR; | |
263 ret->right->op = first; | |
264 } | |
265 | |
255 ret->left = parse_expression(after_first, end); | 266 ret->left = parse_expression(after_first, end); |
256 if (!ret->left) { | 267 if (!ret->left) { |
257 fprintf(stderr, "Expression expected after `[`\n"); | 268 fprintf(stderr, "Expression expected after `[`\n"); |
258 free(ret); | 269 free(ret); |
259 return NULL; | 270 return NULL; |
394 ret->type = EXPR_UNARY; | 405 ret->type = EXPR_UNARY; |
395 ret->op = first; | 406 ret->op = first; |
396 ret->left = target; | 407 ret->left = target; |
397 return ret; | 408 return ret; |
398 } | 409 } |
399 if (first.type == TOKEN_LBRACKET) { | 410 if (first.type == TOKEN_LBRACKET || first.type == TOKEN_ARRAY) { |
400 expr *ret = calloc(1, sizeof(expr)); | 411 expr *ret = calloc(1, sizeof(expr)); |
401 ret->type = EXPR_MEM; | 412 ret->type = EXPR_MEM; |
413 if (first.type == TOKEN_ARRAY) { | |
414 //current token is the array name | |
415 //consume the bracket token | |
416 parse_token(after_first, &after_first); | |
417 ret->right = calloc(1, sizeof(expr)); | |
418 ret->right->type = EXPR_SCALAR; | |
419 ret->right->op = first; | |
420 } | |
421 | |
402 ret->left = parse_expression(after_first, end); | 422 ret->left = parse_expression(after_first, end); |
403 if (!ret->left) { | 423 if (!ret->left) { |
404 fprintf(stderr, "Expression expected after `[`\n"); | 424 fprintf(stderr, "Expression expected after `[`\n"); |
405 free(ret); | 425 free(ret); |
406 return NULL; | 426 return NULL; |
510 ret->type = EXPR_UNARY; | 530 ret->type = EXPR_UNARY; |
511 ret->op = first; | 531 ret->op = first; |
512 ret->left = target; | 532 ret->left = target; |
513 return ret; | 533 return ret; |
514 } | 534 } |
515 if (first.type == TOKEN_LBRACKET) { | 535 if (first.type == TOKEN_LBRACKET || first.type == TOKEN_ARRAY) { |
516 expr *ret = calloc(1, sizeof(expr)); | 536 expr *ret = calloc(1, sizeof(expr)); |
517 ret->type = EXPR_MEM; | 537 ret->type = EXPR_MEM; |
538 if (first.type == TOKEN_ARRAY) { | |
539 //current token is the array name | |
540 //consume the bracket token | |
541 parse_token(after_first, &after_first); | |
542 ret->right = calloc(1, sizeof(expr)); | |
543 ret->right->type = EXPR_SCALAR; | |
544 ret->right->op = first; | |
545 } | |
546 | |
518 ret->left = parse_expression(after_first, end); | 547 ret->left = parse_expression(after_first, end); |
519 if (!ret->left) { | 548 if (!ret->left) { |
520 fprintf(stderr, "Expression expected after `[`\n"); | 549 fprintf(stderr, "Expression expected after `[`\n"); |
521 free(ret); | 550 free(ret); |
522 return NULL; | 551 return NULL; |
620 *end = after_first; | 649 *end = after_first; |
621 return ret; | 650 return ret; |
622 } | 651 } |
623 } | 652 } |
624 | 653 |
654 static debug_array* full_array_resolve(debug_root *root, const char *name) | |
655 { | |
656 debug_array *ret = root->array_resolve(root, name); | |
657 if (!ret) { | |
658 ret = tern_find_ptr(root->arrays, name); | |
659 } | |
660 return ret; | |
661 } | |
662 | |
625 uint8_t eval_expr(debug_root *root, expr *e, uint32_t *out) | 663 uint8_t eval_expr(debug_root *root, expr *e, uint32_t *out) |
626 { | 664 { |
627 uint32_t right; | 665 uint32_t right; |
628 switch(e->type) | 666 switch(e->type) |
629 { | 667 { |
723 } | 761 } |
724 return 1; | 762 return 1; |
725 case EXPR_MEM: | 763 case EXPR_MEM: |
726 if (!eval_expr(root, e->left, out)) { | 764 if (!eval_expr(root, e->left, out)) { |
727 return 0; | 765 return 0; |
766 } | |
767 if (e->right) { | |
768 debug_array *array = full_array_resolve(root, e->right->op.v.str); | |
769 if (!array || *out >= array->size) { | |
770 return 0; | |
771 } | |
772 *out = array->get(root, array, *out); | |
773 return 1; | |
728 } | 774 } |
729 return root->read_mem(root, out, e->op.v.op[0]); | 775 return root->read_mem(root, out, e->op.v.op[0]); |
730 default: | 776 default: |
731 return 0; | 777 return 0; |
732 } | 778 } |
917 if (!strcmp(name, "f") || !strcmp(name, "frame")) { | 963 if (!strcmp(name, "f") || !strcmp(name, "frame")) { |
918 *out = gen->vdp->frame; | 964 *out = gen->vdp->frame; |
919 return 1; | 965 return 1; |
920 } | 966 } |
921 return 0; | 967 return 0; |
968 } | |
969 | |
970 static uint32_t debug_vram_get(debug_root *root, debug_array *array, uint32_t index) | |
971 { | |
972 m68k_context *m68k = root->cpu_context; | |
973 genesis_context *gen = m68k->system; | |
974 return gen->vdp->vdpmem[index]; | |
975 } | |
976 | |
977 static void debug_vram_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) | |
978 { | |
979 m68k_context *m68k = root->cpu_context; | |
980 genesis_context *gen = m68k->system; | |
981 gen->vdp->vdpmem[index] = value; | |
982 } | |
983 | |
984 static uint32_t debug_vsram_get(debug_root *root, debug_array *array, uint32_t index) | |
985 { | |
986 m68k_context *m68k = root->cpu_context; | |
987 genesis_context *gen = m68k->system; | |
988 return gen->vdp->vsram[index] & VSRAM_BITS; | |
989 } | |
990 | |
991 static void debug_vsram_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) | |
992 { | |
993 m68k_context *m68k = root->cpu_context; | |
994 genesis_context *gen = m68k->system; | |
995 gen->vdp->vsram[index] = value; | |
996 } | |
997 | |
998 static uint32_t debug_cram_get(debug_root *root, debug_array *array, uint32_t index) | |
999 { | |
1000 m68k_context *m68k = root->cpu_context; | |
1001 genesis_context *gen = m68k->system; | |
1002 return gen->vdp->cram[index] & CRAM_BITS; | |
1003 } | |
1004 | |
1005 static void debug_cram_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) | |
1006 { | |
1007 m68k_context *m68k = root->cpu_context; | |
1008 genesis_context *gen = m68k->system; | |
1009 gen->vdp->cram[index] = value; | |
1010 } | |
1011 | |
1012 static uint32_t debug_vreg_get(debug_root *root, debug_array *array, uint32_t index) | |
1013 { | |
1014 m68k_context *m68k = root->cpu_context; | |
1015 genesis_context *gen = m68k->system; | |
1016 return gen->vdp->regs[index]; | |
1017 } | |
1018 | |
1019 static void debug_vreg_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) | |
1020 { | |
1021 m68k_context *m68k = root->cpu_context; | |
1022 genesis_context *gen = m68k->system; | |
1023 vdp_reg_write(gen->vdp, index, value); | |
1024 } | |
1025 | |
1026 static debug_array* resolve_vdp_array(debug_root *root, const char *name) | |
1027 { | |
1028 static debug_array vram = { | |
1029 .get = debug_vram_get, .set = debug_vram_set, | |
1030 .size = VRAM_SIZE, .storage = VRAM_SIZE | |
1031 }; | |
1032 static debug_array vsram = { | |
1033 .get = debug_vsram_get, .set = debug_vsram_set, | |
1034 }; | |
1035 static debug_array cram = { | |
1036 .get = debug_cram_get, .set = debug_cram_set, | |
1037 .storage = CRAM_SIZE, .size = CRAM_SIZE | |
1038 }; | |
1039 static debug_array regs = { | |
1040 .get = debug_vreg_get, .set = debug_vreg_set, | |
1041 .storage = VDP_REGS, .size = VDP_REGS | |
1042 }; | |
1043 if (!strcasecmp(name, "vram")) { | |
1044 return &vram; | |
1045 } | |
1046 if (!strcasecmp(name, "vsram")) { | |
1047 m68k_context *m68k = root->cpu_context; | |
1048 genesis_context *gen = m68k->system; | |
1049 vsram.storage = vsram.size = gen->vdp->vsram_size; | |
1050 return &vsram; | |
1051 } | |
1052 if (!strcasecmp(name, "cram")) { | |
1053 return &cram; | |
1054 } | |
1055 if (!strcasecmp(name, "reg")) { | |
1056 return ®s; | |
1057 } | |
1058 return NULL; | |
1059 } | |
1060 | |
1061 static debug_array* resolve_genesis_array(debug_root *root, const char *name) | |
1062 { | |
1063 for (const char *cur = name; *cur; ++cur) | |
1064 { | |
1065 if (*cur == ':') { | |
1066 if (cur - name == 3 && !memcmp(name, "vdp", 3)) { | |
1067 return resolve_vdp_array(root, cur + 1); | |
1068 } /*else if (cur - name == 3 && !memcmp(name, "sub", 3)) { | |
1069 m68k_context *m68k = root->cpu_context; | |
1070 genesis_context *gen = m68k->system; | |
1071 if (gen->expansion) { | |
1072 segacd_context *cd = gen->expansion; | |
1073 root = find_m68k_root(cd->m68k); | |
1074 return root->resolve(root, cur + 1, out); | |
1075 } else { | |
1076 return NULL; | |
1077 } | |
1078 }*/ else { | |
1079 return NULL; | |
1080 } | |
1081 } | |
1082 } | |
1083 return NULL; | |
1084 } | |
1085 | |
1086 static debug_array* resolve_null_array(debug_root *root, const char *name) | |
1087 { | |
1088 return NULL; | |
922 } | 1089 } |
923 | 1090 |
924 void ambiguous_iter(char *key, tern_val val, uint8_t valtype, void *data) | 1091 void ambiguous_iter(char *key, tern_val val, uint8_t valtype, void *data) |
925 { | 1092 { |
926 char *prefix = data; | 1093 char *prefix = data; |
1613 static uint8_t cmd_set(debug_root *root, parsed_command *cmd) | 1780 static uint8_t cmd_set(debug_root *root, parsed_command *cmd) |
1614 { | 1781 { |
1615 char *name = NULL; | 1782 char *name = NULL; |
1616 char size = 0; | 1783 char size = 0; |
1617 uint32_t address; | 1784 uint32_t address; |
1785 debug_array *array = NULL; | |
1618 switch (cmd->args[0].parsed->type) | 1786 switch (cmd->args[0].parsed->type) |
1619 { | 1787 { |
1620 case EXPR_SCALAR: | 1788 case EXPR_SCALAR: |
1621 if (cmd->args[0].parsed->op.type == TOKEN_NAME) { | 1789 if (cmd->args[0].parsed->op.type == TOKEN_NAME) { |
1622 name = cmd->args[0].parsed->op.v.str; | 1790 name = cmd->args[0].parsed->op.v.str; |
1638 size = cmd->args[0].parsed->op.v.op[0]; | 1806 size = cmd->args[0].parsed->op.v.op[0]; |
1639 if (!eval_expr(root, cmd->args[0].parsed->left, &address)) { | 1807 if (!eval_expr(root, cmd->args[0].parsed->left, &address)) { |
1640 fprintf(stderr, "Failed to eval %s\n", cmd->args[0].raw); | 1808 fprintf(stderr, "Failed to eval %s\n", cmd->args[0].raw); |
1641 return 1; | 1809 return 1; |
1642 } | 1810 } |
1811 if (cmd->args[0].parsed->right) { | |
1812 array = full_array_resolve(root, cmd->args[0].parsed->right->op.v.str); | |
1813 if (!array) { | |
1814 fprintf(stderr, "Failed to resolve array %s\n", cmd->args[0].parsed->right->op.v.str); | |
1815 return 1; | |
1816 } | |
1817 if (!array->set) { | |
1818 fprintf(stderr, "Array %s is read-only\n", cmd->args[0].parsed->right->op.v.str); | |
1819 return 1; | |
1820 } | |
1821 if (address >= array->size) { | |
1822 fprintf(stderr, "Address %X is out of bounds for array %s\n", address, cmd->args[0].parsed->right->op.v.str); | |
1823 return 1; | |
1824 } | |
1825 } | |
1643 break; | 1826 break; |
1644 default: | 1827 default: |
1645 fprintf(stderr, "First argument to set must be a name or memory expression, got %s\n", expr_type_names[cmd->args[0].parsed->type]); | 1828 fprintf(stderr, "First argument to set must be a name or memory expression, got %s\n", expr_type_names[cmd->args[0].parsed->type]); |
1646 return 1; | 1829 return 1; |
1647 } | 1830 } |
1673 root->variables = tern_insert_int(root->variables, name, value); | 1856 root->variables = tern_insert_int(root->variables, name, value); |
1674 } else { | 1857 } else { |
1675 fprintf(stderr, "Failed to set %s\n", name); | 1858 fprintf(stderr, "Failed to set %s\n", name); |
1676 } | 1859 } |
1677 } | 1860 } |
1861 } else if (array) { | |
1862 array->set(root, array, address, value); | |
1678 } else if (!root->write_mem(root, address, value, size)) { | 1863 } else if (!root->write_mem(root, address, value, size)) { |
1679 fprintf(stderr, "Failed to write to address %X\n", address); | 1864 fprintf(stderr, "Failed to write to address %X\n", address); |
1680 } | 1865 } |
1681 return 1; | 1866 return 1; |
1682 } | 1867 } |
1694 return 1; | 1879 return 1; |
1695 } | 1880 } |
1696 value = cmd->args[1].value; | 1881 value = cmd->args[1].value; |
1697 } | 1882 } |
1698 root->variables = tern_insert_int(root->variables, cmd->args[0].parsed->op.v.str, value); | 1883 root->variables = tern_insert_int(root->variables, cmd->args[0].parsed->op.v.str, value); |
1884 return 1; | |
1885 } | |
1886 | |
1887 static uint32_t user_array_get(debug_root *root, debug_array *array, uint32_t index) | |
1888 { | |
1889 return array->data[index]; | |
1890 } | |
1891 | |
1892 static void user_array_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) | |
1893 { | |
1894 array->data[index] = value; | |
1895 } | |
1896 | |
1897 static void user_array_append(debug_root *root, debug_array *array, uint32_t value) | |
1898 { | |
1899 if (array->size == array->storage) { | |
1900 array->storage *= 2; | |
1901 array->data = realloc(array->data, sizeof(uint32_t) * array->storage); | |
1902 } | |
1903 array->data[array->size++] = value; | |
1904 } | |
1905 | |
1906 static uint8_t cmd_array(debug_root *root, parsed_command *cmd) | |
1907 { | |
1908 if (cmd->args[0].parsed->type != EXPR_SCALAR || cmd->args[0].parsed->op.type != TOKEN_NAME) { | |
1909 fprintf(stderr, "First argument to array must be a name, got %s\n", expr_type_names[cmd->args[0].parsed->type]); | |
1910 return 1; | |
1911 } | |
1912 debug_array *array = tern_find_ptr(root->arrays, cmd->args[0].parsed->op.v.str); | |
1913 if (!array) { | |
1914 array = calloc(1, sizeof(debug_array)); | |
1915 array->get = user_array_get; | |
1916 array->set = user_array_set; | |
1917 array->append = user_array_append; | |
1918 array->storage = cmd->num_args > 1 ? cmd->num_args - 1 : 4; | |
1919 array->data = calloc(array->storage, sizeof(uint32_t)); | |
1920 root->arrays = tern_insert_ptr(root->arrays, cmd->args[0].parsed->op.v.str, array); | |
1921 } | |
1922 array->size = cmd->num_args - 1; | |
1923 for (uint32_t i = 1; i < cmd->num_args; i++) | |
1924 { | |
1925 if (!eval_expr(root, cmd->args[i].parsed, &cmd->args[i].value)) { | |
1926 fprintf(stderr, "Failed to eval %s\n", cmd->args[i].raw); | |
1927 return 1; | |
1928 } | |
1929 array->set(root, array, i - 1, cmd->args[i].value); | |
1930 } | |
1931 return 1; | |
1932 } | |
1933 | |
1934 static uint8_t cmd_append(debug_root *root, parsed_command *cmd) | |
1935 { | |
1936 if (cmd->args[0].parsed->type != EXPR_SCALAR || cmd->args[0].parsed->op.type != TOKEN_NAME) { | |
1937 fprintf(stderr, "First argument to append must be a name, got %s\n", expr_type_names[cmd->args[0].parsed->type]); | |
1938 return 1; | |
1939 } | |
1940 debug_array *array = full_array_resolve(root, cmd->args[0].parsed->op.v.str); | |
1941 if (!array) { | |
1942 fprintf(stderr, "Failed to resolve array %s\n", cmd->args[0].parsed->op.v.str); | |
1943 return 1; | |
1944 } | |
1945 if (!array->append) { | |
1946 fprintf(stderr, "Array %s doesn't support appending\n", cmd->args[0].parsed->op.v.str); | |
1947 return 1; | |
1948 } | |
1949 if (!eval_expr(root, cmd->args[1].parsed, &cmd->args[1].value)) { | |
1950 fprintf(stderr, "Failed to eval %s\n", cmd->args[1].raw); | |
1951 return 1; | |
1952 } | |
1953 array->append(root, array, cmd->args[1].value); | |
1699 return 1; | 1954 return 1; |
1700 } | 1955 } |
1701 | 1956 |
1702 static uint8_t cmd_frames(debug_root *root, parsed_command *cmd) | 1957 static uint8_t cmd_frames(debug_root *root, parsed_command *cmd) |
1703 { | 1958 { |
2230 .max_args = 2, | 2485 .max_args = 2, |
2231 .skip_eval = 1 | 2486 .skip_eval = 1 |
2232 }, | 2487 }, |
2233 { | 2488 { |
2234 .names = (const char *[]){ | 2489 .names = (const char *[]){ |
2490 "array", NULL | |
2491 }, | |
2492 .usage = "array NAME [VALUE...]", | |
2493 .desc = "Create a new array called NAME if it doesn't already exist. The array is initialized with the remaining parameters", | |
2494 .impl = cmd_array, | |
2495 .min_args = 1, | |
2496 .max_args = -1, | |
2497 .skip_eval = 1 | |
2498 }, | |
2499 { | |
2500 .names = (const char *[]){ | |
2501 "append", NULL | |
2502 }, | |
2503 .usage = "append NAME VALUE", | |
2504 .desc = "Increase the size of array NAME by 1 and set the last element to VALUE", | |
2505 .impl = cmd_append, | |
2506 .min_args = 2, | |
2507 .max_args = 2, | |
2508 .skip_eval = 1 | |
2509 }, | |
2510 { | |
2511 .names = (const char *[]){ | |
2235 "frames", NULL | 2512 "frames", NULL |
2236 }, | 2513 }, |
2237 .usage = "frames EXPRESSION", | 2514 .usage = "frames EXPRESSION", |
2238 .desc = "Resume execution for EXPRESSION video frames", | 2515 .desc = "Resume execution for EXPRESSION video frames", |
2239 .impl = cmd_frames, | 2516 .impl = cmd_frames, |
2865 case SYSTEM_GENESIS: | 3142 case SYSTEM_GENESIS: |
2866 case SYSTEM_SEGACD: | 3143 case SYSTEM_SEGACD: |
2867 //check if this is the main CPU | 3144 //check if this is the main CPU |
2868 if (context->system == current_system) { | 3145 if (context->system == current_system) { |
2869 root->resolve = resolve_genesis; | 3146 root->resolve = resolve_genesis; |
3147 root->array_resolve = resolve_genesis_array; | |
2870 add_commands(root, genesis_commands, NUM_GENESIS); | 3148 add_commands(root, genesis_commands, NUM_GENESIS); |
2871 if (current_system->type == SYSTEM_SEGACD) { | 3149 if (current_system->type == SYSTEM_SEGACD) { |
2872 add_segacd_maincpu_labels(root->disasm); | 3150 add_segacd_maincpu_labels(root->disasm); |
2873 add_commands(root, scd_main_commands, NUM_SCD_MAIN); | 3151 add_commands(root, scd_main_commands, NUM_SCD_MAIN); |
2874 } | 3152 } |
2877 add_segacd_subcpu_labels(root->disasm); | 3155 add_segacd_subcpu_labels(root->disasm); |
2878 add_commands(root, scd_sub_commands, NUM_SCD_SUB); | 3156 add_commands(root, scd_sub_commands, NUM_SCD_SUB); |
2879 } | 3157 } |
2880 default: | 3158 default: |
2881 root->resolve = resolve_m68k; | 3159 root->resolve = resolve_m68k; |
3160 root->array_resolve = resolve_null_array; | |
2882 } | 3161 } |
2883 tern_foreach(root->disasm->labels, symbol_map, root); | 3162 tern_foreach(root->disasm->labels, symbol_map, root); |
2884 } | 3163 } |
2885 return root; | 3164 return root; |
2886 } | 3165 } |
3395 add_commands(root, sms_commands, NUM_SMS); | 3674 add_commands(root, sms_commands, NUM_SMS); |
3396 break; | 3675 break; |
3397 default: | 3676 default: |
3398 root->resolve = resolve_z80; | 3677 root->resolve = resolve_z80; |
3399 } | 3678 } |
3679 root->array_resolve = resolve_null_array; | |
3400 root->read_mem = read_z80; | 3680 root->read_mem = read_z80; |
3401 root->write_mem = write_z80; | 3681 root->write_mem = write_z80; |
3402 root->set = set_z80; | 3682 root->set = set_z80; |
3403 root->disasm = create_z80_disasm(); | 3683 root->disasm = create_z80_disasm(); |
3404 } | 3684 } |