mirror of
https://github.com/sethm/symon.git
synced 2024-06-03 07:29:30 +00:00
Changed the CPU and Device interface a bit.
This commit is contained in:
parent
a54dbc323d
commit
8df561d292
|
@ -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<Device> 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
|
||||
|
|
|
@ -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 <tt>addr</tt> and <tt>addr + 1</tt>,
|
||||
* and return the address held there.
|
||||
*
|
||||
* @param address
|
||||
* @return The address specified in the two bytes at location <tt>addr</tt>
|
||||
*/
|
||||
private int readAddress(int address) {
|
||||
return (sim.read(address)<<8 & sim.read(address+1));
|
||||
}
|
||||
|
||||
public Simulator getSimulator() {
|
||||
return sim;
|
||||
ir = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,16 +12,20 @@ public abstract class Device implements Comparable<Device> {
|
|||
/** 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<Device> {
|
|||
public abstract int read(int address);
|
||||
public abstract String toString();
|
||||
|
||||
public void setBus(Bus bus) {
|
||||
this.bus = bus;
|
||||
}
|
||||
|
||||
public MemoryRange getMemoryRange() {
|
||||
return memoryRange;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user