X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fsim.src%2Fhw.cc;h=143e9b94b2de76020df5b50d174727aa7f55bf1a;hb=34d14506fd0c12ee5434fec0f9dec27753e1aab5;hp=ed7f8162304c457e9ce53091a5c03f3414fbbddb;hpb=0ac34444ce2ccdcaa5fe722e2420f96c46224039;p=fw%2Fsdcc diff --git a/sim/ucsim/sim.src/hw.cc b/sim/ucsim/sim.src/hw.cc index ed7f8162..143e9b94 100644 --- a/sim/ucsim/sim.src/hw.cc +++ b/sim/ucsim/sim.src/hw.cc @@ -34,8 +34,85 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "hwcl.h" -cl_hw::cl_hw(class cl_uc *auc, enum hw_cath cath, int aid, char *aid_string): - cl_base() +/* + *____________________________________________________________________________ + */ + +cl_watched_cell::cl_watched_cell(class cl_address_space *amem, t_addr aaddr, + class cl_memory_cell **astore, + enum what_to_do_on_cell_change awtd) +{ + mem= amem; + addr= aaddr; + store= astore; + wtd= awtd; + if (mem) + { + cell= mem->get_cell(addr); + if (store) + *store= cell; + } +} + +void +cl_watched_cell::mem_cell_changed(class cl_address_space *amem, t_addr aaddr, + class cl_hw *hw) +{ + if (mem && + mem == amem && + addr == aaddr) + { + cell= mem->get_cell(addr); + if (store && + (wtd & WTD_RESTORE)) + *store= cell; + if (wtd & WTD_WRITE) + { + t_mem d= cell->get(); + hw->write(cell, &d); + } + } +} + +void +cl_watched_cell::address_space_added(class cl_address_space *amem, + class cl_hw *hw) +{ +} + +void +cl_used_cell::mem_cell_changed(class cl_address_space *amem, t_addr aaddr, +class cl_hw *hw) +{ + if (mem && + mem == amem && + addr == aaddr) + { + cell= mem->get_cell(addr); + if (store && + (wtd & WTD_RESTORE)) + *store= cell; + if (wtd & WTD_WRITE) + { + t_mem d= cell->get(); + hw->write(cell, &d); + } + } +} + +void +cl_used_cell::address_space_added(class cl_address_space *amem, + class cl_hw *hw) +{ +} + + +/* + *____________________________________________________________________________ + */ + +cl_hw::cl_hw(class cl_uc *auc, enum hw_cath cath, int aid, const char *aid_string): + cl_guiobj() { flags= HWF_INSIDE; uc= auc; @@ -46,11 +123,50 @@ cl_hw::cl_hw(class cl_uc *auc, enum hw_cath cath, int aid, char *aid_string): id_string= strdup(aid_string); else id_string= strdup("unknown hw element"); + char *s= (char*)malloc(strlen(get_name("hw"))+100); + sprintf(s, "partners of %s", get_name("hw")); + partners= new cl_list(2, 2, s); + sprintf(s, "watched cells of %s", get_name("hw")); + watched_cells= new cl_list(2, 2, s); + free(s); } cl_hw::~cl_hw(void) { free(id_string); + //hws_to_inform->disconn_all(); + delete partners; + delete watched_cells; +} + + +void +cl_hw::new_hw_adding(class cl_hw *new_hw) +{ +} + +void +cl_hw::new_hw_added(class cl_hw *new_hw) +{ + int i; + + for (i= 0; i < partners->count; i++) + { + class cl_partner_hw *ph= (class cl_partner_hw *)(partners->at(i)); + ph->refresh(new_hw); + } +} + +class cl_hw * +cl_hw::make_partner(enum hw_cath cath, int id) +{ + class cl_partner_hw *ph; + class cl_hw *hw; + + ph= new cl_partner_hw(uc, cath, id); + partners->add(ph); + hw= ph->get_partner(); + return(hw); } @@ -58,17 +174,85 @@ cl_hw::~cl_hw(void) * Callback functions for changing memory locations */ -ulong -cl_hw::read(class cl_mem *mem, long addr) +/*t_mem +cl_hw::read(class cl_m *mem, t_addr addr) { // Simply return the value return(mem->get(addr)); +}*/ + +/*void +cl_hw::write(class cl_m *mem, t_addr addr, t_mem *val) +{ + // Do not change *val by default +}*/ + +void +cl_hw::set_cmd(class cl_cmdline *cmdline, class cl_console_base *con) +{ + con->dd_printf("Nothing to do\n"); +} + +class cl_memory_cell * +cl_hw::register_cell(class cl_address_space *mem, t_addr addr, + class cl_memory_cell **store, + enum what_to_do_on_cell_change awtd) +{ + class cl_watched_cell *wc; + class cl_memory_cell *cell; + + if (mem) + mem->register_hw(addr, this, (int*)0, DD_FALSE); + else + printf("regcell JAJ no mem\n"); + wc= new cl_watched_cell(mem, addr, &cell, awtd); + if (store) + *store= cell; + watched_cells->add(wc); + // announce + //uc->sim->mem_cell_changed(mem, addr); + return(cell); +} + +class cl_memory_cell * +cl_hw::use_cell(class cl_address_space *mem, t_addr addr, + class cl_memory_cell **store, + enum what_to_do_on_cell_change awtd) +{ + class cl_watched_cell *wc; + class cl_memory_cell *cell; + + wc= new cl_used_cell(mem, addr, &cell, awtd); + if (store) + *store= cell; + watched_cells->add(wc); + return(cell); } void -cl_hw::write(class cl_mem *mem, long addr, ulong *val) +cl_hw::mem_cell_changed(class cl_address_space *mem, t_addr addr) { - // Do not change *val by default + int i; + + for (i= 0; i < watched_cells->count; i++) + { + class cl_watched_cell *wc= + (class cl_watched_cell *)(watched_cells->at(i)); + wc->mem_cell_changed(mem, addr, this); + } +} + +void +cl_hw::address_space_added(class cl_address_space *as) +{ + int i; + + for (i= 0; i < watched_cells->count; i++) + { + class cl_watched_cell *wc= + dynamic_cast(watched_cells->object_at(i)); + wc->address_space_added(as, this); + } } @@ -83,9 +267,138 @@ cl_hw::tick(int cycles) } void -cl_hw::print_info(class cl_console *con) +cl_hw::inform_partners(enum hw_event he, void *params) +{ + int i; + + for (i= 0; i < partners->count; i++) + { + class cl_partner_hw *ph= (class cl_partner_hw *)(partners->at(i)); + ph->happen(this, he, params); + } +} + + +void +cl_hw::print_info(class cl_console_base *con) +{ + con->dd_printf("%s[%d]\n", id_string, id); +} + + +t_index +cl_hws::add(void *item) +{ + int i; + t_index res; + + // pre-add + for (i= 0; i < count; i++) + { + class cl_hw *hw= (class cl_hw *)(at(i)); + hw->new_hw_adding((class cl_hw *)item); + } + // add + res= cl_list::add(item); + // post-add + for (i= 0; i < count; i++) + { + class cl_hw *hw= (class cl_hw *)(at(i)); + hw->new_hw_added((class cl_hw *)item); + } + ((class cl_hw *)item)->added_to_uc(); + return(res); +} + + +void +cl_hws::mem_cell_changed(class cl_address_space *mem, t_addr addr) +{ + int i; + + for (i= 0; i < count; i++) + { + class cl_hw *hw= (class cl_hw *)(at(i)); + hw->mem_cell_changed(mem, addr); + } +} + +void +cl_hws::address_space_added(class cl_address_space *mem) +{ + int i; + + for (i= 0; i < count; i++) + { + class cl_hw *hw= (class cl_hw *)(at(i)); + hw->address_space_added(mem); + } +} + + +/* + *____________________________________________________________________________ + */ + +cl_partner_hw::cl_partner_hw(class cl_uc *auc, enum hw_cath cath, int aid): + cl_base() +{ + uc= auc; + cathegory= cath; + id= aid; + partner= uc->get_hw(cathegory, id, 0); +} + +class cl_hw * +cl_partner_hw::get_partner(void) +{ + return(partner); +} + +void +cl_partner_hw::refresh(void) +{ + class cl_hw *hw= uc->get_hw(cathegory, id, 0); + + if (!hw) + return; + if (partner) + { + // partner is already set + if (partner != hw) + { + // partner changed? + partner= hw; + } + else + partner= hw; + } + partner= hw; +} + +void +cl_partner_hw::refresh(class cl_hw *new_hw) +{ + if (!new_hw) + return; + if (cathegory == new_hw->cathegory && + id == new_hw->id) + { + if (partner) + { + // partner changed? + partner= new_hw; + } + else + partner= new_hw; + } +} + +void +cl_partner_hw::happen(class cl_hw *where, enum hw_event he, void *params) { - con->printf("%s[%d]\n", id_string, id); + if (partner) + partner->happen(where, he, params); }