mirror of
https://github.com/sethm/symon.git
synced 2024-06-22 23:29:38 +00:00
Bugfixes, change logger, update copyright
- IR field in status panel now correctly displays the next instruction to be executed, instead of the instruction that was just executed. - Switched from built-in Java util logger to Logback - Updated all copyright strings to 2016
This commit is contained in:
parent
ae5c5d48b2
commit
a4a110dcef
5
pom.xml
5
pom.xml
|
@ -35,6 +35,11 @@
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.1.3</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
@ -25,8 +25,9 @@ package com.loomcom.symon;
|
||||||
|
|
||||||
import com.loomcom.symon.exceptions.MemoryAccessException;
|
import com.loomcom.symon.exceptions.MemoryAccessException;
|
||||||
import com.loomcom.symon.util.HexUtil;
|
import com.loomcom.symon.util.HexUtil;
|
||||||
import java.util.logging.Level;
|
import org.slf4j.Logger;
|
||||||
import java.util.logging.Logger;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class provides a simulation of the MOS 6502 CPU's state machine.
|
* This class provides a simulation of the MOS 6502 CPU's state machine.
|
||||||
|
@ -35,6 +36,8 @@ import java.util.logging.Logger;
|
||||||
*/
|
*/
|
||||||
public class Cpu implements InstructionTable {
|
public class Cpu implements InstructionTable {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(Cpu.class.getName());
|
||||||
|
|
||||||
/* Process status register mnemonics */
|
/* Process status register mnemonics */
|
||||||
public static final int P_CARRY = 0x01;
|
public static final int P_CARRY = 0x01;
|
||||||
public static final int P_ZERO = 0x02;
|
public static final int P_ZERO = 0x02;
|
||||||
|
@ -146,6 +149,8 @@ public class Cpu implements InstructionTable {
|
||||||
state.a = 0;
|
state.a = 0;
|
||||||
state.x = 0;
|
state.x = 0;
|
||||||
state.y = 0;
|
state.y = 0;
|
||||||
|
|
||||||
|
peekAhead();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void step(int num) throws MemoryAccessException {
|
public void step(int num) throws MemoryAccessException {
|
||||||
|
@ -732,6 +737,18 @@ public class Cpu implements InstructionTable {
|
||||||
}
|
}
|
||||||
|
|
||||||
delayLoop(state.ir);
|
delayLoop(state.ir);
|
||||||
|
|
||||||
|
// Peek ahead to the next insturction and arguments
|
||||||
|
peekAhead();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void peekAhead() throws MemoryAccessException {
|
||||||
|
state.nextIr = bus.read(state.pc);
|
||||||
|
int nextInstSize = Cpu.instructionSizes[state.nextIr];
|
||||||
|
for (int i = 1; i < nextInstSize; i++) {
|
||||||
|
int nextRead = (state.pc + i) % bus.endAddress();
|
||||||
|
state.nextArgs[i-1] = bus.read(nextRead);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleIrq(int returnPc) throws MemoryAccessException {
|
private void handleIrq(int returnPc) throws MemoryAccessException {
|
||||||
|
@ -1117,6 +1134,14 @@ public class Cpu implements InstructionTable {
|
||||||
|
|
||||||
public void setProgramCounter(int addr) {
|
public void setProgramCounter(int addr) {
|
||||||
state.pc = addr;
|
state.pc = addr;
|
||||||
|
|
||||||
|
// As a side-effect of setting the program counter,
|
||||||
|
// we want to peek ahead at the next state.
|
||||||
|
try {
|
||||||
|
peekAhead();
|
||||||
|
} catch (MemoryAccessException ex) {
|
||||||
|
logger.error("Could not peek ahead at next instruction state.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStackPointer() {
|
public int getStackPointer() {
|
||||||
|
@ -1359,15 +1384,20 @@ public class Cpu implements InstructionTable {
|
||||||
*/
|
*/
|
||||||
public int pc;
|
public int pc;
|
||||||
/**
|
/**
|
||||||
* Instruction Register
|
* Last Loaded Instruction Register
|
||||||
*/
|
*/
|
||||||
public int ir;
|
public int ir;
|
||||||
public int lastPc;
|
/**
|
||||||
|
* Peek-Ahead to next IR
|
||||||
|
*/
|
||||||
|
public int nextIr;
|
||||||
public int[] args = new int[2];
|
public int[] args = new int[2];
|
||||||
|
public int[] nextArgs = new int[2];
|
||||||
public int instSize;
|
public int instSize;
|
||||||
public boolean opTrap;
|
public boolean opTrap;
|
||||||
public boolean irqAsserted;
|
public boolean irqAsserted;
|
||||||
public boolean nmiAsserted;
|
public boolean nmiAsserted;
|
||||||
|
public int lastPc;
|
||||||
|
|
||||||
/* Status Flag Register bits */
|
/* Status Flag Register bits */
|
||||||
public boolean carryFlag;
|
public boolean carryFlag;
|
||||||
|
@ -1387,7 +1417,7 @@ public class Cpu implements InstructionTable {
|
||||||
/**
|
/**
|
||||||
* Snapshot a copy of the CpuState.
|
* Snapshot a copy of the CpuState.
|
||||||
*
|
*
|
||||||
* (This is a copy constructor rather than an implementation of <code>Clonable</code>
|
* (This is a copy constructor rather than an implementation of <code>Cloneable</code>
|
||||||
* based on Josh Bloch's recommendation)
|
* based on Josh Bloch's recommendation)
|
||||||
*
|
*
|
||||||
* @param s The CpuState to copy.
|
* @param s The CpuState to copy.
|
||||||
|
@ -1399,9 +1429,12 @@ public class Cpu implements InstructionTable {
|
||||||
this.sp = s.sp;
|
this.sp = s.sp;
|
||||||
this.pc = s.pc;
|
this.pc = s.pc;
|
||||||
this.ir = s.ir;
|
this.ir = s.ir;
|
||||||
|
this.nextIr = s.nextIr;
|
||||||
this.lastPc = s.lastPc;
|
this.lastPc = s.lastPc;
|
||||||
this.args[0] = s.args[0];
|
this.args[0] = s.args[0];
|
||||||
this.args[1] = s.args[1];
|
this.args[1] = s.args[1];
|
||||||
|
this.nextArgs[0] = s.nextArgs[0];
|
||||||
|
this.nextArgs[1] = s.nextArgs[1];
|
||||||
this.instSize = s.instSize;
|
this.instSize = s.instSize;
|
||||||
this.opTrap = s.opTrap;
|
this.opTrap = s.opTrap;
|
||||||
this.irqAsserted = s.irqAsserted;
|
this.irqAsserted = s.irqAsserted;
|
||||||
|
@ -1421,7 +1454,7 @@ public class Cpu implements InstructionTable {
|
||||||
* @return a string formatted for the trace log.
|
* @return a string formatted for the trace log.
|
||||||
*/
|
*/
|
||||||
public String toTraceEvent() {
|
public String toTraceEvent() {
|
||||||
String opcode = disassembleOp();
|
String opcode = disassembleLastOp();
|
||||||
StringBuilder sb = new StringBuilder(getInstructionByteStatus());
|
StringBuilder sb = new StringBuilder(getInstructionByteStatus());
|
||||||
sb.append(" ");
|
sb.append(" ");
|
||||||
sb.append(String.format("%-14s", opcode));
|
sb.append(String.format("%-14s", opcode));
|
||||||
|
@ -1483,13 +1516,13 @@ public class Cpu implements InstructionTable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an opcode and its operands, return a formatted name.
|
* Return a formatted string representing the last instruction and
|
||||||
|
* operands that were executed.
|
||||||
*
|
*
|
||||||
* @return A string representing the mnemonic and operands of the instruction
|
* @return A string representing the mnemonic and operands of the instruction
|
||||||
*/
|
*/
|
||||||
public String disassembleOp() {
|
private String disassembleOp(int ir, int[] args) {
|
||||||
String mnemonic = opcodeNames[ir];
|
String mnemonic = opcodeNames[ir];
|
||||||
|
|
||||||
if (mnemonic == null) {
|
if (mnemonic == null) {
|
||||||
|
@ -1535,6 +1568,20 @@ public class Cpu implements InstructionTable {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String disassembleLastOp() {
|
||||||
|
return disassembleOp(ir, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a formatted string representing the next instruction and
|
||||||
|
* operands to be executed.
|
||||||
|
*
|
||||||
|
* @return A string representing the mnemonic and operands of the instruction
|
||||||
|
*/
|
||||||
|
public String disassembleNextOp() {
|
||||||
|
return disassembleOp(nextIr, nextArgs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given two bytes, return an address.
|
* Given two bytes, return an address.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
* Maik Merten <maikmerten@googlemail.com>
|
* Maik Merten <maikmerten@googlemail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyrighi (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
@ -31,14 +31,14 @@ import com.loomcom.symon.exceptions.SymonException;
|
||||||
import com.loomcom.symon.machines.Machine;
|
import com.loomcom.symon.machines.Machine;
|
||||||
import com.loomcom.symon.ui.*;
|
import com.loomcom.symon.ui.*;
|
||||||
import com.loomcom.symon.ui.Console;
|
import com.loomcom.symon.ui.Console;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.border.EmptyBorder;
|
import javax.swing.border.EmptyBorder;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Symon Simulator Interface and Control.
|
* Symon Simulator Interface and Control.
|
||||||
|
@ -50,6 +50,8 @@ import java.util.logging.Logger;
|
||||||
*/
|
*/
|
||||||
public class Simulator {
|
public class Simulator {
|
||||||
|
|
||||||
|
private final static Logger logger = LoggerFactory.getLogger(Simulator.class.getName());
|
||||||
|
|
||||||
// UI constants
|
// UI constants
|
||||||
private static final int DEFAULT_FONT_SIZE = 12;
|
private static final int DEFAULT_FONT_SIZE = 12;
|
||||||
private static final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, DEFAULT_FONT_SIZE);
|
private static final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, DEFAULT_FONT_SIZE);
|
||||||
|
@ -66,8 +68,6 @@ public class Simulator {
|
||||||
//
|
//
|
||||||
private static final int MAX_STEPS_BETWEEN_UPDATES = 20000;
|
private static final int MAX_STEPS_BETWEEN_UPDATES = 20000;
|
||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(Simulator.class.getName());
|
|
||||||
|
|
||||||
// The simulated machine
|
// The simulated machine
|
||||||
private Machine machine;
|
private Machine machine;
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ public class Simulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.log(Level.INFO, "Reset requested. Resetting CPU.");
|
logger.info("Reset requested. Resetting CPU.");
|
||||||
// Reset CPU
|
// Reset CPU
|
||||||
machine.getCpu().reset();
|
machine.getCpu().reset();
|
||||||
// Clear the console.
|
// Clear the console.
|
||||||
|
@ -302,15 +302,9 @@ public class Simulator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Update status.
|
// Update status.
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
updateVisibleState();
|
||||||
public void run() {
|
|
||||||
// Now update the state
|
|
||||||
statusPane.updateState();
|
|
||||||
memoryWindow.updateState();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (MemoryAccessException ex) {
|
} catch (MemoryAccessException ex) {
|
||||||
logger.log(Level.SEVERE, "Exception during simulator reset: " + ex.getMessage());
|
logger.error("Exception during simulator reset", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,17 +316,9 @@ public class Simulator {
|
||||||
for (int i = 0; i < numSteps; i++) {
|
for (int i = 0; i < numSteps; i++) {
|
||||||
step();
|
step();
|
||||||
}
|
}
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
updateVisibleState();
|
||||||
public void run() {
|
|
||||||
if (traceLog.isVisible()) {
|
|
||||||
traceLog.refresh();
|
|
||||||
}
|
|
||||||
statusPane.updateState();
|
|
||||||
memoryWindow.updateState();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (SymonException ex) {
|
} catch (SymonException ex) {
|
||||||
logger.log(Level.SEVERE, "Exception during simulator step: " + ex.getMessage());
|
logger.error("Exception during simulator step", ex);
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -359,7 +345,7 @@ public class Simulator {
|
||||||
machine.getAcia().rxWrite((int) console.readInputChar());
|
machine.getAcia().rxWrite((int) console.readInputChar());
|
||||||
}
|
}
|
||||||
} catch (FifoUnderrunException ex) {
|
} catch (FifoUnderrunException ex) {
|
||||||
logger.severe("Console type-ahead buffer underrun!");
|
logger.error("Console type-ahead buffer underrun!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (videoWindow != null && stepsSinceLastCrtcRefresh++ > stepsBetweenCrtcRefreshes) {
|
if (videoWindow != null && stepsSinceLastCrtcRefresh++ > stepsBetweenCrtcRefreshes) {
|
||||||
|
@ -373,13 +359,7 @@ public class Simulator {
|
||||||
// a delay, so we don't want to overwhelm the Swing event processing thread
|
// a delay, so we don't want to overwhelm the Swing event processing thread
|
||||||
// with requests. Limit the number of ui updates that can be performed.
|
// with requests. Limit the number of ui updates that can be performed.
|
||||||
if (stepsSinceLastUpdate++ > MAX_STEPS_BETWEEN_UPDATES) {
|
if (stepsSinceLastUpdate++ > MAX_STEPS_BETWEEN_UPDATES) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
updateVisibleState();
|
||||||
public void run() {
|
|
||||||
// Now update the state
|
|
||||||
statusPane.updateState();
|
|
||||||
memoryWindow.updateState();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
stepsSinceLastUpdate = 0;
|
stepsSinceLastUpdate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,8 +374,7 @@ public class Simulator {
|
||||||
machine.getBus().write(addr++, program[i] & 0xff);
|
machine.getBus().write(addr++, program[i] & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.log(Level.INFO, "Loaded " + i + " bytes at address 0x" +
|
logger.info("Loaded {} bytes at address 0x{}", i, Integer.toString(startAddress, 16));
|
||||||
Integer.toString(startAddress, 16));
|
|
||||||
|
|
||||||
// After loading, be sure to reset and
|
// After loading, be sure to reset and
|
||||||
// Reset (but don't clear memory, naturally)
|
// Reset (but don't clear memory, naturally)
|
||||||
|
@ -405,16 +384,9 @@ public class Simulator {
|
||||||
machine.getCpu().setProgramCounter(preferences.getProgramStartAddress());
|
machine.getCpu().setProgramCounter(preferences.getProgramStartAddress());
|
||||||
|
|
||||||
// Immediately update the UI.
|
// Immediately update the UI.
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
updateVisibleState();
|
||||||
public void run() {
|
|
||||||
// Now update the state
|
|
||||||
statusPane.updateState();
|
|
||||||
memoryWindow.updateState();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main run thread.
|
* The main run thread.
|
||||||
*/
|
*/
|
||||||
|
@ -430,7 +402,7 @@ public class Simulator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
logger.log(Level.INFO, "Starting main run loop.");
|
logger.info("Starting main run loop.");
|
||||||
isRunning = true;
|
isRunning = true;
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@ -449,8 +421,7 @@ public class Simulator {
|
||||||
step();
|
step();
|
||||||
} while (shouldContinue());
|
} while (shouldContinue());
|
||||||
} catch (SymonException ex) {
|
} catch (SymonException ex) {
|
||||||
logger.log(Level.SEVERE, "Exception in main simulator run thread. Exiting run.");
|
logger.error("Exception in main simulator run thread. Exiting run.", ex);
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@ -529,10 +500,10 @@ public class Simulator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.SEVERE, "Unable to read program file: " + ex.getMessage());
|
logger.error("Unable to read program file.", ex);
|
||||||
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
||||||
} catch (MemoryAccessException ex) {
|
} catch (MemoryAccessException ex) {
|
||||||
logger.log(Level.SEVERE, "Memory access error loading program: " + ex.getMessage());
|
logger.error("Memory access error loading program", ex);
|
||||||
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -555,34 +526,36 @@ public class Simulator {
|
||||||
|
|
||||||
if (fileSize != machine.getRomSize()) {
|
if (fileSize != machine.getRomSize()) {
|
||||||
throw new IOException("ROM file must be exactly " + String.valueOf(machine.getRomSize()) + " bytes.");
|
throw new IOException("ROM file must be exactly " + String.valueOf(machine.getRomSize()) + " bytes.");
|
||||||
} else {
|
|
||||||
|
|
||||||
// Load the new ROM image
|
|
||||||
Memory rom = Memory.makeROM(machine.getRomBase(), machine.getRomBase() + machine.getRomSize() - 1, romFile);
|
|
||||||
machine.setRom(rom);
|
|
||||||
|
|
||||||
// Now, reset
|
|
||||||
machine.getCpu().reset();
|
|
||||||
|
|
||||||
logger.log(Level.INFO, "ROM File `" + romFile.getName() + "' loaded at " +
|
|
||||||
String.format("0x%04X", machine.getRomBase()));
|
|
||||||
// TODO: "Don't Show Again" checkbox
|
|
||||||
JOptionPane.showMessageDialog(mainWindow,
|
|
||||||
"Loaded Successfully At " +
|
|
||||||
String.format("$%04X", machine.getRomBase()),
|
|
||||||
"OK",
|
|
||||||
JOptionPane.PLAIN_MESSAGE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load the new ROM image
|
||||||
|
Memory rom = Memory.makeROM(machine.getRomBase(), machine.getRomBase() + machine.getRomSize() - 1, romFile);
|
||||||
|
machine.setRom(rom);
|
||||||
|
|
||||||
|
// Now, reset
|
||||||
|
machine.getCpu().reset();
|
||||||
|
|
||||||
|
updateVisibleState();
|
||||||
|
|
||||||
|
logger.info("ROM File `{}' loaded at {}", romFile.getName(),
|
||||||
|
String.format("0x%04X", machine.getRomBase()));
|
||||||
|
// TODO: "Don't Show Again" checkbox
|
||||||
|
JOptionPane.showMessageDialog(mainWindow,
|
||||||
|
"Loaded Successfully At " +
|
||||||
|
String.format("$%04X", machine.getRomBase()),
|
||||||
|
"OK",
|
||||||
|
JOptionPane.PLAIN_MESSAGE);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.log(Level.SEVERE, "Unable to read ROM file: " + ex.getMessage());
|
logger.error("Unable to read ROM file: {}", ex.getMessage());
|
||||||
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
||||||
} catch (MemoryRangeException ex) {
|
} catch (MemoryRangeException ex) {
|
||||||
logger.log(Level.SEVERE, "Memory range error while loading ROM file: " + ex.getMessage());
|
logger.error("Memory range error while loading ROM file: {}", ex.getMessage());
|
||||||
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
||||||
} catch (MemoryAccessException ex) {
|
} catch (MemoryAccessException ex) {
|
||||||
logger.log(Level.SEVERE, "Memory access error while loading ROM file: " + ex.getMessage());
|
logger.error("Memory access error while loading ROM file: {}", ex.getMessage());
|
||||||
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
JOptionPane.showMessageDialog(mainWindow, ex.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -837,4 +810,18 @@ public class Simulator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateVisibleState() {
|
||||||
|
// Immediately update the UI.
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
// Now update the state
|
||||||
|
statusPane.updateState();
|
||||||
|
memoryWindow.updateState();
|
||||||
|
if (traceLog.shouldUpdate()) {
|
||||||
|
traceLog.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
* Maik Merten <maikmerten@googlemail.com>
|
* Maik Merten <maikmerten@googlemail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
* Maik Merten <maikmerten@googlemail.com>
|
* Maik Merten <maikmerten@googlemail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
* Maik Merten <maikmerten@googlemail.com>
|
* Maik Merten <maikmerten@googlemail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
* Maik Merten <maikmerten@googlemail.com>
|
* Maik Merten <maikmerten@googlemail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
* Maik Merten <maikmerten@googlemail.com>
|
* Maik Merten <maikmerten@googlemail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
* Maik Merten <maikmerten@googlemail.com>
|
* Maik Merten <maikmerten@googlemail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
@ -28,13 +28,14 @@ import com.loomcom.symon.Bus;
|
||||||
import com.loomcom.symon.Cpu;
|
import com.loomcom.symon.Cpu;
|
||||||
import com.loomcom.symon.devices.*;
|
import com.loomcom.symon.devices.*;
|
||||||
import com.loomcom.symon.exceptions.MemoryRangeException;
|
import com.loomcom.symon.exceptions.MemoryRangeException;
|
||||||
import java.io.File;
|
import org.slf4j.Logger;
|
||||||
import java.util.logging.Logger;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public class SymonMachine implements Machine {
|
public class SymonMachine implements Machine {
|
||||||
|
|
||||||
private final static Logger logger = Logger.getLogger(SymonMachine.class.getName());
|
private final static Logger logger = LoggerFactory.getLogger(SymonMachine.class.getName());
|
||||||
|
|
||||||
// Constants used by the simulated system. These define the memory map.
|
// Constants used by the simulated system. These define the memory map.
|
||||||
private static final int BUS_BOTTOM = 0x0000;
|
private static final int BUS_BOTTOM = 0x0000;
|
||||||
|
@ -86,11 +87,10 @@ public class SymonMachine implements Machine {
|
||||||
// TODO: Make this configurable, of course.
|
// TODO: Make this configurable, of course.
|
||||||
File romImage = new File("rom.bin");
|
File romImage = new File("rom.bin");
|
||||||
if (romImage.canRead()) {
|
if (romImage.canRead()) {
|
||||||
logger.info("Loading ROM image from file " + romImage);
|
logger.info("Loading ROM image from file {}", romImage);
|
||||||
this.rom = Memory.makeROM(ROM_BASE, ROM_BASE + ROM_SIZE - 1, romImage);
|
this.rom = Memory.makeROM(ROM_BASE, ROM_BASE + ROM_SIZE - 1, romImage);
|
||||||
} else {
|
} else {
|
||||||
logger.info("Default ROM file " + romImage +
|
logger.info("Default ROM file {} not found, loading empty R/W memory image.", romImage);
|
||||||
" not found, loading empty R/W memory image.");
|
|
||||||
this.rom = Memory.makeRAM(ROM_BASE, ROM_BASE + ROM_SIZE - 1);
|
this.rom = Memory.makeRAM(ROM_BASE, ROM_BASE + ROM_SIZE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
@ -32,9 +32,6 @@ import javax.swing.border.EtchedBorder;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UI component that displays the current state of the simulated CPU.
|
* UI component that displays the current state of the simulated CPU.
|
||||||
|
@ -154,7 +151,7 @@ public class StatusPanel extends JPanel {
|
||||||
|
|
||||||
// Create and add register and address labels
|
// Create and add register and address labels
|
||||||
statusFlagsLabel = makeLabel("Flags");
|
statusFlagsLabel = makeLabel("Flags");
|
||||||
opcodeLabel = makeLabel("IR");
|
opcodeLabel = makeLabel("Next IR");
|
||||||
pcLabel = makeLabel("PC");
|
pcLabel = makeLabel("PC");
|
||||||
spLabel = makeLabel("SP");
|
spLabel = makeLabel("SP");
|
||||||
aLabel = makeLabel("A");
|
aLabel = makeLabel("A");
|
||||||
|
@ -317,7 +314,9 @@ public class StatusPanel extends JPanel {
|
||||||
negativeFlagLabel.setIcon(iconForFlag(status, 7));
|
negativeFlagLabel.setIcon(iconForFlag(status, 7));
|
||||||
|
|
||||||
// Update the register and address displays
|
// Update the register and address displays
|
||||||
opcodeField.setText(cpu.getCpuState().disassembleOp());
|
|
||||||
|
// We always want to show the NEXT instruction that will be executed
|
||||||
|
opcodeField.setText(cpu.getCpuState().disassembleNextOp());
|
||||||
pcField.setText(cpu.getProgramCounterStatus());
|
pcField.setText(cpu.getProgramCounterStatus());
|
||||||
spField.setText(cpu.getStackPointerStatus());
|
spField.setText(cpu.getStackPointerStatus());
|
||||||
aField.setText(cpu.getAccumulatorStatus());
|
aField.setText(cpu.getAccumulatorStatus());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
* Maik Merten <maikmerten@googlemail.com>
|
* Maik Merten <maikmerten@googlemail.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
@ -113,4 +113,8 @@ public class TraceLog extends JFrame {
|
||||||
traceLogTextArea.setEnabled(true);
|
traceLogTextArea.setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean shouldUpdate() {
|
||||||
|
return isVisible() && traceLogTextArea.isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Seth J. Morabito <web@loomcom.com>
|
* Copyright (c) 2016 Seth J. Morabito <web@loomcom.com>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files (the
|
* a copy of this software and associated documentation files (the
|
||||||
|
|
Loading…
Reference in New Issue
Block a user