Mercurial > repos > blastem
comparison debug.c @ 2187:d0129f19ca52
Add a printf command to the debugger
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 14 Aug 2022 17:37:37 -0700 |
parents | 935e684f2d58 |
children | e17d99c96c89 |
comparison
equal
deleted
inserted
replaced
2186:935e684f2d58 | 2187:d0129f19ca52 |
---|---|
1125 uint32_t addr = args[i].value; | 1125 uint32_t addr = args[i].value; |
1126 for (j = 0; j < sizeof(tmp)-1; j++, addr++) | 1126 for (j = 0; j < sizeof(tmp)-1; j++, addr++) |
1127 { | 1127 { |
1128 uint32_t tmp_addr = addr; | 1128 uint32_t tmp_addr = addr; |
1129 root->read_mem(root, &tmp_addr, 'b'); | 1129 root->read_mem(root, &tmp_addr, 'b'); |
1130 char c = addr; | 1130 char c = tmp_addr; |
1131 if (c < 0x20 || c > 0x7F) { | 1131 if (c < 0x20 || c > 0x7F) { |
1132 break; | 1132 break; |
1133 } | 1133 } |
1134 tmp[j] = c; | 1134 tmp[j] = c; |
1135 } | 1135 } |
1136 tmp[j] = 0; | 1136 tmp[j] = 0; |
1137 printf(format_str, args[i].raw, tmp); | 1137 printf(format_str, args[i].raw, tmp); |
1138 } else { | 1138 } else { |
1139 printf(format_str, args[i].raw, args[i].value); | 1139 printf(format_str, args[i].raw, args[i].value); |
1140 } | |
1141 } | |
1142 return 1; | |
1143 } | |
1144 | |
1145 static uint8_t cmd_printf(debug_root *root, char *format, char *param) | |
1146 { | |
1147 if (!param) { | |
1148 fputs("printf requires at least one parameter\n", stderr); | |
1149 return 1; | |
1150 } | |
1151 while (isblank(*param)) | |
1152 { | |
1153 ++param; | |
1154 } | |
1155 if (*param != '"') { | |
1156 fprintf(stderr, "First parameter to printf must be a string, found '%s'\n", param); | |
1157 return 1; | |
1158 } | |
1159 ++param; | |
1160 char *fmt = strdup(param); | |
1161 char *cur = param, *out = fmt; | |
1162 while (*cur && *cur != '"') | |
1163 { | |
1164 if (*cur == '\\') { | |
1165 switch (cur[1]) | |
1166 { | |
1167 case 't': | |
1168 *(out++) = '\t'; | |
1169 break; | |
1170 case 'n': | |
1171 *(out++) = '\n'; | |
1172 break; | |
1173 case 'r': | |
1174 *(out++) = '\r'; | |
1175 break; | |
1176 case '\\': | |
1177 *(out++) = '\\'; | |
1178 break; | |
1179 default: | |
1180 fprintf(stderr, "Unsupported escape character %c in string %s\n", cur[1], fmt); | |
1181 free(fmt); | |
1182 return 1; | |
1183 } | |
1184 cur += 2; | |
1185 } else { | |
1186 *(out++) = *(cur++); | |
1187 } | |
1188 } | |
1189 *out = 0; | |
1190 ++cur; | |
1191 param = cur; | |
1192 cur = fmt; | |
1193 char format_str[3] = {'%', 'd', 0}; | |
1194 while (*cur) | |
1195 { | |
1196 if (*cur == '%') { | |
1197 switch(cur[1]) | |
1198 { | |
1199 case 'x': | |
1200 case 'X': | |
1201 case 'c': | |
1202 case 'd': | |
1203 case 's': | |
1204 break; | |
1205 default: | |
1206 fprintf(stderr, "Unsupported format character %c\n", cur[1]); | |
1207 free(fmt); | |
1208 return 1; | |
1209 } | |
1210 format_str[1] = cur[1]; | |
1211 expr *arg = parse_expression(param, ¶m); | |
1212 if (!arg) { | |
1213 free(fmt); | |
1214 return 1; | |
1215 } | |
1216 uint32_t val; | |
1217 if (!eval_expr(root, arg, &val)) { | |
1218 free(fmt); | |
1219 return 1; | |
1220 } | |
1221 if (cur[1] == 's') { | |
1222 char tmp[128]; | |
1223 int j; | |
1224 for (j = 0; j < sizeof(tmp)-1; j++, val++) | |
1225 { | |
1226 uint32_t addr = val; | |
1227 root->read_mem(root, &addr, 'b'); | |
1228 char c = addr; | |
1229 if (c < 0x20 || c > 0x7F) { | |
1230 break; | |
1231 } | |
1232 tmp[j] = c; | |
1233 } | |
1234 tmp[j] = 0; | |
1235 printf(format_str, tmp); | |
1236 } else { | |
1237 printf(format_str, val); | |
1238 } | |
1239 cur += 2; | |
1240 } else { | |
1241 putchar(*cur); | |
1242 ++cur; | |
1140 } | 1243 } |
1141 } | 1244 } |
1142 return 1; | 1245 return 1; |
1143 } | 1246 } |
1144 | 1247 |
1687 "print", NULL | 1790 "print", NULL |
1688 }, | 1791 }, |
1689 .usage = "print[/FORMAT] EXPRESSION...", | 1792 .usage = "print[/FORMAT] EXPRESSION...", |
1690 .desc = "Print one or more expressions using the optional format character", | 1793 .desc = "Print one or more expressions using the optional format character", |
1691 .impl = cmd_print, | 1794 .impl = cmd_print, |
1795 .min_args = 1, | |
1796 .max_args = -1 | |
1797 }, | |
1798 { | |
1799 .names = (const char *[]){ | |
1800 "printf", NULL | |
1801 }, | |
1802 .usage = "printf FORMAT EXPRESSION...", | |
1803 .desc = "Print a string with C-style formatting specifiers replaced with the value of the remaining arguments", | |
1804 .raw_impl = cmd_printf, | |
1692 .min_args = 1, | 1805 .min_args = 1, |
1693 .max_args = -1 | 1806 .max_args = -1 |
1694 }, | 1807 }, |
1695 { | 1808 { |
1696 .names = (const char *[]){ | 1809 .names = (const char *[]){ |