📄 uc.cc
字号:
/* * Simulator of microcontrollers (uc.cc) * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * *//* This file is part of microcontroller simulator: ucsim.UCSIM is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.UCSIM is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with UCSIM; see the file COPYING. If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA. *//*@1@*/#include "ddconfig.h"#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"#include "cmdmemcl.h"#include "cmdutil.h"// local, sim.src#include "uccl.h"#include "hwcl.h"#include "memcl.h"#include "simcl.h"#include "itsrccl.h"static class cl_uc_error_registry uc_error_registry;/* * Clock counter */cl_ticker::cl_ticker(int adir, int in_isr, char *aname){ options= TICK_RUN; if (in_isr) options|= TICK_INISR; dir= adir; ticks= 0; set_name(aname);}cl_ticker::~cl_ticker(void) {}intcl_ticker::tick(int nr){ if (options&TICK_RUN) ticks+= dir*nr; return(ticks);}doublecl_ticker::get_rtime(double xtal){ double d; d= (double)ticks/xtal; return(d);}voidcl_ticker::dump(int nr, double xtal, class cl_console *con){ 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);}/* * Options of uc */cl_xtal_option::cl_xtal_option(class cl_uc *the_uc): cl_optref(the_uc){ uc= the_uc;}voidcl_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; sim = asim; //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); 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, "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); 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 hws; //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 stack_ops; errors->free_all(); delete errors; delete xtal_option; delete address_spaces; delete memchips; //delete address_decoders;}intcl_uc::init(void){ int i; set_name("controller"); cl_base::init(); if (xtal_option->use("xtal")) xtal= xtal_option->get_value(xtal); else 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(); 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);}char *cl_uc::id_string(void){ return("unknown microcontroller");}voidcl_uc::reset(void){ class it_level *il; instPC= PC= 0; state = stGO; ticks->ticks= 0; isr_ticks->ticks= 0; idle_ticks->ticks= 0; /*FIXME should we clear user counters?*/ il= (class it_level *)(it_levels->top()); while (il && il->level >= 0) { il= (class it_level *)(it_levels->pop()); delete il; il= (class it_level *)(it_levels->top()); } sp_max= 0; sp_avg= 0; stack_ops->free_all(); int i; for (i= 0; i < hws->count; i++) { class cl_hw *hw= (class cl_hw *)(hws->at(i)); hw->reset(); }}/* * Making elements */voidcl_uc::make_memories(void){}/*t_addrcl_uc::get_mem_size(char *id){ class cl_memory *m= memory(id); return(m?(m->get_size()):0);}intcl_uc::get_mem_width(char *id){ class cl_memory *m= memory(id); return(m?(m->width):8);}*/voidcl_uc::mk_hw_elements(void){}voidcl_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 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", 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_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", DD_TRUE,"dc [start [stop]] Dump code in disass form","long help of dc")); cmd->init(); cmdset->add(cmd= new cl_disassemble_cmd("disassemble", DD_TRUE,"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(); } { // 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")); 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(); 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(); } 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(); } { 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(); }}/* * Read/write simulated memory */t_memcl_uc::read_mem(char *id, t_addr addr){ class cl_address_space *m= address_space(id); return(m?(m->read(addr)):0);}t_memcl_uc::get_mem(char *id, t_addr addr){ class cl_address_space *m= address_space(id); return(m?(m->get(addr)):0);}voidcl_uc::write_mem(char *id, t_addr addr, t_mem val){ class cl_address_space *m= address_space(id); if (m) m->write(addr, val);}voidcl_uc::set_mem(char *id, t_addr addr, t_mem val){ class cl_address_space *m= address_space(id); if(m) m->set(addr, val);}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -