comparison debug.c @ 2362:b6c5a0fa3dfc

Refactor debugger a bit. Allow types other than integers to be passed in expressions and stored in arrays. Better namespace support
author Michael Pavone <pavone@retrodev.com>
date Mon, 06 Nov 2023 22:41:33 -0800
parents 3350b3c8faa8
children b865f33fd47e
comparison
equal deleted inserted replaced
2361:3350b3c8faa8 2362:b6c5a0fa3dfc
22 #define Z80_OPTS opts 22 #define Z80_OPTS opts
23 #else 23 #else
24 #define Z80_OPTS options 24 #define Z80_OPTS options
25 #endif 25 #endif
26 26
27 static debug_root roots[5]; 27 static debug_root *roots;
28 static uint32_t num_roots; 28 static uint32_t num_roots, root_storage;
29 #define MAX_DEBUG_ROOTS (sizeof(roots)/sizeof(*roots))
30 29
31 debug_root *find_root(void *cpu) 30 debug_root *find_root(void *cpu)
32 { 31 {
33 for (uint32_t i = 0; i < num_roots; i++) 32 for (uint32_t i = 0; i < num_roots; i++)
34 { 33 {
35 if (roots[i].cpu_context == cpu) { 34 if (roots[i].cpu_context == cpu) {
36 return roots + i; 35 return roots + i;
37 } 36 }
38 } 37 }
39 if (num_roots < MAX_DEBUG_ROOTS) { 38 if (num_roots == root_storage) {
40 num_roots++; 39 root_storage = root_storage ? root_storage * 2 : 5;
41 memset(roots + num_roots - 1, 0, sizeof(debug_root)); 40 roots = realloc(roots, root_storage * sizeof(debug_root));
42 roots[num_roots-1].cpu_context = cpu; 41 }
43 return roots + num_roots - 1; 42 num_roots++;
44 } 43 memset(roots + num_roots - 1, 0, sizeof(debug_root));
45 return NULL; 44 roots[num_roots-1].cpu_context = cpu;
45 return roots + num_roots - 1;
46 } 46 }
47 47
48 bp_def ** find_breakpoint(bp_def ** cur, uint32_t address, uint8_t type) 48 bp_def ** find_breakpoint(bp_def ** cur, uint32_t address, uint8_t type)
49 { 49 {
50 while (*cur) { 50 while (*cur) {
63 break; 63 break;
64 } 64 }
65 cur = &((*cur)->next); 65 cur = &((*cur)->next);
66 } 66 }
67 return cur; 67 return cur;
68 }
69
70 static debug_array *arrays;
71 static uint32_t num_arrays, array_storage;
72 static debug_array *alloc_array(void)
73 {
74 if (num_arrays == array_storage) {
75 array_storage = array_storage ? array_storage * 2 : 4;
76 arrays = realloc(arrays, sizeof(debug_array) * array_storage);
77 }
78 return arrays + num_arrays++;
79 }
80
81 static debug_val new_fixed_array(void *base, debug_array_get get, debug_array_set set, uint32_t size)
82 {
83 debug_array *array = alloc_array();
84 array->get = get;
85 array->set = set;
86 array->append = NULL;
87 array->base = base;
88 array->size = array->storage = size;
89 debug_val ret;
90 ret.type = DBG_VAL_ARRAY;
91 ret.v.u32 = array - arrays;
92 return ret;
93 }
94
95 static debug_val user_array_get(debug_array *array, uint32_t index)
96 {
97 debug_val *data = array->base;
98 return data[index];
99 }
100
101 static void user_array_set(debug_array *array, uint32_t index, debug_val value)
102 {
103 debug_val *data = array->base;
104 data[index] = value;
105 }
106
107 static void user_array_append(debug_array *array, debug_val value)
108 {
109 if (array->size == array->storage) {
110 array->storage *= 2;
111 array->base = realloc(array->base, sizeof(debug_val) * array->storage);
112 }
113 debug_val *data = array->base;
114 data[array->size++] = value;
115 }
116
117 static debug_val new_user_array(uint32_t size)
118 {
119 debug_array *array = alloc_array();
120 array->get = user_array_get;
121 array->set = user_array_set;
122 array->append = user_array_append;
123 array->size = size;
124 array->storage = size ? size : 4;
125 debug_val ret;
126 ret.type = DBG_VAL_ARRAY;
127 ret.v.u32 = array - arrays;
128 return ret;
129 }
130
131 debug_array *get_array(debug_val val)
132 {
133 if (val.type != DBG_VAL_ARRAY) {
134 return NULL;
135 }
136 return arrays + val.v.u32;
137 }
138
139 debug_val user_var_get(debug_var *var)
140 {
141 return var->val;
142 }
143
144 void user_var_set(debug_var *var, debug_val val)
145 {
146 var->val = val;
147 }
148
149 static void new_user_variable(debug_root *root, const char *name, debug_val val)
150 {
151 debug_var *var = calloc(1, sizeof(debug_var));
152 var->get = user_var_get;
153 var->set = user_var_set;
154 var->val = val;
155 root->variables = tern_insert_ptr(root->variables, name, var);
156 }
157
158 static void new_readonly_variable(debug_root *root, const char *name, debug_val val)
159 {
160 debug_var *var = calloc(1, sizeof(debug_var));
161 var->get = user_var_get;
162 var->set = NULL;
163 var->val = val;
164 root->variables = tern_insert_ptr(root->variables, name, var);
165 }
166
167 static debug_val debug_int(uint32_t i)
168 {
169 debug_val ret;
170 ret.type = DBG_VAL_U32;
171 ret.v.u32 = i;
172 return ret;
68 } 173 }
69 174
70 static const char *token_type_names[] = { 175 static const char *token_type_names[] = {
71 "TOKEN_NONE", 176 "TOKEN_NONE",
72 "TOKEN_NUM", 177 "TOKEN_NUM",
225 } 330 }
226 331
227 static expr *parse_scalar_or_muldiv(char *start, char **end); 332 static expr *parse_scalar_or_muldiv(char *start, char **end);
228 static expr *parse_expression(char *start, char **end); 333 static expr *parse_expression(char *start, char **end);
229 334
335 static void handle_namespace(expr *e)
336 {
337 if (e->op.type != TOKEN_NAME && e->op.type != TOKEN_ARRAY) {
338 return;
339 }
340 char *start = e->op.v.str;
341 char *orig_start = start;
342 for (char *cur = start; *cur; ++cur)
343 {
344 if (*cur == ':') {
345 char *ns = malloc(cur - start + 1);
346 memcpy(ns, start, cur - start);
347 ns[cur - start] = 0;
348 expr *inner = calloc(1, sizeof(expr));
349 inner->type = EXPR_SCALAR;
350 inner->op.type = TOKEN_NAME;
351 start = cur + 1;
352 inner->op.v.str = start;
353 e->left = inner;
354 e->type = EXPR_NAMESPACE;
355 e->op.v.str = ns;
356 e = inner;
357 }
358 }
359 if (start != orig_start) {
360 //We've split the original string up into
361 //a bunch of individually allocated fragments
362 //this is just a little stup of the original
363 e->op.v.str = strdup(e->op.v.str);
364 free(orig_start);
365 }
366 }
367
230 static expr *parse_scalar(char *start, char **end) 368 static expr *parse_scalar(char *start, char **end)
231 { 369 {
232 char *after_first; 370 char *after_first;
233 token first = parse_token(start, &after_first); 371 token first = parse_token(start, &after_first);
234 if (!first.type) { 372 if (!first.type) {
259 //consume the bracket token 397 //consume the bracket token
260 parse_token(after_first, &after_first); 398 parse_token(after_first, &after_first);
261 ret->right = calloc(1, sizeof(expr)); 399 ret->right = calloc(1, sizeof(expr));
262 ret->right->type = EXPR_SCALAR; 400 ret->right->type = EXPR_SCALAR;
263 ret->right->op = first; 401 ret->right->op = first;
402 handle_namespace(ret->right);
264 } 403 }
265 404
266 ret->left = parse_expression(after_first, end); 405 ret->left = parse_expression(after_first, end);
267 if (!ret->left) { 406 if (!ret->left) {
268 fprintf(stderr, "Expression expected after `[`\n"); 407 fprintf(stderr, "Expression expected after `[`\n");
304 token second = parse_token(after_first, end); 443 token second = parse_token(after_first, end);
305 if (second.type != TOKEN_SIZE) { 444 if (second.type != TOKEN_SIZE) {
306 expr *ret = calloc(1, sizeof(expr)); 445 expr *ret = calloc(1, sizeof(expr));
307 ret->type = EXPR_SCALAR; 446 ret->type = EXPR_SCALAR;
308 ret->op = first; 447 ret->op = first;
448 handle_namespace(ret);
309 *end = after_first; 449 *end = after_first;
310 return ret; 450 return ret;
311 } 451 }
312 expr *ret = calloc(1, sizeof(expr)); 452 expr *ret = calloc(1, sizeof(expr));
313 ret->type = EXPR_SIZE; 453 ret->type = EXPR_SIZE;
314 ret->left = calloc(1, sizeof(expr)); 454 ret->left = calloc(1, sizeof(expr));
315 ret->left->type = EXPR_SCALAR; 455 ret->left->type = EXPR_SCALAR;
316 ret->left->op = second; 456 ret->left->op = second;
457 handle_namespace(ret->left);
317 ret->op = first; 458 ret->op = first;
318 return ret; 459 return ret;
319 } 460 }
320 461
321 static expr *maybe_binary(expr *left, char *start, char **end) 462 static expr *maybe_binary(expr *left, char *start, char **end)
415 //consume the bracket token 556 //consume the bracket token
416 parse_token(after_first, &after_first); 557 parse_token(after_first, &after_first);
417 ret->right = calloc(1, sizeof(expr)); 558 ret->right = calloc(1, sizeof(expr));
418 ret->right->type = EXPR_SCALAR; 559 ret->right->type = EXPR_SCALAR;
419 ret->right->op = first; 560 ret->right->op = first;
561 handle_namespace(ret->right);
420 } 562 }
421 563
422 ret->left = parse_expression(after_first, end); 564 ret->left = parse_expression(after_first, end);
423 if (!ret->left) { 565 if (!ret->left) {
424 fprintf(stderr, "Expression expected after `[`\n"); 566 fprintf(stderr, "Expression expected after `[`\n");
464 expr *bin = calloc(1, sizeof(expr)); 606 expr *bin = calloc(1, sizeof(expr));
465 bin->type = EXPR_BINARY; 607 bin->type = EXPR_BINARY;
466 bin->left = calloc(1, sizeof(expr)); 608 bin->left = calloc(1, sizeof(expr));
467 bin->left->type = EXPR_SCALAR; 609 bin->left->type = EXPR_SCALAR;
468 bin->left->op = first; 610 bin->left->op = first;
611 handle_namespace(bin->left);
469 bin->op = second; 612 bin->op = second;
470 switch (second.v.op[0]) 613 switch (second.v.op[0])
471 { 614 {
472 case '*': 615 case '*':
473 case '/': 616 case '/':
497 value->type = EXPR_SIZE; 640 value->type = EXPR_SIZE;
498 value->op = second; 641 value->op = second;
499 value->left = calloc(1, sizeof(expr)); 642 value->left = calloc(1, sizeof(expr));
500 value->left->type = EXPR_SCALAR; 643 value->left->type = EXPR_SCALAR;
501 value->left->op = first; 644 value->left->op = first;
645 handle_namespace(value->left);
502 return maybe_muldiv(value, after_second, end); 646 return maybe_muldiv(value, after_second, end);
503 } else { 647 } else {
504 expr *ret = calloc(1, sizeof(expr)); 648 expr *ret = calloc(1, sizeof(expr));
505 ret->type = EXPR_SCALAR; 649 ret->type = EXPR_SCALAR;
506 ret->op = first; 650 ret->op = first;
651 handle_namespace(ret);
507 *end = after_first; 652 *end = after_first;
508 return ret; 653 return ret;
509 } 654 }
510 } 655 }
511 656
540 //consume the bracket token 685 //consume the bracket token
541 parse_token(after_first, &after_first); 686 parse_token(after_first, &after_first);
542 ret->right = calloc(1, sizeof(expr)); 687 ret->right = calloc(1, sizeof(expr));
543 ret->right->type = EXPR_SCALAR; 688 ret->right->type = EXPR_SCALAR;
544 ret->right->op = first; 689 ret->right->op = first;
690 handle_namespace(ret->right);
545 } 691 }
546 692
547 ret->left = parse_expression(after_first, end); 693 ret->left = parse_expression(after_first, end);
548 if (!ret->left) { 694 if (!ret->left) {
549 fprintf(stderr, "Expression expected after `[`\n"); 695 fprintf(stderr, "Expression expected after `[`\n");
588 expr *bin = calloc(1, sizeof(expr)); 734 expr *bin = calloc(1, sizeof(expr));
589 bin->type = EXPR_BINARY; 735 bin->type = EXPR_BINARY;
590 bin->left = calloc(1, sizeof(expr)); 736 bin->left = calloc(1, sizeof(expr));
591 bin->left->type = EXPR_SCALAR; 737 bin->left->type = EXPR_SCALAR;
592 bin->left->op = first; 738 bin->left->op = first;
739 handle_namespace(bin->left);
593 bin->op = second; 740 bin->op = second;
594 switch (second.v.op[0]) 741 switch (second.v.op[0])
595 { 742 {
596 case '*': 743 case '*':
597 case '/': 744 case '/':
636 value->type = EXPR_SIZE; 783 value->type = EXPR_SIZE;
637 value->op = second; 784 value->op = second;
638 value->left = calloc(1, sizeof(expr)); 785 value->left = calloc(1, sizeof(expr));
639 value->left->type = EXPR_SCALAR; 786 value->left->type = EXPR_SCALAR;
640 value->left->op = first; 787 value->left->op = first;
788 handle_namespace(value->left);
641 return maybe_binary(value, after_second, end); 789 return maybe_binary(value, after_second, end);
642 } else { 790 } else {
643 if (second.type == TOKEN_NAME) { 791 if (second.type == TOKEN_NAME) {
644 free(second.v.str); 792 free(second.v.str);
645 } 793 }
646 expr *ret = calloc(1, sizeof(expr)); 794 expr *ret = calloc(1, sizeof(expr));
647 ret->type = EXPR_SCALAR; 795 ret->type = EXPR_SCALAR;
648 ret->op = first; 796 ret->op = first;
797 handle_namespace(ret);
649 *end = after_first; 798 *end = after_first;
650 return ret; 799 return ret;
651 } 800 }
652 } 801 }
653 802
654 static debug_array* full_array_resolve(debug_root *root, const char *name) 803 uint8_t eval_expr(debug_root *root, expr *e, debug_val *out)
655 { 804 {
656 debug_array *ret = root->array_resolve(root, name); 805 debug_val right;
657 if (!ret) {
658 ret = tern_find_ptr(root->arrays, name);
659 }
660 return ret;
661 }
662
663 uint8_t eval_expr(debug_root *root, expr *e, uint32_t *out)
664 {
665 uint32_t right;
666 switch(e->type) 806 switch(e->type)
667 { 807 {
668 case EXPR_SCALAR: 808 case EXPR_SCALAR:
669 if (e->op.type == TOKEN_NAME) { 809 if (e->op.type == TOKEN_NAME || e->op.type == TOKEN_ARRAY) {
670 if (root->resolve(root, e->op.v.str, out)) { 810 debug_var *var = tern_find_ptr(root->variables, e->op.v.str);
671 return 1; 811 if (!var) {
672 } 812 return 0;
673 tern_val v; 813 }
674 if (tern_find(root->variables, e->op.v.str, &v)) { 814 *out = var->get(var);
675 *out = v.intval; 815 return 1;
676 return 1;
677 }
678 if (tern_find(root->symbols, e->op.v.str, &v)) {
679 *out = v.intval;
680 return 1;
681 }
682 return 0;
683 } else { 816 } else {
684 *out = e->op.v.num; 817 *out = debug_int(e->op.v.num);
685 return 1; 818 return 1;
686 } 819 }
687 case EXPR_UNARY: 820 case EXPR_UNARY:
688 if (!eval_expr(root, e->left, out)) { 821 if (!eval_expr(root, e->left, out)) {
689 return 0; 822 return 0;
690 } 823 }
691 switch (e->op.v.op[0]) 824 switch (e->op.v.op[0])
692 { 825 {
693 case '!': 826 case '!':
694 *out = !*out; 827 if (out->type != DBG_VAL_U32) { fprintf(stderr, "operator ! is only defined for integers"); return 0; }
828 out->v.u32 = !out->v.u32;
695 break; 829 break;
696 case '~': 830 case '~':
697 *out = ~*out; 831 if (out->type != DBG_VAL_U32) { fprintf(stderr, "operator ~ is only defined for integers"); return 0; }
832 out->v.u32 = ~out->v.u32;
698 break; 833 break;
699 case '-': 834 case '-':
700 *out = -*out; 835 if (out->type == DBG_VAL_U32) {
836 out->v.u32 = -out->v.u32;
837 } else if (out->type == DBG_VAL_F32) {
838 out->v.f32 = -out->v.f32;
839 } else {
840 fprintf(stderr, "operator ~ is only defined for integers and floats");
841 return 0;
842 }
701 break; 843 break;
702 default: 844 default:
703 return 0; 845 return 0;
704 } 846 }
705 return 1; 847 return 1;
706 case EXPR_BINARY: 848 case EXPR_BINARY:
707 if (!eval_expr(root, e->left, out) || !eval_expr(root, e->right, &right)) { 849 if (!eval_expr(root, e->left, out) || !eval_expr(root, e->right, &right)) {
708 return 0; 850 return 0;
709 } 851 }
710 switch (e->op.v.op[0]) 852 if (out->type != right.type) {
711 { 853 if (out->type == DBG_VAL_F32) {
712 case '+': 854 if (right.type == DBG_VAL_U32) {
713 *out += right; 855 right.type = DBG_VAL_F32;
714 break; 856 float v = right.v.u32;
715 case '-': 857 right.v.f32 = v;
716 *out -= right; 858 } else {
717 break; 859 fprintf(stderr, "Invalid type on right side of binary operator\n");
718 case '*': 860 return 0;
719 *out *= right; 861 }
720 break; 862 } else if (out->type == DBG_VAL_U32) {
721 case '/': 863 if (right.type == DBG_VAL_F32) {
722 *out /= right; 864 out->type = DBG_VAL_F32;
723 break; 865 float v = out->v.u32;
724 case '&': 866 out->v.f32 = v;
725 *out &= right; 867 } else {
726 break; 868 fprintf(stderr, "Invalid type on right side of binary operator\n");
727 case '|': 869 return 0;
728 *out |= right; 870 }
729 break; 871 }
730 case '^': 872 }
731 *out ^= right; 873 if (out->type == DBG_VAL_U32) {
732 break; 874 switch (e->op.v.op[0])
733 case '=': 875 {
734 *out = *out == right; 876 case '+':
735 break; 877 out->v.u32 += right.v.u32;
736 case '!': 878 break;
737 *out = *out != right; 879 case '-':
738 break; 880 out->v.u32 -= right.v.u32;
739 case '>': 881 break;
740 *out = e->op.v.op[1] ? *out >= right : *out > right; 882 case '*':
741 break; 883 out->v.u32 *= right.v.u32;
742 case '<': 884 break;
743 *out = e->op.v.op[1] ? *out <= right : *out < right; 885 case '/':
744 break; 886 out->v.u32 /= right.v.u32;
745 default: 887 break;
746 return 0; 888 case '&':
889 out->v.u32 &= right.v.u32;
890 break;
891 case '|':
892 out->v.u32 |= right.v.u32;
893 break;
894 case '^':
895 out->v.u32 ^= right.v.u32;
896 break;
897 case '=':
898 out->v.u32 = out->v.u32 == right.v.u32;
899 break;
900 case '!':
901 out->v.u32 = out->v.u32 != right.v.u32;
902 break;
903 case '>':
904 out->v.u32 = e->op.v.op[1] ? out->v.u32 >= right.v.u32 : out->v.u32 > right.v.u32;
905 break;
906 case '<':
907 out->v.u32 = e->op.v.op[1] ? out->v.u32 <= right.v.u32 : out->v.u32 < right.v.u32;
908 break;
909 default:
910 return 0;
911 }
912 } else if (out->type == DBG_VAL_F32) {
913 switch (e->op.v.op[0])
914 {
915 case '+':
916 out->v.f32 += right.v.f32;
917 break;
918 case '-':
919 out->v.f32 -= right.v.f32;
920 break;
921 case '*':
922 out->v.f32 *= right.v.f32;
923 break;
924 case '/':
925 out->v.f32 /= right.v.f32;
926 break;
927 case '=':
928 out->v.u32 = out->v.f32 == right.v.f32;
929 out->type = DBG_VAL_U32;
930 break;
931 case '!':
932 out->v.u32 = out->v.f32 != right.v.f32;
933 out->type = DBG_VAL_U32;
934 break;
935 case '>':
936 out->v.u32 = e->op.v.op[1] ? out->v.f32 >= right.v.f32 : out->v.f32 > right.v.f32;
937 out->type = DBG_VAL_U32;
938 break;
939 case '<':
940 out->v.u32 = e->op.v.op[1] ? out->v.f32 <= right.v.f32 : out->v.f32 < right.v.f32;
941 out->type = DBG_VAL_U32;
942 break;
943 default:
944 return 0;
945 }
747 } 946 }
748 return 1; 947 return 1;
749 case EXPR_SIZE: 948 case EXPR_SIZE:
750 if (!eval_expr(root, e->left, out)) { 949 if (!eval_expr(root, e->left, out)) {
751 return 0; 950 return 0;
752 } 951 }
952 if (out->type != DBG_VAL_U32) { fprintf(stderr, "Size expressions are only defined for integers"); return 0; }
753 switch (e->op.v.op[0]) 953 switch (e->op.v.op[0])
754 { 954 {
755 case 'b': 955 case 'b':
756 *out &= 0xFF; 956 out->v.u32 &= 0xFF;
757 break; 957 break;
758 case 'w': 958 case 'w':
759 *out &= 0xFFFF; 959 out->v.u32 &= 0xFFFF;
760 break; 960 break;
761 } 961 }
762 return 1; 962 return 1;
763 case EXPR_MEM: 963 case EXPR_MEM:
764 if (!eval_expr(root, e->left, out)) { 964 if (!eval_expr(root, e->left, out)) {
765 return 0; 965 return 0;
766 } 966 }
967 if (out->type != DBG_VAL_U32) { fprintf(stderr, "Array index must be integer"); return 0; }
767 if (e->right) { 968 if (e->right) {
768 debug_array *array = full_array_resolve(root, e->right->op.v.str); 969 if (!eval_expr(root, e->right, &right)) {
769 if (!array || *out >= array->size) {
770 return 0; 970 return 0;
771 } 971 }
772 *out = array->get(root, array, *out); 972 debug_array *array = get_array(right);
973 if (!array) {
974 fprintf(stderr, "Attempt to index into value that is not an array");
975 return 0;
976 }
977 if (out->v.u32 >= array->size) {
978 return 0;
979 }
980 *out = array->get(array, out->v.u32);
773 return 1; 981 return 1;
774 } 982 }
775 return root->read_mem(root, out, e->op.v.op[0]); 983 return root->read_mem(root, &out->v.u32, e->op.v.op[0]);
984 case EXPR_NAMESPACE:
985 root = tern_find_ptr(root->other_roots, e->op.v.str);
986 if (!root) {
987 fprintf(stderr, "%s is not a valid namespace\n", e->op.v.str);
988 return 0;
989 }
990 return eval_expr(root, e->left, out);
776 default: 991 default:
777 return 0; 992 return 0;
778 } 993 }
779 } 994 }
780 995
857 write_word(address, value, (void **)context->mem_pointers, &context->options->gen, context); 1072 write_word(address, value, (void **)context->mem_pointers, &context->options->gen, context);
858 } 1073 }
859 return 1; 1074 return 1;
860 } 1075 }
861 1076
862 static uint8_t resolve_m68k(debug_root *root, const char *name, uint32_t *out) 1077 static uint8_t debug_cast_int(debug_val val, uint32_t *out)
863 { 1078 {
864 m68k_context *context = root->cpu_context; 1079 if (val.type == DBG_VAL_U32) {
865 if ((name[0] == 'd' || name[0] == 'D') && name[1] >= '0' && name[1] <= '7' && !name[2]) { 1080 *out = val.v.u32;
866 *out = context->dregs[name[1]-'0'];
867 } else if ((name[0] == 'a' || name[0] == 'A') && name[1] >= '0' && name[1] <= '7' && !name[2]) {
868 *out = context->aregs[name[1]-'0'];
869 } else if (!strcasecmp(name, "sr")) {
870 *out = context->status << 8;
871 for (int flag = 0; flag < 5; flag++) {
872 *out |= context->flags[flag] << (4-flag);
873 }
874 } else if(!strcasecmp(name, "cycle")) {
875 *out = context->current_cycle;
876 } else if (!strcasecmp(name, "pc")) {
877 *out = root->address;
878 } else if (!strcasecmp(name, "sp")) {
879 *out = context->aregs[7];
880 } else if (!strcasecmp(name, "usp")) {
881 *out = context->status & 0x20 ? context->aregs[8] : context->aregs[7];
882 } else if (!strcasecmp(name, "ssp")) {
883 *out = context->status & 0x20 ? context->aregs[7] : context->aregs[8];
884 } else {
885 return 0;
886 }
887 return 1;
888 }
889
890 static uint8_t set_m68k(debug_root *root, const char *name, uint32_t value)
891 {
892 m68k_context *context = root->cpu_context;
893 if ((name[0] == 'd' || name[0] == 'D') && name[1] >= '0' && name[1] <= '7' && !name[2]) {
894 context->dregs[name[1]-'0'] = value;
895 } else if ((name[0] == 'a' || name[0] == 'A') && name[1] >= '0' && name[1] <= '7' && !name[2]) {
896 context->aregs[name[1]-'0'] = value;
897 } else if (!strcasecmp(name, "sr")) {
898 context->status = value >> 8;
899 for (int flag = 0; flag < 5; flag++) {
900 context->flags[flag] = (value & (1 << (4 - flag))) != 0;
901 }
902 } else if (!strcasecmp(name, "sp")) {
903 context->aregs[7] = value;
904 } else if (!strcasecmp(name, "usp")) {
905 context->aregs[context->status & 0x20 ? 8 : 7] = value;
906 } else if (!strcasecmp(name, "ssp")) {
907 context->aregs[context->status & 0x20 ? 7 : 8] = value;
908 } else {
909 return 0;
910 }
911 return 1;
912 }
913
914 static uint8_t resolve_vdp(debug_root *root, const char *name, uint32_t *out)
915 {
916 m68k_context *m68k = root->cpu_context;
917 genesis_context *gen = m68k->system;
918 vdp_context *vdp = gen->vdp;
919 if (!strcasecmp(name, "vcounter")) {
920 *out = vdp->vcounter;
921 } else if (!strcasecmp(name, "hcounter")) {
922 *out = vdp->hslot;
923 } else if (!strcasecmp(name, "address")) {
924 *out = vdp->address;
925 }else if (!strcasecmp(name, "cd")) {
926 *out = vdp->cd;
927 } else if (!strcasecmp(name, "status")) {
928 *out = vdp_status(vdp);
929 } else {
930 return 0;
931 }
932 return 1;
933 }
934
935 static uint8_t resolve_genesis(debug_root *root, const char *name, uint32_t *out)
936 {
937
938 for (const char *cur = name; *cur; ++cur)
939 {
940 if (*cur == ':') {
941 if (cur - name == 3 && !memcmp(name, "vdp", 3)) {
942 return resolve_vdp(root, cur + 1, out);
943 } else if (cur - name == 3 && !memcmp(name, "sub", 3)) {
944 m68k_context *m68k = root->cpu_context;
945 genesis_context *gen = m68k->system;
946 if (gen->expansion) {
947 segacd_context *cd = gen->expansion;
948 root = find_m68k_root(cd->m68k);
949 return root->resolve(root, cur + 1, out);
950 } else {
951 return 0;
952 }
953 } else {
954 return 0;
955 }
956 }
957 }
958 if (resolve_m68k(root, name, out)) {
959 return 1; 1081 return 1;
960 } 1082 }
961 m68k_context *m68k = root->cpu_context; 1083 if (val.type == DBG_VAL_F32) {
962 genesis_context *gen = m68k->system; 1084 *out = val.v.f32;
963 if (!strcmp(name, "f") || !strcmp(name, "frame")) {
964 *out = gen->vdp->frame;
965 return 1; 1085 return 1;
966 } 1086 }
967 return 0; 1087 return 0;
968 } 1088 }
969 1089
970 static uint32_t debug_vram_get(debug_root *root, debug_array *array, uint32_t index) 1090 static uint8_t debug_cast_bool(debug_val val)
971 { 1091 {
972 m68k_context *m68k = root->cpu_context; 1092 switch(val.type)
973 genesis_context *gen = m68k->system; 1093 {
974 return gen->vdp->vdpmem[index]; 1094 case DBG_VAL_U32: return val.v.u32 != 0;
975 } 1095 case DBG_VAL_F32: return val.v.f32 != 0.0f;
976 1096 case DBG_VAL_ARRAY: return get_array(val)->size != 0;
977 static void debug_vram_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1097 default: return 1;
978 { 1098 }
979 m68k_context *m68k = root->cpu_context; 1099 }
980 genesis_context *gen = m68k->system; 1100
981 gen->vdp->vdpmem[index] = value; 1101 static debug_val m68k_dreg_get(debug_var *var)
982 } 1102 {
983 1103 m68k_context *context = var->ptr;
984 static uint32_t debug_vsram_get(debug_root *root, debug_array *array, uint32_t index) 1104 return debug_int(context->dregs[var->val.v.u32]);
985 { 1105 }
986 m68k_context *m68k = root->cpu_context; 1106
987 genesis_context *gen = m68k->system; 1107 static void m68k_dreg_set(debug_var *var, debug_val val)
988 return gen->vdp->vsram[index] & VSRAM_BITS; 1108 {
989 } 1109 m68k_context *context = var->ptr;
990 1110 uint32_t ival;
991 static void debug_vsram_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1111 if (!debug_cast_int(val, &ival)) {
992 { 1112 fprintf(stderr, "M68K register d%d can only be set to an integer\n", var->val.v.u32);
993 m68k_context *m68k = root->cpu_context; 1113 return;
994 genesis_context *gen = m68k->system; 1114 }
995 gen->vdp->vsram[index] = value; 1115 context->dregs[var->val.v.u32] = ival;
996 } 1116 }
997 1117
998 static uint32_t debug_cram_get(debug_root *root, debug_array *array, uint32_t index) 1118 static debug_val m68k_areg_get(debug_var *var)
999 { 1119 {
1000 m68k_context *m68k = root->cpu_context; 1120 m68k_context *context = var->ptr;
1001 genesis_context *gen = m68k->system; 1121 return debug_int(context->aregs[var->val.v.u32]);
1002 return gen->vdp->cram[index] & CRAM_BITS; 1122 }
1003 } 1123
1004 1124 static void m68k_areg_set(debug_var *var, debug_val val)
1005 static void debug_cram_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1125 {
1006 { 1126 m68k_context *context = var->ptr;
1007 m68k_context *m68k = root->cpu_context; 1127 uint32_t ival;
1008 genesis_context *gen = m68k->system; 1128 if (!debug_cast_int(val, &ival)) {
1009 gen->vdp->cram[index] = value; 1129 fprintf(stderr, "M68K register a%d can only be set to an integer\n", var->val.v.u32);
1010 } 1130 return;
1011 1131 }
1012 static uint32_t debug_vreg_get(debug_root *root, debug_array *array, uint32_t index) 1132 context->aregs[var->val.v.u32] = ival;
1013 { 1133 }
1014 m68k_context *m68k = root->cpu_context; 1134
1015 genesis_context *gen = m68k->system; 1135 static debug_val m68k_sr_get(debug_var *var)
1016 return gen->vdp->regs[index]; 1136 {
1017 } 1137 m68k_context *context = var->ptr;
1018 1138 debug_val ret;
1019 static void debug_vreg_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1139 ret.v.u32 = context->status << 8;
1020 { 1140 for (int flag = 0; flag < 5; flag++)
1021 m68k_context *m68k = root->cpu_context; 1141 {
1022 genesis_context *gen = m68k->system; 1142 ret.v.u32 |= context->flags[flag] << (4-flag);
1023 vdp_reg_write(gen->vdp, index, value); 1143 }
1024 } 1144 ret.type = DBG_VAL_U32;
1025 1145 return ret;
1026 static debug_array* resolve_vdp_array(debug_root *root, const char *name) 1146 }
1027 { 1147
1028 static debug_array vram = { 1148 static void m68k_sr_set(debug_var *var, debug_val val)
1029 .get = debug_vram_get, .set = debug_vram_set, 1149 {
1030 .size = VRAM_SIZE, .storage = VRAM_SIZE 1150 m68k_context *context = var->ptr;
1031 }; 1151 uint32_t ival;
1032 static debug_array vsram = { 1152 if (!debug_cast_int(val, &ival)) {
1033 .get = debug_vsram_get, .set = debug_vsram_set, 1153 fprintf(stderr, "M68K register sr can only be set to an integer\n");
1034 }; 1154 return;
1035 static debug_array cram = { 1155 }
1036 .get = debug_cram_get, .set = debug_cram_set, 1156 context->status = ival >> 8;
1037 .storage = CRAM_SIZE, .size = CRAM_SIZE 1157 for (int flag = 0; flag < 5; flag++) {
1038 }; 1158 context->flags[flag] = (ival & (1 << (4 - flag))) != 0;
1039 static debug_array regs = { 1159 }
1040 .get = debug_vreg_get, .set = debug_vreg_set, 1160 }
1041 .storage = VDP_REGS, .size = VDP_REGS 1161
1042 }; 1162 static debug_val m68k_cycle_get(debug_var *var)
1043 if (!strcasecmp(name, "vram")) { 1163 {
1044 return &vram; 1164 m68k_context *context = var->ptr;
1045 } 1165 return debug_int(context->current_cycle);
1046 if (!strcasecmp(name, "vsram")) { 1166 }
1047 m68k_context *m68k = root->cpu_context; 1167
1048 genesis_context *gen = m68k->system; 1168 static debug_val m68k_usp_get(debug_var *var)
1049 vsram.storage = vsram.size = gen->vdp->vsram_size; 1169 {
1050 return &vsram; 1170 m68k_context *context = var->ptr;
1051 } 1171 return debug_int(context->status & 0x20 ? context->aregs[8] : context->aregs[7]);
1052 if (!strcasecmp(name, "cram")) { 1172 }
1053 return &cram; 1173
1054 } 1174 static void m68k_usp_set(debug_var *var, debug_val val)
1055 if (!strcasecmp(name, "reg")) { 1175 {
1056 return &regs; 1176 m68k_context *context = var->ptr;
1057 } 1177 uint32_t ival;
1058 return NULL; 1178 if (!debug_cast_int(val, &ival)) {
1059 } 1179 fprintf(stderr, "M68K register usp can only be set to an integer\n");
1060 1180 return;
1061 static uint32_t debug_part1_get(debug_root *root, debug_array *array, uint32_t index) 1181 }
1062 { 1182 context->aregs[context->status & 0x20 ? 8 : 7] = ival;
1063 m68k_context *m68k = root->cpu_context; 1183 }
1064 genesis_context *gen = m68k->system; 1184
1065 return gen->ym->part1_regs[index]; 1185 static debug_val m68k_ssp_get(debug_var *var)
1066 } 1186 {
1067 1187 m68k_context *context = var->ptr;
1068 static void debug_part1_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1188 return debug_int(context->status & 0x20 ? context->aregs[7] : context->aregs[8]);
1069 { 1189 }
1070 m68k_context *m68k = root->cpu_context; 1190
1071 genesis_context *gen = m68k->system; 1191 static void m68k_ssp_set(debug_var *var, debug_val val)
1072 uint8_t old_part = gen->ym->selected_part; 1192 {
1073 uint8_t old_reg = gen->ym->selected_reg; 1193 m68k_context *context = var->ptr;
1074 gen->ym->selected_part = 0; 1194 uint32_t ival;
1075 gen->ym->selected_reg = index; 1195 if (!debug_cast_int(val, &ival)) {
1076 ym_data_write(gen->ym, value); 1196 fprintf(stderr, "M68K register ssp can only be set to an integer\n");
1077 gen->ym->selected_part = old_part; 1197 return;
1078 gen->ym->selected_reg = old_reg; 1198 }
1079 } 1199 context->aregs[context->status & 0x20 ? 7 : 8] = ival;
1080 1200 }
1081 static uint32_t debug_part2_get(debug_root *root, debug_array *array, uint32_t index) 1201
1082 { 1202 static debug_val root_address_get(debug_var *var)
1083 m68k_context *m68k = root->cpu_context; 1203 {
1084 genesis_context *gen = m68k->system; 1204 debug_root *root = var->ptr;
1085 return gen->ym->part2_regs[index]; 1205 return debug_int(root->address);
1086 } 1206 }
1087 1207
1088 static void debug_part2_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1208 static void m68k_names(debug_root *root)
1089 { 1209 {
1090 m68k_context *m68k = root->cpu_context; 1210 debug_var *var;
1091 genesis_context *gen = m68k->system; 1211 for (char i = 0; i < 8; i++)
1092 uint8_t old_part = gen->ym->selected_part; 1212 {
1093 uint8_t old_reg = gen->ym->selected_reg; 1213 char rname[3] = {'d', '0' + i, 0};
1094 gen->ym->selected_part = 1; 1214 var = calloc(1, sizeof(debug_var));
1095 gen->ym->selected_reg = index; 1215 var->get = m68k_dreg_get;
1096 ym_data_write(gen->ym, value); 1216 var->set = m68k_dreg_set;
1097 gen->ym->selected_part = old_part; 1217 var->ptr = root->cpu_context;
1098 gen->ym->selected_reg = old_reg; 1218 var->val.v.u32 = i;
1099 } 1219 root->variables = tern_insert_ptr(root->variables, rname, var);
1100 1220 rname[0] = 'D';
1101 static debug_array* resolve_ym2612_array(debug_root *root, const char *name) 1221 root->variables = tern_insert_ptr(root->variables, rname, var);
1102 { 1222
1103 static debug_array part1 = { 1223 var = calloc(1, sizeof(debug_var));
1104 .get = debug_part1_get, .set = debug_part1_set, 1224 var->get = m68k_areg_get;
1105 .storage = YM_REG_END, .size = YM_REG_END 1225 var->set = m68k_areg_set;
1106 }; 1226 var->ptr = root->cpu_context;
1107 static debug_array part2 = { 1227 var->val.v.u32 = i;
1108 .get = debug_part2_get, .set = debug_part2_set, 1228 rname[0] = 'a';
1109 .storage = YM_REG_END, .size = YM_REG_END 1229 root->variables = tern_insert_ptr(root->variables, rname, var);
1110 }; 1230 rname[0] = 'A';
1111 if (!strcasecmp(name, "part1")) { 1231 root->variables = tern_insert_ptr(root->variables, rname, var);
1112 return &part1; 1232 if (i == 7) {
1113 } 1233 root->variables = tern_insert_ptr(root->variables, "sp", var);
1114 if (!strcasecmp(name, "part2")) { 1234 root->variables = tern_insert_ptr(root->variables, "SP", var);
1115 return &part2; 1235 }
1116 } 1236 }
1117 return NULL; 1237
1118 } 1238 var = calloc(1, sizeof(debug_var));
1119 1239 var->get = m68k_sr_get;
1120 static uint32_t debug_psgfreq_get(debug_root *root, debug_array *array, uint32_t index) 1240 var->set = m68k_sr_set;
1121 { 1241 var->ptr = root->cpu_context;
1122 m68k_context *m68k = root->cpu_context; 1242 root->variables = tern_insert_ptr(root->variables, "sr", var);
1123 genesis_context *gen = m68k->system; 1243 root->variables = tern_insert_ptr(root->variables, "SR", var);
1124 return gen->psg->counter_load[index]; 1244
1125 } 1245 var = calloc(1, sizeof(debug_var));
1126 1246 var->get = root_address_get;
1127 static void debug_psgfreq_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1247 var->ptr = root;
1128 { 1248 root->variables = tern_insert_ptr(root->variables, "pc", var);
1129 m68k_context *m68k = root->cpu_context; 1249 root->variables = tern_insert_ptr(root->variables, "PC", var);
1130 genesis_context *gen = m68k->system; 1250
1131 gen->psg->counter_load[index] = value; 1251 var = calloc(1, sizeof(debug_var));
1132 } 1252 var->get = m68k_usp_get;
1133 1253 var->set = m68k_usp_set;
1134 static uint32_t debug_psgcount_get(debug_root *root, debug_array *array, uint32_t index) 1254 var->ptr = root->cpu_context;
1135 { 1255 root->variables = tern_insert_ptr(root->variables, "usp", var);
1136 m68k_context *m68k = root->cpu_context; 1256 root->variables = tern_insert_ptr(root->variables, "USP", var);
1137 genesis_context *gen = m68k->system; 1257
1138 return gen->psg->counters[index]; 1258 var = calloc(1, sizeof(debug_var));
1139 } 1259 var->get = m68k_ssp_get;
1140 1260 var->set = m68k_ssp_set;
1141 static void debug_psgcount_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1261 var->ptr = root->cpu_context;
1142 { 1262 root->variables = tern_insert_ptr(root->variables, "ssp", var);
1143 m68k_context *m68k = root->cpu_context; 1263 root->variables = tern_insert_ptr(root->variables, "SSP", var);
1144 genesis_context *gen = m68k->system; 1264
1145 gen->psg->counters[index] = value; 1265 var = calloc(1, sizeof(debug_var));
1146 } 1266 var->get = m68k_cycle_get;
1147 1267 var->ptr = root->cpu_context;
1148 static uint32_t debug_psgvol_get(debug_root *root, debug_array *array, uint32_t index) 1268 root->variables = tern_insert_ptr(root->variables, "cycle", var);
1149 { 1269 }
1150 m68k_context *m68k = root->cpu_context; 1270
1151 genesis_context *gen = m68k->system; 1271 static debug_val vcounter_get(debug_var *var)
1152 return gen->psg->volume[index]; 1272 {
1153 } 1273 vdp_context *vdp = var->ptr;
1154 1274 return debug_int(vdp->vcounter);
1155 static void debug_psgvol_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value) 1275 }
1156 { 1276
1157 m68k_context *m68k = root->cpu_context; 1277 static debug_val hcounter_get(debug_var *var)
1158 genesis_context *gen = m68k->system; 1278 {
1159 gen->psg->volume[index] = value; 1279 vdp_context *vdp = var->ptr;
1160 } 1280 return debug_int(vdp->hslot);
1161 1281 }
1162 static debug_array* resolve_psg_array(debug_root *root, const char *name) 1282
1163 { 1283 static debug_val vdp_address_get(debug_var *var)
1164 static debug_array freq = { 1284 {
1165 .get = debug_psgfreq_get, .set = debug_psgfreq_set, 1285 vdp_context *vdp = var->ptr;
1166 .storage = 4, .size = 4 1286 return debug_int(vdp->address);
1167 }; 1287 }
1168 static debug_array counter = { 1288
1169 .get = debug_psgcount_get, .set = debug_psgcount_set, 1289 static void vdp_address_set(debug_var *var, debug_val val)
1170 .storage = 4, .size = 4 1290 {
1171 }; 1291 vdp_context *vdp = var->ptr;
1172 static debug_array volume = { 1292 uint32_t ival;
1173 .get = debug_psgvol_get, .set = debug_psgvol_set, 1293 if (!debug_cast_int(val, &ival)) {
1174 .storage = 4, .size = 4 1294 fprintf(stderr, "vdp address can only be set to an integer\n");
1175 }; 1295 return;
1176 if (!strcasecmp("frequency", name)) { 1296 }
1177 return &freq; 1297 vdp->address = ival & 0x1FFFF;
1178 } 1298 }
1179 if (!strcasecmp("counter", name)) { 1299
1180 return &counter; 1300 static debug_val vdp_cd_get(debug_var *var)
1181 } 1301 {
1182 if (!strcasecmp("volume", name)) { 1302 vdp_context *vdp = var->ptr;
1183 return &volume; 1303 return debug_int(vdp->cd);
1184 } 1304 }
1185 return NULL; 1305
1186 } 1306 static void vdp_cd_set(debug_var *var, debug_val val)
1187 1307 {
1188 static debug_array* resolve_genesis_array(debug_root *root, const char *name) 1308 vdp_context *vdp = var->ptr;
1189 { 1309 uint32_t ival;
1190 for (const char *cur = name; *cur; ++cur) 1310 if (!debug_cast_int(val, &ival)) {
1191 { 1311 fprintf(stderr, "vdp cd can only be set to an integer\n");
1192 if (*cur == ':') { 1312 return;
1193 if (cur - name == 3 && !memcmp(name, "vdp", 3)) { 1313 }
1194 return resolve_vdp_array(root, cur + 1); 1314 vdp->cd = ival & 0x3F;
1195 } else if (cur - name == 2 && !memcmp(name, "ym", 2)) { 1315 }
1196 return resolve_ym2612_array(root, cur + 1); 1316
1197 } else if (cur - name == 3 && !memcmp(name, "psg", 3)) { 1317 static debug_val vdp_status_get(debug_var *var)
1198 return resolve_psg_array(root, cur + 1); 1318 {
1199 } /*else if (cur - name == 3 && !memcmp(name, "sub", 3)) { 1319 vdp_context *vdp = var->ptr;
1200 m68k_context *m68k = root->cpu_context; 1320 return debug_int(vdp_status(vdp));
1201 genesis_context *gen = m68k->system; 1321 }
1202 if (gen->expansion) { 1322
1203 segacd_context *cd = gen->expansion; 1323 static debug_val debug_vram_get(debug_array *array, uint32_t index)
1204 root = find_m68k_root(cd->m68k); 1324 {
1205 return root->resolve(root, cur + 1, out); 1325 vdp_context *vdp = array->base;
1206 } else { 1326 return debug_int(vdp->vdpmem[index]);
1207 return NULL; 1327 }
1208 } 1328
1209 }*/ else { 1329 static void debug_vram_set(debug_array *array, uint32_t index, debug_val val)
1210 return NULL; 1330 {
1211 } 1331 uint32_t ival;
1212 } 1332 if (!debug_cast_int(val, &ival)) {
1213 } 1333 fprintf(stderr, "vram can only be set to integers\n");
1214 return NULL; 1334 return;
1215 } 1335 }
1216 1336 vdp_context *vdp = array->base;
1217 static debug_array* resolve_null_array(debug_root *root, const char *name) 1337 vdp->vdpmem[index] = ival;
1218 { 1338 }
1219 return NULL; 1339
1340 static debug_val debug_vsram_get(debug_array *array, uint32_t index)
1341 {
1342 vdp_context *vdp = array->base;
1343 return debug_int(vdp->vsram[index] & VSRAM_BITS);
1344 }
1345
1346 static void debug_vsram_set(debug_array *array, uint32_t index, debug_val val)
1347 {
1348 uint32_t ival;
1349 if (!debug_cast_int(val, &ival)) {
1350 fprintf(stderr, "vsram can only be set to integers\n");
1351 return;
1352 }
1353 vdp_context *vdp = array->base;
1354 vdp->vsram[index] = ival;
1355 }
1356
1357 static debug_val debug_cram_get(debug_array *array, uint32_t index)
1358 {
1359 vdp_context *vdp = array->base;
1360 return debug_int(vdp->cram[index] & CRAM_BITS);
1361 }
1362
1363 static void debug_cram_set(debug_array *array, uint32_t index, debug_val val)
1364 {
1365 uint32_t ival;
1366 if (!debug_cast_int(val, &ival)) {
1367 fprintf(stderr, "cram can only be set to integers\n");
1368 return;
1369 }
1370 vdp_context *vdp = array->base;
1371 vdp->cram[index] = ival;
1372 }
1373
1374 static debug_val debug_vreg_get(debug_array *array, uint32_t index)
1375 {
1376 vdp_context *vdp = array->base;
1377 return debug_int(vdp->regs[index]);
1378 }
1379
1380 static void debug_vreg_set(debug_array *array, uint32_t index, debug_val val)
1381 {
1382 vdp_context *vdp = array->base;
1383 uint32_t ival;
1384 if (!debug_cast_int(val, &ival)) {
1385 fprintf(stderr, "vdp registers can only be set to integers\n");
1386 return;
1387 }
1388 vdp_reg_write(vdp, index, ival);
1389 }
1390
1391 static debug_root* find_vdp_root(vdp_context *context)
1392 {
1393 debug_root *root = find_root(context);
1394 debug_var *var = calloc(1, sizeof(debug_var));
1395 var->get = vcounter_get;
1396 var->ptr = context;
1397 root->variables = tern_insert_ptr(root->variables, "vcounter", var);
1398
1399 var = calloc(1, sizeof(debug_var));
1400 var->get = hcounter_get;
1401 var->ptr = context;
1402 root->variables = tern_insert_ptr(root->variables, "hcounter", var);
1403
1404 var = calloc(1, sizeof(debug_var));
1405 var->get = vdp_address_get;
1406 var->set = vdp_address_set;
1407 var->ptr = context;
1408 root->variables = tern_insert_ptr(root->variables, "address", var);
1409
1410 var = calloc(1, sizeof(debug_var));
1411 var->get = vdp_cd_get;
1412 var->set = vdp_cd_set;
1413 var->ptr = context;
1414 root->variables = tern_insert_ptr(root->variables, "cd", var);
1415
1416 new_readonly_variable(root, "vram", new_fixed_array(context, debug_vram_get, debug_vram_set, VRAM_SIZE));
1417 new_readonly_variable(root, "vsram", new_fixed_array(context, debug_vsram_get, debug_vsram_set, context->vsram_size));
1418 new_readonly_variable(root, "cram", new_fixed_array(context, debug_cram_get, debug_cram_set, CRAM_SIZE));
1419 new_readonly_variable(root, "reg", new_fixed_array(context, debug_vreg_get, debug_vreg_set, VDP_REGS));
1420
1421 return root;
1422 }
1423
1424 static debug_val debug_part1_get(debug_array *array, uint32_t index)
1425 {
1426 ym2612_context *ym = array->base;
1427 return debug_int(ym->part1_regs[index]);
1428 }
1429
1430 static void debug_part1_set(debug_array *array, uint32_t index, debug_val val)
1431 {
1432 uint32_t ival;
1433 if (!debug_cast_int(val, &ival)) {
1434 fprintf(stderr, "ym2612 registers can only be set to integers\n");
1435 return;
1436 }
1437 ym2612_context *ym = array->base;
1438 uint8_t old_part = ym->selected_part;
1439 uint8_t old_reg = ym->selected_reg;
1440 ym->selected_part = 0;
1441 ym->selected_reg = index;
1442 ym_data_write(ym, ival);
1443 ym->selected_part = old_part;
1444 ym->selected_reg = old_reg;
1445 }
1446
1447 static debug_val debug_part2_get(debug_array *array, uint32_t index)
1448 {
1449 ym2612_context *ym = array->base;
1450 return debug_int(ym->part2_regs[index]);
1451 }
1452
1453 static void debug_part2_set(debug_array *array, uint32_t index, debug_val val)
1454 {
1455 uint32_t ival;
1456 if (!debug_cast_int(val, &ival)) {
1457 fprintf(stderr, "ym2612 registers can only be set to integers\n");
1458 return;
1459 }
1460 ym2612_context *ym = array->base;
1461 uint8_t old_part = ym->selected_part;
1462 uint8_t old_reg = ym->selected_reg;
1463 ym->selected_part = 1;
1464 ym->selected_reg = index;
1465 ym_data_write(ym, ival);
1466 ym->selected_part = old_part;
1467 ym->selected_reg = old_reg;
1468 }
1469
1470 static debug_root* find_ym2612_root(ym2612_context *context)
1471 {
1472 debug_root *root = find_root(context);
1473
1474 new_readonly_variable(root, "part1", new_fixed_array(context, debug_part1_get, debug_part1_set, YM_REG_END));
1475 new_readonly_variable(root, "part2", new_fixed_array(context, debug_part2_get, debug_part2_set, YM_REG_END));
1476
1477 return root;
1478 }
1479
1480
1481 static debug_val debug_psgfreq_get(debug_array *array, uint32_t index)
1482 {
1483 psg_context *psg = array->base;
1484 return debug_int(psg->counter_load[index]);
1485 }
1486
1487 static void debug_psgfreq_set(debug_array *array, uint32_t index, debug_val val)
1488 {
1489 uint32_t ival;
1490 if (!debug_cast_int(val, &ival)) {
1491 fprintf(stderr, "psg registers can only be set to integers\n");
1492 return;
1493 }
1494 psg_context *psg = array->base;
1495 psg->counter_load[index] = ival;
1496 }
1497
1498 static debug_val debug_psgcount_get(debug_array *array, uint32_t index)
1499 {
1500 psg_context *psg = array->base;
1501 return debug_int(psg->counters[index]);
1502 }
1503
1504 static void debug_psgcount_set(debug_array *array, uint32_t index, debug_val val)
1505 {
1506 uint32_t ival;
1507 if (!debug_cast_int(val, &ival)) {
1508 fprintf(stderr, "psg registers can only be set to integers\n");
1509 return;
1510 }
1511 psg_context *psg = array->base;
1512 psg->counters[index] = ival;
1513 }
1514
1515 static debug_val debug_psgvol_get(debug_array *array, uint32_t index)
1516 {
1517 psg_context *psg = array->base;
1518 return debug_int(psg->volume[index]);
1519 }
1520
1521 static void debug_psgvol_set(debug_array *array, uint32_t index, debug_val val)
1522 {
1523 uint32_t ival;
1524 if (!debug_cast_int(val, &ival)) {
1525 fprintf(stderr, "psg registers can only be set to integers\n");
1526 return;
1527 }
1528 psg_context *psg = array->base;
1529 psg->volume[index] = ival;
1530 }
1531
1532 debug_root *find_psg_root(psg_context *psg)
1533 {
1534 debug_root *root = find_root(psg);
1535
1536 new_readonly_variable(root, "frequency", new_fixed_array(psg, debug_psgfreq_get, debug_psgfreq_set, 4));
1537 new_readonly_variable(root, "counter", new_fixed_array(psg, debug_psgcount_get, debug_psgcount_set, 4));
1538 new_readonly_variable(root, "volume", new_fixed_array(psg, debug_psgvol_get, debug_psgvol_set, 4));
1539
1540 return root;
1220 } 1541 }
1221 1542
1222 void ambiguous_iter(char *key, tern_val val, uint8_t valtype, void *data) 1543 void ambiguous_iter(char *key, tern_val val, uint8_t valtype, void *data)
1223 { 1544 {
1224 char *prefix = data; 1545 char *prefix = data;
1658 fprintf(stderr, "Unrecognized format character: %c\n", format[0]); 1979 fprintf(stderr, "Unrecognized format character: %c\n", format[0]);
1659 } 1980 }
1660 } 1981 }
1661 } 1982 }
1662 1983
1663 static void do_print(debug_root *root, char *format_str, char *raw, uint32_t value) 1984 static void do_print(debug_root *root, char *format_str, char *raw, debug_val value)
1664 { 1985 {
1665 if (format_str[5] == 's') { 1986 switch(value.type)
1666 char tmp[128]; 1987 {
1667 int j; 1988 case DBG_VAL_U32:
1668 uint32_t addr = value; 1989 if (format_str[5] == 's') {
1669 for (j = 0; j < sizeof(tmp)-1; j++, addr++) 1990 char tmp[128];
1670 { 1991 int j;
1671 uint32_t tmp_addr = addr; 1992 uint32_t addr = value.v.u32;
1672 root->read_mem(root, &tmp_addr, 'b'); 1993 for (j = 0; j < sizeof(tmp)-1; j++, addr++)
1673 char c = tmp_addr; 1994 {
1674 if (c < 0x20 || c > 0x7F) { 1995 uint32_t tmp_addr = addr;
1675 break; 1996 root->read_mem(root, &tmp_addr, 'b');
1676 } 1997 char c = tmp_addr;
1677 tmp[j] = c; 1998 if (c < 0x20 || c > 0x7F) {
1678 } 1999 break;
1679 tmp[j] = 0; 2000 }
1680 printf(format_str, raw, tmp); 2001 tmp[j] = c;
1681 } else { 2002 }
1682 printf(format_str, raw, value); 2003 tmp[j] = 0;
2004 printf(format_str, raw, tmp);
2005 } else {
2006 printf(format_str, raw, value.v.u32);
2007 }
2008 break;
2009 case DBG_VAL_F32: {
2010 char tmp = format_str[5];
2011 format_str[5] = 'f';
2012 printf(format_str, raw, value.v.f32);
2013 format_str[5] = tmp;
2014 break;
2015 }
1683 } 2016 }
1684 } 2017 }
1685 2018
1686 static uint8_t cmd_print(debug_root *root, parsed_command *cmd) 2019 static uint8_t cmd_print(debug_root *root, parsed_command *cmd)
1687 { 2020 {
1764 expr *arg = parse_expression(param, &param); 2097 expr *arg = parse_expression(param, &param);
1765 if (!arg) { 2098 if (!arg) {
1766 free(fmt); 2099 free(fmt);
1767 return 1; 2100 return 1;
1768 } 2101 }
1769 uint32_t val; 2102 debug_val val;
1770 if (!eval_expr(root, arg, &val)) { 2103 if (!eval_expr(root, arg, &val)) {
1771 free(fmt); 2104 free(fmt);
1772 return 1; 2105 return 1;
1773 } 2106 }
1774 if (cur[1] == 's') { 2107 if (cur[1] == 's') {
1775 char tmp[128]; 2108 if (val.type == DBG_VAL_STRING) {
1776 int j; 2109 //TODO: implement me
1777 for (j = 0; j < sizeof(tmp)-1; j++, val++) 2110 } else {
1778 { 2111 char tmp[128];
1779 uint32_t addr = val; 2112 uint32_t address;
1780 root->read_mem(root, &addr, 'b'); 2113 if (!debug_cast_int(val, &address)) {
1781 char c = addr; 2114 fprintf(stderr, "Format char 's' accepts only integers and strings\n");
1782 if (c < 0x20 || c > 0x7F) { 2115 free(fmt);
1783 break; 2116 return 1;
1784 } 2117 }
1785 tmp[j] = c; 2118 int j;
2119 for (j = 0; j < sizeof(tmp)-1; j++, address++)
2120 {
2121 uint32_t addr = address;
2122 root->read_mem(root, &addr, 'b');
2123 char c = addr;
2124 if (c < 0x20 || c > 0x7F) {
2125 break;
2126 }
2127 tmp[j] = c;
2128 }
2129 tmp[j] = 0;
2130 printf(format_str, tmp);
1786 } 2131 }
1787 tmp[j] = 0;
1788 printf(format_str, tmp);
1789 } else { 2132 } else {
1790 printf(format_str, val); 2133 uint32_t ival;
2134 if (!debug_cast_int(val, &ival)) {
2135 fprintf(stderr, "Format char '%c' only accepts integers\n", cur[1]);
2136 free(fmt);
2137 return 1;
2138 }
2139 printf(format_str, ival);
1791 } 2140 }
1792 cur += 2; 2141 cur += 2;
1793 } else { 2142 } else {
1794 putchar(*cur); 2143 putchar(*cur);
1795 ++cur; 2144 ++cur;
1815 } 2164 }
1816 2165
1817 static uint8_t cmd_delete_display(debug_root *root, parsed_command *cmd) 2166 static uint8_t cmd_delete_display(debug_root *root, parsed_command *cmd)
1818 { 2167 {
1819 disp_def **cur = &root->displays; 2168 disp_def **cur = &root->displays;
2169 uint32_t index;
2170 if (!debug_cast_int(cmd->args[0].value, &index)) {
2171 fprintf(stderr, "Argument to deletedisplay must be an integer\n");
2172 return 1;
2173 }
1820 while (*cur) 2174 while (*cur)
1821 { 2175 {
1822 if ((*cur)->index == cmd->args[0].value) { 2176 if ((*cur)->index == index) {
1823 disp_def *del_disp = *cur; 2177 disp_def *del_disp = *cur;
1824 *cur = del_disp->next; 2178 *cur = del_disp->next;
1825 free(del_disp->format); 2179 free(del_disp->format);
1826 for (int i = 0; i < del_disp->num_args; i++) 2180 for (int i = 0; i < del_disp->num_args; i++)
1827 { 2181 {
1849 } 2203 }
1850 } 2204 }
1851 2205
1852 static uint8_t cmd_command(debug_root *root, parsed_command *cmd) 2206 static uint8_t cmd_command(debug_root *root, parsed_command *cmd)
1853 { 2207 {
1854 bp_def **target = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value); 2208 uint32_t index;
2209 if (!debug_cast_int(cmd->args[0].value, &index)) {
2210 fprintf(stderr, "Argument to commands must be an integer\n");
2211 return 1;
2212 }
2213 bp_def **target = find_breakpoint_idx(&root->breakpoints, index);
1855 if (!target) { 2214 if (!target) {
1856 fprintf(stderr, "Breakpoint %d does not exist!\n", cmd->args[0].value); 2215 fprintf(stderr, "Breakpoint %d does not exist!\n", index);
1857 return 1; 2216 return 1;
1858 } 2217 }
1859 for (uint32_t i = 0; i < (*target)->num_commands; i++) 2218 for (uint32_t i = 0; i < (*target)->num_commands; i++)
1860 { 2219 {
1861 free_parsed_command((*target)->commands + i); 2220 free_parsed_command((*target)->commands + i);
1878 return debugging; 2237 return debugging;
1879 } 2238 }
1880 2239
1881 static uint8_t cmd_if(debug_root *root, parsed_command *cmd) 2240 static uint8_t cmd_if(debug_root *root, parsed_command *cmd)
1882 { 2241 {
1883 return execute_block(root, cmd->args[0].value ? &cmd->block : &cmd->else_block); 2242 return execute_block(root, debug_cast_bool(cmd->args[0].value) ? &cmd->block : &cmd->else_block);
1884 } 2243 }
1885 2244
1886 static uint8_t cmd_while(debug_root *root, parsed_command *cmd) 2245 static uint8_t cmd_while(debug_root *root, parsed_command *cmd)
1887 { 2246 {
1888 if (!cmd->args[0].value) { 2247 if (!debug_cast_bool(cmd->args[0].value)) {
1889 return execute_block(root, &cmd->else_block); 2248 return execute_block(root, &cmd->else_block);
1890 } 2249 }
1891 int debugging = 1; 2250 int debugging = 1;
1892 do { 2251 do {
1893 debugging = execute_block(root, &cmd->block) && debugging; 2252 debugging = execute_block(root, &cmd->block) && debugging;
1894 if (!eval_expr(root, cmd->args[0].parsed, &cmd->args[0].value)) { 2253 if (!eval_expr(root, cmd->args[0].parsed, &cmd->args[0].value)) {
1895 fprintf(stderr, "Failed to eval %s\n", cmd->args[0].raw); 2254 fprintf(stderr, "Failed to eval %s\n", cmd->args[0].raw);
1896 return 1; 2255 return 1;
1897 } 2256 }
1898 } while (cmd->args[0].value); 2257 } while (debug_cast_bool(cmd->args[0].value));
1899 return debugging; 2258 return debugging;
1900 } 2259 }
1901 2260
1902 const char *expr_type_names[] = { 2261 const char *expr_type_names[] = {
1903 "EXPR_NONE", 2262 "EXPR_NONE",
1910 2269
1911 static uint8_t cmd_set(debug_root *root, parsed_command *cmd) 2270 static uint8_t cmd_set(debug_root *root, parsed_command *cmd)
1912 { 2271 {
1913 char *name = NULL; 2272 char *name = NULL;
1914 char size = 0; 2273 char size = 0;
1915 uint32_t address; 2274 debug_root *set_root = root;
2275 expr *set_expr = cmd->args[0].parsed;
2276 while (set_expr->type == EXPR_NAMESPACE)
2277 {
2278 set_root = tern_find_ptr(set_root->other_roots, set_expr->op.v.str);
2279 if (!set_root) {
2280 fprintf(stderr, "%s is not a valid namespace\n", set_expr->op.v.str);
2281 return 1;
2282 }
2283 set_expr = set_expr->left;
2284 }
2285 debug_val address;
1916 debug_array *array = NULL; 2286 debug_array *array = NULL;
1917 switch (cmd->args[0].parsed->type) 2287 switch (set_expr->type)
1918 { 2288 {
1919 case EXPR_SCALAR: 2289 case EXPR_SCALAR:
1920 if (cmd->args[0].parsed->op.type == TOKEN_NAME) { 2290 if (set_expr->op.type == TOKEN_NAME) {
1921 name = cmd->args[0].parsed->op.v.str; 2291 name = set_expr->op.v.str;
1922 } else { 2292 } else {
1923 fputs("First argument to set must be a name or memory expression, not a number", stderr); 2293 fputs("First argument to set must be a name or memory expression, not a number", stderr);
1924 return 1; 2294 return 1;
1925 } 2295 }
1926 break; 2296 break;
1927 case EXPR_SIZE: 2297 case EXPR_SIZE:
1928 size = cmd->args[0].parsed->op.v.op[0]; 2298 size = set_expr->op.v.op[0];
1929 if (cmd->args[0].parsed->left->op.type == TOKEN_NAME) { 2299 if (set_expr->left->op.type == TOKEN_NAME) {
1930 name = cmd->args[0].parsed->left->op.v.str; 2300 name = set_expr->left->op.v.str;
1931 } else { 2301 } else {
1932 fputs("First argument to set must be a name or memory expression, not a number", stderr); 2302 fputs("First argument to set must be a name or memory expression, not a number", stderr);
1933 return 1; 2303 return 1;
1934 } 2304 }
1935 break; 2305 break;
1936 case EXPR_MEM: 2306 case EXPR_MEM:
1937 size = cmd->args[0].parsed->op.v.op[0]; 2307 size = set_expr->op.v.op[0];
1938 if (!eval_expr(root, cmd->args[0].parsed->left, &address)) { 2308 if (!eval_expr(root, set_expr->left, &address)) {
1939 fprintf(stderr, "Failed to eval %s\n", cmd->args[0].raw); 2309 fprintf(stderr, "Failed to eval %s\n", cmd->args[0].raw);
1940 return 1; 2310 return 1;
1941 } 2311 }
1942 if (cmd->args[0].parsed->right) { 2312 if (address.type != DBG_VAL_U32) {
1943 array = full_array_resolve(root, cmd->args[0].parsed->right->op.v.str); 2313 fprintf(stderr, "Index in array expression must be integer\n");
2314 return 1;
2315 }
2316 if (set_expr->right) {
2317 debug_val right;
2318 if (!eval_expr(root, set_expr->right, &right)) {
2319 return 1;
2320 }
2321 array = get_array(right);
1944 if (!array) { 2322 if (!array) {
1945 fprintf(stderr, "Failed to resolve array %s\n", cmd->args[0].parsed->right->op.v.str); 2323 fprintf(stderr, "%s does not refer to an array\n", cmd->args[0].raw);
1946 return 1; 2324 return 1;
1947 } 2325 }
1948 if (!array->set) { 2326 if (!array->set) {
1949 fprintf(stderr, "Array %s is read-only\n", cmd->args[0].parsed->right->op.v.str); 2327 fprintf(stderr, "Array %s is read-only\n", set_expr->right->op.v.str);
1950 return 1; 2328 return 1;
1951 } 2329 }
1952 if (address >= array->size) { 2330 if (address.v.u32 >= array->size) {
1953 fprintf(stderr, "Address %X is out of bounds for array %s\n", address, cmd->args[0].parsed->right->op.v.str); 2331 fprintf(stderr, "Address %X is out of bounds for array %s\n", address.v.u32, set_expr->right->op.v.str);
1954 return 1; 2332 return 1;
1955 } 2333 }
1956 } 2334 }
1957 break; 2335 break;
1958 default: 2336 default:
1959 fprintf(stderr, "First argument to set must be a name or memory expression, got %s\n", expr_type_names[cmd->args[0].parsed->type]); 2337 fprintf(stderr, "First argument to set must be a name or memory expression, got %s\n", expr_type_names[set_expr->type]);
1960 return 1; 2338 return 1;
1961 } 2339 }
1962 if (!eval_expr(root, cmd->args[1].parsed, &cmd->args[1].value)) { 2340 if (!eval_expr(root, cmd->args[1].parsed, &cmd->args[1].value)) {
1963 fprintf(stderr, "Failed to eval %s\n", cmd->args[1].raw); 2341 fprintf(stderr, "Failed to eval %s\n", cmd->args[1].raw);
1964 return 1; 2342 return 1;
1965 } 2343 }
1966 uint32_t value = cmd->args[1].value; 2344 debug_val value = cmd->args[1].value;
1967 if (name && size && size != 'l') { 2345 if (name) {
1968 uint32_t old; 2346 debug_var *var = tern_find_ptr(set_root->variables, name);
1969 if (!root->resolve(root, name, &old)) { 2347 if (!var) {
1970 fprintf(stderr, "Failed to eval %s\n", name); 2348 fprintf(stderr, "%s is not defined\n", name);
1971 return 1; 2349 return 1;
1972 } 2350 }
1973 if (size == 'b') { 2351 if (!var->set) {
1974 old &= 0xFFFFFF00; 2352 fprintf(stderr, "%s is read-only\n", name);
1975 value &= 0xFF; 2353 return 1;
1976 value |= old; 2354 }
1977 } else { 2355 if (size && size != 'l') {
1978 old &= 0xFFFF0000; 2356 debug_val old = var->get(var);
1979 value &= 0xFFFF; 2357 if (size == 'b') {
1980 value |= old; 2358 old.v.u32 &= 0xFFFFFF00;
1981 } 2359 value.v.u32 &= 0xFF;
1982 } 2360 value.v.u32 |= old.v.u32;
1983 if (name) {
1984 if (!root->set(root, name, value)) {
1985 tern_val v;
1986 if (tern_find(root->variables, name, &v)) {
1987 root->variables = tern_insert_int(root->variables, name, value);
1988 } else { 2361 } else {
1989 fprintf(stderr, "Failed to set %s\n", name); 2362 old.v.u32 &= 0xFFFF0000;
1990 } 2363 value.v.u32 &= 0xFFFF;
1991 } 2364 value.v.u32 |= old.v.u32;
2365 }
2366 }
2367 var->set(var, value);
1992 } else if (array) { 2368 } else if (array) {
1993 array->set(root, array, address, value); 2369 array->set(array, address.v.u32, value);
1994 } else if (!root->write_mem(root, address, value, size)) { 2370 } else if (!root->write_mem(root, address.v.u32, value.v.u32, size)) {
1995 fprintf(stderr, "Failed to write to address %X\n", address); 2371 fprintf(stderr, "Failed to write to address %X\n", address.v.u32);
1996 } 2372 }
1997 return 1; 2373 return 1;
1998 } 2374 }
1999 2375
2000 static uint8_t cmd_variable(debug_root *root, parsed_command *cmd) 2376 static uint8_t cmd_variable(debug_root *root, parsed_command *cmd)
2001 { 2377 {
2002 if (cmd->args[0].parsed->type != EXPR_SCALAR || cmd->args[0].parsed->op.type != TOKEN_NAME) { 2378 debug_root *set_root = root;
2003 fprintf(stderr, "First argument to variable must be a name, got %s\n", expr_type_names[cmd->args[0].parsed->type]); 2379 expr *set_expr = cmd->args[0].parsed;
2380 while (set_expr->type == EXPR_NAMESPACE)
2381 {
2382 set_root = tern_find_ptr(set_root->other_roots, set_expr->op.v.str);
2383 if (!set_root) {
2384 fprintf(stderr, "%s is not a valid namespace\n", set_expr->op.v.str);
2385 return 1;
2386 }
2387 set_expr = set_expr->left;
2388 }
2389 if (set_expr->type != EXPR_SCALAR || set_expr->op.type != TOKEN_NAME) {
2390 fprintf(stderr, "First argument to variable must be a name, got %s\n", expr_type_names[set_expr->type]);
2004 return 1; 2391 return 1;
2005 } 2392 }
2006 uint32_t value = 0; 2393 debug_var *var = tern_find_ptr(set_root->variables, set_expr->op.v.str);
2394 if (var) {
2395 fprintf(stderr, "%s is already defined\n", set_expr->op.v.str);
2396 return 1;
2397 }
2398 debug_val value;
2399 value.type = DBG_VAL_U32;
2400 value.v.u32 = 0;
2007 if (cmd->num_args > 1) { 2401 if (cmd->num_args > 1) {
2008 if (!eval_expr(root, cmd->args[1].parsed, &cmd->args[1].value)) { 2402 if (!eval_expr(root, cmd->args[1].parsed, &cmd->args[1].value)) {
2009 fprintf(stderr, "Failed to eval %s\n", cmd->args[1].raw); 2403 fprintf(stderr, "Failed to eval %s\n", cmd->args[1].raw);
2010 return 1; 2404 return 1;
2011 } 2405 }
2012 value = cmd->args[1].value; 2406 value = cmd->args[1].value;
2013 } 2407 }
2014 root->variables = tern_insert_int(root->variables, cmd->args[0].parsed->op.v.str, value); 2408 new_user_variable(set_root, set_expr->op.v.str, value);
2015 return 1; 2409 return 1;
2016 } 2410 }
2017 2411
2018 static uint32_t user_array_get(debug_root *root, debug_array *array, uint32_t index)
2019 {
2020 return array->data[index];
2021 }
2022
2023 static void user_array_set(debug_root *root, debug_array *array, uint32_t index, uint32_t value)
2024 {
2025 array->data[index] = value;
2026 }
2027
2028 static void user_array_append(debug_root *root, debug_array *array, uint32_t value)
2029 {
2030 if (array->size == array->storage) {
2031 array->storage *= 2;
2032 array->data = realloc(array->data, sizeof(uint32_t) * array->storage);
2033 }
2034 array->data[array->size++] = value;
2035 }
2036
2037 static uint8_t cmd_array(debug_root *root, parsed_command *cmd) 2412 static uint8_t cmd_array(debug_root *root, parsed_command *cmd)
2038 { 2413 {
2039 if (cmd->args[0].parsed->type != EXPR_SCALAR || cmd->args[0].parsed->op.type != TOKEN_NAME) { 2414 debug_root *set_root = root;
2040 fprintf(stderr, "First argument to array must be a name, got %s\n", expr_type_names[cmd->args[0].parsed->type]); 2415 expr *set_expr = cmd->args[0].parsed;
2416 while (set_expr->type == EXPR_NAMESPACE)
2417 {
2418 set_root = tern_find_ptr(set_root->other_roots, set_expr->op.v.str);
2419 if (!set_root) {
2420 fprintf(stderr, "%s is not a valid namespace\n", set_expr->op.v.str);
2421 return 1;
2422 }
2423 set_expr = set_expr->left;
2424 }
2425 if (set_expr->type != EXPR_SCALAR || set_expr->op.type != TOKEN_NAME) {
2426 fprintf(stderr, "First argument to array must be a name, got %s\n", expr_type_names[set_expr->type]);
2041 return 1; 2427 return 1;
2042 } 2428 }
2043 debug_array *array = tern_find_ptr(root->arrays, cmd->args[0].parsed->op.v.str); 2429 debug_var *var = tern_find_ptr(set_root->variables, set_expr->op.v.str);
2044 if (!array) { 2430 debug_array *array;
2045 array = calloc(1, sizeof(debug_array)); 2431 if (var) {
2046 array->get = user_array_get; 2432 debug_val val = var->get(var);
2047 array->set = user_array_set; 2433 array = get_array(val);
2048 array->append = user_array_append; 2434 if (!array) {
2049 array->storage = cmd->num_args > 1 ? cmd->num_args - 1 : 4; 2435 fprintf(stderr, "%s is already defined as a non-array value\n", set_expr->op.v.str);
2050 array->data = calloc(array->storage, sizeof(uint32_t)); 2436 return 1;
2051 root->arrays = tern_insert_ptr(root->arrays, cmd->args[0].parsed->op.v.str, array); 2437 }
2052 } 2438 } else {
2053 array->size = cmd->num_args - 1; 2439 var = calloc(1, sizeof(debug_var));
2054 for (uint32_t i = 1; i < cmd->num_args; i++) 2440 var->get = user_var_get;
2441 var->set = user_var_set;
2442 var->val = new_user_array(cmd->num_args - 1);
2443 set_root->variables = tern_insert_ptr(set_root->variables, set_expr->op.v.str, var);
2444 array = get_array(var->val);
2445 }
2446 if (array->set == user_array_set) {
2447 array->size = cmd->num_args - 1;
2448 if (array->storage < array->size) {
2449 array->storage = array->size;
2450 array->base = realloc(array->base, sizeof(debug_val) * array->storage);
2451 }
2452 }
2453 for (uint32_t i = 1; i < cmd->num_args && i < array->size; i++)
2055 { 2454 {
2056 if (!eval_expr(root, cmd->args[i].parsed, &cmd->args[i].value)) { 2455 if (!eval_expr(root, cmd->args[i].parsed, &cmd->args[i].value)) {
2057 fprintf(stderr, "Failed to eval %s\n", cmd->args[i].raw); 2456 fprintf(stderr, "Failed to eval %s\n", cmd->args[i].raw);
2058 return 1; 2457 return 1;
2059 } 2458 }
2060 array->set(root, array, i - 1, cmd->args[i].value); 2459 array->set(array, i - 1, cmd->args[i].value);
2061 } 2460 }
2062 return 1; 2461 return 1;
2063 } 2462 }
2064 2463
2065 static uint8_t cmd_append(debug_root *root, parsed_command *cmd) 2464 static uint8_t cmd_append(debug_root *root, parsed_command *cmd)
2066 { 2465 {
2067 if (cmd->args[0].parsed->type != EXPR_SCALAR || cmd->args[0].parsed->op.type != TOKEN_NAME) { 2466 debug_array *array = get_array(cmd->args[0].value);
2068 fprintf(stderr, "First argument to append must be a name, got %s\n", expr_type_names[cmd->args[0].parsed->type]); 2467 if (!array) {
2468 fprintf(stderr, "%s is not an array\n", cmd->args[0].raw);
2069 return 1; 2469 return 1;
2070 } 2470 }
2071 debug_array *array = full_array_resolve(root, cmd->args[0].parsed->op.v.str); 2471 if (!array->append) {
2072 if (!array) { 2472 fprintf(stderr, "Array %s doesn't support appending\n", cmd->args[0].raw);
2073 fprintf(stderr, "Failed to resolve array %s\n", cmd->args[0].parsed->op.v.str);
2074 return 1; 2473 return 1;
2075 } 2474 }
2076 if (!array->append) { 2475 array->append(array, cmd->args[1].value);
2077 fprintf(stderr, "Array %s doesn't support appending\n", cmd->args[0].parsed->op.v.str); 2476 return 1;
2477 }
2478
2479 static uint8_t cmd_frames(debug_root *root, parsed_command *cmd)
2480 {
2481 uint32_t frames;
2482 if (!debug_cast_int(cmd->args[0].value, &frames)) {
2483 fprintf(stderr, "Argument to frames must be an integer\n");
2078 return 1; 2484 return 1;
2079 } 2485 }
2080 if (!eval_expr(root, cmd->args[1].parsed, &cmd->args[1].value)) { 2486 current_system->enter_debugger_frames = frames;
2081 fprintf(stderr, "Failed to eval %s\n", cmd->args[1].raw);
2082 return 1;
2083 }
2084 array->append(root, array, cmd->args[1].value);
2085 return 1;
2086 }
2087
2088 static uint8_t cmd_frames(debug_root *root, parsed_command *cmd)
2089 {
2090 current_system->enter_debugger_frames = cmd->args[0].value;
2091 return 0; 2487 return 0;
2092 } 2488 }
2093 2489
2094 static uint8_t cmd_bindup(debug_root *root, parsed_command *cmd) 2490 static uint8_t cmd_bindup(debug_root *root, parsed_command *cmd)
2095 { 2491 {
2111 { 2507 {
2112 if (!eval_expr(root, cmd->args[0].parsed, &cmd->args[0].value)) { 2508 if (!eval_expr(root, cmd->args[0].parsed, &cmd->args[0].value)) {
2113 fprintf(stderr, "Failed to evaluate breakpoint number: %s\n", cmd->args[0].raw); 2509 fprintf(stderr, "Failed to evaluate breakpoint number: %s\n", cmd->args[0].raw);
2114 return 1; 2510 return 1;
2115 } 2511 }
2116 bp_def **target = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value); 2512 uint32_t index;
2513 if (!debug_cast_int(cmd->args[0].value, &index)) {
2514 fprintf(stderr, "First argument to condition must be an integer\n");
2515 return 1;
2516 }
2517 bp_def **target = find_breakpoint_idx(&root->breakpoints, index);
2117 if (!*target) { 2518 if (!*target) {
2118 fprintf(stderr, "Failed to find breakpoint %u\n", cmd->args[0].value); 2519 fprintf(stderr, "Failed to find breakpoint %u\n", index);
2119 return 1; 2520 return 1;
2120 } 2521 }
2121 free_expr((*target)->condition); 2522 free_expr((*target)->condition);
2122 if (cmd->num_args > 1 && cmd->args[1].parsed) { 2523 if (cmd->num_args > 1 && cmd->args[1].parsed) {
2123 (*target)->condition = cmd->args[1].parsed; 2524 (*target)->condition = cmd->args[1].parsed;
2184 return 1; 2585 return 1;
2185 } 2586 }
2186 2587
2187 static uint8_t cmd_delete_m68k(debug_root *root, parsed_command *cmd) 2588 static uint8_t cmd_delete_m68k(debug_root *root, parsed_command *cmd)
2188 { 2589 {
2189 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value); 2590 uint32_t index;
2591 if (!debug_cast_int(cmd->args[0].value, &index)) {
2592 fprintf(stderr, "Argument to delete must be an integer\n");
2593 return 1;
2594 }
2595 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, index);
2190 if (!*this_bp) { 2596 if (!*this_bp) {
2191 fprintf(stderr, "Breakpoint %d does not exist\n", cmd->args[0].value); 2597 fprintf(stderr, "Breakpoint %d does not exist\n", index);
2192 return 1; 2598 return 1;
2193 } 2599 }
2194 bp_def *tmp = *this_bp; 2600 bp_def *tmp = *this_bp;
2195 if (tmp->type == BP_TYPE_CPU) { 2601 if (tmp->type == BP_TYPE_CPU) {
2196 remove_breakpoint(root->cpu_context, tmp->address); 2602 remove_breakpoint(root->cpu_context, tmp->address);
2207 return 1; 2613 return 1;
2208 } 2614 }
2209 2615
2210 static uint8_t cmd_breakpoint_m68k(debug_root *root, parsed_command *cmd) 2616 static uint8_t cmd_breakpoint_m68k(debug_root *root, parsed_command *cmd)
2211 { 2617 {
2212 insert_breakpoint(root->cpu_context, cmd->args[0].value, debugger); 2618 uint32_t address;
2619 if (!debug_cast_int(cmd->args[0].value, &address)) {
2620 fprintf(stderr, "Argument to breakpoint must be an integer\n");
2621 return 1;
2622 }
2623 insert_breakpoint(root->cpu_context, address, debugger);
2213 bp_def *new_bp = calloc(1, sizeof(bp_def)); 2624 bp_def *new_bp = calloc(1, sizeof(bp_def));
2214 new_bp->next = root->breakpoints; 2625 new_bp->next = root->breakpoints;
2215 new_bp->address = cmd->args[0].value; 2626 new_bp->address = address;
2216 new_bp->mask = 0xFFFFFF; 2627 new_bp->mask = 0xFFFFFF;
2217 new_bp->index = root->bp_index++; 2628 new_bp->index = root->bp_index++;
2218 new_bp->type = BP_TYPE_CPU; 2629 new_bp->type = BP_TYPE_CPU;
2219 root->breakpoints = new_bp; 2630 root->breakpoints = new_bp;
2220 printf("68K Breakpoint %d set at %X\n", new_bp->index, cmd->args[0].value); 2631 printf("68K Breakpoint %d set at %X\n", new_bp->index, address);
2221 return 1; 2632 return 1;
2222 } 2633 }
2223 2634
2224 static void on_vdp_reg_write(vdp_context *context, uint16_t reg, uint16_t value) 2635 static void on_vdp_reg_write(vdp_context *context, uint16_t reg, uint16_t value)
2225 { 2636 {
2231 debug_root *root = find_m68k_root(gen->m68k); 2642 debug_root *root = find_m68k_root(gen->m68k);
2232 bp_def **this_bp = find_breakpoint(&root->breakpoints, reg, BP_TYPE_VDPREG); 2643 bp_def **this_bp = find_breakpoint(&root->breakpoints, reg, BP_TYPE_VDPREG);
2233 int debugging = 1; 2644 int debugging = 1;
2234 if (*this_bp) { 2645 if (*this_bp) {
2235 if ((*this_bp)->condition) { 2646 if ((*this_bp)->condition) {
2236 uint32_t condres; 2647 debug_val condres;
2237 if (eval_expr(root, (*this_bp)->condition, &condres)) { 2648 if (eval_expr(root, (*this_bp)->condition, &condres)) {
2238 if (!condres) { 2649 if (!condres.v.u32) {
2239 return; 2650 return;
2240 } 2651 }
2241 } else { 2652 } else {
2242 fprintf(stderr, "Failed to eval condition for VDP Register Breakpoint %u\n", (*this_bp)->index); 2653 fprintf(stderr, "Failed to eval condition for VDP Register Breakpoint %u\n", (*this_bp)->index);
2243 free_expr((*this_bp)->condition); 2654 free_expr((*this_bp)->condition);
2264 static uint8_t cmd_vdp_reg_break(debug_root *root, parsed_command *cmd) 2675 static uint8_t cmd_vdp_reg_break(debug_root *root, parsed_command *cmd)
2265 { 2676 {
2266 bp_def *new_bp = calloc(1, sizeof(bp_def)); 2677 bp_def *new_bp = calloc(1, sizeof(bp_def));
2267 new_bp->next = root->breakpoints; 2678 new_bp->next = root->breakpoints;
2268 if (cmd->num_args) { 2679 if (cmd->num_args) {
2269 new_bp->address = cmd->args[0].value; 2680 if (!debug_cast_int(cmd->args[0].value, &new_bp->address)) {
2270 new_bp->mask = cmd->num_args > 1 ? cmd->args[1].value : 0xFF; 2681 fprintf(stderr, "Arguments to vdpregbreak must be integers if provided\n");
2682 return 1;
2683 }
2684 if (cmd->num_args > 1) {
2685 if (!debug_cast_int(cmd->args[1].value, &new_bp->mask)) {
2686 fprintf(stderr, "Arguments to vdpregbreak must be integers if provided\n");
2687 return 1;
2688 }
2689 } else {
2690 new_bp->mask = 0xFF;
2691 }
2271 } 2692 }
2272 new_bp->index = root->bp_index++; 2693 new_bp->index = root->bp_index++;
2273 new_bp->type = BP_TYPE_VDPREG; 2694 new_bp->type = BP_TYPE_VDPREG;
2274 root->breakpoints = new_bp; 2695 root->breakpoints = new_bp;
2275 m68k_context *m68k = root->cpu_context; 2696 m68k_context *m68k = root->cpu_context;
2279 return 1; 2700 return 1;
2280 } 2701 }
2281 2702
2282 static uint8_t cmd_advance_m68k(debug_root *root, parsed_command *cmd) 2703 static uint8_t cmd_advance_m68k(debug_root *root, parsed_command *cmd)
2283 { 2704 {
2284 insert_breakpoint(root->cpu_context, cmd->args[0].value, debugger); 2705 uint32_t address;
2706 if (!debug_cast_int(cmd->args[0].value, &address)) {
2707 fprintf(stderr, "Argument to advance must be an integer\n");
2708 return 1;
2709 }
2710 insert_breakpoint(root->cpu_context, address, debugger);
2285 return 0; 2711 return 0;
2286 } 2712 }
2287 2713
2288 static uint8_t cmd_step_m68k(debug_root *root, parsed_command *cmd) 2714 static uint8_t cmd_step_m68k(debug_root *root, parsed_command *cmd)
2289 { 2715 {
2415 static uint8_t cmd_disassemble_m68k(debug_root *root, parsed_command *cmd) 2841 static uint8_t cmd_disassemble_m68k(debug_root *root, parsed_command *cmd)
2416 { 2842 {
2417 m68k_context *context = root->cpu_context; 2843 m68k_context *context = root->cpu_context;
2418 uint32_t address = root->address; 2844 uint32_t address = root->address;
2419 if (cmd->num_args) { 2845 if (cmd->num_args) {
2420 address = cmd->args[0].value; 2846 if (!debug_cast_int(cmd->args[0].value, &address)) {
2847 fprintf(stderr, "Argument to disassemble must be an integer if provided\n");
2848 return 1;
2849 }
2421 } 2850 }
2422 char disasm_buf[1024]; 2851 char disasm_buf[1024];
2423 m68kinst inst; 2852 m68kinst inst;
2424 do { 2853 do {
2425 label_def *def = find_label(root->disasm, address); 2854 label_def *def = find_label(root->disasm, address);
2456 static uint8_t cmd_ym_channel(debug_root *root, parsed_command *cmd) 2885 static uint8_t cmd_ym_channel(debug_root *root, parsed_command *cmd)
2457 { 2886 {
2458 m68k_context *context = root->cpu_context; 2887 m68k_context *context = root->cpu_context;
2459 genesis_context * gen = context->system; 2888 genesis_context * gen = context->system;
2460 if (cmd->num_args) { 2889 if (cmd->num_args) {
2461 ym_print_channel_info(gen->ym, cmd->args[0].value - 1); 2890 ym_print_channel_info(gen->ym, cmd->args[0].value.v.u32 - 1);
2462 } else { 2891 } else {
2463 for (int i = 0; i < 6; i++) { 2892 for (int i = 0; i < 6; i++) {
2464 ym_print_channel_info(gen->ym, i); 2893 ym_print_channel_info(gen->ym, i);
2465 } 2894 }
2466 } 2895 }
2695 }, 3124 },
2696 .usage = "append NAME VALUE", 3125 .usage = "append NAME VALUE",
2697 .desc = "Increase the size of array NAME by 1 and set the last element to VALUE", 3126 .desc = "Increase the size of array NAME by 1 and set the last element to VALUE",
2698 .impl = cmd_append, 3127 .impl = cmd_append,
2699 .min_args = 2, 3128 .min_args = 2,
2700 .max_args = 2, 3129 .max_args = 2
2701 .skip_eval = 1
2702 }, 3130 },
2703 { 3131 {
2704 .names = (const char *[]){ 3132 .names = (const char *[]){
2705 "frames", NULL 3133 "frames", NULL
2706 }, 3134 },
2968 3396
2969 #ifndef NO_Z80 3397 #ifndef NO_Z80
2970 3398
2971 static uint8_t cmd_delete_z80(debug_root *root, parsed_command *cmd) 3399 static uint8_t cmd_delete_z80(debug_root *root, parsed_command *cmd)
2972 { 3400 {
2973 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, cmd->args[0].value); 3401 uint32_t index;
3402 if (!debug_cast_int(cmd->args[0].value, &index)) {
3403 fprintf(stderr, "Argument to delete must be an integer\n");
3404 return 1;
3405 }
3406 bp_def **this_bp = find_breakpoint_idx(&root->breakpoints, index);
2974 if (!*this_bp) { 3407 if (!*this_bp) {
2975 fprintf(stderr, "Breakpoint %d does not exist\n", cmd->args[0].value); 3408 fprintf(stderr, "Breakpoint %d does not exist\n", index);
2976 return 1; 3409 return 1;
2977 } 3410 }
2978 bp_def *tmp = *this_bp; 3411 bp_def *tmp = *this_bp;
2979 zremove_breakpoint(root->cpu_context, tmp->address); 3412 zremove_breakpoint(root->cpu_context, tmp->address);
2980 *this_bp = (*this_bp)->next; 3413 *this_bp = (*this_bp)->next;
2989 return 1; 3422 return 1;
2990 } 3423 }
2991 3424
2992 static uint8_t cmd_breakpoint_z80(debug_root *root, parsed_command *cmd) 3425 static uint8_t cmd_breakpoint_z80(debug_root *root, parsed_command *cmd)
2993 { 3426 {
2994 zinsert_breakpoint(root->cpu_context, cmd->args[0].value, (uint8_t *)zdebugger); 3427 uint32_t address;
3428 if (!debug_cast_int(cmd->args[0].value, &address)) {
3429 fprintf(stderr, "Argument to breakpoint must be an integer\n");
3430 return 1;
3431 }
3432 zinsert_breakpoint(root->cpu_context, address, (uint8_t *)zdebugger);
2995 bp_def *new_bp = calloc(1, sizeof(bp_def)); 3433 bp_def *new_bp = calloc(1, sizeof(bp_def));
2996 new_bp->next = root->breakpoints; 3434 new_bp->next = root->breakpoints;
2997 new_bp->address = cmd->args[0].value; 3435 new_bp->address = address;
2998 new_bp->mask = 0xFFFF; 3436 new_bp->mask = 0xFFFF;
2999 new_bp->type = BP_TYPE_CPU; 3437 new_bp->type = BP_TYPE_CPU;
3000 new_bp->index = root->bp_index++; 3438 new_bp->index = root->bp_index++;
3001 root->breakpoints = new_bp; 3439 root->breakpoints = new_bp;
3002 printf("Z80 Breakpoint %d set at %X\n", new_bp->index, cmd->args[0].value); 3440 printf("Z80 Breakpoint %d set at %X\n", new_bp->index, address);
3003 return 1; 3441 return 1;
3004 } 3442 }
3005 3443
3006 static uint8_t cmd_advance_z80(debug_root *root, parsed_command *cmd) 3444 static uint8_t cmd_advance_z80(debug_root *root, parsed_command *cmd)
3007 { 3445 {
3008 zinsert_breakpoint(root->cpu_context, cmd->args[0].value, (uint8_t *)zdebugger); 3446 uint32_t address;
3447 if (!debug_cast_int(cmd->args[0].value, &address)) {
3448 fprintf(stderr, "Argument to advance must be an integer\n");
3449 return 1;
3450 }
3451 zinsert_breakpoint(root->cpu_context, address, (uint8_t *)zdebugger);
3009 return 0; 3452 return 0;
3010 } 3453 }
3011 3454
3012 static uint8_t cmd_step_z80(debug_root *root, parsed_command *cmd) 3455 static uint8_t cmd_step_z80(debug_root *root, parsed_command *cmd)
3013 { 3456 {
3116 static uint8_t cmd_disassemble_z80(debug_root *root, parsed_command *cmd) 3559 static uint8_t cmd_disassemble_z80(debug_root *root, parsed_command *cmd)
3117 { 3560 {
3118 z80_context *context = root->cpu_context; 3561 z80_context *context = root->cpu_context;
3119 uint32_t address = root->address; 3562 uint32_t address = root->address;
3120 if (cmd->num_args) { 3563 if (cmd->num_args) {
3121 address = cmd->args[0].value; 3564 if (!debug_cast_int(cmd->args[0].value, &address)) {
3565 fprintf(stderr, "Argument to disassemble must be an integer if provided\n");
3566 return 1;
3567 }
3122 } 3568 }
3123 char disasm_buf[1024]; 3569 char disasm_buf[1024];
3124 z80inst inst; 3570 z80inst inst;
3125 do { 3571 do {
3126 label_def *def = find_label(root->disasm, address); 3572 label_def *def = find_label(root->disasm, address);
3330 { 3776 {
3331 root->symbols = tern_insert_int(root->symbols, label->labels[i], label->full_address); 3777 root->symbols = tern_insert_int(root->symbols, label->labels[i], label->full_address);
3332 } 3778 }
3333 } 3779 }
3334 3780
3781 static debug_val debug_frame_get(debug_var *var)
3782 {
3783 vdp_context *vdp = var->ptr;
3784 return debug_int(vdp->frame);
3785 }
3786
3335 debug_root *find_m68k_root(m68k_context *context) 3787 debug_root *find_m68k_root(m68k_context *context)
3336 { 3788 {
3337 debug_root *root = find_root(context); 3789 debug_root *root = find_root(context);
3338 if (root && !root->commands) { 3790 if (root && !root->commands) {
3339 add_commands(root, common_commands, NUM_COMMON); 3791 add_commands(root, common_commands, NUM_COMMON);
3340 add_commands(root, m68k_commands, NUM_68K); 3792 add_commands(root, m68k_commands, NUM_68K);
3341 root->read_mem = read_m68k; 3793 root->read_mem = read_m68k;
3342 root->write_mem = write_m68k; 3794 root->write_mem = write_m68k;
3343 root->set = set_m68k;
3344 root->disasm = create_68000_disasm(); 3795 root->disasm = create_68000_disasm();
3796 m68k_names(root);
3797 debug_var *var;
3345 switch (current_system->type) 3798 switch (current_system->type)
3346 { 3799 {
3347 case SYSTEM_GENESIS: 3800 case SYSTEM_GENESIS:
3348 case SYSTEM_SEGACD: 3801 case SYSTEM_SEGACD:
3349 //check if this is the main CPU 3802 //check if this is the main CPU
3350 if (context->system == current_system) { 3803 if (context->system == current_system) {
3351 root->resolve = resolve_genesis; 3804 genesis_context *gen = context->system;
3352 root->array_resolve = resolve_genesis_array; 3805 root->other_roots = tern_insert_ptr(root->other_roots, "z80", find_z80_root(gen->z80));
3806 root->other_roots = tern_insert_ptr(root->other_roots, "vdp", find_vdp_root(gen->vdp));
3807 root->other_roots = tern_insert_ptr(root->other_roots, "ym", find_ym2612_root(gen->ym));
3808 root->other_roots = tern_insert_ptr(root->other_roots, "psg", find_psg_root(gen->psg));
3353 add_commands(root, genesis_commands, NUM_GENESIS); 3809 add_commands(root, genesis_commands, NUM_GENESIS);
3810 var = calloc(1, sizeof(debug_var));
3811 var->get = debug_frame_get;
3812 var->ptr = gen->vdp;
3813 root->variables = tern_insert_ptr(root->variables, "frame", var);
3354 if (current_system->type == SYSTEM_SEGACD) { 3814 if (current_system->type == SYSTEM_SEGACD) {
3355 add_segacd_maincpu_labels(root->disasm); 3815 add_segacd_maincpu_labels(root->disasm);
3356 add_commands(root, scd_main_commands, NUM_SCD_MAIN); 3816 add_commands(root, scd_main_commands, NUM_SCD_MAIN);
3817 segacd_context *scd = gen->expansion;
3818 root->other_roots = tern_insert_ptr(root->other_roots, "sub", find_m68k_root(scd->m68k));
3357 } 3819 }
3358 break; 3820 break;
3359 } else { 3821 } else {
3360 add_segacd_subcpu_labels(root->disasm); 3822 add_segacd_subcpu_labels(root->disasm);
3361 add_commands(root, scd_sub_commands, NUM_SCD_SUB); 3823 add_commands(root, scd_sub_commands, NUM_SCD_SUB);
3824 segacd_context *scd = context->system;
3825 root->other_roots = tern_insert_ptr(root->other_roots, "main", find_m68k_root(scd->genesis->m68k));
3362 } 3826 }
3363 default: 3827 default:
3364 root->resolve = resolve_m68k; 3828 break;
3365 root->array_resolve = resolve_null_array;
3366 } 3829 }
3367 tern_foreach(root->disasm->labels, symbol_map, root); 3830 tern_foreach(root->disasm->labels, symbol_map, root);
3368 } 3831 }
3369 return root; 3832 return root;
3370 } 3833 }
3390 write_byte(address + 1, value >> 8, (void **)context->mem_pointers, &context->options->gen, context); 3853 write_byte(address + 1, value >> 8, (void **)context->mem_pointers, &context->options->gen, context);
3391 } 3854 }
3392 return 1; 3855 return 1;
3393 } 3856 }
3394 3857
3395 static uint8_t resolve_z80(debug_root *root, const char *name, uint32_t *out) 3858 static debug_val z80_reg8_get(debug_var *var)
3396 { 3859 {
3397 z80_context *context = root->cpu_context; 3860 z80_context *context = var->ptr;
3398 switch (tolower(name[0])) 3861 return debug_int(context->regs[var->val.v.u32]);
3399 { 3862 }
3400 case 'a': 3863
3401 if (!name[1]) { 3864 static void z80_reg8_set(debug_var *var, debug_val val)
3402 *out = context->regs[Z80_A]; 3865 {
3403 } else if (name[1] == '\'' && !name[2]) { 3866 z80_context *context = var->ptr;
3404 *out = context->alt_regs[Z80_A]; 3867 uint32_t ival;
3405 } else if (tolower(name[1]) == 'f') { 3868 if (!debug_cast_int(val, &ival)) {
3406 if (!name[2]) { 3869 fprintf(stderr, "Z80 register %s can only be set to an integer\n", z80_regs[var->val.v.u32]);
3407 *out = context->regs[Z80_A] << 8; 3870 return;
3408 *out |= context->flags[ZF_S] << 7; 3871 }
3409 *out |= context->flags[ZF_Z] << 6; 3872 context->regs[var->val.v.u32] = ival;
3410 *out |= context->flags[ZF_H] << 4; 3873 }
3411 *out |= context->flags[ZF_PV] << 2; 3874
3412 *out |= context->flags[ZF_N] << 1; 3875
3413 *out |= context->flags[ZF_C]; 3876 static debug_val z80_alt_reg8_get(debug_var *var)
3414 } else if (name[2] == '\'' && !name[3]) { 3877 {
3415 *out = context->alt_regs[Z80_A] << 8; 3878 z80_context *context = var->ptr;
3416 *out |= context->alt_flags[ZF_S] << 7; 3879 return debug_int(context->alt_regs[var->val.v.u32]);
3417 *out |= context->alt_flags[ZF_Z] << 6; 3880 }
3418 *out |= context->alt_flags[ZF_H] << 4; 3881
3419 *out |= context->alt_flags[ZF_PV] << 2; 3882 static void z80_alt_reg8_set(debug_var *var, debug_val val)
3420 *out |= context->alt_flags[ZF_N] << 1; 3883 {
3421 *out |= context->alt_flags[ZF_C]; 3884 z80_context *context = var->ptr;
3885 uint32_t ival;
3886 if (!debug_cast_int(val, &ival)) {
3887 fprintf(stderr, "Z80 register %s' can only be set to an integer\n", z80_regs[var->val.v.u32]);
3888 return;
3889 }
3890 context->alt_regs[var->val.v.u32] = ival;
3891 }
3892
3893 static debug_val z80_flags_get(debug_var *var)
3894 {
3895 z80_context *context = var->ptr;
3896 debug_val ret;
3897 ret.type = DBG_VAL_U32;
3898 ret.v.u32 = context->flags[ZF_S] << 7;
3899 ret.v.u32 |= context->flags[ZF_Z] << 6;
3900 ret.v.u32 |= context->flags[ZF_H] << 4;
3901 ret.v.u32 |= context->flags[ZF_PV] << 2;
3902 ret.v.u32 |= context->flags[ZF_N] << 1;
3903 ret.v.u32 |= context->flags[ZF_C];
3904 return ret;
3905 }
3906
3907 static debug_val z80_alt_flags_get(debug_var *var)
3908 {
3909 z80_context *context = var->ptr;
3910 debug_val ret;
3911 ret.type = DBG_VAL_U32;
3912 ret.v.u32 = context->alt_flags[ZF_S] << 7;
3913 ret.v.u32 |= context->alt_flags[ZF_Z] << 6;
3914 ret.v.u32 |= context->alt_flags[ZF_H] << 4;
3915 ret.v.u32 |= context->alt_flags[ZF_PV] << 2;
3916 ret.v.u32 |= context->alt_flags[ZF_N] << 1;
3917 ret.v.u32 |= context->alt_flags[ZF_C];
3918 return ret;
3919 }
3920
3921 static void z80_flags_set(debug_var *var, debug_val val)
3922 {
3923 z80_context *context = var->ptr;
3924 uint32_t ival;
3925 if (!debug_cast_int(val, &ival)) {
3926 fprintf(stderr, "Z80 register F can only be set to an integer\n");
3927 return;
3928 }
3929 context->flags[ZF_S] = ival >> 7 & 1;
3930 context->flags[ZF_Z] = ival >> 6 & 1;
3931 context->flags[ZF_H] = ival >> 4 & 1;
3932 context->flags[ZF_PV] = ival >> 2 & 1;
3933 context->flags[ZF_N] = ival >> 1 & 1;
3934 context->flags[ZF_C] = ival & 1;
3935 }
3936
3937 static void z80_alt_flags_set(debug_var *var, debug_val val)
3938 {
3939 z80_context *context = var->ptr;
3940 uint32_t ival;
3941 if (!debug_cast_int(val, &ival)) {
3942 fprintf(stderr, "Z80 register F' can only be set to an integer\n");
3943 return;
3944 }
3945 context->alt_flags[ZF_S] = ival >> 7 & 1;
3946 context->alt_flags[ZF_Z] = ival >> 6 & 1;
3947 context->alt_flags[ZF_H] = ival >> 4 & 1;
3948 context->alt_flags[ZF_PV] = ival >> 2 & 1;
3949 context->alt_flags[ZF_N] = ival >> 1 & 1;
3950 context->alt_flags[ZF_C] = ival & 1;
3951 }
3952
3953 static debug_val z80_regpair_get(debug_var *var)
3954 {
3955 z80_context *context = var->ptr;
3956 debug_val ret;
3957 if (var->val.v.u32 == Z80_AF) {
3958 ret = z80_flags_get(var);
3959 ret.v.u32 |= context->regs[Z80_A] << 8;
3960 } else {
3961 ret = debug_int(context->regs[z80_high_reg(var->val.v.u32)] << 8 | context->regs[z80_low_reg(var->val.v.u32)]);
3962 }
3963 return ret;
3964 }
3965
3966 static void z80_regpair_set(debug_var *var, debug_val val)
3967 {
3968 z80_context *context = var->ptr;
3969 uint32_t ival;
3970 if (!debug_cast_int(val, &ival)) {
3971 fprintf(stderr, "Z80 register %s can only be set to an integer\n", z80_regs[var->val.v.u32]);
3972 return;
3973 }
3974 if (var->val.v.u32 == Z80_AF) {
3975 context->regs[Z80_A] = ival >> 8;
3976 z80_flags_set(var, val);
3977 } else {
3978 context->regs[z80_high_reg(var->val.v.u32)] = ival >> 8;
3979 context->regs[z80_low_reg(var->val.v.u32)] = ival;
3980 }
3981 }
3982
3983 static debug_val z80_alt_regpair_get(debug_var *var)
3984 {
3985 z80_context *context = var->ptr;
3986 debug_val ret;
3987 if (var->val.v.u32 == Z80_AF) {
3988 ret = z80_alt_flags_get(var);
3989 ret.v.u32 |= context->alt_regs[Z80_A] << 8;
3990 } else {
3991 ret = debug_int(context->alt_regs[z80_high_reg(var->val.v.u32)] << 8 | context->alt_regs[z80_low_reg(var->val.v.u32)]);
3992 }
3993 return ret;
3994 }
3995
3996 static void z80_alt_regpair_set(debug_var *var, debug_val val)
3997 {
3998 z80_context *context = var->ptr;
3999 uint32_t ival;
4000 if (!debug_cast_int(val, &ival)) {
4001 fprintf(stderr, "Z80 register %s' can only be set to an integer\n", z80_regs[var->val.v.u32]);
4002 return;
4003 }
4004 if (var->val.v.u32 == Z80_AF) {
4005 context->regs[Z80_A] = ival >> 8;
4006 z80_alt_flags_set(var, val);
4007 } else {
4008 context->alt_regs[z80_high_reg(var->val.v.u32)] = ival >> 8;
4009 context->alt_regs[z80_low_reg(var->val.v.u32)] = ival;
4010 }
4011 }
4012
4013 static debug_val z80_sp_get(debug_var *var)
4014 {
4015 z80_context *context = var->ptr;
4016 return debug_int(context->sp);
4017 }
4018
4019 static void z80_sp_set(debug_var *var, debug_val val)
4020 {
4021 z80_context *context = var->ptr;
4022 uint32_t ival;
4023 if (!debug_cast_int(val, &ival)) {
4024 fprintf(stderr, "Z80 register sp can only be set to an integer\n");
4025 return;
4026 }
4027 context->sp = ival;
4028 }
4029
4030 static debug_val z80_im_get(debug_var *var)
4031 {
4032 z80_context *context = var->ptr;
4033 return debug_int(context->im);
4034 }
4035
4036 static void z80_im_set(debug_var *var, debug_val val)
4037 {
4038 z80_context *context = var->ptr;
4039 uint32_t ival;
4040 if (!debug_cast_int(val, &ival)) {
4041 fprintf(stderr, "Z80 register im can only be set to an integer\n");
4042 return;
4043 }
4044 context->im = ival & 3;
4045 }
4046
4047 static debug_val z80_iff1_get(debug_var *var)
4048 {
4049 z80_context *context = var->ptr;
4050 return debug_int(context->iff1);
4051 }
4052
4053 static void z80_iff1_set(debug_var *var, debug_val val)
4054 {
4055 z80_context *context = var->ptr;
4056 context->iff1 = debug_cast_bool(val);
4057 }
4058
4059 static debug_val z80_iff2_get(debug_var *var)
4060 {
4061 z80_context *context = var->ptr;
4062 return debug_int(context->iff2);
4063 }
4064
4065 static void z80_iff2_set(debug_var *var, debug_val val)
4066 {
4067 z80_context *context = var->ptr;
4068 context->iff2 = debug_cast_bool(val);
4069 }
4070
4071 static debug_val z80_cycle_get(debug_var *var)
4072 {
4073 z80_context *context = var->ptr;
4074 return debug_int(context->current_cycle);
4075 }
4076
4077 static debug_val z80_pc_get(debug_var *var)
4078 {
4079 z80_context *context = var->ptr;
4080 return debug_int(context->pc);
4081 }
4082
4083 static void z80_names(debug_root *root)
4084 {
4085 debug_var *var;
4086 for (int i = 0; i < Z80_UNUSED; i++)
4087 {
4088 var = calloc(1, sizeof(debug_var));
4089 var->ptr = root->cpu_context;
4090 if (i < Z80_BC) {
4091 var->get = z80_reg8_get;
4092 var->set = z80_reg8_set;
4093 } else if (i == Z80_SP) {
4094 var->get = z80_sp_get;
4095 var->set = z80_sp_set;
4096 } else {
4097 var->get = z80_regpair_get;
4098 var->set = z80_regpair_set;
4099 }
4100 var->val.v.u32 = i;
4101 root->variables = tern_insert_ptr(root->variables, z80_regs[i], var);
4102 size_t name_size = strlen(z80_regs[i]);
4103 char *name = malloc(name_size + 2);
4104 char *d = name;
4105 for (const char *c = z80_regs[i]; *c; c++, d++)
4106 {
4107 *d = toupper(*c);
4108 }
4109 name[name_size] = 0;
4110 root->variables = tern_insert_ptr(root->variables, name, var);
4111
4112 if (i < Z80_IXL || (i > Z80_R && i < Z80_IX && i != Z80_SP)) {
4113 memcpy(name, z80_regs[i], name_size);
4114 name[name_size] = '\'';
4115 name[name_size + 1] = 0;
4116 var = calloc(1, sizeof(debug_var));
4117 var->ptr = root->cpu_context;
4118 if (i < Z80_BC) {
4119 var->get = z80_alt_reg8_get;
4120 var->set = z80_alt_reg8_set;
3422 } else { 4121 } else {
3423 return 0; 4122 var->get = z80_alt_regpair_get;
3424 } 4123 var->set = z80_alt_regpair_set;
3425 } else { 4124 }
3426 return 0; 4125 var->val.v.u32 = i;
3427 } 4126 root->variables = tern_insert_ptr(root->variables, name, var);
3428 break; 4127 d = name;
3429 case 'b': 4128 for (const char *c = z80_regs[i]; *c; c++, d++)
3430 if (!name[1]) {
3431 *out = context->regs[Z80_B];
3432 } else if (name[1] == '\'' && !name[2]) {
3433 *out = context->alt_regs[Z80_B];
3434 } else if (tolower(name[1]) == 'c') {
3435 if (!name[2]) {
3436 *out = context->regs[Z80_B] << 8 | context->regs[Z80_C];
3437 } else if (name[2] == '\'' && !name[3]) {
3438 *out = context->alt_regs[Z80_B] << 8 | context->alt_regs[Z80_C];
3439 } else {
3440 return 0;
3441 }
3442 }
3443 break;
3444 case 'c':
3445 if (!name[1]) {
3446 *out = context->regs[Z80_C];
3447 } else if (name[1] == '\'' && !name[2]) {
3448 *out = context->alt_regs[Z80_C];
3449 } else if (!strcmp(name + 1, "ycle")) {
3450 *out = context->current_cycle;
3451 } else {
3452 return 0;
3453 }
3454 break;
3455 case 'd':
3456 if (!name[1]) {
3457 *out = context->regs[Z80_D];
3458 } else if (name[1] == '\'' && !name[2]) {
3459 *out = context->alt_regs[Z80_D];
3460 } else if (tolower(name[1]) == 'e') {
3461 if (!name[2]) {
3462 *out = context->regs[Z80_D] << 8 | context->regs[Z80_E];
3463 } else if (name[2] == '\'' && !name[3]) {
3464 *out = context->alt_regs[Z80_D] << 8 | context->alt_regs[Z80_E];
3465 } else {
3466 return 0;
3467 }
3468 }
3469 break;
3470 case 'e':
3471 if (!name[1]) {
3472 *out = context->regs[Z80_E];
3473 } else if (name[1] == '\'' && !name[2]) {
3474 *out = context->alt_regs[Z80_E];
3475 } else {
3476 return 0;
3477 }
3478 break;
3479 case 'f':
3480 if (!name[1]) {
3481 *out = context->flags[ZF_S] << 7;
3482 *out |= context->flags[ZF_Z] << 6;
3483 *out |= context->flags[ZF_H] << 4;
3484 *out |= context->flags[ZF_PV] << 2;
3485 *out |= context->flags[ZF_N] << 1;
3486 *out |= context->flags[ZF_C];
3487 } else if (name[1] == '\'' && !name[2]) {
3488 *out = context->alt_flags[ZF_S] << 7;
3489 *out |= context->alt_flags[ZF_Z] << 6;
3490 *out |= context->alt_flags[ZF_H] << 4;
3491 *out |= context->alt_flags[ZF_PV] << 2;
3492 *out |= context->alt_flags[ZF_N] << 1;
3493 *out |= context->alt_flags[ZF_C];
3494 } else {
3495 return 0;
3496 }
3497 break;
3498 case 'h':
3499 if (!name[1]) {
3500 *out = context->regs[Z80_H];
3501 } else if (name[1] == '\'' && !name[2]) {
3502 *out = context->alt_regs[Z80_H];
3503 } else if (tolower(name[1]) == 'l') {
3504 if (!name[2]) {
3505 *out = context->regs[Z80_H] << 8 | context->regs[Z80_L];
3506 } else if (name[2] == '\'' && !name[3]) {
3507 *out = context->alt_regs[Z80_H] << 8 | context->alt_regs[Z80_L];
3508 } else {
3509 return 0;
3510 }
3511 }
3512 break;
3513 case 'i':
3514 switch (tolower(name[1]))
3515 {
3516 case 0:
3517 *out = context->regs[Z80_I];
3518 break;
3519 case 'f':
3520 if (name[2] != 'f' || name[3] < '1' || name[4]) {
3521 return 0;
3522 }
3523 if (name[3] == '1') {
3524 *out = context->iff1;
3525 } else if (name[3] == '2') {
3526 *out = context->iff2;
3527 } else {
3528 return 0;
3529 }
3530 break;
3531 case 'm':
3532 if (name[2]) {
3533 return 0;
3534 }
3535 *out = context->im;
3536 break;
3537 case 'n':
3538 if (strcasecmp(name +2, "t_cycle")) {
3539 return 0;
3540 }
3541 *out = context->int_cycle;
3542 break;
3543 case 'r':
3544 if (name[2]) {
3545 return 0;
3546 }
3547 *out = context->regs[Z80_I] << 8 | context->regs[Z80_R];
3548 break;
3549 case 'x':
3550 switch (tolower(name[2]))
3551 { 4129 {
3552 case 0: 4130 *d = toupper(*c);
3553 *out = context->regs[Z80_IXH] << 8 | context->regs[Z80_IXL]; 4131 }
3554 break; 4132 root->variables = tern_insert_ptr(root->variables, name, var);
3555 case 'h': 4133 }
3556 if (name[3]) { 4134 free(name);
3557 return 0; 4135 }
3558 } 4136 var = calloc(1, sizeof(debug_var));
3559 *out = context->regs[Z80_IXH]; 4137 var->ptr = root->cpu_context;
3560 case 'l': 4138 var->get = z80_flags_get;
3561 if (name[3]) { 4139 var->set = z80_flags_set;
3562 return 0; 4140 root->variables = tern_insert_ptr(root->variables, "f", var);
3563 } 4141 root->variables = tern_insert_ptr(root->variables, "F", var);
3564 *out = context->regs[Z80_IXL]; 4142 var = calloc(1, sizeof(debug_var));
3565 default: 4143 var->ptr = root->cpu_context;
3566 return 0; 4144 var->get = z80_alt_flags_get;
3567 } 4145 var->set = z80_alt_flags_set;
3568 break; 4146 root->variables = tern_insert_ptr(root->variables, "f'", var);
3569 case 'y': 4147 root->variables = tern_insert_ptr(root->variables, "F'", var);
3570 switch (tolower(name[2])) 4148 var = calloc(1, sizeof(debug_var));
3571 { 4149 var->ptr = root->cpu_context;
3572 case 0: 4150 var->get = z80_im_get;
3573 *out = context->regs[Z80_IYH] << 8 | context->regs[Z80_IYL]; 4151 var->set = z80_im_set;
3574 break; 4152 root->variables = tern_insert_ptr(root->variables, "im", var);
3575 case 'h': 4153 root->variables = tern_insert_ptr(root->variables, "IM", var);
3576 if (name[3]) { 4154 var = calloc(1, sizeof(debug_var));
3577 return 0; 4155 var->ptr = root->cpu_context;
3578 } 4156 var->get = z80_iff1_get;
3579 *out = context->regs[Z80_IYH]; 4157 var->set = z80_iff1_set;
3580 case 'l': 4158 root->variables = tern_insert_ptr(root->variables, "iff1", var);
3581 if (name[3]) { 4159 var = calloc(1, sizeof(debug_var));
3582 return 0; 4160 var->ptr = root->cpu_context;
3583 } 4161 var->get = z80_iff2_get;
3584 *out = context->regs[Z80_IYL]; 4162 var->set = z80_iff2_set;
3585 default: 4163 root->variables = tern_insert_ptr(root->variables, "iff2", var);
3586 return 0; 4164 var = calloc(1, sizeof(debug_var));
3587 } 4165 var->ptr = root->cpu_context;
3588 break; 4166 var->get = z80_cycle_get;
3589 default: 4167 root->variables = tern_insert_ptr(root->variables, "cycle", var);
3590 return 0; 4168 var = calloc(1, sizeof(debug_var));
3591 } 4169 var->ptr = root->cpu_context;
3592 break; 4170 var->get = z80_pc_get;
3593 case 'l': 4171 root->variables = tern_insert_ptr(root->variables, "pc", var);
3594 if (!name[1]) { 4172 root->variables = tern_insert_ptr(root->variables, "PC", var);
3595 *out = context->regs[Z80_L];
3596 } else if (name[1] == '\'' && !name[2]) {
3597 *out = context->alt_regs[Z80_L];
3598 } else {
3599 return 0;
3600 }
3601 break;
3602 case 'p':
3603 if (tolower(name[1]) != 'c' || name[2]) {
3604 return 0;
3605 }
3606 *out = root->address;
3607 break;
3608 case 'r':
3609 if (name[1]) {
3610 return 0;
3611 }
3612 *out = context->regs[Z80_R];
3613 case 's':
3614 if (tolower(name[1]) != 'p' || name[2]) {
3615 return 0;
3616 }
3617 *out = context->sp;
3618 break;
3619 default:
3620 return 0;
3621 }
3622 return 1;
3623 }
3624
3625 static uint8_t resolve_sms(debug_root *root, const char *name, uint32_t *out)
3626 {
3627 if (resolve_z80(root, name, out)) {
3628 return 1;
3629 }
3630 z80_context *z80 = root->cpu_context;
3631 sms_context *sms = z80->system;
3632 if (!strcmp(name, "f") || !strcmp(name, "frame")) {
3633 *out = sms->vdp->frame;
3634 return 1;
3635 }
3636 return 0;
3637 }
3638
3639 static uint8_t set_z80(debug_root *root, const char *name, uint32_t value)
3640 {
3641 z80_context *context = root->cpu_context;
3642 switch (tolower(name[0]))
3643 {
3644 case 'a':
3645 if (!name[1]) {
3646 context->regs[Z80_A] = value;
3647 } else if (name[1] == '\'' && !name[2]) {
3648 context->alt_regs[Z80_A] = value;
3649 } else if (tolower(name[1]) == 'f') {
3650 if (!name[2]) {
3651 context->regs[Z80_A] = value >> 8;
3652 context->flags[ZF_S] = value >> 7 & 1;
3653 context->flags[ZF_Z] = value >> 6 & 1;
3654 context->flags[ZF_H] = value >> 4 & 1;
3655 context->flags[ZF_PV] = value >> 2 & 1;
3656 context->flags[ZF_N] = value >> 1 & 1;
3657 context->flags[ZF_C] = value & 1;
3658 } else if (name[2] == '\'' && !name[3]) {
3659 context->alt_regs[Z80_A] = value >> 8;
3660 context->alt_flags[ZF_S] = value >> 7 & 1;
3661 context->alt_flags[ZF_Z] = value >> 6 & 1;
3662 context->alt_flags[ZF_H] = value >> 4 & 1;
3663 context->alt_flags[ZF_PV] = value >> 2 & 1;
3664 context->alt_flags[ZF_N] = value >> 1 & 1;
3665 context->alt_flags[ZF_C] = value & 1;
3666 } else {
3667 return 0;
3668 }
3669 } else {
3670 return 0;
3671 }
3672 break;
3673 case 'b':
3674 if (!name[1]) {
3675 context->regs[Z80_B] = value;
3676 } else if (name[1] == '\'' && !name[2]) {
3677 context->alt_regs[Z80_B] = value;
3678 } else if (tolower(name[1]) == 'c') {
3679 if (!name[2]) {
3680 context->regs[Z80_B] = value >> 8;
3681 context->regs[Z80_C] = value;
3682 } else if (name[2] == '\'' && !name[3]) {
3683 context->alt_regs[Z80_B] = value >> 8;
3684 context->alt_regs[Z80_C] = value;
3685 } else {
3686 return 0;
3687 }
3688 }
3689 break;
3690 case 'c':
3691 if (!name[1]) {
3692 context->regs[Z80_C] = value;
3693 } else if (name[1] == '\'' && !name[2]) {
3694 context->alt_regs[Z80_C] = value;
3695 } else {
3696 return 0;
3697 }
3698 break;
3699 case 'd':
3700 if (!name[1]) {
3701 context->regs[Z80_D] = value;
3702 } else if (name[1] == '\'' && !name[2]) {
3703 context->alt_regs[Z80_D] = value;
3704 } else if (tolower(name[1]) == 'e') {
3705 if (!name[2]) {
3706 context->regs[Z80_D] = value >> 8;
3707 context->regs[Z80_E] = value;
3708 } else if (name[2] == '\'' && !name[3]) {
3709 context->alt_regs[Z80_D] = value >> 8;
3710 context->alt_regs[Z80_E] = value;
3711 } else {
3712 return 0;
3713 }
3714 }
3715 break;
3716 case 'e':
3717 if (!name[1]) {
3718 context->regs[Z80_E] = value;
3719 } else if (name[1] == '\'' && !name[2]) {
3720 context->alt_regs[Z80_E] = value;
3721 } else {
3722 return 0;
3723 }
3724 break;
3725 case 'f':
3726 if (!name[1]) {
3727 context->flags[ZF_S] = value >> 7 & 1;
3728 context->flags[ZF_Z] = value >> 6 & 1;
3729 context->flags[ZF_H] = value >> 4 & 1;
3730 context->flags[ZF_PV] = value >> 2 & 1;
3731 context->flags[ZF_N] = value >> 1 & 1;
3732 context->flags[ZF_C] = value & 1;
3733 } else if (name[1] == '\'' && !name[2]) {
3734 context->alt_flags[ZF_S] = value >> 7 & 1;
3735 context->alt_flags[ZF_Z] = value >> 6 & 1;
3736 context->alt_flags[ZF_H] = value >> 4 & 1;
3737 context->alt_flags[ZF_PV] = value >> 2 & 1;
3738 context->alt_flags[ZF_N] = value >> 1 & 1;
3739 context->alt_flags[ZF_C] = value & 1;
3740 } else {
3741 return 0;
3742 }
3743 break;
3744 case 'h':
3745 if (!name[1]) {
3746 context->regs[Z80_H] = value;
3747 } else if (name[1] == '\'' && !name[2]) {
3748 context->alt_regs[Z80_H] = value;
3749 } else if (tolower(name[1]) == 'e') {
3750 if (!name[2]) {
3751 context->regs[Z80_H] = value >> 8;
3752 context->regs[Z80_L] = value;
3753 } else if (name[2] == '\'' && !name[3]) {
3754 context->alt_regs[Z80_H] = value >> 8;
3755 context->alt_regs[Z80_L] = value;
3756 } else {
3757 return 0;
3758 }
3759 }
3760 break;
3761 case 'i':
3762 switch (tolower(name[1]))
3763 {
3764 case 0:
3765 context->regs[Z80_I] = value;
3766 break;
3767 case 'f':
3768 if (name[2] != 'f' || name[3] < '1' || name[4]) {
3769 return 0;
3770 }
3771 if (name[3] == '1') {
3772 context->iff1 = value != 0;
3773 } else if (name[3] == '2') {
3774 context->iff2 = value != 0;
3775 } else {
3776 return 0;
3777 }
3778 break;
3779 case 'm':
3780 if (name[2]) {
3781 return 0;
3782 }
3783 context->im = value & 3;
3784 break;
3785 case 'r':
3786 if (name[2]) {
3787 return 0;
3788 }
3789 context->regs[Z80_I] = value >> 8;
3790 context->regs[Z80_R] = value;
3791 break;
3792 case 'x':
3793 switch (tolower(name[2]))
3794 {
3795 case 0:
3796 context->regs[Z80_IXH] = value >> 8;
3797 context->regs[Z80_IXL] = value;
3798 break;
3799 case 'h':
3800 if (name[3]) {
3801 return 0;
3802 }
3803 context->regs[Z80_IXH] = value;
3804 case 'l':
3805 if (name[3]) {
3806 return 0;
3807 }
3808 context->regs[Z80_IXL] = value;
3809 default:
3810 return 0;
3811 }
3812 break;
3813 case 'y':
3814 switch (tolower(name[2]))
3815 {
3816 case 0:
3817 context->regs[Z80_IYH] = value >> 8;
3818 context->regs[Z80_IYL] = value;
3819 break;
3820 case 'h':
3821 if (name[3]) {
3822 return 0;
3823 }
3824 context->regs[Z80_IYH] = value;
3825 case 'l':
3826 if (name[3]) {
3827 return 0;
3828 }
3829 context->regs[Z80_IYL] = value;
3830 default:
3831 return 0;
3832 }
3833 break;
3834 default:
3835 return 0;
3836 }
3837 break;
3838 case 'l':
3839 if (!name[1]) {
3840 context->regs[Z80_L] = value;
3841 } else if (name[1] == '\'' && !name[2]) {
3842 context->alt_regs[Z80_L] = value;
3843 } else {
3844 return 0;
3845 }
3846 break;
3847 case 'r':
3848 if (name[1]) {
3849 return 0;
3850 }
3851 context->regs[Z80_R] = value;
3852 case 's':
3853 if (tolower(name[1]) != 'p' || name[2]) {
3854 return 0;
3855 }
3856 context->sp = value;
3857 break;
3858 default:
3859 return 0;
3860 }
3861 return 1;
3862 } 4173 }
3863 4174
3864 debug_root *find_z80_root(z80_context *context) 4175 debug_root *find_z80_root(z80_context *context)
3865 { 4176 {
3866 debug_root *root = find_root(context); 4177 debug_root *root = find_root(context);
3867 if (root && !root->commands) { 4178 if (root && !root->commands) {
3868 add_commands(root, common_commands, NUM_COMMON); 4179 add_commands(root, common_commands, NUM_COMMON);
3869 add_commands(root, z80_commands, NUM_Z80); 4180 add_commands(root, z80_commands, NUM_Z80);
4181 z80_names(root);
4182 genesis_context *gen;
4183 sms_context *sms;
4184 debug_var *var;
4185 //TODO: populate names
3870 switch (current_system->type) 4186 switch (current_system->type)
3871 { 4187 {
3872 case SYSTEM_GENESIS: 4188 case SYSTEM_GENESIS:
3873 case SYSTEM_SEGACD: 4189 case SYSTEM_SEGACD:
4190 gen = context->system;
3874 add_commands(root, gen_z80_commands, NUM_GEN_Z80); 4191 add_commands(root, gen_z80_commands, NUM_GEN_Z80);
3875 root->resolve = resolve_z80; 4192 root->other_roots = tern_insert_ptr(root->other_roots, "m68k", find_m68k_root(gen->m68k));
4193 //root->resolve = resolve_z80;
3876 break; 4194 break;
3877 case SYSTEM_SMS: 4195 case SYSTEM_SMS:
3878 root->resolve = resolve_sms; 4196 sms = context->system;
3879 add_commands(root, sms_commands, NUM_SMS); 4197 add_commands(root, sms_commands, NUM_SMS);
4198 root->other_roots = tern_insert_ptr(root->other_roots, "vdp", find_vdp_root(sms->vdp));
4199 root->other_roots = tern_insert_ptr(root->other_roots, "psg", find_psg_root(sms->psg));
4200 var = calloc(1, sizeof(debug_var));
4201 var->get = debug_frame_get;
4202 var->ptr = sms->vdp;
4203 root->variables = tern_insert_ptr(root->variables, "frame", var);
3880 break; 4204 break;
3881 default: 4205 //default:
3882 root->resolve = resolve_z80; 4206 //root->resolve = resolve_z80;
3883 } 4207 }
3884 root->array_resolve = resolve_null_array;
3885 root->read_mem = read_z80; 4208 root->read_mem = read_z80;
3886 root->write_mem = write_z80; 4209 root->write_mem = write_z80;
3887 root->set = set_z80;
3888 root->disasm = create_z80_disasm(); 4210 root->disasm = create_z80_disasm();
3889 } 4211 }
3890 return root; 4212 return root;
3891 } 4213 }
3892 4214
3904 root->address = address; 4226 root->address = address;
3905 //Check if this is a user set breakpoint, or just a temporary one 4227 //Check if this is a user set breakpoint, or just a temporary one
3906 bp_def ** this_bp = find_breakpoint(&root->breakpoints, address, BP_TYPE_CPU); 4228 bp_def ** this_bp = find_breakpoint(&root->breakpoints, address, BP_TYPE_CPU);
3907 if (*this_bp) { 4229 if (*this_bp) {
3908 if ((*this_bp)->condition) { 4230 if ((*this_bp)->condition) {
3909 uint32_t condres; 4231 debug_val condres;
3910 if (eval_expr(root, (*this_bp)->condition, &condres)) { 4232 if (eval_expr(root, (*this_bp)->condition, &condres)) {
3911 if (!condres) { 4233 if (!condres.v.u32) {
3912 return context; 4234 return context;
3913 } 4235 }
3914 } else { 4236 } else {
3915 fprintf(stderr, "Failed to eval condition for Z80 breakpoint %u\n", (*this_bp)->index); 4237 fprintf(stderr, "Failed to eval condition for Z80 breakpoint %u\n", (*this_bp)->index);
3916 free_expr((*this_bp)->condition); 4238 free_expr((*this_bp)->condition);
3993 int debugging = 1; 4315 int debugging = 1;
3994 //Check if this is a user set breakpoint, or just a temporary one 4316 //Check if this is a user set breakpoint, or just a temporary one
3995 bp_def ** this_bp = find_breakpoint(&root->breakpoints, address, BP_TYPE_CPU); 4317 bp_def ** this_bp = find_breakpoint(&root->breakpoints, address, BP_TYPE_CPU);
3996 if (*this_bp) { 4318 if (*this_bp) {
3997 if ((*this_bp)->condition) { 4319 if ((*this_bp)->condition) {
3998 uint32_t condres; 4320 debug_val condres;
3999 if (eval_expr(root, (*this_bp)->condition, &condres)) { 4321 if (eval_expr(root, (*this_bp)->condition, &condres)) {
4000 if (!condres) { 4322 if (!condres.v.u32) {
4001 return; 4323 return;
4002 } 4324 }
4003 } else { 4325 } else {
4004 fprintf(stderr, "Failed to eval condition for M68K breakpoint %u\n", (*this_bp)->index); 4326 fprintf(stderr, "Failed to eval condition for M68K breakpoint %u\n", (*this_bp)->index);
4005 free_expr((*this_bp)->condition); 4327 free_expr((*this_bp)->condition);