PageRenderTime 61ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/version-0_4_1-pre5/sdcc/sim/ucsim/sim.src/uc.cc

#
C++ | 1611 lines | 1257 code | 206 blank | 148 comment | 196 complexity | 1cc74171500e97691f732c168680239c 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. // local, sim.src
  42. #include "uccl.h"
  43. #include "hwcl.h"
  44. #include "memcl.h"
  45. #include "simcl.h"
  46. #include "itsrccl.h"
  47. /*
  48. * Clock counter
  49. */
  50. cl_ticker::cl_ticker(int adir, int in_isr, char *aname)
  51. {
  52. options= TICK_RUN;
  53. if (in_isr)
  54. options|= TICK_INISR;
  55. dir= adir;
  56. ticks= 0;
  57. set_name(aname);
  58. }
  59. cl_ticker::~cl_ticker(void) {}
  60. int
  61. cl_ticker::tick(int nr)
  62. {
  63. if (options&TICK_RUN)
  64. ticks+= dir*nr;
  65. return(ticks);
  66. }
  67. double
  68. cl_ticker::get_rtime(double xtal)
  69. {
  70. double d;
  71. d= (double)ticks/xtal;
  72. return(d);
  73. }
  74. void
  75. cl_ticker::dump(int nr, double xtal, class cl_console *con)
  76. {
  77. con->dd_printf("timer #%d(\"%s\") %s%s: %g sec (%lu clks)\n",
  78. nr, get_name("unnamed"),
  79. (options&TICK_RUN)?"ON":"OFF",
  80. (options&TICK_INISR)?",ISR":"",
  81. get_rtime(xtal), ticks);
  82. }
  83. /*
  84. * Abstract microcontroller
  85. ******************************************************************************
  86. */
  87. cl_uc::cl_uc(class cl_sim *asim):
  88. cl_base()
  89. {
  90. int i;
  91. sim = asim;
  92. mems= new cl_list(MEM_TYPES, 1);
  93. hws = new cl_hws();
  94. //options= new cl_list(2, 2);
  95. for (i= MEM_ROM; i < MEM_TYPES; i++)
  96. mems->add(0);
  97. ticks= new cl_ticker(+1, 0, "time");
  98. isr_ticks= new cl_ticker(+1, TICK_INISR, "isr");
  99. idle_ticks= new cl_ticker(+1, TICK_IDLE, "idle");
  100. counters= new cl_list(2, 2);
  101. it_levels= new cl_list(2, 2);
  102. it_sources= new cl_irqs(2, 2);
  103. class it_level *il= new it_level(-1, 0, 0, 0);
  104. it_levels->push(il);
  105. st_ops= new cl_list(2, 2);
  106. errors= new cl_list(2, 2);
  107. events= new cl_list(2, 2);
  108. sp_max= 0;
  109. sp_avg= 0;
  110. inst_exec= DD_FALSE;
  111. }
  112. cl_uc::~cl_uc(void)
  113. {
  114. delete mems;
  115. delete hws;
  116. //delete options;
  117. delete ticks;
  118. delete isr_ticks;
  119. delete idle_ticks;
  120. delete counters;
  121. events->disconn_all();
  122. delete events;
  123. delete fbrk;
  124. delete ebrk;
  125. delete it_levels;
  126. delete it_sources;
  127. delete st_ops;
  128. errors->free_all();
  129. delete errors;
  130. }
  131. int
  132. cl_uc::init(void)
  133. {
  134. int mc, i;
  135. cl_base::init();
  136. if (!(sim->app->args->arg_avail('X')) ||
  137. sim->app->args->get_farg('X', 0) == 0)
  138. xtal= 11059200;
  139. else
  140. xtal= sim->app->args->get_farg('X', 0);
  141. for (mc= MEM_ROM; mc < MEM_TYPES; mc++)
  142. {
  143. class cl_mem *m= mk_mem((enum mem_class)mc,
  144. get_id_string(mem_classes, mc));
  145. mems->put_at(mc, m);
  146. }
  147. ebrk= new brk_coll(2, 2, /*(class cl_rom *)*/mem(MEM_ROM));
  148. fbrk= new brk_coll(2, 2, /*(class cl_rom *)*/mem(MEM_ROM));
  149. fbrk->Duplicates= DD_FALSE;
  150. brk_counter= 0;
  151. mk_hw_elements();
  152. reset();
  153. class cl_cmdset *cs= sim->app->get_commander()->cmdset;
  154. build_cmdset(cs);
  155. for (i= 0; i < sim->app->in_files->count; i++)
  156. {
  157. char *fname= (char *)(sim->app->in_files->at(i));
  158. long l;
  159. if ((l= read_hex_file(fname)) >= 0)
  160. {
  161. sim->app->get_commander()->all_printf("%ld words read from %s\n",
  162. l, fname);
  163. }
  164. }
  165. return(0);
  166. }
  167. char *
  168. cl_uc::id_string(void)
  169. {
  170. return("unknown microcontroller");
  171. }
  172. void
  173. cl_uc::reset(void)
  174. {
  175. class it_level *il;
  176. PC= 0;
  177. state = stGO;
  178. ticks->ticks= 0;
  179. isr_ticks->ticks= 0;
  180. idle_ticks->ticks= 0;
  181. /*FIXME should we clear user counters?*/
  182. il= (class it_level *)(it_levels->top());
  183. while (il &&
  184. il->level >= 0)
  185. {
  186. il= (class it_level *)(it_levels->pop());
  187. delete il;
  188. il= (class it_level *)(it_levels->top());
  189. }
  190. sp_max= 0;
  191. sp_avg= 0;
  192. int i;
  193. for (i= 0; i < hws->count; i++)
  194. {
  195. class cl_hw *hw= (class cl_hw *)(hws->at(i));
  196. hw->reset();
  197. }
  198. }
  199. /*
  200. * Making elements
  201. */
  202. class cl_mem *
  203. cl_uc::mk_mem(enum mem_class type, char *class_name)
  204. {
  205. class cl_mem *m;
  206. if (get_mem_size(type) < 0)
  207. return(0);
  208. m= new cl_m(type, get_id_string(mem_classes, type),
  209. get_mem_size(type), get_mem_width(type), this);
  210. m->init();
  211. return(m);
  212. }
  213. t_addr
  214. cl_uc::get_mem_size(enum mem_class type)
  215. {
  216. switch (type)
  217. {
  218. case MEM_ROM: return(0x10000);
  219. case MEM_XRAM: return(0x10000);
  220. case MEM_IRAM: return(0x80);
  221. case MEM_SFR: return(0x100);
  222. case MEM_TYPES:
  223. default: return(0);
  224. }
  225. return(0);
  226. }
  227. int
  228. cl_uc::get_mem_width(enum mem_class type)
  229. {
  230. return(8);
  231. }
  232. void
  233. cl_uc::mk_hw_elements(void)
  234. {
  235. }
  236. void
  237. cl_uc::build_cmdset(class cl_cmdset *cmdset)
  238. {
  239. class cl_cmd *cmd;
  240. class cl_super_cmd *super_cmd;
  241. class cl_cmdset *cset;
  242. cmdset->add(cmd= new cl_state_cmd("state", 0,
  243. "state State of microcontroller",
  244. "long help of state"));
  245. cmd->init();
  246. #ifdef STATISTIC
  247. cmdset->add(cmd= new cl_statistic_cmd("statistic", 0,
  248. "statistic [mem [startaddr [endaddr]]]\n"
  249. " Statistic of memory accesses",
  250. "long help of statistic"));
  251. cmd->init();
  252. #endif
  253. cmdset->add(cmd= new cl_file_cmd("file", 0,
  254. "file \"FILE\" Load FILE into ROM",
  255. "long help of file"));
  256. cmd->init();
  257. cmd->add_name("load");
  258. cmdset->add(cmd= new cl_dl_cmd("download", 0,
  259. "download,dl Load (intel.hex) data",
  260. "long help of download"));
  261. cmd->init();
  262. cmd->add_name("dl");
  263. cmdset->add(cmd= new cl_pc_cmd("pc", 0,
  264. "pc [addr] Set/get PC",
  265. "long help of pc"));
  266. cmd->init();
  267. cmdset->add(cmd= new cl_reset_cmd("reset", 0,
  268. "reset Reset",
  269. "long help of reset"));
  270. cmd->init();
  271. cmdset->add(cmd= new cl_dump_cmd("dump", 0,
  272. "dump memory_type [start [stop [bytes_per_line]]]\n"
  273. " Dump memory of specified type\n"
  274. "dump bit... Dump bits",
  275. "long help of dump"));
  276. cmd->init();
  277. cmdset->add(cmd= new cl_di_cmd("di", 0,
  278. "di [start [stop]] Dump Internal RAM",
  279. "long help of di"));
  280. cmd->init();
  281. cmdset->add(cmd= new cl_dx_cmd("dx", 0,
  282. "dx [start [stop]] Dump External RAM",
  283. "long help of dx"));
  284. cmd->init();
  285. cmdset->add(cmd= new cl_ds_cmd("ds", 0,
  286. "ds [start [stop]] Dump SFR",
  287. "long help of ds"));
  288. cmd->init();
  289. cmdset->add(cmd= new cl_dch_cmd("dch", 0,
  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", 0,
  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", 0,
  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. {
  395. cset= new cl_cmdset();
  396. cset->init();
  397. cset->add(cmd= new cl_info_bp_cmd("breakpoints", 0,
  398. "info breakpoints Status of user-settable breakpoints",
  399. "long help of info breakpoints"));
  400. cmd->add_name("bp");
  401. cmd->init();
  402. cset->add(cmd= new cl_info_reg_cmd("registers", 0,
  403. "info registers List of integer registers and their contents",
  404. "long help of info registers"));
  405. cmd->init();
  406. cset->add(cmd= new cl_info_hw_cmd("hardware", 0,
  407. "info hardware cathegory\n"
  408. " Status of hardware elements of the CPU",
  409. "long help of info hardware"));
  410. cmd->add_name("hw");
  411. cmd->init();
  412. }
  413. cmdset->add(cmd= new cl_super_cmd("info", 0,
  414. "info subcommand Information, see `info' command for more help",
  415. "long help of info", cset));
  416. cmd->init();
  417. cmdset->add(cmd= new cl_timer_cmd("timer", 0,
  418. "timer a|d|g|r|s|v id [direction|value]\n"
  419. " Timer add|del|get|run|stop|value",
  420. "timer add|create|make id [direction] -- create a new timer\n"
  421. "timer del id -- delete a timer\n"
  422. "timer get id -- list timers\n"
  423. "timer run id -- turn a timer ON\n"
  424. "timer stop id -- turn a timer OFF\n"
  425. "timer value id val -- set value of a timer to `val'"));
  426. cmd->init();
  427. }
  428. /*
  429. * Read/write simulated memory
  430. */
  431. t_mem
  432. cl_uc::read_mem(enum mem_class type, t_addr addr)
  433. {
  434. class cl_mem *m;
  435. if ((m= (class cl_mem*)mems->at(type)) == 0)
  436. m= (class cl_mem*)(mems->at(MEM_DUMMY));
  437. return(m->read(addr));
  438. }
  439. t_mem
  440. cl_uc::get_mem(enum mem_class type, t_addr addr)
  441. {
  442. class cl_mem *m;
  443. if ((m= (class cl_mem*)mems->at(type)) == 0)
  444. m= (class cl_mem*)(mems->at(MEM_DUMMY));
  445. return(m->get(addr));
  446. }
  447. void
  448. cl_uc::write_mem(enum mem_class type, t_addr addr, t_mem val)
  449. {
  450. class cl_mem *m;
  451. if ((m= (class cl_mem*)mems->at(type)) == 0)
  452. m= (class cl_mem*)(mems->at(MEM_DUMMY));
  453. m->write(addr, val);
  454. }
  455. void
  456. cl_uc::set_mem(enum mem_class type, t_addr addr, t_mem val)
  457. {
  458. class cl_mem *m;
  459. if ((m= (class cl_mem*)mems->at(type)) == 0)
  460. m= (class cl_mem*)(mems->at(MEM_DUMMY));
  461. m->set(addr, val);
  462. }
  463. class cl_mem *
  464. cl_uc::mem(enum mem_class type)
  465. {
  466. class cl_mem *m;
  467. if (mems->count < type)
  468. m= (class cl_mem *)(mems->at(MEM_DUMMY));
  469. else
  470. m= (class cl_mem *)(mems->at(type));
  471. return(m);
  472. }
  473. class cl_mem *
  474. cl_uc::mem(char *class_name)
  475. {
  476. int i, found= 0;
  477. char *mcn, *n, *s;
  478. if (!class_name)
  479. return(0);
  480. s= n= strdup(class_name);
  481. while (*s)
  482. {
  483. *s= toupper(*s);
  484. s++;
  485. }
  486. if (!class_name ||
  487. !(*class_name))
  488. return(0);
  489. for (i= 0; !found && i < mems->count; i++)
  490. {
  491. cl_mem *m= (cl_mem *)(mems->at(i));
  492. if (!m ||
  493. !m->class_name ||
  494. !(*(m->class_name)))
  495. continue;
  496. s= mcn= strdup(m->class_name);
  497. while (*s)
  498. {
  499. *s= toupper(*s);
  500. s++;
  501. }
  502. if (strstr(/*m->class_name*/mcn,/*class_name*/n) == /*m->class_name*/mcn)
  503. found= 1;
  504. free(mcn);
  505. if (found)
  506. {
  507. free(n);
  508. return(m);
  509. }
  510. }
  511. free(n);
  512. return(0);
  513. }
  514. static long
  515. ReadInt(FILE *f, bool *ok, int bytes)
  516. {
  517. char s2[3];
  518. long l= 0;
  519. *ok= DD_FALSE;
  520. while (bytes)
  521. {
  522. if (fscanf(f, "%2c", &s2[0]) == EOF)
  523. return(0);
  524. s2[2]= '\0';
  525. l= l*256 + strtol(s2, NULL, 16);
  526. bytes--;
  527. }
  528. *ok= DD_TRUE;
  529. return(l);
  530. }
  531. /*
  532. * Reading intel hexa file into EROM
  533. *____________________________________________________________________________
  534. *
  535. * If parameter is a NULL pointer, this function reads data from `cmd_in'
  536. *
  537. */
  538. long
  539. cl_uc::read_hex_file(const char *nam)
  540. {
  541. FILE *f;
  542. int c;
  543. long written= 0, recnum= 0;
  544. uchar dnum; // data number
  545. uchar rtyp=0; // record type
  546. uint addr= 0; // address
  547. uchar rec[300]; // data record
  548. uchar sum ; // checksum
  549. uchar chk ; // check
  550. int i;
  551. bool ok, get_low= 1;
  552. uchar low= 0, high;
  553. if (!nam)
  554. {
  555. sim->app->get_commander()->
  556. dd_printf("cl_uc::read_hex_file File name not specified\n");
  557. return(-1);
  558. }
  559. else
  560. if ((f= fopen(nam, "r")) == NULL)
  561. {
  562. fprintf(stderr, "Can't open `%s': %s\n", nam, strerror(errno));
  563. return(-1);
  564. }
  565. //memset(inst_map, '\0', sizeof(inst_map));
  566. ok= DD_TRUE;
  567. while (ok &&
  568. rtyp != 1)
  569. {
  570. while (((c= getc(f)) != ':') &&
  571. (c != EOF)) ;
  572. if (c != ':')
  573. {fprintf(stderr, ": not found\n");break;}
  574. recnum++;
  575. dnum= ReadInt(f, &ok, 1);//printf("dnum=%02x",dnum);
  576. chk = dnum;
  577. addr= ReadInt(f, &ok, 2);//printf("addr=%04x",addr);
  578. chk+= (addr & 0xff);
  579. chk+= ((addr >> 8) & 0xff);
  580. rtyp= ReadInt(f, &ok, 1);//printf("rtyp=%02x ",rtyp);
  581. chk+= rtyp;
  582. for (i= 0; ok && (i < dnum); i++)
  583. {
  584. rec[i]= ReadInt(f, &ok, 1);//printf("%02x",rec[i]);
  585. chk+= rec[i];
  586. }
  587. if (ok)
  588. {
  589. sum= ReadInt(f, &ok, 1);//printf(" sum=%02x\n",sum);
  590. if (ok)
  591. {
  592. if (((sum + chk) & 0xff) == 0)
  593. {
  594. if (rtyp == 0)
  595. {
  596. if (get_mem_width(MEM_ROM) > 8)
  597. addr/= 2;
  598. for (i= 0; i < dnum; i++)
  599. {
  600. if (get_mem_width(MEM_ROM) <= 8)
  601. {
  602. set_mem(MEM_ROM, addr, rec[i]);
  603. addr++;
  604. written++;
  605. }
  606. else if (get_mem_width(MEM_ROM) <= 16)
  607. {
  608. if (get_low)
  609. {
  610. low= rec[i];
  611. get_low= 0;
  612. }
  613. else
  614. {
  615. high= rec[i];
  616. set_mem(MEM_ROM, addr, (high*256)+low);
  617. addr++;
  618. written++;
  619. get_low= 1;
  620. }
  621. }
  622. }
  623. }
  624. else
  625. if (sim->app->args->get_iarg('V', 0) &&
  626. rtyp != 1)
  627. sim->app->get_commander()->
  628. dd_printf("Unknown record type %d(0x%x)\n", rtyp, rtyp);
  629. }
  630. else
  631. if (sim->app->args->get_iarg('V', 0))
  632. sim->app->get_commander()->
  633. dd_printf("Checksum error (%x instead of %x) in "
  634. "record %ld.\n", chk, sum, recnum);
  635. }
  636. else
  637. if (sim->app->args->get_iarg('V', 0))
  638. sim->app->get_commander()->
  639. dd_printf("Read error in record %ld.\n", recnum);
  640. }
  641. }
  642. if (get_mem_width(MEM_ROM) > 8 &&
  643. !get_low)
  644. set_mem(MEM_ROM, addr, low);
  645. if (nam)
  646. fclose(f);
  647. if (sim->app->args->get_iarg('V', 0))
  648. sim->app->get_commander()->dd_printf("%ld records have been read\n", recnum);
  649. analyze(0);
  650. return(written);
  651. }
  652. /*
  653. * Handling instruction map
  654. *
  655. * `inst_at' is checking if the specified address is in instruction
  656. * map and `set_inst_at' marks the address in the map and
  657. * `del_inst_at' deletes the mark. `there_is_inst' cheks if there is
  658. * any mark in the map
  659. */
  660. bool
  661. cl_uc::inst_at(t_addr addr)
  662. {
  663. class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
  664. if (!rom)
  665. return(0);
  666. //return(rom->inst_map->get(addr));
  667. return(rom->get_cell_flag(addr, CELL_INST));
  668. }
  669. void
  670. cl_uc::set_inst_at(t_addr addr)
  671. {
  672. class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
  673. if (rom)
  674. //rom->inst_map->set(addr);
  675. rom->set_cell_flag(addr, DD_TRUE, CELL_INST);
  676. }
  677. void
  678. cl_uc::del_inst_at(t_addr addr)
  679. {
  680. class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
  681. if (rom)
  682. //rom->inst_map->clear(addr);
  683. rom->set_cell_flag(addr, DD_FALSE, CELL_INST);
  684. }
  685. bool
  686. cl_uc::there_is_inst(void)
  687. {
  688. class cl_mem/*rom*/ *rom= /*(class cl_rom *)*/mem(MEM_ROM);
  689. if (!rom)
  690. return(0);
  691. //return(!(rom->inst_map->empty()));
  692. bool got= DD_FALSE;
  693. t_addr addr;
  694. for (addr= 0; addr < rom->size && !got; addr++)
  695. got= rom->get_cell_flag(addr, CELL_INST);
  696. return(got);
  697. }
  698. /*
  699. * Manipulating HW elements of the CPU
  700. *****************************************************************************
  701. */
  702. /* Register callback hw objects for mem read/write */
  703. /*void
  704. cl_uc::register_hw_read(enum mem_class type, t_addr addr, class cl_hw *hw)
  705. {
  706. class cl_mem *m;
  707. class cl_memloc *l;
  708. if ((m= (class cl_mem*)mems->at(type)))
  709. {
  710. if ((l= m->read_locs->get_loc(addr)) == 0)
  711. {
  712. l= new cl_memloc(addr);
  713. l->init();
  714. m->read_locs->add(l);
  715. }
  716. l->hws->add(hw);
  717. }
  718. else
  719. printf("cl_uc::register_hw_read TROUBLE\n");
  720. }*/
  721. /*void
  722. cl_uc::register_hw_write(enum mem_class type, t_addr addr, class cl_hw *hw)
  723. {
  724. }*/
  725. /* Looking for a specific HW element */
  726. class cl_hw *
  727. cl_uc::get_hw(enum hw_cath cath, int *idx)
  728. {
  729. class cl_hw *hw= 0;
  730. int i= 0;
  731. if (idx)
  732. i= *idx;
  733. for (; i < hws->count; i++)
  734. {
  735. hw= (class cl_hw *)(hws->at(i));
  736. if (hw->cathegory == cath)
  737. break;
  738. }
  739. if (i >= hws->count)
  740. return(0);
  741. if (idx)
  742. *idx= i;
  743. return(hw);
  744. }
  745. class cl_hw *
  746. cl_uc::get_hw(char *id_string, int *idx)
  747. {
  748. class cl_hw *hw= 0;
  749. int i= 0;
  750. if (idx)
  751. i= *idx;
  752. for (; i < hws->count; i++)
  753. {
  754. hw= (class cl_hw *)(hws->at(i));
  755. if (strstr(hw->id_string, id_string) == hw->id_string)
  756. break;
  757. }
  758. if (i >= hws->count)
  759. return(0);
  760. if (idx)
  761. *idx= i;
  762. return(hw);
  763. }
  764. class cl_hw *
  765. cl_uc::get_hw(enum hw_cath cath, int hwid, int *idx)
  766. {
  767. class cl_hw *hw;
  768. int i= 0;
  769. if (idx)
  770. i= *idx;
  771. hw= get_hw(cath, &i);
  772. while (hw &&
  773. hw->id != hwid)
  774. {
  775. i++;
  776. hw= get_hw(cath, &i);
  777. }
  778. if (hw &&
  779. idx)
  780. *idx= i;
  781. return(hw);
  782. }
  783. class cl_hw *
  784. cl_uc::get_hw(char *id_string, int hwid, int *idx)
  785. {
  786. class cl_hw *hw;
  787. int i= 0;
  788. if (idx)
  789. i= *idx;
  790. hw= get_hw(id_string, &i);
  791. while (hw &&
  792. hw->id != hwid)
  793. {
  794. i++;
  795. hw= get_hw(id_string, &i);
  796. }
  797. if (hw &&
  798. idx)
  799. *idx= i;
  800. return(hw);
  801. }
  802. /*
  803. * Help of the command interpreter
  804. */
  805. struct dis_entry *
  806. cl_uc::dis_tbl(void)
  807. {
  808. static struct dis_entry empty= { 0, 0, 0, 0, NULL };
  809. return(&empty);
  810. }
  811. struct name_entry *
  812. cl_uc::sfr_tbl(void)
  813. {
  814. static struct name_entry empty= { 0, 0 };
  815. return(&empty);
  816. }
  817. struct name_entry *
  818. cl_uc::bit_tbl(void)
  819. {
  820. static struct name_entry empty= { 0, 0 };
  821. return(&empty);
  822. }
  823. char *
  824. cl_uc::disass(t_addr addr, char *sep)
  825. {
  826. char *buf;
  827. buf= (char*)malloc(100);
  828. strcpy(buf, "uc::disass() unimplemented\n");
  829. return(buf);
  830. }
  831. void
  832. cl_uc::print_disass(t_addr addr, class cl_console *con)
  833. {
  834. char *dis;
  835. class cl_brk *b;
  836. int i;
  837. class cl_mem *rom= mem(MEM_ROM);
  838. t_mem code= get_mem(MEM_ROM, addr);
  839. if (!rom)
  840. return;
  841. b= fbrk_at(addr);
  842. dis= disass(addr, NULL);
  843. if (b)
  844. con->dd_printf("%c", (b->perm == brkFIX)?'F':'D');
  845. else
  846. con->dd_printf(" ");
  847. con->dd_printf("%c ", inst_at(addr)?' ':'?');
  848. con->dd_printf(rom->addr_format, addr); con->dd_printf(" ");
  849. con->dd_printf(rom->data_format, code);
  850. for (i= 1; i < inst_length(addr); i++)
  851. {
  852. con->dd_printf(" ");
  853. con->dd_printf(rom->data_format, get_mem(MEM_ROM, addr+i));
  854. }
  855. int li= longest_inst();
  856. while (i < li)
  857. {
  858. int j;
  859. j= rom->width/4 + ((rom->width%4)?1:0) + 1;
  860. while (j)
  861. con->dd_printf(" "), j--;
  862. i++;
  863. }
  864. con->dd_printf(" %s\n", dis);
  865. free(dis);
  866. }
  867. void
  868. cl_uc::print_regs(class cl_console *con)
  869. {
  870. con->dd_printf("No registers\n");
  871. }
  872. int
  873. cl_uc::inst_length(t_addr addr)
  874. {
  875. struct dis_entry *tabl= dis_tbl();
  876. int i;
  877. t_mem code;
  878. code = get_mem(MEM_ROM, addr);
  879. for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++) ;
  880. return(tabl[i].mnemonic?tabl[i].length:1);
  881. }
  882. int
  883. cl_uc::inst_branch(t_addr addr)
  884. {
  885. struct dis_entry *tabl= dis_tbl();
  886. int i;
  887. t_mem code;
  888. code = get_mem(MEM_ROM, addr);
  889. for (i= 0; tabl[i].mnemonic && (code & tabl[i].mask) != tabl[i].code; i++)
  890. ;
  891. return tabl[i].branch;
  892. }
  893. int
  894. cl_uc::longest_inst(void)
  895. {
  896. struct dis_entry *de= dis_tbl();
  897. int max= 0;
  898. while (de &&
  899. de->mnemonic)
  900. {
  901. if (de->length > max)
  902. max= de->length;
  903. de++;
  904. }
  905. return(max);
  906. }
  907. bool
  908. cl_uc::get_name(t_addr addr, struct name_entry tab[], char *buf)
  909. {
  910. int i;
  911. i= 0;
  912. while (tab[i].name &&
  913. (!(tab[i].cpu_type & type) ||
  914. (tab[i].addr != addr)))
  915. i++;
  916. if (tab[i].name)
  917. strcpy(buf, tab[i].name);
  918. return(tab[i].name != NULL);
  919. }
  920. char *
  921. cl_uc::symbolic_bit_name(t_addr bit_address,
  922. class cl_mem *mem,
  923. t_addr mem_addr,
  924. t_mem bit_mask)
  925. {
  926. char *sym_name= 0;
  927. int i;
  928. i= 0;
  929. while (bit_tbl()[i].name &&
  930. (bit_tbl()[i].addr != bit_address))
  931. i++;
  932. if (bit_tbl()[i].name)
  933. {
  934. sym_name= strdup(bit_tbl()[i].name);
  935. return(sym_name);
  936. }
  937. if (mem &&
  938. mem->class_name &&
  939. strstr(mem->class_name, "sfr") == mem->class_name)
  940. {
  941. i= 0;
  942. while (sfr_tbl()[i].name &&
  943. (sfr_tbl()[i].addr != mem_addr))
  944. i++;
  945. if (sfr_tbl()[i].name)
  946. sym_name= strdup(sfr_tbl()[i].name);
  947. else
  948. sym_name= 0;
  949. }
  950. if (!sym_name)
  951. {
  952. sym_name= (char *)malloc(16);
  953. sprintf(sym_name, mem?(mem->addr_format):"0x%06x", mem_addr);
  954. }
  955. sym_name= (char *)realloc(sym_name, strlen(sym_name)+2);
  956. strcat(sym_name, ".");
  957. i= 0;
  958. while (bit_mask > 1)
  959. {
  960. bit_mask>>=1;
  961. i++;
  962. }
  963. char bitnumstr[10];
  964. sprintf(bitnumstr, "%1d", i);
  965. strcat(sym_name, bitnumstr);
  966. return(sym_name);
  967. }
  968. /*
  969. * Messages to broadcast
  970. */
  971. void
  972. cl_uc::mem_cell_changed(class cl_mem *mem, t_addr addr)
  973. {
  974. if (hws)
  975. hws->mem_cell_changed(mem, addr);
  976. else
  977. printf("JAJ uc\n");//FIXME
  978. if (mems &&
  979. mems->count)
  980. {
  981. int i;
  982. for (i= 0; i < mems->count; i++)
  983. {
  984. }
  985. }
  986. }
  987. /*
  988. * Error handling
  989. */
  990. void
  991. cl_uc::error(class cl_error *error)
  992. {
  993. errors->add(error);
  994. if ((error->inst= inst_exec))
  995. error->PC= instPC;
  996. }
  997. void
  998. cl_uc::check_errors(void)
  999. {
  1000. int i;
  1001. class cl_commander *c= sim->app->get_commander();
  1002. if (c)
  1003. {
  1004. for (i= 0; i < errors->count; i++)
  1005. {
  1006. class cl_error *error= (class cl_error *)(errors->at(i));
  1007. error->print(c);
  1008. if (error->inst)
  1009. {
  1010. class cl_console *con;
  1011. con= c->actual_console;
  1012. if (!con)
  1013. con= c->frozen_console;
  1014. if (con)
  1015. print_disass(error->PC, con);
  1016. }
  1017. }
  1018. errors->free_all();
  1019. }
  1020. else
  1021. fprintf(stderr, "no actual console, %d errors\n", errors->count);
  1022. }
  1023. /*
  1024. * Converting bit address into real memory
  1025. */
  1026. class cl_mem *
  1027. cl_uc::bit2mem(t_addr bitaddr, t_addr *memaddr, t_mem *bitmask)
  1028. {
  1029. if (memaddr)
  1030. *memaddr= bitaddr;
  1031. if (bitmask)
  1032. *bitmask= 1 << (bitaddr & 0x7);
  1033. return(0); // abstract...
  1034. }
  1035. /*
  1036. * Execution
  1037. */
  1038. int
  1039. cl_uc::tick_hw(int cycles)
  1040. {
  1041. class cl_hw *hw;
  1042. int i;//, cpc= clock_per_cycle();
  1043. // tick hws
  1044. for (i= 0; i < hws->count; i++)
  1045. {
  1046. hw= (class cl_hw *)(hws->at(i));
  1047. if (hw->flags & HWF_INSIDE)
  1048. hw->tick(cycles);
  1049. }
  1050. do_extra_hw(cycles);
  1051. return(0);
  1052. }
  1053. void
  1054. cl_uc::do_extra_hw(int cycles)
  1055. {}
  1056. int
  1057. cl_uc::tick(int cycles)
  1058. {
  1059. //class cl_hw *hw;
  1060. int i, cpc= clock_per_cycle();
  1061. // increase time
  1062. ticks->tick(cycles * cpc);
  1063. class it_level *il= (class it_level *)(it_levels->top());
  1064. if (il->level >= 0)
  1065. isr_ticks->tick(cycles * cpc);
  1066. if (state == stIDLE)
  1067. idle_ticks->tick(cycles * cpc);
  1068. for (i= 0; i < counters->count; i++)
  1069. {
  1070. class cl_ticker *t= (class cl_ticker *)(counters->at(i));
  1071. if (t)
  1072. {
  1073. if ((t->options&TICK_INISR) ||
  1074. il->level < 0)
  1075. t->tick(cycles * cpc);
  1076. }
  1077. }
  1078. // tick for hardwares
  1079. inst_ticks+= cycles;
  1080. return(0);
  1081. }
  1082. class cl_ticker *
  1083. cl_uc::get_counter(int nr)
  1084. {
  1085. if (nr >= counters->count)
  1086. return(0);
  1087. return((class cl_ticker *)(counters->at(nr)));
  1088. }
  1089. class cl_ticker *
  1090. cl_uc::get_counter(char *nam)
  1091. {
  1092. int i;
  1093. if (!nam)
  1094. return(0);
  1095. for (i= 0; i < counters->count; i++)
  1096. {
  1097. class cl_ticker *t= (class cl_ticker *)(counters->at(i));
  1098. if (t &&
  1099. t->get_name() &&
  1100. strcmp(t->get_name(), nam) == 0)
  1101. return(t);
  1102. }
  1103. return(0);
  1104. }
  1105. void
  1106. cl_uc::add_counter(class cl_ticker *ticker, int nr)
  1107. {
  1108. while (counters->count <= nr)
  1109. counters->add(0);
  1110. counters->put_at(nr, ticker);
  1111. }
  1112. void
  1113. cl_uc::add_counter(class cl_ticker *ticker, char */*nam*/)
  1114. {
  1115. int i;
  1116. if (counters->count < 1)
  1117. counters->add(0);
  1118. for (i= 1; i < counters->count; i++)
  1119. {
  1120. class cl_ticker *t= (class cl_ticker *)(counters->at(i));
  1121. if (!t)
  1122. {
  1123. counters->put_at(i, ticker);
  1124. return;
  1125. }
  1126. }
  1127. counters->add(ticker);
  1128. }
  1129. void
  1130. cl_uc::del_counter(int nr)
  1131. {
  1132. class cl_ticker *t;
  1133. if (nr >= counters->count)
  1134. return;
  1135. if ((t= (class cl_ticker *)(counters->at(0))) != 0)
  1136. delete t;
  1137. counters->put_at(nr, 0);
  1138. }
  1139. void
  1140. cl_uc::del_counter(char *nam)
  1141. {
  1142. int i;
  1143. if (!nam)
  1144. return;
  1145. for (i= 0; i < counters->count; i++)
  1146. {
  1147. class cl_ticker *t= (class cl_ticker *)(counters->at(i));
  1148. if (t &&
  1149. t->get_name() &&
  1150. strcmp(t->get_name(), nam) == 0)
  1151. {
  1152. delete t;
  1153. counters->put_at(i, 0);
  1154. return;
  1155. }
  1156. }
  1157. }
  1158. /*
  1159. * Fetch without checking for breakpoint hit
  1160. */
  1161. t_mem
  1162. cl_uc::fetch(void)
  1163. {
  1164. ulong code;
  1165. code= read_mem(MEM_ROM, PC);
  1166. PC++;
  1167. if (PC >= get_mem_size(MEM_ROM))
  1168. PC= 0;
  1169. return(code);
  1170. }
  1171. /*
  1172. * Fetch but checking for breakpoint hit first, returns TRUE if
  1173. * a breakpoint is hit
  1174. */
  1175. bool
  1176. cl_uc::fetch(t_mem *code)
  1177. {
  1178. class cl_brk *brk;
  1179. int idx;
  1180. if (!code)
  1181. return(0);
  1182. if (sim->state & SIM_GO)
  1183. {
  1184. if (mem(MEM_ROM)->get_cell_flag(PC, CELL_FETCH_BRK) &&
  1185. (brk= fbrk->get_bp(PC, &idx)) &&
  1186. (brk->do_hit()))
  1187. {
  1188. if (brk->perm == brkDYNAMIC)
  1189. fbrk->del_bp(PC);
  1190. return(1);
  1191. }
  1192. }
  1193. *code= fetch();
  1194. return(0);
  1195. }
  1196. int
  1197. cl_uc::do_inst(int step)
  1198. {
  1199. int res= resGO;
  1200. if (step < 0)
  1201. step= 1;
  1202. while (step-- &&
  1203. res == resGO)
  1204. {
  1205. pre_inst();
  1206. res= exec_inst();
  1207. post_inst();
  1208. }
  1209. if (res != resGO)
  1210. sim->stop(res);
  1211. return(res);
  1212. }
  1213. void
  1214. cl_uc::pre_inst(void)
  1215. {
  1216. inst_exec= DD_TRUE;
  1217. inst_ticks= 0;
  1218. events->disconn_all();
  1219. }
  1220. int
  1221. cl_uc::exec_inst(void)
  1222. {
  1223. instPC= PC;
  1224. return(resGO);
  1225. }
  1226. void
  1227. cl_uc::post_inst(void)
  1228. {
  1229. tick_hw(inst_ticks);
  1230. if (errors->count)
  1231. check_errors();
  1232. if (events->count)
  1233. check_events();
  1234. inst_exec= DD_FALSE;
  1235. }
  1236. /*
  1237. * Time related functions
  1238. */
  1239. double
  1240. cl_uc::get_rtime(void)
  1241. {
  1242. /* double d;
  1243. d= (double)ticks/xtal;
  1244. return(d);*/
  1245. return(ticks->get_rtime(xtal));
  1246. }
  1247. int
  1248. cl_uc::clock_per_cycle(void)
  1249. {
  1250. return(1);
  1251. }
  1252. /*
  1253. * Stack tracking system
  1254. */
  1255. void
  1256. cl_uc::st_push(class cl_stack_op *op)
  1257. {
  1258. st_ops->push(op);
  1259. }
  1260. void
  1261. cl_uc::st_call(class cl_stack_op *op)
  1262. {
  1263. st_ops->push(op);
  1264. }
  1265. int
  1266. cl_uc::st_pop(class cl_stack_op *op)
  1267. {
  1268. class cl_stack_op *sop= (class cl_stack_op *)(st_ops->pop());
  1269. if (!sop)
  1270. return(1);
  1271. return(0);
  1272. }
  1273. int
  1274. cl_uc::st_ret(class cl_stack_op *op)
  1275. {
  1276. class cl_stack_op *sop= (class cl_stack_op *)(st_ops->pop());
  1277. if (!sop)
  1278. return(1);
  1279. return(0);
  1280. }
  1281. /*
  1282. * Breakpoint handling
  1283. */
  1284. class cl_fetch_brk *
  1285. cl_uc::fbrk_at(t_addr addr)
  1286. {
  1287. int idx;
  1288. return((class cl_fetch_brk *)(fbrk->get_bp(addr, &idx)));
  1289. }
  1290. class cl_ev_brk *
  1291. cl_uc::ebrk_at(t_addr addr, char *id)
  1292. {
  1293. int i;
  1294. class cl_ev_brk *eb;
  1295. for (i= 0; i < ebrk->count; i++)
  1296. {
  1297. eb= (class cl_ev_brk *)(ebrk->at(i));
  1298. if (eb->addr == addr &&
  1299. !strcmp(eb->id, id))
  1300. return(eb);
  1301. }
  1302. return(0);
  1303. }
  1304. /*void
  1305. cl_uc::rm_fbrk(long addr)
  1306. {
  1307. fbrk->del_bp(addr);
  1308. }*/
  1309. /* Get a breakpoint specified by its number */
  1310. class cl_brk *
  1311. cl_uc::brk_by_nr(int nr)
  1312. {
  1313. class cl_brk *bp;
  1314. if ((bp= fbrk->get_bp(nr)))
  1315. return(bp);
  1316. if ((bp= ebrk->get_bp(nr)))
  1317. return(bp);
  1318. return(0);
  1319. }
  1320. /* Get a breakpoint from the specified collection by its number */
  1321. class cl_brk *
  1322. cl_uc::brk_by_nr(class brk_coll *bpcoll, int nr)
  1323. {
  1324. class cl_brk *bp;
  1325. if ((bp= bpcoll->get_bp(nr)))
  1326. return(bp);
  1327. return(0);
  1328. }
  1329. /* Remove an event breakpoint specified by its address and id */
  1330. void
  1331. cl_uc::rm_ebrk(t_addr addr, char *id)
  1332. {
  1333. int i;
  1334. class cl_ev_brk *eb;
  1335. for (i= 0; i < ebrk->count; i++)
  1336. {
  1337. eb= (class cl_ev_brk *)(ebrk->at(i));
  1338. if (eb->addr == addr &&
  1339. !strcmp(eb->id, id))
  1340. ebrk->del_bp(i, 0);
  1341. }
  1342. }
  1343. /* Remove a breakpoint specified by its number */
  1344. bool
  1345. cl_uc::rm_brk(int nr)
  1346. {
  1347. class cl_brk *bp;
  1348. if ((bp= brk_by_nr(fbrk, nr)))
  1349. {
  1350. fbrk->del_bp(bp->addr);
  1351. return(DD_TRUE);
  1352. }
  1353. else if ((bp= brk_by_nr(ebrk, nr)))
  1354. {
  1355. ebrk->del_bp(ebrk->index_of(bp), 0);
  1356. return(DD_TRUE);
  1357. }
  1358. return(DD_FALSE);
  1359. }
  1360. void
  1361. cl_uc::put_breaks(void)
  1362. {}
  1363. /* Remove all fetch and event breakpoints */
  1364. void
  1365. cl_uc::remove_all_breaks(void)
  1366. {
  1367. while (fbrk->count)
  1368. {
  1369. class cl_brk *brk= (class cl_brk *)(fbrk->at(0));
  1370. fbrk->del_bp(brk->addr);
  1371. }
  1372. while (ebrk->count)
  1373. ebrk->del_bp(ebrk->count-1, 0);
  1374. }
  1375. int
  1376. cl_uc::make_new_brknr(void)
  1377. {
  1378. if (brk_counter == 0)
  1379. return(brk_counter= 1);
  1380. if (fbrk->count == 0 &&
  1381. ebrk->count == 0)
  1382. return(brk_counter= 1);
  1383. return(++brk_counter);
  1384. }
  1385. class cl_ev_brk *
  1386. cl_uc::mk_ebrk(enum brk_perm perm, class cl_mem *mem,
  1387. char op, t_addr addr, int hit)
  1388. {
  1389. class cl_ev_brk *b;
  1390. op= toupper(op);
  1391. b= new cl_ev_brk(mem, make_new_brknr(), addr, perm, hit, op);
  1392. b->init();
  1393. return(b);
  1394. }
  1395. void
  1396. cl_uc::check_events(void)
  1397. {
  1398. sim->stop(resBREAKPOINT);
  1399. }
  1400. /* End of uc.cc */