19c3e767525fce837a58af706f1440c49d0bd8de
[fw/sdcc] / sim / ucsim / cmd.src / bp.cc
1 /*
2  * Simulator of microcontrollers (cmd.src/bp.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 "stdlib.h"
31
32 // sim
33 #include "brkcl.h"
34 #include "argcl.h"
35 #include "simcl.h"
36
37 // cmd
38 #include "cmdsetcl.h"
39 #include "bpcl.h"
40
41
42 /*
43  * BREAK command
44  */
45
46 //int
47 //cl_break_cmd::do_work(class cl_sim *sim,
48 //                    class cl_cmdline *cmdline, class cl_console *con)
49 COMMAND_DO_WORK_UC(cl_break_cmd)
50 {
51   t_addr addr= 0;
52   int hit= 1;
53   char op;
54   class cl_mem *mem;
55   class cl_cmd_arg *params[4]= { cmdline->param(0),
56                                  cmdline->param(1),
57                                  cmdline->param(2),
58                                  cmdline->param(3) };
59
60   if (cmdline->syntax_match(uc, ADDRESS)) {
61     addr= params[0]->value.address;
62     hit= 1;
63     do_fetch(uc, addr, hit, con);
64   }
65   else if (cmdline->syntax_match(uc, ADDRESS NUMBER)) {
66     addr= params[0]->value.address;
67     hit= params[1]->value.number;
68     do_fetch(uc, addr, hit, con);
69   }
70   else if (cmdline->syntax_match(uc, MEMORY STRING ADDRESS)) {
71     mem= params[0]->value.memory;
72     op= *(params[1]->get_svalue());
73     addr= params[2]->value.address;
74     hit= 1;
75     do_event(uc, mem, op, addr, hit, con);
76   }
77   else if (cmdline->syntax_match(uc, MEMORY STRING ADDRESS NUMBER)) {
78     mem= params[0]->value.memory;
79     op= *(params[1]->get_svalue());
80     addr= params[2]->value.address;
81     hit= params[3]->value.number;
82     do_event(uc, mem, op, addr, hit, con);
83   }
84   else
85     {
86       con->printf("%s\n", short_help?short_help:"Error: wrong syntax\n");
87       return(DD_FALSE);
88     }
89   return(DD_FALSE);
90 }
91
92 void
93 cl_break_cmd::do_fetch(class cl_uc *uc,
94                        t_addr addr, int hit, class cl_console *con)
95 {
96   if (hit > 99999)
97     {
98       con->printf("Hit value %d is too big.\n", hit);
99       return;
100     }
101   if (uc->fbrk->bp_at(addr))
102     con->printf("Breakpoint at 0x%06x is already set.\n", addr);
103   else
104     {
105       class cl_brk *b= new cl_fetch_brk(uc->make_new_brknr(),
106                                         addr, perm, hit);
107       b->init();
108       uc->fbrk->add_bp(b);
109       char *s= uc->disass(addr, NULL);
110       con->printf("Breakpoint %d at 0x%06x: %s\n", b->nr, addr, s);
111       free(s);
112     }
113 }
114
115 void
116 cl_break_cmd::do_event(class cl_uc *uc,
117                        class cl_mem *mem, char op, t_addr addr, int hit,
118                        class cl_console *con)
119 {
120   class cl_ev_brk *b= NULL;
121
122   b= uc->mk_ebrk(perm, mem, op, addr, hit);
123   if (b)
124     uc->ebrk->add_bp(b);
125   else
126     con->printf("Couldn't make event breakpoint\n");
127 }
128
129
130 /*
131  * CLEAR address
132  */
133
134 //int
135 //cl_clear_cmd::do_work(class cl_sim *sim,
136 //                    class cl_cmdline *cmdline, class cl_console *con)
137 COMMAND_DO_WORK_UC(cl_clear_cmd)
138 {
139   int idx;
140   class cl_brk *brk= uc->fbrk->get_bp(uc->PC, &idx);
141
142   if (cmdline->param(0) == 0)
143     {
144       if (!brk)
145         {
146           con->printf("No breakpoint at this address.\n");
147           return(0);
148         }
149       uc->fbrk->del_bp(uc->PC);
150       return(0);
151     }
152
153   int i= 0;
154   class cl_cmd_arg *param;
155   while ((param= cmdline->param(i++)))
156     {
157       t_addr addr;
158       if (!param->as_address(uc))
159         return(DD_FALSE);
160       addr= param->value.address;
161       if (uc->fbrk->bp_at(addr) == 0)
162         con->printf("No breakpoint at 0x%06x\n", addr);
163       else
164         uc->fbrk->del_bp(addr);
165     }
166
167   return(DD_FALSE);
168 }
169
170
171 /*
172  * DELETE nr nr ...
173  */
174
175 //int
176 //cl_delete_cmd::do_work(class cl_sim *sim,
177 //                     class cl_cmdline *cmdline, class cl_console *con)
178 COMMAND_DO_WORK_UC(cl_delete_cmd)
179 {
180   if (cmdline->param(0) == 0)
181     {
182       // delete all
183       uc->remove_all_breaks();
184     }
185   else
186     {
187       int i= 0;
188       class cl_cmd_arg *param;
189       while ((param= cmdline->param(i++)))
190         {
191           long num;
192           if (param->get_ivalue(&num))
193             uc->rm_brk(num);
194         }
195     }
196   return(DD_FALSE);
197 }
198
199
200 /* End of cmd.src/bp.cc */