📄 mem.cc
字号:
} return(t);}intcl_event_handler::copy_from(class cl_event_handler *eh){ int i, t= CELL_NORMAL; if (!eh) return(t); for (i= 0; i < eh->read_bps->count; i++) { class cl_brk *bp= (class cl_brk *)(eh->read_bps->at(i)); t|= add_bp(bp); } for (i= 0; i < eh->write_bps->count; i++) { class cl_brk *bp= (class cl_brk *)(eh->write_bps->at(i)); t|= add_bp(bp); } return(t);}intcl_event_handler::del_bp(class cl_brk *bp){ int t= CELL_NORMAL; write_bps->disconn(bp); read_bps->disconn(bp); if (write_bps->count) t|= CELL_WRITE_BRK; if (read_bps->count) t|= CELL_READ_BRK; return(t);}/* */cl_event_cell::cl_event_cell(uchar awidth, class cl_uc *auc): cl_normal_cell(awidth){ eh= new cl_event_handler(auc);}cl_event_cell::~cl_event_cell(void){ delete eh;}t_memcl_event_cell::read(void){ if (type & CELL_READ_BRK) eh->read(); return(cl_normal_cell::read());}t_memcl_event_cell::write(t_mem val){ if (type & CELL_WRITE_BRK) eh->write(); return(cl_normal_cell::write(val));}/* */cl_ev_reg_cell::cl_ev_reg_cell(uchar awidth, class cl_uc *auc): cl_registered_cell(awidth){ eh= new cl_event_handler(auc);}cl_ev_reg_cell::~cl_ev_reg_cell(void){}t_memcl_ev_reg_cell::read(void){ if (type & CELL_READ_BRK) eh->read(); return(cl_registered_cell::read());}t_memcl_ev_reg_cell::write(t_mem val){ if (type & CELL_WRITE_BRK) eh->write(); return(cl_registered_cell::write(val));}/* */cl_mapped_cell::cl_mapped_cell(class cl_cell *realcell){ real_cell= realcell;}cl_mapped_cell::~cl_mapped_cell(void){}t_memcl_mapped_cell::read(void){ return(real_cell->read());}t_memcl_mapped_cell::read(enum hw_cath skip){ return(real_cell->read(skip));}t_memcl_mapped_cell::get(void){ return(real_cell->get());}t_memcl_mapped_cell::write(t_mem val){ return(real_cell->write(val));}t_memcl_mapped_cell::set(t_mem val){ return(real_cell->set(val));}t_memcl_mapped_cell::add(long what){ return(real_cell->add(what));}t_memcl_mapped_cell::wadd(long what){ return(real_cell->wadd(what));}voidcl_mapped_cell::set_bit1(t_mem bits){ return(real_cell->set_bit1(bits));}voidcl_mapped_cell::set_bit0(t_mem bits){ return(real_cell->set_bit0(bits));}class cl_cell *cl_mapped_cell::add_hw(class cl_hw *hw, int *ith){ return(real_cell->add_hw(hw, ith));}class cl_hw *cl_mapped_cell::get_hw(int ith){ return(real_cell->get_hw(ith));}class cl_event_handler *cl_mapped_cell::get_event_handler(void){ return(real_cell->get_event_handler());}/* */cl_m::cl_m(enum mem_class atype, char *aclass_name, t_addr asize, int awidth, class cl_uc *auc): cl_mem(atype, aclass_name, 0, awidth, auc){ t_addr a; size= asize; width= awidth; array= (class cl_cell **)calloc(size, sizeof(class cl_cell *)); for (a= 0; a < size; a++) array[a]= new cl_normal_cell(width); bus_mask= 0; t_addr i; for (i= 1; i < size; i<<=1) bus_mask= (bus_mask<<1)|1; dummy= new cl_normal_cell(width); //mk_cell(size, 0);}cl_m::~cl_m(void){ t_addr a; for (a= 0; a < size; a++) delete array[a]; free(array); delete dummy;}voidcl_m::err_inv_addr(t_addr addr){ if (!uc) return; class cl_error *e= new cl_err_inv_addr(this, addr); uc->error(e);}/*voidcl_m::mk_cell(t_addr addr, class cl_cell *cell){ if (!cell) cell= new cl_cell(width); class cl_cell *p; if (addr >= size) p= dummy; else p= array[addr]; if (p == 0) { p= (class cl_cell *)calloc(1, sizeof(*cell)); } else { p->destroy(); p= (class cl_cell *)realloc(p, sizeof(cell)); } memcpy(p, cell, sizeof(*cell)); cell->destroy(); delete cell;}*/intcl_m::get_cell_flag(t_addr addr){ if (addr >= size) { return(dummy->get_type()); } return(array[addr]->get_type());}boolcl_m::get_cell_flag(t_addr addr, int flag){ if (addr >= size) { return(dummy->get_type() & flag); } return(array[addr]->get_type() & flag);}voidcl_m::set_cell_flag(t_addr addr, bool set_to, int flag){ class cl_cell *cell; if (addr >= size) { cell= dummy; } else cell= array[addr]; if (set_to) cell->set_type(cell->get_type() | flag); else cell->set_type(cell->get_type() & ~flag);}t_memcl_m::read(t_addr addr){ //addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); return(dummy->read()); } return(array[addr]->read());}t_memcl_m::read(t_addr addr, enum hw_cath skip){ //addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); return(dummy->read(skip)); } return(array[addr]->read(skip));}t_memcl_m::get(t_addr addr){ addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); return(dummy->get()); } return(array[addr]->get());}t_memcl_m::write(t_addr addr, t_mem val){ //addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); return(dummy->write(val)); } return(array[addr]->write(val));}voidcl_m::set(t_addr addr, t_mem val){ if (addr >= size) { err_inv_addr(addr); //addr&= bus_mask; dummy->set(val); return; } //addr&= bus_mask; array[addr]->set(val);}class cl_cell *cl_m::get_cell(t_addr addr){ //addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); return(dummy); } return(array[addr]);}/* Set or clear bits, without callbacks */voidcl_m::set_bit1(t_addr addr, t_mem bits){ class cl_cell *cell; addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); cell= dummy; } else cell= array[addr]; bits&= cell->get_mask(); cell->set(cell->get() | bits);}voidcl_m::write_bit1(t_addr addr, t_mem bits){ class cl_cell *cell; addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); cell= dummy; } else cell= array[addr]; bits&= cell->get_mask(); cell->write(cell->get() | bits);}voidcl_m::set_bit0(t_addr addr, t_mem bits){ class cl_cell *cell; addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); cell= dummy; } else cell= array[addr]; bits&= cell->get_mask(); cell->set(cell->get() & ~bits);}voidcl_m::write_bit0(t_addr addr, t_mem bits){ class cl_cell *cell; addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); cell =dummy; } else cell= array[addr]; bits&= cell->get_mask(); cell->write(cell->get() & ~bits);}t_memcl_m::add(t_addr addr, long what){ addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); return(dummy->add(what)); } return(array[addr]->add(what));}t_memcl_m::wadd(t_addr addr, long what){ addr&= bus_mask; if (addr >= size) { err_inv_addr(addr); return(dummy->wadd(what)); } return(array[addr]->wadd(what));}class cl_cell *cl_m::register_hw(t_addr addr, class cl_hw *hw, int *ith, bool announce){ class cl_cell *cell, *nc; addr&= bus_mask; if (addr >= size) cell= dummy; else cell= array[addr]; if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE)) { /* Already registered */ return(cell->add_hw(hw, ith)); } else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK)) { /* Event break is set on it, now register hw */ nc= new cl_ev_reg_cell(width, uc); nc->set(cell->get()); nc->set_type(nc->get_type() & ~(CELL_GENERAL|CELL_READ_BRK|CELL_WRITE_BRK)); nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL)); class cl_event_handler *eh= nc->get_event_handler(); if (eh) nc->set_type(nc->get_type() | eh->copy_from(cell->get_event_handler())); nc->add_hw(hw, ith); } else { /* Normal cell, register hw */ nc= new cl_registered_cell(width); nc->set(cell->get()); nc->set_type(nc->get_type() & ~CELL_GENERAL); nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL)); nc->add_hw(hw, ith); } if (addr >= size) { delete dummy; dummy= nc; } else { delete array[addr]; array[addr]= nc; } if (announce) uc->sim->/*app->*/mem_cell_changed(this, addr); return(nc);}voidcl_m::set_brk(t_addr addr, class cl_brk *brk){ class cl_cell *cell, *nc; char e= '_'; addr&= bus_mask; if (addr >= size) cell= dummy; else cell= array[addr]; switch (brk->get_event()) { case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: e= 'W'; break; case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR: e= 'R'; break; case brkNONE: set_cell_flag(addr, DD_TRUE, CELL_FETCH_BRK); return; break; default: e= '.'; break; } if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE)) { /* Hw is registered on it, now set event break */ nc= new cl_ev_reg_cell(width, uc); nc->set(cell->get()); nc->set_type(nc->get_type() & ~CELL_GENERAL); nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL)); int i= 0; class cl_hw *hw; while ((hw= cell->get_hw(i)) != 0) { nc->add_hw(hw, 0); i++; } if (((class cl_registered_cell *)cell)->hardwares) { free(((class cl_registered_cell *)cell)->hardwares); ((class cl_registered_cell *)cell)->hardwares= 0; } class cl_event_handler *eh; if ((eh= nc->get_event_handler())) nc->set_type(nc->get_type() | eh->add_bp(brk)); } else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK)) { /* Break is already set on it */ class cl_event_handler *eh; if ((eh= cell->get_event_handler())) cell->set_type(cell->get_type() | eh->add_bp(brk)); return; } else { /* Normal cell, set event break */ nc= new cl_event_cell(width, uc); nc->set(cell->get()); nc->set_type(nc->get_type() & ~CELL_GENERAL); nc->set_type(nc->get_type() | (cell->get_type() & CELL_GENERAL)); class cl_event_handler *eh; if ((eh= nc->get_event_handler())) nc->set_type(nc->get_type() | eh->add_bp(brk)); } if (addr >= size) { delete dummy; dummy= nc; } else { delete array[addr]; array[addr]= nc; } uc->sim->/*app->*/mem_cell_changed(this, addr);}voidcl_m::del_brk(t_addr addr, class cl_brk *brk){ class cl_cell *cell, *nc; char e= '_'; addr&= bus_mask; if (addr >= size) cell= dummy; else cell= array[addr]; switch (brk->get_event()) { case brkWRITE: case brkWXRAM: case brkWIRAM: case brkWSFR: e= 'W'; break; case brkREAD: case brkRXRAM: case brkRCODE: case brkRIRAM: case brkRSFR: e= 'R'; break; case brkNONE: set_cell_flag(addr, DD_FALSE, CELL_FETCH_BRK); return; break; default: e= '.'; break; } if (cell->get_type() & (CELL_HW_READ | CELL_HW_WRITE)) { /* Hw is registered on it, delete event break */ class cl_event_handler *eh; int t= CELL_NORMAL; if ((eh= cell->get_event_handler())) t= eh->del_bp(brk); if (t & (CELL_READ_BRK|CELL_WRITE_BRK)) { cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK)); cell->set_type(cell->get_type() | t); return; } nc= new cl_registered_cell(width); nc->set(cell->get()); nc->set_type(cell->get_type() & ~CELL_GENERAL); nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL)); int i= 0; class cl_hw *hw; while ((hw= cell->get_hw(i)) != 0) { nc->add_hw(hw, 0); i++; } if (((class cl_registered_cell *)cell)->hardwares) free(((class cl_registered_cell *)cell)->hardwares); } else if (cell->get_type() & (CELL_READ_BRK | CELL_WRITE_BRK)) { /* Break already set on it, delete brk */ class cl_event_handler *eh; int t= CELL_NORMAL; if ((eh= cell->get_event_handler())) t= eh->del_bp(brk); if (t & (CELL_READ_BRK|CELL_WRITE_BRK)) { cell->set_type(cell->get_type() & ~(CELL_READ_BRK|CELL_WRITE_BRK)); cell->set_type(cell->get_type() | t); return; } nc= new cl_normal_cell(width); nc->set(cell->get()); nc->set_type(cell->get_type() & ~CELL_GENERAL); nc->set_type(cell->get_type() | (cell->get_type() & CELL_GENERAL)); return; } else { /* Normal cell */ return; } if (addr >= size) { delete dummy; dummy= nc; } else { delete array[addr]; array[addr]= nc; } uc->sim->/*app->*/mem_cell_changed(this, addr);}#ifdef STATISTICunsigned longcl_m::get_nuof_reads(void){ unsigned long res= 0; t_addr i; for (i= 0; i < size; i++) res+= array[i]->nuof_reads; return(res);}unsigned longcl_m::get_nuof_writes(void){ unsigned long res= 0; t_addr i; for (i= 0; i < size; i++) res+= array[i]->nuof_writes; return(res);}voidcl_m::set_nuof_reads(unsigned long value){ t_addr i; for (i= 0; i < size; i++) array[i]->nuof_reads= value; dummy->nuof_reads= value;}voidcl_m::set_nuof_writes(unsigned long value){ t_addr i; for (i= 0; i < size; i++) array[i]->nuof_writes= value; dummy->nuof_writes= value;}#endif/* * Errors in memory handling */cl_err_inv_addr::cl_err_inv_addr(class cl_mem *amem, t_addr aaddr): cl_error(){ mem= amem; addr= aaddr;}voidcl_err_inv_addr::print(class cl_commander *c){ c->dd_printf("Error: invalid address "); c->dd_printf(mem->addr_format, addr); c->dd_printf(" in memory %s.\n", mem->class_name);}/* End of mem.cc */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -