From 9ca2fc55a73aa8775c5f90bfe051b23d4fd78580 Mon Sep 17 00:00:00 2001 From: Brandon Date: Mon, 24 Sep 2018 03:36:31 -0700 Subject: [PATCH] Expose setup_replay behind a ifdef guard. The ifdef guard isn't set up TO BE CONTINUED --- pylc3/PyLC3.cpp | 26 +++++++++++++++++++++++++ pylc3/PyLC3.hpp | 30 +++++++++++++++-------------- pylc3/cli/comp.py | 48 +++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 82 insertions(+), 22 deletions(-) diff --git a/pylc3/PyLC3.cpp b/pylc3/PyLC3.cpp index 91cbfc9..8a8da5a 100644 --- a/pylc3/PyLC3.cpp +++ b/pylc3/PyLC3.cpp @@ -69,3 +69,29 @@ bool LC3State::loadCode(const std::string& code) } return true; } + +#ifdef HAVE_LC3_REPLAY +#include +void LC3State::setup_replay(const std::string& file, const std::string& replay_str) +{ + try + { + lc3_setup_replay(state, file, replay_str, in); + state.input = ∈ + return "" + } + catch(std::string err) + { + return err; + } + catch(const char* str) + { + return err; + } +} +#else +std::string LC3State::setup_replay(const std::string& file, const std::string& replay_str) +{ + return "NOT IMPLEMENTED"; +} +#endif diff --git a/pylc3/PyLC3.hpp b/pylc3/PyLC3.hpp index d6c0284..e98d73b 100644 --- a/pylc3/PyLC3.hpp +++ b/pylc3/PyLC3.hpp @@ -13,10 +13,10 @@ class LC3State * @param testing_mode Collect extra metrics and disable stdin and stdout. */ explicit LC3State(bool testing_mode = false) : testing(testing_mode) - { + { lc3_init(state); }; - /** @see lc3_init + /** @see lc3_init * @param randomize Enable randomizing of both memory and registers. * @param fill_value If randomize is false the value for every single memory address and register. */ @@ -24,7 +24,7 @@ class LC3State { lc3_init(state, randomize, randomize, fill_value, fill_value); } - /** @see lc3_assemble + /** @see lc3_assemble * @param filename Full path of the file to load. * @param disable_plugins True to disable lc3 plugins. * @param process_debug_comments True to enable processing of @ statements in comments. @@ -50,8 +50,8 @@ class LC3State /** @see lc3_finish */ void finish() { state.halted = 0 ; lc3_finish(state); } /** @see lc3_next_line */ - void next_line(unsigned int num = 0) - { + void next_line(unsigned int num = 0) + { state.halted = 0; for (unsigned int i = 0; i < num; i++) lc3_next_line(state); @@ -71,7 +71,7 @@ class LC3State int lookup(const std::string& symbol) { return lc3_sym_lookup(state, symbol); } /** @see lc3_sym_rev_lookup */ const std::string reverse_lookup(unsigned short address) { return lc3_sym_rev_lookup(state, address); } - + /** Gets value at address, note that the difference between this and memory_read is that memory_read will trigger plugins and devices */ int get_memory(unsigned short address) const { return state.mem[address]; } @@ -79,19 +79,19 @@ class LC3State void set_memory(unsigned short address, int value) { state.mem[address] = value; } /** @see lc3_disassemble */ - const std::string disassemble(unsigned short address, int level) - { + const std::string disassemble(unsigned short address, int level) + { ///TODO remove disassemble's accessing of state.pc it should assume the address where it is located is the "pc" unsigned short pc = state.pc; state.pc = address + 1; - const std::string ret = lc3_disassemble(state, state.mem[address], level); + const std::string ret = lc3_disassemble(state, state.mem[address], level); state.pc = pc; return ret; } /** @see lc3_disassemble */ - const std::string disassemble_data(unsigned short data, int level) - { - return lc3_disassemble(state, data, level); + const std::string disassemble_data(unsigned short data, int level) + { + return lc3_disassemble(state, data, level); } /** @see lc3_add_break */ bool add_breakpoint(unsigned short address, const std::string& condition = "1", int times = -1, const std::string& label = "") { return lc3_add_break(state, address, label, condition, times); } @@ -127,7 +127,7 @@ class LC3State info.address = lookup(subroutine); info.name = subroutine; info.num_params = num_params; - + state.subroutines[info.address] = info; return true; } @@ -166,7 +166,7 @@ class LC3State /** @see lc3_state.memory_ops */ const std::map& get_memory_ops() const { return state.memory_ops; } /** @see lc3_state.comments */ - const std::string comment(unsigned short address) const + const std::string comment(unsigned short address) const { if (state.comments.find(address) == state.comments.end()) return ""; @@ -190,6 +190,8 @@ class LC3State bool get_strict_execution() const { return state.strict_execution; } void set_strict_execution(bool setting) { state.strict_execution = setting; } + std::string setup_replay(const std::string& file, const std::string& replay_str); + /** The following accessors are only meaningful if testing_mode was set */ std::string get_input() const { return in.str(); } void set_input(std::string input) { in.str(input); } diff --git a/pylc3/cli/comp.py b/pylc3/cli/comp.py index 7b36c50..9ddbc8a 100644 --- a/pylc3/cli/comp.py +++ b/pylc3/cli/comp.py @@ -438,7 +438,7 @@ def binary(data): end = self.state.pc + 5 elif end is None: end = start - + table_data = [['Addr', 'Hex', 'Dec', 'Binary', 'Label', 'Instruction', 'Comment']] for addr in xrange(start, end+1): @@ -465,7 +465,7 @@ def do_list_breakpoints(self, arg): for entry in self.state.breakpoints: addr, breakpoint = (entry.key(), entry.data()) - + name = breakpoint.label symbol = self.state.reverse_lookup(addr) target = symbol if symbol else 'x%04x' % addr @@ -474,7 +474,7 @@ def do_list_breakpoints(self, arg): times = str(breakpoint.max_hits) hits = str(breakpoint.hit_count) table_data.append([name, target, enabled, condition, times, hits]) - + table = SingleTable(table_data) self.message(table.table) @@ -492,7 +492,7 @@ def do_list_watchpoints(self, arg): for entry in self.state.register_watchpoints: reg, watchpoint = (entry.key(), entry.data()) - + name = watchpoint.label target = 'R%d' % reg enabled = str(watchpoint.enabled) @@ -503,7 +503,7 @@ def do_list_watchpoints(self, arg): for entry in self.state.memory_watchpoints: addr, watchpoint = (entry.key(), entry.data()) - + name = watchpoint.label symbol = self.state.reverse_lookup(addr) target = symbol if symbol else 'x%04x' % addr @@ -512,7 +512,7 @@ def do_list_watchpoints(self, arg): times = str(watchpoint.max_hits) hits = str(watchpoint.hit_count) table_data.append([name, target, enabled, condition, times, hits]) - + table = SingleTable(table_data) self.message(table.table) @@ -530,7 +530,7 @@ def do_list_blackboxes(self, arg): for entry in self.state.blackboxes: addr, blackbox = (entry.key(), entry.data()) - + name = blackbox.label symbol = self.state.reverse_lookup(addr) target = symbol if symbol else 'x%04x' % addr @@ -538,7 +538,7 @@ def do_list_blackboxes(self, arg): condition = blackbox.condition hits = str(blackbox.hit_count) table_data.append([name, target, enabled, condition, hits]) - + table = SingleTable(table_data) self.message(table.table) @@ -597,6 +597,38 @@ def do_reload_over(self, arg): return self.message('Successfully loaded file %s.' % params) + def do_setup_replay(self, arg): + """setup_replay filename replay_str - Reloads current file with a replay string.""" + params = self.parse(arg, str, str) + if params is None: + return + + filename, replay_str = params + out = self.state.setup_replay(filename, replay_str) + + if out: + self.message(out) + else: + self.message('Successfuly set up test replay.') + self.file = filename + + def do_resetup_replay(self, arg): + """resetup_replay replay_str - Reloads current file with a replay string.""" + if not self.file: + self.message('A file must currently be loaded to use this command.') + return + + params = self.parse(arg, str) + if params is None: + return + + out = self.state.setup_replay(self.file, *params) + + if out: + self.message(out) + else: + self.message('Successfuly set up test replay.') + def do_quit(self, arg): """quit - Exits the simulator.""" self.message('Goodbye.')