void do_finish(void) { state.halted = 0; lc3_finish(state); memory->Update(); registers->Update(); }
/** 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); }