* sim/ucsim/*.*, sim/ucsim/configure, sim/ucsim/configure.in:
[fw/sdcc] / sim / ucsim / sim.src / mem.cc
index 1ac443ee582a1e6a0ddc3b2eb336b733e5d23ecd..b0bc0d4146d927a0b5ce7054a4667c3d913580b1 100644 (file)
 #include "hwcl.h"
 
 
+static class cl_mem_error_registry mem_error_registry;
+
 /*
  *                                                3rd version of memory system
  */
 
-cl_memory::cl_memory(char *id, t_addr asize, int awidth):
+cl_memory::cl_memory(const char *id, t_addr asize, int awidth):
   cl_base()
 {
   size= asize;
@@ -76,12 +78,12 @@ cl_memory::init(void)
 {
   addr_format= (char *)malloc(10);
   sprintf(addr_format, "0x%%0%dx",
-         size-1<=0xf?1:
-         (size-1<=0xff?2:
-          (size-1<=0xfff?3:
-           (size-1<=0xffff?4:
-            (size-1<=0xfffff?5:
-             (size-1<=0xffffff?6:12))))));
+          size-1<=0xf?1:
+          (size-1<=0xff?2:
+           (size-1<=0xfff?3:
+            (size-1<=0xffff?4:
+             (size-1<=0xfffff?5:
+              (size-1<=0xffffff?6:12))))));
   data_format= (char *)malloc(10);
   sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0));
   data_mask= 1;
@@ -100,7 +102,7 @@ bool
 cl_memory::valid_address(t_addr addr)
 {
   return(addr >= start_address &&
-        addr < start_address+size);
+         addr < start_address+size);
 }
 
 t_addr
@@ -162,7 +164,7 @@ cl_memory::err_non_decoded(t_addr addr)
 
 
 t_addr
-cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
+cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console_base *con)
 {
   int i;
   t_addr lva= lowest_valid_address();
@@ -173,42 +175,42 @@ cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
   if (stop > hva)
     stop= hva;
   while ((start <= stop) &&
-        (start < hva))
+         (start < hva))
     {
       con->dd_printf(addr_format, start); con->dd_printf(" ");
       for (i= 0;
-          (i < bpl) &&
-            (start+i < hva) &&
-            (start+i <= stop);
-          i++)
-       {
-         con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" ");
-       }
+           (i < bpl) &&
+             (start+i < hva) &&
+             (start+i <= stop);
+           i++)
+        {
+          con->dd_printf(data_format, /*read*/get(start+i)); con->dd_printf(" ");
+        }
       while (i < bpl)
-       {
-         int j;
-         j= width/4 + ((width%4)?1:0) + 1;
-         while (j)
-           {
-             con->dd_printf(" ");
-             j--;
-           }
-         i++;
-       }
+        {
+          int j;
+          j= width/4 + ((width%4)?1:0) + 1;
+          while (j)
+            {
+              con->dd_printf(" ");
+              j--;
+            }
+          i++;
+        }
       for (i= 0; (i < bpl) &&
-            (start+i < hva) &&
-            (start+i <= stop);
-          i++)
-       {
-         long c= read(start+i);
-         con->dd_printf("%c", isprint(255&c)?(255&c):'.');
-         if (width > 8)
-           con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
-         if (width > 16)
-           con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
-         if (width > 24)
-           con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
-       }
+             (start+i < hva) &&
+             (start+i <= stop);
+           i++)
+        {
+          long c= read(start+i);
+          con->dd_printf("%c", isprint(255&c)?(255&c):'.');
+          if (width > 8)
+            con->dd_printf("%c", isprint(255&(c>>8))?(255&(c>>8)):'.');
+          if (width > 16)
+            con->dd_printf("%c", isprint(255&(c>>16))?(255&(c>>16)):'.');
+          if (width > 24)
+            con->dd_printf("%c", isprint(255&(c>>24))?(255&(c>>24)):'.');
+        }
       con->dd_printf("\n");
       dump_finished= start+i;
       start+= bpl;
@@ -217,14 +219,14 @@ cl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con)
 }
 
 t_addr
-cl_memory::dump(class cl_console *con)
+cl_memory::dump(class cl_console_base *con)
 {
   return(dump(dump_finished, dump_finished+10*8-1, 8, con));
 }
 
 bool
 cl_memory::search_next(bool case_sensitive,
-                      t_mem *array, int len, t_addr *addr)
+                       t_mem *array, int len, t_addr *addr)
 {
   t_addr a;
   int i;
@@ -240,26 +242,26 @@ cl_memory::search_next(bool case_sensitive,
 
   found= DD_FALSE;
   while (!found &&
-        a+len <= size)
+         a+len <= size)
     {
       bool match= DD_TRUE;
       for (i= 0; i < len && match; i++)
-       {
-         t_mem d1, d2;
-         d1= get(a+i);
-         d2= array[i];
-         if (!case_sensitive)
-           {
-             if (/*d1 < 128*/isalpha(d1))
-               d1= toupper(d1);
-             if (/*d2 < 128*/isalpha(d2))
-               d2= toupper(d2);
-           }
-         match= d1 == d2;
-       }
+        {
+          t_mem d1, d2;
+          d1= get(a+i);
+          d2= array[i];
+          if (!case_sensitive)
+            {
+              if (/*d1 < 128*/isalpha(d1))
+                d1= toupper(d1);
+              if (/*d2 < 128*/isalpha(d2))
+                d2= toupper(d2);
+            }
+          match= d1 == d2;
+        }
       found= match;
       if (!found)
-       a++;
+        a++;
     }
 
   if (addr)
@@ -273,7 +275,7 @@ cl_memory::search_next(bool case_sensitive,
  */
 
 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
-                                      t_addr addr):
+                                       t_addr addr):
   cl_base()
 {
   cell= acell;
@@ -284,8 +286,8 @@ cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
 }
 
 cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,
-                                      t_addr addr,
-                                      t_mem *data_place, t_mem the_mask):
+                                       t_addr addr,
+                                       t_mem *data_place, t_mem the_mask):
   cl_base()
 {
   cell= acell;
@@ -325,8 +327,8 @@ cl_memory_operator::write(t_mem val)
 /* Memory operator for hw callbacks */
 
 cl_hw_operator::cl_hw_operator(class cl_memory_cell *acell, t_addr addr,
-                              t_mem *data_place, t_mem the_mask,
-                              class cl_hw *ahw):
+                               t_mem *data_place, t_mem the_mask,
+                               class cl_hw *ahw):
   cl_memory_operator(acell, addr, data_place, the_mask)
 {
   hw= ahw;
@@ -376,8 +378,8 @@ cl_hw_operator::write(t_mem val)
 /* Write event break on cell */
 
 cl_write_operator::cl_write_operator(class cl_memory_cell *acell, t_addr addr,
-                                    t_mem *data_place, t_mem the_mask,
-                                    class cl_uc *auc, class cl_brk *the_bp):
+                                     t_mem *data_place, t_mem the_mask,
+                                     class cl_uc *auc, class cl_brk *the_bp):
   cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp)
 {
   uc= auc;
@@ -399,8 +401,8 @@ cl_write_operator::write(t_mem val)
 /* Read event break on cell */
 
 cl_read_operator::cl_read_operator(class cl_memory_cell *acell, t_addr addr,
-                                  t_mem *data_place, t_mem the_mask,
-                                  class cl_uc *auc, class cl_brk *the_bp):
+                                   t_mem *data_place, t_mem the_mask,
+                                   class cl_uc *auc, class cl_brk *the_bp):
   cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp)
 {
   uc= auc;
@@ -603,10 +605,10 @@ cl_memory_cell::append_operator(class cl_memory_operator *op)
       class cl_memory_operator *o= operators, *n;
       n= o->get_next();
       while (n)
-       {
-         o= n;
-         n= o->get_next();
-       }
+        {
+          o= n;
+          n= o->get_next();
+        }
       o->set_next(op);
     }
 }
@@ -635,14 +637,14 @@ cl_memory_cell::del_operator(class cl_brk *brk)
   else
     {
       while (op->get_next() &&
-            !op->get_next()->match(brk))
-       op= op->get_next();
+             !op->get_next()->match(brk))
+        op= op->get_next();
       if (op->get_next())
-       {
-         class cl_memory_operator *m= op->get_next();
-         op->set_next(m->get_next());;
-         delete m;
-       }
+        {
+          class cl_memory_operator *m= op->get_next();
+          op->set_next(m->get_next());;
+          delete m;
+        }
     }
 }
 
@@ -694,19 +696,14 @@ cl_dummy_cell::set(t_mem val)
  *                                                                Address space
  */
 
-cl_address_space::cl_address_space(char *id,
-                                  t_addr astart, t_addr asize, int awidth):
+cl_address_space::cl_address_space(const char *id,
+                                   t_addr astart, t_addr asize, int awidth):
   cl_memory(id, asize, awidth)
 {
   start_address= astart;
   decoders= new cl_decoder_list(2, 2, DD_FALSE);
-  cells= (class cl_memory_cell **)malloc(size * sizeof(class cl_memory_cell*));
-  int i;
-  for (i= 0; i < size; i++)
-    {
-      cells[i]= new cl_memory_cell();
-      cells[i]->init();
-    }
+  cells= (class cl_memory_cell **)calloc(size, sizeof(class cl_memory_cell*));
+
   dummy= new cl_dummy_cell();
 }
 
@@ -724,79 +721,42 @@ cl_address_space::~cl_address_space(void)
 t_mem
 cl_address_space::read(t_addr addr)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    {
-      err_inv_addr(addr);
-      return(dummy->read());
-    }
-  return(cells[idx]->read());
+  return get_cell(addr)->read();
 }
 
 t_mem
 cl_address_space::read(t_addr addr, enum hw_cath skip)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
+  cl_memory_cell *cell = get_cell(addr);
+  if (cell == dummy)
     {
-      err_inv_addr(addr);
-      return(dummy->read());
+      return dummy->read();
     }
-  return(cells[idx]->read(skip));
+  return cell->read(skip);
 }
 
 t_mem
 cl_address_space::get(t_addr addr)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    {
-      err_inv_addr(addr);
-      return(dummy->get());
-    }
-  return(cells[idx]->get());
+  return get_cell(addr)->get();
 }
 
 t_mem
 cl_address_space::write(t_addr addr, t_mem val)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    {
-      err_inv_addr(addr);
-      return(dummy->write(val));
-    }
-  return(cells[idx]->write(val));
+  return get_cell(addr)->write(val);
 }
 
 void
 cl_address_space::set(t_addr addr, t_mem val)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    {
-      err_inv_addr(addr);
-      dummy->set(val);
-      return;
-    }
-  cells[idx]->set(val);
+  get_cell(addr)->set(val);
 }
 
 t_mem
 cl_address_space::wadd(t_addr addr, long what)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    {
-      err_inv_addr(addr);
-    }
-  return(cells[idx]->wadd(what));
+  return get_cell(addr)->wadd(what);
 }
 
 /* Set or clear bits, without callbacks */
@@ -804,25 +764,42 @@ cl_address_space::wadd(t_addr addr, long what)
 void
 cl_address_space::set_bit1(t_addr addr, t_mem bits)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
+  cl_memory_cell *cell = get_cell(addr);
+  if (cell == dummy)
+    {
     return;
-  class cl_memory_cell *cell= cells[idx];
+    }
   cell->set_bit1(bits);
 }
 
 void
 cl_address_space::set_bit0(t_addr addr, t_mem bits)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    return;
-  class cl_memory_cell *cell= cells[idx];
+  cl_memory_cell *cell = get_cell(addr);
+  if (cell == dummy)
+    {
+      return;
+    }
   cell->set_bit0(bits);
 }
 
+class cl_address_decoder *
+cl_address_space::get_decoder(t_addr addr)
+{
+  int i;
+  for (i= 0; i < decoders->count; i++)
+    {
+      class cl_address_decoder *d=
+        dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
+      if (!d)
+        continue;
+      if (d->covers(addr, addr))
+        {
+          return d;
+        }
+    }
+    return NULL;
+}
 
 class cl_memory_cell *
 cl_address_space::get_cell(t_addr addr)
@@ -834,6 +811,18 @@ cl_address_space::get_cell(t_addr addr)
       err_inv_addr(addr);
       return(dummy);
     }
+  if (cells[idx] == NULL)
+    {
+      cells[idx]= new cl_memory_cell();
+      cells[idx]->init();
+      class cl_address_decoder *decoder;
+      decoder = get_decoder(addr);
+      if (decoder && decoder->activated)
+        {
+          decode_cell(addr, decoder->memchip,
+                      addr - decoder->as_begin + decoder->chip_begin);
+        }
+    }
   return(cells[idx]);
 }
 
@@ -841,53 +830,31 @@ cl_address_space::get_cell(t_addr addr)
 int
 cl_address_space::get_cell_flag(t_addr addr)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    {
-      return(dummy->get_flags());
-    }
-  return(cells[addr]->get_flags());
+  return get_cell(addr)->get_flags();
 }
 
 bool
 cl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    {
-      return(dummy->get_flag(flag));
-    }
-  return(cells[addr]->get_flag(flag));
+  return get_cell(addr)->get_flag(flag);
 }
 
 void
 cl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag)
 {
-  t_addr idx= addr-start_address;
-  class cl_memory_cell *cell;
-  
-  if (idx >= size ||
-      addr < start_address)
-    {
-      cell= dummy;
-    }
-  else
-    cell= cells[addr];
-  cell->set_flag(flag, set_to);
+  get_cell(addr)->set_flag(flag, set_to);
 }
 
 
 bool
 cl_address_space::decode_cell(t_addr addr,
-                             class cl_memory_chip *chip, t_addr chipaddr)
+                              class cl_memory_chip *chip, t_addr chipaddr)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    return(DD_FALSE);
-  class cl_memory_cell *cell= cells[idx];
+  cl_memory_cell *cell = get_cell(addr);
+  if (cell == dummy)
+    {
+      return(DD_FALSE);
+    }
 
   if (!cell->get_flag(CELL_NON_DECODED))
     {
@@ -905,15 +872,20 @@ cl_address_space::undecode_cell(t_addr addr)
   t_addr idx= addr-start_address;
   if (idx >= size ||
       addr < start_address)
-    return;
-  class cl_memory_cell *cell= cells[idx];
-
-  cell->un_decode();
+    {
+      err_inv_addr(addr);
+      return;
+    }
+  if (cells[idx] == NULL)
+    {
+      return;
+    }
+  cells[idx]->un_decode();
 }
 
 void
 cl_address_space::undecode_area(class cl_address_decoder *skip,
-                               t_addr begin, t_addr end,class cl_console *con)
+                                t_addr begin, t_addr end,class cl_console_base *con)
 {
 #define D if (con) con->debug
   D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name());
@@ -921,57 +893,57 @@ cl_address_space::undecode_area(class cl_address_decoder *skip,
   for (i= 0; i < decoders->count; i++)
     {
       class cl_address_decoder *d=
-       dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
+        dynamic_cast<class cl_address_decoder *>(decoders->object_at(i));
       if (!d ||
-         d == skip)
-       continue;
+          d == skip)
+        continue;
       D("  Checking decoder 0x%x-0x%x -> %s[0x%x]\n",
-       d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
+        d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
       if (d->fully_covered_by(begin, end))
-       {
-         // decoder can be removed
-         D("    Can be removed\n");
-         decoders->disconn(d);
-         i--;
-         delete d;
-         if (decoders->count == 0)
-           break;
-       }
+        {
+          // decoder can be removed
+          D("    Can be removed\n");
+          decoders->disconn(d);
+          i--;
+          delete d;
+          if (decoders->count == 0)
+            break;
+        }
       else if (d->covers(begin, end))
-       {
-         // decoder must be split
-         D("    Must be split\n");
-         class cl_address_decoder *nd= d->split(begin, end);
-         D("    After split:\n");
-         D("      0x%x-0x%x -> %s[0x%x]\n",
-           d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
-         if (nd)
-           {
-             decoders->add(nd);
-             D("      0x%x-0x%x -> %s[0x%x]\n",
-               nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin);
-             nd->activate(con);
-           }
-       }
+        {
+          // decoder must be split
+          D("    Must be split\n");
+          class cl_address_decoder *nd= d->split(begin, end);
+          D("    After split:\n");
+          D("      0x%x-0x%x -> %s[0x%x]\n",
+            d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
+          if (nd)
+            {
+              decoders->add(nd);
+              D("      0x%x-0x%x -> %s[0x%x]\n",
+                nd->as_begin, nd->as_end, nd->memchip->get_name(), nd->chip_begin);
+              nd->activate(con);
+            }
+        }
       else if (d->is_in(begin, end))
-       {
-         // decoder sould shrink
-         D("    Sould shrink\n");
-         if (d->shrink_out_of(begin, end))
-           {
-             D("    Can be removed after shrink\n");
-             decoders->disconn(d);
-             i--;
-             delete d;
-             if (decoders->count == 0)
-               break;
-           }
-         else
-           {
-             D("    Shrinked to 0x%x-0x%x -> %s[0x%x]\n",
-               d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
-           }
-       }
+        {
+          // decoder sould shrink
+          D("    Sould shrink\n");
+          if (d->shrink_out_of(begin, end))
+            {
+              D("    Can be removed after shrink\n");
+              decoders->disconn(d);
+              i--;
+              delete d;
+              if (decoders->count == 0)
+                break;
+            }
+          else
+            {
+              D("    Shrinked to 0x%x-0x%x -> %s[0x%x]\n",
+                d->as_begin, d->as_end, d->memchip->get_name(), d->chip_begin);
+            }
+        }
     }
 #undef D
 }
@@ -979,14 +951,14 @@ cl_address_space::undecode_area(class cl_address_decoder *skip,
 
 class cl_memory_cell *
 cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
-                             int *ith,
-                             bool announce)
+                              int *ith,
+                              bool announce)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    return(0);
-  class cl_memory_cell *cell= cells[idx];
+  cl_memory_cell *cell = get_cell(addr);
+  if (cell == dummy)
+    {
+      return(NULL);
+    }
   cell->add_hw(hw, ith, addr);
   //printf("adding hw %s to cell 0x%x(%d) of %s\n", hw->id_string, addr, idx, get_name("as"));
   if (announce)
@@ -998,11 +970,12 @@ cl_address_space::register_hw(t_addr addr, class cl_hw *hw,
 void
 cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    return;
-  class cl_memory_cell *cell= cells[idx];
+  cl_memory_cell *cell = get_cell(addr);
+  if (cell == dummy)
+    {
+      return;
+    }
+
   class cl_memory_operator *op;
 
   switch (brk->get_event())
@@ -1010,12 +983,12 @@ cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
     case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
       //e= 'W';
       op= new cl_write_operator(cell, addr, cell->get_data(), cell->get_mask(),
-                               uc, brk);
+                                uc, brk);
       break;
     case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
       //e= 'R';
       op= new cl_read_operator(cell, addr, cell->get_data(), cell->get_mask(),
-                              uc, brk);
+                               uc, brk);
       break;
     case brkNONE:
       set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);
@@ -1033,11 +1006,11 @@ cl_address_space::set_brk(t_addr addr, class cl_brk *brk)
 void
 cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
 {
-  t_addr idx= addr-start_address;
-  if (idx >= size ||
-      addr < start_address)
-    return;
-  class cl_memory_cell *cell= cells[idx];
+  cl_memory_cell *cell = get_cell(addr);
+  if (cell == dummy)
+    {
+      return;
+    }
 
   switch (brk->get_event())
     {
@@ -1083,7 +1056,7 @@ cl_address_space_list::add(class cl_address_space *mem)
  *                                                                  Memory chip
  */
 
-cl_memory_chip::cl_memory_chip(char *id, int asize, int awidth, int initial):
+cl_memory_chip::cl_memory_chip(const char *id, int asize, int awidth, int initial):
   cl_memory(id, asize, awidth)
 {
   array= (t_mem *)malloc(size * sizeof(t_mem));
@@ -1103,7 +1076,7 @@ cl_memory_chip::init(void)
   int i;
   for (i= 0; i < size; i++)
     set(i,
-       (init_value<0)?rand():(init_value));
+        (init_value<0)?rand():(init_value));
   return(0);
 }
 
@@ -1160,8 +1133,8 @@ cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
  */
 
 cl_address_decoder::cl_address_decoder(class cl_memory *as,
-                                      class cl_memory *chip,
-                                      t_addr asb, t_addr ase, t_addr cb)
+                                       class cl_memory *chip,
+                                       t_addr asb, t_addr ase, t_addr cb)
 {
   if (as->is_address_space())
     address_space= (class cl_address_space *)as;
@@ -1193,7 +1166,7 @@ cl_address_decoder::init(void)
 
 
 bool
-cl_address_decoder::activate(class cl_console *con)
+cl_address_decoder::activate(class cl_console_base *con)
 {
 #define D if (con) con->debug
   D("Activation of an address decoder\n");
@@ -1238,16 +1211,6 @@ cl_address_decoder::activate(class cl_console *con)
 
   address_space->undecode_area(this, as_begin, as_end, con);
 
-  t_addr asa, ca;
-  for (asa= as_begin, ca= chip_begin;
-       asa <= as_end;
-       asa++, ca++)
-    {
-      if (!address_space->decode_cell(asa, memchip, ca))
-       {
-         D("Decoding 0x%06x->0x%06x failed\n", asa, ca);
-       }
-    }
   activated= DD_TRUE;
 
 #undef D
@@ -1298,7 +1261,7 @@ cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
   if (begin > a)
     a= begin;
   while (a <= end &&
-        a <= as_end)
+         a <= as_end)
     {
       address_space->undecode_cell(a);
       a++;
@@ -1322,15 +1285,15 @@ cl_address_decoder::split(t_addr begin, t_addr end)
   if (begin > as_begin)
     {
       if (as_end > end)
-       nd= new cl_address_decoder(address_space, memchip,
-                                  end+1, as_end, chip_begin+(end-as_begin)+1);
+        nd= new cl_address_decoder(address_space, memchip,
+                                   end+1, as_end, chip_begin+(end-as_begin)+1);
       shrink_out_of(begin, as_end);
     }
   else if (end < as_end)
     {
       if (as_begin < begin)
-       nd= new cl_address_decoder(address_space, memchip,
-                                  as_begin, begin-1, chip_begin);
+        nd= new cl_address_decoder(address_space, memchip,
+                                   as_begin, begin-1, chip_begin);
       shrink_out_of(end+1, as_end);
     }
   if (nd)
@@ -1350,7 +1313,7 @@ cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):
   by_chip= bychip;
 }
 
-void *
+const void *
 cl_decoder_list::key_of(void *item)
 {
   class cl_address_decoder *d= (class cl_address_decoder *)item;
@@ -1361,9 +1324,9 @@ cl_decoder_list::key_of(void *item)
 }
 
 int
-cl_decoder_list::compare(void *key1, void *key2)
+cl_decoder_list::compare(const void *key1, const void *key2)
 {
-  t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);
+  const t_addr k1= *(static_cast<const t_addr *>(key1)), k2= *(static_cast<const t_addr*>(key2));
   if (k1 == k2)
     return(0);
   else if (k1 > k2)
@@ -1378,59 +1341,53 @@ cl_decoder_list::compare(void *key1, void *key2)
 
 /* All of memory errors */
 
-class cl_error_class *cl_error_mem::error_mem_class;
-
 cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr)
 {
   mem= amem;
   addr= aaddr;
-  if (NULL == error_mem_class)
-    error_mem_class= new cl_error_class(err_error, "memory", classification, ERROR_OFF);
-  classification= error_mem_class;
+  classification= mem_error_registry.find("memory");
 }
 
 /* Invalid address in memory access */
 
-class cl_error_class *cl_error_mem_invalid_address::error_mem_invalid_address_class;
-
 cl_error_mem_invalid_address::
 cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):
   cl_error_mem(amem, aaddr)
 {
-  if (NULL == error_mem_invalid_address_class)
-    error_mem_invalid_address_class= new cl_error_class(err_error, "invalid_address", classification);
-  classification= error_mem_invalid_address_class;
+  classification= mem_error_registry.find("invalid_address");
 }
 
 void
-cl_error_mem_invalid_address::print(class cl_commander *c)
+cl_error_mem_invalid_address::print(class cl_commander_base *c)
 {
-  FILE *f= c->get_out();
-  cmd_fprintf(f, "%s: invalid address ", get_type_name());
-  cmd_fprintf(f, mem->addr_format, addr);
-  cmd_fprintf(f, " in memory %s.\n", mem->get_name());
+  c->dd_printf("%s: invalid address ", get_type_name());
+  c->dd_printf(mem->addr_format, addr);
+  c->dd_printf(" in memory %s.\n", mem->get_name());
 }
 
 /* Non-decoded address space access */
 
-class cl_error_class *cl_error_mem_non_decoded::error_mem_non_decoded_class;
-
 cl_error_mem_non_decoded::
 cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):
   cl_error_mem(amem, aaddr)
 {
-  if (NULL == error_mem_non_decoded_class)
-    error_mem_non_decoded_class= new cl_error_class(err_error, "non_decoded", classification);
-  classification= error_mem_non_decoded_class;
+  classification= mem_error_registry.find("non_decoded");
 }
 
 void
-cl_error_mem_non_decoded::print(class cl_commander *c)
+cl_error_mem_non_decoded::print(class cl_commander_base *c)
+{
+  c->dd_printf("%s: access of non-decoded address ", get_type_name());
+  c->dd_printf(mem->addr_format, addr);
+  c->dd_printf(" in memory %s.\n", mem->get_name());
+}
+
+cl_mem_error_registry::cl_mem_error_registry(void)
 {
-  FILE *f= c->get_out();
-  cmd_fprintf(f, "%s: access of non-decoded address ", get_type_name());
-  cmd_fprintf(f, mem->addr_format, addr);
-  cmd_fprintf(f, " in memory %s.\n", mem->get_name());
+  class cl_error_class *prev = mem_error_registry.find("non-classified");
+  prev = register_error(new cl_error_class(err_error, "memory", prev, ERROR_OFF));
+  prev = register_error(new cl_error_class(err_error, "invalid_address", prev));
+  prev = register_error(new cl_error_class(err_error, "non_decoded", prev));
 }