コード例 #1
0
ファイル: ComplxFrame.cpp プロジェクト: cchen396/complx
/** DoLoadFile
  *
  * Handles loading an assembly file into the simulator
  */
void ComplxFrame::DoLoadFile(const wxFileName& filename)
{
    //CleanUp();
    lc3_state dummy_state;
    lc3_init(dummy_state);

    // Save the symbols
    std::map<std::string, unsigned short> symbol_table = state.symbols;
    std::map<unsigned short, std::string> rev_symbol_table = state.rev_symbols;

    state.symbols.clear();
    state.rev_symbols.clear();
    lc3_remove_plugins(state);

    try
    {
        lc3_assemble(dummy_state, filename.GetFullPath().ToStdString(), false);
        lc3_assemble(state, filename.GetFullPath().ToStdString());

    }
    catch (LC3AssembleException e)
    {
        wxMessageBox(wxString::Format("BAD STUDENT! %s", e.what()), _("Loading ") + filename.GetFullName() + _(" Failed"));
        goto merge;
    }
    catch (std::vector<LC3AssembleException> e)
    {
        std::stringstream oss;
        for (unsigned int i = 0; i < e.size(); i++)
            oss << e[i].what() << std::endl;
        wxMessageBox(wxString::Format("BAD STUDENT! %s", oss.str()), _("Loading ") + filename.GetFullName() + _(" Failed"));
        goto merge;
    }

    //if (DoAssemble(filename)) return;
    currentFile = filename;
    SetTitle(wxString::Format("Complx - %s", filename.GetFullPath()));
    merge:

    std::map<std::string, unsigned short>::const_iterator i;
    std::map<unsigned short, std::string>::const_iterator j;
    for (i = symbol_table.begin(); i != symbol_table.end(); ++i)
    {
        state.symbols[i->first] = i->second;
    }
    for (j = rev_symbol_table.begin(); j != rev_symbol_table.end(); ++j)
    {
        state.rev_symbols[j->first] = j->second;
    }

    //DoLoad(filename);
    UpdateStatus();
    UpdateRegisters();
    UpdateMemory();

}
コード例 #2
0
ファイル: ComplxFrame.cpp プロジェクト: TricksterGuy/complx
/** DoLoadFile
  *
  * Handles loading an assembly file into the simulator
  */
void ComplxFrame::DoLoadFile(const LoadingOptions& opts)
{
    auto* config = wxConfigBase::Get();

    wxFileName filename(opts.file);
    bool randomize_registers = opts.registers == RANDOMIZE;
    bool randomize_memory = opts.memory == RANDOMIZE;
    short fill_registers = opts.registers;
    short fill_memory = opts.memory;

    lc3_init(state, randomize_registers, randomize_memory, fill_registers, fill_memory);
    state.pc = opts.pc;

    PostInit();

    // Now the actual loading
    if (opts.file.empty())
        return;

    lc3_state dummy_state;
    lc3_init(dummy_state);

    // Save the symbols
    std::map<std::string, unsigned short> symbol_table = state.symbols;
    std::map<unsigned short, std::string> rev_symbol_table = state.rev_symbols;

    state.symbols.clear();
    state.rev_symbols.clear();
    lc3_remove_plugins(state);

    bool tvt_modification = false;
    bool ivt_modification = false;
    bool subroutine_found = false;

    try
    {
        ///TODO should only make one call to lc3_assemble.
        std::vector<code_range> ranges;
        LC3AssembleOptions options;
        options.multiple_errors = false;
        lc3_assemble(dummy_state, filename.GetFullPath().ToStdString(), options);
        options.multiple_errors = true;
        options.warnings_as_errors = false;
        options.process_debug_comments = true;
        options.enable_warnings = false;
        options.disable_plugins = false;
        lc3_assemble(state, filename.GetFullPath().ToStdString(), ranges, options);

        // Update list of addresses modified for Show only Code/Data option.
        modified_addresses.clear();
        for (const auto& code_range : ranges)
            modified_addresses.push_back(ViewRange(code_range.location, code_range.location + code_range.size));
        /// TODO Automatically determine state of true traps and interrupts via the code ranges.
        // Dummy call to update hidden addresses.
        wxCommandEvent event;
        OnUpdateHideAddresses(event);
        // Check for TVT and IVT modification
        for (const auto& code_range : ranges)
        {
            if ((code_range.location >= 0 && code_range.location <= 0xFF) || (code_range.location + code_range.size >= 0 && code_range.location + code_range.size <= 0xFF))
                tvt_modification = true;
            if ((code_range.location >= 0x100 && code_range.location <= 0x1FF) || (code_range.location + code_range.size >= 0x100 && code_range.location + code_range.size <= 0x1FF))
                ivt_modification = true;
        }
        subroutine_found = DetectSubroutine(ranges);
    }
    catch (LC3AssembleException e)
    {
        wxMessageBox(wxString::Format("ERROR! %s", e.what()), wxString::Format("Loading %s failed", filename.GetFullName()));
        goto merge;
    }
    catch (std::vector<LC3AssembleException> e)
    {
        std::stringstream oss;
        for (unsigned int i = 0; i < e.size(); i++)
            oss << e[i].what() << std::endl;
        wxMessageBox(wxString::Format("ERROR! %s", oss.str()), wxString::Format("Loading %s failed", filename.GetFullName()));
        goto merge;
    }

    lc3_set_true_traps(state, opts.true_traps || tvt_modification);
    state.interrupt_enabled = opts.interrupts || ivt_modification;
    console->SetInput(opts.console_input);
    state.strict_execution = opts.strict_execution;
    // Update menus
    menuStateTrueTraps->Check(opts.true_traps || tvt_modification);
    menuStateInterrupts->Check(opts.interrupts || ivt_modification);
    menuStateStrictExecution->Check(opts.strict_execution);

    if (tvt_modification)
    {
        bool tvt_popup = config->Read("/firsttimetrap", "").IsEmpty();
        if (tvt_popup)
        {
            wxMessageBox("Pardon the interruption!\n"
                         "It appears you have loaded a file with a custom trap.\n"
                         "This will automatically enable true traps mode.\n"
                         "This will allow you to step into the code for the standard traps (IN,OUT,GETC,PUTS,HALT) and your own custom trap.\n"
                         "This notice to to remind you of the above, executing HALT will jump to some random code, but I assure you this random code is the code to HALT the LC-3.\n"
                         "If you'd rather stop the execution right at the HALT statement then put a breakpoint on your HALT statement.\n",
                         "Notice");
            config->Write("/firsttimetrap", "1");
        }
    }

    if (subroutine_found)
    {
        wxCommandEvent event;
        OnControlModeAdvanced(event);
        bool subroutine_popup = config->Read("/firsttimesubroutine", "").IsEmpty();
        if (subroutine_popup)
        {
            wxMessageBox("Pardon the interruption!\n"
                         "It appears you have loaded a file with a custom trap or subroutine.\n"
                         "You may notice 3 new buttons in the control area.\n"
                         "Next Line\n    Allows you to STEP OVER a subroutine or trap, meaning it will skip over it (but still execute it).\n"
                         "Prev Line\n    Allows you to BACK STEP OVER a subroutine or trap.\n"
                         "Finish\n    Allows you to STEP OUT of a subroutine, it finishes execution of it.\n\n"
                         "Another thing to note if you want to always step over/out a subroutine to select the subroutine label and select mark as blackbox.\n"
                         "If you use step on a JSR/JSRR/TRAP instruction that is blackboxed it will never step into it.\n"
                         "For more information Read The Manual :)\n"
                         , "Notice");
            config->Write("/firsttimesubroutine", "1");
        }
    }

    SetTitle(wxString::Format("%s - %s", base_title, filename.GetFullPath()));

merge:
    std::map<std::string, unsigned short>::const_iterator i;
    std::map<unsigned short, std::string>::const_iterator j;
    for (i = symbol_table.begin(); i != symbol_table.end(); ++i)
    {
        state.symbols[i->first] = i->second;
    }
    for (j = rev_symbol_table.begin(); j != rev_symbol_table.end(); ++j)
    {
        state.rev_symbols[j->first] = j->second;
    }

    UpdateStatus();
    UpdateRegisters();
    UpdateMemory();

    // Save in reload options
    reload_options = opts;

    // Update timestamps
    wxFileName file_loaded(reload_options.file);
    reload_options.file_modification_time = file_loaded.GetModificationTime();
}
コード例 #3
0
/** lc3_init
  *
  * Initializes the state of the lc3
  *
  * @param state An LC3 state
  * @param randomize_registers if true randomizes registers
  * @param randomize_memory if true randomizes memory
  * @param fill_value ignored if randomize_XXX is true otherwise sets registers/memory to this value (except R7).
  */
void lc3_init(lc3_state& state, bool randomize_registers, bool randomize_memory, short fill_value)
{
    // Set Registers
    state.regs[0] = randomize_registers ? lc3_random() : fill_value;
    state.regs[1] = randomize_registers ? lc3_random() : fill_value;
    state.regs[2] = randomize_registers ? lc3_random() : fill_value;
    state.regs[3] = randomize_registers ? lc3_random() : fill_value;
    state.regs[4] = randomize_registers ? lc3_random() : fill_value;
    state.regs[5] = randomize_registers ? lc3_random() : fill_value;
    state.regs[6] = randomize_registers ? lc3_random() : fill_value;
    state.regs[7] = randomize_registers ? lc3_random() : 0x490;

    // PC is initially at address 3000
    state.pc = 0x3000;

    // User mode
    state.privilege = 1;
    state.priority = 0;


    // Set Control Flags
    state.n = 0;
    state.z = 1;
    state.p = 0;

    // Set Additional Flags
    state.halted = 0;
    state.true_traps = 0;
    state.warnings = 0;
    state.executions = 0;
    state.interrupt_enabled = 0;

    // Clear subroutine info
    state.max_call_stack_size = -1;
    state.call_stack.clear();

    // Set Stack Flags
    state.max_stack_size = -1;
    state.undo_stack.clear();

    // Set I/O Stuff
    state.input = &std::cin;
    state.reader = lc3_read_char;
    state.peek = lc3_peek_char;
    state.output = &std::cout;
    state.writer = lc3_do_write_char;
    state.warning = &std::cout;

    // Clear memory
    if (randomize_memory)
    {
        lc3_randomize(state);
    }
    else
    {
        for (unsigned int i = 0; i < 65536; i++)
            state.mem[i] = fill_value;
    }

    // Add LC3 OS
    memcpy(state.mem, lc3_os, LC3_OS_SIZE * sizeof(unsigned short));

    // Clear plugins
    lc3_remove_plugins(state);

    // Clear Symbol Table
    state.symbols.clear();
    state.rev_symbols.clear();

    // Clear Breakpoints and all that jazz
    state.breakpoints.clear();
    state.blackboxes.clear();
    state.comments.clear();
    state.reg_watchpoints.clear();
    state.mem_watchpoints.clear();
    state.subroutines.clear();

    // Clear pending interrupts
    state.interrupts.clear();
    state.interrupt_test.clear();
    state.interrupt_vector = -1;
    state.savedssp = 0x3000;
    state.savedusp = 0xF000;

    state.memory_ops.clear();
    state.total_reads = 0;
    state.total_writes = 0;

    state.in_lc3test = false;
}