Issue #24: Additional unit tests added, bugs in BBR/BBS opcodes fixed (not that there's any software that uses those...)

This commit is contained in:
Brendan Robert 2016-02-15 23:53:24 -06:00
parent 7edbbd9c8d
commit ef9f7019e5
2 changed files with 44 additions and 28 deletions

View File

@ -98,6 +98,7 @@ public class MOS65C02 extends CPU {
V = true; V = true;
N = true; N = true;
STACK = 0xff; STACK = 0xff;
setWaitCycles(0);
} }
public enum OPCODE { public enum OPCODE {
@ -435,21 +436,21 @@ public class MOS65C02 extends CPU {
} }
return address; return address;
}), }),
ZP_REL(2, "$~1,$R", new AddressCalculator() { ZP_REL(3, "$~1,$R", new AddressCalculator() {
@Override @Override
public int calculateAddress(MOS65C02 cpu) { public int calculateAddress(MOS65C02 cpu) {
// Note: This is two's compliment addition and the cpu.getMemory().read() returns a signed 8-bit value // Note: This is two's compliment addition and the cpu.getMemory().read() returns a signed 8-bit value
int pc = cpu.getProgramCounter(); 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! // 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; return address;
} }
@Override @Override
public int getValue(boolean isRead, MOS65C02 cpu) { public int getValue(boolean isRead, MOS65C02 cpu) {
int pc = cpu.getProgramCounter(); 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); return cpu.getMemory().read(address, TYPE.READ_DATA, true, false);
} }
}); });
@ -542,10 +543,7 @@ public class MOS65C02 extends CPU {
@Override @Override
public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) { public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) {
if (((value >> bit) & 1) != 0) { if ((value & (1 << bit)) == 0) {
return;
}
if (cpu.C != 0) {
cpu.setProgramCounter(address); cpu.setProgramCounter(address);
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1); cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
} }
@ -562,10 +560,7 @@ public class MOS65C02 extends CPU {
@Override @Override
public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) { public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) {
if (((value >> bit) & 1) == 0) { if ((value & (1 << bit)) != 0) {
return;
}
if (cpu.C != 0) {
cpu.setProgramCounter(address); cpu.setProgramCounter(address);
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1); cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
} }

View File

@ -24,8 +24,6 @@ import jace.core.SoundMixer;
import jace.core.Utility; import jace.core.Utility;
import jace.ide.HeadlessProgram; import jace.ide.HeadlessProgram;
import jace.ide.Program; import jace.ide.Program;
import java.util.Collections;
import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import org.junit.Before; import org.junit.Before;
@ -61,34 +59,57 @@ public class Basic6502FuncationalityTest {
@Before @Before
public void setup() { public void setup() {
cpu.suspend(); cpu.suspend();
for (int i = 0; i < 1024; i++) {
ram.write(i, (byte) 0, false, false);
}
cpu.setProgramCounter(0);
cpu.setWaitCycles(0);
cpu.clearState(); cpu.clearState();
} }
@After
public void teardown() {
}
@Test @Test
public void testAdditionNonDecimal() { public void testAdditionNonDecimal() {
cpu.A = 0; cpu.A = 0;
cpu.D = false; cpu.D = false;
cpu.C = 0; cpu.C = 0;
assemble(" adc #1"); assemble(" adc #1");
assertEquals("Nothing should change yet", 0, cpu.A); assertEquals("0+1 (c=0) = 1", 1, cpu.A);
cpu.tick(); assertFalse("Result is not zero", cpu.Z);
assertEquals("0+1 = 1", 1, cpu.A); }
@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); assertFalse("Result is not zero", cpu.Z);
} }
private void assemble(String code) { private void assemble(String code) {
assembleAt(code, 0x0300);
}
private void assembleAt(String code, int addr) {
HeadlessProgram program = new HeadlessProgram(Program.DocumentType.assembly); 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(); program.execute();
cpu.tick();
} }
} }