[+] Gradle init
This commit is contained in:
@@ -0,0 +1,536 @@
|
||||
package mars.simulator;
|
||||
import mars.*;
|
||||
import mars.venus.*;
|
||||
import mars.util.*;
|
||||
import mars.mips.hardware.*;
|
||||
import mars.mips.instructions.*;
|
||||
import java.util.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/*
|
||||
Copyright (c) 2003-2010, Pete Sanderson and Kenneth Vollmar
|
||||
|
||||
Developed by Pete Sanderson (psanderson@otterbein.edu)
|
||||
and Kenneth Vollmar (kenvollmar@missouristate.edu)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject
|
||||
to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
|
||||
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
||||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
(MIT license, http://www.opensource.org/licenses/mit-license.html)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used to simulate the execution of an assembled MIPS program.
|
||||
* @author Pete Sanderson
|
||||
* @version August 2005
|
||||
**/
|
||||
|
||||
public class Simulator extends Observable {
|
||||
private SimThread simulatorThread;
|
||||
private static Simulator simulator = null; // Singleton object
|
||||
private static Runnable interactiveGUIUpdater = null;
|
||||
// Others can set this true to indicate external interrupt. Initially used
|
||||
// to simulate keyboard and display interrupts. The device is identified
|
||||
// by the address of its MMIO control register. keyboard 0xFFFF0000 and
|
||||
// display 0xFFFF0008. DPS 23 July 2008.
|
||||
public static final int NO_DEVICE = 0;
|
||||
public static volatile int externalInterruptingDevice = NO_DEVICE;
|
||||
/** various reasons for simulate to end... */
|
||||
public static final int BREAKPOINT = 1;
|
||||
public static final int EXCEPTION = 2;
|
||||
public static final int MAX_STEPS = 3; // includes step mode (where maxSteps is 1)
|
||||
public static final int NORMAL_TERMINATION = 4;
|
||||
public static final int CLIFF_TERMINATION = 5; // run off bottom of program
|
||||
public static final int PAUSE_OR_STOP = 6;
|
||||
|
||||
/**
|
||||
* Returns the Simulator object
|
||||
*
|
||||
* @return the Simulator object in use
|
||||
*/
|
||||
public static Simulator getInstance() {
|
||||
// Do NOT change this to create the Simulator at load time (in declaration above)!
|
||||
// Its constructor looks for the GUI, which at load time is not created yet,
|
||||
// and incorrectly leaves interactiveGUIUpdater null! This causes runtime
|
||||
// exceptions while running in timed mode.
|
||||
if (simulator==null) {
|
||||
simulator = new Simulator();
|
||||
}
|
||||
return simulator;
|
||||
}
|
||||
|
||||
private Simulator() {
|
||||
simulatorThread = null;
|
||||
if (Globals.getGui() != null) {
|
||||
interactiveGUIUpdater = new UpdateGUI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether or not the next instruction to be executed is in a
|
||||
* "delay slot". This means delayed branching is enabled, the branch
|
||||
* condition has evaluated true, and the next instruction executed will
|
||||
* be the one following the branch. It is said to occupy the "delay slot."
|
||||
* Normally programmers put a nop instruction here but it can be anything.
|
||||
*
|
||||
* @return true if next instruction is in delay slot, false otherwise.
|
||||
*/
|
||||
|
||||
public static boolean inDelaySlot() {
|
||||
return DelayedBranch.isTriggered();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simulate execution of given MIPS program. It must have already been assembled.
|
||||
* @param p The MIPSprogram to be simulated.
|
||||
* @param pc address of first instruction to simulate; this goes into program counter
|
||||
* @param maxSteps maximum number of steps to perform before returning false (0 or less means no max)
|
||||
* @param breakPoints array of breakpoint program counter values, use null if none
|
||||
* @param actor the GUI component responsible for this call, usually GO or STEP. null if none.
|
||||
* @return true if execution completed, false otherwise
|
||||
* @throws ProcessingException Throws exception if run-time exception occurs.
|
||||
**/
|
||||
|
||||
public boolean simulate(MIPSprogram p, int pc, int maxSteps, int[] breakPoints, AbstractAction actor) throws ProcessingException {
|
||||
simulatorThread = new SimThread(p,pc,maxSteps,breakPoints,actor);
|
||||
simulatorThread.start();
|
||||
|
||||
// Condition should only be true if run from command-line instead of GUI.
|
||||
// If so, just stick around until execution thread is finished.
|
||||
if (actor == null) {
|
||||
Object dun = simulatorThread.get(); // this should emulate join()
|
||||
ProcessingException pe = simulatorThread.pe;
|
||||
boolean done = simulatorThread.done;
|
||||
if (done) SystemIO.resetFiles(); // close any files opened in MIPS progra
|
||||
this.simulatorThread = null;
|
||||
if (pe != null) {
|
||||
throw pe;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the volatile stop boolean variable checked by the execution
|
||||
* thread at the end of each MIPS instruction execution. If variable
|
||||
* is found to be true, the execution thread will depart
|
||||
* gracefully so the main thread handling the GUI can take over.
|
||||
* This is used by both STOP and PAUSE features.
|
||||
*/
|
||||
public void stopExecution(AbstractAction actor) {
|
||||
|
||||
if (simulatorThread != null) {
|
||||
simulatorThread.setStop(actor);
|
||||
for (StopListener l : stopListeners) {
|
||||
l.stopped(this);
|
||||
}
|
||||
simulatorThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
/* This interface is required by the Asker class in MassagesPane
|
||||
* to be notified about the fact that the user has requested to
|
||||
* stop the execution. When that happens, it must unblock the
|
||||
* simulator thread. */
|
||||
public interface StopListener {
|
||||
void stopped(Simulator s);
|
||||
}
|
||||
|
||||
private ArrayList<StopListener> stopListeners = new ArrayList<StopListener>(1);
|
||||
public void addStopListener(StopListener l) {
|
||||
stopListeners.add(l);
|
||||
}
|
||||
|
||||
public void removeStopListener(StopListener l) {
|
||||
stopListeners.remove(l);
|
||||
}
|
||||
|
||||
// The Simthread object will call this method when it enters and returns from
|
||||
// its construct() method. These signal start and stop, respectively, of
|
||||
// simulation execution. The observer can then adjust its own state depending
|
||||
// on the execution state. Note that "stop" and "done" are not the same thing.
|
||||
// "stop" just means it is leaving execution state; this could be triggered
|
||||
// by Stop button, by Pause button, by Step button, by runtime exception, by
|
||||
// instruction count limit, by breakpoint, or by end of simulation (truly done).
|
||||
private void notifyObserversOfExecutionStart(int maxSteps, int programCounter) {
|
||||
this.setChanged();
|
||||
this.notifyObservers(new SimulatorNotice(SimulatorNotice.SIMULATOR_START,
|
||||
maxSteps, RunSpeedPanel.getInstance().getRunSpeed(), programCounter) );
|
||||
}
|
||||
|
||||
private void notifyObserversOfExecutionStop(int maxSteps, int programCounter) {
|
||||
this.setChanged();
|
||||
this.notifyObservers(new SimulatorNotice(SimulatorNotice.SIMULATOR_STOP,
|
||||
maxSteps, RunSpeedPanel.getInstance().getRunSpeed(), programCounter) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* SwingWorker subclass to perform the simulated execution in background thread.
|
||||
* It is "interrupted" when main thread sets the "stop" variable to true.
|
||||
* The variable is tested before the next MIPS instruction is simulated. Thus
|
||||
* interruption occurs in a tightly controlled fashion.
|
||||
*
|
||||
* See SwingWorker.java for more details on its functionality and usage. It is
|
||||
* provided by Sun Microsystems for download and is not part of the Swing library.
|
||||
*/
|
||||
|
||||
class SimThread extends SwingWorker {
|
||||
private MIPSprogram p;
|
||||
private int pc, maxSteps;
|
||||
private int[] breakPoints;
|
||||
private boolean done;
|
||||
private ProcessingException pe;
|
||||
private volatile boolean stop = false;
|
||||
private volatile AbstractAction stopper;
|
||||
private AbstractAction starter;
|
||||
private int constructReturnReason;
|
||||
|
||||
|
||||
/**
|
||||
* SimThread constructor. Receives all the information it needs to simulate execution.
|
||||
*
|
||||
* @param p the MIPSprogram to be simulated
|
||||
* @param pc address in text segment of first instruction to simulate
|
||||
* @param maxSteps maximum number of instruction steps to simulate. Default of -1 means no maximum
|
||||
* @param breakPoints array of breakpoints (instruction addresses) specified by user
|
||||
* @param starter the GUI component responsible for this call, usually GO or STEP. null if none.
|
||||
*/
|
||||
SimThread(MIPSprogram p, int pc, int maxSteps, int[] breakPoints, AbstractAction starter) {
|
||||
super(Globals.getGui()!=null);
|
||||
this.p = p;
|
||||
this.pc = pc;
|
||||
this.maxSteps = maxSteps;
|
||||
this.breakPoints = breakPoints;
|
||||
this.done = false;
|
||||
this.pe = null;
|
||||
this.starter = starter;
|
||||
this.stopper = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets to "true" the volatile boolean variable that is tested after each
|
||||
* MIPS instruction is executed. After calling this method, the next test
|
||||
* will yield "true" and "construct" will return.
|
||||
*
|
||||
* @param actor the Swing component responsible for this call.
|
||||
*/
|
||||
public void setStop(AbstractAction actor) {
|
||||
stop = true;
|
||||
stopper = actor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is comparable to the Runnable "run" method (it is called by
|
||||
* SwingWorker's "run" method). It simulates the program
|
||||
* execution in the backgorund.
|
||||
*
|
||||
* @return boolean value true if execution done, false otherwise
|
||||
*/
|
||||
|
||||
public Object construct() {
|
||||
// The next two statements are necessary for GUI to be consistently updated
|
||||
// before the simulation gets underway. Without them, this happens only intermittently,
|
||||
// with a consequence that some simulations are interruptable using PAUSE/STOP and others
|
||||
// are not (because one or the other or both is not yet enabled).
|
||||
Thread.currentThread().setPriority(Thread.NORM_PRIORITY-1);
|
||||
Thread.yield(); // let the main thread run a bit to finish updating the GUI
|
||||
|
||||
if (breakPoints == null || breakPoints.length == 0) {
|
||||
breakPoints = null;
|
||||
}
|
||||
else {
|
||||
Arrays.sort(breakPoints); // must be pre-sorted for binary search
|
||||
}
|
||||
|
||||
Simulator.getInstance().notifyObserversOfExecutionStart(maxSteps, pc);
|
||||
|
||||
RegisterFile.initializeProgramCounter(pc);
|
||||
ProgramStatement statement = null;
|
||||
try {
|
||||
statement = Globals.memory.getStatement(RegisterFile.getProgramCounter());
|
||||
}
|
||||
catch (AddressErrorException e) {
|
||||
ErrorList el = new ErrorList();
|
||||
el.add(new ErrorMessage((MIPSprogram)null,0,0,"invalid program counter value: "+Binary.intToHexString(RegisterFile.getProgramCounter())));
|
||||
this.pe = new ProcessingException(el, e);
|
||||
// Next statement is a hack. Previous statement sets EPC register to ProgramCounter-4
|
||||
// because it assumes the bad address comes from an operand so the ProgramCounter has already been
|
||||
// incremented. In this case, bad address is the instruction fetch itself so Program Counter has
|
||||
// not yet been incremented. We'll set the EPC directly here. DPS 8-July-2013
|
||||
Coprocessor0.updateRegister(Coprocessor0.EPC, RegisterFile.getProgramCounter());
|
||||
this.constructReturnReason = EXCEPTION;
|
||||
this.done = true;
|
||||
SystemIO.resetFiles(); // close any files opened in MIPS program
|
||||
Simulator.getInstance().notifyObserversOfExecutionStop(maxSteps, pc);
|
||||
return new Boolean(done);
|
||||
}
|
||||
int steps = 0;
|
||||
|
||||
// ******************* PS addition 26 July 2006 **********************
|
||||
// A couple statements below were added for the purpose of assuring that when
|
||||
// "back stepping" is enabled, every instruction will have at least one entry
|
||||
// on the back-stepping stack. Most instructions will because they write either
|
||||
// to a register or memory. But "nop" and branches not taken do not. When the
|
||||
// user is stepping backward through the program, the stack is popped and if
|
||||
// an instruction has no entry it will be skipped over in the process. This has
|
||||
// no effect on the correctness of the mechanism but the visual jerkiness when
|
||||
// instruction highlighting skips such instrutions is disruptive. Current solution
|
||||
// is to add a "do nothing" stack entry for instructions that do no write anything.
|
||||
// To keep this invisible to the "simulate()" method writer, we
|
||||
// will push such an entry onto the stack here if there is none for this instruction
|
||||
// by the time it has completed simulating. This is done by the IF statement
|
||||
// just after the call to the simulate method itself. The BackStepper method does
|
||||
// the aforementioned check and decides whether to push or not. The result
|
||||
// is a a smoother interaction experience. But it comes at the cost of slowing
|
||||
// simulation speed for flat-out runs, for every MIPS instruction executed even
|
||||
// though very few will require the "do nothing" stack entry. For stepped or
|
||||
// timed execution the slower execution speed is not noticeable.
|
||||
//
|
||||
// To avoid this cost I tried a different technique: back-fill with "do nothings"
|
||||
// during the backstepping itself when this situation is recognized. Problem
|
||||
// was in recognizing all possible situations in which the stack contained such
|
||||
// a "gap". It became a morass of special cases and it seemed every weird test
|
||||
// case revealed another one. In addition, when a program
|
||||
// begins with one or more such instructions ("nop" and branches not taken),
|
||||
// the backstep button is not enabled until a "real" instruction is executed.
|
||||
// This is noticeable in stepped mode.
|
||||
// *********************************************************************
|
||||
|
||||
int pc = 0; // added: 7/26/06 (explanation above)
|
||||
|
||||
while (statement != null) {
|
||||
pc = RegisterFile.getProgramCounter(); // added: 7/26/06 (explanation above)
|
||||
RegisterFile.incrementPC();
|
||||
// Perform the MIPS instruction in synchronized block. If external threads agree
|
||||
// to access MIPS memory and registers only through synchronized blocks on same
|
||||
// lock variable, then full (albeit heavy-handed) protection of MIPS memory and
|
||||
// registers is assured. Not as critical for reading from those resources.
|
||||
synchronized (Globals.memoryAndRegistersLock) {
|
||||
try {
|
||||
if (Simulator.externalInterruptingDevice != NO_DEVICE) {
|
||||
int deviceInterruptCode = externalInterruptingDevice;
|
||||
Simulator.externalInterruptingDevice = NO_DEVICE;
|
||||
throw new ProcessingException(statement, "External Interrupt", deviceInterruptCode);
|
||||
}
|
||||
BasicInstruction instruction = (BasicInstruction)statement.getInstruction();
|
||||
if (instruction == null) {
|
||||
throw new ProcessingException(statement,
|
||||
"undefined instruction ("+Binary.intToHexString(statement.getBinaryStatement())+")",
|
||||
Exceptions.RESERVED_INSTRUCTION_EXCEPTION);
|
||||
}
|
||||
// THIS IS WHERE THE INSTRUCTION EXECUTION IS ACTUALLY SIMULATED!
|
||||
instruction.getSimulationCode().simulate(statement);
|
||||
|
||||
// IF statement added 7/26/06 (explanation above)
|
||||
if (Globals.getSettings().getBackSteppingEnabled()) {
|
||||
Globals.program.getBackStepper().addDoNothing(pc);
|
||||
}
|
||||
}
|
||||
catch (ProcessingException pe) {
|
||||
if (pe.errors() == null) {
|
||||
this.constructReturnReason = NORMAL_TERMINATION;
|
||||
this.done = true;
|
||||
SystemIO.resetFiles(); // close any files opened in MIPS program
|
||||
Simulator.getInstance().notifyObserversOfExecutionStop(maxSteps, pc);
|
||||
return new Boolean(done); // execution completed without error.
|
||||
}
|
||||
else {
|
||||
// See if an exception handler is present. Assume this is the case
|
||||
// if and only if memory location Memory.exceptionHandlerAddress
|
||||
// (e.g. 0x80000180) contains an instruction. If so, then set the
|
||||
// program counter there and continue. Otherwise terminate the
|
||||
// MIPS program with appropriate error message.
|
||||
ProgramStatement exceptionHandler = null;
|
||||
try {
|
||||
exceptionHandler = Globals.memory.getStatement(Memory.exceptionHandlerAddress);
|
||||
}
|
||||
catch (AddressErrorException aee) { } // will not occur with this well-known addres
|
||||
if (exceptionHandler != null) {
|
||||
RegisterFile.setProgramCounter(Memory.exceptionHandlerAddress);
|
||||
}
|
||||
else {
|
||||
this.constructReturnReason = EXCEPTION;
|
||||
this.pe = pe;
|
||||
this.done = true;
|
||||
SystemIO.resetFiles(); // close any files opened in MIPS program
|
||||
Simulator.getInstance().notifyObserversOfExecutionStop(maxSteps, pc);
|
||||
return new Boolean(done);
|
||||
}
|
||||
}
|
||||
}
|
||||
}// end synchronized block
|
||||
|
||||
///////// DPS 15 June 2007. Handle delayed branching if it occurs./////
|
||||
if (DelayedBranch.isTriggered()) {
|
||||
RegisterFile.setProgramCounter(DelayedBranch.getBranchTargetAddress());
|
||||
DelayedBranch.clear();
|
||||
}
|
||||
else if (DelayedBranch.isRegistered()) {
|
||||
DelayedBranch.trigger();
|
||||
}//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Volatile variable initialized false but can be set true by the main thread.
|
||||
// Used to stop or pause a running MIPS program. See stopSimulation() above.
|
||||
if (stop == true) {
|
||||
this.constructReturnReason = PAUSE_OR_STOP;
|
||||
this.done = false;
|
||||
Simulator.getInstance().notifyObserversOfExecutionStop(maxSteps, pc);
|
||||
return new Boolean(done);
|
||||
}
|
||||
// Return if we've reached a breakpoint.
|
||||
if((breakPoints != null) &&
|
||||
(Arrays.binarySearch(breakPoints,RegisterFile.getProgramCounter()) >= 0)) {
|
||||
this.constructReturnReason = BREAKPOINT;
|
||||
this.done = false;
|
||||
Simulator.getInstance().notifyObserversOfExecutionStop(maxSteps, pc);
|
||||
return new Boolean(done); // false;
|
||||
}
|
||||
// Check number of MIPS instructions executed. Return if at limit (-1 is no limit).
|
||||
if (maxSteps > 0) {
|
||||
steps++;
|
||||
if (steps >= maxSteps) {
|
||||
this.constructReturnReason = MAX_STEPS;
|
||||
this.done = false;
|
||||
Simulator.getInstance().notifyObserversOfExecutionStop(maxSteps, pc);
|
||||
return new Boolean(done);// false;
|
||||
}
|
||||
}
|
||||
|
||||
// schedule GUI update only if: there is in fact a GUI! AND
|
||||
// using Run, not Step (maxSteps > 1) AND
|
||||
// running slowly enough for GUI to keep up
|
||||
//if (Globals.getGui() != null && maxSteps != 1 &&
|
||||
if (interactiveGUIUpdater != null && maxSteps != 1 &&
|
||||
RunSpeedPanel.getInstance().getRunSpeed() < RunSpeedPanel.UNLIMITED_SPEED) {
|
||||
SwingUtilities.invokeLater(interactiveGUIUpdater);
|
||||
}
|
||||
if (Globals.getGui() != null || Globals.runSpeedPanelExists) { // OR added by DPS 24 July 2008 to enable speed control by stand-alone tool
|
||||
if (maxSteps != 1 &&
|
||||
RunSpeedPanel.getInstance().getRunSpeed() < RunSpeedPanel.UNLIMITED_SPEED) {
|
||||
try { Thread.sleep((int)(1000/RunSpeedPanel.getInstance().getRunSpeed())); // make sure it's never zero!
|
||||
}
|
||||
catch (InterruptedException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get next instruction in preparation for next iteration.
|
||||
|
||||
try {
|
||||
statement = Globals.memory.getStatement(RegisterFile.getProgramCounter());
|
||||
}
|
||||
catch (AddressErrorException e) {
|
||||
ErrorList el = new ErrorList();
|
||||
el.add(new ErrorMessage((MIPSprogram)null,0,0,"invalid program counter value: "+Binary.intToHexString(RegisterFile.getProgramCounter())));
|
||||
this.pe = new ProcessingException(el,e);
|
||||
// Next statement is a hack. Previous statement sets EPC register to ProgramCounter-4
|
||||
// because it assumes the bad address comes from an operand so the ProgramCounter has already been
|
||||
// incremented. In this case, bad address is the instruction fetch itself so Program Counter has
|
||||
// not yet been incremented. We'll set the EPC directly here. DPS 8-July-2013
|
||||
Coprocessor0.updateRegister(Coprocessor0.EPC, RegisterFile.getProgramCounter());
|
||||
this.constructReturnReason = EXCEPTION;
|
||||
this.done = true;
|
||||
SystemIO.resetFiles(); // close any files opened in MIPS program
|
||||
Simulator.getInstance().notifyObserversOfExecutionStop(maxSteps, pc);
|
||||
return new Boolean(done);
|
||||
}
|
||||
}
|
||||
// DPS July 2007. This "if" statement is needed for correct program
|
||||
// termination if delayed branching on and last statement in
|
||||
// program is a branch/jump. Program will terminate rather than branch,
|
||||
// because that's what MARS does when execution drops off the bottom.
|
||||
if (DelayedBranch.isTriggered() || DelayedBranch.isRegistered()) {
|
||||
DelayedBranch.clear();
|
||||
}
|
||||
// If we got here it was due to null statement, which means program
|
||||
// counter "fell off the end" of the program. NOTE: Assumes the
|
||||
// "while" loop contains no "break;" statements.
|
||||
this.constructReturnReason = CLIFF_TERMINATION;
|
||||
this.done = true;
|
||||
SystemIO.resetFiles(); // close any files opened in MIPS program
|
||||
Simulator.getInstance().notifyObserversOfExecutionStop(maxSteps, pc);
|
||||
return new Boolean(done); // true; // execution completed
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is invoked by the SwingWorker when the "construct" method returns.
|
||||
* It will update the GUI appropriately. According to Sun's documentation, it
|
||||
* is run in the main thread so should work OK with Swing components (which are
|
||||
* not thread-safe).
|
||||
*
|
||||
* Its action depends on what caused the return from construct() and what
|
||||
* action led to the call of construct() in the first place.
|
||||
*/
|
||||
|
||||
public void finished() {
|
||||
// If running from the command-line, then there is no GUI to update.
|
||||
if (Globals.getGui() == null) {
|
||||
return;
|
||||
}
|
||||
String starterName = (String) starter.getValue(AbstractAction.NAME);
|
||||
if (starterName.equals("Step")) {
|
||||
((RunStepAction)starter).stepped(done,constructReturnReason,pe);
|
||||
}
|
||||
if (starterName.equals("Go")) {
|
||||
if (done) {
|
||||
((RunGoAction)starter).stopped(pe,constructReturnReason);
|
||||
}
|
||||
else if (constructReturnReason == BREAKPOINT) {
|
||||
((RunGoAction)starter).paused(done,constructReturnReason,pe);
|
||||
}
|
||||
else {
|
||||
String stopperName = (String) stopper.getValue(AbstractAction.NAME);
|
||||
if ("Pause".equals(stopperName)) {
|
||||
((RunGoAction)starter).paused(done,constructReturnReason,pe);
|
||||
}
|
||||
else if ("Stop".equals(stopperName)) {
|
||||
((RunGoAction)starter).stopped(pe,constructReturnReason);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class UpdateGUI implements Runnable {
|
||||
public void run() {
|
||||
if (Globals.getGui().getRegistersPane().getSelectedComponent() ==
|
||||
Globals.getGui().getMainPane().getExecutePane().getRegistersWindow()) {
|
||||
Globals.getGui().getMainPane().getExecutePane().getRegistersWindow().updateRegisters();
|
||||
}
|
||||
else {
|
||||
Globals.getGui().getMainPane().getExecutePane().getCoprocessor1Window().updateRegisters();
|
||||
}
|
||||
Globals.getGui().getMainPane().getExecutePane().getDataSegmentWindow().updateValues();
|
||||
Globals.getGui().getMainPane().getExecutePane().getTextSegmentWindow().setCodeHighlighting(true);
|
||||
Globals.getGui().getMainPane().getExecutePane().getTextSegmentWindow().highlightStepAtPC();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user