00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef MIMA_H
00023 #define MIMA_H
00024
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028
00029 #include <string>
00030 #include <ostream>
00031 #include <map>
00032 #include <vector>
00033 #include <sigc++/sigc++.h>
00034
00035
00036
00037
00038
00039 typedef std::map<int, int> type_memory_map;
00040 typedef std::map<int, int>::iterator type_memory_map_iterator;
00041 typedef std::map<int, int>::const_iterator type_memory_map_const_iterator;
00042 typedef std::vector<int> type_breakpoint_list;
00043 typedef std::vector<int>::iterator type_breakpoint_list_iterator;
00044
00045
00046 namespace MimaSim {
00047 class Mima;
00048 class Cli;
00049 class AssConvert;
00050 }
00051
00053 std::ostream& operator<<(std::ostream& os, const MimaSim::Mima& mima);
00054
00056 std::istream& operator>>(std::istream& is, const MimaSim::Mima& mima);
00057
00059 namespace MimaSim {
00060
00061 enum State {
00062 RUNNING,
00063 STOPPED,
00064 STOPPED_ON_ERR
00065 };
00066
00067 enum ConvertError {
00068 UNKNOWN_MNEMONIC = -1,
00069 NO_ARG = -2,
00070 INVALID_ARG = -3
00071 };
00072
00074
00190 class Mima
00191 {
00192 private:
00193 struct TermCollect;
00194
00195
00196
00197
00198
00199 typedef sigc::signal<void> type_signal_void;
00200 typedef sigc::signal<void, int> type_signal_void_int;
00201 typedef sigc::signal<void, int, int> type_signal_void_int_int;
00202 typedef sigc::signal<void, int, char> type_signal_void_int_char;
00203 typedef sigc::signal<void, int, bool> type_signal_void_int_bool;
00204 typedef sigc::signal<void, State> type_signal_void_state;
00205 typedef sigc::signal<char, int> type_signal_char_int;
00206
00207 typedef sigc::signal<char, int>::accumulated<TermCollect> type_signal_char_int_termcollect;
00208
00209
00210
00211
00212
00214 class Counter
00215 {
00216 private:
00217
00218
00219
00220
00221 int m_value;
00222
00223 protected:
00224 type_signal_void_int m_signal_changed;
00225
00226 public:
00227 Counter() : m_value(0) {};
00228 ~Counter() {};
00229
00231 int get() const { return m_value; };
00232
00234 int inc();
00235
00237 bool reset();
00238
00240 type_signal_void_int signal_changed() { return m_signal_changed; };
00241
00242 };
00243
00245 class Register
00246 {
00247 private:
00248
00249
00250
00251
00252 int m_value;
00253
00254 protected:
00255 type_signal_void_int m_signal_changed;
00256
00257 public:
00258 Register() : m_value(0) {};
00259 ~Register() {};
00260
00262 int get() const { return m_value; };
00263
00265 bool set(int new_value);
00266
00268 int inc();
00269
00271 int dec();
00272
00274 int shr(int n = 1);
00275
00277 type_signal_void_int signal_changed() { return m_signal_changed; };
00278
00279 };
00280
00282
00299 class Memory
00300 {
00301 private:
00302 type_memory_map m_memory;
00303 int m_memsize;
00304
00305 protected:
00306 type_signal_void m_signal_clear;
00307 type_signal_void_int m_signal_memsize_changed;
00308 type_signal_void_int_int m_signal_value_changed;
00309 type_signal_void_int_bool m_signal_breakpoint_changed;
00310
00311 public:
00312 Memory(int memsize);
00313 ~Memory();
00314
00315 int get_memsize() const { return m_memsize; };
00317 bool set_memsize(int size);
00319 int get(int address);
00320 bool set(int address, int value);
00321 bool toggle_breakpoint(int address);
00322 bool get_breakpoint(int address);
00323 bool clear();
00324
00326 type_memory_map get(int start = 0, int end = -1) const;
00328 type_breakpoint_list get_breakpoints(int start = 0, int end = -1) const;
00329
00330 type_signal_void signal_clear() { return m_signal_clear; };
00331 type_signal_void_int signal_memsize_changed() { return m_signal_memsize_changed; };
00332 type_signal_void_int_int signal_value_changed() { return m_signal_value_changed; };
00333 type_signal_void_int_bool signal_breakpoint_changed() { return m_signal_breakpoint_changed; };
00334
00335 };
00336
00338
00343 struct TermCollect
00344 {
00345 typedef char result_type;
00346 template<typename T_iterator>
00347 result_type operator()(T_iterator first, T_iterator last) const
00348 {
00349 for (; first != last; ++first)
00350 if (*first != '\0') return *first;
00351 return '\0';
00352 }
00353 };
00354
00355
00356
00357
00358
00359 Register m_acc;
00360 Register m_iar;
00361 Counter m_counter;
00362 Memory m_memory;
00363 State m_state;
00364 int m_steps;
00365 bool m_ignore_breakpoint;
00366 Cli *m_cli;
00367
00368 protected:
00369
00370
00371
00372
00373 type_signal_void m_signal_quit;
00374 type_signal_void_state m_signal_state_changed;
00375 type_signal_void_int_char m_signal_out;
00376 type_signal_char_int_termcollect m_signal_in;
00377
00378
00379
00380
00381
00383 int sign_extend(int arg);
00384
00386 void increment_iar();
00387
00389 void decrement_iar();
00390
00392 void increment_counter();
00393
00395 void set_state(State state);
00396
00397 public:
00398 Mima(int memsize = DEFAULT_MEMSIZE);
00399 ~Mima();
00400
00401
00402
00403
00404
00406 type_signal_void signal_quit() { return m_signal_quit; };
00408 type_signal_void signal_memory_clear() { return m_memory.signal_clear(); };
00410 type_signal_void_int signal_acc_changed() { return m_acc.signal_changed(); };
00412 type_signal_void_int signal_iar_changed() { return m_iar.signal_changed(); };
00414 type_signal_void_int signal_counter_changed() { return m_counter.signal_changed(); };
00416 type_signal_void_int signal_memsize_changed() { return m_memory.signal_memsize_changed(); };
00418 type_signal_void_int_int signal_memory_value_changed() { return m_memory.signal_value_changed(); };
00420 type_signal_void_int_char signal_out() { return m_signal_out; };
00422 type_signal_char_int_termcollect signal_in() { return m_signal_in; };
00424 type_signal_void_int_bool signal_memory_breakpoint_changed() { return m_memory.signal_breakpoint_changed(); };
00426 type_signal_void_state signal_state_changed() { return m_signal_state_changed; };
00427
00428
00429
00430
00431
00433 void set_acc(int value);
00434
00436 void set_iar(int value);
00437
00439 void set_memsize(int size);
00440
00442 void set_memory(int address, int value);
00443
00445 void reset_counter();
00446
00448 void reset(bool full = false);
00449
00451 int get_acc() const
00452 { return m_acc.get(); };
00453
00455 int get_iar() const
00456 { return m_iar.get(); };
00457
00459 int get_counter() const
00460 { return m_counter.get(); };
00461
00463 int get_memsize() const
00464 { return m_memory.get_memsize(); };
00465
00467 int get_memory(int address)
00468 { return m_memory.get(address); };
00469
00470 Cli *get_cli()
00471 { return m_cli; }
00472
00474
00478 type_memory_map get_memory_map(int start = 0, int end = -1) const
00479 { return m_memory.get(start, end); };
00480
00482 type_breakpoint_list get_breakpoints() const
00483 { return m_memory.get_breakpoints(); };
00484
00486 bool toggle_breakpoint(int address)
00487 { return m_memory.toggle_breakpoint(address); };
00488
00490 bool get_breakpoint(int address)
00491 { return m_memory.get_breakpoint(address); };
00492
00494 void run(int steps = -1);
00495
00497 void clock();
00498
00500 void stop();
00501
00503 void quit();
00504
00505 };
00506
00508
00574 class Cli
00575 {
00576 private:
00577
00578
00579
00580
00581 class Command
00582 {
00583 public:
00584 Command(char *cmd_str);
00585 ~Command();
00586 char cmd;
00587 int arg1, arg2;
00588 };
00589
00590
00591
00592
00593
00594 Mima *m_mima;
00595
00596 protected:
00597
00598
00599
00600
00602 std::string step(Command cmd);
00603
00605 std::string dump_memory(Command cmd);
00606
00608 std::string set_memory(Command cmd);
00609
00611 std::string set_acc(Command cmd);
00612
00614 std::string set_iar(Command cmd);
00615
00617 std::string dump_state(Command cmd);
00618
00620 std::string run(Command cmd);
00621
00623 std::string reset(bool full = false);
00624
00626 std::string toggle_breakpoint(Command cmd);
00627
00629 std::string print_help();
00630
00631 public:
00632 Cli(Mima *mima) : m_mima(mima) {}
00633 ~Cli() {}
00634
00635
00636
00637
00638
00640 const char* execute(char *cmd_str);
00641
00642 };
00643
00645
00648 class AssConvert
00649 {
00650 private:
00651
00652
00653
00654
00655 Mima *m_mima;
00656
00657 protected:
00658
00659 public:
00660 AssConvert(Mima *_mima);
00661 ~AssConvert();
00662
00664 int ass2mem(std::istream& code, int address_start);
00665
00667 std::istream& mem2ass(int address_start, int len);
00668 };
00669
00670 }
00671 #endif // MIMA_H