3543b1b2d4ae8254c78727c1aa84fad1f93f20ab
[fw/sdcc] / sim / ucsim / sim.src / brk.cc
1 /*
2  * Simulator of microcontrollers (brk.cc)
3  *
4  * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
5  * 
6  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
7  *
8  */
9
10 /* This file is part of microcontroller simulator: ucsim.
11
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING.  If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26 /*@1@*/
27
28 #include "ddconfig.h"
29
30 #include <stdio.h>
31
32 #include "pobjcl.h"
33 #include "brkcl.h"
34
35
36 /*
37  * Base object of breakpoints
38  */
39
40 cl_brk::cl_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
41   cl_base()
42 {
43   nr   = inr;
44   addr = iaddr;
45   perm = iperm;
46   hit  = ihit;
47   cnt  = ihit;
48 }
49
50 cl_brk::~cl_brk(void)
51 {}
52
53 bool
54 cl_brk::do_hit(void)
55 {
56   cnt--;
57   if (cnt <= 0)
58     {
59       cnt= hit;
60       return(1);
61     }
62   return(0);
63 }
64
65
66 /*
67  * FETCH type of breakpoint
68  */
69
70 cl_fetch_brk::cl_fetch_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
71   cl_brk(inr, iaddr, iperm, ihit)
72 {
73   code = 0;
74 }
75
76 enum brk_type
77 cl_fetch_brk::type(void)
78 {
79   return(brkFETCH);
80 }
81
82
83 /*
84  * Base of EVENT type of breakpoints
85  */
86
87 cl_ev_brk::cl_ev_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit,
88                      enum brk_event ievent, const char *iid):
89   cl_brk(inr, iaddr, iperm, ihit)
90 {
91   event= ievent;
92   id   = iid;
93 }
94
95 enum brk_type
96 cl_ev_brk::type(void)
97 {
98   return(brkEVENT);
99 }
100
101 bool
102 cl_ev_brk::match(struct event_rec *ev)
103 {
104   return(DD_FALSE);
105 }
106
107
108 /*
109  * WRITE IRAM type of EVENT breakpoints
110  */
111
112 cl_wi_brk::cl_wi_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
113   cl_ev_brk(inr, iaddr, iperm, ihit, brkWIRAM, "wi")
114 {}
115
116 bool
117 cl_wi_brk::match(struct event_rec *ev)
118 {
119   return(ev->wi == addr);
120 }
121
122
123 /*
124  * READ IRAM type of EVENT breakpoints
125  */
126
127 cl_ri_brk::cl_ri_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
128   cl_ev_brk(inr, iaddr, iperm, ihit, brkRIRAM, "ri")
129 {}
130
131 bool
132 cl_ri_brk::match(struct event_rec *ev)
133 {
134   return(ev->ri == addr);
135 }
136
137
138 /*
139  * WRITE XRAM type of EVENT breakpoints
140  */
141
142 cl_wx_brk::cl_wx_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
143   cl_ev_brk(inr, iaddr, iperm, ihit, brkWXRAM, "wx")
144 {}
145
146 bool
147 cl_wx_brk::match(struct event_rec *ev)
148 {
149   return(ev->wx == addr);
150 }
151
152
153 /*
154  * READ XRAM type of EVENT breakpoints
155  */
156
157 cl_rx_brk::cl_rx_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
158   cl_ev_brk(inr, iaddr, iperm, ihit, brkRXRAM, "rx")
159 {}
160
161 bool
162 cl_rx_brk::match(struct event_rec *ev)
163 {
164   return(ev->rx == addr);
165 }
166
167
168 /*
169  * WRITE SFR type of EVENT breakpoints
170  */
171
172 cl_ws_brk::cl_ws_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
173   cl_ev_brk(inr, iaddr, iperm, ihit, brkWSFR, "ws")
174 {}
175
176 bool
177 cl_ws_brk::match(struct event_rec *ev)
178 {
179   return(ev->ws == addr);
180 }
181
182
183 /*
184  * READ SFR type of EVENT breakpoints
185  */
186
187 cl_rs_brk::cl_rs_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
188   cl_ev_brk(inr, iaddr, iperm, ihit, brkRSFR, "rs")
189 {}
190
191 bool
192 cl_rs_brk::match(struct event_rec *ev)
193 {
194   return(ev->rs == addr);
195 }
196
197
198 /*
199  * READ CODE type of EVENT breakpoints
200  */
201
202 cl_rc_brk::cl_rc_brk(int inr, t_addr iaddr, enum brk_perm iperm, int ihit):
203   cl_ev_brk(inr, iaddr, iperm, ihit, brkRCODE, "rc")
204 {}
205
206 bool
207 cl_rc_brk::match(struct event_rec *ev)
208 {
209   return(ev->rc == addr);
210 }
211
212
213 /*
214  * Collection of break-points
215  *
216  * This is a sorted collection, sorted by nr field of brk items.
217  */
218
219 brk_coll::brk_coll(t_index alimit, t_index adelta, class cl_rom *arom):
220   cl_sorted_list(alimit, adelta)
221 {
222   rom= arom;
223 }
224
225 void *
226 brk_coll::key_of(void *item)
227 {
228   return((void *)&(((class cl_brk *)(item))->nr));
229 }
230
231
232 int
233 brk_coll::compare(void *key1, void *key2)
234 {
235   int k1, k2;
236
237   k1= *(int *)key1;
238   k2= *(int *)key2;
239
240   if (k1 == k2)
241     return(0);
242   else
243     if (k1 < k2)
244       return(-1);
245     else
246       return(+1);
247 }
248
249
250 /*
251  * Checking if there is an event breakpoint for the specified event
252  */
253
254 bool
255 brk_coll::there_is_event(enum brk_event ev)
256 {
257   class cl_brk *b;
258   int   i;
259
260   for (i= 0; i < count; i++)
261     {
262       b= (class cl_brk *)at(i);
263       if (b->type() == brkEVENT &&
264           ((class cl_ev_brk *)b)->event == ev)
265         return(DD_TRUE);
266     }
267   return(DD_FALSE);
268 }
269
270 int
271 brk_coll::make_new_nr(void)
272 {
273   if (count == 0)
274     return(1);
275   class cl_brk *b= (class cl_brk *)(at(count-1));
276   return(b->nr+1);
277 }
278
279 void
280 brk_coll::add_bp(class cl_brk *bp)
281 {
282   add(bp);
283   if (rom &&
284       bp->addr < rom->size)
285     rom->bp_map->set(bp->addr);
286 }
287
288 void
289 brk_coll::del_bp(t_addr addr)
290 {
291   int idx;
292
293   if (get_bp(addr, &idx))
294     free_at(idx);
295   if (rom &&
296       addr < rom->size)
297     rom->bp_map->clear(addr);
298 }
299
300 class cl_brk *
301 brk_coll::get_bp(t_addr addr, int *idx)
302 {
303   if (rom &&
304       addr < rom->size &&
305       rom->bp_map->get(addr))
306     {
307       for (*idx= 0; *idx < count; (*idx)++)
308         {
309           class cl_brk *b= (class cl_brk *)(at(*idx));
310           if (b->addr == addr)
311             return(b);
312         }
313     }
314   return(0);
315 }
316
317 bool
318 brk_coll::bp_at(t_addr addr)
319 {
320   return(rom &&
321          addr < rom->size &&
322          rom->bp_map->get(addr));
323 }
324
325
326 /* End of brk.cc */