⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem.cc

📁 sdcc是为51等小型嵌入式cpu设计的c语言编译器支持数种不同类型的cpu
💻 CC
📖 第 1 页 / 共 2 页
字号:
				   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 **)calloc(size, sizeof(class cl_memory_cell*));  dummy= new cl_dummy_cell();}cl_address_space::~cl_address_space(void){  delete decoders;  int i;  for (i= 0; i < size; i++)    if (cells[i])      delete cells[i];  delete dummy;}  t_memcl_address_space::read(t_addr addr){  return get_cell(addr)->read();}t_memcl_address_space::read(t_addr addr, enum hw_cath skip){  cl_memory_cell *cell = get_cell(addr);  if (cell == dummy)    {      return dummy->read();    }  return cell->read(skip);}t_memcl_address_space::get(t_addr addr){  return get_cell(addr)->get();}t_memcl_address_space::write(t_addr addr, t_mem val){  return get_cell(addr)->write(val);}voidcl_address_space::set(t_addr addr, t_mem val){  get_cell(addr)->set(val);}t_memcl_address_space::wadd(t_addr addr, long what){  return get_cell(addr)->wadd(what);}/* Set or clear bits, without callbacks */voidcl_address_space::set_bit1(t_addr addr, t_mem bits){  cl_memory_cell *cell = get_cell(addr);  if (cell == dummy)    {    return;    }  cell->set_bit1(bits);}voidcl_address_space::set_bit0(t_addr addr, t_mem bits){  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){  t_addr idx= addr-start_address;  if (idx >= size ||      addr < start_address)    {      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]);}intcl_address_space::get_cell_flag(t_addr addr){  return get_cell(addr)->get_flags();}boolcl_address_space::get_cell_flag(t_addr addr, enum cell_flag flag){  return get_cell(addr)->get_flag(flag);}voidcl_address_space::set_cell_flag(t_addr addr, bool set_to, enum cell_flag flag){  get_cell(addr)->set_flag(flag, set_to);}boolcl_address_space::decode_cell(t_addr addr,			      class cl_memory_chip *chip, t_addr chipaddr){  cl_memory_cell *cell = get_cell(addr);  if (cell == dummy)    {      return(DD_FALSE);    }  if (!cell->get_flag(CELL_NON_DECODED))    {      // un-decode first!      cell->un_decode();    }  cell->decode(chip, chipaddr);  return(!cell->get_flag(CELL_NON_DECODED));}voidcl_address_space::undecode_cell(t_addr addr){  t_addr idx= addr-start_address;  if (idx >= size ||      addr < start_address)    {      err_inv_addr(addr);      return;    }  if (cells[idx] == NULL)    {      return;    }  cells[idx]->un_decode();}voidcl_address_space::undecode_area(class cl_address_decoder *skip,				t_addr begin, t_addr end,class cl_console *con){#define D if (con) con->debug  D("Undecoding area 0x%x-0x%x of %s\n", begin, end, get_name());  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 ||	  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);      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;	}      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);	    }	}      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);	    }	}    }#undef D}class cl_memory_cell *cl_address_space::register_hw(t_addr addr, class cl_hw *hw,			      int *ith,			      bool announce){  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)    ;//uc->sim->/*app->*/mem_cell_changed(this, addr);//FIXME  return(cell);}voidcl_address_space::set_brk(t_addr addr, class cl_brk *brk){  cl_memory_cell *cell = get_cell(addr);  if (cell == dummy)    {      return;    }  class cl_memory_operator *op;  switch (brk->get_event())    {    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);      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);      break;    case brkNONE:      set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK);      return;      break;    default:      //e= '.';      op= 0;      break;      }  if (op)    cell->append_operator(op);}voidcl_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_indexcl_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(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);}intcl_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_memcl_memory_chip::get(t_addr addr){  if (!array ||      size <= addr)    return(0);  return(array[addr]);}voidcl_memory_chip::set(t_addr addr, t_mem val){  if (!array ||      size <= addr)    return;  array[addr]= val & data_mask;}voidcl_memory_chip::set_bit1(t_addr addr, t_mem bits){  if (!array ||      size <= addr)    return;  array[addr]|= (bits & data_mask);}voidcl_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);}intcl_address_decoder::init(void){  return(0);}boolcl_address_decoder::activate(class cl_console *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);}boolcl_address_decoder::fully_covered_by(t_addr begin, t_addr end){  if (begin <= as_begin &&      end >= as_end)    return(DD_TRUE);  return(DD_FALSE);}boolcl_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);}boolcl_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 */boolcl_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);}/* * List of address decoders */cl_decoder_list::cl_decoder_list(t_index alimit, t_index adelta, bool bychip):  cl_sorted_list(alimit, adelta, "decoder list"){  Duplicates= DD_TRUE;  by_chip= bychip;}void *cl_decoder_list::key_of(void *item){  class cl_address_decoder *d= (class cl_address_decoder *)item;  if (by_chip)    return(&(d->chip_begin));  else    return(&(d->as_begin));}intcl_decoder_list::compare(void *key1, void *key2){  t_addr k1= *((t_addr*)key1), k2= *((t_addr*)key2);  if (k1 == k2)    return(0);  else if (k1 > k2)    return(1);  return(-1);}/* * Errors in memory handling *//* All of memory errors */cl_error_mem::cl_error_mem(class cl_memory *amem, t_addr aaddr){  mem= amem;  addr= aaddr;  classification= mem_error_registry.find("memory");}/* Invalid address in memory access */cl_error_mem_invalid_address::cl_error_mem_invalid_address(class cl_memory *amem, t_addr aaddr):  cl_error_mem(amem, aaddr){  classification= mem_error_registry.find("invalid_address");}voidcl_error_mem_invalid_address::print(class cl_commander *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());}/* Non-decoded address space access */cl_error_mem_non_decoded::cl_error_mem_non_decoded(class cl_memory *amem, t_addr aaddr):  cl_error_mem(amem, aaddr){  classification= mem_error_registry.find("non_decoded");}voidcl_error_mem_non_decoded::print(class cl_commander *c){  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());}cl_mem_error_registry::cl_mem_error_registry(void){  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));}/* End of mem.cc */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -