#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <ctype.h>
#include "i_string.h"
+// prj
+#include "globals.h"
+#include "utils.h"
+
+// cmd.src
+#include "newcmdcl.h"
+#include "cmduccl.h"
+#include "bpcl.h"
+#include "getcl.h"
+#include "setcl.h"
+#include "infocl.h"
+#include "timercl.h"
+#include "cmdstatcl.h"
+
+// local, sim.src
#include "uccl.h"
#include "hwcl.h"
#include "memcl.h"
options|= TICK_INISR;
dir= adir;
ticks= 0;
- name= aname?strdup(aname):0;
+ set_name(aname);
}
-cl_ticker::~cl_ticker(void)
-{
- if (name)
- free(name);
-}
+cl_ticker::~cl_ticker(void) {}
int
cl_ticker::tick(int nr)
void
cl_ticker::dump(int nr, double xtal, class cl_console *con)
{
- con->printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n",
- nr, name?name:"unnamed",
- (options&TICK_RUN)?"ON":"OFF",
- (options&TICK_INISR)?",ISR":"",
- get_rtime(xtal), ticks);
+ con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n",
+ nr, get_name("unnamed"),
+ (options&TICK_RUN)?"ON":"OFF",
+ (options&TICK_INISR)?",ISR":"",
+ get_rtime(xtal), ticks);
}
int i;
sim = asim;
mems= new cl_list(MEM_TYPES, 1);
- hws = new cl_list(2, 1);
- options= new cl_list(2, 2);
+ hws = new cl_hws();
+ //options= new cl_list(2, 2);
for (i= MEM_ROM; i < MEM_TYPES; i++)
mems->add(0);
ticks= new cl_ticker(+1, 0, "time");
idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle");
counters= new cl_list(2, 2);
it_levels= new cl_list(2, 2);
- it_sources= new cl_list(2, 2);
+ it_sources= new cl_irqs(2, 2);
class it_level *il= new it_level(-1, 0, 0, 0);
it_levels->push(il);
st_ops= new cl_list(2, 2);
+ errors= new cl_list(2, 2);
+ events= new cl_list(2, 2);
sp_max= 0;
sp_avg= 0;
+ inst_exec= DD_FALSE;
}
{
delete mems;
delete hws;
- delete options;
+ //delete options;
delete ticks;
delete isr_ticks;
delete idle_ticks;
delete counters;
+ events->disconn_all();
+ delete events;
delete fbrk;
delete ebrk;
delete it_levels;
delete it_sources;
delete st_ops;
+ errors->free_all();
+ delete errors;
}
int
cl_uc::init(void)
{
- int mc;
+ int mc, i;
cl_base::init();
- if (!(sim->arg_avail('X')) ||
- sim->get_farg('X', 0) == 0)
+ if (!(sim->app->args->arg_avail('X')) ||
+ sim->app->args->get_farg('X', 0) == 0)
xtal= 11059200;
else
- xtal= sim->get_farg('X', 0);
+ xtal= sim->app->args->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));
+ 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();
+ class cl_cmdset *cs= sim->app->get_commander()->cmdset;
+ build_cmdset(cs);
+
+ for (i= 0; i < sim->app->in_files->count; i++)
+ {
+ char *fname= (char *)(sim->app->in_files->at(i));
+ long l;
+ if ((l= read_hex_file(fname)) >= 0)
+ {
+ sim->app->get_commander()->all_printf("%ld words read from %s\n",
+ l, fname);
+ }
+ }
return(0);
}
}
sp_max= 0;
sp_avg= 0;
+
+ int i;
+ for (i= 0; i < hws->count; i++)
+ {
+ class cl_hw *hw= (class cl_hw *)(hws->at(i));
+ hw->reset();
+ }
}
/*
*/
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;
- if (get_mem_size(type) <= 0)
+ if (get_mem_size(type) < 0)
return(0);
- 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_m(type, get_id_string(mem_classes, type),
+ get_mem_size(type), get_mem_width(type), this);
m->init();
return(m);
}
{
case MEM_ROM: return(0x10000);
case MEM_XRAM: return(0x10000);
- case MEM_IRAM: return(0x100);
+ case MEM_IRAM: return(0x80);
case MEM_SFR: return(0x100);
case MEM_TYPES:
default: return(0);
{
}
+void
+cl_uc::build_cmdset(class cl_cmdset *cmdset)
+{
+ class cl_cmd *cmd;
+ class cl_super_cmd *super_cmd;
+ class cl_cmdset *cset;
+
+ cmdset->add(cmd= new cl_state_cmd("state", 0,
+"state State of microcontroller",
+"long help of state"));
+ cmd->init();
+
+#ifdef STATISTIC
+ cmdset->add(cmd= new cl_statistic_cmd("statistic", 0,
+"statistic [mem [startaddr [endaddr]]]\n"
+" Statistic of memory accesses",
+"long help of statistic"));
+ cmd->init();
+#endif
+
+ cmdset->add(cmd= new cl_file_cmd("file", 0,
+"file \"FILE\" Load FILE into ROM",
+"long help of file"));
+ cmd->init();
+ cmd->add_name("load");
+
+ cmdset->add(cmd= new cl_dl_cmd("download", 0,
+"download,dl Load (intel.hex) data",
+"long help of download"));
+ cmd->init();
+ cmd->add_name("dl");
+
+ cmdset->add(cmd= new cl_pc_cmd("pc", 0,
+"pc [addr] Set/get PC",
+"long help of pc"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_reset_cmd("reset", 0,
+"reset Reset",
+"long help of reset"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_dump_cmd("dump", 0,
+"dump memory_type [start [stop [bytes_per_line]]]\n"
+" Dump memory of specified type\n"
+"dump bit... Dump bits",
+"long help of dump"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_di_cmd("di", 0,
+"di [start [stop]] Dump Internal RAM",
+"long help of di"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_dx_cmd("dx", 0,
+"dx [start [stop]] Dump External RAM",
+"long help of dx"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_ds_cmd("ds", 0,
+"ds [start [stop]] Dump SFR",
+"long help of ds"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_dch_cmd("dch", 0,
+"dch [start [stop]] Dump code in hex form",
+"long help of dch"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_dc_cmd("dc", 0,
+"dc [start [stop]] Dump code in disass form",
+"long help of dc"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_disassemble_cmd("disassemble", 0,
+"disassemble [start [offset [lines]]]\n"
+" Disassemble code",
+"long help of disassemble"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_fill_cmd("fill", 0,
+"fill memory_type start end data\n"
+" Fill memory region with data",
+"long help of fill"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_where_cmd("where", 0,
+"where memory_type data...\n"
+" Case unsensitive search for data",
+"long help of where"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_Where_cmd("Where", 0,
+"Where memory_type data...\n"
+" Case sensitive search for data",
+"long help of Where"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_break_cmd("break", 0,
+"break addr [hit] Set fix breakpoint\n"
+"break mem_type r|w addr [hit]\n"
+" Set fix event breakpoint",
+"long help of break"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_tbreak_cmd("tbreak", 0,
+"tbreak addr [hit] Set temporary breakpoint\n"
+"tbreak mem_type r|w addr [hit]\n"
+" Set temporary event breakpoint",
+"long help of tbreak"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_clear_cmd("clear", 0,
+"clear [addr...] Clear fix breakpoint",
+"long help of clear"));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_delete_cmd("delete", 0,
+"delete [nr...] Delete breakpoint(s)",
+"long help of clear"));
+ cmd->init();
+
+ {
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("get"));
+ if (super_cmd)
+ cset= super_cmd->commands;
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ cset->add(cmd= new cl_get_sfr_cmd("sfr", 0,
+"get sfr address...\n"
+" Get value of addressed SFRs",
+"long help of get sfr"));
+ cmd->init();
+ /*cset->add(cmd= new cl_get_option_cmd("option", 0,
+"get option name\n"
+" Get value of an option",
+"long help of get option"));
+cmd->init();*/
+ }
+ if (!super_cmd)
+ {
+ cmdset->add(cmd= new cl_super_cmd("get", 0,
+"get subcommand Get, see `get' command for more help",
+"long help of get", cset));
+ cmd->init();
+ }
+
+ {
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("set"));
+ if (super_cmd)
+ cset= super_cmd->commands;
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ cset->add(cmd= new cl_set_mem_cmd("memory", 0,
+"set memory memory_type address data...\n"
+" Place list of data into memory",
+"long help of set memory"));
+ cmd->init();
+ cset->add(cmd= new cl_set_bit_cmd("bit", 0,
+"set bit addr 0|1 Set specified bit to 0 or 1",
+"long help of set bit"));
+ cmd->init();
+ cset->add(cmd= new cl_set_hw_cmd("hardware", 0,
+"set hardware cathegory params...\n"
+" Set parameters of specified hardware element",
+"long help of set hardware"));
+ cmd->add_name("hw");
+ cmd->init();
+ }
+ if (!super_cmd)
+ {
+ cmdset->add(cmd= new cl_super_cmd("set", 0,
+"set subcommand Set, see `set' command for more help",
+"long help of set", cset));
+ cmd->init();
+ }
+
+ {
+ cset= new cl_cmdset();
+ cset->init();
+ cset->add(cmd= new cl_info_bp_cmd("breakpoints", 0,
+"info breakpoints Status of user-settable breakpoints",
+"long help of info breakpoints"));
+ cmd->add_name("bp");
+ cmd->init();
+ cset->add(cmd= new cl_info_reg_cmd("registers", 0,
+"info registers List of integer registers and their contents",
+"long help of info registers"));
+ cmd->init();
+ cset->add(cmd= new cl_info_hw_cmd("hardware", 0,
+"info hardware cathegory\n"
+" Status of hardware elements of the CPU",
+"long help of info hardware"));
+ cmd->add_name("hw");
+ cmd->init();
+ }
+ cmdset->add(cmd= new cl_super_cmd("info", 0,
+"info subcommand Information, see `info' command for more help",
+"long help of info", cset));
+ cmd->init();
+
+ cmdset->add(cmd= new cl_timer_cmd("timer", 0,
+"timer a|d|g|r|s|v id [direction|value]\n"
+" Timer add|del|get|run|stop|value",
+"timer add|create|make id [direction] -- create a new timer\n"
+"timer del id -- delete a timer\n"
+"timer get id -- list timers\n"
+"timer run id -- turn a timer ON\n"
+"timer stop id -- turn a timer OFF\n"
+"timer value id val -- set value of a timer to `val'"));
+ cmd->init();
+}
+
/*
* Read/write simulated memory
*/
-ulong
-cl_uc::read_mem(enum mem_class type, long addr)
+t_mem
+cl_uc::read_mem(enum mem_class type, t_addr addr)
{
class cl_mem *m;
- if ((m= (class cl_mem*)mems->at(type)))
- return(m->read(addr));
- //FIXME
-fprintf(stderr, "cl_uc::read_mem(type= %d, 0x%06lx) TROUBLE\n", type, addr);
- return(0);
+ if ((m= (class cl_mem*)mems->at(type)) == 0)
+ m= (class cl_mem*)(mems->at(MEM_DUMMY));
+ return(m->read(addr));
}
-ulong
-cl_uc::get_mem(enum mem_class type, long addr)
+t_mem
+cl_uc::get_mem(enum mem_class type, t_addr addr)
{
class cl_mem *m;
- if ((m= (class cl_mem*)mems->at(type)))
- return(m->get(addr));
- //FIXME
-printf("cl_uc::get_mem(type= %d, 0x%06lx) TROUBLE\n", type, addr);
- return(0);
+ if ((m= (class cl_mem*)mems->at(type)) == 0)
+ m= (class cl_mem*)(mems->at(MEM_DUMMY));
+ return(m->get(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;
- if ((m= (class cl_mem*)mems->at(type)))
- {
- m->write(addr, &val);
- //m->mem[addr]= val;
- }
- //FIXME
-else printf("cl_uc::write_mem(type= %d, 0x%06lx, 0x%lx) TROUBLE\n", type, addr, val);
+ if ((m= (class cl_mem*)mems->at(type)) == 0)
+ m= (class cl_mem*)(mems->at(MEM_DUMMY));
+ m->write(addr, val);
}
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;
- if ((m= (class cl_mem*)mems->at(type)))
- m->set(addr, val);
- //FIXME
-else printf("cl_uc::set_mem(type= %d, 0x%06lx, 0x%lx) TROUBLE\n", type, addr, val);
+ if ((m= (class cl_mem*)mems->at(type)) == 0)
+ m= (class cl_mem*)(mems->at(MEM_DUMMY));
+ m->set(addr, val);
}
class cl_mem *
cl_uc::mem(enum mem_class type)
{
+ class cl_mem *m;
+
if (mems->count < type)
- //FIXME
-{printf("TROUBLE\n"); return(0);
-}
- return((class cl_mem *)(mems->at(type)));
+ m= (class cl_mem *)(mems->at(MEM_DUMMY));
+ else
+ m= (class cl_mem *)(mems->at(type));
+ return(m);
}
-TYPE_UBYTE *
-cl_uc::MEM(enum mem_class type)
+class cl_mem *
+cl_uc::mem(char *class_name)
{
- class cl_mem *m;
+ int i, found= 0;
+ char *mcn, *n, *s;
- if ((m= mem(type)) == 0)
- //FIXME
-{printf("TROUBLE\n"); return(0);
-}
- return((TYPE_UBYTE *)(m->mem));
+ 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);
}
-
-/* Local function for `read_hex_file' method to read some bytes */
-
static long
ReadInt(FILE *f, bool *ok, int bytes)
{
*/
long
-cl_uc::read_hex_file(const char *name)
+cl_uc::read_hex_file(const char *nam)
{
FILE *f;
- char c;
+ int c;
long written= 0, recnum= 0;
uchar dnum; // data number
bool ok, get_low= 1;
uchar low= 0, high;
- if (!name)
- f= sim->/*FIXME*/cmd_in();
+ if (!nam)
+ {
+ sim->app->get_commander()->
+ dd_printf("cl_uc::read_hex_file File name not specified\n");
+ return(-1);
+ }
else
- if ((f= fopen(name, "r")) == NULL)
+ if ((f= fopen(nam, "r")) == NULL)
{
- fprintf(stderr, "Can't open `%s': %s\n", name, strerror(errno));
+ fprintf(stderr, "Can't open `%s': %s\n", nam, strerror(errno));
return(-1);
}
}
}
else
- if (sim->get_iarg('V', 0) &&
+ if (sim->app->args->get_iarg('V', 0) &&
rtyp != 1)
- fprintf(sim->cmd_out(),
- "Unknown record type %d(0x%x)\n", rtyp, rtyp);
+ sim->app->get_commander()->
+ dd_printf("Unknown record type %d(0x%x)\n", rtyp, rtyp);
}
else
- if (sim->get_iarg('V', 0))
- fprintf(sim->cmd_out(),
- "Checksum error (%x instead of %x) in record %ld.\n",
- chk, sum, recnum);
+ if (sim->app->args->get_iarg('V', 0))
+ sim->app->get_commander()->
+ dd_printf("Checksum error (%x instead of %x) in "
+ "record %ld.\n", chk, sum, recnum);
}
else
- if (sim->get_iarg('V', 0))
- fprintf(sim->cmd_out(), "Read error in record %ld.\n", recnum);
+ if (sim->app->args->get_iarg('V', 0))
+ sim->app->get_commander()->
+ dd_printf("Read error in record %ld.\n", recnum);
}
}
if (get_mem_width(MEM_ROM) > 8 &&
!get_low)
set_mem(MEM_ROM, addr, low);
- if (name)
+ if (nam)
fclose(f);
- if (sim->get_iarg('V', 0))
- fprintf(sim->cmd_out(), "%ld records have been read\n", recnum);
+ if (sim->app->args->get_iarg('V', 0))
+ sim->app->get_commander()->dd_printf("%ld records have been read\n", recnum);
analyze(0);
return(written);
}
*/
bool
-cl_uc::inst_at(uint addr)
+cl_uc::inst_at(t_addr addr)
{
- class cl_rom *rom= (class cl_rom *)mem(MEM_ROM);
+ class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
if (!rom)
return(0);
- return(rom->inst_map->get(addr));
+ //return(rom->inst_map->get(addr));
+ return(rom->get_cell_flag(addr, CELL_INST));
}
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);
+ class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
if (rom)
- rom->inst_map->set(addr);
+ //rom->inst_map->set(addr);
+ rom->set_cell_flag(addr, DD_TRUE, CELL_INST);
}
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);
+ class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
if (rom)
- rom->inst_map->clear(addr);
+ //rom->inst_map->clear(addr);
+ rom->set_cell_flag(addr, DD_FALSE, CELL_INST);
}
bool
cl_uc::there_is_inst(void)
{
- class cl_rom *rom= (class cl_rom *)mem(MEM_ROM);
+ class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
if (!rom)
return(0);
- return(!(rom->inst_map->empty()));
+ //return(!(rom->inst_map->empty()));
+ bool got= DD_FALSE;
+ t_addr addr;
+ for (addr= 0; addr < rom->size && !got; addr++)
+ got= rom->get_cell_flag(addr, CELL_INST);
+ return(got);
}
/* Register callback hw objects for mem read/write */
-void
-cl_uc::register_hw_read(enum mem_class type, long addr, class cl_hw *hw)
+/*void
+cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw)
{
class cl_mem *m;
class cl_memloc *l;
}
else
printf("cl_uc::register_hw_read TROUBLE\n");
-}
+}*/
-void
-cl_uc::register_hw_write(enum mem_class type, long addr, class cl_hw *hw)
+/*void
+cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw)
{
-}
+}*/
/* Looking for a specific HW element */
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)
{
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
}
char *
-cl_uc::disass(uint addr, char *sep)
+cl_uc::disass(t_addr addr, char *sep)
{
char *buf;
buf= (char*)malloc(100);
- strcpy(buf, "uc::do_disass unimplemented\n");
+ strcpy(buf, "uc::disass() unimplemented\n");
return(buf);
}
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->dd_printf("%c", (b->perm == brkFIX)?'F':'D');
+ else
+ con->dd_printf(" ");
+ con->dd_printf("%c ", inst_at(addr)?' ':'?');
+ con->dd_printf(rom->addr_format, addr); con->dd_printf(" ");
+ con->dd_printf(rom->data_format, code);
+ for (i= 1; i < inst_length(addr); i++)
+ {
+ con->dd_printf(" ");
+ con->dd_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->dd_printf(" "), j--;
+ i++;
+ }
+ con->dd_printf(" %s\n", dis);
+ free(dis);
}
void
cl_uc::print_regs(class cl_console *con)
{
- con->printf("No registers\n");
+ con->dd_printf("No registers\n");
}
int
-cl_uc::inst_length(uint code)
+cl_uc::inst_length(t_addr addr)
{
struct dis_entry *tabl= dis_tbl();
int i;
+ t_mem code;
+ code = get_mem(MEM_ROM, addr);
for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ;
- return(tabl[i].mnemonic?tabl[i].length:1);
+ return(tabl[i].mnemonic?tabl[i].length:1);
+}
+
+int
+cl_uc::inst_branch(t_addr addr)
+{
+ struct dis_entry *tabl= dis_tbl();
+ int i;
+ t_mem code;
+
+ code = get_mem(MEM_ROM, addr);
+ for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
+ ;
+ return tabl[i].branch;
+}
+
+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;
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);
+}
+
+
+/*
+ * Messages to broadcast
+ */
+
+void
+cl_uc::mem_cell_changed(class cl_mem *mem, t_addr addr)
+{
+ if (hws)
+ hws->mem_cell_changed(mem, addr);
+ else
+ printf("JAJ uc\n");//FIXME
+ if (mems &&
+ mems->count)
+ {
+ int i;
+ for (i= 0; i < mems->count; i++)
+ {
+ }
+ }
+}
+
+
+/*
+ * Error handling
+ */
+
+void
+cl_uc::error(class cl_error *error)
+{
+ errors->add(error);
+ if ((error->inst= inst_exec))
+ error->PC= instPC;
+}
+
+void
+cl_uc::check_errors(void)
+{
+ int i;
+ class cl_commander *c= sim->app->get_commander();
+
+ if (c)
+ {
+ for (i= 0; i < errors->count; i++)
+ {
+ class cl_error *error= (class cl_error *)(errors->at(i));
+ error->print(c);
+ if (error->inst)
+ {
+ class cl_console *con;
+ con= c->actual_console;
+ if (!con)
+ con= c->frozen_console;
+ if (con)
+ print_disass(error->PC, con);
+ }
+ }
+ errors->free_all();
+ }
+ else
+ fprintf(stderr, "no actual console, %d errors\n", errors->count);
+}
+
+
+/*
+ * Converting bit address into real memory
+ */
+
+class cl_mem *
+cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask)
+{
+ if (memaddr)
+ *memaddr= bitaddr;
+ if (bitmask)
+ *bitmask= 1 << (bitaddr & 0x7);
+ return(0); // abstract...
+}
+
/*
* Execution
*/
int
-cl_uc::tick(int cycles)
+cl_uc::tick_hw(int cycles)
{
class cl_hw *hw;
+ int i;//, cpc= clock_per_cycle();
+
+ // tick hws
+ for (i= 0; i < hws->count; i++)
+ {
+ hw= (class cl_hw *)(hws->at(i));
+ if (hw->flags & HWF_INSIDE)
+ hw->tick(cycles);
+ }
+ do_extra_hw(cycles);
+ return(0);
+}
+
+void
+cl_uc::do_extra_hw(int cycles)
+{}
+
+int
+cl_uc::tick(int cycles)
+{
+ //class cl_hw *hw;
int i, cpc= clock_per_cycle();
// increase time
}
}
- // tick hws
- for (i= 0; i < hws->count; i++)
- {
- hw= (class cl_hw *)(hws->at(i));
- if (hw->flags & HWF_INSIDE)
- hw->tick(cycles);
- }
+ // tick for hardwares
+ inst_ticks+= cycles;
return(0);
}
}
class cl_ticker *
-cl_uc::get_counter(char *name)
+cl_uc::get_counter(char *nam)
{
int i;
- if (!name)
+ if (!nam)
return(0);
for (i= 0; i < counters->count; i++)
{
class cl_ticker *t= (class cl_ticker *)(counters->at(i));
if (t &&
- t->name &&
- strcmp(t->name, name) == 0)
+ t->get_name() &&
+ strcmp(t->get_name(), nam) == 0)
return(t);
}
return(0);
}
void
-cl_uc::add_counter(class cl_ticker *ticker, char */*name*/)
+cl_uc::add_counter(class cl_ticker *ticker, char */*nam*/)
{
int i;
}
void
-cl_uc::del_counter(char *name)
+cl_uc::del_counter(char *nam)
{
int i;
- if (!name)
+ if (!nam)
return;
for (i= 0; i < counters->count; i++)
{
class cl_ticker *t= (class cl_ticker *)(counters->at(i));
if (t &&
- t->name &&
- strcmp(t->name, name) == 0)
+ t->get_name() &&
+ strcmp(t->get_name(), nam) == 0)
{
delete t;
counters->put_at(i, 0);
}
/*
- * Fetch but checking for breakpoint hit first
+ * Fetch but checking for breakpoint hit first, returns TRUE if
+ * a breakpoint is hit
*/
bool
-cl_uc::fetch(ulong *code)
+cl_uc::fetch(t_mem *code)
{
class cl_brk *brk;
int idx;
return(0);
if (sim->state & SIM_GO)
{
- if ((brk= fbrk->get_bp(PC, &idx)) &&
+ if (mem(MEM_ROM)->get_cell_flag(PC, CELL_FETCH_BRK) &&
+ (brk= fbrk->get_bp(PC, &idx)) &&
(brk->do_hit()))
{
if (brk->perm == brkDYNAMIC)
void
cl_uc::pre_inst(void)
-{}
+{
+ inst_exec= DD_TRUE;
+ inst_ticks= 0;
+ events->disconn_all();
+}
int
cl_uc::exec_inst(void)
{
+ instPC= PC;
return(resGO);
}
void
cl_uc::post_inst(void)
-{}
+{
+ tick_hw(inst_ticks);
+ if (errors->count)
+ check_errors();
+ if (events->count)
+ check_events();
+ inst_exec= DD_FALSE;
+}
/*
*/
class cl_fetch_brk *
-cl_uc::fbrk_at(long addr)
+cl_uc::fbrk_at(t_addr addr)
{
int idx;
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)
{
eb= (class cl_ev_brk *)(ebrk->at(i));
if (eb->addr == addr &&
!strcmp(eb->id, id))
- ebrk->free_at(i);
+ ebrk->del_bp(i, 0);
+ }
+}
+
+/* Remove a breakpoint specified by its number */
+
+bool
+cl_uc::rm_brk(int nr)
+{
+ class cl_brk *bp;
+
+ if ((bp= brk_by_nr(fbrk, nr)))
+ {
+ fbrk->del_bp(bp->addr);
+ return(DD_TRUE);
+ }
+ else if ((bp= brk_by_nr(ebrk, nr)))
+ {
+ ebrk->del_bp(ebrk->index_of(bp), 0);
+ return(DD_TRUE);
}
+ return(DD_FALSE);
}
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->del_bp(ebrk->count-1, 0);
+}
+
+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);
+
+ b= new cl_ev_brk(mem, make_new_brknr(), addr, perm, hit, op);
+ b->init();
+ return(b);
+}
+
+void
+cl_uc::check_events(void)
+{
+ sim->stop(resBREAKPOINT);
+}
/* End of uc.cc */