2 * Simulator of microcontrollers (uc.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
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.
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.
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
48 #include "cmdstatcl.h"
62 cl_ticker::cl_ticker(int adir, int in_isr, char *aname)
72 cl_ticker::~cl_ticker(void) {}
75 cl_ticker::tick(int nr)
83 cl_ticker::get_rtime(double xtal)
87 d= (double)ticks/xtal;
92 cl_ticker::dump(int nr, double xtal, class cl_console *con)
94 con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n",
95 nr, get_name("unnamed"),
96 (options&TICK_RUN)?"ON":"OFF",
97 (options&TICK_INISR)?",ISR":"",
98 get_rtime(xtal), ticks);
103 * Abstract microcontroller
104 ******************************************************************************
107 cl_uc::cl_uc(class cl_sim *asim):
112 mems= new cl_list(MEM_TYPES, 1);
114 //options= new cl_list(2, 2);
115 for (i= MEM_ROM; i < MEM_TYPES; i++)
117 ticks= new cl_ticker(+1, 0, "time");
118 isr_ticks= new cl_ticker(+1, TICK_INISR, "isr");
119 idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle");
120 counters= new cl_list(2, 2);
121 it_levels= new cl_list(2, 2);
122 it_sources= new cl_irqs(2, 2);
123 class it_level *il= new it_level(-1, 0, 0, 0);
125 st_ops= new cl_list(2, 2);
126 errors= new cl_list(2, 2);
127 events= new cl_list(2, 2);
143 events->disconn_all();
161 if (!(sim->app->args->arg_avail('X')) ||
162 sim->app->args->get_farg('X', 0) == 0)
165 xtal= sim->app->args->get_farg('X', 0);
166 for (mc= MEM_ROM; mc < MEM_TYPES; mc++)
168 class cl_mem *m= mk_mem((enum mem_class)mc,
169 get_id_string(mem_classes, mc));
172 ebrk= new brk_coll(2, 2, /*(class cl_rom *)*/mem(MEM_ROM));
173 fbrk= new brk_coll(2, 2, /*(class cl_rom *)*/mem(MEM_ROM));
174 fbrk->Duplicates= DD_FALSE;
178 class cl_cmdset *cs= sim->app->get_commander()->cmdset;
181 for (i= 0; i < sim->app->in_files->count; i++)
183 char *fname= (char *)(sim->app->in_files->at(i));
185 if ((l= read_hex_file(fname)) >= 0)
187 sim->app->get_commander()->all_printf("%ld words read from %s\n",
195 cl_uc::id_string(void)
197 return("unknown microcontroller");
209 idle_ticks->ticks= 0;
210 /*FIXME should we clear user counters?*/
211 il= (class it_level *)(it_levels->top());
215 il= (class it_level *)(it_levels->pop());
217 il= (class it_level *)(it_levels->top());
223 for (i= 0; i < hws->count; i++)
225 class cl_hw *hw= (class cl_hw *)(hws->at(i));
235 cl_uc::mk_mem(enum mem_class type, char *class_name)
239 if (get_mem_size(type) < 0)
241 m= new cl_m(type, get_id_string(mem_classes, type),
242 get_mem_size(type), get_mem_width(type), this);
248 cl_uc::get_mem_size(enum mem_class type)
252 case MEM_ROM: return(0x10000);
253 case MEM_XRAM: return(0x10000);
254 case MEM_IRAM: return(0x80);
255 case MEM_SFR: return(0x100);
263 cl_uc::get_mem_width(enum mem_class type)
269 cl_uc::mk_hw_elements(void)
274 cl_uc::build_cmdset(class cl_cmdset *cmdset)
277 class cl_super_cmd *super_cmd;
278 class cl_cmdset *cset;
280 cmdset->add(cmd= new cl_state_cmd("state", 0,
281 "state State of microcontroller",
282 "long help of state"));
286 cmdset->add(cmd= new cl_statistic_cmd("statistic", 0,
287 "statistic [mem [startaddr [endaddr]]]\n"
288 " Statistic of memory accesses",
289 "long help of statistic"));
293 cmdset->add(cmd= new cl_file_cmd("file", 0,
294 "file \"FILE\" Load FILE into ROM",
295 "long help of file"));
297 cmd->add_name("load");
299 cmdset->add(cmd= new cl_dl_cmd("download", 0,
300 "download,dl Load (intel.hex) data",
301 "long help of download"));
305 cmdset->add(cmd= new cl_pc_cmd("pc", 0,
306 "pc [addr] Set/get PC",
310 cmdset->add(cmd= new cl_reset_cmd("reset", 0,
312 "long help of reset"));
315 cmdset->add(cmd= new cl_dump_cmd("dump", 0,
316 "dump memory_type [start [stop [bytes_per_line]]]\n"
317 " Dump memory of specified type\n"
318 "dump bit... Dump bits",
319 "long help of dump"));
322 cmdset->add(cmd= new cl_di_cmd("di", 0,
323 "di [start [stop]] Dump Internal RAM",
327 cmdset->add(cmd= new cl_dx_cmd("dx", 0,
328 "dx [start [stop]] Dump External RAM",
332 cmdset->add(cmd= new cl_ds_cmd("ds", 0,
333 "ds [start [stop]] Dump SFR",
337 cmdset->add(cmd= new cl_dch_cmd("dch", 0,
338 "dch [start [stop]] Dump code in hex form",
339 "long help of dch"));
342 cmdset->add(cmd= new cl_dc_cmd("dc", 0,
343 "dc [start [stop]] Dump code in disass form",
347 cmdset->add(cmd= new cl_disassemble_cmd("disassemble", 0,
348 "disassemble [start [offset [lines]]]\n"
350 "long help of disassemble"));
353 cmdset->add(cmd= new cl_fill_cmd("fill", 0,
354 "fill memory_type start end data\n"
355 " Fill memory region with data",
356 "long help of fill"));
359 cmdset->add(cmd= new cl_where_cmd("where", 0,
360 "where memory_type data...\n"
361 " Case unsensitive search for data",
362 "long help of where"));
365 cmdset->add(cmd= new cl_Where_cmd("Where", 0,
366 "Where memory_type data...\n"
367 " Case sensitive search for data",
368 "long help of Where"));
371 cmdset->add(cmd= new cl_break_cmd("break", 0,
372 "break addr [hit] Set fix breakpoint\n"
373 "break mem_type r|w addr [hit]\n"
374 " Set fix event breakpoint",
375 "long help of break"));
378 cmdset->add(cmd= new cl_tbreak_cmd("tbreak", 0,
379 "tbreak addr [hit] Set temporary breakpoint\n"
380 "tbreak mem_type r|w addr [hit]\n"
381 " Set temporary event breakpoint",
382 "long help of tbreak"));
385 cmdset->add(cmd= new cl_clear_cmd("clear", 0,
386 "clear [addr...] Clear fix breakpoint",
387 "long help of clear"));
390 cmdset->add(cmd= new cl_delete_cmd("delete", 0,
391 "delete [nr...] Delete breakpoint(s)",
392 "long help of clear"));
396 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("get"));
398 cset= super_cmd->commands;
400 cset= new cl_cmdset();
403 cset->add(cmd= new cl_get_sfr_cmd("sfr", 0,
404 "get sfr address...\n"
405 " Get value of addressed SFRs",
406 "long help of get sfr"));
408 /*cset->add(cmd= new cl_get_option_cmd("option", 0,
410 " Get value of an option",
411 "long help of get option"));
416 cmdset->add(cmd= new cl_super_cmd("get", 0,
417 "get subcommand Get, see `get' command for more help",
418 "long help of get", cset));
423 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("set"));
425 cset= super_cmd->commands;
427 cset= new cl_cmdset();
430 cset->add(cmd= new cl_set_mem_cmd("memory", 0,
431 "set memory memory_type address data...\n"
432 " Place list of data into memory",
433 "long help of set memory"));
435 cset->add(cmd= new cl_set_bit_cmd("bit", 0,
436 "set bit addr 0|1 Set specified bit to 0 or 1",
437 "long help of set bit"));
439 cset->add(cmd= new cl_set_hw_cmd("hardware", 0,
440 "set hardware cathegory params...\n"
441 " Set parameters of specified hardware element",
442 "long help of set hardware"));
448 cmdset->add(cmd= new cl_super_cmd("set", 0,
449 "set subcommand Set, see `set' command for more help",
450 "long help of set", cset));
455 cset= new cl_cmdset();
457 cset->add(cmd= new cl_info_bp_cmd("breakpoints", 0,
458 "info breakpoints Status of user-settable breakpoints",
459 "long help of info breakpoints"));
462 cset->add(cmd= new cl_info_reg_cmd("registers", 0,
463 "info registers List of integer registers and their contents",
464 "long help of info registers"));
466 cset->add(cmd= new cl_info_hw_cmd("hardware", 0,
467 "info hardware cathegory\n"
468 " Status of hardware elements of the CPU",
469 "long help of info hardware"));
473 cmdset->add(cmd= new cl_super_cmd("info", 0,
474 "info subcommand Information, see `info' command for more help",
475 "long help of info", cset));
478 cmdset->add(cmd= new cl_timer_cmd("timer", 0,
479 "timer a|d|g|r|s|v id [direction|value]\n"
480 " Timer add|del|get|run|stop|value",
481 "timer add|create|make id [direction] -- create a new timer\n"
482 "timer del id -- delete a timer\n"
483 "timer get id -- list timers\n"
484 "timer run id -- turn a timer ON\n"
485 "timer stop id -- turn a timer OFF\n"
486 "timer value id val -- set value of a timer to `val'"));
492 * Read/write simulated memory
496 cl_uc::read_mem(enum mem_class type, t_addr addr)
500 if ((m= (class cl_mem*)mems->at(type)) == 0)
501 m= (class cl_mem*)(mems->at(MEM_DUMMY));
502 return(m->read(addr));
506 cl_uc::get_mem(enum mem_class type, t_addr addr)
510 if ((m= (class cl_mem*)mems->at(type)) == 0)
511 m= (class cl_mem*)(mems->at(MEM_DUMMY));
512 return(m->get(addr));
516 cl_uc::write_mem(enum mem_class type, t_addr addr, t_mem val)
520 if ((m= (class cl_mem*)mems->at(type)) == 0)
521 m= (class cl_mem*)(mems->at(MEM_DUMMY));
526 cl_uc::set_mem(enum mem_class type, t_addr addr, t_mem val)
530 if ((m= (class cl_mem*)mems->at(type)) == 0)
531 m= (class cl_mem*)(mems->at(MEM_DUMMY));
536 cl_uc::mem(enum mem_class type)
540 if (mems->count < type)
541 m= (class cl_mem *)(mems->at(MEM_DUMMY));
543 m= (class cl_mem *)(mems->at(type));
548 cl_uc::mem(char *class_name)
555 s= n= strdup(class_name);
564 for (i= 0; !found && i < mems->count; i++)
566 cl_mem *m= (cl_mem *)(mems->at(i));
571 s= mcn= strdup(m->class_name);
577 if (strstr(/*m->class_name*/mcn,/*class_name*/n) == /*m->class_name*/mcn)
591 ReadInt(FILE *f, bool *ok, int bytes)
599 if (fscanf(f, "%2c", &s2[0]) == EOF)
602 l= l*256 + strtol(s2, NULL, 16);
611 * Reading intel hexa file into EROM
612 *____________________________________________________________________________
614 * If parameter is a NULL pointer, this function reads data from `cmd_in'
619 cl_uc::read_hex_file(const char *nam)
623 long written= 0, recnum= 0;
625 uchar dnum; // data number
626 uchar rtyp=0; // record type
627 uint addr= 0; // address
628 uchar rec[300]; // data record
629 uchar sum ; // checksum
637 sim->app->get_commander()->
638 dd_printf("cl_uc::read_hex_file File name not specified\n");
642 if ((f= fopen(nam, "r")) == NULL)
644 fprintf(stderr, "Can't open `%s': %s\n", nam, strerror(errno));
648 //memset(inst_map, '\0', sizeof(inst_map));
653 while (((c= getc(f)) != ':') &&
656 {fprintf(stderr, ": not found\n");break;}
658 dnum= ReadInt(f, &ok, 1);//printf("dnum=%02x",dnum);
660 addr= ReadInt(f, &ok, 2);//printf("addr=%04x",addr);
662 chk+= ((addr >> 8) & 0xff);
663 rtyp= ReadInt(f, &ok, 1);//printf("rtyp=%02x ",rtyp);
665 for (i= 0; ok && (i < dnum); i++)
667 rec[i]= ReadInt(f, &ok, 1);//printf("%02x",rec[i]);
672 sum= ReadInt(f, &ok, 1);//printf(" sum=%02x\n",sum);
675 if (((sum + chk) & 0xff) == 0)
679 if (get_mem_width(MEM_ROM) > 8)
681 for (i= 0; i < dnum; i++)
683 if (get_mem_width(MEM_ROM) <= 8)
685 set_mem(MEM_ROM, addr, rec[i]);
689 else if (get_mem_width(MEM_ROM) <= 16)
699 set_mem(MEM_ROM, addr, (high*256)+low);
708 if (sim->app->args->get_iarg('V', 0) &&
710 sim->app->get_commander()->
711 dd_printf("Unknown record type %d(0x%x)\n", rtyp, rtyp);
714 if (sim->app->args->get_iarg('V', 0))
715 sim->app->get_commander()->
716 dd_printf("Checksum error (%x instead of %x) in "
717 "record %ld.\n", chk, sum, recnum);
720 if (sim->app->args->get_iarg('V', 0))
721 sim->app->get_commander()->
722 dd_printf("Read error in record %ld.\n", recnum);
725 if (get_mem_width(MEM_ROM) > 8 &&
727 set_mem(MEM_ROM, addr, low);
731 if (sim->app->args->get_iarg('V', 0))
732 sim->app->get_commander()->dd_printf("%ld records have been read\n", recnum);
739 * Handling instruction map
741 * `inst_at' is checking if the specified address is in instruction
742 * map and `set_inst_at' marks the address in the map and
743 * `del_inst_at' deletes the mark. `there_is_inst' cheks if there is
744 * any mark in the map
748 cl_uc::inst_at(t_addr addr)
750 class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
754 //return(rom->inst_map->get(addr));
755 return(rom->get_cell_flag(addr, CELL_INST));
759 cl_uc::set_inst_at(t_addr addr)
761 class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
764 //rom->inst_map->set(addr);
765 rom->set_cell_flag(addr, DD_TRUE, CELL_INST);
769 cl_uc::del_inst_at(t_addr addr)
771 class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
774 //rom->inst_map->clear(addr);
775 rom->set_cell_flag(addr, DD_FALSE, CELL_INST);
779 cl_uc::there_is_inst(void)
781 class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
785 //return(!(rom->inst_map->empty()));
788 for (addr= 0; addr < rom->size && !got; addr++)
789 got= rom->get_cell_flag(addr, CELL_INST);
795 * Manipulating HW elements of the CPU
796 *****************************************************************************
799 /* Register callback hw objects for mem read/write */
802 cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw)
807 if ((m= (class cl_mem*)mems->at(type)))
809 if ((l= m->read_locs->get_loc(addr)) == 0)
811 l= new cl_memloc(addr);
813 m->read_locs->add(l);
818 printf("cl_uc::register_hw_read TROUBLE\n");
822 cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw)
826 /* Looking for a specific HW element */
829 cl_uc::get_hw(enum hw_cath cath, int *idx)
836 for (; i < hws->count; i++)
838 hw= (class cl_hw *)(hws->at(i));
839 if (hw->cathegory == cath)
850 cl_uc::get_hw(char *id_string, int *idx)
857 for (; i < hws->count; i++)
859 hw= (class cl_hw *)(hws->at(i));
860 if (strstr(hw->id_string, id_string) == hw->id_string)
871 cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx)
878 hw= get_hw(cath, &i);
883 hw= get_hw(cath, &i);
892 cl_uc::get_hw(char *id_string, int hwid, int *idx)
899 hw= get_hw(id_string, &i);
904 hw= get_hw(id_string, &i);
914 * Help of the command interpreter
920 static struct dis_entry empty= { 0, 0, 0, 0, NULL };
927 static struct name_entry empty= { 0, 0 };
934 static struct name_entry empty= { 0, 0 };
939 cl_uc::disass(t_addr addr, char *sep)
943 buf= (char*)malloc(100);
944 strcpy(buf, "uc::disass() unimplemented\n");
949 cl_uc::print_disass(t_addr addr, class cl_console *con)
954 class cl_mem *rom= mem(MEM_ROM);
955 t_mem code= get_mem(MEM_ROM, addr);
960 dis= disass(addr, NULL);
962 con->dd_printf("%c", (b->perm == brkFIX)?'F':'D');
965 con->dd_printf("%c ", inst_at(addr)?' ':'?');
966 con->dd_printf(rom->addr_format, addr); con->dd_printf(" ");
967 con->dd_printf(rom->data_format, code);
968 for (i= 1; i < inst_length(addr); i++)
971 con->dd_printf(rom->data_format, get_mem(MEM_ROM, addr+i));
973 int li= longest_inst();
977 j= rom->width/4 + ((rom->width%4)?1:0) + 1;
979 con->dd_printf(" "), j--;
982 con->dd_printf(" %s\n", dis);
987 cl_uc::print_regs(class cl_console *con)
989 con->dd_printf("No registers\n");
993 cl_uc::inst_length(t_addr addr)
995 struct dis_entry *tabl= dis_tbl();
999 code = get_mem(MEM_ROM, addr);
1000 for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ;
1001 return(tabl[i].mnemonic?tabl[i].length:1);
1005 cl_uc::inst_branch(t_addr addr)
1007 struct dis_entry *tabl= dis_tbl();
1011 code = get_mem(MEM_ROM, addr);
1012 for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
1014 return tabl[i].branch;
1018 cl_uc::longest_inst(void)
1020 struct dis_entry *de= dis_tbl();
1026 if (de->length > max)
1034 cl_uc::get_name(t_addr addr, struct name_entry tab[], char *buf)
1039 while (tab[i].name &&
1040 (!(tab[i].cpu_type & type) ||
1041 (tab[i].addr != addr)))
1044 strcpy(buf, tab[i].name);
1045 return(tab[i].name != NULL);
1049 cl_uc::symbolic_bit_name(t_addr bit_address,
1058 while (bit_tbl()[i].name &&
1059 (bit_tbl()[i].addr != bit_address))
1061 if (bit_tbl()[i].name)
1063 sym_name= strdup(bit_tbl()[i].name);
1069 strstr(mem->class_name, "sfr") == mem->class_name)
1072 while (sfr_tbl()[i].name &&
1073 (sfr_tbl()[i].addr != mem_addr))
1075 if (sfr_tbl()[i].name)
1076 sym_name= strdup(sfr_tbl()[i].name);
1082 sym_name= (char *)malloc(16);
1083 sprintf(sym_name, mem?(mem->addr_format):"0x%06x", mem_addr);
1085 sym_name= (char *)realloc(sym_name, strlen(sym_name)+2);
1086 strcat(sym_name, ".");
1088 while (bit_mask > 1)
1094 sprintf(bitnumstr, "%1d", i);
1095 strcat(sym_name, bitnumstr);
1101 * Messages to broadcast
1105 cl_uc::mem_cell_changed(class cl_mem *mem, t_addr addr)
1108 hws->mem_cell_changed(mem, addr);
1110 printf("JAJ uc\n");//FIXME
1115 for (i= 0; i < mems->count; i++)
1127 cl_uc::error(class cl_error *error)
1130 if ((error->inst= inst_exec))
1135 cl_uc::check_errors(void)
1138 class cl_commander *c= sim->app->get_commander();
1142 for (i= 0; i < errors->count; i++)
1144 class cl_error *error= (class cl_error *)(errors->at(i));
1148 class cl_console *con;
1149 con= c->actual_console;
1151 con= c->frozen_console;
1153 print_disass(error->PC, con);
1159 fprintf(stderr, "no actual console, %d errors\n", errors->count);
1164 * Converting bit address into real memory
1168 cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask)
1173 *bitmask= 1 << (bitaddr & 0x7);
1174 return(0); // abstract...
1183 cl_uc::tick_hw(int cycles)
1186 int i;//, cpc= clock_per_cycle();
1189 for (i= 0; i < hws->count; i++)
1191 hw= (class cl_hw *)(hws->at(i));
1192 if (hw->flags & HWF_INSIDE)
1195 do_extra_hw(cycles);
1200 cl_uc::do_extra_hw(int cycles)
1204 cl_uc::tick(int cycles)
1207 int i, cpc= clock_per_cycle();
1210 ticks->tick(cycles * cpc);
1211 class it_level *il= (class it_level *)(it_levels->top());
1213 isr_ticks->tick(cycles * cpc);
1214 if (state == stIDLE)
1215 idle_ticks->tick(cycles * cpc);
1216 for (i= 0; i < counters->count; i++)
1218 class cl_ticker *t= (class cl_ticker *)(counters->at(i));
1221 if ((t->options&TICK_INISR) ||
1223 t->tick(cycles * cpc);
1227 // tick for hardwares
1228 inst_ticks+= cycles;
1233 cl_uc::get_counter(int nr)
1235 if (nr >= counters->count)
1237 return((class cl_ticker *)(counters->at(nr)));
1241 cl_uc::get_counter(char *nam)
1247 for (i= 0; i < counters->count; i++)
1249 class cl_ticker *t= (class cl_ticker *)(counters->at(i));
1252 strcmp(t->get_name(), nam) == 0)
1259 cl_uc::add_counter(class cl_ticker *ticker, int nr)
1261 while (counters->count <= nr)
1263 counters->put_at(nr, ticker);
1267 cl_uc::add_counter(class cl_ticker *ticker, char */*nam*/)
1271 if (counters->count < 1)
1273 for (i= 1; i < counters->count; i++)
1275 class cl_ticker *t= (class cl_ticker *)(counters->at(i));
1278 counters->put_at(i, ticker);
1282 counters->add(ticker);
1286 cl_uc::del_counter(int nr)
1290 if (nr >= counters->count)
1292 if ((t= (class cl_ticker *)(counters->at(0))) != 0)
1294 counters->put_at(nr, 0);
1298 cl_uc::del_counter(char *nam)
1304 for (i= 0; i < counters->count; i++)
1306 class cl_ticker *t= (class cl_ticker *)(counters->at(i));
1309 strcmp(t->get_name(), nam) == 0)
1312 counters->put_at(i, 0);
1319 * Fetch without checking for breakpoint hit
1327 code= read_mem(MEM_ROM, PC);
1329 if (PC >= get_mem_size(MEM_ROM))
1335 * Fetch but checking for breakpoint hit first, returns TRUE if
1336 * a breakpoint is hit
1340 cl_uc::fetch(t_mem *code)
1347 if (sim->state & SIM_GO)
1349 if (mem(MEM_ROM)->get_cell_flag(PC, CELL_FETCH_BRK) &&
1350 (brk= fbrk->get_bp(PC, &idx)) &&
1353 if (brk->perm == brkDYNAMIC)
1363 cl_uc::do_inst(int step)
1382 cl_uc::pre_inst(void)
1386 events->disconn_all();
1390 cl_uc::exec_inst(void)
1397 cl_uc::post_inst(void)
1399 tick_hw(inst_ticks);
1404 inst_exec= DD_FALSE;
1409 * Time related functions
1413 cl_uc::get_rtime(void)
1417 d= (double)ticks/xtal;
1419 return(ticks->get_rtime(xtal));
1423 cl_uc::clock_per_cycle(void)
1430 * Stack tracking system
1434 cl_uc::st_push(class cl_stack_op *op)
1440 cl_uc::st_call(class cl_stack_op *op)
1446 cl_uc::st_pop(class cl_stack_op *op)
1448 class cl_stack_op *sop= (class cl_stack_op *)(st_ops->pop());
1456 cl_uc::st_ret(class cl_stack_op *op)
1458 class cl_stack_op *sop= (class cl_stack_op *)(st_ops->pop());
1467 * Breakpoint handling
1470 class cl_fetch_brk *
1471 cl_uc::fbrk_at(t_addr addr)
1475 return((class cl_fetch_brk *)(fbrk->get_bp(addr, &idx)));
1479 cl_uc::ebrk_at(t_addr addr, char *id)
1482 class cl_ev_brk *eb;
1484 for (i= 0; i < ebrk->count; i++)
1486 eb= (class cl_ev_brk *)(ebrk->at(i));
1487 if (eb->addr == addr &&
1488 !strcmp(eb->id, id))
1495 cl_uc::rm_fbrk(long addr)
1500 /* Get a breakpoint specified by its number */
1503 cl_uc::brk_by_nr(int nr)
1507 if ((bp= fbrk->get_bp(nr)))
1509 if ((bp= ebrk->get_bp(nr)))
1514 /* Get a breakpoint from the specified collection by its number */
1517 cl_uc::brk_by_nr(class brk_coll *bpcoll, int nr)
1521 if ((bp= bpcoll->get_bp(nr)))
1526 /* Remove an event breakpoint specified by its address and id */
1529 cl_uc::rm_ebrk(t_addr addr, char *id)
1532 class cl_ev_brk *eb;
1534 for (i= 0; i < ebrk->count; i++)
1536 eb= (class cl_ev_brk *)(ebrk->at(i));
1537 if (eb->addr == addr &&
1538 !strcmp(eb->id, id))
1543 /* Remove a breakpoint specified by its number */
1546 cl_uc::rm_brk(int nr)
1550 if ((bp= brk_by_nr(fbrk, nr)))
1552 fbrk->del_bp(bp->addr);
1555 else if ((bp= brk_by_nr(ebrk, nr)))
1557 ebrk->del_bp(ebrk->index_of(bp), 0);
1564 cl_uc::put_breaks(void)
1567 /* Remove all fetch and event breakpoints */
1570 cl_uc::remove_all_breaks(void)
1574 class cl_brk *brk= (class cl_brk *)(fbrk->at(0));
1575 fbrk->del_bp(brk->addr);
1578 ebrk->del_bp(ebrk->count-1, 0);
1582 cl_uc::make_new_brknr(void)
1584 if (brk_counter == 0)
1585 return(brk_counter= 1);
1586 if (fbrk->count == 0 &&
1588 return(brk_counter= 1);
1589 return(++brk_counter);
1593 cl_uc::mk_ebrk(enum brk_perm perm, class cl_mem *mem,
1594 char op, t_addr addr, int hit)
1599 b= new cl_ev_brk(mem, make_new_brknr(), addr, perm, hit, op);
1605 cl_uc::check_events(void)
1607 sim->stop(resBREAKPOINT);