PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/sdcc-290-pre1/sdcc/sim/ucsim/sim.src/uc.cc

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