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"
59 static class cl_uc_error_registry uc_error_registry;
65 cl_ticker::cl_ticker(int adir, int in_isr, const char *aname)
75 cl_ticker::~cl_ticker(void) {}
78 cl_ticker::tick(int nr)
86 cl_ticker::get_rtime(double xtal)
90 d= (double)ticks/xtal;
95 cl_ticker::dump(int nr, double xtal, class cl_console_base *con)
97 con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n",
98 nr, get_name("unnamed"),
99 (options&TICK_RUN)?"ON":"OFF",
100 (options&TICK_INISR)?",ISR":"",
101 get_rtime(xtal), ticks);
109 cl_xtal_option::cl_xtal_option(class cl_uc *the_uc):
116 cl_xtal_option::option_changed(void)
121 option->get_value(&d);
127 * Abstract microcontroller
128 ******************************************************************************
131 cl_uc::cl_uc(class cl_sim *asim):
136 //mems= new cl_list(MEM_TYPES, 1);
137 memchips= new cl_list(2, 2, "memchips");
138 address_spaces= new cl_address_space_list(this);
139 //address_decoders= new cl_list(2, 2);
143 //options= new cl_list(2, 2);
144 //for (i= MEM_ROM; i < MEM_TYPES; i++) mems->add(0);
145 xtal_option= new cl_xtal_option(this);
147 ticks= new cl_ticker(+1, 0, "time");
148 isr_ticks= new cl_ticker(+1, TICK_INISR, "isr");
149 idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle");
150 counters= new cl_list(2, 2, "counters");
151 it_levels= new cl_list(2, 2, "it levels");
152 it_sources= new cl_irqs(2, 2);
153 class it_level *il= new it_level(-1, 0, 0, 0);
155 stack_ops= new cl_list(2, 2, "stack operations");
156 errors= new cl_list(2, 2, "errors in uc");
157 events= new cl_list(2, 2, "events in uc");
173 events->disconn_all();
183 delete address_spaces;
185 //delete address_decoders;
194 set_name("controller");
196 if (xtal_option->use("xtal"))
197 xtal= xtal_option->get_value(xtal);
201 rom= address_space(MEM_ROM_ID);
202 ebrk= new brk_coll(2, 2, rom);
203 fbrk= new brk_coll(2, 2, rom);
204 fbrk->Duplicates= DD_FALSE;
208 class cl_cmdset *cs= sim->app->get_commander()->cmdset;
211 for (i= 0; i < sim->app->in_files->count; i++)
213 char *fname= (char *)(sim->app->in_files->at(i));
215 if ((l= read_hex_file(fname)) >= 0)
217 sim->app->get_commander()->all_printf("%ld words read from %s\n",
225 cl_uc::id_string(void)
227 return("unknown microcontroller");
239 idle_ticks->ticks= 0;
240 /*FIXME should we clear user counters?*/
241 il= (class it_level *)(it_levels->top());
245 il= (class it_level *)(it_levels->pop());
247 il= (class it_level *)(it_levels->top());
252 stack_ops->free_all();
255 for (i= 0; i < hws->count; i++)
257 class cl_hw *hw= (class cl_hw *)(hws->at(i));
267 cl_uc::make_memories(void)
271 cl_uc::get_mem_size(char *id)
273 class cl_memory *m= memory(id);
274 return(m?(m->get_size()):0);
278 cl_uc::get_mem_width(char *id)
280 class cl_memory *m= memory(id);
281 return(m?(m->width):8);
285 cl_uc::mk_hw_elements(void)
290 cl_uc::build_cmdset(class cl_cmdset *cmdset)
293 class cl_super_cmd *super_cmd;
294 class cl_cmdset *cset;
296 cmdset->add(cmd= new cl_state_cmd("state", 0,
297 "state State of microcontroller",
298 "long help of state"));
302 cmdset->add(cmd= new cl_statistic_cmd("statistic", 0,
303 "statistic [mem [startaddr [endaddr]]]\n"
304 " Statistic of memory accesses",
305 "long help of statistic"));
309 cmdset->add(cmd= new cl_file_cmd("file", 0,
310 "file \"FILE\" Load FILE into ROM",
311 "long help of file"));
313 cmd->add_name("load");
315 cmdset->add(cmd= new cl_dl_cmd("download", 0,
316 "download Load (intel.hex) data",
317 "long help of download"));
321 cmdset->add(cmd= new cl_pc_cmd("pc", 0,
322 "pc [addr] Set/get PC",
326 cmdset->add(cmd= new cl_reset_cmd("reset", 0,
328 "long help of reset"));
331 cmdset->add(cmd= new cl_dump_cmd("dump", DD_TRUE,
332 "dump memory_type [start [stop [bytes_per_line]]]\n"
333 " Dump memory of specified type\n"
334 "dump bit... Dump bits",
335 "long help of dump"));
338 cmdset->add(cmd= new cl_dch_cmd("dch", DD_TRUE,
339 "dch [start [stop]] Dump code in hex form",
340 "long help of dch"));
343 cmdset->add(cmd= new cl_dc_cmd("dc", DD_TRUE,
344 "dc [start [stop]] Dump code in disass form",
348 cmdset->add(cmd= new cl_disassemble_cmd("disassemble", DD_TRUE,
349 "disassemble [start [offset [lines]]]\n"
351 "long help of disassemble"));
354 cmdset->add(cmd= new cl_fill_cmd("fill", 0,
355 "fill memory_type start end data\n"
356 " Fill memory region with data",
357 "long help of fill"));
360 cmdset->add(cmd= new cl_where_cmd("where", 0,
361 "where memory_type data...\n"
362 " Case unsensitive search for data",
363 "long help of where"));
366 cmdset->add(cmd= new cl_Where_cmd("Where", 0,
367 "Where memory_type data...\n"
368 " Case sensitive search for data",
369 "long help of Where"));
372 cmdset->add(cmd= new cl_break_cmd("break", 0,
373 "break addr [hit] Set fix breakpoint\n"
374 "break mem_type r|w addr [hit]\n"
375 " Set fix event breakpoint",
376 "long help of break"));
379 cmdset->add(cmd= new cl_tbreak_cmd("tbreak", 0,
380 "tbreak addr [hit] Set temporary breakpoint\n"
381 "tbreak mem_type r|w addr [hit]\n"
382 " Set temporary event breakpoint",
383 "long help of tbreak"));
386 cmdset->add(cmd= new cl_clear_cmd("clear", 0,
387 "clear [addr...] Clear fix breakpoint",
388 "long help of clear"));
391 cmdset->add(cmd= new cl_delete_cmd("delete", 0,
392 "delete [nr...] Delete breakpoint(s)",
393 "long help of clear"));
397 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("get"));
399 cset= super_cmd->commands;
401 cset= new cl_cmdset();
404 cset->add(cmd= new cl_get_sfr_cmd("sfr", 0,
405 "get sfr address...\n"
406 " Get value of addressed SFRs",
407 "long help of get sfr"));
409 /*cset->add(cmd= new cl_get_option_cmd("option", 0,
411 " Get value of an option",
412 "long help of get option"));
417 cmdset->add(cmd= new cl_super_cmd("get", 0,
418 "get subcommand Get, see `get' command for more help",
419 "long help of get", cset));
424 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("set"));
426 cset= super_cmd->commands;
428 cset= new cl_cmdset();
431 cset->add(cmd= new cl_set_mem_cmd("memory", 0,
432 "set memory memory_type address data...\n"
433 " Place list of data into memory",
434 "long help of set memory"));
436 cset->add(cmd= new cl_set_bit_cmd("bit", 0,
437 "set bit addr 0|1 Set specified bit to 0 or 1",
438 "long help of set bit"));
440 cset->add(cmd= new cl_set_hw_cmd("hardware", 0,
441 "set hardware cathegory params...\n"
442 " Set parameters of specified hardware element",
443 "long help of set hardware"));
449 cmdset->add(cmd= new cl_super_cmd("set", 0,
450 "set subcommand Set, see `set' command for more help",
451 "long help of set", cset));
456 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("info"));
458 cset= super_cmd->get_subcommands();
460 cset= new cl_cmdset();
463 cset->add(cmd= new cl_info_bp_cmd("breakpoints", 0,
464 "info breakpoints Status of user-settable breakpoints",
465 "long help of info breakpoints"));
468 cset->add(cmd= new cl_info_reg_cmd("registers", 0,
469 "info registers List of integer registers and their contents",
470 "long help of info registers"));
472 cset->add(cmd= new cl_info_hw_cmd("hardware", 0,
473 "info hardware cathegory\n"
474 " Status of hardware elements of the CPU",
475 "long help of info hardware"));
478 cset->add(cmd= new cl_info_stack_cmd("stack", 0,
479 "info stack Status of stack of the CPU",
480 "long help of info stack"));
482 cset->add(cmd= new cl_info_memory_cmd("memory", 0,
483 "info memory Information about memory system",
484 "long help of info memory"));
488 cmdset->add(cmd= new cl_super_cmd("info", 0,
489 "info subcommand Information, see `info' command for more help",
490 "long help of info", cset));
495 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("timer"));
497 cset= super_cmd->get_subcommands();
499 cset= new cl_cmdset();
502 cset->add(cmd= new cl_timer_add_cmd("add", 0,
503 "timer add id [direction [in_isr]]\n"
504 " Create a clock counter (timer)",
505 "log help of timer add"));
507 cmd->add_name("create");
508 cmd->add_name("make");
509 cset->add(cmd= new cl_timer_delete_cmd("delete", 0,
510 "timer delete id Delete a timer",
511 "long help of timer delete"));
513 cmd->add_name("remove");
514 cset->add(cmd= new cl_timer_get_cmd("get", 0,
515 "timer get [id] Get value of a timer, or all",
516 "long help of timer get"));
518 cset->add(cmd= new cl_timer_run_cmd("run", 0,
519 "timer start id Start a timer",
520 "long help of timer run"));
522 cmd->add_name("start");
523 cset->add(cmd= new cl_timer_stop_cmd("stop", 0,
524 "timer stop id Stop a timer",
525 "long help of timer stop"));
527 cset->add(cmd= new cl_timer_value_cmd("set", 0,
528 "timer set id value\n"
529 " Set a timer value",
530 "long help of timer set"));
532 cmd->add_name("value");
535 cmdset->add(cmd= new cl_super_cmd("timer", 0,
536 "timer subcommand Manage timers",
537 "long help of timer", cset));
542 super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("memory"));
544 cset= super_cmd->get_subcommands();
546 cset= new cl_cmdset();
550 cset->add(cmd= new cl_memory_cmd("_no_parameters_", 0,
551 "memory Information about memory system",
552 "long help of memory"));
555 cset->add(cmd= new cl_memory_createchip_cmd("createchip", 0,
556 "memory createchip id size cellsize\n"
557 " Create a new memory chip",
558 "long help of memory createchip"));
560 cmd->add_name("cchip");
561 cset->add(cmd= new cl_memory_createaddressspace_cmd("createaddressspace", 0,
562 "memory createaddressspace id startaddr size\n"
563 " Create address space",
564 "long help of memory createaddressspace"));
566 cmd->add_name("createaddrspace");
567 cmd->add_name("createaspace");
568 cmd->add_name("caddressspace");
569 cmd->add_name("caddrspace");
570 cmd->add_name("caspace");
571 cset->add(cmd= new cl_memory_createaddressdecoder_cmd("createaddressdecoder", 0,
572 "memory createaddressdecoder addressspace begin end chip begin\n"
573 " Create address decoder",
574 "long help of memory createaddressdecoder"));
576 cmd->add_name("createaddrdecoder");
577 cmd->add_name("createadecoder");
578 cmd->add_name("caddressdecoder");
579 cmd->add_name("caddrdecoder");
580 cmd->add_name("cadecoder");
583 cmdset->add(cmd= new cl_super_cmd("memory", 0,
584 "memory subcommand Manage memory chips and address spaces",
585 "long help of memory", cset));
592 * Read/write simulated memory
596 cl_uc::read_mem(const char *id, t_addr addr)
598 class cl_address_space *m= address_space(id);
600 return(m?(m->read(addr)):0);
604 cl_uc::get_mem(const char *id, t_addr addr)
606 class cl_address_space *m= address_space(id);
608 return(m?(m->get(addr)):0);
612 cl_uc::write_mem(const char *id, t_addr addr, t_mem val)
614 class cl_address_space *m= address_space(id);
621 cl_uc::set_mem(const char *id, t_addr addr, t_mem val)
623 class cl_address_space *m= address_space(id);
632 cl_uc::mem(enum mem_class type)
636 if (mems->count < type)
637 m= (class cl_m *)(mems->at(MEM_DUMMY));
639 m= (class cl_m *)(mems->at(type));
644 class cl_address_space *
645 cl_uc::address_space(const char *id)
652 for (i= 0; i < address_spaces->count; i++)
654 class cl_address_space *m= (cl_address_space *)(address_spaces->at(i));
656 !m->have_real_name())
658 if (m->is_inamed(id))
665 cl_uc::memory(const char *id)
672 for (i= 0; i < address_spaces->count; i++)
674 class cl_memory *m= (cl_memory *)(address_spaces->at(i));
676 !m->have_real_name())
678 if (m->is_inamed(id))
681 for (i= 0; i < memchips->count; i++)
683 class cl_memory *m= (cl_memory *)(memchips->at(i));
685 !m->have_real_name())
687 if (m->is_inamed(id))
695 ReadInt(FILE *f, bool *ok, int bytes)
703 if (fscanf(f, "%2c", &s2[0]) == EOF)
706 l= l*256 + strtol(s2, NULL, 16);
715 * Reading intel hexa file into EROM
716 *____________________________________________________________________________
718 * If parameter is a NULL pointer, this function reads data from `cmd_in'
723 cl_uc::read_hex_file(const char *nam)
727 long written= 0, recnum= 0;
729 uchar dnum; // data number
730 uchar rtyp=0; // record type
731 uint addr= 0; // address
732 uchar rec[300]; // data record
733 uchar sum ; // checksum
741 sim->app->get_commander()->
742 dd_printf("No ROM address space to read in.\n");
748 sim->app->get_commander()->
749 dd_printf("cl_uc::read_hex_file File name not specified\n");
753 if ((f= fopen(nam, "r")) == NULL)
755 fprintf(stderr, "Can't open `%s': %s\n", nam, strerror(errno));
759 //memset(inst_map, '\0', sizeof(inst_map));
764 while (((c= getc(f)) != ':') &&
767 {fprintf(stderr, ": not found\n");break;}
769 dnum= ReadInt(f, &ok, 1);//printf("dnum=%02x",dnum);
771 addr= ReadInt(f, &ok, 2);//printf("addr=%04x",addr);
773 chk+= ((addr >> 8) & 0xff);
774 rtyp= ReadInt(f, &ok, 1);//printf("rtyp=%02x ",rtyp);
776 for (i= 0; ok && (i < dnum); i++)
778 rec[i]= ReadInt(f, &ok, 1);//printf("%02x",rec[i]);
783 sum= ReadInt(f, &ok, 1);//printf(" sum=%02x\n",sum);
786 if (((sum + chk) & 0xff) == 0)
792 for (i= 0; i < dnum; i++)
796 rom->set(addr, rec[i]);
800 else if (rom->width <= 16)
810 rom->set(addr, (high*256)+low);
820 application->debug("Unknown record type %d(0x%x)\n",
824 application->debug("Checksum error (%x instead of %x) in "
825 "record %ld.\n", chk, sum, recnum);
828 application->debug("Read error in record %ld.\n", recnum);
831 if (rom->width > 8 &&
837 application->debug("%ld records have been read\n", recnum);
844 * Handling instruction map
846 * `inst_at' is checking if the specified address is in instruction
847 * map and `set_inst_at' marks the address in the map and
848 * `del_inst_at' deletes the mark. `there_is_inst' cheks if there is
849 * any mark in the map
853 cl_uc::inst_at(t_addr addr)
857 return(rom->get_cell_flag(addr, CELL_INST));
861 cl_uc::set_inst_at(t_addr addr)
864 rom->set_cell_flag(addr, DD_TRUE, CELL_INST);
868 cl_uc::del_inst_at(t_addr addr)
871 rom->set_cell_flag(addr, DD_FALSE, CELL_INST);
875 cl_uc::there_is_inst(void)
881 for (addr= 0; rom->valid_address(addr) && !got; addr++)
882 got= rom->get_cell_flag(addr, CELL_INST);
888 * Manipulating HW elements of the CPU
889 *****************************************************************************
892 /* Register callback hw objects for mem read/write */
895 cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw)
900 if ((m= (class cl_m*)mems->at(type)))
902 if ((l= m->read_locs->get_loc(addr)) == 0)
904 l= new cl_memloc(addr);
906 m->read_locs->add(l);
911 printf("cl_uc::register_hw_read TROUBLE\n");
915 cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw)
919 /* Looking for a specific HW element */
922 cl_uc::get_hw(enum hw_cath cath, int *idx)
929 for (; i < hws->count; i++)
931 hw= (class cl_hw *)(hws->at(i));
932 if (hw->cathegory == cath)
943 cl_uc::get_hw(char *id_string, int *idx)
950 for (; i < hws->count; i++)
952 hw= (class cl_hw *)(hws->at(i));
953 if (strstr(hw->id_string, id_string) == hw->id_string)
964 cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx)
971 hw= get_hw(cath, &i);
976 hw= get_hw(cath, &i);
985 cl_uc::get_hw(char *id_string, int hwid, int *idx)
992 hw= get_hw(id_string, &i);
997 hw= get_hw(id_string, &i);
1007 * Help of the command interpreter
1011 cl_uc::dis_tbl(void)
1013 static struct dis_entry empty= { 0, 0, 0, 0, NULL };
1018 cl_uc::sfr_tbl(void)
1020 static struct name_entry empty= { 0, 0 };
1025 cl_uc::bit_tbl(void)
1027 static struct name_entry empty= { 0, 0 };
1032 cl_uc::disass(t_addr addr, const char *sep)
1036 buf= (char*)malloc(100);
1037 strcpy(buf, "uc::disass() unimplemented\n");
1042 cl_uc::print_disass(t_addr addr, class cl_console_base *con)
1051 t_mem code= rom->get(addr);
1053 dis= disass(addr, NULL);
1055 con->dd_printf("%c", (b->perm == brkFIX)?'F':'D');
1057 con->dd_printf(" ");
1058 con->dd_printf("%c ", inst_at(addr)?' ':'?');
1059 con->dd_printf(rom->addr_format, addr); con->dd_printf(" ");
1060 con->dd_printf(rom->data_format, code);
1061 for (i= 1; i < inst_length(addr); i++)
1063 con->dd_printf(" ");
1064 con->dd_printf(rom->data_format, rom->get(addr+i));
1066 int li= longest_inst();
1070 j= rom->width/4 + ((rom->width%4)?1:0) + 1;
1072 con->dd_printf(" "), j--;
1075 con->dd_printf(" %s\n", dis);
1080 cl_uc::print_regs(class cl_console_base *con)
1082 con->dd_printf("No registers\n");
1086 cl_uc::inst_length(t_addr addr)
1088 struct dis_entry *tabl= dis_tbl();
1095 code = rom->get(addr);
1096 for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ;
1097 return(tabl[i].mnemonic?tabl[i].length:1);
1101 cl_uc::inst_branch(t_addr addr)
1103 struct dis_entry *tabl= dis_tbl();
1110 code = rom->get(addr);
1111 for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
1113 return tabl[i].branch;
1117 cl_uc::longest_inst(void)
1119 struct dis_entry *de= dis_tbl();
1125 if (de->length > max)
1133 cl_uc::get_name(t_addr addr, struct name_entry tab[], char *buf)
1138 while (tab[i].name &&
1139 (!(tab[i].cpu_type & type) ||
1140 (tab[i].addr != addr)))
1143 strcpy(buf, tab[i].name);
1144 return(tab[i].name != NULL);
1148 cl_uc::symbol2address(char *sym, struct name_entry tab[],
1157 while (tab[i].name &&
1158 (!(tab[i].cpu_type & type) ||
1159 strcasecmp(sym, tab[i].name) != 0))
1171 cl_uc::symbolic_bit_name(t_addr bit_address,
1172 class cl_memory *mem,
1180 while (bit_tbl()[i].name &&
1181 (bit_tbl()[i].addr != bit_address))
1183 if (bit_tbl()[i].name)
1185 sym_name= strdup(bit_tbl()[i].name);
1190 mem->have_real_name() &&
1191 strstr(mem->get_name(), "sfr") == mem->get_name())
1194 while (sfr_tbl()[i].name &&
1195 (sfr_tbl()[i].addr != mem_addr))
1197 if (sfr_tbl()[i].name)
1198 sym_name= strdup(sfr_tbl()[i].name);
1204 sym_name= (char *)malloc(16);
1205 sprintf(sym_name, mem?(mem->addr_format):"0x%06x", mem_addr);
1207 sym_name= (char *)realloc(sym_name, strlen(sym_name)+2);
1208 strcat(sym_name, ".");
1210 while (bit_mask > 1)
1216 sprintf(bitnumstr, "%1d", i);
1217 strcat(sym_name, bitnumstr);
1223 * Messages to broadcast
1227 cl_uc::handle_event(class cl_event &event)
1231 case ev_address_space_added:
1234 class cl_event_address_space_added &e=
1235 dynamic_cast<class cl_event_address_space_added &>(event);
1236 address_space_added(e.as);
1244 return(pass_event_down(event));
1252 cl_uc::mem_cell_changed(class cl_address_space *mem, t_addr addr)
1255 hws->mem_cell_changed(mem, addr);
1257 printf("JAJ uc\n");//FIXME
1262 for (i= 0; i < mems->count; i++)
1270 cl_uc::address_space_added(class cl_address_space *as)
1273 hws->address_space_added(as);
1275 printf("JAJ uc\n");//FIXME
1284 cl_uc::error(class cl_error *error)
1287 if ((error->inst= inst_exec))
1292 cl_uc::check_errors(void)
1295 class cl_commander_base *c= sim->app->get_commander();
1296 bool must_stop= DD_FALSE;
1300 for (i= 0; i < errors->count; i++)
1302 class cl_error *error= (class cl_error *)(errors->at(i));
1303 if (!error->is_on())
1306 must_stop= must_stop || (error->get_type() & err_stop);
1309 class cl_console_base *con;
1310 con= c->actual_console;
1312 con= c->frozen_console;
1315 con->dd_printf("Erronouse instruction: ");
1316 print_disass(error->PC, con);
1323 fprintf(stderr, "no actual console, %d errors\n", errors->count);
1325 sim->stop(resERROR);
1330 * Converting bit address into real memory
1333 class cl_address_space *
1334 cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask)
1339 *bitmask= 1 << (bitaddr & 0x7);
1340 return(0); // abstract...
1349 cl_uc::tick_hw(int cycles)
1352 int i;//, cpc= clock_per_cycle();
1355 for (i= 0; i < hws->count; i++)
1357 hw= (class cl_hw *)(hws->at(i));
1358 if (hw->flags & HWF_INSIDE)
1361 do_extra_hw(cycles);
1366 cl_uc::do_extra_hw(int cycles)
1370 cl_uc::tick(int cycles)
1373 int i, cpc= clock_per_cycle();
1376 ticks->tick(cycles * cpc);
1377 class it_level *il= (class it_level *)(it_levels->top());
1379 isr_ticks->tick(cycles * cpc);
1380 if (state == stIDLE)
1381 idle_ticks->tick(cycles * cpc);
1382 for (i= 0; i < counters->count; i++)
1384 class cl_ticker *t= (class cl_ticker *)(counters->at(i));
1387 if ((t->options&TICK_INISR) ||
1389 t->tick(cycles * cpc);
1393 // tick for hardwares
1394 inst_ticks+= cycles;
1399 cl_uc::get_counter(int nr)
1401 if (nr >= counters->count)
1403 return((class cl_ticker *)(counters->at(nr)));
1407 cl_uc::get_counter(char *nam)
1413 for (i= 0; i < counters->count; i++)
1415 class cl_ticker *t= (class cl_ticker *)(counters->at(i));
1418 strcmp(t->get_name(), nam) == 0)
1425 cl_uc::add_counter(class cl_ticker *ticker, int nr)
1427 while (counters->count <= nr)
1429 counters->put_at(nr, ticker);
1433 cl_uc::add_counter(class cl_ticker *ticker, char */*nam*/)
1437 if (counters->count < 1)
1439 for (i= 1; i < counters->count; i++)
1441 class cl_ticker *t= (class cl_ticker *)(counters->at(i));
1444 counters->put_at(i, ticker);
1448 counters->add(ticker);
1452 cl_uc::del_counter(int nr)
1456 if (nr >= counters->count)
1458 if ((t= (class cl_ticker *)(counters->at(0))) != 0)
1460 counters->put_at(nr, 0);
1464 cl_uc::del_counter(char *nam)
1470 for (i= 0; i < counters->count; i++)
1472 class cl_ticker *t= (class cl_ticker *)(counters->at(i));
1475 strcmp(t->get_name(), nam) == 0)
1478 counters->put_at(i, 0);
1485 * Fetch without checking for breakpoint hit
1496 code= rom->read(PC);
1497 PC= rom->inc_address(PC);
1502 * Fetch but checking for breakpoint hit first, returns TRUE if
1503 * a breakpoint is hit
1507 cl_uc::fetch(t_mem *code)
1514 if ((sim->state & SIM_GO) &&
1517 if (rom->get_cell_flag(PC, CELL_FETCH_BRK) &&
1518 (brk= fbrk->get_bp(PC, &idx)) &&
1521 if (brk->perm == brkDYNAMIC)
1531 cl_uc::do_inst(int step)
1550 cl_uc::pre_inst(void)
1554 events->disconn_all();
1558 cl_uc::exec_inst(void)
1565 cl_uc::post_inst(void)
1567 tick_hw(inst_ticks);
1572 inst_exec= DD_FALSE;
1577 * Time related functions
1581 cl_uc::get_rtime(void)
1585 d= (double)ticks/xtal;
1587 return(ticks->get_rtime(xtal));
1591 cl_uc::clock_per_cycle(void)
1598 * Stack tracking system
1602 cl_uc::stack_write(class cl_stack_op *op)
1604 if (op->get_op() & stack_read_operation)
1606 class cl_error_stack_tracker_wrong_handle *e= new
1607 cl_error_stack_tracker_wrong_handle(DD_FALSE);
1608 //fprintf(stderr, "%06"_A_"x cl_uc::stack_read() should be called for "
1609 //"%s\n", op->get_pc(), op->get_op_name());
1614 stack_ops->push(op);
1618 cl_uc::stack_read(class cl_stack_op *op)
1620 class cl_stack_op *top= (class cl_stack_op *)(stack_ops->top());
1622 if (op->get_op() & stack_write_operation)
1624 class cl_error_stack_tracker_wrong_handle *e= new
1625 cl_error_stack_tracker_wrong_handle(DD_TRUE);
1628 //fprintf(stderr, "%06"_A_"x cl_uc::stack_write() should be called for "
1629 //"%s\n", op->get_pc(), op->get_op_name());
1634 class cl_error *e= new cl_error_stack_tracker_empty(op);
1635 /*printf("0x%06"_A_"x %s operation on stack but no operation was before\n
1637 op->get_pc(), op->get_op_name());*/
1645 if (!top->match(op))
1647 class cl_error *e= new cl_error_stack_tracker_unmatch(top, op);
1650 /*printf("0x%06"_A_"x %s operation on stack but last was %s\n",
1651 op->get_pc(), op->get_op_name(), top->get_op_name());*/
1653 int top_size= top->data_size(), op_size= op->data_size();
1654 if (top_size != op_size)
1656 application->debug("0x%06"_A_"x %d bytes to read out of stack "
1657 "but %d was pushed in last operation\n",
1658 op->get_pc(), op_size, top_size);
1664 top->can_removed(op))
1666 top= (class cl_stack_op *)stack_ops->pop();
1668 top= (class cl_stack_op *)stack_ops->top();
1673 application->debug("0x%06"_A_"x %d ops removed from stack-tracker "
1674 "when %s happened, top pc=0x%06"_A_"x "
1675 "top before=0x%06"_A_"x op after=0x%06"_A_"x\n",
1676 op->get_pc(), removed, op->get_op_name(),
1677 top?(top->get_pc()):0, top?(top->get_before()):0,
1683 int ta= top->get_after(), oa= op->get_after();
1686 application->debug("0x%06"_A_"x stack still inconsistent after %s, "
1687 "%d byte(s) should be read out; top after"
1688 "=0x%06"_A_"x op after=0x%06"_A_"x\n",
1689 op->get_pc(), op->get_op_name(), abs(ta-oa),
1692 new cl_error_stack_tracker_inconsistent(op, abs(ta-oa));
1703 * Breakpoint handling
1706 class cl_fetch_brk *
1707 cl_uc::fbrk_at(t_addr addr)
1711 return((class cl_fetch_brk *)(fbrk->get_bp(addr, &idx)));
1715 cl_uc::ebrk_at(t_addr addr, char *id)
1718 class cl_ev_brk *eb;
1720 for (i= 0; i < ebrk->count; i++)
1722 eb= (class cl_ev_brk *)(ebrk->at(i));
1723 if (eb->addr == addr &&
1724 !strcmp(eb->id, id))
1731 cl_uc::rm_fbrk(long addr)
1736 /* Get a breakpoint specified by its number */
1739 cl_uc::brk_by_nr(int nr)
1743 if ((bp= fbrk->get_bp(nr)))
1745 if ((bp= ebrk->get_bp(nr)))
1750 /* Get a breakpoint from the specified collection by its number */
1753 cl_uc::brk_by_nr(class brk_coll *bpcoll, int nr)
1757 if ((bp= bpcoll->get_bp(nr)))
1762 /* Remove an event breakpoint specified by its address and id */
1765 cl_uc::rm_ebrk(t_addr addr, char *id)
1768 class cl_ev_brk *eb;
1770 for (i= 0; i < ebrk->count; i++)
1772 eb= (class cl_ev_brk *)(ebrk->at(i));
1773 if (eb->addr == addr &&
1774 !strcmp(eb->id, id))
1779 /* Remove a breakpoint specified by its number */
1782 cl_uc::rm_brk(int nr)
1786 if ((bp= brk_by_nr(fbrk, nr)))
1788 fbrk->del_bp(bp->addr);
1791 else if ((bp= brk_by_nr(ebrk, nr)))
1793 ebrk->del_bp(ebrk->index_of(bp), 0);
1800 cl_uc::put_breaks(void)
1803 /* Remove all fetch and event breakpoints */
1806 cl_uc::remove_all_breaks(void)
1810 class cl_brk *brk= (class cl_brk *)(fbrk->at(0));
1811 fbrk->del_bp(brk->addr);
1814 ebrk->del_bp(ebrk->count-1, 0);
1818 cl_uc::make_new_brknr(void)
1820 if (brk_counter == 0)
1821 return(brk_counter= 1);
1822 if (fbrk->count == 0 &&
1824 return(brk_counter= 1);
1825 return(++brk_counter);
1829 cl_uc::mk_ebrk(enum brk_perm perm, class cl_address_space *mem,
1830 char op, t_addr addr, int hit)
1835 b= new cl_ev_brk(mem, make_new_brknr(), addr, perm, hit, op);
1841 cl_uc::check_events(void)
1844 for (i= 0; i < events->count; i++)
1846 class cl_ev_brk *brk=
1847 dynamic_cast<class cl_ev_brk *>(events->object_at(i));
1850 sim->stop(resBREAKPOINT);
1856 *----------------------------------------------------------------------------
1859 cl_error_unknown_code::cl_error_unknown_code(class cl_uc *the_uc)
1862 classification= uc_error_registry.find("unknown_code");
1866 cl_error_unknown_code::print(class cl_commander_base *c)
1868 c->dd_printf("%s: unknown instruction code at ", get_type_name());
1871 c->dd_printf(uc->rom->addr_format, PC);
1873 c->dd_printf(uc->rom->data_format, uc->rom->get(PC));
1877 c->dd_printf("0x%06x", PC);
1881 cl_uc_error_registry::cl_uc_error_registry(void)
1883 class cl_error_class *prev = uc_error_registry.find("non-classified");
1884 prev = register_error(new cl_error_class(err_error, "unknown_code", prev, ERROR_OFF));