X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fsim.src%2Fuc.cc;h=9eff9810db352a385024d3da06a5bd4f2bdee78f;hb=a8b895ee0de37ed91bcc35e1633da977a638e4bf;hp=026648b0b50088e26106200c6add1570d3af8a1f;hpb=f4f097b91aab55fb5fe55566e870dd201bafee19;p=fw%2Fsdcc diff --git a/sim/ucsim/sim.src/uc.cc b/sim/ucsim/sim.src/uc.cc index 026648b0..9eff9810 100644 --- a/sim/ucsim/sim.src/uc.cc +++ b/sim/ucsim/sim.src/uc.cc @@ -30,14 +30,33 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#include #include "i_string.h" +// prj +#include "globals.h" +#include "utils.h" + +// cmd.src +#include "newcmdcl.h" +#include "cmduccl.h" +#include "bpcl.h" +#include "getcl.h" +#include "setcl.h" +#include "infocl.h" +#include "timercl.h" +#include "cmdstatcl.h" +#include "cmdmemcl.h" +#include "cmdutil.h" + +// local, sim.src #include "uccl.h" #include "hwcl.h" #include "memcl.h" #include "simcl.h" #include "itsrccl.h" +static class cl_uc_error_registry uc_error_registry; /* * Clock counter @@ -50,14 +69,10 @@ cl_ticker::cl_ticker(int adir, int in_isr, char *aname) 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) @@ -79,11 +94,32 @@ cl_ticker::get_rtime(double xtal) void cl_ticker::dump(int nr, double xtal, class cl_console *con) { - con->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); + con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n", + 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; } @@ -95,65 +131,93 @@ 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); - hws = new cl_list(2, 1); - options= new cl_list(2, 2); - for (i= MEM_ROM; i < MEM_TYPES; i++) - mems->add(0); + //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); + 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; + int i; + set_name("controller"); cl_base::init(); - if (!(sim->arg_avail('X')) || - sim->get_farg('X', 0) == 0) - xtal= 11059200; + if (xtal_option->use("xtal")) + xtal= xtal_option->get_value(xtal); else - xtal= sim->get_farg('X', 0); - for (mc= MEM_ROM; mc < MEM_TYPES; mc++) - { - class cl_mem *m= mk_mem((enum mem_class)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(); reset(); + class cl_cmdset *cs= sim->app->get_commander()->cmdset; + build_cmdset(cs); + + for (i= 0; i < sim->app->in_files->count; i++) + { + 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); + } + } return(0); } @@ -168,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; @@ -176,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; @@ -184,131 +248,448 @@ 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) -{ - 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_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) { } +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, +"state State of microcontroller", +"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")); + cmd->init(); + cmd->add_name("load"); + + cmdset->add(cmd= new cl_dl_cmd("download", 0, +"download Load (intel.hex) data", +"long help of download")); + cmd->init(); + cmd->add_name("dl"); + + cmdset->add(cmd= new cl_pc_cmd("pc", 0, +"pc [addr] Set/get PC", +"long help of pc")); + cmd->init(); + + cmdset->add(cmd= new cl_reset_cmd("reset", 0, +"reset Reset", +"long help of reset")); + cmd->init(); + + 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_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", DD_TRUE, +"dc [start [stop]] Dump code in disass form", +"long help of dc")); + cmd->init(); + + cmdset->add(cmd= new cl_disassemble_cmd("disassemble", DD_TRUE, +"disassemble [start [offset [lines]]]\n" +" Disassemble code", +"long help of disassemble")); + cmd->init(); + + cmdset->add(cmd= new cl_fill_cmd("fill", 0, +"fill memory_type start end data\n" +" Fill memory region with data", +"long help of fill")); + cmd->init(); + + cmdset->add(cmd= new cl_where_cmd("where", 0, +"where memory_type data...\n" +" Case unsensitive search for data", +"long help of where")); + cmd->init(); + + cmdset->add(cmd= new cl_Where_cmd("Where", 0, +"Where memory_type data...\n" +" Case sensitive search for data", +"long help of Where")); + cmd->init(); + + cmdset->add(cmd= new cl_break_cmd("break", 0, +"break addr [hit] Set fix breakpoint\n" +"break mem_type r|w addr [hit]\n" +" Set fix event breakpoint", +"long help of break")); + cmd->init(); + + cmdset->add(cmd= new cl_tbreak_cmd("tbreak", 0, +"tbreak addr [hit] Set temporary breakpoint\n" +"tbreak mem_type r|w addr [hit]\n" +" Set temporary event breakpoint", +"long help of tbreak")); + cmd->init(); + + cmdset->add(cmd= new cl_clear_cmd("clear", 0, +"clear [addr...] Clear fix breakpoint", +"long help of clear")); + cmd->init(); + + cmdset->add(cmd= new cl_delete_cmd("delete", 0, +"delete [nr...] Delete breakpoint(s)", +"long help of clear")); + cmd->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, +"get option name\n" +" Get value of an option", +"long help of get option")); +cmd->init();*/ + } + 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(); + } + + { + 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", +"long help of set memory")); + cmd->init(); + cset->add(cmd= new cl_set_bit_cmd("bit", 0, +"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_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(); + } + 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(); + } + + { // 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")); + cmd->add_name("bp"); + cmd->init(); + cset->add(cmd= new cl_info_reg_cmd("registers", 0, +"info registers List of integer registers and their contents", +"long help of info registers")); + cmd->init(); + cset->add(cmd= new cl_info_hw_cmd("hardware", 0, +"info hardware cathegory\n" +" Status of hardware elements of the CPU", +"long help of info hardware")); + 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(); + } + 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(); + } + + { + 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(); + } +} + /* * Read/write simulated memory */ -ulong -cl_uc::read_mem(enum mem_class type, long addr) +t_mem +cl_uc::read_mem(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, long addr) +t_mem +cl_uc::get_mem(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, long addr, ulong val) +cl_uc::write_mem(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, long addr, ulong val) +cl_uc::set_mem(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); } +*/ -TYPE_UBYTE * -cl_uc::MEM(enum mem_class type) +class cl_address_space * +cl_uc::address_space(char *id) { - class cl_mem *m; + int i; - if ((m= mem(type)) == 0) - //FIXME -{printf("TROUBLE\n"); return(0); -} - return((uchar *)(m->mem)); + if (!id || + !(*id)) + return(0); + for (i= 0; i < address_spaces->count; i++) + { + class cl_address_space *m= (cl_address_space *)(address_spaces->at(i)); + if (!m || + !m->have_real_name()) + continue; + if (m->is_inamed(id)) + return(m); + } + return(0); } +class cl_memory * +cl_uc::memory(char *id) +{ + int i; + + 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); +} -/* Local function for `read_hex_file' method to read some bytes */ static long ReadInt(FILE *f, bool *ok, int bytes) @@ -320,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--; @@ -339,10 +720,10 @@ 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; - char c; + int c; long written= 0, recnum= 0; uchar dnum; // data number @@ -355,27 +736,35 @@ cl_uc::read_hex_file(const char *name) bool ok, get_low= 1; uchar low= 0, high; - if (!name) + if (!rom) { - sim->cmd->printf("cl_uc::read_hex_file File name not specified\n"); + sim->app->get_commander()-> + 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; @@ -385,71 +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->get_iarg('V', 0) && - rtyp != 1) - sim->cmd->printf("Unknown record type %d(0x%x)\n", - rtyp, rtyp); - } - else - if (sim->get_iarg('V', 0)) - sim->cmd->printf("Checksum error (%x instead of %x) in " - "record %ld.\n", chk, sum, recnum); - } - else - if (sim->get_iarg('V', 0)) - sim->cmd->printf("Read error in record %ld.\n", recnum); - } - } - if (get_mem_width(MEM_ROM) > 8 && + { + 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 (rom->width > 8 && !get_low) - set_mem(MEM_ROM, addr, low); + rom->set(addr, low); - if (name) + if (nam) fclose(f); - if (sim->get_iarg('V', 0)) - sim->cmd->printf("%ld records have been read\n", recnum); + application->debug("%ld records have been read\n", recnum); analyze(0); return(written); } @@ -465,41 +850,37 @@ cl_uc::read_hex_file(const char *name) */ bool -cl_uc::inst_at(uint addr) +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(uint addr) +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(uint addr) +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); } @@ -510,30 +891,30 @@ cl_uc::there_is_inst(void) /* Register callback hw objects for mem read/write */ -void -cl_uc::register_hw_read(enum mem_class type, long addr, class cl_hw *hw) +/*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 -cl_uc::register_hw_write(enum mem_class type, long addr, class cl_hw *hw) +/*void +cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw) { -} +}*/ /* Looking for a specific HW element */ @@ -549,7 +930,28 @@ 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); + if (idx) + *idx= i; + return(hw); +} + +class cl_hw * +cl_uc::get_hw(char *id_string, int *idx) +{ + class cl_hw *hw= 0; + int i= 0; + + if (idx) + i= *idx; + for (; i < hws->count; i++) + { + hw= (class cl_hw *)(hws->at(i)); + if (strstr(hw->id_string, id_string) == hw->id_string) + break; } if (i >= hws->count) return(0); @@ -568,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); @@ -579,6 +981,27 @@ cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx) return(hw); } +class cl_hw * +cl_uc::get_hw(char *id_string, int hwid, int *idx) +{ + class cl_hw *hw; + int i= 0; + + if (idx) + i= *idx; + hw= get_hw(id_string, &i); + while (hw && + hw->id != hwid) + { + i++; + hw= get_hw(id_string, &i); + } + if (hw && + idx) + *idx= i; + return(hw); +} + /* * Help of the command interpreter @@ -606,61 +1029,347 @@ cl_uc::bit_tbl(void) } char * -cl_uc::disass(uint addr, char *sep) +cl_uc::disass(t_addr addr, 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(uint addr, class cl_console *con) +cl_uc::print_disass(t_addr addr, class cl_console *con) { - con->printf("uc::print_disass unimplemented\n"); + char *dis; + class cl_brk *b; + int i; + + if (!rom) + return; + + t_mem code= rom->get(addr); + b= fbrk_at(addr); + dis= disass(addr, NULL); + if (b) + con->dd_printf("%c", (b->perm == brkFIX)?'F':'D'); + else + con->dd_printf(" "); + 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(addr); i++) + { + con->dd_printf(" "); + con->dd_printf(rom->data_format, rom->get(addr+i)); + } + int li= longest_inst(); + while (i < li) + { + int j; + j= rom->width/4 + ((rom->width%4)?1:0) + 1; + while (j) + con->dd_printf(" "), j--; + i++; + } + con->dd_printf(" %s\n", dis); + free(dis); } void cl_uc::print_regs(class cl_console *con) { - con->printf("No registers\n"); + con->dd_printf("No registers\n"); } int -cl_uc::inst_length(uint 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 +cl_uc::longest_inst(void) +{ + struct dis_entry *de= dis_tbl(); + int max= 0; + + while (de && + de->mnemonic) + { + if (de->length > max) + max= de->length; + de++; + } + return(max); } bool -cl_uc::get_name(uint addr, struct name_entry tab[], char *buf) +cl_uc::get_name(t_addr addr, struct name_entry tab[], char *buf) { int i; 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_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)) + i++; + if (bit_tbl()[i].name) + { + sym_name= strdup(bit_tbl()[i].name); + return(sym_name); + } + + if (mem && + 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++; + if (sfr_tbl()[i].name) + sym_name= strdup(sfr_tbl()[i].name); + else + sym_name= 0; + } + if (!sym_name) + { + sym_name= (char *)malloc(16); + sprintf(sym_name, mem?(mem->addr_format):"0x%06x", mem_addr); + } + sym_name= (char *)realloc(sym_name, strlen(sym_name)+2); + strcat(sym_name, "."); + i= 0; + while (bit_mask > 1) + { + bit_mask>>=1; + i++; + } + char bitnumstr[10]; + sprintf(bitnumstr, "%1d", i); + strcat(sym_name, bitnumstr); + return(sym_name); +} + + +/* + * 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 *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 *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 @@ -674,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); } @@ -700,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); } @@ -726,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; @@ -736,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); } @@ -757,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; + } } } @@ -785,35 +1489,39 @@ 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 -cl_uc::fetch(ulong *code) +cl_uc::fetch(t_mem *code) { class cl_brk *brk; int idx; 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); @@ -827,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(); @@ -840,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; +} /* @@ -879,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; } @@ -916,7 +1704,7 @@ cl_uc::st_ret(class cl_stack_op *op) */ class cl_fetch_brk * -cl_uc::fbrk_at(long addr) +cl_uc::fbrk_at(t_addr addr) { int idx; @@ -933,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); } @@ -945,6 +1733,34 @@ cl_uc::rm_fbrk(long addr) fbrk->del_bp(addr); }*/ +/* Get a breakpoint specified by its number */ + +class cl_brk * +cl_uc::brk_by_nr(int nr) +{ + class cl_brk *bp; + + if ((bp= fbrk->get_bp(nr))) + return(bp); + if ((bp= ebrk->get_bp(nr))) + return(bp); + return(0); +} + +/* Get a breakpoint from the specified collection by its number */ + +class cl_brk * +cl_uc::brk_by_nr(class brk_coll *bpcoll, int nr) +{ + class cl_brk *bp; + + if ((bp= bpcoll->get_bp(nr))) + return(bp); + return(0); +} + +/* Remove an event breakpoint specified by its address and id */ + void cl_uc::rm_ebrk(t_addr addr, char *id) { @@ -955,18 +1771,118 @@ 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 */ + +bool +cl_uc::rm_brk(int nr) +{ + class cl_brk *bp; + + if ((bp= brk_by_nr(fbrk, nr))) + { + fbrk->del_bp(bp->addr); + return(DD_TRUE); + } + else if ((bp= brk_by_nr(ebrk, nr))) + { + ebrk->del_bp(ebrk->index_of(bp), 0); + return(DD_TRUE); } + return(DD_FALSE); } void cl_uc::put_breaks(void) {} +/* Remove all fetch and event breakpoints */ + void -cl_uc::remove_breaks(void) -{} +cl_uc::remove_all_breaks(void) +{ + while (fbrk->count) + { + class cl_brk *brk= (class cl_brk *)(fbrk->at(0)); + fbrk->del_bp(brk->addr); + } + while (ebrk->count) + ebrk->del_bp(ebrk->count-1, 0); +} + +int +cl_uc::make_new_brknr(void) +{ + if (brk_counter == 0) + return(brk_counter= 1); + if (fbrk->count == 0 && + ebrk->count == 0) + return(brk_counter= 1); + return(++brk_counter); +} + +class cl_ev_brk * +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); + + 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 *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 */