X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=s51%2Fs51-parse.c;fp=s51%2Fs51-parse.c;h=170c979dbed599a1f99d643ce0fda2dd31f66351;hp=0000000000000000000000000000000000000000;hb=17d2432a8b9c15963cd3b821f025ad33972ef477;hpb=210dbaa23cdacf3a6f2d6e23493e96ee2ac9bca7 diff --git a/s51/s51-parse.c b/s51/s51-parse.c new file mode 100644 index 00000000..170c979d --- /dev/null +++ b/s51/s51-parse.c @@ -0,0 +1,241 @@ +/* + * Copyright © 2008 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include "s51.h" + +static struct command_function functions[] = { + { "help", "?", command_help, "help", "Print this list\n" }, + { "quit", "q", command_quit, "[q]uit", "Quit\n" }, + { "di", "di", command_di, "di ", + "Dump imem\n" }, + { "ds", "ds", command_ds, "ds ", + "Dump sprs\n" }, + { "dx", "dx", command_dx, "dx ", + "Dump xaddr\n" }, + { "set", "t", command_set, "se[t] mem
...", + "Set mem {xram|rom|iram|sfr}\n" + "set bit \n" }, + { "dump", "d", command_dump, "[d]ump ", + "Dump {xram|rom|iram|sfr} \n" }, + { "file", "file", command_file, "file ", + "Pretend to load executable from \n" }, + { "pc", "p", command_pc, "[p]c [addr]", + "Get or set pc value\n" }, + { "break", "b", command_break,"[b]reak ", + "Set break point\n" }, + { "clear", "c", command_clear,"[c]lear ", + "Clear break point\n" }, + { "run", "r", command_run, "[r]un [start] [stop]", + "Run with optional start and temp breakpoint addresses\n" }, + { "go", "g", command_run, "[g]o [start] [stop]", + "Run with optional start and temp breakpoint addresses\n" }, + { "next", "n", command_next, "[n]ext", + "Step over one instruction, past any call\n" }, + { "step", "s", command_step, "[s]tep", + "Single step\n" }, + { "load", "l", command_load, "[l]oad ", + "Load a hex file into memory or flash" }, + { "halt", "h", command_halt, "[h]alt", + "Halt the processor\n" }, + { "reset","res",command_reset, "[res]et", + "Reset the CPU\n" }, + { "status","status",command_status, "status", + "Display CC1111 debug status\n" }, + { "info", "i", command_info, "[i]info", + "Get information\n" }, + { "stop", "stop", command_stop, "stop", + "Ignored\n" }, + { NULL, NULL, NULL, NULL, NULL }, +}; + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +static int +string_to_int(char *s, int *v) +{ + char *endptr; + + if (isdigit(s[0]) || s[0] == '-' || s[0] == '+') { + *v = strtol(s, &endptr, 0); + if (endptr == s) + return FALSE; + } else if (*s == '\'') { + s++; + if (*s == '\\') { + s++; + switch (*s) { + case 'n': + *v = '\n'; + break; + case 't': + *v = '\t'; + break; + default: + *v = (int) *s; + break; + } + } else + *v = (int) *s; + s++; + if (*s != '\'') + return FALSE; + } + else + return FALSE; + return TRUE; +} + +struct command_function * +command_string_to_function(struct command_function *functions, char *name) +{ + int i; + for (i = 0; functions[i].name; i++) + if (!strcmp(name, functions[i].name) || + !strcmp(name, functions[i].alias)) + return &functions[i]; + return NULL; +} + +enum command_result +command_function_help(struct command_function *functions, int argc, char **argv) +{ + int i; + struct command_function *func; + + if (argc == 1) { + for (i = 0; functions[i].name; i++) + s51_printf("%-10s%s\n", functions[i].name, + functions[i].usage); + } else { + for (i = 1; i < argc; i++) { + func = command_string_to_function(functions, argv[i]); + if (!func) { + s51_printf("%-10s unknown command\n", argv[i]); + return command_syntax; + } + s51_printf("%-10s %s\n%s", func->name, + func->usage, func->help); + } + } + return command_debug; +} + +static int +command_split_into_words(char *line, char **argv) +{ + char quotechar; + int argc; + + argc = 0; + while (*line) { + while (isspace(*line)) + line++; + if (!*line) + break; + if (*line == '"') { + quotechar = *line++; + *argv++ = line; + argc++; + while (*line && *line != quotechar) + line++; + if (*line) + *line++ = '\0'; + } else { + *argv++ = line; + argc++; + while (*line && !isspace(*line)) + line++; + if (*line) + *line++ = '\0'; + } + } + *argv = 0; + return argc; +} + +enum command_result +command_help(int argc, char **argv) +{ + return command_function_help(functions, argc, argv); +} + +void +command_syntax_error(int argc, char **argv) +{ + s51_printf("Syntax error in:"); + while (*argv) + s51_printf(" %s", *argv++); + s51_printf("\n"); +} + +void +command_read (void) +{ + int argc; + char line[1024]; + char *argv[20]; + enum command_result result; + struct command_function *func; + + s51_dbg = ccdbg_open (); + if (!s51_dbg) { + perror("ccdbg_open"); + exit(1); + } + ccdbg_debug_mode(s51_dbg); + ccdbg_halt(s51_dbg); + s51_printf("Welcome to the non-simulated processor\n"); + for (;;) { + if (s51_read_line (line, sizeof line) == 0) + break; + s51_interrupted = 0; + argc = command_split_into_words(line, argv); + if (argc > 0) { + func = command_string_to_function(functions, argv[0]); + if (!func) + command_syntax_error(argc, argv); + else + { + result = (*func->func)(argc, argv); + if (s51_interrupted) + result = command_interrupt; + switch (result) { + case command_syntax: + command_syntax_error(argc, argv); + break; + case command_error: + s51_printf("Error\n"); + break; + case command_success: + break; + case command_interrupt: + ccdbg_halt(s51_dbg); + s51_printf("Interrupted\n"); + break; + default: + break; + } + } + } + } + ccdbg_close(s51_dbg); + s51_printf("...\n"); +}