#include "setcl.h"
#include "infocl.h"
#include "timercl.h"
+#include "cmdstatcl.h"
+#include "cmdmemcl.h"
+#include "cmdutil.h"
// local, sim.src
#include "uccl.h"
#include "simcl.h"
#include "itsrccl.h"
+static class cl_uc_error_registry uc_error_registry;
/*
* Clock counter
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)
cl_ticker::dump(int nr, double xtal, class cl_console *con)
{
con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n",
- nr, name?name:"unnamed",
+ nr, get_name("unnamed"),
(options&TICK_RUN)?"ON":"OFF",
(options&TICK_INISR)?",ISR":"",
get_rtime(xtal), ticks);
}
+/*
+ * Options of uc
+ */
+
+cl_xtal_option::cl_xtal_option(class cl_uc *the_uc):
+ cl_optref(the_uc)
+{
+ uc= the_uc;
+}
+
+void
+cl_xtal_option::option_changed(void)
+{
+ if (!uc)
+ return;
+ double d;
+ option->get_value(&d);
+ uc->xtal= d;
+}
+
+
/*
* Abstract microcontroller
******************************************************************************
cl_uc::cl_uc(class cl_sim *asim):
cl_base()
{
- int i;
+ //int i;
sim = asim;
- mems= new cl_list(MEM_TYPES, 1);
+ //mems= new cl_list(MEM_TYPES, 1);
+ memchips= new cl_list(2, 2, "memchips");
+ address_spaces= new cl_address_space_list(this);
+ //address_decoders= new cl_list(2, 2);
+ rom= 0;
+
hws = new cl_hws();
- options= new cl_list(2, 2);
- for (i= MEM_ROM; i < MEM_TYPES; i++)
- mems->add(0);
+ //options= new cl_list(2, 2);
+ //for (i= MEM_ROM; i < MEM_TYPES; i++) mems->add(0);
+ xtal_option= new cl_xtal_option(this);
+ xtal_option->init();
ticks= new cl_ticker(+1, 0, "time");
isr_ticks= new cl_ticker(+1, TICK_INISR, "isr");
idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle");
- counters= new cl_list(2, 2);
- it_levels= new cl_list(2, 2);
+ counters= new cl_list(2, 2, "counters");
+ it_levels= new cl_list(2, 2, "it levels");
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);
+ stack_ops= new cl_list(2, 2, "stack operations");
+ errors= new cl_list(2, 2, "errors in uc");
+ events= new cl_list(2, 2, "events in uc");
sp_max= 0;
sp_avg= 0;
inst_exec= DD_FALSE;
cl_uc::~cl_uc(void)
{
- delete mems;
+ //delete mems;
delete hws;
- delete options;
+ //delete options;
delete ticks;
delete isr_ticks;
delete idle_ticks;
delete ebrk;
delete it_levels;
delete it_sources;
- delete st_ops;
+ delete stack_ops;
errors->free_all();
delete errors;
+ delete xtal_option;
+ delete address_spaces;
+ delete memchips;
+ //delete address_decoders;
}
int
cl_uc::init(void)
{
- int mc, i;
+ int i;
+ set_name("controller");
cl_base::init();
- if (!(sim->app->args->arg_avail('X')) ||
- sim->app->args->get_farg('X', 0) == 0)
- xtal= 11059200;
+ if (xtal_option->use("xtal"))
+ xtal= xtal_option->get_value(xtal);
else
- 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,
- 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));
+ xtal= 11059200;
+ make_memories();
+ rom= address_space(MEM_ROM_ID);
+ ebrk= new brk_coll(2, 2, rom);
+ fbrk= new brk_coll(2, 2, rom);
fbrk->Duplicates= DD_FALSE;
brk_counter= 0;
mk_hw_elements();
{
class it_level *il;
- PC= 0;
+ instPC= PC= 0;
state = stGO;
ticks->ticks= 0;
isr_ticks->ticks= 0;
sp_max= 0;
sp_avg= 0;
+ stack_ops->free_all();
+
int i;
for (i= 0; i < hws->count; i++)
{
* Making elements
*/
-class cl_mem *
-cl_uc::mk_mem(enum mem_class type, char *class_name)
-{
- class cl_mem *m;
-
- if (get_mem_size(type) < 0)
- return(0);
- m= new cl_m(type, get_id_string(mem_classes, type),
- get_mem_size(type), get_mem_width(type), this);
- m->init();
- return(m);
-}
+void
+cl_uc::make_memories(void)
+{}
-t_addr
-cl_uc::get_mem_size(enum mem_class type)
+/*t_addr
+cl_uc::get_mem_size(char *id)
{
- switch (type)
- {
- case MEM_ROM: return(0x10000);
- case MEM_XRAM: return(0x10000);
- case MEM_IRAM: return(0x80);
- case MEM_SFR: return(0x100);
- case MEM_TYPES:
- default: return(0);
- }
- return(0);
+ class cl_memory *m= memory(id);
+ return(m?(m->get_size()):0);
}
int
-cl_uc::get_mem_width(enum mem_class type)
+cl_uc::get_mem_width(char *id)
{
- return(8);
+ class cl_memory *m= memory(id);
+ return(m?(m->width):8);
}
-
+*/
void
cl_uc::mk_hw_elements(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,
"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->add_name("load");
cmdset->add(cmd= new cl_dl_cmd("download", 0,
-"download,dl Load (intel.hex) data",
+"download Load (intel.hex) data",
"long help of download"));
cmd->init();
cmd->add_name("dl");
"long help of reset"));
cmd->init();
- cmdset->add(cmd= new cl_dump_cmd("dump", 0,
+ cmdset->add(cmd= new cl_dump_cmd("dump", DD_TRUE,
"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,
+ cmdset->add(cmd= new cl_dch_cmd("dch", DD_TRUE,
"dch [start [stop]] Dump code in hex form",
"long help of dch"));
cmd->init();
- cmdset->add(cmd= new cl_dc_cmd("dc", 0,
+ cmdset->add(cmd= new cl_dc_cmd("dc", DD_TRUE,
"dc [start [stop]] Dump code in disass form",
"long help of dc"));
cmd->init();
- cmdset->add(cmd= new cl_disassemble_cmd("disassemble", 0,
+ cmdset->add(cmd= new cl_disassemble_cmd("disassemble", DD_TRUE,
"disassemble [start [offset [lines]]]\n"
" Disassemble code",
"long help of disassemble"));
cmd->init();
{
- cset= new cl_cmdset();
- cset->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,
+ /*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();
+cmd->init();*/
}
- cmdset->add(cmd= new cl_super_cmd("get", 0,
+ 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();
+ cmd->init();
+ }
{
- cset= new cl_cmdset();
- cset->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 hardware"));
cmd->add_name("hw");
cmd->init();
- cset->add(cmd= new cl_set_option_cmd("option", 0,
-"set option name value\n"
-" Set value of an option",
-"long help of set option"));
- cmd->init();
}
- cmdset->add(cmd= new cl_super_cmd("set", 0,
+ 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();
+ cmd->init();
+ }
- {
- cset= new cl_cmdset();
- cset->init();
+ { // info
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("info"));
+ if (super_cmd)
+ cset= super_cmd->get_subcommands();
+ else {
+ 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"));
"long help of info hardware"));
cmd->add_name("hw");
cmd->init();
+ cset->add(cmd= new cl_info_stack_cmd("stack", 0,
+"info stack Status of stack of the CPU",
+"long help of info stack"));
+ cmd->init();
+ cset->add(cmd= new cl_info_memory_cmd("memory", 0,
+"info memory Information about memory system",
+"long help of info memory"));
+ cmd->init();
}
- cmdset->add(cmd= new cl_super_cmd("info", 0,
+ if (!super_cmd) {
+ 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();
+ 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();
+ {
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("timer"));
+ if (super_cmd)
+ cset= super_cmd->get_subcommands();
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ cset->add(cmd= new cl_timer_add_cmd("add", 0,
+"timer add id [direction [in_isr]]\n"
+" Create a clock counter (timer)",
+"log help of timer add"));
+ cmd->init();
+ cmd->add_name("create");
+ cmd->add_name("make");
+ cset->add(cmd= new cl_timer_delete_cmd("delete", 0,
+"timer delete id Delete a timer",
+"long help of timer delete"));
+ cmd->init();
+ cmd->add_name("remove");
+ cset->add(cmd= new cl_timer_get_cmd("get", 0,
+"timer get [id] Get value of a timer, or all",
+"long help of timer get"));
+ cmd->init();
+ cset->add(cmd= new cl_timer_run_cmd("run", 0,
+"timer start id Start a timer",
+"long help of timer run"));
+ cmd->init();
+ cmd->add_name("start");
+ cset->add(cmd= new cl_timer_stop_cmd("stop", 0,
+"timer stop id Stop a timer",
+"long help of timer stop"));
+ cmd->init();
+ cset->add(cmd= new cl_timer_value_cmd("set", 0,
+"timer set id value\n"
+" Set a timer value",
+"long help of timer set"));
+ cmd->init();
+ cmd->add_name("value");
+ }
+ if (!super_cmd) {
+ cmdset->add(cmd= new cl_super_cmd("timer", 0,
+"timer subcommand Manage timers",
+"long help of timer", cset));
+ cmd->init();
+ }
+
+ {
+ super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("memory"));
+ if (super_cmd)
+ cset= super_cmd->get_subcommands();
+ else {
+ cset= new cl_cmdset();
+ cset->init();
+ }
+ /*
+ cset->add(cmd= new cl_memory_cmd("_no_parameters_", 0,
+"memory Information about memory system",
+"long help of memory"));
+ cmd->init();
+ */
+ cset->add(cmd= new cl_memory_createchip_cmd("createchip", 0,
+"memory createchip id size cellsize\n"
+" Create a new memory chip",
+"long help of memory createchip"));
+ cmd->init();
+ cmd->add_name("cchip");
+ cset->add(cmd= new cl_memory_createaddressspace_cmd("createaddressspace", 0,
+"memory createaddressspace id startaddr size\n"
+" Create address space",
+"long help of memory createaddressspace"));
+ cmd->init();
+ cmd->add_name("createaddrspace");
+ cmd->add_name("createaspace");
+ cmd->add_name("caddressspace");
+ cmd->add_name("caddrspace");
+ cmd->add_name("caspace");
+ cset->add(cmd= new cl_memory_createaddressdecoder_cmd("createaddressdecoder", 0,
+"memory createaddressdecoder addressspace begin end chip begin\n"
+" Create address decoder",
+"long help of memory createaddressdecoder"));
+ cmd->init();
+ cmd->add_name("createaddrdecoder");
+ cmd->add_name("createadecoder");
+ cmd->add_name("caddressdecoder");
+ cmd->add_name("caddrdecoder");
+ cmd->add_name("cadecoder");
+ }
+ if (!super_cmd) {
+ cmdset->add(cmd= new cl_super_cmd("memory", 0,
+"memory subcommand Manage memory chips and address spaces",
+"long help of memory", cset));
+ cmd->init();
+ }
}
*/
t_mem
-cl_uc::read_mem(enum mem_class type, t_addr addr)
+cl_uc::read_mem(char *id, t_addr addr)
{
- class cl_mem *m;
+ class cl_address_space *m= address_space(id);
- if ((m= (class cl_mem*)mems->at(type)) == 0)
- m= (class cl_mem*)(mems->at(MEM_DUMMY));
- return(m->read(addr));
+ return(m?(m->read(addr)):0);
}
t_mem
-cl_uc::get_mem(enum mem_class type, t_addr addr)
+cl_uc::get_mem(char *id, t_addr addr)
{
- class cl_mem *m;
+ class cl_address_space *m= address_space(id);
- if ((m= (class cl_mem*)mems->at(type)) == 0)
- m= (class cl_mem*)(mems->at(MEM_DUMMY));
- return(m->get(addr));
+ return(m?(m->get(addr)):0);
}
void
-cl_uc::write_mem(enum mem_class type, t_addr addr, t_mem val)
+cl_uc::write_mem(char *id, t_addr addr, t_mem val)
{
- class cl_mem *m;
+ class cl_address_space *m= address_space(id);
- if ((m= (class cl_mem*)mems->at(type)) == 0)
- m= (class cl_mem*)(mems->at(MEM_DUMMY));
- m->write(addr, val);
+ if (m)
+ m->write(addr, val);
}
void
-cl_uc::set_mem(enum mem_class type, t_addr addr, t_mem val)
+cl_uc::set_mem(char *id, t_addr addr, t_mem val)
{
- class cl_mem *m;
+ class cl_address_space *m= address_space(id);
- if ((m= (class cl_mem*)mems->at(type)) == 0)
- m= (class cl_mem*)(mems->at(MEM_DUMMY));
- m->set(addr, val);
+ if(m)
+ m->set(addr, val);
}
-class cl_mem *
+
+/*
+class cl_memory *
cl_uc::mem(enum mem_class type)
{
- class cl_mem *m;
+ class cl_m *m;
if (mems->count < type)
- m= (class cl_mem *)(mems->at(MEM_DUMMY));
+ m= (class cl_m *)(mems->at(MEM_DUMMY));
else
- m= (class cl_mem *)(mems->at(type));
+ m= (class cl_m *)(mems->at(type));
return(m);
}
+*/
-class cl_mem *
-cl_uc::mem(char *class_name)
+class cl_address_space *
+cl_uc::address_space(char *id)
{
- int i, found= 0;
- char *mcn, *n, *s;
+ int i;
- if (!class_name)
+ if (!id ||
+ !(*id))
return(0);
- s= n= strdup(class_name);
- while (*s)
+ for (i= 0; i < address_spaces->count; i++)
{
- *s= toupper(*s);
- s++;
+ class cl_address_space *m= (cl_address_space *)(address_spaces->at(i));
+ if (!m ||
+ !m->have_real_name())
+ continue;
+ if (m->is_inamed(id))
+ return(m);
}
- if (!class_name ||
- !(*class_name))
+ return(0);
+}
+
+class cl_memory *
+cl_uc::memory(char *id)
+{
+ int i;
+
+ if (!id ||
+ !(*id))
return(0);
- for (i= 0; !found && i < mems->count; i++)
+ for (i= 0; i < address_spaces->count; i++)
{
- cl_mem *m= (cl_mem *)(mems->at(i));
+ class cl_memory *m= (cl_memory *)(address_spaces->at(i));
if (!m ||
- !m->class_name ||
- !(*(m->class_name)))
+ !m->have_real_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);
- }
+ if (m->is_inamed(id))
+ return(m);
+ }
+ for (i= 0; i < memchips->count; i++)
+ {
+ class cl_memory *m= (cl_memory *)(memchips->at(i));
+ if (!m ||
+ !m->have_real_name())
+ continue;
+ if (m->is_inamed(id))
+ return(m);
}
- free(n);
return(0);
}
+
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;
int c;
bool ok, get_low= 1;
uchar low= 0, high;
- if (!name)
+ if (!rom)
+ {
+ sim->app->get_commander()->
+ dd_printf("No ROM address space to read in.\n");
+ return(-1);
+ }
+
+ 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);
}
{
if (rtyp == 0)
{
- if (get_mem_width(MEM_ROM) > 8)
+ if (rom->width > 8)
addr/= 2;
for (i= 0; i < dnum; i++)
{
- if (get_mem_width(MEM_ROM) <= 8)
+ if (rom->width <= 8)
{
- set_mem(MEM_ROM, addr, rec[i]);
+ rom->set(addr, rec[i]);
addr++;
written++;
}
- else if (get_mem_width(MEM_ROM) <= 16)
+ else if (rom->width <= 16)
{
if (get_low)
{
else
{
high= rec[i];
- set_mem(MEM_ROM, addr, (high*256)+low);
+ rom->set(addr, (high*256)+low);
addr++;
written++;
get_low= 1;
}
}
else
- if (sim->app->args->get_iarg('V', 0) &&
- rtyp != 1)
- sim->app->get_commander()->
- dd_printf("Unknown record type %d(0x%x)\n", rtyp, rtyp);
+ if (rtyp != 1)
+ application->debug("Unknown record type %d(0x%x)\n",
+ rtyp, rtyp);
}
else
- 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);
+ application->debug("Checksum error (%x instead of %x) in "
+ "record %ld.\n", chk, sum, recnum);
}
else
- if (sim->app->args->get_iarg('V', 0))
- sim->app->get_commander()->
- dd_printf("Read error in record %ld.\n", recnum);
+ application->debug("Read error in record %ld.\n", recnum);
}
}
- if (get_mem_width(MEM_ROM) > 8 &&
+ if (rom->width > 8 &&
!get_low)
- set_mem(MEM_ROM, addr, low);
+ rom->set(addr, low);
- if (name)
+ if (nam)
fclose(f);
- if (sim->app->args->get_iarg('V', 0))
- sim->app->get_commander()->dd_printf("%ld records have been read\n", recnum);
+ application->debug("%ld records have been read\n", recnum);
analyze(0);
return(written);
}
bool
cl_uc::inst_at(t_addr addr)
{
- class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
-
if (!rom)
return(0);
- //return(rom->inst_map->get(addr));
return(rom->get_cell_flag(addr, CELL_INST));
}
void
cl_uc::set_inst_at(t_addr addr)
{
- class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
-
if (rom)
- //rom->inst_map->set(addr);
rom->set_cell_flag(addr, DD_TRUE, CELL_INST);
}
void
cl_uc::del_inst_at(t_addr addr)
{
- class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
-
if (rom)
- //rom->inst_map->clear(addr);
rom->set_cell_flag(addr, DD_FALSE, CELL_INST);
}
bool
cl_uc::there_is_inst(void)
{
- class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
-
if (!rom)
return(0);
- //return(!(rom->inst_map->empty()));
bool got= DD_FALSE;
t_addr addr;
- for (addr= 0; addr < rom->size && !got; addr++)
+ for (addr= 0; rom->valid_address(addr) && !got; addr++)
got= rom->get_cell_flag(addr, CELL_INST);
return(got);
}
/*void
cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw)
{
- class cl_mem *m;
+ class cl_m *m;
class cl_memloc *l;
- if ((m= (class cl_mem*)mems->at(type)))
+ if ((m= (class cl_m*)mems->at(type)))
{
if ((l= m->read_locs->get_loc(addr)) == 0)
{
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;
+
+ t_mem code= rom->get(addr);
b= fbrk_at(addr);
dis= disass(addr, NULL);
if (b)
for (i= 1; i < inst_length(addr); i++)
{
con->dd_printf(" ");
- con->dd_printf(rom->data_format, get_mem(MEM_ROM, addr+i));
+ con->dd_printf(rom->data_format, rom->get(addr+i));
}
int li= longest_inst();
while (i < li)
int i;
t_mem code;
- code = get_mem(MEM_ROM, addr);
+ if (!rom)
+ return(0);
+
+ code = rom->get(addr);
for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ;
return(tabl[i].mnemonic?tabl[i].length:1);
}
int i;
t_mem code;
- code = get_mem(MEM_ROM, addr);
+ if (!rom)
+ return(0);
+
+ code = rom->get(addr);
for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
;
return tabl[i].branch;
return(tab[i].name != NULL);
}
+bool
+cl_uc::symbol2address(char *sym, struct name_entry tab[],
+ t_addr *addr)
+{
+ int i;
+
+ if (!sym ||
+ !*sym)
+ return(DD_FALSE);
+ i= 0;
+ while (tab[i].name &&
+ (!(tab[i].cpu_type & type) ||
+ strcasecmp(sym, tab[i].name) != 0))
+ i++;
+ if (tab[i].name)
+ {
+ if (addr)
+ *addr= tab[i].addr;
+ return(DD_TRUE);
+ }
+ return(DD_FALSE);
+}
+
char *
cl_uc::symbolic_bit_name(t_addr bit_address,
- class cl_mem *mem,
+ class cl_memory *mem,
t_addr mem_addr,
t_mem bit_mask)
{
}
if (mem &&
- mem->class_name &&
- strstr(mem->class_name, "sfr") == mem->class_name)
+ mem->have_real_name() &&
+ strstr(mem->get_name(), "sfr") == mem->get_name())
{
i= 0;
while (sfr_tbl()[i].name &&
* Messages to broadcast
*/
+bool
+cl_uc::handle_event(class cl_event &event)
+{
+ switch (event.what)
+ {
+ case ev_address_space_added:
+ {
+ try {
+ class cl_event_address_space_added &e=
+ dynamic_cast<class cl_event_address_space_added &>(event);
+ address_space_added(e.as);
+ e.handle();
+ }
+ catch (...)
+ { break; }
+ break;
+ }
+ default:
+ return(pass_event_down(event));
+ break;
+ }
+ return(DD_FALSE);
+}
+
+/*
void
-cl_uc::mem_cell_changed(class cl_mem *mem, t_addr addr)
+cl_uc::mem_cell_changed(class cl_address_space *mem, t_addr addr)
{
if (hws)
hws->mem_cell_changed(mem, addr);
}
}
}
+*/
+
+void
+cl_uc::address_space_added(class cl_address_space *as)
+{
+ if (hws)
+ hws->address_space_added(as);
+ else
+ printf("JAJ uc\n");//FIXME
+}
/*
{
int i;
class cl_commander *c= sim->app->get_commander();
+ bool must_stop= DD_FALSE;
if (c)
{
for (i= 0; i < errors->count; i++)
{
class cl_error *error= (class cl_error *)(errors->at(i));
+ if (!error->is_on())
+ continue;
error->print(c);
+ must_stop= must_stop || (error->get_type() & err_stop);
if (error->inst)
{
class cl_console *con;
if (!con)
con= c->frozen_console;
if (con)
- print_disass(error->PC, con);
+ {
+ con->dd_printf("Erronouse instruction: ");
+ print_disass(error->PC, con);
+ }
}
}
errors->free_all();
}
else
fprintf(stderr, "no actual console, %d errors\n", errors->count);
+ if (must_stop)
+ sim->stop(resERROR);
}
* Converting bit address into real memory
*/
-class cl_mem *
+class cl_address_space *
cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask)
{
if (memaddr)
}
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);
cl_uc::fetch(void)
{
ulong code;
+
+ if (!rom)
+ return(0);
- code= read_mem(MEM_ROM, PC);
- PC++;
- if (PC >= get_mem_size(MEM_ROM))
- PC= 0;
+ code= rom->read(PC);
+ PC= rom->inc_address(PC);
return(code);
}
if (!code)
return(0);
- if (sim->state & SIM_GO)
+ if ((sim->state & SIM_GO) &&
+ rom)
{
- if (mem(MEM_ROM)->get_cell_flag(PC, CELL_FETCH_BRK) &&
+ if (rom->get_cell_flag(PC, CELL_FETCH_BRK) &&
(brk= fbrk->get_bp(PC, &idx)) &&
(brk->do_hit()))
{
*/
void
-cl_uc::st_push(class cl_stack_op *op)
+cl_uc::stack_write(class cl_stack_op *op)
{
- st_ops->push(op);
+ if (op->get_op() & stack_read_operation)
+ {
+ class cl_error_stack_tracker_wrong_handle *e= new
+ cl_error_stack_tracker_wrong_handle(DD_FALSE);
+ //fprintf(stderr, "%06"_A_"x cl_uc::stack_read() should be called for "
+ //"%s\n", op->get_pc(), op->get_op_name());
+ e->init();
+ error(e);
+ return;
+ }
+ stack_ops->push(op);
}
void
-cl_uc::st_call(class cl_stack_op *op)
+cl_uc::stack_read(class cl_stack_op *op)
{
- st_ops->push(op);
-}
-
-int
-cl_uc::st_pop(class cl_stack_op *op)
-{
- class cl_stack_op *sop= (class cl_stack_op *)(st_ops->pop());
-
- if (!sop)
- return(1);
- return(0);
-}
+ class cl_stack_op *top= (class cl_stack_op *)(stack_ops->top());
+
+ if (op->get_op() & stack_write_operation)
+ {
+ class cl_error_stack_tracker_wrong_handle *e= new
+ cl_error_stack_tracker_wrong_handle(DD_TRUE);
+ e->init();
+ error(e);
+ //fprintf(stderr, "%06"_A_"x cl_uc::stack_write() should be called for "
+ //"%s\n", op->get_pc(), op->get_op_name());
+ return;
+ }
+ if (!top)
+ {
+ class cl_error *e= new cl_error_stack_tracker_empty(op);
+ /*printf("0x%06"_A_"x %s operation on stack but no operation was before\n
+ ",
+ op->get_pc(), op->get_op_name());*/
+ e->init();
+ error(e);
+ return;
+ }
-int
-cl_uc::st_ret(class cl_stack_op *op)
-{
- class cl_stack_op *sop= (class cl_stack_op *)(st_ops->pop());
+ if (top)
+ {
+ if (!top->match(op))
+ {
+ class cl_error *e= new cl_error_stack_tracker_unmatch(top, op);
+ e->init();
+ error(e);
+ /*printf("0x%06"_A_"x %s operation on stack but last was %s\n",
+ op->get_pc(), op->get_op_name(), top->get_op_name());*/
+ }
+ int top_size= top->data_size(), op_size= op->data_size();
+ if (top_size != op_size)
+ {
+ application->debug("0x%06"_A_"x %d bytes to read out of stack "
+ "but %d was pushed in last operation\n",
+ op->get_pc(), op_size, top_size);
+ }
+ }
- if (!sop)
- return(1);
- return(0);
+ int removed= 0;
+ while (top &&
+ top->can_removed(op))
+ {
+ top= (class cl_stack_op *)stack_ops->pop();
+ delete top;
+ top= (class cl_stack_op *)stack_ops->top();
+ removed++;
+ }
+ if (removed != 1)
+ {
+ application->debug("0x%06"_A_"x %d ops removed from stack-tracker "
+ "when %s happened, top pc=0x%06"_A_"x "
+ "top before=0x%06"_A_"x op after=0x%06"_A_"x\n",
+ op->get_pc(), removed, op->get_op_name(),
+ top?(top->get_pc()):0, top?(top->get_before()):0,
+ op->get_after());
+ }
+
+ if (top)
+ {
+ int ta= top->get_after(), oa= op->get_after();
+ if (ta != oa)
+ {
+ application->debug("0x%06"_A_"x stack still inconsistent after %s, "
+ "%d byte(s) should be read out; top after"
+ "=0x%06"_A_"x op after=0x%06"_A_"x\n",
+ op->get_pc(), op->get_op_name(), abs(ta-oa),
+ ta, oa);
+ class cl_error *e=
+ new cl_error_stack_tracker_inconsistent(op, abs(ta-oa));
+ e->init();
+ error(e);
+ }
+ }
+
+ delete op;
}
}
class cl_ev_brk *
-cl_uc::mk_ebrk(enum brk_perm perm, class cl_mem *mem,
+cl_uc::mk_ebrk(enum brk_perm perm, class cl_address_space *mem,
char op, t_addr addr, int hit)
{
class cl_ev_brk *b;
void
cl_uc::check_events(void)
{
+ int i;
+ for (i= 0; i < events->count; i++)
+ {
+ class cl_ev_brk *brk=
+ dynamic_cast<class cl_ev_brk *>(events->object_at(i));
+ sim->stop(brk);
+ }
sim->stop(resBREAKPOINT);
}
+/*
+ * Errors
+ *----------------------------------------------------------------------------
+ */
+
+cl_error_unknown_code::cl_error_unknown_code(class cl_uc *the_uc)
+{
+ uc= the_uc;
+ classification= uc_error_registry.find("unknown_code");
+}
+
+void
+cl_error_unknown_code::print(class cl_commander *c)
+{
+ FILE *f= c->get_out();
+ cmd_fprintf(f, "%s: unknown instruction code at ", get_type_name());
+ if (uc->rom)
+ {
+ cmd_fprintf(f, uc->rom->addr_format, PC);
+ cmd_fprintf(f, " (");
+ cmd_fprintf(f, uc->rom->data_format, uc->rom->get(PC));
+ cmd_fprintf(f, ")");
+ }
+ else
+ cmd_fprintf(f, "0x%06x", PC);
+ cmd_fprintf(f, "\n");
+}
+
+cl_uc_error_registry::cl_uc_error_registry(void)
+{
+ class cl_error_class *prev = uc_error_registry.find("non-classified");
+ prev = register_error(new cl_error_class(err_error, "unknown_code", prev, ERROR_OFF));
+}
+
+
/* End of uc.cc */