mirror of
https://github.com/sethm/symon.git
synced 2025-04-14 21:37:21 +00:00
More unit tests. SBC partially working, but I need to figure out what's going wrong.
This commit is contained in:
parent
1bd59b048b
commit
088b0823e1
@ -6,7 +6,7 @@ import java.util.Arrays;
|
||||
* Main 6502 CPU Simulation.
|
||||
*/
|
||||
public class Cpu implements InstructionTable {
|
||||
|
||||
|
||||
public static final int DEFAULT_BASE_ADDRESS = 0x200;
|
||||
|
||||
/* The Bus */
|
||||
@ -24,9 +24,9 @@ public class Cpu implements InstructionTable {
|
||||
|
||||
/* Operands for the current instruction */
|
||||
private int[] operands = new int[2];
|
||||
private int addr; // The address the most recent instruction
|
||||
private int addr; // The address the most recent instruction
|
||||
// was fetched from
|
||||
|
||||
|
||||
/* Status Flag Register bits */
|
||||
private boolean carryFlag;
|
||||
private boolean negativeFlag;
|
||||
@ -62,13 +62,13 @@ public class Cpu implements InstructionTable {
|
||||
public void reset() {
|
||||
// Registers
|
||||
sp = 0x01ff;
|
||||
|
||||
|
||||
// Set the PC to the address stored in 0xfffc
|
||||
pc = CpuUtils.address(bus.read(0xfffc), bus.read(0xfffd));
|
||||
|
||||
|
||||
// Clear instruction register.
|
||||
ir = 0;
|
||||
|
||||
|
||||
// Clear status register bits.
|
||||
carryFlag = false;
|
||||
irqDisableFlag = false;
|
||||
@ -95,7 +95,7 @@ public class Cpu implements InstructionTable {
|
||||
|
||||
// TODO: The way we increment the PC may need
|
||||
// to change when interrupts are implemented
|
||||
|
||||
|
||||
// Increment PC
|
||||
incProgramCounter();
|
||||
|
||||
@ -109,7 +109,7 @@ public class Cpu implements InstructionTable {
|
||||
|
||||
// Execute
|
||||
switch(ir) {
|
||||
|
||||
|
||||
case 0x00: // HLT
|
||||
// TODO: Halt!
|
||||
break;
|
||||
@ -522,7 +522,8 @@ public class Cpu implements InstructionTable {
|
||||
case 0xbf: // n/a
|
||||
break;
|
||||
|
||||
case 0xc0: // n/a
|
||||
case 0xc0: // CPY - Immediate
|
||||
cmp(y, operands[0]);
|
||||
break;
|
||||
case 0xc1: // n/a
|
||||
break;
|
||||
@ -540,7 +541,8 @@ public class Cpu implements InstructionTable {
|
||||
break;
|
||||
case 0xc8: // n/a
|
||||
break;
|
||||
case 0xc9: // n/a
|
||||
case 0xc9: // CMP - Immediate
|
||||
cmp(a, operands[0]);
|
||||
break;
|
||||
case 0xca: // n/a
|
||||
break;
|
||||
@ -588,7 +590,8 @@ public class Cpu implements InstructionTable {
|
||||
case 0xdf: // n/a
|
||||
break;
|
||||
|
||||
case 0xe0: // n/a
|
||||
case 0xe0: // CPX - Immediate
|
||||
cmp(x, operands[0]);
|
||||
break;
|
||||
case 0xe1: // n/a
|
||||
break;
|
||||
@ -607,6 +610,8 @@ public class Cpu implements InstructionTable {
|
||||
case 0xe8: // n/a
|
||||
break;
|
||||
case 0xe9: // n/a
|
||||
a = sbc(a, operands[0]);
|
||||
setArithmeticFlags(a);
|
||||
break;
|
||||
case 0xea: // NOP
|
||||
break;
|
||||
@ -658,25 +663,36 @@ public class Cpu implements InstructionTable {
|
||||
|
||||
/**
|
||||
* Add with Carry, used by all addressing mode implementations of ADC.
|
||||
* As a side effect, this will set the
|
||||
*
|
||||
* As a side effect, this will set the
|
||||
*
|
||||
* @param acc The current value of the accumulator
|
||||
* @param operand The operand
|
||||
* @return
|
||||
*/
|
||||
public int adc(int acc, int operand) {
|
||||
int result = operand + a + (carryFlag ? 1 : 0);
|
||||
int carry = (operand & 0x7f) + (a & 0x7f) + (carryFlag ? 1 : 0);
|
||||
if (result > 0xff) { setCarryFlag(true); }
|
||||
int result = operand + acc + (carryFlag ? 1 : 0);
|
||||
int carry = (operand & 0x7f) + (acc & 0x7f) + (carryFlag ? 1 : 0);
|
||||
setCarryFlag(result > 0xff);
|
||||
result = result & 0xff;
|
||||
setOverflowFlag(carryFlag ^ ((carry & 0x80) != 0));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public int sbc(int acc, int operand) {
|
||||
// Equivalent to ADC of the 2's complement of the operand
|
||||
return adc(acc, (--operand) ^ 0xff);
|
||||
}
|
||||
|
||||
public void cmp(int reg, int operand) {
|
||||
setCarryFlag(reg >= operand);
|
||||
setZeroFlag(reg == operand);
|
||||
setNegativeFlag((reg - operand) > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Negative and Zero flags based on the current value of the
|
||||
* register operand.
|
||||
*
|
||||
*
|
||||
* @param reg The register.
|
||||
*/
|
||||
public void setArithmeticFlags(int reg) {
|
||||
@ -689,7 +705,7 @@ public class Cpu implements InstructionTable {
|
||||
public boolean getNegativeFlag() {
|
||||
return negativeFlag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param register the register value to test for negativity
|
||||
*/
|
||||
@ -702,7 +718,7 @@ public class Cpu implements InstructionTable {
|
||||
public void setNegativeFlag(boolean negativeFlag) {
|
||||
this.negativeFlag = negativeFlag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the carry flag
|
||||
*/
|
||||
@ -716,14 +732,14 @@ public class Cpu implements InstructionTable {
|
||||
public void setCarryFlag(boolean carryFlag) {
|
||||
this.carryFlag = carryFlag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the zero flag
|
||||
*/
|
||||
public boolean getZeroFlag() {
|
||||
return zeroFlag;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param zeroFlag the zero flag to set
|
||||
*/
|
||||
@ -786,23 +802,23 @@ public class Cpu implements InstructionTable {
|
||||
public void setOverflowFlag(boolean overflowFlag) {
|
||||
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.
|
||||
*/
|
||||
@ -819,7 +835,7 @@ public class Cpu implements InstructionTable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing the CPU state.
|
||||
* Returns a string representing the CPU state.
|
||||
*/
|
||||
public String toString() {
|
||||
String opcode = CpuUtils.opcode(ir, operands[0], operands[1]);
|
||||
@ -833,20 +849,20 @@ public class Cpu implements InstructionTable {
|
||||
sb.append("P=" + statusRegisterString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Push an item onto the stack, and decrement the stack counter.
|
||||
* Silently fails to push onto the stack if SP is
|
||||
* TODO: Unit tests.
|
||||
* TODO: Unit tests.
|
||||
*/
|
||||
protected void push(int data) {
|
||||
bus.write(sp, data);
|
||||
if (sp > 0x100) { sp--; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Pop a byte off the user stack, and increment the stack counter.
|
||||
* Pop a byte off the user stack, and increment the stack counter.
|
||||
* TODO: Unit tests.
|
||||
*/
|
||||
protected int pop() {
|
||||
@ -865,5 +881,5 @@ public class Cpu implements InstructionTable {
|
||||
++pc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
640
src/test/java/com/loomcom/symon/CpuImmediateModeTest.java
Normal file
640
src/test/java/com/loomcom/symon/CpuImmediateModeTest.java
Normal file
@ -0,0 +1,640 @@
|
||||
package com.loomcom.symon;
|
||||
|
||||
import com.loomcom.symon.devices.Memory;
|
||||
import com.loomcom.symon.exceptions.MemoryRangeException;
|
||||
import junit.framework.*;
|
||||
|
||||
public class CpuImmediateModeTest extends TestCase {
|
||||
|
||||
protected Cpu cpu;
|
||||
protected Bus bus;
|
||||
protected Memory mem;
|
||||
|
||||
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(mem);
|
||||
|
||||
// Load the reset vector.
|
||||
bus.write(0xfffc, Cpu.DEFAULT_BASE_ADDRESS & 0x00ff);
|
||||
bus.write(0xfffd, (Cpu.DEFAULT_BASE_ADDRESS & 0xff00)>>>8);
|
||||
|
||||
cpu.reset();
|
||||
}
|
||||
|
||||
/* ORA Immediate Mode Tests - 0x09 */
|
||||
|
||||
public void test_ORA_SetsAccumulator() {
|
||||
bus.loadProgram(0x09, 0x00, // ORA #$00
|
||||
0x09, 0x11, // ORA #$11
|
||||
0x09, 0x22, // ORA #$22
|
||||
0x09, 0x44, // ORA #$44
|
||||
0x09, 0x88); // ORA #$88
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x11, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x33, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x77, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0xff, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_ORA_SetsZeroFlagIfResultIsZero() {
|
||||
bus.loadProgram(0x09, 0x00); // ORA #$00
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_ORA_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.loadProgram(0x09, 0x01); // ORA #$01
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_ORA_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.loadProgram(0x09, 0x80); // ORA #$80
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_ORA_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.loadProgram(0x09, 0x7f); // ORA #$7F
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* AND Immediate Mode Tests - 0x29 */
|
||||
|
||||
public void test_AND_SetsAccumulator() {
|
||||
bus.loadProgram(0x29, 0x00, // AND #$00
|
||||
0x29, 0x11, // AND #$11
|
||||
0xa9, 0xaa, // LDA #$AA
|
||||
0x29, 0xff, // AND #$FF
|
||||
0x29, 0x99, // AND #$99
|
||||
0x29, 0x11); // AND #$11
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
|
||||
cpu.step(2);
|
||||
assertEquals(0xaa, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x88, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_AND_SetsZeroFlagIfResultIsZero() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x29, 0x11); // AND #$11
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_AND_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x29, 0xf1); // AND #$F1
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_AND_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x29, 0xf0); // AND #$F0
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_AND_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x29, 0x0f); // AND #$0F
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* EOR Immediate Mode Tests - 0x49 */
|
||||
|
||||
public void test_EOR_SetsAccumulator() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x49, 0x00, // EOR #$00
|
||||
0x49, 0xff, // EOR #$ff
|
||||
0x49, 0x33); // EOR #$33
|
||||
cpu.step(2);
|
||||
assertEquals(0x88, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x77, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x44, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_EOR_SetsArithmeticFlags() {
|
||||
bus.loadProgram(0xa9, 0x77, // LDA #$77
|
||||
0x49, 0x77, // EOR #$77
|
||||
0x49, 0xff); // EOR #$ff
|
||||
cpu.step(2);
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0xff, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* ADC Immediate Mode Tests - 0x69 */
|
||||
|
||||
public void test_ADC_SetsAccumulator() {
|
||||
bus.loadProgram(0x69, 0x01, // ADC #$01
|
||||
0x69, 0xa0, // ADC #$a0
|
||||
0x69, 0x02, // ADC #$02
|
||||
0x69, 0x06); // ADC #$06
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x01, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0xa1, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0xa3, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0xa9, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_ADC_IncludesCarry() {
|
||||
cpu.setCarryFlag(true);
|
||||
|
||||
bus.loadProgram(0x69, 0x01); // ADC #$01
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0x02, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_ADC_SetsCarryIfResultCarries() {
|
||||
bus.loadProgram(0xa9, 0xff, // LDA #$FE
|
||||
0x69, 0x02);
|
||||
|
||||
cpu.step(2);
|
||||
|
||||
assertEquals(0x01, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_SetsOverflowIfResultChangesSign() {
|
||||
bus.loadProgram(0xa9, 0x7f, // LDA #$7f
|
||||
0x69, 0x01); // ADC #$01
|
||||
|
||||
cpu.step(2);
|
||||
|
||||
assertEquals(0x80, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getOverflowFlag());
|
||||
|
||||
cpu.reset();
|
||||
|
||||
bus.loadProgram(0xa9, 0x80, // LDA #$80
|
||||
0x69, 0xff); // ADC #$ff
|
||||
|
||||
cpu.step(2);
|
||||
|
||||
assertEquals(0x7f, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertTrue(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_DoesNotSetOverflowIfNotNeeded() {
|
||||
bus.loadProgram(0xa9, 0xff, // LDA #$ff
|
||||
0x69, 0x01); // ADC #$01
|
||||
|
||||
cpu.step(2);
|
||||
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
|
||||
cpu.reset();
|
||||
|
||||
bus.loadProgram(0xa9, 0x01, // LDA #$01
|
||||
0x69, 0x01); // ADC #$01
|
||||
|
||||
cpu.step(2);
|
||||
assertEquals(0x02, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.loadProgram(0xa9, 0x7f, // LDA #$7F
|
||||
0x69, 0x01); // ADC #$01
|
||||
|
||||
cpu.step(2);
|
||||
|
||||
assertEquals(0x80, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
assertTrue(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_SetsZeroFlagIfResultIsZero() {
|
||||
bus.loadProgram(0xa9, 0xff, // LDA #$FF
|
||||
0x69, 0x01); // ADC #$01
|
||||
|
||||
cpu.step(2);
|
||||
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.loadProgram(0xa9, 0x7e, // LDA #$7E
|
||||
0x69, 0x01); // ADC #$01
|
||||
|
||||
cpu.step(2);
|
||||
|
||||
assertEquals(0x7f, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.loadProgram(0xa9, 0xff, // LDA #$ff
|
||||
0x69, 0x03); // ADC #$03
|
||||
|
||||
cpu.step(2);
|
||||
|
||||
assertEquals(0x2, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
/* LDY Immediate Mode Tests - 0xa0 */
|
||||
|
||||
public void test_LDY_SetsYRegister() {
|
||||
bus.loadProgram(0xa0, 0x12); // LDY #$12
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getYRegister());
|
||||
}
|
||||
|
||||
public void test_LDY_SetsZeroFlagIfArgIsZero() {
|
||||
bus.loadProgram(0xa0, 0x00); // LDY #$00
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.loadProgram(0xa0, 0x12); // LDY #$12
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.loadProgram(0xa0, 0x80); // LDY #$80
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.loadProgram(0xa0, 0x7f); // LDY #$7F
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDX Immediate Mode Tests - 0xa2 */
|
||||
|
||||
public void test_LDX_SetsXRegister() {
|
||||
bus.loadProgram(0xa2, 0x12); // LDX #$12
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getXRegister());
|
||||
}
|
||||
|
||||
public void test_LDX_SetsZeroFlagIfResultIsZero() {
|
||||
bus.loadProgram(0xa2, 0x00); // LDX #$00
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.loadProgram(0xa2, 0x12); // LDX #$12
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.loadProgram(0xa2, 0x80); // LDX #$80
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.loadProgram(0xa2, 0x7f); // LDX #$7F
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDA Immediate Mode Tests - 0xa9 */
|
||||
|
||||
public void test_LDA_SetsAccumulator() {
|
||||
bus.loadProgram(0xa9, 0x12); // LDA #$12
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_LDA_SetsZeroFlagIfResultIsZero() {
|
||||
bus.loadProgram(0xa9, 0x00); // LDA #$00
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.loadProgram(0xa9, 0x12); // LDA #$12
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.loadProgram(0xa9, 0x80); // LDA #$80
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.loadProgram(0xa9, 0x7f); // LDA #$7F
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* CPY Immediate Mode Tests - 0xc0 */
|
||||
|
||||
public void test_CPY_SetsZeroAndCarryFlagsIfNumbersSame() {
|
||||
bus.loadProgram(0xa0, 0x00, // LDY #$00
|
||||
0xc0, 0x00); // CPY #$00
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa0, 0x01, // LDY #$01
|
||||
0xc0, 0x01); // CPY #$01
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa0, 0x7f, // LDY #$7F
|
||||
0xc0, 0x7f); // CPY #$7F
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa0, 0xFF, // LDY #$FF
|
||||
0xc0, 0xFF); // CPY #$FF
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_CPY_SetsCarryFlagIfYGreaterThanMemory() {
|
||||
bus.loadProgram(0xa0, 0x0a, // LDY #$0A
|
||||
0xc0, 0x08); // CPY #$08
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
// $08 - $0a = negative
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa0, 0xfa, // LDY #$FA
|
||||
0xc0, 0x80); // CPY #$80
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
// $80 - $FA = negative
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_CPY_DoesNotSetCarryFlagIfYGreaterThanMemory() {
|
||||
bus.loadProgram(0xa0, 0x08, // LDY #$08
|
||||
0xc0, 0x0a); // CPY #$0A
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa0, 0x70, // LDY #$70
|
||||
0xc0, 0x80); // CPY #$80
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* CMP Immediate Mode Tests - 0xc9 */
|
||||
|
||||
public void test_CMP_SetsZeroAndCarryFlagsIfNumbersSame() {
|
||||
bus.loadProgram(0xa9, 0x00, // LDA #$00
|
||||
0xc9, 0x00); // CMP #$00
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa9, 0x01, // LDA #$01
|
||||
0xc9, 0x01); // CMP #$01
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa9, 0x7f, // LDA #$7F
|
||||
0xc9, 0x7f); // CMP #$7F
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa9, 0xFF, // LDA #$FF
|
||||
0xc9, 0xFF); // CMP #$FF
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_CMP_SetsCarryFlagIfYGreaterThanMemory() {
|
||||
bus.loadProgram(0xa9, 0x0a, // LDA #$0A
|
||||
0xc9, 0x08); // CMP #$08
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
// $08 - $0a = negative
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa9, 0xfa, // LDA #$FA
|
||||
0xc9, 0x80); // CMP #$80
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
// $80 - $FA = negative
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_CMP_DoesNotSetCarryFlagIfYGreaterThanMemory() {
|
||||
bus.loadProgram(0xa9, 0x08, // LDA #$08
|
||||
0xc9, 0x0a); // CMP #$0A
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa9, 0x70, // LDA #$70
|
||||
0xc9, 0x80); // CMP #$80
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* CPX Immediate Mode Tests - 0xe0 */
|
||||
|
||||
public void test_CPX_SetsZeroAndCarryFlagsIfNumbersSame() {
|
||||
bus.loadProgram(0xa2, 0x00, // LDX #$00
|
||||
0xe0, 0x00); // CPX #$00
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa2, 0x01, // LDX #$01
|
||||
0xe0, 0x01); // CPX #$01
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa2, 0x7f, // LDX #$7F
|
||||
0xe0, 0x7f); // CPX #$7F
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa2, 0xFF, // LDX #$FF
|
||||
0xe0, 0xFF); // CPX #$FF
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_CPX_SetsCarryFlagIfYGreaterThanMemory() {
|
||||
bus.loadProgram(0xa2, 0x0a, // LDX #$0A
|
||||
0xe0, 0x08); // CPX #$08
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
// $08 - $0a = negative
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa2, 0xfa, // LDX #$FA
|
||||
0xe0, 0x80); // CPX #$80
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
// $80 - $FA = negative
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_CPX_DoesNotSetCarryFlagIfYGreaterThanMemory() {
|
||||
bus.loadProgram(0xa2, 0x08, // LDX #$08
|
||||
0xe0, 0x0a); // CPX #$0A
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
|
||||
cpu.reset();
|
||||
bus.loadProgram(0xa2, 0x70, // LDX #$70
|
||||
0xe0, 0x80); // CMX #$80
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* SBC Immediate Mode Tests - 0xe9 */
|
||||
|
||||
public void test_SBC_SetsAccumulator() {
|
||||
bus.loadProgram(0xa9, 0xff, // LDA #$FF
|
||||
0xe9, 0x01, // SBC #$01
|
||||
0xe9, 0x01, // SBC #$a0
|
||||
0xe9, 0x01, // SBC #$02
|
||||
0xe9, 0x01); // SBC #$06
|
||||
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
cpu.step(2);
|
||||
assertEquals(0xfd, cpu.getAccumulator());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0xfc, cpu.getAccumulator());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0xfb, cpu.getAccumulator());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
|
||||
cpu.step();
|
||||
assertEquals(0xfa, cpu.getAccumulator());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
}
|
||||
|
||||
}
|
@ -1,457 +0,0 @@
|
||||
package com.loomcom.symon;
|
||||
|
||||
import com.loomcom.symon.devices.Memory;
|
||||
import com.loomcom.symon.exceptions.MemoryRangeException;
|
||||
import junit.framework.*;
|
||||
|
||||
public class CpuImmediateModeTests extends TestCase {
|
||||
|
||||
protected Cpu cpu;
|
||||
protected Bus bus;
|
||||
protected Memory mem;
|
||||
|
||||
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(mem);
|
||||
|
||||
// Load the reset vector.
|
||||
bus.write(0xfffc, Cpu.DEFAULT_BASE_ADDRESS & 0x00ff);
|
||||
bus.write(0xfffd, (Cpu.DEFAULT_BASE_ADDRESS & 0xff00)>>>8);
|
||||
|
||||
cpu.reset();
|
||||
}
|
||||
|
||||
/* ORA Immediate Mode Tests - 0x09 */
|
||||
|
||||
public void test_ORA_SetsAccumulator() {
|
||||
bus.loadProgram(0x09, 0x00, // ORA #$00
|
||||
0x09, 0x11, // ORA #$11
|
||||
0x09, 0x22, // ORA #$22
|
||||
0x09, 0x44, // ORA #$44
|
||||
0x09, 0x88); // ORA #$88
|
||||
cpu.step();
|
||||
// 0x00 | 0x00 == 0x00
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
// 0x00 | 0x11 == 0x11
|
||||
assertEquals(0x11, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
// 0x11 | 0x22 == 0x33
|
||||
assertEquals(0x33, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
// 0x33 | 0x44 == 0x77
|
||||
assertEquals(0x77, cpu.getAccumulator());
|
||||
|
||||
cpu.step();
|
||||
// 0x77 | 0x88 == 0xFF
|
||||
assertEquals(0xff, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_ORA_SetsZeroFlagIfResultIsZero() {
|
||||
bus.loadProgram(0x09, 0x00); // ORA #$00
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_ORA_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.loadProgram(0x09, 0x01); // ORA #$01
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_ORA_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.loadProgram(0x09, 0x80); // ORA #$80
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_ORA_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.loadProgram(0x09, 0x7f); // ORA #$7F
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* AND Immediate Mode Tests - 0x29 */
|
||||
|
||||
public void test_AND_SetsAccumulator() {
|
||||
bus.write(0x0200, 0x29); // AND #$00
|
||||
bus.write(0x0201, 0x00);
|
||||
cpu.step();
|
||||
// 0x00 & 0x00 == 0x00
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
|
||||
bus.write(0x0202, 0x29); // AND #$FF
|
||||
bus.write(0x0203, 0x11);
|
||||
cpu.step();
|
||||
// 0x00 & 0xff == 0x00
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
|
||||
// Load Accumulator with AA - %10101010
|
||||
|
||||
bus.write(0x0204, 0xa9); // LDA #$AA
|
||||
bus.write(0x0205, 0xaa);
|
||||
cpu.step();
|
||||
|
||||
bus.write(0x0206, 0x29); // AND #$FF
|
||||
bus.write(0x0207, 0xff);
|
||||
cpu.step();
|
||||
// 0xaa & 0xff == 0xaa
|
||||
assertEquals(0xaa, cpu.getAccumulator());
|
||||
|
||||
bus.write(0x0208, 0x29); // AND #$99
|
||||
bus.write(0x0209, 0x99);
|
||||
cpu.step();
|
||||
// 0xaa & 0x99 == 0x88
|
||||
|
||||
assertEquals(0x88, cpu.getAccumulator());
|
||||
bus.write(0x020a, 0x29); // AND #$99
|
||||
bus.write(0x020b, 0x11);
|
||||
cpu.step();
|
||||
// 0x88 & 0x11 == 0x00
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_AND_SetsZeroFlagIfResultIsZero() {
|
||||
bus.write(0x0200, 0xa9); // LDA #$88
|
||||
bus.write(0x0201, 0x88);
|
||||
cpu.step();
|
||||
bus.write(0x0202, 0x29); // AND #$11
|
||||
bus.write(0x0203, 0x11);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_AND_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x29, 0xf1); // AND #$F1
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_AND_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x29, 0xf0); // AND #$F0
|
||||
cpu.step(2);
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_AND_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x29, 0x0f); // AND #$0F
|
||||
cpu.step(2);
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* EOR Immediate Mode Tests - 0x49 */
|
||||
|
||||
public void test_EOR_SetsAccumulator() {
|
||||
bus.loadProgram(0xa9, 0x88, // LDA #$88
|
||||
0x49, 0x00, // EOR #$00
|
||||
0x49, 0xff, // EOR #$ff
|
||||
0x49, 0x33); // EOR #$33
|
||||
cpu.step();
|
||||
cpu.step();
|
||||
assertEquals(0x88, cpu.getAccumulator());
|
||||
cpu.step();
|
||||
assertEquals(0x77, cpu.getAccumulator());
|
||||
cpu.step();
|
||||
assertEquals(0x44, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_EOR_SetsArithmeticFlags() {
|
||||
bus.loadProgram(0xa9, 0x77, // LDA #$77
|
||||
0x49, 0x77, // EOR #$77
|
||||
0x49, 0xff); // EOR #$ff
|
||||
cpu.step();
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
cpu.step();
|
||||
assertEquals(0xff, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* ADC Immediate Mode Tests - 0x69 */
|
||||
|
||||
public void test_ADC_SetsAccumulator() {
|
||||
bus.write(0x200, 0x69);
|
||||
bus.write(0x201, 0x01);
|
||||
cpu.step();
|
||||
assertEquals(0x01, cpu.getAccumulator());
|
||||
|
||||
bus.write(0x202, 0x69);
|
||||
bus.write(0x203, 0xa0);
|
||||
cpu.step();
|
||||
assertEquals(0xa1, cpu.getAccumulator());
|
||||
|
||||
bus.write(0x204, 0x69);
|
||||
bus.write(0x205, 0x02);
|
||||
cpu.step();
|
||||
assertEquals(0xa3, cpu.getAccumulator());
|
||||
|
||||
bus.write(0x206, 0x69);
|
||||
bus.write(0x207, 0x06);
|
||||
cpu.step();
|
||||
assertEquals(0xa9, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_ADC_IncludesCarry() {
|
||||
cpu.setCarryFlag(true);
|
||||
bus.write(0x200, 0x69);
|
||||
bus.write(0x201, 0x01);
|
||||
cpu.step();
|
||||
assertEquals(0x02, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_ADC_SetsCarryIfResultCarries() {
|
||||
bus.write(0x200, 0xa9); // LDA #$fe
|
||||
bus.write(0x201, 0xff);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$02
|
||||
bus.write(0x203, 0x02);
|
||||
cpu.step();
|
||||
// $ff + $02 = $101 = [c] + $01
|
||||
assertEquals(0x01, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_SetsOverflowIfResultChangesSign() {
|
||||
bus.write(0x200, 0xa9); // LDA #$7f
|
||||
bus.write(0x201, 0x7f);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$01
|
||||
bus.write(0x203, 0x01);
|
||||
cpu.step();
|
||||
assertEquals(0x80, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getOverflowFlag());
|
||||
|
||||
cpu.reset();
|
||||
|
||||
bus.write(0x200, 0xa9); // LDA #$80
|
||||
bus.write(0x201, 0x80);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$ff
|
||||
bus.write(0x203, 0xff);
|
||||
cpu.step();
|
||||
assertEquals(0x7f, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertTrue(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_DoesNotSetOverflowIfNotNeeded() {
|
||||
bus.write(0x200, 0xa9); // LDA #$ff
|
||||
bus.write(0x201, 0xff);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$01
|
||||
bus.write(0x203, 0x01);
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
|
||||
cpu.reset();
|
||||
|
||||
bus.write(0x200, 0xa9); // LDA #$01
|
||||
bus.write(0x201, 0x01);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$01
|
||||
bus.write(0x203, 0x01);
|
||||
cpu.step();
|
||||
assertEquals(0x02, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.write(0x200, 0xa9); // LDA #$7f
|
||||
bus.write(0x201, 0x7f);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$01
|
||||
bus.write(0x203, 0x01);
|
||||
cpu.step();
|
||||
assertEquals(0x80, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
assertTrue(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_SetsZeroFlagIfResultIsZero() {
|
||||
bus.write(0x200, 0xa9); // LDA #$ff
|
||||
bus.write(0x201, 0xff);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$01
|
||||
bus.write(0x203, 0x01);
|
||||
cpu.step();
|
||||
assertEquals(0x00, cpu.getAccumulator());
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.write(0x200, 0xa9); // LDA #$7f
|
||||
bus.write(0x201, 0x7e);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$01
|
||||
bus.write(0x203, 0x01);
|
||||
cpu.step();
|
||||
assertEquals(0x7f, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertFalse(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
public void test_ADC_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.write(0x200, 0xa9); // LDA #$ff
|
||||
bus.write(0x201, 0xff);
|
||||
cpu.step();
|
||||
bus.write(0x202, 0x69); // ADC #$01
|
||||
bus.write(0x203, 0x03);
|
||||
cpu.step();
|
||||
assertEquals(0x2, cpu.getAccumulator());
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
assertTrue(cpu.getCarryFlag());
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
assertFalse(cpu.getOverflowFlag());
|
||||
}
|
||||
|
||||
/* LDY Immediate Mode Tests - 0xa0 */
|
||||
|
||||
public void test_LDY_SetsYRegister() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getYRegister());
|
||||
}
|
||||
|
||||
public void test_LDY_SetsZeroFlagIfArgIsZero() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x00);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x80);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDY_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.write(0x0200, 0xa0);
|
||||
bus.write(0x0201, 0x7f);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDX Immediate Mode Tests - 0xa2 */
|
||||
|
||||
public void test_LDX_SetsXRegister() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getXRegister());
|
||||
}
|
||||
|
||||
public void test_LDX_SetsZeroFlagIfResultIsZero() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x00);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x80);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDX_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.write(0x0200, 0xa2);
|
||||
bus.write(0x0201, 0x7f);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* LDA Immediate Mode Tests - 0xa9 */
|
||||
|
||||
public void test_LDA_SetsAccumulator() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertEquals(0x12, cpu.getAccumulator());
|
||||
}
|
||||
|
||||
public void test_LDA_SetsZeroFlagIfResultIsZero() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x00);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_DoesNotSetZeroFlagIfResultNotZero() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x12);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getZeroFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_SetsNegativeFlagIfResultIsNegative() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x80);
|
||||
cpu.step();
|
||||
assertTrue(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
public void test_LDA_DoesNotSetNegativeFlagIfResultNotNegative() {
|
||||
bus.write(0x0200, 0xa9);
|
||||
bus.write(0x0201, 0x7f);
|
||||
cpu.step();
|
||||
assertFalse(cpu.getNegativeFlag());
|
||||
}
|
||||
|
||||
/* CPY Immediate Mode Tests - 0xc0 */
|
||||
|
||||
/* CMP Immediate Mode Tests - 0xc9 */
|
||||
|
||||
/* CPX Immediate Mode Tests - 0xe0 */
|
||||
|
||||
/* SBC Immediate Mode Tests - 0xe9 */
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user