* Add Support for All 65C02 Opcodes and all Rockwell/WDC opcodes except WAI/STP
* Add 65C02 Opcode tests * All tests pass, Klaus' 6502_functional_tests pass & Klaus' 65C02_extended_opcodes_test also all pass
This commit is contained in:
1 parent
faf5d22660
commit
a9c6d5964f
13 files changed
+2655
-153
No files matched your search
@@ -0,0 +1,252 @@
|
||||
package com.loomcom.symon;
|
||||
|
||||
import com.loomcom.symon.devices.Memory;
|
||||
import com.loomcom.symon.exceptions.MemoryAccessException;
|
||||
import junit.framework.*;
|
||||
|
||||
import static junit.framework.TestCase.assertFalse;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test for Zero Page Indirect addressing mode, found on some instructions
|
||||
* in the 65C02 and 65816
|
||||
*/
|
||||
public class Cpu65C02ImpliedModeTest extends TestCase {
|
||||
protected Cpu cpu;
|
||||
protected Bus bus;
|
||||
protected Memory mem;
|
||||
|
||||
private void makeCmosCpu() throws Exception {
|
||||
makeCpu(InstructionTable.CpuBehavior.CMOS_6502);
|
||||
}
|
||||
|
||||
private void makeNmosCpu() throws Exception {
|
||||
makeCpu(InstructionTable.CpuBehavior.NMOS_6502);
|
||||
}
|
||||
|
||||
private void makeCpu(InstructionTable.CpuBehavior behavior) throws Exception {
|
||||
this.cpu = new Cpu(behavior);
|
||||
this.bus = new Bus(0x0000, 0xffff);
|
||||
this.mem = new Memory(0x0000, 0xffff);
|
||||
bus.addCpu(cpu);
|
||||
bus.addDevice(mem);
|
||||
|
||||
// Load the reset vector.
|
||||
bus.write(0xfffc, Bus.DEFAULT_LOAD_ADDRESS & 0x00ff);
|
||||
bus.write(0xfffd, (Bus.DEFAULT_LOAD_ADDRESS & 0xff00) >>> 8);
|
||||
|
||||
cpu.reset();
|
||||
}
|
||||
|
||||
public void test_PHX() throws Exception {
|
||||
makeCmosCpu();
|
||||
cpu.stackPush(0x00);
|
||||
cpu.setXRegister(0xff);
|
||||
bus.loadProgram(0xda);
|
||||
|
||||
assertEquals(cpu.stackPeek(), 0x00);
|
||||
cpu.step();
|
||||
assertEquals(cpu.stackPeek(), 0xff);
|
||||
|
||||
}
|
||||
|
||||
public void test_PHXRequiresCmosCpu() throws Exception {
|
||||
makeNmosCpu();
|
||||
cpu.stackPush(0x00);
|
||||
cpu.setXRegister(0xff);
|
||||
bus.loadProgram(0xda);
|
||||
|
||||
assertEquals(cpu.stackPeek(), 0x00);
|
||||
cpu.step();
|
||||
assertEquals(cpu.stackPeek(), 0x00);
|
||||
|
||||
}
|
||||
|
||||
public void test_PLX() throws Exception {
|
||||
makeCmosCpu();
|
||||
cpu.stackPush(0xff);
|
||||
cpu.setXRegister(0x00);
|
||||
bus.loadProgram(0xfa);
|
||||
|
||||
assertEquals(0x00, cpu.getXRegister());
|
||||
cpu.step();
|
||||
assertEquals(0xff, cpu.getXRegister());
|
||||
|
||||
}
|
||||
|
||||
public void test_PLXRequiresCmosCpu() throws Exception {
|
||||
makeNmosCpu();
|
||||
cpu.stackPush(0xff);
|
||||
cpu.setXRegister(0x00);
|
||||
bus.loadProgram(0xfa);
|
||||
|
||||
assertEquals(0x00, cpu.getXRegister());
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getXRegister());
|
||||
|
||||
}
|
||||
|
||||
public void test_PHY() throws Exception {
|
||||
makeCmosCpu();
|
||||
cpu.stackPush(0x00);
|
||||
cpu.setYRegister(0xff);
|
||||
bus.loadProgram(0x5a);
|
||||
|
||||
assertEquals(0x00, cpu.stackPeek());
|
||||
cpu.step();
|
||||
assertEquals(0xff, cpu.stackPeek());
|
||||
|
||||
}
|
||||
|
||||
public void test_PHYRequiresCmosCpu() throws Exception {
|
||||
makeNmosCpu();
|
||||
cpu.stackPush(0x00);
|
||||
cpu.setYRegister(0xff);
|
||||
bus.loadProgram(0x5a);
|
||||
|
||||
assertEquals(0x00, cpu.stackPeek());
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.stackPeek());
|
||||
|
||||
}
|
||||
|
||||
public void test_PLY() throws Exception {
|
||||
makeCmosCpu();
|
||||
cpu.stackPush(0xff);
|
||||
cpu.setYRegister(0x00);
|
||||
bus.loadProgram(0x7a);
|
||||
|
||||
assertEquals(0x00, cpu.getYRegister());
|
||||
cpu.step();
|
||||
assertEquals(0xff, cpu.getYRegister());
|
||||
|
||||
}
|
||||
|
||||
public void test_PLYRequiresCmosCpu() throws Exception {
|
||||
makeNmosCpu();
|
||||
cpu.stackPush(0xff);
|
||||
cpu.setYRegister(0x00);
|
||||
bus.loadProgram(0x7a);
|
||||
|
||||
assertEquals(0x00, cpu.getYRegister());
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getYRegister());
|
||||
|
||||
}
|
||||
|
||||
public void test_INC_A() throws Exception {
|
||||
makeCmosCpu();
|
||||
cpu.setAccumulator(0x10);
|
||||
bus.loadProgram(0x1a);
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x11, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
// Incrementing to 0 should set Zero Flag
|
||||
cpu.reset();
|
||||
cpu.setAccumulator(0xff);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
// Should set Negative Flag
|
||||
cpu.reset();
|
||||
cpu.setAccumulator(0x7F);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
|
||||
}
|
||||
|
||||
public void test_INC_ARequiresCmosCpu() throws Exception {
|
||||
makeNmosCpu();
|
||||
cpu.setAccumulator(0x10);
|
||||
bus.loadProgram(0x1a);
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x10, cpu.getAccumulator());
|
||||
|
||||
}
|
||||
|
||||
public void test_DEC_A() throws Exception {
|
||||
makeCmosCpu();
|
||||
cpu.setAccumulator(0x10);
|
||||
bus.loadProgram(0x3a);
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x0F, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
// Decrementing to 0 should set Zero Flag
|
||||
cpu.reset();
|
||||
cpu.setAccumulator(0x01);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
// Should set Negative Flag
|
||||
cpu.reset();
|
||||
cpu.setAccumulator(0x00);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
|
||||
}
|
||||
|
||||
public void test_DEC_ARequiresCmosCpu() throws Exception {
|
||||
makeNmosCpu();
|
||||
cpu.setAccumulator(0x10);
|
||||
bus.loadProgram(0x3a);
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x10, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
}
|
||||
|
||||
public void test_BRK_clearsDecimalModeFlag() throws Exception {
|
||||
makeCmosCpu();
|
||||
cpu.setDecimalModeFlag();
|
||||
assertEquals(0x00, cpu.stackPeek());
|
||||
assertFalse(cpu.getBreakFlag());
|
||||
assertTrue(cpu.getDecimalModeFlag());
|
||||
assertEquals(0x0200, cpu.getProgramCounter());
|
||||
assertEquals(0xff, cpu.getStackPointer());
|
||||
|
||||
// Set the IRQ vector
|
||||
bus.write(0xffff, 0x12);
|
||||
bus.write(0xfffe, 0x34);
|
||||
|
||||
bus.loadProgram(0xea, // NOP
|
||||
0xea, // NOP
|
||||
0xea, // NOP
|
||||
0x00, // BRK
|
||||
0xea, // NOP
|
||||
0xea); // NOP
|
||||
|
||||
cpu.step(3); // Three NOP instructions
|
||||
|
||||
assertEquals(0x203, cpu.getProgramCounter());
|
||||
assertTrue(cpu.getDecimalModeFlag());
|
||||
cpu.step(); // Triggers the BRK
|
||||
|
||||
// Was at PC = 0x204. PC+1 should now be on the stack
|
||||
assertEquals(0x02, bus.read(0x1ff, true)); // PC high byte
|
||||
assertEquals(0x05, bus.read(0x1fe, true)); // PC low byte
|
||||
|
||||
|
||||
// Interrupt vector held 0x1234, so we should be there.
|
||||
assertEquals(0x1234, cpu.getProgramCounter());
|
||||
assertEquals(0xfc, cpu.getStackPointer());
|
||||
|
||||
// B and I flags should have been set on P
|
||||
assertTrue(cpu.getBreakFlag());
|
||||
assertFalse(cpu.getDecimalModeFlag());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user