1
0
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:
Seth Morabito 2008-12-11 17:22:39 -08:00
parent a54dbc323d
commit 8df561d292
8 changed files with 90 additions and 97 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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());
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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());

View File

@ -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());
}
}