Imported Upstream version 2.9.0
[debian/cc1111] / 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_address_space *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_address_space *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_address_space *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_address_space *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  * Collection of break-points
152  *
153  * This is a sorted collection, sorted by nr field of brk items.
154  */
155
156 brk_coll::brk_coll(t_index alimit, t_index adelta,
157                    class cl_address_space *arom):
158   cl_sorted_list(alimit, adelta, "breakpoints")
159 {
160   rom= arom;
161 }
162
163 const void *
164 brk_coll::key_of(void *item)
165 {
166   return((void *)&(((class cl_brk *)(item))->nr));
167 }
168
169
170 int
171 brk_coll::compare(const void *key1, const void *key2)
172 {
173   int k1, k2;
174
175   k1= *(int *)key1;
176   k2= *(int *)key2;
177
178   if (k1 == k2)
179     return(0);
180   else
181     if (k1 < k2)
182       return(-1);
183     else
184       return(+1);
185 }
186
187
188 /*
189  * Checking if there is an event breakpoint for the specified event
190  */
191
192 bool
193 brk_coll::there_is_event(enum brk_event ev)
194 {
195   class cl_brk *b;
196   int   i;
197
198   for (i= 0; i < count; i++)
199     {
200       b= (class cl_brk *)at(i);
201       if (b->type() == brkEVENT &&
202           ((class cl_ev_brk *)b)->event == ev)
203         return(DD_TRUE);
204     }
205   return(DD_FALSE);
206 }
207
208 /*int
209 brk_coll::make_new_nr(void)
210 {
211   if (count == 0)
212     return(1);
213   class cl_brk *b= (class cl_brk *)(at(count-1));
214   return(b->nr+1);
215 }*/
216
217 void
218 brk_coll::add_bp(class cl_brk *bp)
219 {
220   add(bp);
221   bp->activate();
222   return;
223   /*if (rom &&
224       bp->addr < rom->size)
225       / *rom->bp_map->set(bp->addr)* /rom->set_brk(bp->addr, bp);*/
226 }
227
228 void
229 brk_coll::del_bp(t_addr addr)
230 {
231   int idx;
232   class cl_brk *bp;
233
234   if ((bp= get_bp(addr, &idx)))
235     {
236       bp->inactivate();
237       free_at(idx);
238     }
239   return;
240   /*if (rom &&
241       addr < rom->size)
242     {
243       fprintf(stderr, "brk_coll::del_bp(0x%"_A_"x\n", addr);//FIXME
244       //rom->bp_map->clear(addr);
245       }*/
246 }
247
248 void
249 brk_coll::del_bp(t_index idx, int /*dummy*/)
250 {
251   class cl_brk *bp;
252
253   if (idx >= count)
254     return;
255   bp= (class cl_brk *)(at(idx));
256   if (!bp)
257     return;
258   bp->inactivate();
259   free_at(idx);
260 }
261
262 class cl_brk *
263 brk_coll::get_bp(t_addr addr, int *idx)
264 {
265   if (rom &&
266       rom->valid_address(addr) &&
267       rom->get_cell_flag(addr, CELL_FETCH_BRK))
268     {
269       for (*idx= 0; *idx < count; (*idx)++)
270         {
271           class cl_brk *b= (class cl_brk *)(at(*idx));
272           if (b->addr == addr)
273             return(b);
274         }
275     }
276   return(0);
277 }
278
279 class cl_brk *
280 brk_coll::get_bp(int nr)
281 {
282   int i;
283
284   for (i= 0; i < count; i++)
285     {
286       class cl_brk *bp= (class cl_brk *)(at(i));
287       if (bp->nr == nr)
288         return(bp);
289     }
290   return(0);
291 }
292
293 bool
294 brk_coll::bp_at(t_addr addr)
295 {
296   return(rom &&
297          rom->valid_address(addr) &&
298          rom->get_cell_flag(addr, CELL_FETCH_BRK));
299 }
300
301
302 /* End of brk.cc */