void lc3_step_one(lc3machine* state) { // If the machine is not halted // Fetch an instruction // And call lc3_execute if (state->mem[state->pc] != LC3_TRAP_FULL_HALT) { u16 instruction = lc3_fetch(state); lc3_execute(state, instruction); } }
/** lc3_step_one * * Get the next instrution and execute it if not halted * * @param state LC3 simulator */ void lc3_step_one(lc3machine* state) { // check if machine is running if (state->halted) return; // get the next instruciton unsigned short instruction = lc3_fetch(state); // run it lc3_execute(state, instruction); }
void lc3_step_one(lc3machine* state) { state->halted = 0; unsigned short instr = lc3_fetch(state); // get instruction returned from fetch lc3_execute(state, instr); // execute that instruction }
/** lc3_step * * Executes one instruction */ void lc3_step(lc3_state& state) { // If we are halted then don't step. if (state.halted) return; // Tick all plugins lc3_tick_plugins(state); // Fetch Instruction unsigned short data = state.mem[state.pc]; // Test for blackbox (If the line was a JSR statement and it had a blackbox). bool blackbox_finish = lc3_blackbox_test(state); // Increment PC state.pc++; // Form Instruction lc3_instr instr = lc3_decode(state, data); // Execute Instruction const lc3_state_change change = lc3_execute(state, instr); // Test for blackbox (If the first line of subroutine had a blackbox). if (instr.data.opcode == JSR_INSTR || (instr.data.opcode == TRAP_INSTR && state.true_traps)) blackbox_finish = blackbox_finish || lc3_blackbox_test(state); // Increment executions state.executions++; if (state.max_stack_size != 0) { // If the change is INTERRUPT END if (change.changes == LC3_INTERRUPT_END) { // After you've scrubbed all of the floors in hyrule (remove all instructions that have been added except the LC3_INTERRUPT change. lc3_state_change* hmm = &state.undo_stack.back(); while (hmm->changes != LC3_INTERRUPT_BEGIN) { state.undo_stack.pop_back(); hmm = &state.undo_stack.back(); } // Please sire have mercy (Change LC3_INTERRUPT_BEGIN to LC3_INTERRUPT to signal a completed interrupt) lc3_state_change& lib = state.undo_stack.back(); lib.changes = LC3_INTERRUPT; } else { // Push Old into state state.undo_stack.push_back(change); } // Never pop if you are in privileged mode. if (state.privilege && state.max_stack_size < state.undo_stack.size()) state.undo_stack.pop_front(); } // Tock all plugins lc3_tock_plugins(state); if (blackbox_finish) lc3_finish(state); // If we hit an error or a halt instruction return. no need to do any breakpoint tests. if (state.halted) return; // Breakpoint test lc3_break_test(state, &change); if (!state.interrupt_enabled) return; // Chime in on all observers. std::list<interrupt_test_func>::iterator i; for (i = state.interrupt_test.begin(); i != state.interrupt_test.end(); ++i) { interrupt_test_func func = *i; func(); } // Interrupt? if (!lc3_interrupt(state)) return; lc3_state_change interrupt; interrupt.changes = LC3_INTERRUPT_BEGIN; interrupt.warnings = state.warnings; interrupt.executions = state.executions; if (state.max_stack_size != 0) state.undo_stack.push_back(interrupt); // Another breakpoint test lc3_break_test(state, &interrupt); }
instr = lc3_decode(state, 0xF100); BOOST_REQUIRE_EQUAL(instr.trap.opcode, TRAP_INSTR); BOOST_CHECK_EQUAL(instr.trap.unused, 1); BOOST_CHECK_EQUAL(instr.trap.vector, 0); } BOOST_FIXTURE_TEST_CASE(MalformedInstructionTest, LC3BasicTest) { const std::vector<unsigned short> malformed_instructions = {0, 1, 0x1008, 0x4001, 0x4200, 0x5008, 0x8001, 0x903E, 0xC001, 0xC200, 0xF100}; for (const auto& data : malformed_instructions) { BOOST_TEST_MESSAGE("data = x" << std::hex << data); lc3_instr instr = lc3_decode(state, data); lc3_state_change change = lc3_execute(state, instr); BOOST_CHECK(state.halted); BOOST_CHECK_EQUAL(state.warnings, 1); BOOST_CHECK_EQUAL(state.pc, 0x2FFF); BOOST_CHECK_EQUAL(change.pc, 0x3000); BOOST_CHECK(!change.halted); lc3_init(state, false, false); } } BOOST_FIXTURE_TEST_CASE(MalformedInstructionDisassemble, LC3BasicTest) { const std::vector<unsigned short> malformed_instructions = {0, 1, 0x1008, 0x4001, 0x4200, 0x5008, 0x8001, 0x903E, 0xC001, 0xC200, 0xF100}; const std::vector<std::string> answers = {"NOP *", "NOP *", "ADD R0, R0, R0 *", "JSRR R0 *", "JSRR R0 *", "AND R0, R0, R0 *", "RTI *", "NOT R0, R0 *", "JMP R0 *", "JMP R0 *", "TRAP x00 *"};