📄 mem.cc
字号:
/* * 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 modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with UCSIM; see the file COPYING. If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA02111-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"// local#include "memcl.h"#include "hwcl.h"/* * Memory location handled specially by a hw element *//*cl_memloc::cl_memloc(t_addr addr): cl_base(){ address= addr; hws= new cl_list(2, 2); hws->init();}*//*cl_memloc::~cl_memloc(void){ hws->disconn_all(); delete hws;}*//*ulongcl_memloc::read(class cl_mem *mem){ uchar ret= 0; class cl_hw *hw; if (!hws || hws->count == 0) return(ret); if ((hw= (class cl_hw *)(hws->at(0)))) ret= hw->read(mem, address); return(ret);}*//*voidcl_memloc::write(class cl_mem *mem, t_addr addr, t_mem *val){ class cl_hw *hw; int i; if (!hws) return; for (i= 0; i < hws->count; i++) { hw= (class cl_hw *)hws->at(0); hw->write(mem, addr, val); }}*//* Sorted collection of memory locations *//*cl_memloc_coll::cl_memloc_coll(void): cl_sorted_list(2, 2){ Duplicates= DD_FALSE;}*//*void *cl_memloc_coll::key_of(void *item){ return(&(((class cl_memloc *)item)->address));}*//*intcl_memloc_coll::compare(void *key1, void *key2){ if (*(long*)key1 > *(long*)key2) return(1); else if (*(long*)key1 < *(long*)key2) return(-1); else return(0);}*//*class cl_memloc *cl_memloc_coll::get_loc(t_addr address){ t_index i; if (search(&address, i)) return((class cl_memloc*)(at(i))); return(0);}*//* * Memory ****************************************************************************** */cl_mem::cl_mem(enum mem_class atype, char *aclass_name, t_addr asize, int awidth, class cl_uc *auc): cl_guiobj(){ int i; uc= auc; type= atype; class_name= aclass_name; width= awidth; size= asize; mem= 0; for (i= width, mask= 0; i; i--) mask= (mask<<1) | 1; if (width == 0 || size == 0) mem= 0; else if (width <= 8) mem= (TYPE_UBYTE *)malloc(size); else if (width <= 16) mem= (TYPE_UWORD *)malloc(size*sizeof(TYPE_WORD)); else mem= (TYPE_UDWORD *)malloc(size*sizeof(TYPE_DWORD)); //read_locs= new cl_memloc_coll(); //write_locs= new cl_memloc_coll(); dump_finished= 0; addr_format= data_format= 0;}cl_mem::~cl_mem(void){ if (mem) free(mem); if (addr_format) free(addr_format); if (data_format) free(data_format); //delete read_locs; //delete write_locs;}intcl_mem::init(void){ t_addr i; 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)); for (i= 0; i < size; i++) set(i, (type==MEM_ROM)?(-1):0); return(0);}char *cl_mem::id_string(void){ char *s= get_id_string(mem_ids, type); return(s?s:(char*)"NONE");}t_memcl_mem::read(t_addr addr){ //class cl_memloc *loc; if (addr >= size) { //FIXME fprintf(stderr, "Address 0x%06"_A_"x is over 0x%06"_A_"x\n", addr, size); return(0); } /*if ((loc= read_locs->get_loc(addr))) return(loc->read(this));*/ if (width <= 8) return((((TYPE_UBYTE*)mem)[addr])&mask); else if (width <= 16) return((((TYPE_UWORD*)mem)[addr])&mask); else return((((TYPE_UDWORD*)mem)[addr])&mask);}t_memcl_mem::get(t_addr addr){ if (addr >= size) return(0); if (width <= 8) return((((TYPE_UBYTE*)mem)[addr])&mask); else if (width <= 16) return((((TYPE_UWORD*)mem)[addr])&mask); else return((((TYPE_UDWORD*)mem)[addr])&mask);}/* * Modify memory location *//* Write calls callbacks of HW elements */t_memcl_mem::write(t_addr addr, t_mem val){ /* class cl_memloc *loc; if (addr >= size) return; if ((loc= write_locs->get_loc(addr))) loc->write(this, addr, val); if (width <= 8) ((TYPE_UBYTE*)mem)[addr]= (*val)&mask; else if (width <= 16) ((TYPE_UWORD*)mem)[addr]= (*val)&mask; else ((TYPE_UDWORD*)mem)[addr]= (*val)&mask;*/ fprintf(stderr, "FIXME cl_mem::write(0x%06"_A_"x, 0x%04"_M_"x)\n", addr, val); return(0);}/* Set doesn't call callbacks */voidcl_mem::set(t_addr addr, t_mem val){ if (addr >= size) return; if (width <= 8) ((TYPE_UBYTE*)mem)[addr]= val&mask; else if (width <= 16) ((TYPE_UWORD*)mem)[addr]= val&mask; else ((TYPE_UDWORD*)mem)[addr]= val&mask;}/* Set or clear bits, without callbacks */voidcl_mem::set_bit1(t_addr addr, t_mem bits){ if (addr >= size) return; bits&= mask; if (width <= 8) ((TYPE_UBYTE*)mem)[addr]|= bits; else if (width <= 16) ((TYPE_UWORD*)mem)[addr]|= bits; else ((TYPE_UDWORD*)mem)[addr]|= bits;}voidcl_mem::set_bit0(t_addr addr, t_mem bits){ if (addr >= size) return; bits&= mask; if (width <= 8) ((TYPE_UBYTE*)mem)[addr]&= ~bits; else if (width <= 16) ((TYPE_UWORD*)mem)[addr]&= ~bits; else ((TYPE_UDWORD*)mem)[addr]&= ~bits;}t_memcl_mem::add(t_addr addr, long what){ if (addr >= size) return(0); if (width <= 8) { ((TYPE_UBYTE*)mem)[addr]= ((TYPE_UBYTE*)mem)[addr] + what; return(((TYPE_UBYTE*)mem)[addr]); } else if (width <= 16) { ((TYPE_UWORD*)mem)[addr]= ((TYPE_UWORD*)mem)[addr] + what; return(((TYPE_UWORD*)mem)[addr]); } else { ((TYPE_UDWORD*)mem)[addr]= ((TYPE_UDWORD*)mem)[addr] + what; return(((TYPE_UDWORD*)mem)[addr]); }}t_addrcl_mem::dump(t_addr start, t_addr stop, int bpl, class cl_console *con){ int i; while ((start <= stop) && (start < size)) { con->dd_printf(addr_format, start); con->dd_printf(" "); for (i= 0; (i < bpl) && (start+i < size) && (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 < size) && (start+i <= stop); i++) { long c= get(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_mem::dump(class cl_console *con){ return(dump(dump_finished, dump_finished+10*8-1, 8, con));}boolcl_mem::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);}/* * Bitmap *//*cl_bitmap::cl_bitmap(t_addr asize): cl_base(){ map= (uchar*)malloc(size= asize/(8*SIZEOF_CHAR)); memset(map, 0, size);}cl_bitmap::~cl_bitmap(void){ free(map);}voidcl_bitmap::set(t_addr pos){ int i; if ((i= pos/(8*SIZEOF_CHAR)) < size) map[i]|= (1 << (pos & ((8*SIZEOF_CHAR)-1)));}voidcl_bitmap::clear(t_addr pos){ int i; if ((i= pos/(8*SIZEOF_CHAR)) < size) map[i]&= ~(1 << (pos & ((8*SIZEOF_CHAR)-1)));}boolcl_bitmap::get(t_addr pos){ return(map[pos/(8*SIZEOF_CHAR)] & (1 << (pos & ((8*SIZEOF_CHAR)-1))));}boolcl_bitmap::empty(void){ int i; for (i= 0; i < size && map[i] == 0; i++) ; return(i == size);}*//* * Special memory for code (ROM) *//*cl_rom::cl_rom(t_addr asize, int awidth, class cl_uc *auc): cl_mem(MEM_ROM, get_id_string(mem_classes, MEM_ROM), asize, awidth, auc){ bp_map= new cl_bitmap(asize); inst_map= new cl_bitmap(asize);}cl_rom::~cl_rom(void){ delete bp_map; delete inst_map;}*//* * New type of memory simulation */cl_cell::cl_cell(void): cl_base(){#ifdef STATISTIC nuof_writes= nuof_reads= 0;#endif}cl_normal_cell::cl_normal_cell(uchar awidth): cl_cell(){ type= CELL_NORMAL; data= 0; mask= 1; width= awidth; for (--awidth; awidth; awidth--) { mask<<= 1; mask|= 1; }}t_memcl_normal_cell::add(long what){ t_mem d; if (width <= 8) d= TYPE_BYTE(data) + what; else if (width <= 16) d= TYPE_WORD(data) + what; else d= TYPE_DWORD(data) + what; return(data= d & mask);}t_memcl_normal_cell::wadd(long what){ t_mem d; if (width <= 8) d= TYPE_BYTE(data) + what; else if (width <= 16) d= TYPE_WORD(data) + what; else d= TYPE_DWORD(data) + what; return(write(d));}voidcl_normal_cell::set_bit1(t_mem bits){ bits&= mask; data|= bits;}voidcl_normal_cell::set_bit0(t_mem bits){ bits&= mask; data&= ~bits;}/* */cl_registered_cell::cl_registered_cell(uchar awidth): cl_normal_cell(awidth){ type= CELL_HW_READ | CELL_HW_WRITE; //hws= new cl_list(1, 1); hardwares= 0; nuof_hws= 0;}cl_registered_cell::~cl_registered_cell(void){ if (hardwares) free(hardwares);}/*voidcl_registered_cell::destroy(void){ hardwares= 0; nuof_hws= 0;}*/t_memcl_registered_cell::read(void){ int i; t_mem d= data; if (nuof_hws) for (i= 0; i < nuof_hws; i++) { d= hardwares[i]->read(this); ; }#ifdef STATISTIC nuof_reads++;#endif return(d & mask);}t_memcl_registered_cell::read(enum hw_cath skip){ int i; t_mem d= data; if (nuof_hws) for (i= 0; i < nuof_hws; i++) { if ((skip & hardwares[i]->cathegory) == 0) d= hardwares[i]->read(this); ; }#ifdef STATISTIC nuof_reads++;#endif return(d & mask);}t_memcl_registered_cell::write(t_mem val){ int i; val&= mask; if (nuof_hws) for (i= 0; i < nuof_hws; i++) { hardwares[i]->write(this, &val); ; }#ifdef STATISTIC nuof_writes++;#endif return(data= val & mask);}class cl_cell *cl_registered_cell::add_hw(class cl_hw *hw, int *ith){ if (!hw) { /* Whatta hell!? */ return(0); } if (!hardwares) hardwares= (class cl_hw **)malloc(sizeof(class cl_hw *)); else hardwares= (class cl_hw **)realloc(hardwares, sizeof(class c_hw *) * (nuof_hws+1)); hardwares[nuof_hws]= hw; nuof_hws++; if (ith) *ith= nuof_hws-1; return(this);}class cl_hw *cl_registered_cell::get_hw(int ith){ if (ith >= nuof_hws) return(0); return(hardwares[ith]);}/* */cl_event_handler::cl_event_handler(class cl_uc *auc): cl_base(){ uc= auc; read_bps= new cl_list(1, 1); write_bps= new cl_list(1, 1);}cl_event_handler::~cl_event_handler(void){ read_bps->disconn_all(); write_bps->disconn_all(); delete read_bps; delete write_bps;}voidcl_event_handler::write(void){ int i; for (i= 0; i < write_bps->count; i++) { class cl_brk *bp= (class cl_brk *)(write_bps->at(i)); uc->events->add(bp); }}voidcl_event_handler::read(void){ int i; for (i= 0; i < read_bps->count; i++) { class cl_brk *bp= (class cl_brk *)(read_bps->at(i)); uc->events->add(bp); }}intcl_event_handler::add_bp(class cl_brk *bp){ int t= CELL_NORMAL; if (!bp) return(CELL_NORMAL); switch (bp->get_event()) { case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: t|= CELL_WRITE_BRK; write_bps->add(bp); break; case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR: t|= CELL_READ_BRK; read_bps->add(bp); break; default: t|= CELL_READ_BRK | CELL_WRITE_BRK; read_bps->add(bp); write_bps->add(bp); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -