gbdk/sdcc/sim/ucsim/sim.src/brk.cc
2015-01-10 16:25:09 +01:00

341 lines
5.5 KiB
C++

/*
* 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 "pobjcl.h"
#include "brkcl.h"
/*
* Base object of breakpoints
*/
cl_brk::cl_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_base()
{
nr = inr;
addr = iaddr;
perm = iperm;
hit = ihit;
cnt = ihit;
}
cl_brk::~cl_brk(void)
{}
bool
cl_brk::do_hit(void)
{
cnt--;
if (cnt <= 0)
{
cnt= hit;
return(1);
}
return(0);
}
/*
* FETCH type of breakpoint
*/
cl_fetch_brk::cl_fetch_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_brk(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(int inr, t_addr iaddr, enum brk_perm iperm, int ihit,
enum brk_event ievent, const char *iid):
cl_brk(inr, iaddr, iperm, ihit)
{
event= ievent;
id = iid;
}
enum brk_type
cl_ev_brk::type(void)
{
return(brkEVENT);
}
bool
cl_ev_brk::match(struct event_rec *ev)
{
return(DD_FALSE);
}
/*
* WRITE IRAM type of EVENT breakpoints
*/
cl_wi_brk::cl_wi_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_ev_brk(inr, iaddr, iperm, ihit, brkWIRAM, "wi")
{}
bool
cl_wi_brk::match(struct event_rec *ev)
{
return(ev->wi == addr);
}
/*
* READ IRAM type of EVENT breakpoints
*/
cl_ri_brk::cl_ri_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_ev_brk(inr, iaddr, iperm, ihit, brkRIRAM, "ri")
{}
bool
cl_ri_brk::match(struct event_rec *ev)
{
return(ev->ri == addr);
}
/*
* WRITE XRAM type of EVENT breakpoints
*/
cl_wx_brk::cl_wx_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_ev_brk(inr, iaddr, iperm, ihit, brkWXRAM, "wx")
{}
bool
cl_wx_brk::match(struct event_rec *ev)
{
return(ev->wx == addr);
}
/*
* READ XRAM type of EVENT breakpoints
*/
cl_rx_brk::cl_rx_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_ev_brk(inr, iaddr, iperm, ihit, brkRXRAM, "rx")
{}
bool
cl_rx_brk::match(struct event_rec *ev)
{
return(ev->rx == addr);
}
/*
* WRITE SFR type of EVENT breakpoints
*/
cl_ws_brk::cl_ws_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_ev_brk(inr, iaddr, iperm, ihit, brkWSFR, "ws")
{}
bool
cl_ws_brk::match(struct event_rec *ev)
{
return(ev->ws == addr);
}
/*
* READ SFR type of EVENT breakpoints
*/
cl_rs_brk::cl_rs_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_ev_brk(inr, iaddr, iperm, ihit, brkRSFR, "rs")
{}
bool
cl_rs_brk::match(struct event_rec *ev)
{
return(ev->rs == addr);
}
/*
* READ CODE type of EVENT breakpoints
*/
cl_rc_brk::cl_rc_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
cl_ev_brk(inr, iaddr, iperm, ihit, brkRCODE, "rc")
{}
bool
cl_rc_brk::match(struct event_rec *ev)
{
return(ev->rc == addr);
}
/*
* 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_rom *arom):
cl_sorted_list(alimit, adelta)
{
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(DD_TRUE);
}
return(DD_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);
if (rom &&
bp->addr < rom->size)
rom->bp_map->set(bp->addr);
}
void
brk_coll::del_bp(t_addr addr)
{
int idx;
if (get_bp(addr, &idx))
free_at(idx);
if (rom &&
addr < rom->size)
rom->bp_map->clear(addr);
}
class cl_brk *
brk_coll::get_bp(t_addr addr, int *idx)
{
if (rom &&
addr < rom->size &&
rom->bp_map->get(addr))
{
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 &&
addr < rom->size &&
rom->bp_map->get(addr));
}
/* End of brk.cc */