mirror of
https://github.com/sethm/symon.git
synced 2024-06-07 19:29:27 +00:00
a9c6d5964f
* Add 65C02 Opcode tests * All tests pass, Klaus' 6502_functional_tests pass & Klaus' 65C02_extended_opcodes_test also all pass
253 lines
6.7 KiB
Java
253 lines
6.7 KiB
Java
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());
|
|
}
|
|
|
|
}
|