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/sim.src/brk.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/sim.src/brk.cc')
| -rw-r--r-- | sim/ucsim/sim.src/brk.cc | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/sim/ucsim/sim.src/brk.cc b/sim/ucsim/sim.src/brk.cc new file mode 100644 index 0000000..aaa396a --- /dev/null +++ b/sim/ucsim/sim.src/brk.cc @@ -0,0 +1,312 @@ +/* + * Simulator of microcontrollers (brk.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 "ddconfig.h" + +#include <stdio.h> +#include <ctype.h> + +#include "pobjcl.h" +#include "globals.h" + +#include "brkcl.h" + + +/* + * Base object of breakpoints + */ + +cl_brk::cl_brk(class cl_address_space *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_base() +{ + mem = imem; + nr = inr; + addr = iaddr; + perm = iperm; + hit = ihit; + cnt = ihit; + cond = chars(""); + commands= chars(""); +} + +cl_brk::~cl_brk(void) +{} + +bool +cl_brk::condition(void) +{ + if (cond.empty()) + return true; + long l; + l= application->eval(cond); + //fprintf(stderr,"BP[%d]EVAL: %s =%ld\n", nr, (char*)cond, l); + return l!=0; +} + +void +cl_brk::activate(void) +{ + if (mem) + mem->set_brk(addr, this); +} + +void +cl_brk::inactivate(void) +{ + if (mem) + mem->del_brk(addr, this); +} + +bool +cl_brk::do_hit(void) +{ + cnt--; + if (cnt <= 0) + { + cnt= hit; + if (condition()) + return(1); + } + return(0); +} + + +/* + * FETCH type of breakpoint + */ + +cl_fetch_brk::cl_fetch_brk(class cl_address_space *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit): + cl_brk(imem, inr, iaddr, iperm, ihit) +{ + code = 0; +} + +enum brk_type +cl_fetch_brk::type(void) +{ + return(brkFETCH); +} + + +/* + * Base of EVENT type of breakpoints + */ + +cl_ev_brk::cl_ev_brk(class cl_address_space *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit, + enum brk_event ievent, const char *iid): + cl_brk(imem, inr, iaddr, iperm, ihit) +{ + event= ievent; + id = iid; + mem = imem; +} + +cl_ev_brk::cl_ev_brk(class cl_address_space *imem, int inr, t_addr iaddr, + enum brk_perm iperm, int ihit, char op): + cl_brk(imem, inr, iaddr, iperm, ihit) +{ + mem = imem; + if ((op= toupper(op)) == 'R') + { + event= brkREAD; + id= "read"; + } + else if (op == 'W') + { + event= brkWRITE; + id= "write"; + } + else + { + event= brkACCESS; + id= "access"; + } +} + +enum brk_type +cl_ev_brk::type(void) +{ + return(brkEVENT); +} + +bool +cl_ev_brk::match(struct event_rec *ev) +{ + return(false); +} + + +/* + * Collection of break-points + * + * This is a sorted collection, sorted by nr field of brk items. + */ + +brk_coll::brk_coll(t_index alimit, t_index adelta, + class cl_address_space *arom): + cl_sorted_list(alimit, adelta, "breakpoints") +{ + rom= arom; +} + +void * +brk_coll::key_of(void *item) +{ + return((void *)&(((class cl_brk *)(item))->nr)); +} + + +int +brk_coll::compare(void *key1, void *key2) +{ + int k1, k2; + + k1= *(int *)key1; + k2= *(int *)key2; + + if (k1 == k2) + return(0); + else + if (k1 < k2) + return(-1); + else + return(+1); +} + + +/* + * Checking if there is an event breakpoint for the specified event + */ + +bool +brk_coll::there_is_event(enum brk_event ev) +{ + class cl_brk *b; + int i; + + for (i= 0; i < count; i++) + { + b= (class cl_brk *)at(i); + if (b->type() == brkEVENT && + ((class cl_ev_brk *)b)->event == ev) + return(true); + } + return(false); +} + +/*int +brk_coll::make_new_nr(void) +{ + if (count == 0) + return(1); + class cl_brk *b= (class cl_brk *)(at(count-1)); + return(b->nr+1); +}*/ + +void +brk_coll::add_bp(class cl_brk *bp) +{ + add(bp); + bp->activate(); + return; + /*if (rom && + bp->addr < rom->size) + / *rom->bp_map->set(bp->addr)* /rom->set_brk(bp->addr, bp);*/ +} + +void +brk_coll::del_bp(t_addr addr) +{ + int idx; + class cl_brk *bp; + + if ((bp= get_bp(addr, &idx))) + { + bp->inactivate(); + free_at(idx); + } + return; +} + +void +brk_coll::del_bp(t_index idx, int /*dummy*/) +{ + class cl_brk *bp; + + if (idx >= count) + return; + bp= (class cl_brk *)(at(idx)); + if (!bp) + return; + bp->inactivate(); + free_at(idx); +} + +class cl_brk * +brk_coll::get_bp(t_addr addr, int *idx) +{ + if (rom && + rom->valid_address(addr) && + rom->get_cell_flag(addr, CELL_FETCH_BRK)) + { + for (*idx= 0; *idx < count; (*idx)++) + { + class cl_brk *b= (class cl_brk *)(at(*idx)); + if (b->addr == addr) + return(b); + } + } + return(0); +} + +class cl_brk * +brk_coll::get_bp(int nr) +{ + int i; + + for (i= 0; i < count; i++) + { + class cl_brk *bp= (class cl_brk *)(at(i)); + if (bp->nr == nr) + return(bp); + } + return(0); +} + +bool +brk_coll::bp_at(t_addr addr) +{ + return(rom && + rom->valid_address(addr) && + rom->get_cell_flag(addr, CELL_FETCH_BRK)); +} + + +/* End of brk.cc */ |
