From 8df561d29283708ab65dd08d589d4d55d7b6b0fc Mon Sep 17 00:00:00 2001 From: Seth Morabito Date: Thu, 11 Dec 2008 17:22:39 -0800 Subject: [PATCH] Changed the CPU and Device interface a bit. --- src/main/java/com/loomcom/lm6502/Bus.java | 17 +++-- src/main/java/com/loomcom/lm6502/Cpu.java | 72 ++++++++----------- .../java/com/loomcom/lm6502/Profiler.java | 29 ++++---- .../java/com/loomcom/lm6502/Simulator.java | 8 +-- .../com/loomcom/lm6502/devices/Device.java | 16 +++-- .../com/loomcom/lm6502/devices/Memory.java | 15 ++-- src/test/java/com/loomcom/lm6502/BusTest.java | 22 +++--- src/test/java/com/loomcom/lm6502/CpuTest.java | 8 +-- 8 files changed, 90 insertions(+), 97 deletions(-) diff --git a/src/main/java/com/loomcom/lm6502/Bus.java b/src/main/java/com/loomcom/lm6502/Bus.java index 9856a93..b4b419b 100644 --- a/src/main/java/com/loomcom/lm6502/Bus.java +++ b/src/main/java/com/loomcom/lm6502/Bus.java @@ -4,15 +4,17 @@ import java.util.*; import com.loomcom.lm6502.devices.*; import com.loomcom.lm6502.exceptions.*; +/** + * The Bus ties the whole thing together, man. + */ public class Bus { - /* By default, our bus starts at 0, and goes up to 64K */ + // By default, our bus starts at 0, and goes up to 64K private int startAddress = 0x0000; private int endAddress = 0xffff; - - /** - * Ordered list of IO devices. - */ + // The CPU + private Cpu cpu; + // Ordered list of IO devices. private SortedSet devices; public Bus(int size) { @@ -45,9 +47,14 @@ public class Bus { } // Add the device + device.setBus(this); devices.add(device); } + public void addCpu(Cpu cpu) { + this.cpu = cpu; + } + /** * Returns true if the memory map is full, i.e., there are no * gaps between any IO devices. All memory locations map to some diff --git a/src/main/java/com/loomcom/lm6502/Cpu.java b/src/main/java/com/loomcom/lm6502/Cpu.java index 4c8d1bc..1c47868 100644 --- a/src/main/java/com/loomcom/lm6502/Cpu.java +++ b/src/main/java/com/loomcom/lm6502/Cpu.java @@ -5,13 +5,38 @@ package com.loomcom.lm6502; */ public class Cpu { - private int pc; - private int sp; - private Simulator sim; + /* The Bus */ + private Bus bus; - public Cpu(Simulator sim) { + /* User Registers */ + private int a; // Accumulator + private int x; // X index register + private int y; // Y index register + + /* Internal Registers */ + private int pc; // Program Counter register + private int sp; // Stack Pointer register + private int ir; // Instruction register + + /** + * Construct a new CPU. + */ + public Cpu() { reset(); - this.sim = sim; + } + + /** + * Set the bus reference for this CPU. + */ + public void setBus(Bus bus) { + this.bus = bus; + } + + /** + * Return the Bus that this CPU is associated with. + */ + public Bus getBus() { + return bus; } /** @@ -19,43 +44,8 @@ public class Cpu { */ public void reset() { sp = 0x01ff; - /* locations fffc and fffd hold the reset vector address */ pc = 0xfffc; - } - - /** - * Trigger a maskable interrupt. - */ - public void interrupt() { - } - - /** - * Trigger a nonmaskable interrupt. - */ - public void nmiInterrupt() { - } - - /** - * @return An address specified by the two bytes immediately following the - * Program Counter. - */ - private int readAddress() { - return readAddress(pc); - } - - /** - * Read the two bytes located at addr and addr + 1, - * and return the address held there. - * - * @param address - * @return The address specified in the two bytes at location addr - */ - private int readAddress(int address) { - return (sim.read(address)<<8 & sim.read(address+1)); - } - - public Simulator getSimulator() { - return sim; + ir = 0; } } diff --git a/src/main/java/com/loomcom/lm6502/Profiler.java b/src/main/java/com/loomcom/lm6502/Profiler.java index 2c5315e..82872d4 100644 --- a/src/main/java/com/loomcom/lm6502/Profiler.java +++ b/src/main/java/com/loomcom/lm6502/Profiler.java @@ -18,14 +18,14 @@ public class Profiler { Bus b = new Bus(0, 65535); // Create eight devices, each 8KB, to fill the bus. - b.addDevice(new Memory(0x0000, 0x2000, null)); // 8KB @ $0000-$1fff - b.addDevice(new Memory(0x2000, 0x2000, null)); // 8KB @ $2000-$3fff - b.addDevice(new Memory(0x4000, 0x2000, null)); // 8KB @ $4000-$5fff - b.addDevice(new Memory(0x6000, 0x2000, null)); // 8KB @ $6000-$7fff - b.addDevice(new Memory(0x8000, 0x2000, null)); // 8KB @ $8000-$9fff - b.addDevice(new Memory(0xa000, 0x2000, null)); // 8KB @ $a000-$bfff - b.addDevice(new Memory(0xc000, 0x2000, null)); // 8KB @ $c000-$dfff - b.addDevice(new Memory(0xe000, 0x2000, null)); // 8KB @ $e000-$ffff + b.addDevice(new Memory(0x0000, 0x2000)); // 8KB @ $0000-$1fff + b.addDevice(new Memory(0x2000, 0x2000)); // 8KB @ $2000-$3fff + b.addDevice(new Memory(0x4000, 0x2000)); // 8KB @ $4000-$5fff + b.addDevice(new Memory(0x6000, 0x2000)); // 8KB @ $6000-$7fff + b.addDevice(new Memory(0x8000, 0x2000)); // 8KB @ $8000-$9fff + b.addDevice(new Memory(0xa000, 0x2000)); // 8KB @ $a000-$bfff + b.addDevice(new Memory(0xc000, 0x2000)); // 8KB @ $c000-$dfff + b.addDevice(new Memory(0xe000, 0x2000)); // 8KB @ $e000-$ffff // Read memory long sum = 0; @@ -42,7 +42,8 @@ public class Profiler { for (int j = 0; j < 0xffff; j++) { buf = b.read(j); if (buf != 0xff) { - System.out.println("WARNING! MEMORY SHOULD HAVE BEEN $FF, WAS: " + buf); + System.out.println("WARNING! MEMORY SHOULD HAVE " + + "BEEN $FF, WAS: " + buf); System.exit(0); } } @@ -50,15 +51,13 @@ public class Profiler { long endTime = System.nanoTime(); long diff = endTime - startTime; - // System.out.println("Read of 64KB took: " + diff + " ns (" + (diff / 1000) + " us)"); - sum += diff; average = sum / (i + 1); } - - System.out.println("Average time to read 64KB: " + average + " ns (" + (average / 1000) + " us)"); - System.out.println("Average time to read one byte: " + sum / (64 * 1024 * iters) + " ns"); - + System.out.println("Average time to read 64KB: " + average + + " ns (" + (average / 1000) + " us)"); + System.out.println("Average time to read one byte: " + + sum / (64 * 1024 * iters) + " ns"); } catch (MemoryRangeException ex) { System.out.println("Memory Access Exception! " + ex.getMessage()); } diff --git a/src/main/java/com/loomcom/lm6502/Simulator.java b/src/main/java/com/loomcom/lm6502/Simulator.java index 0aeeac4..3cdaba9 100644 --- a/src/main/java/com/loomcom/lm6502/Simulator.java +++ b/src/main/java/com/loomcom/lm6502/Simulator.java @@ -10,21 +10,21 @@ public class Simulator { /** * Command-line parser used by this simulator. */ - CommandParser parser; + private CommandParser parser; /** * The CPU itself. */ - Cpu cpu; + private Cpu cpu; /** * The Bus responsible for routing memory read/write requests to the * correct IO devices. */ - Bus bus; + private Bus bus; public Simulator() { - cpu = new Cpu(this); + cpu = new Cpu(); parser = new CommandParser(System.in, System.out, this); } diff --git a/src/main/java/com/loomcom/lm6502/devices/Device.java b/src/main/java/com/loomcom/lm6502/devices/Device.java index 20cb6b2..9c25212 100644 --- a/src/main/java/com/loomcom/lm6502/devices/Device.java +++ b/src/main/java/com/loomcom/lm6502/devices/Device.java @@ -12,16 +12,20 @@ public abstract class Device implements Comparable { /** The memory range for this device. */ private MemoryRange memoryRange; + /** The name of the device. */ private String name; - /** Reference to the CPU, for interrupts. */ - private Cpu cpu; + /** Reference to the bus where this Device is attached. */ + private Bus bus; - public Device(int address, int size, String name, Cpu cpu) + public Device(int address, int size, String name) throws MemoryRangeException { this.memoryRange = new MemoryRange(address, address + size - 1); this.name = name; - this.cpu = cpu; + } + + public Device(int address, int size) throws MemoryRangeException { + this(address, size, null); } /* Methods required to be implemented by inheriting classes. */ @@ -29,6 +33,10 @@ public abstract class Device implements Comparable { public abstract int read(int address); public abstract String toString(); + public void setBus(Bus bus) { + this.bus = bus; + } + public MemoryRange getMemoryRange() { return memoryRange; } diff --git a/src/main/java/com/loomcom/lm6502/devices/Memory.java b/src/main/java/com/loomcom/lm6502/devices/Memory.java index fc308f3..1a8d2ac 100644 --- a/src/main/java/com/loomcom/lm6502/devices/Memory.java +++ b/src/main/java/com/loomcom/lm6502/devices/Memory.java @@ -8,29 +8,24 @@ import com.loomcom.lm6502.exceptions.*; public class Memory extends Device { private boolean readOnly; - private int[] mem; - public Memory(int address, int size, Cpu cpu, boolean readOnly) + public Memory(int address, int size, boolean readOnly) throws MemoryRangeException { - super(address, size, "RW Memory", cpu); - + super(address, size, "RW Memory"); this.readOnly = readOnly; this.mem = new int[size]; - - // Init the mem to all 0xff + // Initialize all locations to 0xff Arrays.fill(this.mem, 0xff); } - public Memory(int address, int size, Cpu cpu) + public Memory(int address, int size) throws MemoryRangeException { - this(address, size, cpu, false); + this(address, size, false); } public void write(int address, int data) { - System.out.println(String.format("[write] Before write: $%04x=$%04x", address, this.mem[address])); this.mem[address] = data; - System.out.println(String.format("[write] After write: $%04x=$%04x", address, this.mem[address])); } public int read(int address) { diff --git a/src/test/java/com/loomcom/lm6502/BusTest.java b/src/test/java/com/loomcom/lm6502/BusTest.java index 744e8c6..24c0529 100644 --- a/src/test/java/com/loomcom/lm6502/BusTest.java +++ b/src/test/java/com/loomcom/lm6502/BusTest.java @@ -49,8 +49,8 @@ public class BusTest extends TestCase { } public void testAddDevice() throws MemoryRangeException { - Device memory = new Memory(0x0000, 0x0100, null, true); - Device rom = new Memory(0x0100, 0x0200, null, false); + Device memory = new Memory(0x0000, 0x0100, true); + Device rom = new Memory(0x0100, 0x0200, false); Bus b = new Bus(0x0000, 0xffff); @@ -62,8 +62,8 @@ public class BusTest extends TestCase { } public void testOverlappingDevicesShouldFail() throws MemoryRangeException { - Device memory = new Memory(0x0000, 0x0100, null, true); - Device rom = new Memory(0x00ff, 0x0200, null, false); + Device memory = new Memory(0x0000, 0x0100, true); + Device rom = new Memory(0x00ff, 0x0200, false); Bus b = new Bus(0x0000, 0xffff); @@ -78,7 +78,7 @@ public class BusTest extends TestCase { } public void testIsCompleteWithFirstDeviceNotStartingAtStartAddress() throws MemoryRangeException { - Device memory = new Memory(0x00ff, 0xff00, null, true); + Device memory = new Memory(0x00ff, 0xff00, true); Bus b = new Bus(0x0000, 0xffff); assertFalse("Address space was unexpectedly complete!", b.isComplete()); @@ -87,7 +87,7 @@ public class BusTest extends TestCase { } public void testIsCompleteWithOneDevice() throws MemoryRangeException { - Device memory = new Memory(0x0000, 0x10000, null, true); + Device memory = new Memory(0x0000, 0x10000, true); Bus b = new Bus(0x0000, 0xffff); assertFalse("Address space was unexpectedly complete!", b.isComplete()); @@ -96,8 +96,8 @@ public class BusTest extends TestCase { } public void testIsCompleteWithTwoDevices() throws MemoryRangeException { - Device memory = new Memory(0x0000, 0x8000, null, true); - Device rom = new Memory(0x8000, 0x8000, null, false); + Device memory = new Memory(0x0000, 0x8000, true); + Device rom = new Memory(0x8000, 0x8000, false); Bus b = new Bus(0x0000, 0xffff); assertFalse("Address space was unexpectedly complete!", b.isComplete()); @@ -108,9 +108,9 @@ public class BusTest extends TestCase { } public void testIsCompleteWithThreeDevices() throws MemoryRangeException { - Device memory = new Memory(0x0000, 0x8000, null, true); - Device rom1 = new Memory(0x8000, 0x4000, null, false); - Device rom2 = new Memory(0xC000, 0x4000, null, false); + Device memory = new Memory(0x0000, 0x8000, true); + Device rom1 = new Memory(0x8000, 0x4000, false); + Device rom2 = new Memory(0xC000, 0x4000, false); Bus b = new Bus(0x0000, 0xffff); assertFalse("Address space was unexpectedly complete!", b.isComplete()); diff --git a/src/test/java/com/loomcom/lm6502/CpuTest.java b/src/test/java/com/loomcom/lm6502/CpuTest.java index 6de6af4..e8d2b24 100644 --- a/src/test/java/com/loomcom/lm6502/CpuTest.java +++ b/src/test/java/com/loomcom/lm6502/CpuTest.java @@ -19,14 +19,8 @@ public class CpuTest extends TestCase { } public void testCpu() { - Cpu cpu = new Cpu(new Simulator()); + Cpu cpu = new Cpu(); assertNotNull(cpu); } - public void testGetSimulator() { - Simulator sim = new Simulator(); - Cpu cpu = new Cpu(sim); - assertEquals(sim, cpu.getSimulator()); - } - } \ No newline at end of file