mirror of
https://github.com/sethm/symon.git
synced 2025-04-14 21:37:21 +00:00
1. CPU now correctly sets Zero and Negative flags for LDA, LDX, and LDY
immediate mode instructions. 2. Added unit tests for LDA, LDX, LDY immediate mode instructions.
This commit is contained in:
parent
59e5572039
commit
9a6a256073
@ -27,6 +27,7 @@ public class Cpu implements InstructionTable {
|
||||
|
||||
/* Status Flag Register bits */
|
||||
private boolean carryFlag;
|
||||
private boolean negativeFlag;
|
||||
private boolean zeroFlag;
|
||||
private boolean irqDisableFlag;
|
||||
private boolean decimalModeFlag;
|
||||
@ -435,13 +436,15 @@ public class Cpu implements InstructionTable {
|
||||
|
||||
case 0xa0: // LDY - Immediate
|
||||
y = operands[0];
|
||||
// TODO: Set Zero Flag, Negative Flag
|
||||
setZeroFlag(y);
|
||||
setNegativeFlag(y);
|
||||
break;
|
||||
case 0xa1: // n/a
|
||||
break;
|
||||
case 0xa2: // LDX - Immediate
|
||||
x = operands[0];
|
||||
// TODO: Set Zero Flag, Negative Flag
|
||||
setZeroFlag(x);
|
||||
setNegativeFlag(x);
|
||||
break;
|
||||
case 0xa3: // n/a
|
||||
break;
|
||||
@ -457,7 +460,8 @@ public class Cpu implements InstructionTable {
|
||||
break;
|
||||
case 0xa9: // LDA - Immediate
|
||||
a = operands[0];
|
||||
// TODO: Set Zero Flag, Negative Flag
|
||||
setZeroFlag(a);
|
||||
setNegativeFlag(a);
|
||||
break;
|
||||
case 0xaa: // n/a
|
||||
break;
|
||||
@ -643,8 +647,21 @@ public class Cpu implements InstructionTable {
|
||||
* @return the negative flag
|
||||
*/
|
||||
public boolean getNegativeFlag() {
|
||||
// True if the most significant bit is '1'
|
||||
return ((a>>>7)&0xff) == 1;
|
||||
return negativeFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param register the register value to test for negativity
|
||||
*/
|
||||
public void setNegativeFlag(int register) {
|
||||
this.negativeFlag = (((register>>>7)&0xff) == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param negativeFlag the negative flag to set
|
||||
*/
|
||||
public void setNegativeFlag(boolean negativeFlag) {
|
||||
this.negativeFlag = negativeFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -668,6 +685,13 @@ public class Cpu implements InstructionTable {
|
||||
return zeroFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param register the register to test for zero
|
||||
*/
|
||||
public void setZeroFlag(int register) {
|
||||
this.zeroFlag = (register == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param zeroFlag the zero flag to set
|
||||
*/
|
||||
@ -731,6 +755,22 @@ public class Cpu implements InstructionTable {
|
||||
this.overflowFlag = overflowFlag;
|
||||
}
|
||||
|
||||
public int getAccumulator() {
|
||||
return a;
|
||||
}
|
||||
|
||||
public int getXRegister() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getYRegister() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getProgramCounter() {
|
||||
return pc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string representing the current status register state.
|
||||
*/
|
||||
@ -751,12 +791,13 @@ public class Cpu implements InstructionTable {
|
||||
*/
|
||||
public String toString() {
|
||||
String opcode = CpuUtils.opcode(ir, operands[0], operands[1]);
|
||||
StringBuffer sb = new StringBuffer(String.format("$%04X", addr) + " ");
|
||||
sb.append(String.format("%-12s", opcode));
|
||||
sb.append("A=" + String.format("$%02X", a) + "; ");
|
||||
sb.append("X=" + String.format("$%02X", x) + "; ");
|
||||
sb.append("Y=" + String.format("$%02X", y) + "; ");
|
||||
sb.append("PC=" + String.format("$%04X", pc)+ "; ");
|
||||
StringBuffer sb = new StringBuffer(String.format("$%04X", addr) +
|
||||
" ");
|
||||
sb.append(String.format("%-14s", opcode));
|
||||
sb.append("A=" + String.format("$%02X", a) + " ");
|
||||
sb.append("X=" + String.format("$%02X", x) + " ");
|
||||
sb.append("Y=" + String.format("$%02X", y) + " ");
|
||||
sb.append("PC=" + String.format("$%04X", pc)+ " ");
|
||||
sb.append("P=" + statusRegisterString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public class CpuUtils {
|
||||
*/
|
||||
public static String opcode(int opcode, int op1, int op2) {
|
||||
String opcodeName = Cpu.opcodeNames[opcode];
|
||||
if (opcodeName == null) { return "??"; }
|
||||
if (opcodeName == null) { return "???"; }
|
||||
|
||||
StringBuffer sb = new StringBuffer(opcodeName);
|
||||
|
||||
|
@ -65,23 +65,30 @@ public class Simulator {
|
||||
bus.write(0x0306, 0x1a);
|
||||
bus.write(0x0307, 0xea); // NOP
|
||||
bus.write(0x0308, 0xea); // NOP
|
||||
bus.write(0x0309, 0xa2); // LDX #$03
|
||||
bus.write(0x030a, 0x03);
|
||||
bus.write(0x0309, 0xa2); // LDX #$90
|
||||
bus.write(0x030a, 0x90);
|
||||
|
||||
bus.write(0x030b, 0xa9); // LDA #$00
|
||||
bus.write(0x030c, 0x00);
|
||||
bus.write(0x030d, 0xa2); // LDX #$00
|
||||
bus.write(0x030e, 0x00);
|
||||
bus.write(0x030f, 0xa0); // LDY #$00
|
||||
bus.write(0x0310, 0x00);
|
||||
bus.write(0x030b, 0xea); // NOP
|
||||
bus.write(0x030c, 0xea); // NOP
|
||||
bus.write(0x030d, 0xea); // NOP
|
||||
|
||||
bus.write(0x030e, 0xa2); // LDX #$02
|
||||
bus.write(0x030f, 0x02);
|
||||
|
||||
bus.write(0x0310, 0xa9); // LDA #$00
|
||||
bus.write(0x0311, 0x00);
|
||||
bus.write(0x0312, 0xa2); // LDX #$00
|
||||
bus.write(0x0313, 0x00);
|
||||
bus.write(0x0314, 0xa0); // LDY #$00
|
||||
bus.write(0x0315, 0x00);
|
||||
|
||||
bus.write(0x0311, 0x4c); // JMP #$0300
|
||||
bus.write(0x0312, 0x00);
|
||||
bus.write(0x0313, 0x03);
|
||||
bus.write(0x0316, 0x4c); // JMP #$0300
|
||||
bus.write(0x0317, 0x00);
|
||||
bus.write(0x0318, 0x03);
|
||||
|
||||
cpu.reset();
|
||||
|
||||
for (int i = 0; i <= 23; i++) {
|
||||
for (int i = 0; i <= 40; i++) {
|
||||
cpu.step();
|
||||
System.out.println(cpu.toString());
|
||||
}
|
||||
|
@ -2,11 +2,18 @@ package com.loomcom.lm6502;
|
||||
|
||||
import junit.framework.*;
|
||||
|
||||
import com.loomcom.lm6502.devices.*;
|
||||
import com.loomcom.lm6502.exceptions.*;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class CpuTest extends TestCase {
|
||||
|
||||
private Cpu cpu;
|
||||
private Bus bus;
|
||||
private Memory mem;
|
||||
|
||||
public CpuTest(String testName) {
|
||||
super(testName);
|
||||
}
|
||||
@ -14,10 +21,143 @@ public class CpuTest extends TestCase {
|
||||
public static Test suite() {
|
||||
return new TestSuite(CpuTest.class);
|
||||
}
|
||||
|
||||
public void setUp() throws MemoryRangeException {
|
||||
this.cpu = new Cpu();
|
||||
this.bus = new Bus(0x0000, 0xffff);
|
||||
this.mem = new Memory(0x0000, 0x10000);
|
||||
bus.addCpu(cpu);
|
||||
bus.addDevice(new Memory(0x0000, 0x10000));
|
||||
|
||||
public void testCpu() {
|
||||
Cpu cpu = new Cpu();
|
||||
assertNotNull(cpu);
|
||||
// All test programs start at 0x0200;
|
||||
bus.write(0xfffc, 0x00);
|
||||
bus.write(0xfffd, 0x02);
|
||||
|
||||
cpu.reset();
|
||||
}
|
||||
|
||||
public void testReset() {
|
||||
assertEquals(0, cpu.getAccumulator());
|
||||
assertEquals(0, cpu.getXRegister());
|
||||
assertEquals(0, cpu.getYRegister());
|
||||
assertEquals(0x0200, cpu.getProgramCounter());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getIrqDisableFlag());
|
||||
assertFalse(cpu.getDecimalModeFlag());
|
||||
assertFalse(cpu.getBreakFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDA Immediate Mode Tests - 0xa9 */
|
||||
|
||||
public void test_LDA_IMM_SetsAccumulator() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_LDA_IMM_SetsZeroFlagIfArgIsZero() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x00);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_IMM_DoesNotSetZeroFlagIfArgNotZero() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_IMM_SetsNegativeFlagIfArgIsNegative() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x80);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_IMM_DoesNotSetNegativeFlagIfArgNotNegative() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x7f);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDX Immediate Mode Tests - 0xa2 */
|
||||
|
||||
public void test_LDX_IMM_SetsXRegister() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getXRegister());
|
||||
}
|
||||
|
||||
public void test_LDX_IMM_SetsZeroFlagIfArgIsZero() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x00);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_IMM_DoesNotSetZeroFlagIfArgNotZero() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_IMM_SetsNegativeFlagIfArgIsNegative() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x80);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_IMM_DoesNotSetNegativeFlagIfArgNotNegative() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x7f);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDY Immediate Mode Tests - 0xa0 */
|
||||
|
||||
public void test_LDY_IMM_SetsYRegister() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getYRegister());
|
||||
}
|
||||
|
||||
public void test_LDY_IMM_SetsZeroFlagIfArgIsZero() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x00);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_IMM_DoesNotSetZeroFlagIfArgNotZero() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_IMM_SetsNegativeFlagIfArgIsNegative() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x80);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_IMM_DoesNotSetNegativeFlagIfArgNotNegative() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x7f);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user