X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=sim%2Fucsim%2Fsim.src%2Fuc.cc;h=7d7e74238fa604ce4dc7c82c75601eb1edef4a9d;hb=f27cbdc6513b26748661452e50ed3af99fac16a2;hp=026648b0b50088e26106200c6add1570d3af8a1f;hpb=4c3872ef27c1263faae7d9b85c1821381646ece8;p=fw%2Fsdcc diff --git a/sim/ucsim/sim.src/uc.cc b/sim/ucsim/sim.src/uc.cc index 026648b0..7d7e7423 100644 --- a/sim/ucsim/sim.src/uc.cc +++ b/sim/ucsim/sim.src/uc.cc @@ -30,8 +30,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#include #include "i_string.h" +#include "globals.h" +#include "utils.h" + #include "uccl.h" #include "hwcl.h" #include "memcl.h" @@ -146,12 +150,14 @@ cl_uc::init(void) xtal= sim->get_farg('X', 0); for (mc= MEM_ROM; mc < MEM_TYPES; mc++) { - class cl_mem *m= mk_mem((enum mem_class)mc); + class cl_mem *m= mk_mem((enum mem_class)mc, + get_id_string(mem_classes, mc)); mems->put_at(mc, m); } ebrk= new brk_coll(2, 2, (class cl_rom *)mem(MEM_ROM)); fbrk= new brk_coll(2, 2, (class cl_rom *)mem(MEM_ROM)); fbrk->Duplicates= DD_FALSE; + brk_counter= 0; mk_hw_elements(); reset(); return(0); @@ -191,7 +197,7 @@ cl_uc::reset(void) */ class cl_mem * -cl_uc::mk_mem(enum mem_class type) +cl_uc::mk_mem(enum mem_class type, char *class_name) { class cl_mem *m; @@ -200,7 +206,8 @@ cl_uc::mk_mem(enum mem_class type) if (type == MEM_ROM) m= new cl_rom(get_mem_size(type), get_mem_width(type)); else - m= new cl_mem(type, get_mem_size(type), get_mem_width(type)); + m= new cl_mem(type, get_id_string(mem_classes, type), + get_mem_size(type), get_mem_width(type)); m->init(); return(m); } @@ -237,7 +244,7 @@ cl_uc::mk_hw_elements(void) */ ulong -cl_uc::read_mem(enum mem_class type, long addr) +cl_uc::read_mem(enum mem_class type, t_mem addr) { class cl_mem *m; @@ -249,7 +256,7 @@ fprintf(stderr, "cl_uc::read_mem(type= %d, 0x%06lx) TROUBLE\n", type, addr); } ulong -cl_uc::get_mem(enum mem_class type, long addr) +cl_uc::get_mem(enum mem_class type, t_addr addr) { class cl_mem *m; @@ -261,7 +268,7 @@ printf("cl_uc::get_mem(type= %d, 0x%06lx) TROUBLE\n", type, addr); } void -cl_uc::write_mem(enum mem_class type, long addr, ulong val) +cl_uc::write_mem(enum mem_class type, t_addr addr, t_mem val) { class cl_mem *m; @@ -275,7 +282,7 @@ else printf("cl_uc::write_mem(type= %d, 0x%06lx, 0x%lx) TROUBLE\n", type, addr, } void -cl_uc::set_mem(enum mem_class type, long addr, ulong val) +cl_uc::set_mem(enum mem_class type, t_addr addr, t_mem val) { class cl_mem *m; @@ -295,7 +302,50 @@ cl_uc::mem(enum mem_class type) return((class cl_mem *)(mems->at(type))); } -TYPE_UBYTE * +class cl_mem * +cl_uc::mem(char *class_name) +{ + int i, found= 0; + char *mcn, *n, *s; + + if (!class_name) + return(0); + s= n= strdup(class_name); + while (*s) + { + *s= toupper(*s); + s++; + } + if (!class_name || + !(*class_name)) + return(0); + for (i= 0; !found && i < mems->count; i++) + { + cl_mem *m= (cl_mem *)(mems->at(i)); + if (!m || + !m->class_name || + !(*(m->class_name))) + continue; + s= mcn= strdup(m->class_name); + while (*s) + { + *s= toupper(*s); + s++; + } + if (strstr(/*m->class_name*/mcn,/*class_name*/n) == /*m->class_name*/mcn) + found= 1; + free(mcn); + if (found) + { + free(n); + return(m); + } + } + free(n); + return(0); +} + +/*TYPE_UBYTE * cl_uc::MEM(enum mem_class type) { class cl_mem *m; @@ -304,8 +354,8 @@ cl_uc::MEM(enum mem_class type) //FIXME {printf("TROUBLE\n"); return(0); } - return((uchar *)(m->mem)); -} + return((TYPE_UBYTE *)(m->mem)); +}*/ /* Local function for `read_hex_file' method to read some bytes */ @@ -465,7 +515,7 @@ cl_uc::read_hex_file(const char *name) */ bool -cl_uc::inst_at(uint addr) +cl_uc::inst_at(t_addr addr) { class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); @@ -475,7 +525,7 @@ cl_uc::inst_at(uint addr) } void -cl_uc::set_inst_at(uint addr) +cl_uc::set_inst_at(t_addr addr) { class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); @@ -484,7 +534,7 @@ cl_uc::set_inst_at(uint addr) } void -cl_uc::del_inst_at(uint addr) +cl_uc::del_inst_at(t_addr addr) { class cl_rom *rom= (class cl_rom *)mem(MEM_ROM); @@ -511,7 +561,7 @@ cl_uc::there_is_inst(void) /* Register callback hw objects for mem read/write */ void -cl_uc::register_hw_read(enum mem_class type, long addr, class cl_hw *hw) +cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw) { class cl_mem *m; class cl_memloc *l; @@ -531,7 +581,7 @@ cl_uc::register_hw_read(enum mem_class type, long addr, class cl_hw *hw) } void -cl_uc::register_hw_write(enum mem_class type, long addr, class cl_hw *hw) +cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw) { } @@ -558,6 +608,27 @@ cl_uc::get_hw(enum hw_cath cath, int *idx) return(hw); } +class cl_hw * +cl_uc::get_hw(char *id_string, int *idx) +{ + class cl_hw *hw= 0; + int i= 0; + + if (idx) + i= *idx; + for (; i < hws->count; i++) + { + hw= (class cl_hw *)(hws->at(i)); + if (strstr(hw->id_string, id_string) == hw->id_string) + break; + } + if (i >= hws->count) + return(0); + if (idx) + *idx= i; + return(hw); +} + class cl_hw * cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx) { @@ -579,6 +650,27 @@ cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx) return(hw); } +class cl_hw * +cl_uc::get_hw(char *id_string, int hwid, int *idx) +{ + class cl_hw *hw; + int i= 0; + + if (idx) + i= *idx; + hw= get_hw(id_string, &i); + while (hw && + hw->id != hwid) + { + i++; + hw= get_hw(id_string, &i); + } + if (hw && + idx) + *idx= i; + return(hw); +} + /* * Help of the command interpreter @@ -606,7 +698,7 @@ cl_uc::bit_tbl(void) } char * -cl_uc::disass(uint addr, char *sep) +cl_uc::disass(t_addr addr, char *sep) { char *buf; @@ -616,9 +708,41 @@ cl_uc::disass(uint addr, char *sep) } void -cl_uc::print_disass(uint addr, class cl_console *con) +cl_uc::print_disass(t_addr addr, class cl_console *con) { - con->printf("uc::print_disass unimplemented\n"); + char *dis; + class cl_brk *b; + int i; + class cl_mem *rom= mem(MEM_ROM); + t_mem code= get_mem(MEM_ROM, addr); + + if (!rom) + return; + b= fbrk_at(addr); + dis= disass(addr, NULL); + if (b) + con->printf("%c", (b->perm == brkFIX)?'F':'D'); + else + con->printf(" "); + con->printf("%c ", inst_at(addr)?' ':'?'); + con->printf(rom->addr_format, addr); con->printf(" "); + con->printf(rom->data_format, code); + for (i= 1; i < inst_length(code); i++) + { + con->printf(" "); + con->printf(rom->data_format, get_mem(MEM_ROM, addr+i)); + } + int li= longest_inst(); + while (i < li) + { + int j; + j= rom->width/4 + ((rom->width%4)?1:0) + 1; + while (j) + con->printf(" "), j--; + i++; + } + con->printf(" %s\n", dis); + free(dis); } void @@ -628,7 +752,7 @@ cl_uc::print_regs(class cl_console *con) } int -cl_uc::inst_length(uint code) +cl_uc::inst_length(t_mem code) { struct dis_entry *tabl= dis_tbl(); int i; @@ -637,8 +761,24 @@ cl_uc::inst_length(uint code) return(tabl[i].mnemonic?tabl[i].length:1); } +int +cl_uc::longest_inst(void) +{ + struct dis_entry *de= dis_tbl(); + int max= 0; + + while (de && + de->mnemonic) + { + if (de->length > max) + max= de->length; + de++; + } + return(max); +} + bool -cl_uc::get_name(uint addr, struct name_entry tab[], char *buf) +cl_uc::get_name(t_addr addr, struct name_entry tab[], char *buf) { int i; @@ -652,6 +792,57 @@ cl_uc::get_name(uint addr, struct name_entry tab[], char *buf) return(tab[i].name != NULL); } +char * +cl_uc::symbolic_bit_name(t_addr bit_address, + class cl_mem *mem, + t_addr mem_addr, + t_mem bit_mask) +{ + char *sym_name= 0; + int i; + + i= 0; + while (bit_tbl()[i].name && + (bit_tbl()[i].addr != bit_address)) + i++; + if (bit_tbl()[i].name) + { + sym_name= strdup(bit_tbl()[i].name); + return(sym_name); + } + + if (mem && + mem->class_name && + strstr(mem->class_name, "sfr") == mem->class_name) + { + i= 0; + while (sfr_tbl()[i].name && + (sfr_tbl()[i].addr != mem_addr)) + i++; + if (sfr_tbl()[i].name) + sym_name= strdup(sfr_tbl()[i].name); + else + sym_name= 0; + } + if (!sym_name) + { + sym_name= (char *)malloc(16); + sprintf(sym_name, mem?(mem->addr_format):"0x%06x", mem_addr); + } + sym_name= (char *)realloc(sym_name, strlen(sym_name)+2); + strcat(sym_name, "."); + i= 0; + while (bit_mask > 1) + { + bit_mask>>=1; + i++; + } + char bitnumstr[10]; + sprintf(bitnumstr, "%1d", i); + strcat(sym_name, bitnumstr); + return(sym_name); +} + /* * Execution @@ -798,7 +989,7 @@ cl_uc::fetch(void) */ bool -cl_uc::fetch(ulong *code) +cl_uc::fetch(t_mem *code) { class cl_brk *brk; int idx; @@ -916,7 +1107,7 @@ cl_uc::st_ret(class cl_stack_op *op) */ class cl_fetch_brk * -cl_uc::fbrk_at(long addr) +cl_uc::fbrk_at(t_addr addr) { int idx; @@ -945,6 +1136,34 @@ cl_uc::rm_fbrk(long addr) fbrk->del_bp(addr); }*/ +/* Get a breakpoint specified by its number */ + +class cl_brk * +cl_uc::brk_by_nr(int nr) +{ + class cl_brk *bp; + + if ((bp= fbrk->get_bp(nr))) + return(bp); + if ((bp= ebrk->get_bp(nr))) + return(bp); + return(0); +} + +/* Get a breakpoint from the specified collection by its number */ + +class cl_brk * +cl_uc::brk_by_nr(class brk_coll *bpcoll, int nr) +{ + class cl_brk *bp; + + if ((bp= bpcoll->get_bp(nr))) + return(bp); + return(0); +} + +/* Remove an event breakpoint specified by its address and id */ + void cl_uc::rm_ebrk(t_addr addr, char *id) { @@ -960,13 +1179,93 @@ cl_uc::rm_ebrk(t_addr addr, char *id) } } +/* Remove a breakpoint specified by its number */ + +void +cl_uc::rm_brk(int nr) +{ + class cl_brk *bp; + + if ((bp= brk_by_nr(fbrk, nr))) + fbrk->del_bp(bp->addr); + else if ((bp= brk_by_nr(ebrk, nr))) + ebrk->free_at(ebrk->index_of(bp)); +} + void cl_uc::put_breaks(void) {} +/* Remove all fetch and event breakpoints */ + void -cl_uc::remove_breaks(void) -{} +cl_uc::remove_all_breaks(void) +{ + while (fbrk->count) + { + class cl_brk *brk= (class cl_brk *)(fbrk->at(0)); + fbrk->del_bp(brk->addr); + } + while (ebrk->count) + ebrk->free_at(ebrk->count-1); +} + +int +cl_uc::make_new_brknr(void) +{ + if (brk_counter == 0) + return(brk_counter= 1); + if (fbrk->count == 0 && + ebrk->count == 0) + return(brk_counter= 1); + return(++brk_counter); +} + +class cl_ev_brk * +cl_uc::mk_ebrk(enum brk_perm perm, class cl_mem *mem, + char op, t_addr addr, int hit) +{ + class cl_ev_brk *b; + op= toupper(op); + + switch (mem->type) + { + case MEM_ROM: + if (op == 'R') + b= new cl_rc_brk(make_new_brknr(), addr, perm, hit); + else + return(0); + break; + case MEM_IRAM: + if (op == 'R') + b= new cl_ri_brk(make_new_brknr(), addr, perm, hit); + else if (op == 'W') + b= new cl_wi_brk(make_new_brknr(), addr, perm, hit); + else + return(0); + break; + case MEM_XRAM: + if (op == 'R') + b= new cl_rx_brk(make_new_brknr(), addr, perm, hit); + else if (op == 'W') + b= new cl_wx_brk(make_new_brknr(), addr, perm, hit); + else + return(0); + break; + case MEM_SFR: + if (op == 'R') + b= new cl_rs_brk(make_new_brknr(), addr, perm, hit); + else if (op == 'W') + b= new cl_ws_brk(make_new_brknr(), addr, perm, hit); + else + return(0); + break; + default: + return(0); + } + b->init(); + return(b); +} /* End of uc.cc */