diff --git a/README.md b/README.md
index 47307a2..68607c7 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
-SYMON - A 6502 System Simulator
+kSYMON - A 6502 System Simulator
===============================
-**Version:** 1.5.0
+**Version:** 1.5.1k
-**Last Updated:** 30 March, 2025
+**Last Updated:** 24 September, 2026
See the file COPYING for license.
@@ -71,6 +71,13 @@ memory.
- `$6000`--`$600F`: 6522 VIA
- `$8000`--`$FFFF`: 16KB ROM
+#### 3.1.5 Mike42 Memory Map
+
+ - `$0000`--`$7FFF`: 32KB RAM
+ - `$8000`--`$800F`: 6522 VIA
+ - `$8400`--`$8403`: MOS 6551 ACIA (Serial Console)
+ - `$C000`--`$FFFF`: 16KB ROM
+
### 3.2 Serial Console and CPU Status

diff --git a/pom.xml b/pom.xml
index 71058d5..c23771d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.loomcom.symon
symon
jar
- 1.5.0
+ 1.5.1k
symon
https://git.loomcom.com/seth/symon
@@ -26,7 +26,7 @@
ch.qos.logback
logback-classic
- 1.5.16
+ 1.5.34
commons-cli
@@ -55,6 +55,11 @@
4.11.0
test
+
+ net.java.dev.jna
+ jna
+ 5.14.0
+
@@ -66,7 +71,7 @@
+ implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
com.loomcom.symon.Main
@@ -97,8 +102,8 @@
3.7.0
-Xlint:unchecked
- 11
- 11
+ 16
+ 16
diff --git a/src/main/java/com/loomcom/symon/machines/MichaelBillingtonMachine.java b/src/main/java/com/loomcom/symon/machines/MichaelBillingtonMachine.java
new file mode 100644
index 0000000..affbbe8
--- /dev/null
+++ b/src/main/java/com/loomcom/symon/machines/MichaelBillingtonMachine.java
@@ -0,0 +1,134 @@
+package com.loomcom.symon.machines;
+
+import com.loomcom.symon.Bus;
+import com.loomcom.symon.Cpu;
+import com.loomcom.symon.InstructionTable;
+import com.loomcom.symon.devices.*;
+import com.loomcom.symon.exceptions.MemoryRangeException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+public class MichaelBillingtonMachine implements Machine{
+
+ private static final Logger logger = LoggerFactory.getLogger(MichaelBillingtonMachine.class.getName());
+
+ // Constants used by the simulated system
+ private static final int BUS_BOTTOM = 0x0000;
+ private static final int BUS_TOP = 0xffff;
+
+ // 32k of ram, from $0000 to $7fff
+ private static final int MEMORY_BASE = 0x0000;
+ private static final int MEMORY_SIZE = 0x8000;
+
+ // VIA at $8000-$800f
+ private static final int PIA_BASE = 0x8000;
+
+ // ACIA at $8400-$8403
+ private static final int ACIA_BASE = 0x8400;
+
+ // 16k ROM from $c000 to $ffff
+ private static final int ROM_BASE = 0xc000;
+ private static final int ROM_SIZE = 0x4000;
+
+ private final Bus bus;
+ private final Cpu cpu;
+ private final Acia acia;
+ private final Pia pia;
+ private final Memory ram;
+ private Memory rom;
+
+ public MichaelBillingtonMachine(String romFile) throws Exception {
+ this.bus = new Bus(BUS_BOTTOM, BUS_TOP);
+ this.cpu = new Cpu();
+ this.ram = new Memory(MEMORY_BASE, MEMORY_BASE + MEMORY_SIZE - 1);
+ this.pia = new Via6522(PIA_BASE);
+ this.acia = new Acia6551(ACIA_BASE);
+
+ bus.addCpu(cpu);
+ bus.addDevice(ram);
+ bus.addDevice(pia);
+ bus.addDevice(acia);
+
+ if (romFile != null) {
+ File romImage = new File(romFile);
+ if (romImage.canRead()) {
+ logger.info("Loading ROM image from file {}", romImage);
+ this.rom = Memory.makeROM(ROM_BASE, ROM_BASE + ROM_SIZE - 1, romImage);
+ } else {
+ logger.info("Default ROM file {} not found, loading empty R/W memory image.", romImage);
+ this.rom = Memory.makeRAM(ROM_BASE, ROM_BASE + ROM_SIZE - 1);
+ }
+ } else {
+ logger.info("No ROM file specified, loading empty R/W memory image.");
+ this.rom = Memory.makeRAM(ROM_BASE, ROM_BASE + ROM_SIZE - 1);
+ }
+
+ bus.addDevice(rom);
+ }
+
+ @Override
+ public Bus getBus() {
+ return bus;
+ }
+
+ @Override
+ public Cpu getCpu() {
+ return cpu;
+ }
+
+ @Override
+ public Memory getRam() {
+ return ram;
+ }
+
+ @Override
+ public Acia getAcia() {
+ return acia;
+ }
+
+ @Override
+ public Pia getPia() {
+ return pia;
+ }
+
+ @Override
+ public Crtc getCrtc() {
+ return null;
+ }
+
+ @Override
+ public Memory getRom() {
+ return rom;
+ }
+
+ @Override
+ public void setRom(Memory rom) throws MemoryRangeException {
+ if (this.rom != null) {
+ bus.removeDevice(this.rom);
+ }
+ this.rom = rom;
+ bus.addDevice(this.rom);
+ }
+
+ @Override
+ public int getRomBase() {
+ return ROM_BASE;
+ }
+
+ @Override
+ public int getRomSize() {
+ return ROM_SIZE;
+ }
+
+ @Override
+ public int getMemorySize() {
+ return MEMORY_SIZE;
+ }
+
+ @Override
+ public String getName() {
+ return "mike42";
+ }
+}
diff --git a/src/main/java/com/loomcom/symon/ui/Ui.java b/src/main/java/com/loomcom/symon/ui/Ui.java
index 57ff169..bb4bdee 100644
--- a/src/main/java/com/loomcom/symon/ui/Ui.java
+++ b/src/main/java/com/loomcom/symon/ui/Ui.java
@@ -30,6 +30,7 @@ import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
+import com.loomcom.symon.machines.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -84,7 +85,7 @@ public final class Ui {
}
public static Class> showMachineSelectionDialog() {
- Object[] possibilities = { "Symon", "Multicomp", "Simple", "BenEater" };
+ Object[] possibilities = { "Symon", "Multicomp", "Simple", "BenEater", "Mike42" };
String s = (String) JOptionPane.showInputDialog(
null,
"Please choose the machine type to be emulated:",
@@ -100,6 +101,8 @@ public final class Ui {
return SimpleMachine.class;
} else if (s != null && s.equals("BenEater")) {
return BenEaterMachine.class;
+ } else if (s != null && s.equals("Mike42")) {
+ return MichaelBillingtonMachine.class;
} else {
return SymonMachine.class;
}