mirror of
https://github.com/sethm/symon.git
synced 2024-06-03 07:29:30 +00:00
a9c6d5964f
* Add 65C02 Opcode tests * All tests pass, Klaus' 6502_functional_tests pass & Klaus' 65C02_extended_opcodes_test also all pass
330 lines
9.1 KiB
Java
330 lines
9.1 KiB
Java
package com.loomcom.symon;
|
|
|
|
import com.loomcom.symon.devices.Memory;
|
|
import org.junit.Test;
|
|
|
|
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 CpuZeroPageIndirectTest {
|
|
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();
|
|
}
|
|
|
|
@Test
|
|
public void test_ora() throws Exception {
|
|
makeCmosCpu();
|
|
|
|
// Set some initial values in zero page.
|
|
bus.write(0x30, 0x00);
|
|
bus.write(0x31, 0x10);
|
|
|
|
bus.write(0x40, 0x01);
|
|
bus.write(0x41, 0x10);
|
|
|
|
bus.write(0x50, 0x02);
|
|
bus.write(0x51, 0x10);
|
|
|
|
bus.write(0x60, 0x03);
|
|
bus.write(0x61, 0x10);
|
|
|
|
bus.write(0x1000, 0x11);
|
|
bus.write(0x1001, 0x22);
|
|
bus.write(0x1002, 0x44);
|
|
bus.write(0x1003, 0x88);
|
|
|
|
bus.loadProgram(0x12, 0x30, // ORA ($30)
|
|
0x12, 0x40, // ORA ($40)
|
|
0x12, 0x50, // ORA ($50)
|
|
0x12, 0x60); // ORA ($60)
|
|
|
|
|
|
assertEquals(0x00, cpu.getAccumulator());
|
|
|
|
// 0x00 | 0x11 = 0x11
|
|
cpu.step();
|
|
assertEquals(0x11, cpu.getAccumulator());
|
|
assertFalse(cpu.getZeroFlag());
|
|
assertFalse(cpu.getNegativeFlag());
|
|
|
|
// 0x11 | 0x22 = 0x33
|
|
cpu.step();
|
|
assertEquals(0x33, cpu.getAccumulator());
|
|
assertFalse(cpu.getZeroFlag());
|
|
assertFalse(cpu.getNegativeFlag());
|
|
|
|
// 0x33 | 0x44 = 0x77
|
|
cpu.step();
|
|
assertEquals(0x77, cpu.getAccumulator());
|
|
assertFalse(cpu.getZeroFlag());
|
|
assertFalse(cpu.getNegativeFlag());
|
|
|
|
// 0x77 | 0x88 = 0xff
|
|
cpu.step();
|
|
assertEquals(0xff, cpu.getAccumulator());
|
|
assertFalse(cpu.getZeroFlag());
|
|
assertTrue(cpu.getNegativeFlag());
|
|
}
|
|
|
|
@Test
|
|
public void test_ora_requiresCmosCpu() throws Exception {
|
|
makeNmosCpu();
|
|
|
|
// Set some initial values in zero page.
|
|
bus.write(0x30, 0x00);
|
|
bus.write(0x31, 0x10);
|
|
|
|
bus.write(0x40, 0x01);
|
|
bus.write(0x41, 0x10);
|
|
|
|
bus.write(0x50, 0x02);
|
|
bus.write(0x51, 0x10);
|
|
|
|
bus.write(0x60, 0x03);
|
|
bus.write(0x61, 0x10);
|
|
|
|
bus.write(0x1000, 0x11);
|
|
bus.write(0x1001, 0x22);
|
|
bus.write(0x1002, 0x44);
|
|
bus.write(0x1003, 0x88);
|
|
|
|
bus.loadProgram(0x12, 0x30, // ORA ($30)
|
|
0x12, 0x40, // ORA ($40)
|
|
0x12, 0x50, // ORA ($50)
|
|
0x12, 0x60); // ORA ($60)
|
|
|
|
|
|
assertEquals(0x00, cpu.getAccumulator());
|
|
|
|
boolean zState = cpu.getZeroFlag();
|
|
boolean nState = cpu.getNegativeFlag();
|
|
|
|
// 0x00 | 0x11 = 0x11, but not implemented in NMOS cpu
|
|
cpu.step();
|
|
assertEquals(0x00, cpu.getAccumulator());
|
|
assertEquals(zState, cpu.getZeroFlag()); // unchanged
|
|
assertEquals(nState, cpu.getNegativeFlag()); // unchanged
|
|
|
|
// 0x11 | 0x22 = 0x33, but not implemented in NMOS cpu
|
|
cpu.step();
|
|
assertEquals(0x00, cpu.getAccumulator());
|
|
assertEquals(zState, cpu.getZeroFlag()); // unchanged
|
|
assertEquals(nState, cpu.getNegativeFlag()); // unchanged
|
|
|
|
// 0x33 | 0x44 = 0x77, but not implemented in NMOS cpu
|
|
cpu.step();
|
|
assertEquals(0x00, cpu.getAccumulator());
|
|
assertEquals(zState, cpu.getZeroFlag()); // unchanged
|
|
assertEquals(nState, cpu.getNegativeFlag()); // unchanged
|
|
|
|
// 0x77 | 0x88 = 0xff, but not implemented in NMOS cpu
|
|
cpu.step();
|
|
assertEquals(0x00, cpu.getAccumulator());
|
|
assertEquals(zState, cpu.getZeroFlag()); // unchanged
|
|
assertEquals(nState, cpu.getNegativeFlag()); // unchanged
|
|
}
|
|
|
|
@Test
|
|
public void test_and() throws Exception {
|
|
makeCmosCpu();
|
|
|
|
// Set some initial values in zero page.
|
|
bus.write(0x30, 0x00);
|
|
bus.write(0x31, 0x10);
|
|
|
|
bus.write(0x40, 0x01);
|
|
bus.write(0x41, 0x10);
|
|
|
|
bus.write(0x50, 0x02);
|
|
bus.write(0x51, 0x10);
|
|
|
|
bus.write(0x1000, 0x33);
|
|
bus.write(0x1001, 0x11);
|
|
bus.write(0x1002, 0x88);
|
|
|
|
bus.loadProgram(0x32, 0x30, // AND ($30)
|
|
0x32, 0x40, // AND ($40)
|
|
0x32, 0x50); // AND ($50)
|
|
|
|
cpu.setAccumulator(0xff);
|
|
|
|
// 0xFF & 0x33 == 0x33
|
|
cpu.step();
|
|
assertEquals(0x33, cpu.getAccumulator());
|
|
assertFalse(cpu.getZeroFlag());
|
|
assertFalse(cpu.getNegativeFlag());
|
|
|
|
// 0x33 & 0x11 == 0x11
|
|
cpu.step();
|
|
assertEquals(0x11, cpu.getAccumulator());
|
|
assertFalse(cpu.getZeroFlag());
|
|
assertFalse(cpu.getNegativeFlag());
|
|
|
|
// 0x11 & 0x80 == 0
|
|
cpu.step();
|
|
assertEquals(0, cpu.getAccumulator());
|
|
assertTrue(cpu.getZeroFlag());
|
|
assertFalse(cpu.getNegativeFlag());
|
|
}
|
|
|
|
@Test
|
|
public void test_and_requiresCmosCpu() throws Exception {
|
|
makeNmosCpu();
|
|
|
|
// Set some initial values in zero page.
|
|
bus.write(0x30, 0x00);
|
|
bus.write(0x31, 0x10);
|
|
|
|
bus.write(0x40, 0x01);
|
|
bus.write(0x41, 0x10);
|
|
|
|
bus.write(0x50, 0x02);
|
|
bus.write(0x51, 0x10);
|
|
|
|
bus.write(0x1000, 0x33);
|
|
bus.write(0x1001, 0x11);
|
|
bus.write(0x1002, 0x88);
|
|
|
|
bus.loadProgram(0x32, 0x30, // AND ($30)
|
|
0x32, 0x40, // AND ($40)
|
|
0x32, 0x50); // AND ($50)
|
|
|
|
|
|
cpu.setAccumulator(0xff);
|
|
|
|
boolean zState = cpu.getZeroFlag();
|
|
boolean nState = cpu.getNegativeFlag();
|
|
|
|
// 0xFF & 0x33 == 0x33, but not implemented in NMOS cpu
|
|
cpu.step();
|
|
assertEquals(0xff, cpu.getAccumulator());
|
|
assertEquals(zState, cpu.getZeroFlag());
|
|
assertEquals(nState, cpu.getNegativeFlag());
|
|
|
|
// 0x33 & 0x11 == 0x11, but not implemented in NMOS cpu
|
|
cpu.step();
|
|
assertEquals(0xff, cpu.getAccumulator());
|
|
assertEquals(zState, cpu.getZeroFlag());
|
|
assertEquals(nState, cpu.getNegativeFlag());
|
|
|
|
// 0x11 & 0x80 == 0, but not implemented in NMOS cpu
|
|
cpu.step();
|
|
assertEquals(0xff, cpu.getAccumulator());
|
|
assertEquals(zState, cpu.getZeroFlag());
|
|
assertEquals(nState, cpu.getNegativeFlag());
|
|
}
|
|
|
|
@Test
|
|
public void test_eor() throws Exception {
|
|
makeCmosCpu();
|
|
|
|
// Set some initial values in zero page.
|
|
bus.write(0x30, 0x00);
|
|
bus.write(0x31, 0x10);
|
|
|
|
bus.write(0x40, 0x01);
|
|
bus.write(0x41, 0x10);
|
|
|
|
bus.write(0x50, 0x02);
|
|
bus.write(0x51, 0x10);
|
|
|
|
bus.write(0x60, 0x03);
|
|
bus.write(0x61, 0x10);
|
|
|
|
bus.write(0x1000, 0x00);
|
|
bus.write(0x1001, 0xff);
|
|
bus.write(0x1002, 0x33);
|
|
bus.write(0x1003, 0x44);
|
|
|
|
bus.loadProgram(0x52, 0x30, // AND ($30)
|
|
0x52, 0x40, // AND ($40)
|
|
0x52, 0x50, // EOR ($50)
|
|
0x52, 0x60); // AND ($60)
|
|
|
|
|
|
cpu.setAccumulator(0x88);
|
|
|
|
cpu.step();
|
|
assertEquals(0x88, cpu.getAccumulator());
|
|
|
|
cpu.step();
|
|
assertEquals(0x77, cpu.getAccumulator());
|
|
|
|
cpu.step();
|
|
assertEquals(0x44, cpu.getAccumulator());
|
|
|
|
cpu.step();
|
|
assertEquals(0x00, cpu.getAccumulator());
|
|
}
|
|
|
|
@Test
|
|
public void test_eor_requiresCmosCpu() throws Exception {
|
|
makeNmosCpu();
|
|
|
|
// Set some initial values in zero page.
|
|
bus.write(0x30, 0x00);
|
|
bus.write(0x31, 0x10);
|
|
|
|
bus.write(0x40, 0x01);
|
|
bus.write(0x41, 0x10);
|
|
|
|
bus.write(0x50, 0x02);
|
|
bus.write(0x51, 0x10);
|
|
|
|
bus.write(0x60, 0x03);
|
|
bus.write(0x61, 0x10);
|
|
|
|
bus.write(0x1000, 0x00);
|
|
bus.write(0x1001, 0xff);
|
|
bus.write(0x1002, 0x33);
|
|
bus.write(0x1003, 0x44);
|
|
|
|
bus.loadProgram(0x52, 0x30, // AND ($30)
|
|
0x52, 0x40, // AND ($40)
|
|
0x52, 0x50, // EOR ($50)
|
|
0x52, 0x60); // AND ($60)
|
|
|
|
|
|
cpu.setAccumulator(0x88);
|
|
|
|
cpu.step();
|
|
assertEquals(0x88, cpu.getAccumulator());
|
|
|
|
cpu.step();
|
|
assertEquals(0x88, cpu.getAccumulator());
|
|
|
|
cpu.step();
|
|
assertEquals(0x88, cpu.getAccumulator());
|
|
|
|
cpu.step();
|
|
assertEquals(0x88, cpu.getAccumulator());
|
|
}
|
|
}
|