CPU bug fixes and Simulator enhancements.
Bug Fixes: - Fixed several bugs in the CPU that caused processor status flags to be set incorrectly. Instructions affected were: STA, STX, STY, CMP, CPX, CPY, BIT. - Made some internal-use-only methods on the CPU class private. - Fixed incorrect disassembly of (Indirect,X) and (Indirect),Y instructions. Although this didn't affect behavior, it certainly caused me some confusion in debugging. - Added missing "BCS" instruction to instruction table. Enhancements: - Now includes a full version of Lee Davison's Enhanced 6502 BASIC bundled as source code and a ROM image. Get that REAL COMPUTER EXPERIENCE!(tm) - If a file named "rom.bin" exists in the same directory where the simulator is executed, it will be loaded at addresses $d000-$ffff. - Gave the CPU an idle loop to make simulated timing a little more realistic (but this is still an area needing major improvement) - Changed the CPU's toString() method to give better debugging output. - Added a small typeahead buffer to the Console. - Better exception messaging. Misc: - Bumped version to 0.5, updated README.
This commit is contained in:
1 parent
c1caf8c6b4
commit
795ccfde5d
25 files changed
+13622
-4508
No files matched your search
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -412,7 +412,8 @@ public class CpuAbsoluteYModeTest extends TestCase {
|
||||
bus.loadProgram(0x99, 0x10, 0xab); // STA $ab10,Y
|
||||
cpu.step();
|
||||
assertEquals(0x00, bus.read(0xab40));
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
// STA should have NO effect on flags
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
@@ -434,7 +435,7 @@ public class CpuAbsoluteYModeTest extends TestCase {
|
||||
cpu.step();
|
||||
assertEquals(0x80, bus.read(0xab40));
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDX - Load X Register - $be */
|
||||
@@ -523,7 +524,7 @@ public class CpuAbsoluteYModeTest extends TestCase {
|
||||
cpu.step();
|
||||
assertFalse(cpu.getCarryFlag()); // m < y
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag()); // m - y > 0
|
||||
assertTrue(cpu.getNegativeFlag()); // $80 - $ff = $81
|
||||
}
|
||||
|
||||
/* SBC - Subtract with Carry - $f9 */
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -412,7 +412,7 @@ public class CpuIndirectXModeTest extends TestCase {
|
||||
bus.loadProgram(0x9d, 0x10, 0xab); // STA $ab10,X
|
||||
cpu.step();
|
||||
assertEquals(0x00, bus.read(0xab40));
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
@@ -434,7 +434,7 @@ public class CpuIndirectXModeTest extends TestCase {
|
||||
cpu.step();
|
||||
assertEquals(0x80, bus.read(0xab40));
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDA - Load Accumulator - $bd */
|
||||
@@ -494,7 +494,7 @@ public class CpuIndirectXModeTest extends TestCase {
|
||||
cpu.step();
|
||||
assertFalse(cpu.getCarryFlag()); // m < y
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag()); // m - y > 0
|
||||
assertTrue(cpu.getNegativeFlag()); // m - y < 0
|
||||
}
|
||||
|
||||
/* SBC - Subtract with Carry - $fd */
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -709,7 +709,8 @@ public class CpuZeroPageXModeTest extends TestCase {
|
||||
bus.loadProgram(0x94, 0x10); // STY $10,X
|
||||
cpu.step();
|
||||
assertEquals(0x00, bus.read(0x40));
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
// Should have no effect on flags.
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
@@ -730,7 +731,7 @@ public class CpuZeroPageXModeTest extends TestCase {
|
||||
cpu.step();
|
||||
assertEquals(0x80, bus.read(0x40));
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* STA - Store Accumulator - $95 */
|
||||
@@ -742,7 +743,8 @@ public class CpuZeroPageXModeTest extends TestCase {
|
||||
bus.loadProgram(0x95, 0x10); // STA $10,X
|
||||
cpu.step();
|
||||
assertEquals(0x00, bus.read(0x40));
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
// Should have no effect on flags.
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
@@ -763,7 +765,7 @@ public class CpuZeroPageXModeTest extends TestCase {
|
||||
cpu.step();
|
||||
assertEquals(0x80, bus.read(0x40));
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDY - Load Y Register - $b4 */
|
||||
@@ -852,7 +854,7 @@ public class CpuZeroPageXModeTest extends TestCase {
|
||||
cpu.step();
|
||||
assertFalse(cpu.getCarryFlag()); // m < y
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag()); // m - y > 0
|
||||
assertTrue(cpu.getNegativeFlag()); // m - y < 0
|
||||
}
|
||||
|
||||
/* DEC - Decrement Memory Location - $d6 */
|
||||
|
||||
@@ -7,96 +7,97 @@ import junit.framework.TestCase;
|
||||
|
||||
public class CpuZeroPageYModeTest extends TestCase {
|
||||
|
||||
protected Cpu cpu;
|
||||
protected Bus bus;
|
||||
protected Memory mem;
|
||||
protected Cpu cpu;
|
||||
protected Bus bus;
|
||||
protected Memory mem;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
this.cpu = new Cpu();
|
||||
this.bus = new Bus(0x0000, 0xffff);
|
||||
this.mem = new Memory(0x0000, 0x10000);
|
||||
bus.addCpu(cpu);
|
||||
bus.addDevice(mem);
|
||||
protected void setUp() throws Exception {
|
||||
this.cpu = new Cpu();
|
||||
this.bus = new Bus(0x0000, 0xffff);
|
||||
this.mem = new Memory(0x0000, 0x10000);
|
||||
bus.addCpu(cpu);
|
||||
bus.addDevice(mem);
|
||||
|
||||
// Load the reset vector.
|
||||
bus.write(0xfffc, Cpu.DEFAULT_BASE_ADDRESS & 0x00ff);
|
||||
bus.write(0xfffd, (Cpu.DEFAULT_BASE_ADDRESS & 0xff00)>>>8);
|
||||
// Load the reset vector.
|
||||
bus.write(0xfffc, Cpu.DEFAULT_BASE_ADDRESS & 0x00ff);
|
||||
bus.write(0xfffd, (Cpu.DEFAULT_BASE_ADDRESS & 0xff00) >>> 8);
|
||||
|
||||
cpu.reset();
|
||||
// Assert initial state
|
||||
assertEquals(0, cpu.getAccumulator());
|
||||
assertEquals(0, cpu.getXRegister());
|
||||
assertEquals(0, cpu.getYRegister());
|
||||
assertEquals(0x200, cpu.getProgramCounter());
|
||||
assertEquals(0xff, cpu.getStackPointer());
|
||||
assertEquals(0x20, cpu.getProcessorStatus());
|
||||
}
|
||||
cpu.reset();
|
||||
// Assert initial state
|
||||
assertEquals(0, cpu.getAccumulator());
|
||||
assertEquals(0, cpu.getXRegister());
|
||||
assertEquals(0, cpu.getYRegister());
|
||||
assertEquals(0x200, cpu.getProgramCounter());
|
||||
assertEquals(0xff, cpu.getStackPointer());
|
||||
assertEquals(0x20, cpu.getProcessorStatus());
|
||||
}
|
||||
|
||||
/*
|
||||
* The following opcodes are tested for correctness in this file:
|
||||
*
|
||||
* STX - $96
|
||||
* LDX - $b6
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* The following opcodes are tested for correctness in this file:
|
||||
*
|
||||
* STX - $96
|
||||
* LDX - $b6
|
||||
*
|
||||
*/
|
||||
|
||||
/* STX - Store X Register - $96 */
|
||||
/* STX - Store X Register - $96 */
|
||||
|
||||
public void test_STX() throws MemoryAccessException {
|
||||
cpu.setYRegister(0x30);
|
||||
cpu.setXRegister(0x00);
|
||||
bus.loadProgram(0x96, 0x10); // STX $10,Y
|
||||
cpu.step();
|
||||
assertEquals(0x00, bus.read(0x40));
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
public void test_STX() throws MemoryAccessException {
|
||||
cpu.setYRegister(0x30);
|
||||
cpu.setXRegister(0x00);
|
||||
bus.loadProgram(0x96, 0x10); // STX $10,Y
|
||||
cpu.step();
|
||||
assertEquals(0x00, bus.read(0x40));
|
||||
// Should have no effect on flags.
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
cpu.setYRegister(0x30);
|
||||
cpu.setXRegister(0x0f);
|
||||
bus.loadProgram(0x96, 0x10); // STX $10,Y
|
||||
cpu.step();
|
||||
assertEquals(0x0f, bus.read(0x40));
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
cpu.reset();
|
||||
cpu.setYRegister(0x30);
|
||||
cpu.setXRegister(0x0f);
|
||||
bus.loadProgram(0x96, 0x10); // STX $10,Y
|
||||
cpu.step();
|
||||
assertEquals(0x0f, bus.read(0x40));
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
cpu.setYRegister(0x30);
|
||||
cpu.setXRegister(0x80);
|
||||
bus.loadProgram(0x96, 0x10); // STX $10,Y
|
||||
cpu.step();
|
||||
assertEquals(0x80, bus.read(0x40));
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
cpu.reset();
|
||||
cpu.setYRegister(0x30);
|
||||
cpu.setXRegister(0x80);
|
||||
bus.loadProgram(0x96, 0x10); // STX $10,Y
|
||||
cpu.step();
|
||||
assertEquals(0x80, bus.read(0x40));
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDX - Load X Register - $b6 */
|
||||
/* LDX - Load X Register - $b6 */
|
||||
|
||||
public void test_LDX() throws MemoryAccessException {
|
||||
bus.write(0x40, 0x00);
|
||||
bus.write(0x41, 0x0f);
|
||||
bus.write(0x42, 0x80);
|
||||
public void test_LDX() throws MemoryAccessException {
|
||||
bus.write(0x40, 0x00);
|
||||
bus.write(0x41, 0x0f);
|
||||
bus.write(0x42, 0x80);
|
||||
|
||||
bus.loadProgram(0xb6, 0x10,
|
||||
0xb6, 0x11,
|
||||
0xb6, 0x12);
|
||||
bus.loadProgram(0xb6, 0x10,
|
||||
0xb6, 0x11,
|
||||
0xb6, 0x12);
|
||||
|
||||
cpu.setYRegister(0x30);
|
||||
cpu.setYRegister(0x30);
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getXRegister());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getXRegister());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x0f, cpu.getXRegister());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
cpu.step();
|
||||
assertEquals(0x0f, cpu.getXRegister());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x80, cpu.getXRegister());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
cpu.step();
|
||||
assertEquals(0x80, cpu.getXRegister());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user