341 lines
5.5 KiB
C++
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 */
|