refactors unit tests to separate address mode tests from instruction tests.\nAlso fixes SBC instruction

master
Joey Pollack 2 years ago
parent cccc23f2e6
commit 6af0fb3cb3

@ -173,19 +173,23 @@ impl Instructions
// Using a technique written javidx9 // Using a technique written javidx9
// The code in this function falls under the License (OLC-3) SEE LICENSE FILE // The code in this function falls under the License (OLC-3) SEE LICENSE FILE
// https://github.com/OneLoneCoder/olcNES/blob/master/Part%232%20-%20CPU/olc6502.cpp#L714 // https://github.com/OneLoneCoder/olcNES/blob/master/Part%232%20-%20CPU/olc6502.cpp#L714
//
// More info about the carry bit:
// http://forum.6502.org/viewtopic.php?t=18
pub fn SBC(cpu: &mut R6502, bus: &mut dyn Bus) pub fn SBC(cpu: &mut R6502, bus: &mut dyn Bus)
{ {
// Seem to need the + 1 here for javidx9's algorithm to work let value = cpu.working_data ^ 0x00FF;
let value = (cpu.working_data ^ 0x00FF) + 1;
let carry = cpu.check_flag(Flags::C) as u16; let carry = cpu.check_flag(Flags::C) as u16;
let temp: u16 = cpu.a as u16 + value + carry; let temp: u16 = cpu.a as u16 + value + carry;
cpu.clear_flag(Flags::C);
if temp > 255 if temp > 255
{ {
cpu.set_flag(Flags::C); cpu.set_flag(Flags::C);
} }
cpu.clear_flag(Flags::Z);
if temp == 0 if temp == 0
{ {
cpu.set_flag(Flags::Z); cpu.set_flag(Flags::Z);

@ -4,6 +4,18 @@
use crate::tests::test_bus::RAMBus; use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers}; use crate::r6502::{R6502, Bus, Registers};
#[test]
fn IMP()
{
}
#[test]
fn ACM()
{
}
#[test] #[test]
fn IMM() fn IMM()
{ {
@ -94,6 +106,19 @@ fn ZPX()
assert_eq!(0x08, cpu.debug_get_reg(Registers::A)); assert_eq!(0x08, cpu.debug_get_reg(Registers::A));
} }
#[test]
fn ZPY()
{
}
#[test]
fn REL()
{
}
#[test] #[test]
fn ABS() fn ABS()
{ {
@ -193,6 +218,12 @@ fn ABY()
assert_eq!(0x08, cpu.debug_get_reg(Registers::A)); assert_eq!(0x08, cpu.debug_get_reg(Registers::A));
} }
#[test]
fn IND()
{
}
#[test] #[test]
fn IZX() fn IZX()
{ {

@ -5,7 +5,7 @@ use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers, Flags}; use crate::r6502::{R6502, Bus, Registers, Flags};
#[test] #[test]
fn IMM() fn basic()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -32,55 +32,14 @@ fn IMM()
cpu.clock(&mut bus); cpu.clock(&mut bus);
// Is 0x0A in the A register? // Is 0x0A in the A register?
assert_eq!(0x0A, cpu.debug_get_reg(Registers::A), "Failed basic addition"); assert_eq!(0x0A, cpu.debug_get_reg(Registers::A), "Wrong answer");
assert_eq!(0, cpu.check_flag(Flags::V), "Overflow bit should not be set");
/////////////////////////////////////////// assert_eq!(0, cpu.check_flag(Flags::C), "Carry bit should not be set");
// EXTRA TESTING
// Add with carry in
// Write the program to memory
// ADC 6
bus.write(addr, 0x69); // ADC - Immediate mode
bus.write(addr + 1, 0x06); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu internals
cpu.debug_set_reg(Registers::A, 0x04);
cpu.set_flag(Flags::C);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A), "Failed addition with carry");
// Add with overflow
// Write the program to memory
// ADC 126
bus.write(addr, 0x69); // ADC - Immediate mode
bus.write(addr + 1, 126); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu internals
cpu.debug_set_reg(Registers::A, 0x04);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 130 in the A register?
assert_eq!(130, cpu.debug_get_reg(Registers::A));
// Is the overflow bit set?
assert_eq!(1, cpu.check_flag(Flags::V), "Failed addition with overflow");
} }
#[test] #[test]
fn ZP0() fn with_carry()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -92,62 +51,30 @@ fn ZP0()
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x04 into memory in the zero page // Add with carry in
bus.write(0x000B, 0x04); // Write the program to memory
// ADC 6
// ADC #6 bus.write(addr, 0x69); // ADC - Immediate mode
bus.write(addr, 0x65); // ADC - Zero Page mode bus.write(addr + 1, 0x06); // Argument
bus.write(addr + 1, 0x0B); // Argument
// Restart cpu // Restart cpu
cpu.reset(&mut bus); cpu.reset(&mut bus);
// manually setup the cpu internals
cpu.debug_set_reg(Registers::A, 0x04);
cpu.set_flag(Flags::C);
// manually setup the cpu registers // Clock the cpu twice (Clock essentially runs one full instruction)
cpu.debug_set_reg(Registers::A, 0x06);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus); cpu.clock(&mut bus);
// Is 0x0A in the A register? // Is 0x0B in the A register?
assert_eq!(0x0A, cpu.debug_get_reg(Registers::A)); assert_eq!(0x0B, cpu.debug_get_reg(Registers::A), "Wrong answer");
} assert_eq!(0, cpu.check_flag(Flags::V), "Overflow bit should not be set");
#[test]
fn ZPX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x000B, 0x04);
// ADC #A
bus.write(addr, 0x75); // ADC - Zero Page, X mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x06);
cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0A in the A register?
assert_eq!(0x0A, cpu.debug_get_reg(Registers::A));
} }
#[test] #[test]
fn ABS() fn with_overflow()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -159,95 +86,24 @@ fn ABS()
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page // Add with overflow
bus.write(0x010B, 0x06); // Write the program to memory
// ADC 126
// AND $10B bus.write(addr, 0x69); // ADC - Immediate mode
bus.write(addr, 0x6D); // ADC - Absolute mode bus.write(addr + 1, 126); // Argument
bus.write(addr + 1, 0x0B); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu // Restart cpu
cpu.reset(&mut bus); cpu.reset(&mut bus);
// manually setup the cpu registers // manually setup the cpu internals
cpu.debug_set_reg(Registers::A, 0x04); cpu.debug_set_reg(Registers::A, 0x04);
// Clock the cpu to run the program (Clock essentially runs one full instruction) // Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x0A, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory
bus.write(0x010C, 0x04);
// ADC $10C
bus.write(addr, 0x7D); // ADC - Absolute, X mode
bus.write(addr + 1, 0x0B); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x06);
cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus); cpu.clock(&mut bus);
// Is 0x0A in the A register? // Is 130 in the A register?
assert_eq!(0x0A, cpu.debug_get_reg(Registers::A)); assert_eq!(130, cpu.debug_get_reg(Registers::A));
}
#[test]
fn IZX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x04 into memory
bus.write(0x010C, 0x04);
// Manually put 0x010C into the Zero Page
bus.write(0x00B, 0x0C);
bus.write(0x00C, 0x01);
// ADC $10C
bus.write(addr, 0x61); // ADC - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument pointer into the Zero Page
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x06);
cpu.debug_set_reg(Registers::X, 0x01); // Zero Page pointer offset
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0A in the A register? // Is the overflow bit set?
assert_eq!(0x0A, cpu.debug_get_reg(Registers::A)); assert_eq!(1, cpu.check_flag(Flags::V), "Failed addition with overflow");
} }

@ -1,245 +0,0 @@
#![allow(dead_code, non_snake_case)]
use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers, Flags};
#[test]
fn IMM()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// AND #3
bus.write(addr, 0x29); // AND - Immediate mode
bus.write(addr + 1, 0x03); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x02 in the A register?
assert_eq!(0x02, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ZP0()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x000B, 0x03);
// AND #3
bus.write(addr, 0x25); // AND - Zero Page mode
bus.write(addr + 1, 0x0B); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x02 in the A register?
assert_eq!(0x02, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ZPX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x000B, 0x03);
// AND #3
bus.write(addr, 0x35); // AND - Zero Page, X mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x02 in the A register?
assert_eq!(0x02, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABS()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x010B, 0x03);
// AND #3
bus.write(addr, 0x2D); // AND - Absolute mode
bus.write(addr + 1, 0x0B); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
//cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x02 in the A register?
assert_eq!(0x02, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x010C, 0x03);
// AND #3
bus.write(addr, 0x3D); // AND - Absolute, X mode
bus.write(addr + 1, 0x0B); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x02 in the A register?
assert_eq!(0x02, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABY()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x010C, 0x03);
// AND #3
bus.write(addr, 0x39); // AND - Absolute, X mode
bus.write(addr + 1, 0x0B); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
cpu.debug_set_reg(Registers::Y, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x02 in the A register?
assert_eq!(0x02, cpu.debug_get_reg(Registers::A));
}
#[test]
fn IZX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory
bus.write(0x010C, 0x03);
// Manually put 0x010C into the Zero Page
bus.write(0x000B, 0x0C);
bus.write(0x000C, 0x01);
// AND #3
bus.write(addr, 0x21); // AND - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument - Pointer into the Zero Page
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
cpu.debug_set_reg(Registers::X, 0x01); // Zero Page pointer offset
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x02 in the A register?
assert_eq!(0x02, cpu.debug_get_reg(Registers::A));
}

@ -4,12 +4,8 @@
use crate::tests::test_bus::RAMBus; use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers, Flags}; use crate::r6502::{R6502, Bus, Registers, Flags};
//////////////////////////////////////////////////////////////////////////////
/// IMM IMM IMM IMM IMM IMM IMM IMM IMM
//////////////////////////////////////////////////////////////////////////////
#[test] #[test]
fn IMM() fn less_than()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -41,62 +37,10 @@ fn IMM()
assert_eq!(1, cpu.check_flag(Flags::C)); assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z)); assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N)); assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is equal to the A reg
// Program to compare 0x10 with 0x10
bus.write(addr, 0xC9); // CMP - Immediate mode
bus.write(addr + 1, 0x10); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 1, N Flag should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(1, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is greater than A reg
// Program to compare 0x05 with 0x10
bus.write(addr, 0xC9); // CMP - Immediate mode
bus.write(addr + 1, 0x10); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x05);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 0, N Flag should be 1
assert_eq!(0, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(1, cpu.check_flag(Flags::N));
} }
//////////////////////////////////////////////////////////////////////////////
/// ZP0 ZP0 ZP0 ZP0 ZP0 ZP0 ZP0 ZP0 ZP0
//////////////////////////////////////////////////////////////////////////////
#[test] #[test]
fn ZP0() fn equal_to()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -108,41 +52,12 @@ fn ZP0()
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
///////////////////////
// Parameter is less than A reg
// Manually put 0x05 into memory in the zero page
bus.write(0x000A, 0x05);
// Program to compare 0x10 with 0x05 (0x05 will be the argument)
bus.write(addr, 0xC5); // CMP - Zero Page mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Flag should be 1, Z N Flags should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
/////////////////////// ///////////////////////
// Parameter is equal to the A reg // Parameter is equal to the A reg
// Manually put 0x05 into memory in the zero page
bus.write(0x000A, 0x10);
// Program to compare 0x10 with 0x10 // Program to compare 0x10 with 0x10
bus.write(addr, 0xC5); // CMP - Zero Page mode bus.write(addr, 0xC9); // CMP - Immediate mode
bus.write(addr + 1, 0x0A); // Argument bus.write(addr + 1, 0x10); // Argument
// Restart cpu // Restart cpu
cpu.reset(&mut bus); cpu.reset(&mut bus);
@ -157,39 +72,10 @@ fn ZP0()
assert_eq!(1, cpu.check_flag(Flags::C)); assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(1, cpu.check_flag(Flags::Z)); assert_eq!(1, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N)); assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is greater than A reg
// Manually put 0x05 into memory in the zero page
bus.write(0x000A, 0x10);
// Program to compare 0x10 with 0x10
bus.write(addr, 0xC5); // CMP - Zero Page mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x05);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 0, N Flag should be 1
assert_eq!(0, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(1, cpu.check_flag(Flags::N));
} }
//////////////////////////////////////////////////////////////////////////////
/// ZPX ZPX ZPX ZPX ZPX ZPX ZPX ZPX ZPX
//////////////////////////////////////////////////////////////////////////////
#[test] #[test]
fn ZPX() fn greater_than()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -200,162 +86,13 @@ fn ZPX()
// Set the program counter address // Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
///////////////////////
// Parameter is less than A reg
// Manually put 0x05 into memory in the zero page
bus.write(0x000A, 0x05);
// Program to compare 0x05 and 0x10
bus.write(addr, 0xD5); // CMP - Zero Page, X mode
bus.write(addr + 1, 0x04); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x10);
cpu.debug_set_reg(Registers::X, 0x06);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Flag should be 1, Z N Flags should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is equal to the A reg
// Manually put 0x10 into memory in the zero page
bus.write(0x000A, 0x10);
// Program to compare 0x05 and 0x10
bus.write(addr, 0xD5); // CMP - Zero Page, X mode
bus.write(addr + 1, 0x04); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x10);
cpu.debug_set_reg(Registers::X, 0x06);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 1, N Flag should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(1, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is greater than A reg
// Manually put 0x10 into memory in the zero page
bus.write(0x000A, 0x10);
// Program to compare 0x05 and 0x10
bus.write(addr, 0xD5); // CMP - Zero Page, X mode
bus.write(addr + 1, 0x04); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x05);
cpu.debug_set_reg(Registers::X, 0x06);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 0, N Flag should be 1
assert_eq!(0, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(1, cpu.check_flag(Flags::N));
}
//////////////////////////////////////////////////////////////////////////////
/// ABS ABS ABS ABS ABS ABS ABS ABS ABS
//////////////////////////////////////////////////////////////////////////////
#[test]
fn ABS()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
///////////////////////
// Parameter is less than A reg
// Manually put 0x05 into memory
bus.write(0x010A, 0x05);
// Program to compare 0x05 and 0x10
bus.write(addr, 0xCD); // CMP - Absolute mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Flag should be 1, Z N Flags should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is equal to the A reg
// Manually put 0x10 into memory
bus.write(0x010A, 0x10);
// Program to compare 0x10 and 0x10
bus.write(addr, 0xCD); // LDA - Absolute mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 1, N Flag should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(1, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
/////////////////////// ///////////////////////
// Parameter is greater than A reg // Parameter is greater than A reg
// Manually put 0x10 into memory // Program to compare 0x05 with 0x10
bus.write(0x010A, 0x10); bus.write(addr, 0xC9); // CMP - Immediate mode
bus.write(addr + 1, 0x10); // Argument
// Program to compare 0x05 and 0x10
bus.write(addr, 0xCD); // LDA - Absolute mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu // Restart cpu
cpu.reset(&mut bus); cpu.reset(&mut bus);
@ -366,305 +103,6 @@ fn ABS()
// Clock the cpu to run the program (Clock essentially runs one full instruction) // Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus); cpu.clock(&mut bus);
// C Z Flags should be 0, N Flag should be 1
assert_eq!(0, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(1, cpu.check_flag(Flags::N));
}
//////////////////////////////////////////////////////////////////////////////
/// ABX ABX ABX ABX ABX ABX ABX ABX ABX
//////////////////////////////////////////////////////////////////////////////
#[test]
fn ABX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
///////////////////////
// Parameter is less than A reg
// Manually put 0x05 into memory
bus.write(0x010B, 0x05);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xDD); // CMP - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Flag should be 1, Z N Flags should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is equal to the A reg
// Manually put 0x10 into memory
bus.write(0x010B, 0x10);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xDD); // CMP - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 1, N Flag should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(1, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is greater than A reg
// Manually put 0x05 into memory
bus.write(0x010B, 0x10);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xDD); // CMP - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x05);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 0, N Flag should be 1
assert_eq!(0, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(1, cpu.check_flag(Flags::N));
}
//////////////////////////////////////////////////////////////////////////////
/// ABY ABY ABY ABY ABY ABY ABY ABY ABY
//////////////////////////////////////////////////////////////////////////////
#[test]
fn ABY()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
///////////////////////
// Parameter is less than A reg
// Manually put 0x05 into memory
bus.write(0x010B, 0x05);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xD9); // CMP - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::Y, 0x01);
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Flag should be 1, Z N Flags should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is equal to the A reg
// Manually put 0x10 into memory
bus.write(0x010B, 0x10);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xD9); // CMP - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::Y, 0x01);
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 1, N Flag should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(1, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is greater than A reg
// Manually put 0x05 into memory
bus.write(0x010B, 0x10);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xD9); // CMP - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::Y, 0x01);
cpu.debug_set_reg(Registers::A, 0x05);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 0, N Flag should be 1
assert_eq!(0, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(1, cpu.check_flag(Flags::N));
}
//////////////////////////////////////////////////////////////////////////////
/// IZX IZX IZX IZX IZX IZX IZX IZX IZX
//////////////////////////////////////////////////////////////////////////////
#[test]
fn IZX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
///////////////////////
// Parameter is less than A reg
// Manually put 0x05 into memory
bus.write(0x010B, 0x05);
// Manually put 0x010B into the Zero Page
bus.write(0x000B, 0x0B);
bus.write(0x000C, 0x01);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xC1); // CMP - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Flag should be 1, Z N Flags should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is equal to the A reg
// Manually put 0x10 into memory
bus.write(0x010B, 0x10);
// Manually put 0x010B into the Zero Page
bus.write(0x000B, 0x0B);
bus.write(0x000C, 0x01);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xC1); // CMP - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x10);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 1, N Flag should be 0
assert_eq!(1, cpu.check_flag(Flags::C));
assert_eq!(1, cpu.check_flag(Flags::Z));
assert_eq!(0, cpu.check_flag(Flags::N));
///////////////////////
// Parameter is greater than A reg
// Manually put 0x05 into memory
bus.write(0x010B, 0x10);
// Program to compare 0x05 to 0x10
bus.write(addr, 0xC1); // CMP - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument lo word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x05);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// C Z Flags should be 0, N Flag should be 1 // C Z Flags should be 0, N Flag should be 1
assert_eq!(0, cpu.check_flag(Flags::C)); assert_eq!(0, cpu.check_flag(Flags::C));
assert_eq!(0, cpu.check_flag(Flags::Z)); assert_eq!(0, cpu.check_flag(Flags::Z));

@ -1,246 +0,0 @@
#![allow(dead_code, non_snake_case)]
use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers};
#[test]
fn IMM()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// AND #3
bus.write(addr, 0x49); // EOR - Immediate mode
bus.write(addr + 1, 0x03); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x09, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ZP0()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x000B, 0x03);
// AND #3
bus.write(addr, 0x45); // EOR - Zero Page mode
bus.write(addr + 1, 0x0B); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x09, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ZPX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x000B, 0x03);
// AND #3
bus.write(addr, 0x55); // EOR - Zero Page, X mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x09, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABS()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x010B, 0x03);
// AND #3
bus.write(addr, 0x4D); // EOR - Absolute mode
bus.write(addr + 1, 0x0B); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
//cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x09, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x03 into memory
bus.write(0x010C, 0x03);
// EOR $10B
bus.write(addr, 0x5D); // EOR - Absolute, X mode
bus.write(addr + 1, 0x0B); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x09, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABY()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x010C, 0x03);
// AND #3
bus.write(addr, 0x59); // EOR - Absolute, X mode
bus.write(addr + 1, 0x0B); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
cpu.debug_set_reg(Registers::Y, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x09, cpu.debug_get_reg(Registers::A));
}
#[test]
fn IZX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
bus.write(0x010C, 0x03);
// Manually put 0x010C in the Zero Page
bus.write(0x000B, 0x0C);
bus.write(0x000C, 0x01);
// AND #3
bus.write(addr, 0x41); // EOR - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
cpu.debug_set_reg(Registers::X, 0x01);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x09, cpu.debug_get_reg(Registers::A));
}

@ -1,269 +0,0 @@
#![allow(dead_code, non_snake_case)]
// mod test_bus;
// #[cfg(test)]
use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers};
#[test]
fn IMM()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// ORA #2
bus.write(addr, 0x09); // ORA - Immediate mode
bus.write(addr + 1, 0x02); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x09);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ZP0()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x000A, 0x02);
// ORA #2
bus.write(addr, 0x05); // ORA - Zero Page mode
bus.write(addr +1, 0x0A); // Argument (memory address of the value we want to OR with)
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x09);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ZPX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x000A, 0x02);
// ORA #2
bus.write(addr, 0x15); // ORA - Zero Page, X mode
bus.write(addr + 1, 0x04); // Argument (memory address of the value we want to OR with)
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x06);
cpu.debug_set_reg(Registers::A, 0x09);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABS()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x010A, 0x02);
// ORA #2
bus.write(addr, 0x0D); // ORA - Absolute mode
bus.write(addr + 1, 0x0A); // Argument (memory address of the value we want to OR with)
bus.write(addr + 2, 0x01); // Argument (memory address of the value we want to OR with)
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
// cpu.debug_set_reg(Registers::X, 0x06);
cpu.debug_set_reg(Registers::A, 0x09);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x010B, 0x02);
// ORA #2
bus.write(addr, 0x1D); // ORA - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument (memory address of the value we want to OR with)
bus.write(addr + 2, 0x01); // Argument (memory address of the value we want to OR with)
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x09);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A));
}
#[test]
fn ABY()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x010B, 0x02);
// ORA #2
bus.write(addr, 0x19); // ORA - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument (memory address of the value we want to OR with)
bus.write(addr + 2, 0x01); // Argument (memory address of the value we want to OR with)
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::Y, 0x01);
cpu.debug_set_reg(Registers::A, 0x09);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A));
}
#[test]
fn IZX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x010B, 0x02);
// Manually put 0x010B into the Zero Page
bus.write(0x000B, 0x0B);
bus.write(0x000C, 0x01);
// ORA #2
bus.write(addr, 0x01); // ORA - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument - Pointer to Zero Page
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01); // Zero page pointer offset
cpu.debug_set_reg(Registers::A, 0x09);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A));
}

@ -2,14 +2,11 @@
#![allow(dead_code, non_snake_case)] #![allow(dead_code, non_snake_case)]
use crate::tests::test_bus::RAMBus; use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers}; use crate::r6502::{R6502, Bus, Registers, Flags};
//////////////////////////////////////////////////////////////////////////////
/// IMM IMM IMM IMM IMM IMM IMM IMM IMM
//////////////////////////////////////////////////////////////////////////////
#[test] #[test]
fn IMM() fn basic()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -28,23 +25,21 @@ fn IMM()
// Restart cpu // Restart cpu
cpu.reset(&mut bus); cpu.reset(&mut bus);
// manually setup the cpu registers // manually setup the cpu state
cpu.set_flag(Flags::C);
cpu.debug_set_reg(Registers::A, 0x0A); cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction) // Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus); cpu.clock(&mut bus);
// Is 0x04 in the A register? // Is 0x04 in the A register?
assert_eq!(0x04, cpu.debug_get_reg(Registers::A)); assert_eq!(0x04, cpu.debug_get_reg(Registers::A), "wrong answer");
assert_eq!(1, cpu.check_flag(Flags::C), "Carry bit should be set");
assert_eq!(0, cpu.check_flag(Flags::V), "Overflow bit should not be set");
} }
//////////////////////////////////////////////////////////////////////////////
/// ZP0 ZP0 ZP0 ZP0 ZP0 ZP0 ZP0 ZP0 ZP0
//////////////////////////////////////////////////////////////////////////////
#[test] #[test]
fn ZP0() fn with_carry()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -56,72 +51,28 @@ fn ZP0()
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x06 into memory in the zero page // Program to subtract 0x09 from 0x08
bus.write(0x000A, 0x06); bus.write(addr, 0xE9); // SBC - Immediate mode
bus.write(addr + 1, 0x09); // Argument
// Program to
bus.write(addr, 0xE5); // SBC - Zero Page mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x04 in the A register?
assert_eq!(0x04, cpu.debug_get_reg(Registers::A));
}
//////////////////////////////////////////////////////////////////////////////
/// ZPX ZPX ZPX ZPX ZPX ZPX ZPX ZPX ZPX
//////////////////////////////////////////////////////////////////////////////
#[test]
fn ZPX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x06 into memory in the zero page
bus.write(0x000A, 0x06);
// Program to
bus.write(addr, 0xF5); // - Zero Page, X mode
bus.write(addr + 1, 0x04); // Argument
// Restart cpu // Restart cpu
cpu.reset(&mut bus); cpu.reset(&mut bus);
// manually setup the cpu registers // manually setup the cpu state
cpu.debug_set_reg(Registers::X, 0x06); cpu.set_flag(Flags::C);
cpu.debug_set_reg(Registers::A, 0x0A); cpu.debug_set_reg(Registers::A, 0x08);
// Clock the cpu to run the program (Clock essentially runs one full instruction) // Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus); cpu.clock(&mut bus);
// Is 0x04 in the A register? // Is -1 in the A register?
assert_eq!(0x04, cpu.debug_get_reg(Registers::A)); assert_eq!(0xFF as u16, cpu.debug_get_reg(Registers::A), "Wrong answer");
assert_eq!(0, cpu.check_flag(Flags::C), "Carry bit should not be set");
assert_eq!(0, cpu.check_flag(Flags::V), "Overflow bit should not be set");
} }
//////////////////////////////////////////////////////////////////////////////
/// ABS ABS ABS ABS ABS ABS ABS ABS ABS
//////////////////////////////////////////////////////////////////////////////
#[test] #[test]
fn ABS() fn with_overflow()
{ {
let mut cpu = R6502::new(); let mut cpu = R6502::new();
let mut bus = RAMBus::new(); let mut bus = RAMBus::new();
@ -133,143 +84,22 @@ fn ABS()
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x06 into memory in the zero page // Program to subtract 0x7E from 0xFB (-5 - 126)
bus.write(0x010A, 0x06); bus.write(addr, 0xE9); // SBC - Immediate mode
bus.write(addr + 1, 0x7E); // Argument
// Program to
bus.write(addr, 0xED); // SBC - Absolute mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu // Restart cpu
cpu.reset(&mut bus); cpu.reset(&mut bus);
cpu.debug_set_reg(Registers::A, 0x0A); // manually setup the cpu state
cpu.set_flag(Flags::C);
cpu.debug_set_reg(Registers::A, 0xFB);
// Clock the cpu to run the program (Clock essentially runs one full instruction) // Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus); cpu.clock(&mut bus);
// Is 0x04 in the A register?
assert_eq!(0x04, cpu.debug_get_reg(Registers::A));
}
//////////////////////////////////////////////////////////////////////////////
/// ABX ABX ABX ABX ABX ABX ABX ABX ABX
//////////////////////////////////////////////////////////////////////////////
#[test]
fn ABX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x06 into memory in the zero page
bus.write(0x010B, 0x06);
// Program to assert_eq!(0x7D, cpu.debug_get_reg(Registers::A), "Wrong answer");
bus.write(addr, 0xFD); // SBC - Absolute, X mode assert_eq!(1, cpu.check_flag(Flags::C), "Carry bit should be set");
bus.write(addr + 1, 0x0A); // Argument lo word assert_eq!(1, cpu.check_flag(Flags::V), "Overflow bit should be set");
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x04 in the A register?
assert_eq!(0x04, cpu.debug_get_reg(Registers::A));
}
//////////////////////////////////////////////////////////////////////////////
/// ABY ABY ABY ABY ABY ABY ABY ABY ABY
//////////////////////////////////////////////////////////////////////////////
#[test]
fn ABY()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x08 into memory in the zero page
bus.write(0x010B, 0x06);
// Program to
bus.write(addr, 0xF9); // - Absolute, Y mode
bus.write(addr + 1, 0x0A); // Argument lo word
bus.write(addr + 2, 0x01); // Argument hi word
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::Y, 0x01);
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x04 in the A register?
assert_eq!(0x04, cpu.debug_get_reg(Registers::A));
} }
//////////////////////////////////////////////////////////////////////////////
/// IZX IZX IZX IZX IZX IZX IZX IZX IZX
//////////////////////////////////////////////////////////////////////////////
#[test]
fn IZX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x08 into memory in the zero page
bus.write(0x010B, 0x06);
// Manually put 0x010B into the Zero page
bus.write(0x000B, 0x0B);
bus.write(0x000C, 0x01);
// Program to
bus.write(addr, 0xE1); // - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument - Pointer into the Zero Page
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01); // Zero Page Pointer offset
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x04 in the A register?
assert_eq!(0x04, cpu.debug_get_reg(Registers::A));
}

@ -1,226 +0,0 @@
#![allow(dead_code, non_snake_case)]
use crate::tests::test_bus::RAMBus;
use crate::r6502::{R6502, Bus, Registers};
#[test]
fn ZP0()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x0A into memory in the zero page
//bus.write(0x000B, 0x0A);
// STA $0A
bus.write(addr, 0x85); // STA - Zero Page mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0F);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F at memory address 0x0A?
assert_eq!(0x0F, bus.read(0x0A));
}
#[test]
fn ZPX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// STA
bus.write(addr, 0x95); // STA - Zero Page, X mode
bus.write(addr + 1, 0x04); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x06);
cpu.debug_set_reg(Registers::A, 0x0F);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F at memory address 0x0A?
assert_eq!(0x0F, bus.read(0x0A));
}
#[test]
fn ABS()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x010A, 0x02);
// STA
bus.write(addr, 0x8D); // STA - Absolute mode
bus.write(addr + 1, 0x0A); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
// cpu.debug_set_reg(Registers::X, 0x06);
cpu.debug_set_reg(Registers::A, 0x0F);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F at memory address 0x010A?
assert_eq!(0x0F, bus.read(0x010A));
}
#[test]
fn ABX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// STA
bus.write(addr, 0x9D); // STA - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01);
cpu.debug_set_reg(Registers::A, 0x0F);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F at memory address 0x010B?
assert_eq!(0x0F, bus.read(0x010B));
}
#[test]
fn ABY()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x010B, 0x02);
// STA
bus.write(addr, 0x99); // STA - Absolute, X mode
bus.write(addr + 1, 0x0A); // Argument
bus.write(addr + 2, 0x01); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::Y, 0x01);
cpu.debug_set_reg(Registers::A, 0x0F);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F at memory address 0x010B?
assert_eq!(0x0F, bus.read(0x010B));
}
#[test]
fn IZX()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Manually put 0x02 into memory in the zero page
bus.write(0x010B, 0x02);
// Manuall put 0x010B into the Zero Page
bus.write(0x000B, 0x0B);
bus.write(0x000C, 0x01);
// STA
bus.write(addr, 0x81); // STA - Indirect, X mode
bus.write(addr + 1, 0x0A); // Argument - Pointer into the Zero page
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::X, 0x01); // Zero Page pointer offset
cpu.debug_set_reg(Registers::A, 0x0F);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F at memory address 0x010B?
assert_eq!(0x0F, bus.read(0x010B));
}

@ -1,21 +1,163 @@
#[cfg(test)] #![allow(dead_code, non_snake_case)]
mod ORA;
#[cfg(test)] use crate::tests::test_bus::RAMBus;
mod AND; use crate::r6502::{R6502, Bus, Registers, Flags};
#[cfg(test)]
mod EOR; #[test]
fn ORA()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// ORA #2
bus.write(addr, 0x09); // ORA - Immediate mode
bus.write(addr + 1, 0x02); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x09);
// Clock the cpu twice (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0B in the A register?
assert_eq!(0x0B, cpu.debug_get_reg(Registers::A));
}
#[cfg(test)] #[cfg(test)]
mod ADC; mod ADC;
#[cfg(test)] #[test]
mod LDA; fn AND()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
#[cfg(test)] // program address
mod STA; let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// AND #3
bus.write(addr, 0x29); // AND - Immediate mode
bus.write(addr + 1, 0x03); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x02 in the A register?
assert_eq!(0x02, cpu.debug_get_reg(Registers::A));
}
#[test]
fn EOR()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// AND #3
bus.write(addr, 0x49); // EOR - Immediate mode
bus.write(addr + 1, 0x03); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0A);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x09 in the A register?
assert_eq!(0x09, cpu.debug_get_reg(Registers::A));
}
#[test]
fn LDA()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// Program to load 0x08 into the accumulator
bus.write(addr, 0xA9); // LDA - Immediate mode
bus.write(addr + 1, 0x08); // Argument
// Restart cpu
cpu.reset(&mut bus);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x08 in the A register?
assert_eq!(0x08, cpu.debug_get_reg(Registers::A));
}
#[test]
fn STA()
{
let mut cpu = R6502::new();
let mut bus = RAMBus::new();
// program address
let addr = 0x0020 as u16;
// Set the program counter address
bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte
bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte
// STA $0A
bus.write(addr, 0x85); // STA - Zero Page mode
bus.write(addr + 1, 0x0A); // Argument
// Restart cpu
cpu.reset(&mut bus);
// manually setup the cpu registers
cpu.debug_set_reg(Registers::A, 0x0F);
// Clock the cpu to run the program (Clock essentially runs one full instruction)
cpu.clock(&mut bus);
// Is 0x0F at memory address 0x0A?
assert_eq!(0x0F, bus.read(0x0A));
}
#[cfg(test)] #[cfg(test)]
mod CMP; mod CMP;

Loading…
Cancel
Save