X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fsim.src%2Fuc.cc;h=4550bb09494e559f8edfd27b73e08d6bc570c238;hb=34d14506fd0c12ee5434fec0f9dec27753e1aab5;hp=bae853289dacb5f5c9af81de2a899cfbddf4d716;hpb=109dd226aad40f4f2f122e6ccfc7f038610a5ceb;p=fw%2Fsdcc diff --git a/sim/ucsim/sim.src/uc.cc b/sim/ucsim/sim.src/uc.cc index bae85328..4550bb09 100644 --- a/sim/ucsim/sim.src/uc.cc +++ b/sim/ucsim/sim.src/uc.cc @@ -45,6 +45,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "setcl.h" #include "infocl.h" #include "timercl.h" +#include "cmdstatcl.h" +#include "cmdmemcl.h" +#include "cmdutil.h" // local, sim.src #include "uccl.h" @@ -53,26 +56,23 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "simcl.h" #include "itsrccl.h" +static class cl_uc_error_registry uc_error_registry; /* * Clock counter */ -cl_ticker::cl_ticker(int adir, int in_isr, char *aname) +cl_ticker::cl_ticker(int adir, int in_isr, const char *aname) { options= TICK_RUN; if (in_isr) options|= TICK_INISR; dir= adir; ticks= 0; - name= aname?strdup(aname):0; + set_name(aname); } -cl_ticker::~cl_ticker(void) -{ - if (name) - free(name); -} +cl_ticker::~cl_ticker(void) {} int cl_ticker::tick(int nr) @@ -92,13 +92,34 @@ cl_ticker::get_rtime(double xtal) } void -cl_ticker::dump(int nr, double xtal, class cl_console *con) +cl_ticker::dump(int nr, double xtal, class cl_console_base *con) { con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n", - nr, name?name:"unnamed", - (options&TICK_RUN)?"ON":"OFF", - (options&TICK_INISR)?",ISR":"", - get_rtime(xtal), ticks); + nr, get_name("unnamed"), + (options&TICK_RUN)?"ON":"OFF", + (options&TICK_INISR)?",ISR":"", + get_rtime(xtal), ticks); +} + + +/* + * Options of uc + */ + +cl_xtal_option::cl_xtal_option(class cl_uc *the_uc): + cl_optref(the_uc) +{ + uc= the_uc; +} + +void +cl_xtal_option::option_changed(void) +{ + if (!uc) + return; + double d; + option->get_value(&d); + uc->xtal= d; } @@ -110,63 +131,76 @@ cl_ticker::dump(int nr, double xtal, class cl_console *con) cl_uc::cl_uc(class cl_sim *asim): cl_base() { - int i; + //int i; sim = asim; - mems= new cl_list(MEM_TYPES, 1); + //mems= new cl_list(MEM_TYPES, 1); + memchips= new cl_list(2, 2, "memchips"); + address_spaces= new cl_address_space_list(this); + //address_decoders= new cl_list(2, 2); + rom= 0; + hws = new cl_hws(); - options= new cl_list(2, 2); - for (i= MEM_ROM; i < MEM_TYPES; i++) - mems->add(0); + //options= new cl_list(2, 2); + //for (i= MEM_ROM; i < MEM_TYPES; i++) mems->add(0); + xtal_option= new cl_xtal_option(this); + xtal_option->init(); ticks= new cl_ticker(+1, 0, "time"); isr_ticks= new cl_ticker(+1, TICK_INISR, "isr"); idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle"); - counters= new cl_list(2, 2); - it_levels= new cl_list(2, 2); - it_sources= new cl_list(2, 2); + counters= new cl_list(2, 2, "counters"); + it_levels= new cl_list(2, 2, "it levels"); + it_sources= new cl_irqs(2, 2); class it_level *il= new it_level(-1, 0, 0, 0); it_levels->push(il); - st_ops= new cl_list(2, 2); + stack_ops= new cl_list(2, 2, "stack operations"); + errors= new cl_list(2, 2, "errors in uc"); + events= new cl_list(2, 2, "events in uc"); sp_max= 0; sp_avg= 0; + inst_exec= DD_FALSE; } cl_uc::~cl_uc(void) { - delete mems; + //delete mems; delete hws; - delete options; + //delete options; delete ticks; delete isr_ticks; delete idle_ticks; delete counters; + events->disconn_all(); + delete events; delete fbrk; delete ebrk; delete it_levels; delete it_sources; - delete st_ops; + delete stack_ops; + errors->free_all(); + delete errors; + delete xtal_option; + delete address_spaces; + delete memchips; + //delete address_decoders; } int cl_uc::init(void) { - int mc, i; + int i; + set_name("controller"); cl_base::init(); - if (!(sim->app->args->arg_avail('X')) || - sim->app->args->get_farg('X', 0) == 0) - xtal= 11059200; + if (xtal_option->use("xtal")) + xtal= xtal_option->get_value(xtal); else - xtal= sim->app->args->get_farg('X', 0); - for (mc= MEM_ROM; mc < MEM_TYPES; mc++) - { - class cl_mem *m= mk_mem((enum mem_class)mc, - get_id_string(mem_classes, mc)); - mems->put_at(mc, m); - } - ebrk= new brk_coll(2, 2, (class cl_rom *)mem(MEM_ROM)); - fbrk= new brk_coll(2, 2, (class cl_rom *)mem(MEM_ROM)); + xtal= 11059200; + make_memories(); + rom= address_space(MEM_ROM_ID); + ebrk= new brk_coll(2, 2, rom); + fbrk= new brk_coll(2, 2, rom); fbrk->Duplicates= DD_FALSE; brk_counter= 0; mk_hw_elements(); @@ -179,15 +213,15 @@ cl_uc::init(void) char *fname= (char *)(sim->app->in_files->at(i)); long l; if ((l= read_hex_file(fname)) >= 0) - { - sim->app->get_commander()->all_printf("%ld words read from %s\n", - l, fname); - } + { + sim->app->get_commander()->all_printf("%ld words read from %s\n", + l, fname); + } } return(0); } -char * +const char * cl_uc::id_string(void) { return("unknown microcontroller"); @@ -198,7 +232,7 @@ cl_uc::reset(void) { class it_level *il; - PC= 0; + instPC= PC= 0; state = stGO; ticks->ticks= 0; isr_ticks->ticks= 0; @@ -206,7 +240,7 @@ cl_uc::reset(void) /*FIXME should we clear user counters?*/ il= (class it_level *)(it_levels->top()); while (il && - il->level >= 0) + il->level >= 0) { il= (class it_level *)(it_levels->pop()); delete il; @@ -214,49 +248,39 @@ cl_uc::reset(void) } sp_max= 0; sp_avg= 0; + + stack_ops->free_all(); + + int i; + for (i= 0; i < hws->count; i++) + { + class cl_hw *hw= (class cl_hw *)(hws->at(i)); + hw->reset(); + } } /* * Making elements */ -class cl_mem * -cl_uc::mk_mem(enum mem_class type, char *class_name) -{ - class cl_mem *m; - - if (get_mem_size(type) <= 0) - return(0); - if (type == MEM_ROM) - m= new cl_rom(get_mem_size(type), get_mem_width(type)); - else - m= new cl_mem(type, get_id_string(mem_classes, type), - get_mem_size(type), get_mem_width(type)); - m->init(); - return(m); -} +void +cl_uc::make_memories(void) +{} -t_addr -cl_uc::get_mem_size(enum mem_class type) +/*t_addr +cl_uc::get_mem_size(char *id) { - switch (type) - { - case MEM_ROM: return(0x10000); - case MEM_XRAM: return(0x10000); - case MEM_IRAM: return(0x100); - case MEM_SFR: return(0x100); - case MEM_TYPES: - default: return(0); - } - return(0); + class cl_memory *m= memory(id); + return(m?(m->get_size()):0); } int -cl_uc::get_mem_width(enum mem_class type) +cl_uc::get_mem_width(char *id) { - return(8); + class cl_memory *m= memory(id); + return(m?(m->width):8); } - +*/ void cl_uc::mk_hw_elements(void) { @@ -266,6 +290,7 @@ void cl_uc::build_cmdset(class cl_cmdset *cmdset) { class cl_cmd *cmd; + class cl_super_cmd *super_cmd; class cl_cmdset *cset; cmdset->add(cmd= new cl_state_cmd("state", 0, @@ -273,6 +298,14 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) "long help of state")); cmd->init(); +#ifdef STATISTIC + cmdset->add(cmd= new cl_statistic_cmd("statistic", 0, +"statistic [mem [startaddr [endaddr]]]\n" +" Statistic of memory accesses", +"long help of statistic")); + cmd->init(); +#endif + cmdset->add(cmd= new cl_file_cmd("file", 0, "file \"FILE\" Load FILE into ROM", "long help of file")); @@ -280,7 +313,7 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) cmd->add_name("load"); cmdset->add(cmd= new cl_dl_cmd("download", 0, -"download,dl Load (intel.hex) data", +"download Load (intel.hex) data", "long help of download")); cmd->init(); cmd->add_name("dl"); @@ -295,39 +328,24 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) "long help of reset")); cmd->init(); - cmdset->add(cmd= new cl_dump_cmd("dump", 0, + cmdset->add(cmd= new cl_dump_cmd("dump", DD_TRUE, "dump memory_type [start [stop [bytes_per_line]]]\n" " Dump memory of specified type\n" "dump bit... Dump bits", "long help of dump")); cmd->init(); - cmdset->add(cmd= new cl_di_cmd("di", 0, -"di [start [stop]] Dump Internal RAM", -"long help of di")); - cmd->init(); - - cmdset->add(cmd= new cl_dx_cmd("dx", 0, -"dx [start [stop]] Dump External RAM", -"long help of dx")); - cmd->init(); - - cmdset->add(cmd= new cl_ds_cmd("ds", 0, -"ds [start [stop]] Dump SFR", -"long help of ds")); - cmd->init(); - - cmdset->add(cmd= new cl_dch_cmd("dch", 0, + cmdset->add(cmd= new cl_dch_cmd("dch", DD_TRUE, "dch [start [stop]] Dump code in hex form", "long help of dch")); cmd->init(); - cmdset->add(cmd= new cl_dc_cmd("dc", 0, + cmdset->add(cmd= new cl_dc_cmd("dc", DD_TRUE, "dc [start [stop]] Dump code in disass form", "long help of dc")); cmd->init(); - cmdset->add(cmd= new cl_disassemble_cmd("disassemble", 0, + cmdset->add(cmd= new cl_disassemble_cmd("disassemble", DD_TRUE, "disassemble [start [offset [lines]]]\n" " Disassemble code", "long help of disassemble")); @@ -376,27 +394,40 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) cmd->init(); { - cset= new cl_cmdset(); - cset->init(); + super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("get")); + if (super_cmd) + cset= super_cmd->commands; + else { + cset= new cl_cmdset(); + cset->init(); + } cset->add(cmd= new cl_get_sfr_cmd("sfr", 0, "get sfr address...\n" " Get value of addressed SFRs", "long help of get sfr")); cmd->init(); - cset->add(cmd= new cl_get_option_cmd("option", 0, + /*cset->add(cmd= new cl_get_option_cmd("option", 0, "get option name\n" " Get value of an option", "long help of get option")); - cmd->init(); +cmd->init();*/ } - cmdset->add(cmd= new cl_super_cmd("get", 0, + if (!super_cmd) + { + cmdset->add(cmd= new cl_super_cmd("get", 0, "get subcommand Get, see `get' command for more help", "long help of get", cset)); - cmd->init(); + cmd->init(); + } { - cset= new cl_cmdset(); - cset->init(); + super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("set")); + if (super_cmd) + cset= super_cmd->commands; + else { + cset= new cl_cmdset(); + cset->init(); + } cset->add(cmd= new cl_set_mem_cmd("memory", 0, "set memory memory_type address data...\n" " Place list of data into memory", @@ -406,24 +437,29 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) "set bit addr 0|1 Set specified bit to 0 or 1", "long help of set bit")); cmd->init(); - cset->add(cmd= new cl_set_port_cmd("port", 0, -"set port hw data Set data connected to port", -"long help of set port")); - cmd->init(); - cset->add(cmd= new cl_set_option_cmd("option", 0, -"set option name value\n" -" Set value of an option", -"long help of set option")); + cset->add(cmd= new cl_set_hw_cmd("hardware", 0, +"set hardware cathegory params...\n" +" Set parameters of specified hardware element", +"long help of set hardware")); + cmd->add_name("hw"); cmd->init(); } - cmdset->add(cmd= new cl_super_cmd("set", 0, + if (!super_cmd) + { + cmdset->add(cmd= new cl_super_cmd("set", 0, "set subcommand Set, see `set' command for more help", "long help of set", cset)); - cmd->init(); + cmd->init(); + } - { - cset= new cl_cmdset(); - cset->init(); + { // info + super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("info")); + if (super_cmd) + cset= super_cmd->get_subcommands(); + else { + cset= new cl_cmdset(); + cset->init(); + } cset->add(cmd= new cl_info_bp_cmd("breakpoints", 0, "info breakpoints Status of user-settable breakpoints", "long help of info breakpoints")); @@ -437,24 +473,118 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) "info hardware cathegory\n" " Status of hardware elements of the CPU", "long help of info hardware")); - cmd->add_name("h w"); + cmd->add_name("hw"); + cmd->init(); + cset->add(cmd= new cl_info_stack_cmd("stack", 0, +"info stack Status of stack of the CPU", +"long help of info stack")); + cmd->init(); + cset->add(cmd= new cl_info_memory_cmd("memory", 0, +"info memory Information about memory system", +"long help of info memory")); cmd->init(); } - cmdset->add(cmd= new cl_super_cmd("info", 0, + if (!super_cmd) { + cmdset->add(cmd= new cl_super_cmd("info", 0, "info subcommand Information, see `info' command for more help", "long help of info", cset)); - cmd->init(); + cmd->init(); + } - cmdset->add(cmd= new cl_timer_cmd("timer", 0, -"timer a|d|g|r|s|v id [direction|value]\n" -" Timer add|del|get|run|stop|value", -"timer add|create|make id [direction] -- create a new timer\n" -"timer del id -- delete a timer\n" -"timer get id -- list timers\n" -"timer run id -- turn a timer ON\n" -"timer stop id -- turn a timer OFF\n" -"timer value id val -- set value of a timer to `val'")); - cmd->init(); + { + super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("timer")); + if (super_cmd) + cset= super_cmd->get_subcommands(); + else { + cset= new cl_cmdset(); + cset->init(); + } + cset->add(cmd= new cl_timer_add_cmd("add", 0, +"timer add id [direction [in_isr]]\n" +" Create a clock counter (timer)", +"log help of timer add")); + cmd->init(); + cmd->add_name("create"); + cmd->add_name("make"); + cset->add(cmd= new cl_timer_delete_cmd("delete", 0, +"timer delete id Delete a timer", +"long help of timer delete")); + cmd->init(); + cmd->add_name("remove"); + cset->add(cmd= new cl_timer_get_cmd("get", 0, +"timer get [id] Get value of a timer, or all", +"long help of timer get")); + cmd->init(); + cset->add(cmd= new cl_timer_run_cmd("run", 0, +"timer start id Start a timer", +"long help of timer run")); + cmd->init(); + cmd->add_name("start"); + cset->add(cmd= new cl_timer_stop_cmd("stop", 0, +"timer stop id Stop a timer", +"long help of timer stop")); + cmd->init(); + cset->add(cmd= new cl_timer_value_cmd("set", 0, +"timer set id value\n" +" Set a timer value", +"long help of timer set")); + cmd->init(); + cmd->add_name("value"); + } + if (!super_cmd) { + cmdset->add(cmd= new cl_super_cmd("timer", 0, +"timer subcommand Manage timers", +"long help of timer", cset)); + cmd->init(); + } + + { + super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("memory")); + if (super_cmd) + cset= super_cmd->get_subcommands(); + else { + cset= new cl_cmdset(); + cset->init(); + } + /* + cset->add(cmd= new cl_memory_cmd("_no_parameters_", 0, +"memory Information about memory system", +"long help of memory")); + cmd->init(); + */ + cset->add(cmd= new cl_memory_createchip_cmd("createchip", 0, +"memory createchip id size cellsize\n" +" Create a new memory chip", +"long help of memory createchip")); + cmd->init(); + cmd->add_name("cchip"); + cset->add(cmd= new cl_memory_createaddressspace_cmd("createaddressspace", 0, +"memory createaddressspace id startaddr size\n" +" Create address space", +"long help of memory createaddressspace")); + cmd->init(); + cmd->add_name("createaddrspace"); + cmd->add_name("createaspace"); + cmd->add_name("caddressspace"); + cmd->add_name("caddrspace"); + cmd->add_name("caspace"); + cset->add(cmd= new cl_memory_createaddressdecoder_cmd("createaddressdecoder", 0, +"memory createaddressdecoder addressspace begin end chip begin\n" +" Create address decoder", +"long help of memory createaddressdecoder")); + cmd->init(); + cmd->add_name("createaddrdecoder"); + cmd->add_name("createadecoder"); + cmd->add_name("caddressdecoder"); + cmd->add_name("caddrdecoder"); + cmd->add_name("cadecoder"); + } + if (!super_cmd) { + cmdset->add(cmd= new cl_super_cmd("memory", 0, +"memory subcommand Manage memory chips and address spaces", +"long help of memory", cset)); + cmd->init(); + } } @@ -462,123 +592,105 @@ cl_uc::build_cmdset(class cl_cmdset *cmdset) * Read/write simulated memory */ -ulong -cl_uc::read_mem(enum mem_class type, t_mem addr) +t_mem +cl_uc::read_mem(const char *id, t_addr addr) { - class cl_mem *m; + class cl_address_space *m= address_space(id); - if ((m= (class cl_mem*)mems->at(type))) - return(m->read(addr)); - //FIXME -fprintf(stderr, "cl_uc::read_mem(type= %d, 0x%06lx) TROUBLE\n", type, addr); - return(0); + return(m?(m->read(addr)):0); } -ulong -cl_uc::get_mem(enum mem_class type, t_addr addr) +t_mem +cl_uc::get_mem(const char *id, t_addr addr) { - class cl_mem *m; + class cl_address_space *m= address_space(id); - if ((m= (class cl_mem*)mems->at(type))) - return(m->get(addr)); - //FIXME -printf("cl_uc::get_mem(type= %d, 0x%06lx) TROUBLE\n", type, addr); - return(0); + return(m?(m->get(addr)):0); } void -cl_uc::write_mem(enum mem_class type, t_addr addr, t_mem val) +cl_uc::write_mem(const char *id, t_addr addr, t_mem val) { - class cl_mem *m; + class cl_address_space *m= address_space(id); - if ((m= (class cl_mem*)mems->at(type))) - { - m->write(addr, &val); - //m->mem[addr]= val; - } - //FIXME -else printf("cl_uc::write_mem(type= %d, 0x%06lx, 0x%lx) TROUBLE\n", type, addr, val); + if (m) + m->write(addr, val); } void -cl_uc::set_mem(enum mem_class type, t_addr addr, t_mem val) +cl_uc::set_mem(const char *id, t_addr addr, t_mem val) { - class cl_mem *m; + class cl_address_space *m= address_space(id); - if ((m= (class cl_mem*)mems->at(type))) + if(m) m->set(addr, val); - //FIXME -else printf("cl_uc::set_mem(type= %d, 0x%06lx, 0x%lx) TROUBLE\n", type, addr, val); } -class cl_mem * + +/* +class cl_memory * cl_uc::mem(enum mem_class type) { + class cl_m *m; + if (mems->count < type) - //FIXME -{printf("TROUBLE\n"); return(0); -} - return((class cl_mem *)(mems->at(type))); + m= (class cl_m *)(mems->at(MEM_DUMMY)); + else + m= (class cl_m *)(mems->at(type)); + return(m); } +*/ -class cl_mem * -cl_uc::mem(char *class_name) +class cl_address_space * +cl_uc::address_space(const char *id) { - int i, found= 0; - char *mcn, *n, *s; + int i; - if (!class_name) - return(0); - s= n= strdup(class_name); - while (*s) - { - *s= toupper(*s); - s++; - } - if (!class_name || - !(*class_name)) + if (!id || + !(*id)) return(0); - for (i= 0; !found && i < mems->count; i++) + for (i= 0; i < address_spaces->count; i++) { - cl_mem *m= (cl_mem *)(mems->at(i)); + class cl_address_space *m= (cl_address_space *)(address_spaces->at(i)); if (!m || - !m->class_name || - !(*(m->class_name))) - continue; - s= mcn= strdup(m->class_name); - while (*s) - { - *s= toupper(*s); - s++; - } - if (strstr(/*m->class_name*/mcn,/*class_name*/n) == /*m->class_name*/mcn) - found= 1; - free(mcn); - if (found) - { - free(n); - return(m); - } + !m->have_real_name()) + continue; + if (m->is_inamed(id)) + return(m); } - free(n); return(0); } -/*TYPE_UBYTE * -cl_uc::MEM(enum mem_class type) +class cl_memory * +cl_uc::memory(const char *id) { - class cl_mem *m; + int i; - if ((m= mem(type)) == 0) - //FIXME -{printf("TROUBLE\n"); return(0); + if (!id || + !(*id)) + return(0); + for (i= 0; i < address_spaces->count; i++) + { + class cl_memory *m= (cl_memory *)(address_spaces->at(i)); + if (!m || + !m->have_real_name()) + continue; + if (m->is_inamed(id)) + return(m); + } + for (i= 0; i < memchips->count; i++) + { + class cl_memory *m= (cl_memory *)(memchips->at(i)); + if (!m || + !m->have_real_name()) + continue; + if (m->is_inamed(id)) + return(m); + } + return(0); } - return((TYPE_UBYTE *)(m->mem)); -}*/ -/* Local function for `read_hex_file' method to read some bytes */ - static long ReadInt(FILE *f, bool *ok, int bytes) { @@ -589,7 +701,7 @@ ReadInt(FILE *f, bool *ok, int bytes) while (bytes) { if (fscanf(f, "%2c", &s2[0]) == EOF) - return(0); + return(0); s2[2]= '\0'; l= l*256 + strtol(s2, NULL, 16); bytes--; @@ -608,7 +720,7 @@ ReadInt(FILE *f, bool *ok, int bytes) */ long -cl_uc::read_hex_file(const char *name) +cl_uc::read_hex_file(const char *nam) { FILE *f; int c; @@ -624,28 +736,35 @@ cl_uc::read_hex_file(const char *name) bool ok, get_low= 1; uchar low= 0, high; - if (!name) + if (!rom) { sim->app->get_commander()-> - dd_printf("cl_uc::read_hex_file File name not specified\n"); + dd_printf("No ROM address space to read in.\n"); + return(-1); + } + + if (!nam) + { + sim->app->get_commander()-> + dd_printf("cl_uc::read_hex_file File name not specified\n"); return(-1); } else - if ((f= fopen(name, "r")) == NULL) + if ((f= fopen(nam, "r")) == NULL) { - fprintf(stderr, "Can't open `%s': %s\n", name, strerror(errno)); - return(-1); + fprintf(stderr, "Can't open `%s': %s\n", nam, strerror(errno)); + return(-1); } //memset(inst_map, '\0', sizeof(inst_map)); ok= DD_TRUE; while (ok && - rtyp != 1) + rtyp != 1) { while (((c= getc(f)) != ':') && - (c != EOF)) ; + (c != EOF)) ; if (c != ':') - {fprintf(stderr, ": not found\n");break;} + {fprintf(stderr, ": not found\n");break;} recnum++; dnum= ReadInt(f, &ok, 1);//printf("dnum=%02x",dnum); chk = dnum; @@ -655,75 +774,67 @@ cl_uc::read_hex_file(const char *name) rtyp= ReadInt(f, &ok, 1);//printf("rtyp=%02x ",rtyp); chk+= rtyp; for (i= 0; ok && (i < dnum); i++) - { - rec[i]= ReadInt(f, &ok, 1);//printf("%02x",rec[i]); - chk+= rec[i]; - } + { + rec[i]= ReadInt(f, &ok, 1);//printf("%02x",rec[i]); + chk+= rec[i]; + } if (ok) - { - sum= ReadInt(f, &ok, 1);//printf(" sum=%02x\n",sum); - if (ok) - { - if (((sum + chk) & 0xff) == 0) - { - if (rtyp == 0) - { - if (get_mem_width(MEM_ROM) > 8) - addr/= 2; - for (i= 0; i < dnum; i++) - { - if (get_mem_width(MEM_ROM) <= 8) - { - set_mem(MEM_ROM, addr, rec[i]); - addr++; - written++; - } - else if (get_mem_width(MEM_ROM) <= 16) - { - if (get_low) - { - low= rec[i]; - get_low= 0; - } - else - { - high= rec[i]; - set_mem(MEM_ROM, addr, (high*256)+low); - addr++; - written++; - get_low= 1; - } - } - } - } - else - if (sim->app->args->get_iarg('V', 0) && - rtyp != 1) - sim->app->get_commander()-> - dd_printf("Unknown record type %d(0x%x)\n", - rtyp, rtyp); - } - else - if (sim->app->args->get_iarg('V', 0)) - sim->app->get_commander()-> - dd_printf("Checksum error (%x instead of %x) in " - "record %ld.\n", chk, sum, recnum); - } - else - if (sim->app->args->get_iarg('V', 0)) - sim->app->get_commander()-> - dd_printf("Read error in record %ld.\n", recnum); - } + { + sum= ReadInt(f, &ok, 1);//printf(" sum=%02x\n",sum); + if (ok) + { + if (((sum + chk) & 0xff) == 0) + { + if (rtyp == 0) + { + if (rom->width > 8) + addr/= 2; + for (i= 0; i < dnum; i++) + { + if (rom->width <= 8) + { + rom->set(addr, rec[i]); + addr++; + written++; + } + else if (rom->width <= 16) + { + if (get_low) + { + low= rec[i]; + get_low= 0; + } + else + { + high= rec[i]; + rom->set(addr, (high*256)+low); + addr++; + written++; + get_low= 1; + } + } + } + } + else + if (rtyp != 1) + application->debug("Unknown record type %d(0x%x)\n", + rtyp, rtyp); + } + else + application->debug("Checksum error (%x instead of %x) in " + "record %ld.\n", chk, sum, recnum); + } + else + application->debug("Read error in record %ld.\n", recnum); + } } - if (get_mem_width(MEM_ROM) > 8 && + if (rom->width > 8 && !get_low) - set_mem(MEM_ROM, addr, low); + rom->set(addr, low); - if (name) + if (nam) fclose(f); - if (sim->app->args->get_iarg('V', 0)) - sim->app->get_commander()->dd_printf("%ld records have been read\n", - recnum); + application->debug("%ld records have been read\n", recnum); analyze(0); return(written); } @@ -741,39 +852,35 @@ cl_uc::read_hex_file(const char *name) bool cl_uc::inst_at(t_addr addr) { - class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); - if (!rom) return(0); - return(rom->inst_map->get(addr)); + return(rom->get_cell_flag(addr, CELL_INST)); } void cl_uc::set_inst_at(t_addr addr) { - class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); - if (rom) - rom->inst_map->set(addr); + rom->set_cell_flag(addr, DD_TRUE, CELL_INST); } void cl_uc::del_inst_at(t_addr addr) { - class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); - if (rom) - rom->inst_map->clear(addr); + rom->set_cell_flag(addr, DD_FALSE, CELL_INST); } bool cl_uc::there_is_inst(void) { - class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); - if (!rom) return(0); - return(!(rom->inst_map->empty())); + bool got= DD_FALSE; + t_addr addr; + for (addr= 0; rom->valid_address(addr) && !got; addr++) + got= rom->get_cell_flag(addr, CELL_INST); + return(got); } @@ -784,30 +891,30 @@ cl_uc::there_is_inst(void) /* Register callback hw objects for mem read/write */ -void +/*void cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw) { - class cl_mem *m; + class cl_m *m; class cl_memloc *l; - if ((m= (class cl_mem*)mems->at(type))) + if ((m= (class cl_m*)mems->at(type))) { if ((l= m->read_locs->get_loc(addr)) == 0) - { - l= new cl_memloc(addr); - l->init(); - m->read_locs->add(l); - } + { + l= new cl_memloc(addr); + l->init(); + m->read_locs->add(l); + } l->hws->add(hw); } else printf("cl_uc::register_hw_read TROUBLE\n"); -} +}*/ -void +/*void cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw) { -} +}*/ /* Looking for a specific HW element */ @@ -823,7 +930,7 @@ cl_uc::get_hw(enum hw_cath cath, int *idx) { hw= (class cl_hw *)(hws->at(i)); if (hw->cathegory == cath) - break; + break; } if (i >= hws->count) return(0); @@ -844,7 +951,7 @@ cl_uc::get_hw(char *id_string, int *idx) { hw= (class cl_hw *)(hws->at(i)); if (strstr(hw->id_string, id_string) == hw->id_string) - break; + break; } if (i >= hws->count) return(0); @@ -863,7 +970,7 @@ cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx) i= *idx; hw= get_hw(cath, &i); while (hw && - hw->id != hwid) + hw->id != hwid) { i++; hw= get_hw(cath, &i); @@ -884,7 +991,7 @@ cl_uc::get_hw(char *id_string, int hwid, int *idx) i= *idx; hw= get_hw(id_string, &i); while (hw && - hw->id != hwid) + hw->id != hwid) { i++; hw= get_hw(id_string, &i); @@ -922,26 +1029,26 @@ cl_uc::bit_tbl(void) } char * -cl_uc::disass(t_addr addr, char *sep) +cl_uc::disass(t_addr addr, const char *sep) { char *buf; buf= (char*)malloc(100); - strcpy(buf, "uc::do_disass unimplemented\n"); + strcpy(buf, "uc::disass() unimplemented\n"); return(buf); } void -cl_uc::print_disass(t_addr addr, class cl_console *con) +cl_uc::print_disass(t_addr addr, class cl_console_base *con) { char *dis; class cl_brk *b; int i; - class cl_mem *rom= mem(MEM_ROM); - t_mem code= get_mem(MEM_ROM, addr); if (!rom) return; + + t_mem code= rom->get(addr); b= fbrk_at(addr); dis= disass(addr, NULL); if (b) @@ -951,10 +1058,10 @@ cl_uc::print_disass(t_addr addr, class cl_console *con) con->dd_printf("%c ", inst_at(addr)?' ':'?'); con->dd_printf(rom->addr_format, addr); con->dd_printf(" "); con->dd_printf(rom->data_format, code); - for (i= 1; i < inst_length(code); i++) + for (i= 1; i < inst_length(addr); i++) { con->dd_printf(" "); - con->dd_printf(rom->data_format, get_mem(MEM_ROM, addr+i)); + con->dd_printf(rom->data_format, rom->get(addr+i)); } int li= longest_inst(); while (i < li) @@ -962,7 +1069,7 @@ cl_uc::print_disass(t_addr addr, class cl_console *con) int j; j= rom->width/4 + ((rom->width%4)?1:0) + 1; while (j) - con->dd_printf(" "), j--; + con->dd_printf(" "), j--; i++; } con->dd_printf(" %s\n", dis); @@ -970,19 +1077,40 @@ cl_uc::print_disass(t_addr addr, class cl_console *con) } void -cl_uc::print_regs(class cl_console *con) +cl_uc::print_regs(class cl_console_base *con) { con->dd_printf("No registers\n"); } int -cl_uc::inst_length(t_mem code) +cl_uc::inst_length(t_addr addr) { struct dis_entry *tabl= dis_tbl(); int i; + t_mem code; + + if (!rom) + return(0); + code = rom->get(addr); for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ; - return(tabl[i].mnemonic?tabl[i].length:1); + return(tabl[i].mnemonic?tabl[i].length:1); +} + +int +cl_uc::inst_branch(t_addr addr) +{ + struct dis_entry *tabl= dis_tbl(); + int i; + t_mem code; + + if (!rom) + return(0); + + code = rom->get(addr); + for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) + ; + return tabl[i].branch; } int @@ -992,10 +1120,10 @@ cl_uc::longest_inst(void) int max= 0; while (de && - de->mnemonic) + de->mnemonic) { if (de->length > max) - max= de->length; + max= de->length; de++; } return(max); @@ -1008,26 +1136,49 @@ cl_uc::get_name(t_addr addr, struct name_entry tab[], char *buf) i= 0; while (tab[i].name && - (!(tab[i].cpu_type & type) || - (tab[i].addr != addr))) + (!(tab[i].cpu_type & type) || + (tab[i].addr != addr))) i++; if (tab[i].name) strcpy(buf, tab[i].name); return(tab[i].name != NULL); } +bool +cl_uc::symbol2address(char *sym, struct name_entry tab[], + t_addr *addr) +{ + int i; + + if (!sym || + !*sym) + return(DD_FALSE); + i= 0; + while (tab[i].name && + (!(tab[i].cpu_type & type) || + strcasecmp(sym, tab[i].name) != 0)) + i++; + if (tab[i].name) + { + if (addr) + *addr= tab[i].addr; + return(DD_TRUE); + } + return(DD_FALSE); +} + char * cl_uc::symbolic_bit_name(t_addr bit_address, - class cl_mem *mem, - t_addr mem_addr, - t_mem bit_mask) + class cl_memory *mem, + t_addr mem_addr, + t_mem bit_mask) { char *sym_name= 0; int i; i= 0; while (bit_tbl()[i].name && - (bit_tbl()[i].addr != bit_address)) + (bit_tbl()[i].addr != bit_address)) i++; if (bit_tbl()[i].name) { @@ -1036,17 +1187,17 @@ cl_uc::symbolic_bit_name(t_addr bit_address, } if (mem && - mem->class_name && - strstr(mem->class_name, "sfr") == mem->class_name) + mem->have_real_name() && + strstr(mem->get_name(), "sfr") == mem->get_name()) { i= 0; while (sfr_tbl()[i].name && - (sfr_tbl()[i].addr != mem_addr)) - i++; + (sfr_tbl()[i].addr != mem_addr)) + i++; if (sfr_tbl()[i].name) - sym_name= strdup(sfr_tbl()[i].name); + sym_name= strdup(sfr_tbl()[i].name); else - sym_name= 0; + sym_name= 0; } if (!sym_name) { @@ -1068,14 +1219,157 @@ cl_uc::symbolic_bit_name(t_addr bit_address, } +/* + * Messages to broadcast + */ + +bool +cl_uc::handle_event(class cl_event &event) +{ + switch (event.what) + { + case ev_address_space_added: + { + try { + class cl_event_address_space_added &e= + dynamic_cast(event); + address_space_added(e.as); + e.handle(); + } + catch (...) + { break; } + break; + } + default: + return(pass_event_down(event)); + break; + } + return(DD_FALSE); +} + +/* +void +cl_uc::mem_cell_changed(class cl_address_space *mem, t_addr addr) +{ + if (hws) + hws->mem_cell_changed(mem, addr); + else + printf("JAJ uc\n");//FIXME + if (mems && + mems->count) + { + int i; + for (i= 0; i < mems->count; i++) + { + } + } +} +*/ + +void +cl_uc::address_space_added(class cl_address_space *as) +{ + if (hws) + hws->address_space_added(as); + else + printf("JAJ uc\n");//FIXME +} + + +/* + * Error handling + */ + +void +cl_uc::error(class cl_error *error) +{ + errors->add(error); + if ((error->inst= inst_exec)) + error->PC= instPC; +} + +void +cl_uc::check_errors(void) +{ + int i; + class cl_commander_base *c= sim->app->get_commander(); + bool must_stop= DD_FALSE; + + if (c) + { + for (i= 0; i < errors->count; i++) + { + class cl_error *error= (class cl_error *)(errors->at(i)); + if (!error->is_on()) + continue; + error->print(c); + must_stop= must_stop || (error->get_type() & err_stop); + if (error->inst) + { + class cl_console_base *con; + con= c->actual_console; + if (!con) + con= c->frozen_console; + if (con) + { + con->dd_printf("Erronouse instruction: "); + print_disass(error->PC, con); + } + } + } + errors->free_all(); + } + else + fprintf(stderr, "no actual console, %d errors\n", errors->count); + if (must_stop) + sim->stop(resERROR); +} + + +/* + * Converting bit address into real memory + */ + +class cl_address_space * +cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask) +{ + if (memaddr) + *memaddr= bitaddr; + if (bitmask) + *bitmask= 1 << (bitaddr & 0x7); + return(0); // abstract... +} + + /* * Execution */ int -cl_uc::tick(int cycles) +cl_uc::tick_hw(int cycles) { class cl_hw *hw; + int i;//, cpc= clock_per_cycle(); + + // tick hws + for (i= 0; i < hws->count; i++) + { + hw= (class cl_hw *)(hws->at(i)); + if (hw->flags & HWF_INSIDE) + hw->tick(cycles); + } + do_extra_hw(cycles); + return(0); +} + +void +cl_uc::do_extra_hw(int cycles) +{} + +int +cl_uc::tick(int cycles) +{ + //class cl_hw *hw; int i, cpc= clock_per_cycle(); // increase time @@ -1089,20 +1383,15 @@ cl_uc::tick(int cycles) { class cl_ticker *t= (class cl_ticker *)(counters->at(i)); if (t) - { - if ((t->options&TICK_INISR) || - il->level < 0) - t->tick(cycles * cpc); - } + { + if ((t->options&TICK_INISR) || + il->level < 0) + t->tick(cycles * cpc); + } } - // tick hws - for (i= 0; i < hws->count; i++) - { - hw= (class cl_hw *)(hws->at(i)); - if (hw->flags & HWF_INSIDE) - hw->tick(cycles); - } + // tick for hardwares + inst_ticks+= cycles; return(0); } @@ -1115,19 +1404,19 @@ cl_uc::get_counter(int nr) } class cl_ticker * -cl_uc::get_counter(char *name) +cl_uc::get_counter(char *nam) { int i; - if (!name) + if (!nam) return(0); for (i= 0; i < counters->count; i++) { class cl_ticker *t= (class cl_ticker *)(counters->at(i)); if (t && - t->name && - strcmp(t->name, name) == 0) - return(t); + t->get_name() && + strcmp(t->get_name(), nam) == 0) + return(t); } return(0); } @@ -1141,7 +1430,7 @@ cl_uc::add_counter(class cl_ticker *ticker, int nr) } void -cl_uc::add_counter(class cl_ticker *ticker, char */*name*/) +cl_uc::add_counter(class cl_ticker *ticker, char */*nam*/) { int i; @@ -1151,10 +1440,10 @@ cl_uc::add_counter(class cl_ticker *ticker, char */*name*/) { class cl_ticker *t= (class cl_ticker *)(counters->at(i)); if (!t) - { - counters->put_at(i, ticker); - return; - } + { + counters->put_at(i, ticker); + return; + } } counters->add(ticker); } @@ -1172,23 +1461,23 @@ cl_uc::del_counter(int nr) } void -cl_uc::del_counter(char *name) +cl_uc::del_counter(char *nam) { int i; - if (!name) + if (!nam) return; for (i= 0; i < counters->count; i++) { class cl_ticker *t= (class cl_ticker *)(counters->at(i)); if (t && - t->name && - strcmp(t->name, name) == 0) - { - delete t; - counters->put_at(i, 0); - return; - } + t->get_name() && + strcmp(t->get_name(), nam) == 0) + { + delete t; + counters->put_at(i, 0); + return; + } } } @@ -1200,16 +1489,18 @@ t_mem cl_uc::fetch(void) { ulong code; + + if (!rom) + return(0); - code= read_mem(MEM_ROM, PC); - PC++; - if (PC >= get_mem_size(MEM_ROM)) - PC= 0; + code= rom->read(PC); + PC= rom->inc_address(PC); return(code); } /* - * Fetch but checking for breakpoint hit first + * Fetch but checking for breakpoint hit first, returns TRUE if + * a breakpoint is hit */ bool @@ -1220,15 +1511,17 @@ cl_uc::fetch(t_mem *code) if (!code) return(0); - if (sim->state & SIM_GO) + if ((sim->state & SIM_GO) && + rom) { - if ((brk= fbrk->get_bp(PC, &idx)) && - (brk->do_hit())) - { - if (brk->perm == brkDYNAMIC) - fbrk->del_bp(PC); - return(1); - } + if (rom->get_cell_flag(PC, CELL_FETCH_BRK) && + (brk= fbrk->get_bp(PC, &idx)) && + (brk->do_hit())) + { + if (brk->perm == brkDYNAMIC) + fbrk->del_bp(PC); + return(1); + } } *code= fetch(); return(0); @@ -1242,7 +1535,7 @@ cl_uc::do_inst(int step) if (step < 0) step= 1; while (step-- && - res == resGO) + res == resGO) { pre_inst(); res= exec_inst(); @@ -1255,17 +1548,29 @@ cl_uc::do_inst(int step) void cl_uc::pre_inst(void) -{} +{ + inst_exec= DD_TRUE; + inst_ticks= 0; + events->disconn_all(); +} int cl_uc::exec_inst(void) { + instPC= PC; return(resGO); } void cl_uc::post_inst(void) -{} +{ + tick_hw(inst_ticks); + if (errors->count) + check_errors(); + if (events->count) + check_events(); + inst_exec= DD_FALSE; +} /* @@ -1294,35 +1599,103 @@ cl_uc::clock_per_cycle(void) */ void -cl_uc::st_push(class cl_stack_op *op) +cl_uc::stack_write(class cl_stack_op *op) { - st_ops->push(op); + if (op->get_op() & stack_read_operation) + { + class cl_error_stack_tracker_wrong_handle *e= new + cl_error_stack_tracker_wrong_handle(DD_FALSE); + //fprintf(stderr, "%06"_A_"x cl_uc::stack_read() should be called for " + //"%s\n", op->get_pc(), op->get_op_name()); + e->init(); + error(e); + return; + } + stack_ops->push(op); } void -cl_uc::st_call(class cl_stack_op *op) -{ - st_ops->push(op); -} - -int -cl_uc::st_pop(class cl_stack_op *op) +cl_uc::stack_read(class cl_stack_op *op) { - class cl_stack_op *sop= (class cl_stack_op *)(st_ops->pop()); - - if (!sop) - return(1); - return(0); -} + class cl_stack_op *top= (class cl_stack_op *)(stack_ops->top()); + + if (op->get_op() & stack_write_operation) + { + class cl_error_stack_tracker_wrong_handle *e= new + cl_error_stack_tracker_wrong_handle(DD_TRUE); + e->init(); + error(e); + //fprintf(stderr, "%06"_A_"x cl_uc::stack_write() should be called for " + //"%s\n", op->get_pc(), op->get_op_name()); + return; + } + if (!top) + { + class cl_error *e= new cl_error_stack_tracker_empty(op); + /*printf("0x%06"_A_"x %s operation on stack but no operation was before\n + ", + op->get_pc(), op->get_op_name());*/ + e->init(); + error(e); + return; + } -int -cl_uc::st_ret(class cl_stack_op *op) -{ - class cl_stack_op *sop= (class cl_stack_op *)(st_ops->pop()); + if (top) + { + if (!top->match(op)) + { + class cl_error *e= new cl_error_stack_tracker_unmatch(top, op); + e->init(); + error(e); + /*printf("0x%06"_A_"x %s operation on stack but last was %s\n", + op->get_pc(), op->get_op_name(), top->get_op_name());*/ + } + int top_size= top->data_size(), op_size= op->data_size(); + if (top_size != op_size) + { + application->debug("0x%06"_A_"x %d bytes to read out of stack " + "but %d was pushed in last operation\n", + op->get_pc(), op_size, top_size); + } + } - if (!sop) - return(1); - return(0); + int removed= 0; + while (top && + top->can_removed(op)) + { + top= (class cl_stack_op *)stack_ops->pop(); + delete top; + top= (class cl_stack_op *)stack_ops->top(); + removed++; + } + if (removed != 1) + { + application->debug("0x%06"_A_"x %d ops removed from stack-tracker " + "when %s happened, top pc=0x%06"_A_"x " + "top before=0x%06"_A_"x op after=0x%06"_A_"x\n", + op->get_pc(), removed, op->get_op_name(), + top?(top->get_pc()):0, top?(top->get_before()):0, + op->get_after()); + } + + if (top) + { + int ta= top->get_after(), oa= op->get_after(); + if (ta != oa) + { + application->debug("0x%06"_A_"x stack still inconsistent after %s, " + "%d byte(s) should be read out; top after" + "=0x%06"_A_"x op after=0x%06"_A_"x\n", + op->get_pc(), op->get_op_name(), abs(ta-oa), + ta, oa); + class cl_error *e= + new cl_error_stack_tracker_inconsistent(op, abs(ta-oa)); + e->init(); + error(e); + } + } + + delete op; } @@ -1348,8 +1721,8 @@ cl_uc::ebrk_at(t_addr addr, char *id) { eb= (class cl_ev_brk *)(ebrk->at(i)); if (eb->addr == addr && - !strcmp(eb->id, id)) - return(eb); + !strcmp(eb->id, id)) + return(eb); } return(0); } @@ -1398,22 +1771,29 @@ cl_uc::rm_ebrk(t_addr addr, char *id) { eb= (class cl_ev_brk *)(ebrk->at(i)); if (eb->addr == addr && - !strcmp(eb->id, id)) - ebrk->free_at(i); + !strcmp(eb->id, id)) + ebrk->del_bp(i, 0); } } /* Remove a breakpoint specified by its number */ -void +bool cl_uc::rm_brk(int nr) { class cl_brk *bp; if ((bp= brk_by_nr(fbrk, nr))) - fbrk->del_bp(bp->addr); + { + fbrk->del_bp(bp->addr); + return(DD_TRUE); + } else if ((bp= brk_by_nr(ebrk, nr))) - ebrk->free_at(ebrk->index_of(bp)); + { + ebrk->del_bp(ebrk->index_of(bp), 0); + return(DD_TRUE); + } + return(DD_FALSE); } void @@ -1431,7 +1811,7 @@ cl_uc::remove_all_breaks(void) fbrk->del_bp(brk->addr); } while (ebrk->count) - ebrk->free_at(ebrk->count-1); + ebrk->del_bp(ebrk->count-1, 0); } int @@ -1446,50 +1826,63 @@ cl_uc::make_new_brknr(void) } class cl_ev_brk * -cl_uc::mk_ebrk(enum brk_perm perm, class cl_mem *mem, - char op, t_addr addr, int hit) +cl_uc::mk_ebrk(enum brk_perm perm, class cl_address_space *mem, + char op, t_addr addr, int hit) { class cl_ev_brk *b; op= toupper(op); - switch (mem->type) - { - case MEM_ROM: - if (op == 'R') - b= new cl_rc_brk(make_new_brknr(), addr, perm, hit); - else - return(0); - break; - case MEM_IRAM: - if (op == 'R') - b= new cl_ri_brk(make_new_brknr(), addr, perm, hit); - else if (op == 'W') - b= new cl_wi_brk(make_new_brknr(), addr, perm, hit); - else - return(0); - break; - case MEM_XRAM: - if (op == 'R') - b= new cl_rx_brk(make_new_brknr(), addr, perm, hit); - else if (op == 'W') - b= new cl_wx_brk(make_new_brknr(), addr, perm, hit); - else - return(0); - break; - case MEM_SFR: - if (op == 'R') - b= new cl_rs_brk(make_new_brknr(), addr, perm, hit); - else if (op == 'W') - b= new cl_ws_brk(make_new_brknr(), addr, perm, hit); - else - return(0); - break; - default: - return(0); - } + b= new cl_ev_brk(mem, make_new_brknr(), addr, perm, hit, op); b->init(); return(b); } +void +cl_uc::check_events(void) +{ + int i; + for (i= 0; i < events->count; i++) + { + class cl_ev_brk *brk= + dynamic_cast(events->object_at(i)); + sim->stop(brk); + } + sim->stop(resBREAKPOINT); +} + + +/* + * Errors + *---------------------------------------------------------------------------- + */ + +cl_error_unknown_code::cl_error_unknown_code(class cl_uc *the_uc) +{ + uc= the_uc; + classification= uc_error_registry.find("unknown_code"); +} + +void +cl_error_unknown_code::print(class cl_commander_base *c) +{ + c->dd_printf("%s: unknown instruction code at ", get_type_name()); + if (uc->rom) + { + c->dd_printf(uc->rom->addr_format, PC); + c->dd_printf(" ("); + c->dd_printf(uc->rom->data_format, uc->rom->get(PC)); + c->dd_printf(")"); + } + else + c->dd_printf("0x%06x", PC); + c->dd_printf("\n"); +} + +cl_uc_error_registry::cl_uc_error_registry(void) +{ + class cl_error_class *prev = uc_error_registry.find("non-classified"); + prev = register_error(new cl_error_class(err_error, "unknown_code", prev, ERROR_OFF)); +} + /* End of uc.cc */