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

📄 mem.cc

📁 sdcc是为51等小型嵌入式cpu设计的c语言编译器支持数种不同类型的cpu
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* * Simulator of microcontrollers (mem.cc) * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. *  * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * *//*    This file is part of microcontroller simulator: ucsim.       UCSIM is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      UCSIM is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with UCSIM; see the file COPYING.  If not, write to the Free   Software Foundation, 59 Temple Place - Suite 330, Boston, MA    02111-1307, USA.*//*@1@*/#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include "i_string.h"// prj#include "utils.h"#include "globals.h"// sim#include "simcl.h"// cmd#include "newcmdcl.h"#include "cmdutil.h"// local#include "memcl.h"#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_base(){  size= asize;  set_name(id);  addr_format= data_format= 0;  width= awidth;  start_address= 0;  uc= 0;}cl_memory::~cl_memory(void){  if (addr_format)    free(addr_format);  if (data_format)    free(data_format);}intcl_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))))));  data_format= (char *)malloc(10);  sprintf(data_format, "%%0%dx", width/4+((width%4)?1:0));  data_mask= 1;  int w= width;  for (--w; w; w--)    {      data_mask<<= 1;      data_mask|= 1;    }  dump_finished= start_address;  return(0);}boolcl_memory::valid_address(t_addr addr){  return(addr >= start_address &&	 addr < start_address+size);}t_addrcl_memory::inc_address(t_addr addr, int val){  if (!start_address)    return(((signed)addr+val)%size);  addr-= start_address;  addr+= val;  addr%= size;  addr+= start_address;  return(addr);}t_addrcl_memory::inc_address(t_addr addr){  if (!start_address)    return(((signed)addr+1)%size);  addr-= start_address;  addr++;  addr%= size;  addr+= start_address;  return(addr);}t_addrcl_memory::validate_address(t_addr addr){  while (addr < start_address)    addr+= size;  if (addr > start_address+size)    {      addr-= start_address;      addr%= size;      addr+= start_address;    }  return(addr);}voidcl_memory::err_inv_addr(t_addr addr){  if (!uc)    return;  class cl_error *e= new cl_error_mem_invalid_address(this, addr);  uc->error(e);}voidcl_memory::err_non_decoded(t_addr addr){  if (!uc)    return;  class cl_error *e= new cl_error_mem_non_decoded(this, addr);  uc->error(e);}t_addrcl_memory::dump(t_addr start, t_addr stop, int bpl, class cl_console *con){  int i;  t_addr lva= lowest_valid_address();  t_addr hva= highest_valid_address();  if (start < lva)    start= lva;  if (stop > hva)    stop= hva;  while ((start <= stop) &&	 (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(" ");	}      while (i < bpl)	{	  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)):'.');	}      con->dd_printf("\n");      dump_finished= start+i;      start+= bpl;    }  return(dump_finished);}t_addrcl_memory::dump(class cl_console *con){  return(dump(dump_finished, dump_finished+10*8-1, 8, con));}boolcl_memory::search_next(bool case_sensitive,		       t_mem *array, int len, t_addr *addr){  t_addr a;  int i;  bool found;  if (addr == NULL)    a= 0;  else    a= *addr;    if (a+len > size)    return(DD_FALSE);  found= DD_FALSE;  while (!found &&	 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;	}      found= match;      if (!found)	a++;    }  if (addr)    *addr= a;  return(found);}/* *                                                             Memory operators */cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,				       t_addr addr):  cl_base(){  cell= acell;  data= 0;  mask= ~0;  next_operator= 0;  address= addr;}cl_memory_operator::cl_memory_operator(class cl_memory_cell *acell,				       t_addr addr,				       t_mem *data_place, t_mem the_mask):  cl_base(){  cell= acell;  data= data_place;  mask= the_mask;  next_operator= 0;  address= addr;}voidcl_memory_operator::set_data(t_mem *data_place, t_mem the_mask){  data= data_place;  mask= the_mask;}t_memcl_memory_operator::read(void){  if (next_operator)    return(next_operator->read());  else    return(*data);}t_memcl_memory_operator::write(t_mem val){  if (next_operator)    return(next_operator->write(val));  else    return(*data= (val & mask));}/* 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):  cl_memory_operator(acell, addr, data_place, the_mask){  hw= ahw;}t_memcl_hw_operator::read(void){  t_mem d= 0;  if (hw)    d= hw->read(cell);  if (next_operator)    next_operator->read();  return(d);}t_memcl_hw_operator::read(enum hw_cath skip){  t_mem d= *data;  if (hw &&      hw->cathegory != skip)    d= hw->read(cell);  if (next_operator)    next_operator->read();  return(d);  }t_memcl_hw_operator::write(t_mem val){  if (hw)    hw->write(cell, &val);  if (next_operator)    val= next_operator->write(val);  return(*data= (val & mask));}/* 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):  cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp){  uc= auc;  bp= the_bp;}t_memcl_write_operator::write(t_mem val){  //printf("write event at 0x%x bp=%p\n",address,bp);  uc->events->add(bp);  if (next_operator)    return(next_operator->write(val));  else    return(*data= (val & mask));}/* 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):  cl_event_break_operator(acell, addr, data_place, the_mask, auc, the_bp){  uc= auc;  bp= the_bp;}t_memcl_read_operator::read(void){  //printf("read event at 0x%x bp=%p\n",address,bp);  uc->events->add(bp);  if (next_operator)    return(next_operator->read());  else    return(*data);}/* *                                                                  Memory cell */cl_memory_cell::cl_memory_cell(void):  cl_base(){  data= (t_mem *)malloc(sizeof(t_mem));  flags= CELL_NON_DECODED;  width= 8;  *data= 0;  operators= NULL;#ifdef STATISTIC  nuof_writes= nuof_reads= 0;#endif  mask= 1;  int w= width;  for (--w; w; w--)    {      mask<<= 1;      mask|= 1;    }}cl_memory_cell::~cl_memory_cell(void){  if ((flags & CELL_NON_DECODED) &&      data)    free(data);}intcl_memory_cell::init(void){  cl_base::init();  set(0/*rand()*/);  return(0);}TYPE_UBYTEcl_memory_cell::get_flags(void){  return(flags);}boolcl_memory_cell::get_flag(enum cell_flag flag){  return(flags & flag);}voidcl_memory_cell::set_flags(TYPE_UBYTE what){  flags= what;}voidcl_memory_cell::set_flag(enum cell_flag flag, bool val){  if (val)    flags|= flag;  else    flags&= ~(flag);}voidcl_memory_cell::un_decode(void){  if ((flags & CELL_NON_DECODED) == 0)    {      data= (t_mem *)malloc(sizeof(t_mem));      flags|= CELL_NON_DECODED;    }}voidcl_memory_cell::decode(class cl_memory_chip *chip, t_addr addr){  if (flags & CELL_NON_DECODED)    free(data);  data= chip->get_slot(addr);  if (!data)    {      data= (t_mem *)malloc(sizeof(t_mem));      flags|= CELL_NON_DECODED;    }  else    flags&= ~(CELL_NON_DECODED);}t_memcl_memory_cell::read(void){#ifdef STATISTIC  nuof_reads++;#endif  if (operators)    return(operators->read());  return(*data);}t_memcl_memory_cell::read(enum hw_cath skip){#ifdef STATISTIC  nuof_reads++;#endif  if (operators)    return(operators->read(skip));  return(*data);} t_memcl_memory_cell::get(void) {  return(*data);}t_memcl_memory_cell::write(t_mem val){#ifdef STATISTIC  nuof_writes++;#endif  if (operators)    return(operators->write(val));  *data= val & mask;  return(*data);}t_memcl_memory_cell::set(t_mem val){  *data= val & mask;  return(*data);}t_memcl_memory_cell::add(long what){  *data= (*data + what) & mask;  return(*data);}t_memcl_memory_cell::wadd(long what){  t_mem d= (*data + what) & mask;  return(write(d));}voidcl_memory_cell::set_bit1(t_mem bits){  bits&= mask;  (*data)|= bits;}voidcl_memory_cell::set_bit0(t_mem bits){  bits&= mask;  (*data)&= ~bits;}voidcl_memory_cell::append_operator(class cl_memory_operator *op){  if (!operators)    operators= op;  else    {      class cl_memory_operator *o= operators, *n;      n= o->get_next();      while (n)	{	  o= n;	  n= o->get_next();	}      o->set_next(op);    }}voidcl_memory_cell::prepend_operator(class cl_memory_operator *op){  if (op)    {      op->set_next(operators);      operators= op;    }}voidcl_memory_cell::del_operator(class cl_brk *brk){  if (!operators)    return;  class cl_memory_operator *op= operators;  if (operators->match(brk))    {      operators= op->get_next();      delete op;    }  else    {      while (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_cell *cl_memory_cell::add_hw(class cl_hw *hw, int *ith, t_addr addr){  class cl_hw_operator *o= new cl_hw_operator(this, addr, data, mask, hw);  append_operator(o);  return(this);}/*class cl_hw *cl_memory_cell::get_hw(int ith){  return(0);}*/class cl_event_handler *cl_memory_cell::get_event_handler(void){  return(0);}/* * Dummy cell for non-existent addresses */t_memcl_dummy_cell::write(t_mem val){#ifdef STATISTIC  nuof_writes++;#endif  *data= rand() & mask;  return(*data);}t_memcl_dummy_cell::set(t_mem val){  *data= rand() & mask;  return(*data);}/* *                                                                Address space */cl_address_space::cl_address_space(char *id,

⌨️ 快捷键说明

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