Work In Progress: CPU behavior, UI changes

This is something of a "Work in Progress" checkpoint of several features
that are all half baked:

1. Allow loading of 16KB ROM files at address $C000 at run-time, not
   just at startup. See the "Load ROM..." File menu item.

2. Introduces the notion of "CPU Behaviors", so the core 6502 CPU
   implementation can match the behavior of either an early NMOS 6502, late
   NMOS 6502, or CMOS 65C02. Very little of this is actually implemented so
   far.

3. Adds a completely bogus implementation of the 6522 VIA (it
   does absolutely nothing right now).

4. Changes the address of the ACIA in the simulated system to match a
   real hardware implementation I put together.
This commit is contained in:
Seth Morabito committed 2012-11-25 22:49:21 -08:00
1 parent 795ccfde5d
commit 2ebdd254b3
33 files changed
+822 -443

No files matched your search

+58 -7
View File
@@ -1,14 +1,37 @@
/*
* Copyright (c) 2008-2012 Seth J. Morabito <sethm@loomcom.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.loomcom.symon;
import com.loomcom.symon.exceptions.MemoryAccessException;
/**
* Main 6502 CPU Simulation.
* This class provides a simulation of the MOS 6502 CPU's state machine.
* A simple interface allows this 6502 to read and write to a simulated bus,
* and exposes some of the internal state for inspection and debugging.
*/
public class Cpu implements InstructionTable {
public static final int DEFAULT_BASE_ADDRESS = 0x200;
/* Process status register mnemonics */
public static final int P_CARRY = 0x01;
public static final int P_ZERO = 0x02;
@@ -33,6 +56,9 @@ public class Cpu implements InstructionTable {
// TODO: Make configurable
private static final int CLOCK_IN_NS = 1000;
/* Simulated behavior */
private static CpuBehavior behavior;
/* The Bus */
private Bus bus;
@@ -82,6 +108,11 @@ public class Cpu implements InstructionTable {
* Construct a new CPU.
*/
public Cpu() {
this(CpuBehavior.NMOS_WITH_INDIRECT_JMP_BUG);
}
public Cpu(CpuBehavior behavior) {
this.behavior = behavior;
}
/**
@@ -98,6 +129,14 @@ public class Cpu implements InstructionTable {
return bus;
}
public void setBehavior(CpuBehavior behavior) {
this.behavior = behavior;
}
public CpuBehavior getBehavior() {
return behavior;
}
/**
* Reset the CPU to known initial values.
*/
@@ -389,7 +428,15 @@ public class Cpu implements InstructionTable {
break;
case 0x6c: // JMP - Indirect
lo = address(args[0], args[1]); // Address of low byte
hi = lo + 1; // Address of high byte
if (args[0] == 0xff &&
(behavior == CpuBehavior.NMOS_WITH_INDIRECT_JMP_BUG ||
behavior == CpuBehavior.NMOS_WITH_ROR_BUG)) {
hi = address(0x00, args[1]);
} else {
hi = lo + 1;
}
pc = address(bus.read(lo), bus.read(hi));
/* TODO: For accuracy, allow a flag to enable broken behavior
* of early 6502s:
@@ -1400,11 +1447,15 @@ public class Cpu implements InstructionTable {
private void delayLoop(int opcode) {
int clockSteps = Cpu.instructionClocks[0xff & opcode];
// Just a precaution. This could be better.
if (clockSteps == 0) { clockSteps = 1; }
if (clockSteps == 0) {
clockSteps = 1;
}
long startTime = System.nanoTime();
long stopTime = startTime + (CLOCK_IN_NS * clockSteps);
// Busy loop
while (System.nanoTime() < stopTime) { ; }
while (System.nanoTime() < stopTime) {
;
}
}
/**
@@ -1459,7 +1510,7 @@ public class Cpu implements InstructionTable {
return sb.toString();
}
public String getInstructionByteStatus() {
switch (Cpu.instructionSizes[ir]) {
case 0: