Skip to content

Commit

Permalink
Expose setup_replay behind a ifdef guard. The ifdef guard isn't set u…
Browse files Browse the repository at this point in the history
…p TO BE CONTINUED
  • Loading branch information
TricksterGuy committed Sep 24, 2018
1 parent bdca688 commit 9ca2fc5
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 22 deletions.
26 changes: 26 additions & 0 deletions pylc3/PyLC3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,29 @@ bool LC3State::loadCode(const std::string& code)
}
return true;
}

#ifdef HAVE_LC3_REPLAY
#include <lc3_replay.hpp>
void LC3State::setup_replay(const std::string& file, const std::string& replay_str)
{
try
{
lc3_setup_replay(state, file, replay_str, in);
state.input = &in;
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
30 changes: 16 additions & 14 deletions pylc3/PyLC3.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ 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.
*/
void init(bool randomize = true, short fill_value = 0)
{
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.
Expand All @@ -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);
Expand All @@ -71,27 +71,27 @@ 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]; }
/** Sets value at address, note that the difference between this and memory_write is that memory_write will trigger plugins and devices */
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); }
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -166,7 +166,7 @@ class LC3State
/** @see lc3_state.memory_ops */
const std::map<unsigned short, lc3_memory_stats>& 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 "";
Expand All @@ -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); }
Expand Down
48 changes: 40 additions & 8 deletions pylc3/cli/comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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
Expand All @@ -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)

Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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)

Expand All @@ -530,15 +530,15 @@ 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
enabled = str(blackbox.enabled)
condition = blackbox.condition
hits = str(blackbox.hit_count)
table_data.append([name, target, enabled, condition, hits])

table = SingleTable(table_data)
self.message(table.table)

Expand Down Expand Up @@ -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.')
Expand Down

0 comments on commit 9ca2fc5

Please sign in to comment.