+void
+cl_address_space::del_brk(t_addr addr, class cl_brk *brk)
+{
+ cl_memory_cell *cell = get_cell(addr);
+ if (cell == dummy)
+ {
+ return;
+ }
+
+ switch (brk->get_event())
+ {
+ case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR:
+ case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR:
+ cell->del_operator(brk);
+ break;
+ case brkNONE:
+ set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK);
+ return;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/*
+ * List of address spaces
+ */
+
+cl_address_space_list::cl_address_space_list(class cl_uc *the_uc):
+ cl_list(2, 2, "address spaces")
+{
+ uc= the_uc;
+}
+
+t_index
+cl_address_space_list::add(class cl_address_space *mem)
+{
+ mem->set_uc(uc);
+ t_index ret= cl_list::add(mem);
+ if (uc)
+ {
+ class cl_event_address_space_added e(mem);
+ uc->handle_event(e);
+ }
+ return(ret);
+}
+
+
+/*
+ * Memory chip
+ */
+
+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));
+ init_value= initial;
+}
+
+cl_memory_chip::~cl_memory_chip(void)
+{
+ if (array)
+ free(array);
+}
+
+int
+cl_memory_chip::init(void)
+{
+ cl_memory::init();
+ int i;
+ for (i= 0; i < size; i++)
+ set(i,
+ (init_value<0)?rand():(init_value));
+ return(0);
+}
+
+
+t_mem *
+cl_memory_chip::get_slot(t_addr addr)
+{
+ if (!array ||
+ size <= addr)
+ return(0);
+ return(&array[addr]);
+}
+
+
+t_mem
+cl_memory_chip::get(t_addr addr)
+{
+ if (!array ||
+ size <= addr)
+ return(0);
+ return(array[addr]);
+}
+
+void
+cl_memory_chip::set(t_addr addr, t_mem val)
+{
+ if (!array ||
+ size <= addr)
+ return;
+ array[addr]= val & data_mask;
+}
+
+void
+cl_memory_chip::set_bit1(t_addr addr, t_mem bits)
+{
+ if (!array ||
+ size <= addr)
+ return;
+ array[addr]|= (bits & data_mask);
+}
+
+void
+cl_memory_chip::set_bit0(t_addr addr, t_mem bits)
+{
+ if (!array ||
+ size <= addr)
+ return;
+ array[addr]&= ((~bits) & data_mask);
+}
+
+
+/*
+ * Address decoder
+ */
+
+cl_address_decoder::cl_address_decoder(class cl_memory *as,
+ 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;
+ else
+ address_space= 0;
+ if (chip->is_chip())
+ memchip= (class cl_memory_chip *)chip;
+ else
+ memchip= 0;
+ as_begin= asb;
+ as_end= ase;
+ chip_begin= cb;
+ activated= DD_FALSE;
+}
+
+cl_address_decoder::~cl_address_decoder(void)
+{
+ t_addr a;
+ if (address_space)
+ for (a= as_begin; a <= as_end; a++)
+ address_space->undecode_cell(a);
+}
+
+int
+cl_address_decoder::init(void)
+{
+ return(0);
+}
+
+
+bool
+cl_address_decoder::activate(class cl_console_base *con)
+{
+#define D if (con) con->debug
+ D("Activation of an address decoder\n");
+ if (activated)
+ {
+ D("Already activated\n");
+ return(DD_FALSE);
+ }
+ if (!address_space ||
+ !address_space->is_address_space())
+ {
+ D("No or non address space\n");
+ return(DD_FALSE);
+ }
+ if (!memchip ||
+ !memchip->is_chip())
+ {
+ D("No or non memory chip\n");
+ return(DD_FALSE);
+ }
+ if (as_begin > as_end)
+ {
+ D("Wrong address area specification\n");
+ return(DD_FALSE);
+ }
+ if (chip_begin >= memchip->get_size())
+ {
+ D("Wrong chip area specification\n");
+ return(DD_FALSE);
+ }
+ if (as_begin < address_space->start_address ||
+ as_end >= address_space->start_address + address_space->get_size())
+ {
+ D("Specified area is out of address space\n");
+ return(DD_FALSE);
+ }
+ if (as_end-as_begin > memchip->get_size()-chip_begin)
+ {
+ D("Specified area is out of chip size\n");
+ return(DD_FALSE);
+ }
+
+ address_space->undecode_area(this, as_begin, as_end, con);
+
+ activated= DD_TRUE;
+
+#undef D
+ return(activated);
+}
+
+
+bool
+cl_address_decoder::fully_covered_by(t_addr begin, t_addr end)
+{
+ if (begin <= as_begin &&
+ end >= as_end)
+ return(DD_TRUE);
+ return(DD_FALSE);
+}
+
+bool
+cl_address_decoder::is_in(t_addr begin, t_addr end)
+{
+ if (begin >= as_begin &&
+ begin <= as_end)
+ return(DD_TRUE);
+ if (end >= as_begin &&
+ end <= as_end)
+ return(DD_TRUE);
+ return(DD_FALSE);
+}
+
+bool
+cl_address_decoder::covers(t_addr begin, t_addr end)
+{
+ if (begin > as_begin &&
+ end < as_end)
+ return(DD_TRUE);
+ return(DD_FALSE);
+}
+
+
+/* Returns TRUE if shrunken decoder is unnecessary */
+
+bool
+cl_address_decoder::shrink_out_of(t_addr begin, t_addr end)
+{
+ t_addr a= as_begin;
+
+ if (!address_space)
+ return(DD_TRUE);
+ if (begin > a)
+ a= begin;
+ while (a <= end &&
+ a <= as_end)
+ {
+ address_space->undecode_cell(a);
+ a++;
+ }
+ if (begin > as_begin)
+ as_end= begin-1;
+ if (as_end > end)
+ {
+ chip_begin+= (end-as_begin+1);
+ as_begin= end+1;
+ }
+ if (as_end < as_begin)
+ return(DD_TRUE);
+ return(DD_FALSE);
+}
+
+class cl_address_decoder *
+cl_address_decoder::split(t_addr begin, t_addr end)
+{
+ class cl_address_decoder *nd= 0;
+ 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);
+ 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);
+ shrink_out_of(end+1, as_end);
+ }
+ if (nd)
+ nd->init();
+ return(nd);
+}
+
+