From ef9f7019e55fee9b1fffbda07caced12c74f53d1 Mon Sep 17 00:00:00 2001 From: Brendan Robert Date: Mon, 15 Feb 2016 23:53:24 -0600 Subject: [PATCH] Issue #24: Additional unit tests added, bugs in BBR/BBS opcodes fixed (not that there's any software that uses those...) --- src/main/java/jace/apple2e/MOS65C02.java | 19 +++---- .../jace/cpu/Basic6502FuncationalityTest.java | 53 +++++++++++++------ 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/main/java/jace/apple2e/MOS65C02.java b/src/main/java/jace/apple2e/MOS65C02.java index 09574a4..79f937e 100644 --- a/src/main/java/jace/apple2e/MOS65C02.java +++ b/src/main/java/jace/apple2e/MOS65C02.java @@ -98,6 +98,7 @@ public class MOS65C02 extends CPU { V = true; N = true; STACK = 0xff; + setWaitCycles(0); } public enum OPCODE { @@ -435,21 +436,21 @@ public class MOS65C02 extends CPU { } return address; }), - ZP_REL(2, "$~1,$R", new AddressCalculator() { + ZP_REL(3, "$~1,$R", new AddressCalculator() { @Override public int calculateAddress(MOS65C02 cpu) { // Note: This is two's compliment addition and the cpu.getMemory().read() returns a signed 8-bit value int pc = cpu.getProgramCounter(); - int address = pc + 2 + cpu.getMemory().read(pc + 2, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false); + int address = pc + 3 + cpu.getMemory().read(pc + 2, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false); // The wait cycles are not added unless the branch actually happens! - cpu.setPageBoundaryPenalty((address & 0x00ff00) != (pc & 0x00ff00)); + cpu.setPageBoundaryPenalty((address & 0x00ff00) != ((pc+3) & 0x00ff00)); return address; } @Override public int getValue(boolean isRead, MOS65C02 cpu) { int pc = cpu.getProgramCounter(); - int address = cpu.getMemory().read(pc + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false); + int address = 0x0ff & cpu.getMemory().read(pc + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false); return cpu.getMemory().read(address, TYPE.READ_DATA, true, false); } }); @@ -542,10 +543,7 @@ public class MOS65C02 extends CPU { @Override public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) { - if (((value >> bit) & 1) != 0) { - return; - } - if (cpu.C != 0) { + if ((value & (1 << bit)) == 0) { cpu.setProgramCounter(address); cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1); } @@ -562,10 +560,7 @@ public class MOS65C02 extends CPU { @Override public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) { - if (((value >> bit) & 1) == 0) { - return; - } - if (cpu.C != 0) { + if ((value & (1 << bit)) != 0) { cpu.setProgramCounter(address); cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1); } diff --git a/src/test/java/jace/cpu/Basic6502FuncationalityTest.java b/src/test/java/jace/cpu/Basic6502FuncationalityTest.java index 212de68..50afdb1 100644 --- a/src/test/java/jace/cpu/Basic6502FuncationalityTest.java +++ b/src/test/java/jace/cpu/Basic6502FuncationalityTest.java @@ -24,8 +24,6 @@ import jace.core.SoundMixer; import jace.core.Utility; import jace.ide.HeadlessProgram; import jace.ide.Program; -import java.util.Collections; -import org.junit.After; import org.junit.AfterClass; import static org.junit.Assert.*; import org.junit.Before; @@ -61,34 +59,57 @@ public class Basic6502FuncationalityTest { @Before public void setup() { cpu.suspend(); - for (int i = 0; i < 1024; i++) { - ram.write(i, (byte) 0, false, false); - } - cpu.setProgramCounter(0); - cpu.setWaitCycles(0); cpu.clearState(); } - @After - public void teardown() { - - } - @Test public void testAdditionNonDecimal() { cpu.A = 0; cpu.D = false; cpu.C = 0; assemble(" adc #1"); - assertEquals("Nothing should change yet", 0, cpu.A); - cpu.tick(); - assertEquals("0+1 = 1", 1, cpu.A); + assertEquals("0+1 (c=0) = 1", 1, cpu.A); assertFalse("Result is not zero", cpu.Z); } + @Test + public void testAdditionNonDecimalWithCarry() { + cpu.A = 0; + cpu.D = false; + cpu.C = 1; + assemble(" adc #1"); + assertEquals("0+1 (c=1) = 2", 2, cpu.A); + assertFalse("Result is not zero", cpu.Z); + } + + @Test + public void testAdditionDecimal() { + cpu.A = 9; + cpu.D = true; + cpu.C = 0; + assemble(" adc #1"); + assertEquals("9+1 (c=0) = 0x10", 0x10, cpu.A); + assertFalse("Result is not zero", cpu.Z); + } + + @Test + public void testAdditionDecimalWithCarry() { + cpu.A = 9; + cpu.D = true; + cpu.C = 1; + assemble(" adc #1"); + assertEquals("9+1 (c=1) = 0x11", 0x11, cpu.A); + assertFalse("Result is not zero", cpu.Z); + } + private void assemble(String code) { + assembleAt(code, 0x0300); + } + + private void assembleAt(String code, int addr) { HeadlessProgram program = new HeadlessProgram(Program.DocumentType.assembly); - program.setValue("*=0\n"+code+"\n BRK"); + program.setValue("*="+Integer.toHexString(addr)+"\n"+code+"\n BRK"); program.execute(); + cpu.tick(); } }