diff --git a/src/main/java/com/loomcom/symon/Main.java b/src/main/java/com/loomcom/symon/Main.java index cb116be..9cce5af 100644 --- a/src/main/java/com/loomcom/symon/Main.java +++ b/src/main/java/com/loomcom/symon/Main.java @@ -26,6 +26,7 @@ package com.loomcom.symon; import com.loomcom.symon.machines.MulticompMachine; +import com.loomcom.symon.machines.SimpleMachine; import com.loomcom.symon.machines.SymonMachine; import java.util.Locale; import javax.swing.JOptionPane; @@ -51,13 +52,15 @@ public class Main { machineClass = SymonMachine.class; } else if(machine.equals("multicomp")) { machineClass = MulticompMachine.class; + } else if (machine.equals("simple")) { + machineClass = SimpleMachine.class; } } } while(true) { if(machineClass == null) { - Object[] possibilities = {"Symon", "Multicomp"}; + Object[] possibilities = {"Symon", "Multicomp", "Simple"}; String s = (String)JOptionPane.showInputDialog( null, "Please choose the machine type to be emulated:", @@ -67,11 +70,15 @@ public class Main { possibilities, "Symon"); - - if(s != null && s.equals("Multicomp")) { - machineClass = MulticompMachine.class; - } else { - machineClass = SymonMachine.class; + + if (s != null) { + if (s.equals("Multicomp")) { + machineClass = MulticompMachine.class; + } else if (s.equals("Simple")) { + machineClass = SimpleMachine.class; + } else { + machineClass = SymonMachine.class; + } } } diff --git a/src/main/java/com/loomcom/symon/Simulator.java b/src/main/java/com/loomcom/symon/Simulator.java index f115ad3..52adeaa 100644 --- a/src/main/java/com/loomcom/symon/Simulator.java +++ b/src/main/java/com/loomcom/symon/Simulator.java @@ -137,7 +137,7 @@ public class Simulator { */ public void createAndShowUi() throws IOException { mainWindow = new JFrame(); - mainWindow.setTitle("Symon 6502 Simulator"); + mainWindow.setTitle("6502 Simulator - " + machine.getName()); mainWindow.setResizable(false); mainWindow.getContentPane().setLayout(new BorderLayout()); @@ -337,7 +337,7 @@ public class Simulator { // Read from the ACIA and immediately update the console if there's // output ready. - if (machine.getAcia().hasTxChar()) { + if (machine.getAcia() != null && machine.getAcia().hasTxChar()) { // This is thread-safe console.print(Character.toString((char) machine.getAcia().txRead())); console.repaint(); @@ -346,7 +346,7 @@ public class Simulator { // If a key has been pressed, fill the ACIA. // TODO: Interrupt handling. try { - if (console.hasInput()) { + if (machine.getAcia() != null && console.hasInput()) { machine.getAcia().rxWrite((int) console.readInputChar()); } } catch (FifoUnderrunException ex) { @@ -703,7 +703,9 @@ public class Simulator { */ public void simulatorDidStart() { loadProgramItem.setEnabled(false); - loadRomItem.setEnabled(false); + if (loadRomItem != null) { + loadRomItem.setEnabled(false); + } } /** @@ -711,7 +713,9 @@ public class Simulator { */ public void simulatorDidStop() { loadProgramItem.setEnabled(true); - loadRomItem.setEnabled(true); + if (loadRomItem != null) { + loadRomItem.setEnabled(true); + } } private void initMenu() { @@ -722,15 +726,22 @@ public class Simulator { JMenu fileMenu = new JMenu("File"); loadProgramItem = new JMenuItem(new LoadProgramAction()); - loadRomItem = new JMenuItem(new LoadRomAction()); - JMenuItem prefsItem = new JMenuItem(new ShowPrefsAction()); - JMenuItem selectMachineItem = new JMenuItem(new SelectMachineAction()); - JMenuItem quitItem = new JMenuItem(new QuitAction()); - fileMenu.add(loadProgramItem); - fileMenu.add(loadRomItem); + + // Simple Machine does not implement a ROM, so it makes no sense to + // offer a ROM load option. + if (machine.getRom() != null) { + loadRomItem = new JMenuItem(new LoadRomAction()); + fileMenu.add(loadRomItem); + } + + JMenuItem prefsItem = new JMenuItem(new ShowPrefsAction()); fileMenu.add(prefsItem); + + JMenuItem selectMachineItem = new JMenuItem(new SelectMachineAction()); fileMenu.add(selectMachineItem); + + JMenuItem quitItem = new JMenuItem(new QuitAction()); fileMenu.add(quitItem); add(fileMenu); diff --git a/src/main/java/com/loomcom/symon/machines/Machine.java b/src/main/java/com/loomcom/symon/machines/Machine.java index a168b89..07569df 100644 --- a/src/main/java/com/loomcom/symon/machines/Machine.java +++ b/src/main/java/com/loomcom/symon/machines/Machine.java @@ -56,5 +56,6 @@ public interface Machine { public int getRomSize(); public int getMemorySize(); - + + String getName(); } diff --git a/src/main/java/com/loomcom/symon/machines/MulticompMachine.java b/src/main/java/com/loomcom/symon/machines/MulticompMachine.java index f5ec3cc..355ec91 100644 --- a/src/main/java/com/loomcom/symon/machines/MulticompMachine.java +++ b/src/main/java/com/loomcom/symon/machines/MulticompMachine.java @@ -147,5 +147,10 @@ public class MulticompMachine implements Machine { public int getMemorySize() { return MEMORY_SIZE; } - + + @Override + public String getName() { + return "Multicomp"; + } + } diff --git a/src/main/java/com/loomcom/symon/machines/SimpleMachine.java b/src/main/java/com/loomcom/symon/machines/SimpleMachine.java new file mode 100644 index 0000000..5c434f5 --- /dev/null +++ b/src/main/java/com/loomcom/symon/machines/SimpleMachine.java @@ -0,0 +1,93 @@ +package com.loomcom.symon.machines; + +import com.loomcom.symon.Bus; +import com.loomcom.symon.Cpu; +import com.loomcom.symon.devices.Acia; +import com.loomcom.symon.devices.Crtc; +import com.loomcom.symon.devices.Memory; +import com.loomcom.symon.devices.Via; +import com.loomcom.symon.exceptions.MemoryRangeException; + +/** + * A SimpleMachine is the simplest 6502 implementation possible - it + * consists solely of RAM and a CPU. This machine is primarily useful + * for running 6502 functional tests or debugging by hand. + */ +public class SimpleMachine implements Machine { + + private static final int BUS_BOTTOM = 0x0000; + private static final int BUS_TOP = 0xffff; + + private final Bus bus; + private final Memory ram; + private final Cpu cpu; + + public SimpleMachine() throws MemoryRangeException { + this.bus = new Bus(BUS_BOTTOM, BUS_TOP); + this.ram = new Memory(BUS_BOTTOM, BUS_TOP, false); + this.cpu = new Cpu(); + + bus.addCpu(cpu); + bus.addDevice(ram); + } + + @Override + public Bus getBus() { + return bus; + } + + @Override + public Cpu getCpu() { + return cpu; + } + + @Override + public Memory getRam() { + return ram; + } + + @Override + public Acia getAcia() { + return null; + } + + @Override + public Via getVia() { + return null; + } + + @Override + public Crtc getCrtc() { + return null; + } + + @Override + public Memory getRom() { + return null; + } + + @Override + public void setRom(Memory rom) throws MemoryRangeException { + // No-op + } + + @Override + public int getRomBase() { + return 0; + } + + @Override + public int getRomSize() { + return 0; + } + + @Override + public int getMemorySize() { + return BUS_TOP + 1; + } + + @Override + public String getName() { + return "Simple"; + } +} diff --git a/src/main/java/com/loomcom/symon/machines/SymonMachine.java b/src/main/java/com/loomcom/symon/machines/SymonMachine.java index 3f9efbb..a9a3b3d 100644 --- a/src/main/java/com/loomcom/symon/machines/SymonMachine.java +++ b/src/main/java/com/loomcom/symon/machines/SymonMachine.java @@ -160,8 +160,11 @@ public class SymonMachine implements Machine { public int getMemorySize() { return MEMORY_SIZE; } - - - + @Override + public String getName() { + return "Symon"; + } + + }