b18b89f3d50d6ee81b2b602218ca5a9797ed1a2a
[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 #include <ctype.h>
32
33 #include "pobjcl.h"
34 #include "brkcl.h"
35
36
37 /*
38  * Base object of breakpoints
39  */
40
41 cl_brk::cl_brk(class cl_mem *imem, int inr, t_addr iaddr,
42                enum brk_perm iperm, int ihit):
43   cl_base()
44 {
45   mem  = imem;
46   nr   = inr;
47   addr = iaddr;
48   perm = iperm;
49   hit  = ihit;
50   cnt  = ihit;
51 }
52
53 cl_brk::~cl_brk(void)
54 {}
55
56 void
57 cl_brk::activate(void)
58 {
59   if (mem)
60     mem->set_brk(addr, this);
61 }
62
63 void
64 cl_brk::inactivate(void)
65 {
66   if (mem)
67     mem->del_brk(addr, this);
68 }
69
70 bool
71 cl_brk::do_hit(void)
72 {
73   cnt--;
74   if (cnt <= 0)
75     {
76       cnt= hit;
77       return(1);
78     }
79   return(0);
80 }
81
82
83 /*
84  * FETCH type of breakpoint
85  */
86
87 cl_fetch_brk::cl_fetch_brk(class cl_mem *imem, int inr, t_addr iaddr,
88                            enum brk_perm iperm, int ihit):
89   cl_brk(imem, inr, iaddr, iperm, ihit)
90 {
91   code = 0;
92 }
93
94 enum brk_type
95 cl_fetch_brk::type(void)
96 {
97   return(brkFETCH);
98 }
99
100
101 /*
102  * Base of EVENT type of breakpoints
103  */
104
105 cl_ev_brk::cl_ev_brk(class cl_mem *imem, int inr, t_addr iaddr,
106                      enum brk_perm iperm, int ihit,
107                      enum brk_event ievent, const char *iid):
108   cl_brk(imem, inr, iaddr, iperm, ihit)
109 {
110   event= ievent;
111   id   = iid;
112   mem  = imem;
113 }
114
115 cl_ev_brk::cl_ev_brk(class cl_mem *imem, int inr, t_addr iaddr,
116                      enum brk_perm iperm, int ihit, char op):
117   cl_brk(imem, inr, iaddr, iperm, ihit)
118 {
119   mem  = imem;
120   if ((op= toupper(op)) == 'R')
121     {
122       event= brkREAD;
123       id= "read";
124     }
125   else if (op == 'W')
126     {
127       event= brkWRITE;
128       id= "write";
129     }
130   else
131     {
132       event= brkACCESS;
133       id= "access";
134     }
135 }
136
137 enum brk_type
138 cl_ev_brk::type(void)
139 {
140   return(brkEVENT);
141 }
142
143 bool
144 cl_ev_brk::match(struct event_rec *ev)
145 {
146   return(DD_FALSE);
147 }
148
149
150 /*
151  * WRITE IRAM type of EVENT breakpoints
152  */
153
154 /*cl_wi_brk::cl_wi_brk(class cl_mem *imem, int inr, t_addr iaddr,
155                      enum brk_perm iperm, int ihit):
156   cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkWIRAM, "wi")
157 {}
158
159 bool
160 cl_wi_brk::match(struct event_rec *ev)
161 {
162   return(ev->wi == addr);
163 }*/
164
165
166 /*
167  * READ IRAM type of EVENT breakpoints
168  */
169
170 /*cl_ri_brk::cl_ri_brk(class cl_mem *imem, int inr, t_addr iaddr,
171                      enum brk_perm iperm, int ihit):
172   cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkRIRAM, "ri")
173 {}
174
175 bool
176 cl_ri_brk::match(struct event_rec *ev)
177 {
178   return(ev->ri == addr);
179 }*/
180
181
182 /*
183  * WRITE XRAM type of EVENT breakpoints
184  */
185
186 /*cl_wx_brk::cl_wx_brk(class cl_mem *imem, int inr, t_addr iaddr,
187                      enum brk_perm iperm, int ihit):
188   cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkWXRAM, "wx")
189 {}
190
191 bool
192 cl_wx_brk::match(struct event_rec *ev)
193 {
194   return(ev->wx == addr);
195 }*/
196
197
198 /*
199  * READ XRAM type of EVENT breakpoints
200  */
201
202 /*cl_rx_brk::cl_rx_brk(class cl_mem *imem, int inr, t_addr iaddr,
203                      enum brk_perm iperm, int ihit):
204   cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkRXRAM, "rx")
205 {}
206
207 bool
208 cl_rx_brk::match(struct event_rec *ev)
209 {
210   return(ev->rx == addr);
211 }*/
212
213
214 /*
215  * WRITE SFR type of EVENT breakpoints
216  */
217
218 /*cl_ws_brk::cl_ws_brk(class cl_mem *imem, int inr, t_addr iaddr,
219                      enum brk_perm iperm, int ihit):
220   cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkWSFR, "ws")
221 {}
222
223 bool
224 cl_ws_brk::match(struct event_rec *ev)
225 {
226   return(ev->ws == addr);
227 }*/
228
229
230 /*
231  * READ SFR type of EVENT breakpoints
232  */
233
234 /*cl_rs_brk::cl_rs_brk(class cl_mem *imem, int inr, t_addr iaddr,
235                      enum brk_perm iperm, int ihit):
236   cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkRSFR, "rs")
237 {}
238
239 bool
240 cl_rs_brk::match(struct event_rec *ev)
241 {
242   return(ev->rs == addr);
243 }*/
244
245
246 /*
247  * READ CODE type of EVENT breakpoints
248  */
249
250 /*cl_rc_brk::cl_rc_brk(class cl_mem *imem, int inr, t_addr iaddr,
251                      enum brk_perm iperm, int ihit):
252   cl_ev_brk(imem, inr, iaddr, iperm, ihit, brkRCODE, "rc")
253 {}
254
255 bool
256 cl_rc_brk::match(struct event_rec *ev)
257 {
258   return(ev->rc == addr);
259 }*/
260
261
262 /*
263  * Collection of break-points
264  *
265  * This is a sorted collection, sorted by nr field of brk items.
266  */
267
268 brk_coll::brk_coll(t_index alimit, t_index adelta, class cl_mem *arom):
269   cl_sorted_list(alimit, adelta)
270 {
271   rom= arom;
272 }
273
274 void *
275 brk_coll::key_of(void *item)
276 {
277   return((void *)&(((class cl_brk *)(item))->nr));
278 }
279
280
281 int
282 brk_coll::compare(void *key1, void *key2)
283 {
284   int k1, k2;
285
286   k1= *(int *)key1;
287   k2= *(int *)key2;
288
289   if (k1 == k2)
290     return(0);
291   else
292     if (k1 < k2)
293       return(-1);
294     else
295       return(+1);
296 }
297
298
299 /*
300  * Checking if there is an event breakpoint for the specified event
301  */
302
303 bool
304 brk_coll::there_is_event(enum brk_event ev)
305 {
306   class cl_brk *b;
307   int   i;
308
309   for (i= 0; i < count; i++)
310     {
311       b= (class cl_brk *)at(i);
312       if (b->type() == brkEVENT &&
313           ((class cl_ev_brk *)b)->event == ev)
314         return(DD_TRUE);
315     }
316   return(DD_FALSE);
317 }
318
319 /*int
320 brk_coll::make_new_nr(void)
321 {
322   if (count == 0)
323     return(1);
324   class cl_brk *b= (class cl_brk *)(at(count-1));
325   return(b->nr+1);
326 }*/
327
328 void
329 brk_coll::add_bp(class cl_brk *bp)
330 {
331   add(bp);
332   bp->activate();
333   return;
334   /*if (rom &&
335       bp->addr < rom->size)
336       / *rom->bp_map->set(bp->addr)* /rom->set_brk(bp->addr, bp);*/
337 }
338
339 void
340 brk_coll::del_bp(t_addr addr)
341 {
342   int idx;
343   class cl_brk *bp;
344
345   if ((bp= get_bp(addr, &idx)))
346     {
347       bp->inactivate();
348       free_at(idx);
349     }
350   return;
351   /*if (rom &&
352       addr < rom->size)
353     {
354       fprintf(stderr, "brk_coll::del_bp(0x%"_A_"x\n", addr);//FIXME
355       //rom->bp_map->clear(addr);
356       }*/
357 }
358
359 void
360 brk_coll::del_bp(t_index idx, int /*dummy*/)
361 {
362   class cl_brk *bp;
363
364   if (idx >= count)
365     return;
366   bp= (class cl_brk *)(at(idx));
367   if (!bp)
368     return;
369   bp->inactivate();
370   free_at(idx);
371 }
372
373 class cl_brk *
374 brk_coll::get_bp(t_addr addr, int *idx)
375 {
376   if (rom &&
377       addr < rom->size &&
378       /*rom->bp_map->get(addr)*/
379       rom->get_cell_flag(addr,  CELL_FETCH_BRK))
380     {
381       for (*idx= 0; *idx < count; (*idx)++)
382         {
383           class cl_brk *b= (class cl_brk *)(at(*idx));
384           if (b->addr == addr)
385             return(b);
386         }
387     }
388   return(0);
389 }
390
391 class cl_brk *
392 brk_coll::get_bp(int nr)
393 {
394   int i;
395
396   for (i= 0; i < count; i++)
397     {
398       class cl_brk *bp= (class cl_brk *)(at(i));
399       if (bp->nr == nr)
400         return(bp);
401     }
402   return(0);
403 }
404
405 bool
406 brk_coll::bp_at(t_addr addr)
407 {
408   return(rom &&
409          addr < rom->size &&
410          /*rom->bp_map->get(addr)*/
411          rom->get_cell_flag(addr, CELL_FETCH_BRK));
412 }
413
414
415 /* End of brk.cc */