PageRenderTime 59ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/ucsim/ucsim-cc2430-f128/sim.src/uc.cc

#
C++ | 1910 lines | 1468 code | 223 blank | 219 comment | 218 complexity | 3f02559d878cbb30fde0c0e5597778fd MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, GPL-3.0
  1. /*
  2. * Simulator of microcontrollers (uc.cc)
  3. *
  4. * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
  5. *
  6. * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
  7. *
  8. */
  9. /* This file is part of microcontroller simulator: ucsim.
  10. UCSIM is free software; you can redistribute it and/or modify
  11. it under the terms of the GNU General Public License as published by
  12. the Free Software Foundation; either version 2 of the License, or
  13. (at your option) any later version.
  14. UCSIM is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18. You should have received a copy of the GNU General Public License
  19. along with UCSIM; see the file COPYING. If not, write to the Free
  20. Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  21. 02111-1307, USA. */
  22. /*@1@*/
  23. #include "ddconfig.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <errno.h>
  27. #include <ctype.h>
  28. #include "i_string.h"
  29. // prj
  30. #include "globals.h"
  31. #include "utils.h"
  32. // cmd.src
  33. #include "newcmdcl.h"
  34. #include "cmduccl.h"
  35. #include "bpcl.h"
  36. #include "getcl.h"
  37. #include "setcl.h"
  38. #include "infocl.h"
  39. #include "timercl.h"
  40. #include "cmdstatcl.h"
  41. #include "cmdmemcl.h"
  42. #include "cmdutil.h"
  43. // local, sim.src
  44. #include "uccl.h"
  45. #include "hwcl.h"
  46. #include "memcl.h"
  47. #include "simcl.h"
  48. #include "itsrccl.h"
  49. #include "simifcl.h"
  50. static class cl_uc_error_registry uc_error_registry;
  51. /*
  52. * Clock counter
  53. */
  54. cl_ticker::cl_ticker(int adir, int in_isr, char *aname)
  55. {
  56. options= TICK_RUN;
  57. if (in_isr)
  58. options|= TICK_INISR;
  59. dir= adir;
  60. ticks= 0;
  61. set_name(aname);
  62. }
  63. cl_ticker::~cl_ticker(void) {}
  64. int
  65. cl_ticker::tick(int nr)
  66. {
  67. if (options&TICK_RUN)
  68. ticks+= dir*nr;
  69. return(ticks);
  70. }
  71. double
  72. cl_ticker::get_rtime(double xtal)
  73. {
  74. double d;
  75. d= (double)ticks/xtal;
  76. return(d);
  77. }
  78. void
  79. cl_ticker::dump(int nr, double xtal, class cl_console *con)
  80. {
  81. con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n",
  82. nr, get_name("unnamed"),
  83. (options&TICK_RUN)?"ON":"OFF",
  84. (options&TICK_INISR)?",ISR":"",
  85. get_rtime(xtal), ticks);
  86. }
  87. /*
  88. * Options of uc
  89. */
  90. cl_xtal_option::cl_xtal_option(class cl_uc *the_uc):
  91. cl_optref(the_uc)
  92. {
  93. uc= the_uc;
  94. }
  95. void
  96. cl_xtal_option::option_changed(void)
  97. {
  98. if (!uc)
  99. return;
  100. double d;
  101. option->get_value(&d);
  102. uc->xtal= d;
  103. }
  104. /*
  105. * Abstract microcontroller
  106. ******************************************************************************
  107. */
  108. cl_uc::cl_uc(class cl_sim *asim):
  109. cl_base()
  110. {
  111. //int i;
  112. sim = asim;
  113. //mems= new cl_list(MEM_TYPES, 1);
  114. memchips= new cl_list(2, 2, "memchips");
  115. address_spaces= new cl_address_space_list(this);
  116. //address_decoders= new cl_list(2, 2);
  117. rom= 0;
  118. hws = new cl_hws();
  119. //options= new cl_list(2, 2);
  120. //for (i= MEM_ROM; i < MEM_TYPES; i++) mems->add(0);
  121. xtal_option= new cl_xtal_option(this);
  122. xtal_option->init();
  123. ticks= new cl_ticker(+1, 0, "time");
  124. isr_ticks= new cl_ticker(+1, TICK_INISR, "isr");
  125. idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle");
  126. counters= new cl_list(2, 2, "counters");
  127. it_levels= new cl_list(2, 2, "it levels");
  128. it_sources= new cl_irqs(2, 2);
  129. class it_level *il= new it_level(-1, 0, 0, 0);
  130. it_levels->push(il);
  131. stack_ops= new cl_list(2, 2, "stack operations");
  132. errors= new cl_list(2, 2, "errors in uc");
  133. events= new cl_list(2, 2, "events in uc");
  134. sp_max= 0;
  135. sp_avg= 0;
  136. inst_exec= DD_FALSE;
  137. }
  138. cl_uc::~cl_uc(void)
  139. {
  140. //delete mems;
  141. delete hws;
  142. //delete options;
  143. delete ticks;
  144. delete isr_ticks;
  145. delete idle_ticks;
  146. delete counters;
  147. events->disconn_all();
  148. delete events;
  149. delete fbrk;
  150. delete ebrk;
  151. delete it_levels;
  152. delete it_sources;
  153. delete stack_ops;
  154. errors->free_all();
  155. delete errors;
  156. delete xtal_option;
  157. delete address_spaces;
  158. delete memchips;
  159. //delete address_decoders;
  160. }
  161. int
  162. cl_uc::init(void)
  163. {
  164. int i;
  165. set_name("controller");
  166. cl_base::init();
  167. if (xtal_option->use("xtal"))
  168. xtal= xtal_option->get_value(xtal);
  169. else
  170. xtal= 11059200;
  171. make_memories();
  172. rom= address_space(MEM_ROM_ID);
  173. ebrk= new brk_coll(2, 2, rom);
  174. fbrk= new brk_coll(2, 2, rom);
  175. fbrk->Duplicates= DD_FALSE;
  176. brk_counter= 0;
  177. mk_hw_elements();
  178. reset();
  179. class cl_cmdset *cs= sim->app->get_commander()->cmdset;
  180. build_cmdset(cs);
  181. for (i= 0; i < sim->app->in_files->count; i++)
  182. {
  183. char *fname= (char *)(sim->app->in_files->at(i));
  184. long l;
  185. if ((l= read_hex_file(fname)) >= 0)
  186. {
  187. sim->app->get_commander()->all_printf("%ld words read from %s\n",
  188. l, fname);
  189. }
  190. }
  191. return(0);
  192. }
  193. char *
  194. cl_uc::id_string(void)
  195. {
  196. return("unknown microcontroller");
  197. }
  198. void
  199. cl_uc::reset(void)
  200. {
  201. class it_level *il;
  202. instPC= PC= 0;
  203. state = stGO;
  204. ticks->ticks= 0;
  205. isr_ticks->ticks= 0;
  206. idle_ticks->ticks= 0;
  207. /*FIXME should we clear user counters?*/
  208. il= (class it_level *)(it_levels->top());
  209. while (il &&
  210. il->level >= 0)
  211. {
  212. il= (class it_level *)(it_levels->pop());
  213. delete il;
  214. il= (class it_level *)(it_levels->top());
  215. }
  216. sp_max= 0;
  217. sp_avg= 0;
  218. stack_ops->free_all();
  219. int i;
  220. for (i= 0; i < hws->count; i++)
  221. {
  222. class cl_hw *hw= (class cl_hw *)(hws->at(i));
  223. hw->reset();
  224. }
  225. }
  226. /*
  227. * Making elements
  228. */
  229. void
  230. cl_uc::make_memories(void)
  231. {}
  232. /*t_addr
  233. cl_uc::get_mem_size(char *id)
  234. {
  235. class cl_memory *m= memory(id);
  236. return(m?(m->get_size()):0);
  237. }
  238. int
  239. cl_uc::get_mem_width(char *id)
  240. {
  241. class cl_memory *m= memory(id);
  242. return(m?(m->width):8);
  243. }
  244. */
  245. void
  246. cl_uc::mk_hw_elements(void)
  247. {
  248. class cl_hw *h;
  249. hws->add(h= new cl_simulator_interface(this, "rom", -1));
  250. h->init();
  251. }
  252. void
  253. cl_uc::build_cmdset(class cl_cmdset *cmdset)
  254. {
  255. class cl_cmd *cmd;
  256. class cl_super_cmd *super_cmd;
  257. class cl_cmdset *cset;
  258. cmdset->add(cmd= new cl_state_cmd("state", 0,
  259. "state State of microcontroller",
  260. "long help of state"));
  261. cmd->init();
  262. #ifdef STATISTIC
  263. cmdset->add(cmd= new cl_statistic_cmd("statistic", 0,
  264. "statistic [mem [startaddr [endaddr]]]\n"
  265. " Statistic of memory accesses",
  266. "long help of statistic"));
  267. cmd->init();
  268. #endif
  269. cmdset->add(cmd= new cl_file_cmd("file", 0,
  270. "file \"FILE\" Load FILE into ROM",
  271. "long help of file"));
  272. cmd->init();
  273. cmd->add_name("load");
  274. cmdset->add(cmd= new cl_dl_cmd("download", 0,
  275. "download Load (intel.hex) data",
  276. "long help of download"));
  277. cmd->init();
  278. cmd->add_name("dl");
  279. cmdset->add(cmd= new cl_pc_cmd("pc", 0,
  280. "pc [addr] Set/get PC",
  281. "long help of pc"));
  282. cmd->init();
  283. cmdset->add(cmd= new cl_reset_cmd("reset", 0,
  284. "reset Reset",
  285. "long help of reset"));
  286. cmd->init();
  287. cmdset->add(cmd= new cl_dump_cmd("dump", DD_TRUE,
  288. "dump memory_type [start [stop [bytes_per_line]]]\n"
  289. " Dump memory of specified type\n"
  290. "dump bit... Dump bits",
  291. "long help of dump"));
  292. cmd->init();
  293. cmdset->add(cmd= new cl_dch_cmd("dch", DD_TRUE,
  294. "dch [start [stop]] Dump code in hex form",
  295. "long help of dch"));
  296. cmd->init();
  297. cmdset->add(cmd= new cl_dc_cmd("dc", DD_TRUE,
  298. "dc [start [stop]] Dump code in disass form",
  299. "long help of dc"));
  300. cmd->init();
  301. cmdset->add(cmd= new cl_disassemble_cmd("disassemble", DD_TRUE,
  302. "disassemble [start [offset [lines]]]\n"
  303. " Disassemble code",
  304. "long help of disassemble"));
  305. cmd->init();
  306. cmdset->add(cmd= new cl_fill_cmd("fill", 0,
  307. "fill memory_type start end data\n"
  308. " Fill memory region with data",
  309. "long help of fill"));
  310. cmd->init();
  311. cmdset->add(cmd= new cl_where_cmd("where", 0,
  312. "where memory_type data...\n"
  313. " Case unsensitive search for data",
  314. "long help of where"));
  315. cmd->init();
  316. cmdset->add(cmd= new cl_Where_cmd("Where", 0,
  317. "Where memory_type data...\n"
  318. " Case sensitive search for data",
  319. "long help of Where"));
  320. cmd->init();
  321. cmdset->add(cmd= new cl_break_cmd("break", 0,
  322. "break addr [hit] Set fix breakpoint\n"
  323. "break mem_type r|w addr [hit]\n"
  324. " Set fix event breakpoint",
  325. "long help of break"));
  326. cmd->init();
  327. cmdset->add(cmd= new cl_tbreak_cmd("tbreak", 0,
  328. "tbreak addr [hit] Set temporary breakpoint\n"
  329. "tbreak mem_type r|w addr [hit]\n"
  330. " Set temporary event breakpoint",
  331. "long help of tbreak"));
  332. cmd->init();
  333. cmdset->add(cmd= new cl_clear_cmd("clear", 0,
  334. "clear [addr...] Clear fix breakpoint",
  335. "long help of clear"));
  336. cmd->init();
  337. cmdset->add(cmd= new cl_delete_cmd("delete", 0,
  338. "delete [nr...] Delete breakpoint(s)",
  339. "long help of clear"));
  340. cmd->init();
  341. {
  342. super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("get"));
  343. if (super_cmd)
  344. cset= super_cmd->commands;
  345. else {
  346. cset= new cl_cmdset();
  347. cset->init();
  348. }
  349. cset->add(cmd= new cl_get_sfr_cmd("sfr", 0,
  350. "get sfr address...\n"
  351. " Get value of addressed SFRs",
  352. "long help of get sfr"));
  353. cmd->init();
  354. /*cset->add(cmd= new cl_get_option_cmd("option", 0,
  355. "get option name\n"
  356. " Get value of an option",
  357. "long help of get option"));
  358. cmd->init();*/
  359. }
  360. if (!super_cmd)
  361. {
  362. cmdset->add(cmd= new cl_super_cmd("get", 0,
  363. "get subcommand Get, see `get' command for more help",
  364. "long help of get", cset));
  365. cmd->init();
  366. }
  367. {
  368. super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("set"));
  369. if (super_cmd)
  370. cset= super_cmd->commands;
  371. else {
  372. cset= new cl_cmdset();
  373. cset->init();
  374. }
  375. cset->add(cmd= new cl_set_mem_cmd("memory", 0,
  376. "set memory memory_type address data...\n"
  377. " Place list of data into memory",
  378. "long help of set memory"));
  379. cmd->init();
  380. cset->add(cmd= new cl_set_bit_cmd("bit", 0,
  381. "set bit addr 0|1 Set specified bit to 0 or 1",
  382. "long help of set bit"));
  383. cmd->init();
  384. cset->add(cmd= new cl_set_hw_cmd("hardware", 0,
  385. "set hardware cathegory params...\n"
  386. " Set parameters of specified hardware element",
  387. "long help of set hardware"));
  388. cmd->add_name("hw");
  389. cmd->init();
  390. }
  391. if (!super_cmd)
  392. {
  393. cmdset->add(cmd= new cl_super_cmd("set", 0,
  394. "set subcommand Set, see `set' command for more help",
  395. "long help of set", cset));
  396. cmd->init();
  397. }
  398. { // info
  399. super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("info"));
  400. if (super_cmd)
  401. cset= super_cmd->get_subcommands();
  402. else {
  403. cset= new cl_cmdset();
  404. cset->init();
  405. }
  406. cset->add(cmd= new cl_info_bp_cmd("breakpoints", 0,
  407. "info breakpoints Status of user-settable breakpoints",
  408. "long help of info breakpoints"));
  409. cmd->add_name("bp");
  410. cmd->init();
  411. cset->add(cmd= new cl_info_reg_cmd("registers", 0,
  412. "info registers List of integer registers and their contents",
  413. "long help of info registers"));
  414. cmd->init();
  415. cset->add(cmd= new cl_info_hw_cmd("hardware", 0,
  416. "info hardware cathegory\n"
  417. " Status of hardware elements of the CPU",
  418. "long help of info hardware"));
  419. cmd->add_name("hw");
  420. cmd->init();
  421. cset->add(cmd= new cl_info_stack_cmd("stack", 0,
  422. "info stack Status of stack of the CPU",
  423. "long help of info stack"));
  424. cmd->init();
  425. cset->add(cmd= new cl_info_memory_cmd("memory", 0,
  426. "info memory Information about memory system",
  427. "long help of info memory"));
  428. cmd->init();
  429. }
  430. if (!super_cmd) {
  431. cmdset->add(cmd= new cl_super_cmd("info", 0,
  432. "info subcommand Information, see `info' command for more help",
  433. "long help of info", cset));
  434. cmd->init();
  435. }
  436. {
  437. super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("timer"));
  438. if (super_cmd)
  439. cset= super_cmd->get_subcommands();
  440. else {
  441. cset= new cl_cmdset();
  442. cset->init();
  443. }
  444. cset->add(cmd= new cl_timer_add_cmd("add", 0,
  445. "timer add id [direction [in_isr]]\n"
  446. " Create a clock counter (timer)",
  447. "log help of timer add"));
  448. cmd->init();
  449. cmd->add_name("create");
  450. cmd->add_name("make");
  451. cset->add(cmd= new cl_timer_delete_cmd("delete", 0,
  452. "timer delete id Delete a timer",
  453. "long help of timer delete"));
  454. cmd->init();
  455. cmd->add_name("remove");
  456. cset->add(cmd= new cl_timer_get_cmd("get", 0,
  457. "timer get [id] Get value of a timer, or all",
  458. "long help of timer get"));
  459. cmd->init();
  460. cset->add(cmd= new cl_timer_run_cmd("run", 0,
  461. "timer start id Start a timer",
  462. "long help of timer run"));
  463. cmd->init();
  464. cmd->add_name("start");
  465. cset->add(cmd= new cl_timer_stop_cmd("stop", 0,
  466. "timer stop id Stop a timer",
  467. "long help of timer stop"));
  468. cmd->init();
  469. cset->add(cmd= new cl_timer_value_cmd("set", 0,
  470. "timer set id value\n"
  471. " Set a timer value",
  472. "long help of timer set"));
  473. cmd->init();
  474. cmd->add_name("value");
  475. }
  476. if (!super_cmd) {
  477. cmdset->add(cmd= new cl_super_cmd("timer", 0,
  478. "timer subcommand Manage timers",
  479. "long help of timer", cset));
  480. cmd->init();
  481. }
  482. {
  483. super_cmd= (class cl_super_cmd *)(cmdset->get_cmd("memory"));
  484. if (super_cmd)
  485. cset= super_cmd->get_subcommands();
  486. else {
  487. cset= new cl_cmdset();
  488. cset->init();
  489. }
  490. /*
  491. cset->add(cmd= new cl_memory_cmd("_no_parameters_", 0,
  492. "memory Information about memory system",
  493. "long help of memory"));
  494. cmd->init();
  495. */
  496. cset->add(cmd= new cl_memory_createchip_cmd("createchip", 0,
  497. "memory createchip id size cellsize\n"
  498. " Create a new memory chip",
  499. "long help of memory createchip"));
  500. cmd->init();
  501. cmd->add_name("cchip");
  502. cset->add(cmd= new cl_memory_createaddressspace_cmd("createaddressspace", 0,
  503. "memory createaddressspace id startaddr size\n"
  504. " Create address space",
  505. "long help of memory createaddressspace"));
  506. cmd->init();
  507. cmd->add_name("createaddrspace");
  508. cmd->add_name("createaspace");
  509. cmd->add_name("caddressspace");
  510. cmd->add_name("caddrspace");
  511. cmd->add_name("caspace");
  512. cset->add(cmd= new cl_memory_createaddressdecoder_cmd("createaddressdecoder", 0,
  513. "memory createaddressdecoder addressspace begin end chip begin\n"
  514. " Create address decoder",
  515. "long help of memory createaddressdecoder"));
  516. cmd->init();
  517. cmd->add_name("createaddrdecoder");
  518. cmd->add_name("createadecoder");
  519. cmd->add_name("caddressdecoder");
  520. cmd->add_name("caddrdecoder");
  521. cmd->add_name("cadecoder");
  522. cset->add(cmd= new cl_info_memory_cmd("info", 0,
  523. "memory info Information about memory system",
  524. "long help of memory info"));
  525. cmd->init();
  526. }
  527. if (!super_cmd) {
  528. cmdset->add(cmd= new cl_super_cmd("memory", 0,
  529. "memory subcommand Manage memory chips and address spaces",
  530. "long help of memory", cset));
  531. cmd->init();
  532. }
  533. }
  534. /*
  535. * Read/write simulated memory
  536. */
  537. t_mem
  538. cl_uc::read_mem(char *id, t_addr addr)
  539. {
  540. class cl_address_space *m= address_space(id);
  541. return(m?(m->read(addr)):0);
  542. }
  543. t_mem
  544. cl_uc::get_mem(char *id, t_addr addr)
  545. {
  546. class cl_address_space *m= address_space(id);
  547. return(m?(m->get(addr)):0);
  548. }
  549. void
  550. cl_uc::write_mem(char *id, t_addr addr, t_mem val)
  551. {
  552. class cl_address_space *m= address_space(id);
  553. if (m)
  554. m->write(addr, val);
  555. }
  556. void
  557. cl_uc::set_mem(char *id, t_addr addr, t_mem val)
  558. {
  559. class cl_address_space *m= address_space(id);
  560. if(m)
  561. m->set(addr, val);
  562. }
  563. /*
  564. class cl_memory *
  565. cl_uc::mem(enum mem_class type)
  566. {
  567. class cl_m *m;
  568. if (mems->count < type)
  569. m= (class cl_m *)(mems->at(MEM_DUMMY));
  570. else
  571. m= (class cl_m *)(mems->at(type));
  572. return(m);
  573. }
  574. */
  575. class cl_address_space *
  576. cl_uc::address_space(char *id)
  577. {
  578. int i;
  579. if (!id ||
  580. !(*id))
  581. return(0);
  582. for (i= 0; i < address_spaces->count; i++)
  583. {
  584. class cl_address_space *m= (cl_address_space *)(address_spaces->at(i));
  585. if (!m ||
  586. !m->have_real_name())
  587. continue;
  588. if (m->is_inamed(id))
  589. return(m);
  590. }
  591. return(0);
  592. }
  593. class cl_memory *
  594. cl_uc::memory(char *id)
  595. {
  596. int i;
  597. if (!id ||
  598. !(*id))
  599. return(0);
  600. for (i= 0; i < address_spaces->count; i++)
  601. {
  602. class cl_memory *m= (cl_memory *)(address_spaces->at(i));
  603. if (!m ||
  604. !m->have_real_name())
  605. continue;
  606. if (m->is_inamed(id))
  607. return(m);
  608. }
  609. for (i= 0; i < memchips->count; i++)
  610. {
  611. class cl_memory *m= (cl_memory *)(memchips->at(i));
  612. if (!m ||
  613. !m->have_real_name())
  614. continue;
  615. if (m->is_inamed(id))
  616. return(m);
  617. }
  618. return(0);
  619. }
  620. static long
  621. ReadInt(FILE *f, bool *ok, int bytes)
  622. {
  623. char s2[3];
  624. long l= 0;
  625. *ok= DD_FALSE;
  626. while (bytes)
  627. {
  628. if (fscanf(f, "%2c", &s2[0]) == EOF)
  629. return(0);
  630. s2[2]= '\0';
  631. l= l*256 + strtol(s2, NULL, 16);
  632. bytes--;
  633. }
  634. *ok= DD_TRUE;
  635. return(l);
  636. }
  637. /*
  638. * Reading intel hexa file into EROM
  639. *____________________________________________________________________________
  640. *
  641. * If parameter is a NULL pointer, this function reads data from `cmd_in'
  642. *
  643. */
  644. long
  645. cl_uc::read_hex_file(const char *nam)
  646. {
  647. FILE *f;
  648. int c;
  649. long written= 0, recnum= 0;
  650. uchar dnum; // data number
  651. uchar rtyp=0; // record type
  652. uint addr= 0; // address
  653. uchar rec[300]; // data record
  654. uchar sum ; // checksum
  655. uchar chk ; // check
  656. int i;
  657. bool ok, get_low= 1;
  658. uchar low= 0, high;
  659. int elar = 0; // Extended Linear Address Record
  660. class cl_address_decoder *ad;
  661. ad = (class cl_address_decoder *) rom->decoders->at(0);
  662. class cl_memory *flash;
  663. flash = (class cl_memory *) ad->memchip;
  664. if (!rom)
  665. {
  666. sim->app->get_commander()->
  667. dd_printf("No ROM address space to read in.\n");
  668. return(-1);
  669. }
  670. if (!nam)
  671. {
  672. sim->app->get_commander()->
  673. dd_printf("cl_uc::read_hex_file File name not specified\n");
  674. return(-1);
  675. }
  676. else
  677. if ((f= fopen(nam, "r")) == NULL)
  678. {
  679. fprintf(stderr, "Can't open `%s': %s\n", nam, strerror(errno));
  680. return(-1);
  681. }
  682. //memset(inst_map, '\0', sizeof(inst_map));
  683. ok= DD_TRUE;
  684. while (ok &&
  685. rtyp != 1)
  686. {
  687. while (((c= getc(f)) != ':') &&
  688. (c != EOF)) ;
  689. if (c != ':')
  690. {fprintf(stderr, ": not found\n");break;}
  691. recnum++;
  692. dnum= ReadInt(f, &ok, 1);//printf("dnum=%02x",dnum);
  693. chk = dnum;
  694. addr= ReadInt(f, &ok, 2);//printf("addr=%04x",addr);
  695. chk+= (addr & 0xff);
  696. chk+= ((addr >> 8) & 0xff);
  697. rtyp= ReadInt(f, &ok, 1);//printf("rtyp=%02x ",rtyp);
  698. chk+= rtyp;
  699. for (i= 0; ok && (i < dnum); i++)
  700. {
  701. rec[i]= ReadInt(f, &ok, 1);//printf("%02x",rec[i]);
  702. chk+= rec[i];
  703. }
  704. if (ok)
  705. {
  706. sum= ReadInt(f, &ok, 1);//printf(" sum=%02x\n",sum);
  707. if (ok)
  708. {
  709. if (((sum + chk) & 0xff) == 0)
  710. {
  711. // Code banking support.
  712. if (rtyp == 4) {
  713. elar = ((rec[0] << 4) + rec[1]) << 16;
  714. printf("elar = 0x%x\n", elar);
  715. }
  716. else if (rtyp == 0)
  717. {
  718. if (rom->width > 8)
  719. addr/= 2;
  720. for (i= 0; i < dnum; i++)
  721. {
  722. if (rom->width <= 8)
  723. {
  724. //rom->set(addr, rec[i]);
  725. flash->set(elar + addr, rec[i]);
  726. addr++;
  727. written++;
  728. }
  729. else if (rom->width <= 16)
  730. {
  731. if (get_low)
  732. {
  733. low= rec[i];
  734. get_low= 0;
  735. }
  736. else
  737. {
  738. high= rec[i];
  739. rom->set(addr, (high*256)+low);
  740. addr++;
  741. written++;
  742. get_low= 1;
  743. }
  744. }
  745. }
  746. }
  747. else
  748. if (rtyp != 1)
  749. application->debug("Unknown record type %d(0x%x)\n",
  750. rtyp, rtyp);
  751. }
  752. else
  753. application->debug("Checksum error (%x instead of %x) in "
  754. "record %ld.\n", chk, sum, recnum);
  755. }
  756. else
  757. application->debug("Read error in record %ld.\n", recnum);
  758. }
  759. }
  760. if (rom->width > 8 &&
  761. !get_low)
  762. rom->set(addr, low);
  763. if (nam)
  764. fclose(f);
  765. application->debug("%ld records have been read\n", recnum);
  766. analyze(0);
  767. return(written);
  768. }
  769. /*
  770. * Handling instruction map
  771. *
  772. * `inst_at' is checking if the specified address is in instruction
  773. * map and `set_inst_at' marks the address in the map and
  774. * `del_inst_at' deletes the mark. `there_is_inst' cheks if there is
  775. * any mark in the map
  776. */
  777. bool
  778. cl_uc::inst_at(t_addr addr)
  779. {
  780. if (!rom)
  781. return(0);
  782. return(rom->get_cell_flag(addr, CELL_INST));
  783. }
  784. void
  785. cl_uc::set_inst_at(t_addr addr)
  786. {
  787. if (rom)
  788. rom->set_cell_flag(addr, DD_TRUE, CELL_INST);
  789. }
  790. void
  791. cl_uc::del_inst_at(t_addr addr)
  792. {
  793. if (rom)
  794. rom->set_cell_flag(addr, DD_FALSE, CELL_INST);
  795. }
  796. bool
  797. cl_uc::there_is_inst(void)
  798. {
  799. if (!rom)
  800. return(0);
  801. bool got= DD_FALSE;
  802. t_addr addr;
  803. for (addr= 0; rom->valid_address(addr) && !got; addr++)
  804. got= rom->get_cell_flag(addr, CELL_INST);
  805. return(got);
  806. }
  807. /*
  808. * Manipulating HW elements of the CPU
  809. *****************************************************************************
  810. */
  811. /* Register callback hw objects for mem read/write */
  812. /*void
  813. cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw)
  814. {
  815. class cl_m *m;
  816. class cl_memloc *l;
  817. if ((m= (class cl_m*)mems->at(type)))
  818. {
  819. if ((l= m->read_locs->get_loc(addr)) == 0)
  820. {
  821. l= new cl_memloc(addr);
  822. l->init();
  823. m->read_locs->add(l);
  824. }
  825. l->hws->add(hw);
  826. }
  827. else
  828. printf("cl_uc::register_hw_read TROUBLE\n");
  829. }*/
  830. /*void
  831. cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw)
  832. {
  833. }*/
  834. /* Looking for a specific HW element */
  835. class cl_hw *
  836. cl_uc::get_hw(enum hw_cath cath, int *idx)
  837. {
  838. class cl_hw *hw= 0;
  839. int i= 0;
  840. if (idx)
  841. i= *idx;
  842. for (; i < hws->count; i++)
  843. {
  844. hw= (class cl_hw *)(hws->at(i));
  845. if (hw->cathegory == cath)
  846. break;
  847. }
  848. if (i >= hws->count)
  849. return(0);
  850. if (idx)
  851. *idx= i;
  852. return(hw);
  853. }
  854. class cl_hw *
  855. cl_uc::get_hw(char *id_string, int *idx)
  856. {
  857. class cl_hw *hw= 0;
  858. int i= 0;
  859. if (idx)
  860. i= *idx;
  861. for (; i < hws->count; i++)
  862. {
  863. hw= (class cl_hw *)(hws->at(i));
  864. if (strstr(hw->id_string, id_string) == hw->id_string)
  865. break;
  866. }
  867. if (i >= hws->count)
  868. return(0);
  869. if (idx)
  870. *idx= i;
  871. return(hw);
  872. }
  873. class cl_hw *
  874. cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx)
  875. {
  876. class cl_hw *hw;
  877. int i= 0;
  878. if (idx)
  879. i= *idx;
  880. hw= get_hw(cath, &i);
  881. while (hw &&
  882. hw->id != hwid)
  883. {
  884. i++;
  885. hw= get_hw(cath, &i);
  886. }
  887. if (hw &&
  888. idx)
  889. *idx= i;
  890. return(hw);
  891. }
  892. class cl_hw *
  893. cl_uc::get_hw(char *id_string, int hwid, int *idx)
  894. {
  895. class cl_hw *hw;
  896. int i= 0;
  897. if (idx)
  898. i= *idx;
  899. hw= get_hw(id_string, &i);
  900. while (hw &&
  901. hw->id != hwid)
  902. {
  903. i++;
  904. hw= get_hw(id_string, &i);
  905. }
  906. if (hw &&
  907. idx)
  908. *idx= i;
  909. return(hw);
  910. }
  911. /*
  912. * Help of the command interpreter
  913. */
  914. struct dis_entry *
  915. cl_uc::dis_tbl(void)
  916. {
  917. static struct dis_entry empty= { 0, 0, 0, 0, NULL };
  918. return(&empty);
  919. }
  920. struct name_entry *
  921. cl_uc::sfr_tbl(void)
  922. {
  923. static struct name_entry empty= { 0, 0 };
  924. return(&empty);
  925. }
  926. struct name_entry *
  927. cl_uc::bit_tbl(void)
  928. {
  929. static struct name_entry empty= { 0, 0 };
  930. return(&empty);
  931. }
  932. char *
  933. cl_uc::disass(t_addr addr, char *sep)
  934. {
  935. char *buf;
  936. buf= (char*)malloc(100);
  937. strcpy(buf, "uc::disass() unimplemented\n");
  938. return(buf);
  939. }
  940. void
  941. cl_uc::print_disass(t_addr addr, class cl_console *con)
  942. {
  943. char *dis;
  944. class cl_brk *b;
  945. int i;
  946. if (!rom)
  947. return;
  948. t_mem code= rom->get(addr);
  949. b= fbrk_at(addr);
  950. dis= disass(addr, NULL);
  951. if (b)
  952. con->dd_printf("%c", (b->perm == brkFIX)?'F':'D');
  953. else
  954. con->dd_printf(" ");
  955. con->dd_printf("%c ", inst_at(addr)?' ':'?');
  956. con->dd_printf(rom->addr_format, addr); con->dd_printf(" ");
  957. con->dd_printf(rom->data_format, code);
  958. for (i= 1; i < inst_length(addr); i++)
  959. {
  960. con->dd_printf(" ");
  961. con->dd_printf(rom->data_format, rom->get(addr+i));
  962. }
  963. int li= longest_inst();
  964. while (i < li)
  965. {
  966. int j;
  967. j= rom->width/4 + ((rom->width%4)?1:0) + 1;
  968. while (j)
  969. con->dd_printf(" "), j--;
  970. i++;
  971. }
  972. con->dd_printf(" %s\n", dis);
  973. free(dis);
  974. }
  975. void
  976. cl_uc::print_regs(class cl_console *con)
  977. {
  978. con->dd_printf("No registers\n");
  979. }
  980. int
  981. cl_uc::inst_length(t_addr addr)
  982. {
  983. struct dis_entry *tabl= dis_tbl();
  984. int i;
  985. t_mem code;
  986. if (!rom)
  987. return(0);
  988. code = rom->get(addr);
  989. for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ;
  990. return(tabl[i].mnemonic?tabl[i].length:1);
  991. }
  992. int
  993. cl_uc::inst_branch(t_addr addr)
  994. {
  995. struct dis_entry *tabl= dis_tbl();
  996. int i;
  997. t_mem code;
  998. if (!rom)
  999. return(0);
  1000. code = rom->get(addr);
  1001. for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
  1002. ;
  1003. return tabl[i].branch;
  1004. }
  1005. int
  1006. cl_uc::longest_inst(void)
  1007. {
  1008. struct dis_entry *de= dis_tbl();
  1009. int max= 0;
  1010. while (de &&
  1011. de->mnemonic)
  1012. {
  1013. if (de->length > max)
  1014. max= de->length;
  1015. de++;
  1016. }
  1017. return(max);
  1018. }
  1019. bool
  1020. cl_uc::get_name(t_addr addr, struct name_entry tab[], char *buf)
  1021. {
  1022. int i;
  1023. i= 0;
  1024. while (tab[i].name &&
  1025. (!(tab[i].cpu_type & type) ||
  1026. (tab[i].addr != addr)))
  1027. i++;
  1028. if (tab[i].name)
  1029. strcpy(buf, tab[i].name);
  1030. return(tab[i].name != NULL);
  1031. }
  1032. bool
  1033. cl_uc::symbol2address(char *sym, struct name_entry tab[],
  1034. t_addr *addr)
  1035. {
  1036. int i;
  1037. if (!sym ||
  1038. !*sym)
  1039. return(DD_FALSE);
  1040. i= 0;
  1041. while (tab[i].name &&
  1042. (!(tab[i].cpu_type & type) ||
  1043. strcasecmp(sym, tab[i].name) != 0))
  1044. i++;
  1045. if (tab[i].name)
  1046. {
  1047. if (addr)
  1048. *addr= tab[i].addr;
  1049. return(DD_TRUE);
  1050. }
  1051. return(DD_FALSE);
  1052. }
  1053. char *
  1054. cl_uc::symbolic_bit_name(t_addr bit_address,
  1055. class cl_memory *mem,
  1056. t_addr mem_addr,
  1057. t_mem bit_mask)
  1058. {
  1059. char *sym_name= 0;
  1060. int i;
  1061. i= 0;
  1062. while (bit_tbl()[i].name &&
  1063. (bit_tbl()[i].addr != bit_address))
  1064. i++;
  1065. if (bit_tbl()[i].name)
  1066. {
  1067. sym_name= strdup(bit_tbl()[i].name);
  1068. return(sym_name);
  1069. }
  1070. if (mem &&
  1071. mem->have_real_name() &&
  1072. strstr(mem->get_name(), "sfr") == mem->get_name())
  1073. {
  1074. i= 0;
  1075. while (sfr_tbl()[i].name &&
  1076. (sfr_tbl()[i].addr != mem_addr))
  1077. i++;
  1078. if (sfr_tbl()[i].name)
  1079. sym_name= strdup(sfr_tbl()[i].name);
  1080. else
  1081. sym_name= 0;
  1082. }
  1083. if (!sym_name)
  1084. {
  1085. sym_name= (char *)malloc(16);
  1086. sprintf(sym_name, mem?(mem->addr_format):"0x%06x", mem_addr);
  1087. }
  1088. sym_name= (char *)realloc(sym_name, strlen(sym_name)+2);
  1089. strcat(sym_name, ".");
  1090. i= 0;
  1091. while (bit_mask > 1)
  1092. {
  1093. bit_mask>>=1;
  1094. i++;
  1095. }
  1096. char bitnumstr[10];
  1097. sprintf(bitnumstr, "%1d", i);
  1098. strcat(sym_name, bitnumstr);
  1099. return(sym_name);
  1100. }
  1101. /*
  1102. * Messages to broadcast
  1103. */
  1104. bool
  1105. cl_uc::handle_event(class cl_event &event)
  1106. {
  1107. switch (event.what)
  1108. {
  1109. case ev_address_space_added:
  1110. {
  1111. try {
  1112. class cl_event_address_space_added &e=
  1113. dynamic_cast<class cl_event_address_space_added &>(event);
  1114. address_space_added(e.as);
  1115. e.handle();
  1116. }
  1117. catch (...)
  1118. { break; }
  1119. break;
  1120. }
  1121. default:
  1122. return(pass_event_down(event));
  1123. break;
  1124. }
  1125. return(DD_FALSE);
  1126. }
  1127. /*
  1128. void
  1129. cl_uc::mem_cell_changed(class cl_address_space *mem, t_addr addr)
  1130. {
  1131. if (hws)
  1132. hws->mem_cell_changed(mem, addr);
  1133. else
  1134. printf("JAJ uc\n");//FIXME
  1135. if (mems &&
  1136. mems->count)
  1137. {
  1138. int i;
  1139. for (i= 0; i < mems->count; i++)
  1140. {
  1141. }
  1142. }
  1143. }
  1144. */
  1145. void
  1146. cl_uc::address_space_added(class cl_address_space *as)
  1147. {
  1148. if (hws)
  1149. hws->address_space_added(as);
  1150. else
  1151. printf("JAJ uc\n");//FIXME
  1152. }
  1153. /*
  1154. * Error handling
  1155. */
  1156. void
  1157. cl_uc::error(class cl_error *error)
  1158. {
  1159. errors->add(error);
  1160. if ((error->inst= inst_exec))
  1161. error->PC= instPC;
  1162. }
  1163. void
  1164. cl_uc::check_errors(void)
  1165. {
  1166. int i;
  1167. class cl_commander *c= sim->app->get_commander();
  1168. bool must_stop= DD_FALSE;
  1169. if (c)
  1170. {
  1171. for (i= 0; i < errors->count; i++)
  1172. {
  1173. class cl_error *error= (class cl_error *)(errors->at(i));
  1174. if (!error->is_on())
  1175. continue;
  1176. error->print(c);
  1177. must_stop= must_stop || (error->get_type() & err_stop);
  1178. if (error->inst)
  1179. {
  1180. class cl_console *con;
  1181. con= c->actual_console;
  1182. if (!con)
  1183. con= c->frozen_console;
  1184. if (con)
  1185. {
  1186. con->dd_printf("Erronouse instruction: ");
  1187. print_disass(error->PC, con);
  1188. }
  1189. }
  1190. }
  1191. errors->free_all();
  1192. }
  1193. else
  1194. fprintf(stderr, "no actual console, %d errors\n", errors->count);
  1195. if (must_stop)
  1196. sim->stop(resERROR);
  1197. }
  1198. /*
  1199. * Converting bit address into real memory
  1200. */
  1201. class cl_address_space *
  1202. cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask)
  1203. {
  1204. if (memaddr)
  1205. *memaddr= bitaddr;
  1206. if (bitmask)
  1207. *bitmask= 1 << (bitaddr & 0x7);
  1208. return(0); // abstract...
  1209. }
  1210. /*
  1211. * Execution
  1212. */
  1213. int
  1214. cl_uc::tick_hw(int cycles)
  1215. {
  1216. class cl_hw *hw;
  1217. int i;//, cpc= clock_per_cycle();
  1218. // tick hws
  1219. for (i= 0; i < hws->count; i++)
  1220. {
  1221. hw= (class cl_hw *)(hws->at(i));
  1222. if (hw->flags & HWF_INSIDE)
  1223. hw->tick(cycles);
  1224. }
  1225. do_extra_hw(cycles);
  1226. return(0);
  1227. }
  1228. void
  1229. cl_uc::do_extra_hw(int cycles)
  1230. {}
  1231. int
  1232. cl_uc::tick(int cycles)
  1233. {
  1234. //class cl_hw *hw;
  1235. int i, cpc= clock_per_cycle();
  1236. // increase time
  1237. ticks->tick(cycles * cpc);
  1238. class it_level *il= (class it_level *)(it_levels->top());
  1239. if (il->level >= 0)
  1240. isr_ticks->tick(cycles * cpc);
  1241. if (state == stIDLE)
  1242. idle_ticks->tick(cycles * cpc);
  1243. for (i= 0; i < counters->count; i++)
  1244. {
  1245. class cl_ticker *t= (class cl_ticker *)(counters->at(i));
  1246. if (t)
  1247. {
  1248. if ((t->options&TICK_INISR) ||
  1249. il->level < 0)
  1250. t->tick(cycles * cpc);
  1251. }
  1252. }
  1253. // tick for hardwares
  1254. inst_ticks+= cycles;
  1255. return(0);
  1256. }
  1257. class cl_ticker *
  1258. cl_uc::get_counter(int nr)
  1259. {
  1260. if (nr >= counters->count)
  1261. return(0);
  1262. return((class cl_ticker *)(counters->at(nr)));
  1263. }
  1264. class cl_ticker *
  1265. cl_uc::get_counter(char *nam)
  1266. {
  1267. int i;
  1268. if (!nam)
  1269. return(0);
  1270. for (i= 0; i < counters->count; i++)
  1271. {
  1272. class cl_ticker *t= (class cl_ticker *)(counters->at(i));
  1273. if (t &&
  1274. t->get_name() &&
  1275. strcmp(t->get_name(), nam) == 0)
  1276. return(t);
  1277. }
  1278. return(0);
  1279. }
  1280. void
  1281. cl_uc::add_counter(class cl_ticker *ticker, int nr)
  1282. {
  1283. while (counters->count <= nr)
  1284. counters->add(0);
  1285. counters->put_at(nr, ticker);
  1286. }
  1287. void
  1288. cl_uc::add_counter(class cl_ticker *ticker, char */*nam*/)
  1289. {
  1290. int i;
  1291. if (counters->count < 1)
  1292. counters->add(0);
  1293. for (i= 1; i < counters->count; i++)
  1294. {
  1295. class cl_ticker *t= (class cl_ticker *)(counters->at(i));
  1296. if (!t)
  1297. {
  1298. counters->put_at(i, ticker);
  1299. return;
  1300. }
  1301. }
  1302. counters->add(ticker);
  1303. }
  1304. void
  1305. cl_uc::del_counter(int nr)
  1306. {
  1307. class cl_ticker *t;
  1308. if (nr >= counters->count)
  1309. return;
  1310. if ((t= (class cl_ticker *)(counters->at(0))) != 0)
  1311. delete t;
  1312. counters->put_at(nr, 0);
  1313. }
  1314. void
  1315. cl_uc::del_counter(char *nam)
  1316. {
  1317. int i;
  1318. if (!nam)
  1319. return;
  1320. for (i= 0; i < counters->count; i++)
  1321. {
  1322. class cl_ticker *t= (class cl_ticker *)(counters->at(i));
  1323. if (t &&
  1324. t->get_name() &&
  1325. strcmp(t->get_name(), nam) == 0)
  1326. {
  1327. delete t;
  1328. counters->put_at(i, 0);
  1329. return;
  1330. }
  1331. }
  1332. }
  1333. /*
  1334. * Fetch without checking for breakpoint hit
  1335. */
  1336. t_mem
  1337. cl_uc::fetch(void)
  1338. {
  1339. ulong code;
  1340. if (!rom)
  1341. return(0);
  1342. code= rom->read(PC);
  1343. PC= rom->inc_address(PC);
  1344. return(code);
  1345. }
  1346. /*
  1347. * Fetch but checking for breakpoint hit first, returns TRUE if
  1348. * a breakpoint is hit
  1349. */
  1350. bool
  1351. cl_uc::fetch(t_mem *code)
  1352. {
  1353. class cl_brk *brk;
  1354. int idx;
  1355. if (!code)
  1356. return(0);
  1357. if ((sim->state & SIM_GO) &&
  1358. rom)
  1359. {
  1360. if (rom->get_cell_flag(PC, CELL_FETCH_BRK) &&
  1361. (brk= fbrk->get_bp(PC, &idx)) &&
  1362. (brk->do_hit()))
  1363. {
  1364. if (brk->perm == brkDYNAMIC)
  1365. fbrk->del_bp(PC);
  1366. return(1);
  1367. }
  1368. }
  1369. *code= fetch();
  1370. return(0);
  1371. }
  1372. int
  1373. cl_uc::do_inst(int step)
  1374. {
  1375. int res= resGO;
  1376. if (step < 0)
  1377. step= 1;
  1378. while (step-- &&
  1379. res == resGO)
  1380. {
  1381. pre_inst();
  1382. res= exec_inst();
  1383. post_inst();
  1384. }
  1385. if (res != resGO)
  1386. sim->stop(res);
  1387. return(res);
  1388. }
  1389. void
  1390. cl_uc::pre_inst(void)
  1391. {
  1392. inst_exec= DD_TRUE;
  1393. inst_ticks= 0;
  1394. events->disconn_all();
  1395. }
  1396. int
  1397. cl_uc::exec_inst(void)
  1398. {
  1399. instPC= PC;
  1400. return(resGO);
  1401. }
  1402. void
  1403. cl_uc::post_inst(void)
  1404. {
  1405. tick_hw(inst_ticks);
  1406. if (errors->count)
  1407. check_errors();
  1408. if (events->count)
  1409. check_events();
  1410. inst_exec= DD_FALSE;
  1411. }
  1412. /*
  1413. * Time related functions
  1414. */
  1415. double
  1416. cl_uc::get_rtime(void)
  1417. {
  1418. /* double d;
  1419. d= (double)ticks/xtal;
  1420. return(d);*/
  1421. return(ticks->get_rtime(xtal));
  1422. }
  1423. int
  1424. cl_uc::clock_per_cycle(void)
  1425. {
  1426. return(1);
  1427. }
  1428. /*
  1429. * Stack tracking system
  1430. */
  1431. void
  1432. cl_uc::stack_write(class cl_stack_op *op)
  1433. {
  1434. if (op->get_op() & stack_read_operation)
  1435. {
  1436. class cl_error_stack_tracker_wrong_handle *e= new
  1437. cl_error_stack_tracker_wrong_handle(DD_FALSE);
  1438. //fprintf(stderr, "%06"_A_"x cl_uc::stack_read() should be called for "
  1439. //"%s\n", op->get_pc(), op->get_op_name());
  1440. e->init();
  1441. error(e);
  1442. return;
  1443. }
  1444. stack_ops->push(op);
  1445. }
  1446. void
  1447. cl_uc::stack_read(class cl_stack_op *op)
  1448. {
  1449. class cl_stack_op *top= (class cl_stack_op *)(stack_ops->top());
  1450. if (op->get_op() & stack_write_operation)
  1451. {
  1452. class cl_error_stack_tracker_wrong_handle *e= new
  1453. cl_error_stack_tracker_wrong_handle(DD_TRUE);
  1454. e->init();
  1455. error(e);
  1456. //fprintf(stderr, "%06"_A_"x cl_uc::stack_write() should be called for "
  1457. //"%s\n", op->get_pc(), op->get_op_name());
  1458. return;
  1459. }
  1460. if (!top)
  1461. {
  1462. class cl_error *e= new cl_error_stack_tracker_empty(op);
  1463. /*printf("0x%06"_A_"x %s operation on stack but no operation was before\n
  1464. ",
  1465. op->get_pc(), op->get_op_name());*/
  1466. e->init();
  1467. error(e);
  1468. return;
  1469. }
  1470. if (top)
  1471. {
  1472. if (!top->match(op))
  1473. {
  1474. class cl_error *e= new cl_error_stack_tracker_unmatch(top, op);
  1475. e->init();
  1476. error(e);
  1477. /*printf("0x%06"_A_"x %s operation on stack but last was %s\n",
  1478. op->get_pc(), op->get_op_name(), top->get_op_name());*/
  1479. }
  1480. int top_size= top->data_size(), op_size= op->data_size();
  1481. if (top_size != op_size)
  1482. {
  1483. application->debug("0x%06"_A_"x %d bytes to read out of stack "
  1484. "but %d was pushed in last operation\n",
  1485. op->get_pc(), op_size, top_size);
  1486. }
  1487. }
  1488. int removed= 0;
  1489. while (top &&
  1490. top->can_removed(op))
  1491. {
  1492. top= (class cl_stack_op *)stack_ops->pop();
  1493. delete top;
  1494. top= (class cl_stack_op *)stack_ops->top();
  1495. removed++;
  1496. }
  1497. if (removed != 1)
  1498. {
  1499. application->debug("0x%06"_A_"x %d ops removed from stack-tracker "
  1500. "when %s happened, top pc=0x%06"_A_"x "
  1501. "top before=0x%06"_A_"x op after=0x%06"_A_"x\n",
  1502. op->get_pc(), removed, op->get_op_name(),
  1503. top?(top->get_pc()):0, top?(top->get_before()):0,
  1504. op->get_after());
  1505. }
  1506. if (top)
  1507. {
  1508. int ta= top->get_after(), oa= op->get_after();
  1509. if (ta != oa)
  1510. {
  1511. application->debug("0x%06"_A_"x stack still inconsistent after %s, "
  1512. "%d byte(s) should be read out; top after"
  1513. "=0x%06"_A_"x op after=0x%06"_A_"x\n",
  1514. op->get_pc(), op->get_op_name(), abs(ta-oa),
  1515. ta, oa);
  1516. class cl_error *e=
  1517. new cl_error_stack_tracker_inconsistent(op, abs(ta-oa));
  1518. e->init();
  1519. error(e);
  1520. }
  1521. }
  1522. delete op;
  1523. }
  1524. /*
  1525. * Breakpoint handling
  1526. */
  1527. class cl_fetch_brk *
  1528. cl_uc::fbrk_at(t_addr addr)
  1529. {
  1530. int idx;
  1531. return((class cl_fetch_brk *)(fbrk->get_bp(addr, &idx)));
  1532. }
  1533. class cl_ev_brk *
  1534. cl_uc::ebrk_at(t_addr addr, char *id)
  1535. {
  1536. int i;
  1537. class cl_ev_brk *eb;
  1538. for (i= 0; i < ebrk->count; i++)
  1539. {
  1540. eb= (class cl_ev_brk *)(ebrk->at(i));
  1541. if (eb->addr == addr &&
  1542. !strcmp(eb->id, id))
  1543. return(eb);
  1544. }
  1545. return(0);
  1546. }
  1547. /*void
  1548. cl_uc::rm_fbrk(long addr)
  1549. {
  1550. fbrk->del_bp(addr);
  1551. }*/
  1552. /* Get a breakpoint specified by its number */
  1553. class cl_brk *
  1554. cl_uc::brk_by_nr(int nr)
  1555. {
  1556. class cl_brk *bp;
  1557. if ((bp= fbrk->get_bp(nr)))
  1558. return(bp);
  1559. if ((bp= ebrk->get_bp(nr)))
  1560. return(bp);
  1561. return(0);
  1562. }
  1563. /* Get a breakpoint from the specified collection by its number */
  1564. class cl_brk *
  1565. cl_uc::brk_by_nr(class brk_coll *bpcoll, int nr)
  1566. {
  1567. class cl_brk *bp;
  1568. if ((bp= bpcoll->get_bp(nr)))
  1569. return(bp);
  1570. return(0);
  1571. }
  1572. /* Remove an event breakpoint specified by its address and id */
  1573. void
  1574. cl_uc::rm_ebrk(t_addr addr, char *id)
  1575. {
  1576. int i;
  1577. class cl_ev_brk *eb;
  1578. for (i= 0; i < ebrk->count; i++)
  1579. {
  1580. eb= (class cl_ev_brk *)(ebrk->at(i));
  1581. if (eb->addr == addr &&
  1582. !strcmp(eb->id, id))
  1583. ebrk->del_bp(i, 0);
  1584. }
  1585. }
  1586. /* Remove a breakpoint specified by its number */
  1587. bool
  1588. cl_uc::rm_brk(int nr)
  1589. {
  1590. class cl_brk *bp;
  1591. if ((bp= brk_by_nr(fbrk, nr)))
  1592. {
  1593. fbrk->del_bp(bp->addr);
  1594. return(DD_TRUE);
  1595. }
  1596. else if ((bp= brk_by_nr(ebrk, nr)))
  1597. {
  1598. ebrk->del_bp(ebrk->index_of(bp), 0);
  1599. return(DD_TRUE);
  1600. }
  1601. return(DD_FALSE);
  1602. }
  1603. void
  1604. cl_uc::put_breaks(void)
  1605. {}
  1606. /* Remove all fetch and event breakpoints */
  1607. void
  1608. cl_uc::remove_all_breaks(void)
  1609. {
  1610. while (fbrk->count)
  1611. {
  1612. class cl_brk *brk= (class cl_brk *)(fbrk->at(0));
  1613. fbrk->del_bp(brk->addr);
  1614. }
  1615. while (ebrk->count)
  1616. ebrk->del_bp(ebrk->count-1, 0);
  1617. }
  1618. int
  1619. cl_uc::make_new_brknr(void)
  1620. {
  1621. if (brk_counter == 0)
  1622. return(brk_counter= 1);
  1623. if (fbrk->count == 0 &&
  1624. ebrk->count == 0)
  1625. return(brk_counter= 1);
  1626. return(++brk_counter);
  1627. }
  1628. class cl_ev_brk *
  1629. cl_uc::mk_ebrk(enum brk_perm perm, class cl_address_space *mem,
  1630. char op, t_addr addr, int hit)
  1631. {
  1632. class cl_ev_brk *b;
  1633. op= toupper(op);
  1634. b= new cl_ev_brk(mem, make_new_brknr(), addr, perm, hit, op);
  1635. b->init();
  1636. return(b);
  1637. }
  1638. void
  1639. cl_uc::check_events(void)
  1640. {
  1641. int i;
  1642. for (i= 0; i < events->count; i++)
  1643. {
  1644. class cl_ev_brk *brk=
  1645. dynamic_cast<class cl_ev_brk *>(events->object_at(i));
  1646. sim->stop(brk);
  1647. }
  1648. sim->stop(resBREAKPOINT);
  1649. }
  1650. /*
  1651. * Errors
  1652. *----------------------------------------------------------------------------
  1653. */
  1654. cl_error_unknown_code::cl_error_unknown_code(class cl_uc *the_uc)
  1655. {
  1656. uc= the_uc;
  1657. classification= uc_error_registry.find("unknown_code");
  1658. }
  1659. void
  1660. cl_error_unknown_code::print(class cl_commander *c)
  1661. {
  1662. FILE *f= c->get_out();
  1663. cmd_fprintf(f, "%s: unknown instruction code at ", get_type_name());
  1664. if (uc->rom)
  1665. {
  1666. cmd_fprintf(f, uc->rom->addr_format, PC);
  1667. cmd_fprintf(f, " (");
  1668. cmd_fprintf(f, uc->rom->data_format, uc->rom->get(PC));
  1669. cmd_fprintf(f, ")");
  1670. }
  1671. else
  1672. cmd_fprintf(f, "0x%06x", PC);
  1673. cmd_fprintf(f, "\n");
  1674. }
  1675. cl_uc_error_registry::cl_uc_error_registry(void)
  1676. {
  1677. class cl_error_class *prev = uc_error_registry.find("non-classified");
  1678. prev = register_error(new cl_error_class(err_error, "unknown_code", prev, ERROR_OFF));
  1679. }
  1680. /* End of uc.cc */