diff options
| author | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
|---|---|---|
| committer | Xavier ASUS <xavi92psx@gmail.com> | 2019-10-18 00:31:54 +0200 |
| commit | 268a53de823a6750d6256ee1fb1e7707b4b45740 (patch) | |
| tree | 42c1799a9a82b2f7d9790ee9fe181d72a7274751 /sim/ucsim/cmd.src/cmd_bp.cc | |
| download | sdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz | |
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'sim/ucsim/cmd.src/cmd_bp.cc')
| -rw-r--r-- | sim/ucsim/cmd.src/cmd_bp.cc | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/sim/ucsim/cmd.src/cmd_bp.cc b/sim/ucsim/cmd.src/cmd_bp.cc new file mode 100644 index 0000000..f9106d5 --- /dev/null +++ b/sim/ucsim/cmd.src/cmd_bp.cc @@ -0,0 +1,393 @@ +/* + * Simulator of microcontrollers (cmd.src/bp.cc) + * + * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. + * + * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu + * + */ + +/* This file is part of microcontroller simulator: ucsim. + +UCSIM 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. + +UCSIM 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 UCSIM; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA. */ +/*@1@*/ + +#include <ctype.h> + +#include "ddconfig.h" + +#include "stdlib.h" + +// sim +#include "brkcl.h" +#include "argcl.h" +#include "simcl.h" + +// cmd +#include "cmd_bpcl.h" + + +/* + * BREAK command + */ + +//int +//cl_break_cmd::do_work(class cl_sim *sim, +// class cl_cmdline *cmdline, class cl_console *con) +COMMAND_DO_WORK_UC(cl_break_cmd) +{ + t_addr addr= 0; + int hit= 1; + char op; + chars cond= ""; + chars s; + class cl_address_space *mem; + class cl_cmd_arg *params[6]= { cmdline->param(0), + cmdline->param(1), + cmdline->param(2), + cmdline->param(3), + cmdline->param(4), + cmdline->param(5) }; + + if (0) {} + else if (cmdline->syntax_match(uc, CELL NUMBER STRING STRING)) { + hit= params[1]->value.number; + mem= uc->address_space(params[0]->value.cell, &addr); + if (!mem) + return syntax_error(con), false; + s= params[2]->get_svalue(); + if (s && *s && + (strcmp(s, "if") == 0)) + cond= params[3]->get_svalue(); + if (mem == uc->rom) + do_fetch(uc, addr, hit, cond, con); + else + { + do_event(uc, mem, 'r', addr, hit, cond, con); + do_event(uc, mem, 'w', addr, hit, cond, con); + } + } + else if (cmdline->syntax_match(uc, CELL STRING STRING)) { + hit= 1; + mem= uc->address_space(params[0]->value.cell, &addr); + if (!mem) + return syntax_error(con), false; + s= params[1]->get_svalue(); + if (s && *s && + (strcmp(s, "if") == 0)) + cond= params[2]->get_svalue(); + if (mem == uc->rom) + do_fetch(uc, addr, hit, cond, con); + else + { + do_event(uc, mem, 'r', addr, hit, cond, con); + do_event(uc, mem, 'w', addr, hit, cond, con); + } + } + else if (cmdline->syntax_match(uc, CELL NUMBER)) { + hit= params[1]->value.number; + mem= uc->address_space(params[0]->value.cell, &addr); + if (!mem) + return syntax_error(con), false; + if (mem == uc->rom) + do_fetch(uc, addr, hit, cond, con); + else + { + do_event(uc, mem, 'r', addr, hit, cond, con); + do_event(uc, mem, 'w', addr, hit, cond, con); + } + } + else if (cmdline->syntax_match(uc, CELL)) { + hit= 1; + mem= uc->address_space(params[0]->value.cell, &addr); + if (!mem) + return syntax_error(con), false; + if (mem == uc->rom) + do_fetch(uc, addr, hit, cond, con); + else + { + do_event(uc, mem, 'r', addr, hit, cond, con); + do_event(uc, mem, 'w', addr, hit, cond, con); + } + } + else if (cmdline->syntax_match(uc, MEMORY STRING ADDRESS NUMBER STRING STRING)) { + mem= params[0]->value.memory.address_space; + op= *(params[1]->get_svalue()); + addr= params[2]->value.address; + hit= params[3]->value.number; + s= params[4]->get_svalue(); + if (s && *s && (s=="if")) + cond= params[5]->get_svalue(); + do_event(uc, mem, op, addr, hit, cond, con); + } + else if (cmdline->syntax_match(uc, MEMORY STRING ADDRESS NUMBER)) { + mem= params[0]->value.memory.address_space; + op= *(params[1]->get_svalue()); + addr= params[2]->value.address; + hit= params[3]->value.number; + do_event(uc, mem, op, addr, hit, cond, con); + } + else if (cmdline->syntax_match(uc, MEMORY STRING ADDRESS STRING STRING)) { + mem= params[0]->value.memory.address_space; + op= *(params[1]->get_svalue()); + addr= params[2]->value.address; + hit= 1; + s= params[3]->get_svalue(); + if (s && *s && (s=="if")) + cond= params[4]->get_svalue(); + do_event(uc, mem, op, addr, hit, cond, con); + } + else if (cmdline->syntax_match(uc, MEMORY STRING ADDRESS)) { + mem= params[0]->value.memory.address_space; + op= *(params[1]->get_svalue()); + addr= params[2]->value.address; + hit= 1; + do_event(uc, mem, op, addr, hit, cond, con); + } + else if (cmdline->syntax_match(uc, ADDRESS NUMBER STRING STRING)) { + addr= params[0]->value.address; + hit= params[1]->value.number; + s= params[2]->get_svalue(); + if (s && *s && (s=="if")) + cond= params[3]->get_svalue(); + do_fetch(uc, addr, hit, cond, con); + } + else if (cmdline->syntax_match(uc, ADDRESS NUMBER)) { + addr= params[0]->value.address; + hit= params[1]->value.number; + do_fetch(uc, addr, hit, cond, con); + } + else if (cmdline->syntax_match(uc, ADDRESS STRING STRING)) { + addr= params[0]->value.address; + hit= 1; + s= params[1]->get_svalue(); + if (s && *s && (s=="if")) + cond= params[2]->get_svalue(); + do_fetch(uc, addr, hit, cond, con); + } + else if (cmdline->syntax_match(uc, ADDRESS)) { + addr= params[0]->value.address; + hit= 1; + do_fetch(uc, addr, hit, cond, con); + } + else + { + syntax_error(con); + return(false); + } + return(false); +} + +CMDHELP(cl_break_cmd, + "break addr [hit [if expr]] | break mem_type r|w addr [hit [if expr]]", + "Set fix or event breakpoint", + "long help of break") + +void +cl_break_cmd::do_fetch(class cl_uc *uc, + t_addr addr, int hit, + chars cond, + class cl_console_base *con) +{ + if (hit > 99999) + { + con->dd_printf("Hit value %d is too big.\n", hit); + return; + } + if (uc->fbrk->bp_at(addr)) + con->dd_printf("Breakpoint at 0x%06x is already set.\n", AI(addr)); + else + { + class cl_brk *b= new cl_fetch_brk(uc->rom/*address_space(MEM_ROM_ID)*/, + uc->make_new_brknr(), + addr, perm, hit); + b->init(); + b->cond= cond; + uc->fbrk->add_bp(b); + const char *s= uc->disass(addr, NULL); + con->dd_printf("Breakpoint %d at 0x%06x: %s (cond=\"%s\")\n", b->nr, AI(addr), s, (char*)cond); + free((char *)s); + } +} + +void +cl_break_cmd::do_event(class cl_uc *uc, + class cl_address_space *mem, + char op, t_addr addr, int hit, + chars cond, + class cl_console_base *con) +{ + class cl_ev_brk *b= NULL; + + b= uc->mk_ebrk(perm, mem, op, addr, hit); + if (b) + { + b->init(); + b->cond= cond; + uc->ebrk->add_bp(b); + } + else + con->dd_printf("Couldn't make event breakpoint\n"); +} + + +/* + * CLEAR address + */ + +//int +//cl_clear_cmd::do_work(class cl_sim *sim, +// class cl_cmdline *cmdline, class cl_console *con) +COMMAND_DO_WORK_UC(cl_clear_cmd) +{ + int idx; + class cl_brk *brk= uc->fbrk->get_bp(uc->PC, &idx); + + if (cmdline->param(0) == 0) + { + if (!brk) + { + con->dd_printf("No breakpoint at this address.\n"); + return(0); + } + uc->fbrk->del_bp(uc->PC); + return(0); + } + + int i= 0; + class cl_cmd_arg *param; + while ((param= cmdline->param(i++))) + { + t_addr addr; + if (!param->as_address(uc)) + return(false); + addr= param->value.address; + if (uc->fbrk->bp_at(addr) == 0) + con->dd_printf("No breakpoint at 0x%06x\n", addr); + else + uc->fbrk->del_bp(addr); + } + + return(false); +} + +CMDHELP(cl_clear_cmd, + "clear [addr...]", + "Clear fix breakpoint", + "long help of clear") + +/* + * DELETE nr nr ... + */ + +//int +//cl_delete_cmd::do_work(class cl_sim *sim, +// class cl_cmdline *cmdline, class cl_console *con) +COMMAND_DO_WORK_UC(cl_delete_cmd) +{ + if (cmdline->param(0) == 0) + { + // delete all + uc->remove_all_breaks(); + } + else + { + int i= 0; + class cl_cmd_arg *param; + while ((param= cmdline->param(i++))) + { + long num; + if (param->get_ivalue(&num)) + { + if (!uc->rm_brk(num)) + con->dd_printf("Error\n"); + } + } + } + return(false); +} + +CMDHELP(cl_delete_cmd, + "delete [nr...]", + "Delete breakpoint(s)", + "long help of clear") + +/* + * COMMANDS [nr] cmdstring... + */ + +COMMAND_DO_WORK_UC(cl_commands_cmd) +{ + int nr= -1; + + cmdline->shift(); + chars s= chars(cmdline->cmd); + if (cmdline->rest) + { + s+= ';'; + s+= cmdline->rest; + } + if (!s.empty()) + { + if (isdigit(((char*)s)[0])) + { + char *p0= (char*)s; + if (p0 && *p0) + { + long l=-2; + l= strtol(p0, 0, 0); + nr= l; + } + cmdline->shift(); + s= chars(cmdline->cmd); + if (cmdline->rest) + { + s+= ';'; + s+= cmdline->rest; + } + } + } + else + return con->dd_printf("command missing\n"), false; + + if (nr < 0) + { + nr= uc->brk_counter; + } + if (nr == 0) + return con->dd_printf("breakpoint (%d) not found\n", nr), false; + + class cl_brk *b= uc->brk_by_nr(nr); + if (!b) + return con->dd_printf("no breakpoint (%d)\n", nr), false; + + if (!s.empty()) + { + b->commands= s; + } + else + b->commands= chars(""); + cmdline->rest= NULL; + + return false; +} + +CMDHELP(cl_commands_cmd, + "commands [breakpoint-nr]", + "command_string", + "long help of commands") + +/* End of cmd.src/cmd_bp.cc */ |
