* src/hc08/gen.c (genPlusIncr, genUminus, genMinusDec, genCmp,
[fw/sdcc] / sim / ucsim / sim.src / uc.cc
index d3293fd1fe96bbc05f03f218cb0ef371753ffda6..7ad8f08a9851918b3719d736adf5820634d2bc7c 100644 (file)
@@ -33,9 +33,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include <ctype.h>
 #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"
+
+// local, sim.src
 #include "uccl.h"
 #include "hwcl.h"
 #include "memcl.h"
@@ -54,14 +66,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)
@@ -83,11 +91,11 @@ 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);
 }
 
 
@@ -102,8 +110,8 @@ cl_uc::cl_uc(class cl_sim *asim):
   int i;
   sim = asim;
   mems= new cl_list(MEM_TYPES, 1);
-  hws = new cl_list(2, 1);
-  options= new cl_list(2, 2);
+  hws = new cl_hws();
+  //options= new cl_list(2, 2);
   for (i= MEM_ROM; i < MEM_TYPES; i++)
     mems->add(0);
   ticks= new cl_ticker(+1, 0, "time");
@@ -111,12 +119,15 @@ cl_uc::cl_uc(class cl_sim *asim):
   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);
+  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);
+  errors= new cl_list(2, 2);
+  events= new cl_list(2, 2);
   sp_max= 0;
   sp_avg= 0;
+  inst_exec= DD_FALSE;
 }
 
 
@@ -124,42 +135,59 @@ cl_uc::~cl_uc(void)
 {
   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;
+  errors->free_all();
+  delete errors;
 }
 
 
 int
 cl_uc::init(void)
 {
-  int mc;
+  int mc, i;
 
   cl_base::init();
-  if (!(sim->arg_avail('X')) ||
-      sim->get_farg('X', 0) == 0)
+  if (!(sim->app->args->arg_avail('X')) ||
+      sim->app->args->get_farg('X', 0) == 0)
     xtal= 11059200;
   else
-    xtal= sim->get_farg('X', 0);
+    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));
+  ebrk= new brk_coll(2, 2, /*(class cl_rom *)*/mem(MEM_ROM));
+  fbrk= new brk_coll(2, 2, /*(class cl_rom *)*/mem(MEM_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);
 }
 
@@ -190,6 +218,13 @@ cl_uc::reset(void)
     }
   sp_max= 0;
   sp_avg= 0;
+  
+  int i;
+  for (i= 0; i < hws->count; i++)
+    {
+      class cl_hw *hw= (class cl_hw *)(hws->at(i));
+      hw->reset();
+    }
 }
 
 /*
@@ -201,13 +236,10 @@ cl_uc::mk_mem(enum mem_class type, char *class_name)
 {
   class cl_mem *m;
 
-  if (get_mem_size(type) <= 0)
+  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= new cl_m(type, get_id_string(mem_classes, type),
+             get_mem_size(type), get_mem_width(type), this);
   m->init();
   return(m);
 }
@@ -219,7 +251,7 @@ cl_uc::get_mem_size(enum mem_class type)
     {
     case MEM_ROM: return(0x10000);
     case MEM_XRAM: return(0x10000);
-    case MEM_IRAM: return(0x100);
+    case MEM_IRAM: return(0x80);
     case MEM_SFR: return(0x100);
     case MEM_TYPES:
     default: return(0);
@@ -238,33 +270,246 @@ 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,dl          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", 0,
+"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,
+"dch [start [stop]] Dump code in hex form",
+"long help of dch"));
+  cmd->init();
+
+  cmdset->add(cmd= new cl_dc_cmd("dc", 0,
+"dc [start [stop]]  Dump code in disass form",
+"long help of dc"));
+  cmd->init();
+
+  cmdset->add(cmd= new cl_disassemble_cmd("disassemble", 0,
+"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();
+    }
+
+  {
+    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();
+  }
+  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();
+
+  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();
+}
+
 
 /*
  * Read/write simulated memory
  */
 
-ulong
-cl_uc::read_mem(enum mem_class type, t_mem addr)
+t_mem
+cl_uc::read_mem(enum mem_class type, t_addr addr)
 {
   class cl_mem *m;
 
-  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);
+  if ((m= (class cl_mem*)mems->at(type)) == 0)
+    m= (class cl_mem*)(mems->at(MEM_DUMMY));
+  return(m->read(addr));
 }
 
-ulong
+t_mem
 cl_uc::get_mem(enum mem_class type, t_addr addr)
 {
   class cl_mem *m;
 
-  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);
+  if ((m= (class cl_mem*)mems->at(type)) == 0)
+    m= (class cl_mem*)(mems->at(MEM_DUMMY));
+  return(m->get(addr));
 }
 
 void
@@ -272,13 +517,9 @@ cl_uc::write_mem(enum mem_class type, t_addr addr, t_mem val)
 {
   class cl_mem *m;
 
-  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= (class cl_mem*)mems->at(type)) == 0)
+    m= (class cl_mem*)(mems->at(MEM_DUMMY));
+  m->write(addr, val);
 }
 
 void
@@ -286,20 +527,21 @@ cl_uc::set_mem(enum mem_class type, t_addr addr, t_mem val)
 {
   class cl_mem *m;
 
-  if ((m= (class cl_mem*)mems->at(type)))
-    m->set(addr, val);
-  //FIXME
-else printf("cl_uc::set_mem(type= %d, 0x%06lx, 0x%lx) TROUBLE\n", type, addr, val);
+  if ((m= (class cl_mem*)mems->at(type)) == 0)
+    m= (class cl_mem*)(mems->at(MEM_DUMMY));
+  m->set(addr, val);
 }
 
 class cl_mem *
 cl_uc::mem(enum mem_class type)
 {
+  class cl_mem *m;
+    
   if (mems->count < type)
-    //FIXME
-{printf("TROUBLE\n");    return(0);
-}
-  return((class cl_mem *)(mems->at(type)));
+    m= (class cl_mem *)(mems->at(MEM_DUMMY));
+  else
+    m= (class cl_mem *)(mems->at(type));
+  return(m);
 }
 
 class cl_mem *
@@ -345,21 +587,6 @@ cl_uc::mem(char *class_name)
   return(0);
 }
 
-/*TYPE_UBYTE *
-cl_uc::MEM(enum mem_class type)
-{
-  class cl_mem *m;
-
-  if ((m= mem(type)) == 0)
-    //FIXME
-{printf("TROUBLE\n");    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)
 {
@@ -389,7 +616,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;
@@ -405,15 +632,16 @@ cl_uc::read_hex_file(const char *name)
   bool ok, get_low= 1;
   uchar low= 0, high;
 
-  if (!name)
+  if (!nam)
     {
-      sim->cmd->printf("cl_uc::read_hex_file File name not specified\n");
+      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));
+       fprintf(stderr, "Can't open `%s': %s\n", nam, strerror(errno));
        return(-1);
       }
 
@@ -477,29 +705,31 @@ cl_uc::read_hex_file(const char *name)
                        }
                    }
                  else
-                   if (sim->get_iarg('V', 0) &&
+                   if (sim->app->args->get_iarg('V', 0) &&
                        rtyp != 1)
-                     sim->cmd->printf("Unknown record type %d(0x%x)\n",
-                                      rtyp, rtyp);
+                     sim->app->get_commander()->
+                       dd_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);
+               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->get_iarg('V', 0))
-             sim->cmd->printf("Read error in record %ld.\n", recnum);
+           if (sim->app->args->get_iarg('V', 0))
+             sim->app->get_commander()->
+               dd_printf("Read error in record %ld.\n", recnum);
        }
     }
   if (get_mem_width(MEM_ROM) > 8 &&
       !get_low)
     set_mem(MEM_ROM, addr, low);
 
-  if (name)
+  if (nam)
     fclose(f);
-  if (sim->get_iarg('V', 0))
-    sim->cmd->printf("%ld records have been read\n", recnum);
+  if (sim->app->args->get_iarg('V', 0))
+    sim->app->get_commander()->dd_printf("%ld records have been read\n", recnum);
   analyze(0);
   return(written);
 }
@@ -517,39 +747,47 @@ 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);
+  class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
   
   if (!rom)
     return(0);
-  return(rom->inst_map->get(addr));
+  //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);
+  class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
   
   if (rom)
-    rom->inst_map->set(addr);
+    //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);
+  class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
   
   if (rom)
-    rom->inst_map->clear(addr);
+    //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);
+  class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
   
   if (!rom)
     return(0);
-  return(!(rom->inst_map->empty()));
+  //return(!(rom->inst_map->empty()));
+  bool got= DD_FALSE;
+  t_addr addr;
+  for (addr= 0; addr < rom->size && !got; addr++)
+    got= rom->get_cell_flag(addr, CELL_INST);
+  return(got);
 }
 
 
@@ -560,7 +798,7 @@ 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;
@@ -578,12 +816,12 @@ cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *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 */
 
@@ -703,7 +941,7 @@ 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);
 }
 
@@ -721,16 +959,16 @@ cl_uc::print_disass(t_addr addr, class cl_console *con)
   b= fbrk_at(addr);
   dis= disass(addr, NULL);
   if (b)
-    con->printf("%c", (b->perm == brkFIX)?'F':'D');
+    con->dd_printf("%c", (b->perm == brkFIX)?'F':'D');
   else
-    con->printf(" ");
-  con->printf("%c ", inst_at(addr)?' ':'?');
-  con->printf(rom->addr_format, addr); con->printf(" ");
-  con->printf(rom->data_format, code);
-  for (i= 1; i < inst_length(code); i++)
+    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->printf(" ");
-      con->printf(rom->data_format, get_mem(MEM_ROM, addr+i));
+      con->dd_printf(" ");
+      con->dd_printf(rom->data_format, get_mem(MEM_ROM, addr+i));
     }
   int li= longest_inst();
   while (i < li)
@@ -738,27 +976,42 @@ 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->printf(" "), j--;
+       con->dd_printf(" "), j--;
       i++;
     }
-  con->printf(" %s\n", dis);
+  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(t_mem code)
+cl_uc::inst_length(t_addr addr)
 {
   struct dis_entry *tabl= dis_tbl();
   int i;
+  t_mem code;
 
+  code = get_mem(MEM_ROM, 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;
+
+  code = get_mem(MEM_ROM, addr);
+  for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
+    ;
+  return tabl[i].branch;
 }
 
 int
@@ -844,14 +1097,113 @@ cl_uc::symbolic_bit_name(t_addr bit_address,
 }
 
 
+/*
+ * Messages to broadcast
+ */
+
+void
+cl_uc::mem_cell_changed(class cl_mem *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++)
+       {
+       }
+    }
+}
+
+
+/*
+ * 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();
+
+  if (c)
+    {
+      for (i= 0; i < errors->count; i++)
+       {
+         class cl_error *error= (class cl_error *)(errors->at(i));
+         error->print(c);
+         if (error->inst)
+           {
+             class cl_console *con;
+             con= c->actual_console;
+             if (!con)
+               con= c->frozen_console;
+             if (con)
+               print_disass(error->PC, con);
+           }
+       }
+      errors->free_all();
+    }
+  else
+    fprintf(stderr, "no actual console, %d errors\n", errors->count);
+}
+
+
+/*
+ * Converting bit address into real memory
+ */
+
+class cl_mem *
+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
@@ -872,13 +1224,8 @@ cl_uc::tick(int cycles)
        }
     }
 
-  // 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);
 }
 
@@ -891,18 +1238,18 @@ 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)
+         t->get_name() &&
+         strcmp(t->get_name(), nam) == 0)
        return(t);
     }
   return(0);
@@ -917,7 +1264,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;
 
@@ -948,18 +1295,18 @@ 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)
+         t->get_name() &&
+         strcmp(t->get_name(), nam) == 0)
        {
          delete t;
          counters->put_at(i, 0);
@@ -985,7 +1332,8 @@ cl_uc::fetch(void)
 }
 
 /*
- * Fetch but checking for breakpoint hit first
+ * Fetch but checking for breakpoint hit first, returns TRUE if
+ * a breakpoint is hit
  */
 
 bool
@@ -998,7 +1346,8 @@ cl_uc::fetch(t_mem *code)
     return(0);
   if (sim->state & SIM_GO)
     {
-      if ((brk= fbrk->get_bp(PC, &idx)) &&
+      if (mem(MEM_ROM)->get_cell_flag(PC, CELL_FETCH_BRK) &&
+         (brk= fbrk->get_bp(PC, &idx)) &&
          (brk->do_hit()))
        {
          if (brk->perm == brkDYNAMIC)
@@ -1031,17 +1380,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;
+}
 
 
 /*
@@ -1175,21 +1536,28 @@ 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);
+       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
@@ -1207,7 +1575,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
@@ -1228,44 +1596,16 @@ cl_uc::mk_ebrk(enum brk_perm perm, class cl_mem *mem,
   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)
+{
+  sim->stop(resBREAKPOINT);
+}
+
 
 /* End of uc.cc */