diff --git a/src/r6502/instructions.rs b/src/r6502/instructions.rs index 57f4c4d..fa839b6 100644 --- a/src/r6502/instructions.rs +++ b/src/r6502/instructions.rs @@ -173,19 +173,23 @@ impl Instructions // Using a technique written javidx9 // 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 + // + // More info about the carry bit: + // http://forum.6502.org/viewtopic.php?t=18 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) + 1; + let value = cpu.working_data ^ 0x00FF; let carry = cpu.check_flag(Flags::C) as u16; let temp: u16 = cpu.a as u16 + value + carry; + cpu.clear_flag(Flags::C); if temp > 255 { cpu.set_flag(Flags::C); } + cpu.clear_flag(Flags::Z); if temp == 0 { cpu.set_flag(Flags::Z); diff --git a/src/tests/instructions/LDA.rs b/src/tests/addressing_modes/mod.rs similarity index 98% rename from src/tests/instructions/LDA.rs rename to src/tests/addressing_modes/mod.rs index 12c4d5d..a4c2a83 100644 --- a/src/tests/instructions/LDA.rs +++ b/src/tests/addressing_modes/mod.rs @@ -4,6 +4,18 @@ use crate::tests::test_bus::RAMBus; use crate::r6502::{R6502, Bus, Registers}; +#[test] +fn IMP() +{ + +} + +#[test] +fn ACM() +{ + +} + #[test] fn IMM() { @@ -94,6 +106,19 @@ fn ZPX() assert_eq!(0x08, cpu.debug_get_reg(Registers::A)); } +#[test] +fn ZPY() +{ + +} + +#[test] +fn REL() +{ + +} + + #[test] fn ABS() { @@ -193,6 +218,12 @@ fn ABY() assert_eq!(0x08, cpu.debug_get_reg(Registers::A)); } +#[test] +fn IND() +{ + +} + #[test] fn IZX() { diff --git a/src/tests/instructions/ADC.rs b/src/tests/instructions/ADC.rs index 6c53606..ed9955c 100644 --- a/src/tests/instructions/ADC.rs +++ b/src/tests/instructions/ADC.rs @@ -5,7 +5,7 @@ use crate::tests::test_bus::RAMBus; use crate::r6502::{R6502, Bus, Registers, Flags}; #[test] -fn IMM() +fn basic() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -32,55 +32,14 @@ fn IMM() cpu.clock(&mut bus); // Is 0x0A in the A register? - assert_eq!(0x0A, cpu.debug_get_reg(Registers::A), "Failed basic addition"); - - /////////////////////////////////////////// - // 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"); + 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"); } #[test] -fn ZP0() +fn with_carry() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -92,62 +51,30 @@ fn ZP0() bus.write(0xFFFC, (addr & 0x00FF) as u8); // low byte bus.write(0xFFFD, ((addr & 0xFF00) >> 8) as u8); // high byte - // Manually put 0x04 into memory in the zero page - bus.write(0x000B, 0x04); - - // ADC #6 - bus.write(addr, 0x65); // ADC - Zero Page mode - bus.write(addr + 1, 0x0B); // Argument + // 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); - // manually setup the cpu registers - cpu.debug_set_reg(Registers::A, 0x06); - - // 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 0x0A in the A register? - assert_eq!(0x0A, 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, 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 0x0B in the A register? + 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"); - // Is 0x0A in the A register? - assert_eq!(0x0A, cpu.debug_get_reg(Registers::A)); } #[test] -fn ABS() +fn with_overflow() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -159,95 +86,24 @@ fn ABS() 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, 0x06); - - // AND $10B - bus.write(addr, 0x6D); // ADC - Absolute mode - bus.write(addr + 1, 0x0B); // Argument - bus.write(addr + 2, 0x01); // Argument + // 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 registers + + // manually setup the cpu internals cpu.debug_set_reg(Registers::A, 0x04); - // 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!(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) + // Clock the cpu twice (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] -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 130 in the A register? + assert_eq!(130, cpu.debug_get_reg(Registers::A)); - // Is 0x0A in the A register? - assert_eq!(0x0A, cpu.debug_get_reg(Registers::A)); + // Is the overflow bit set? + assert_eq!(1, cpu.check_flag(Flags::V), "Failed addition with overflow"); } \ No newline at end of file diff --git a/src/tests/instructions/AND.rs b/src/tests/instructions/AND.rs deleted file mode 100644 index 36b4a5f..0000000 --- a/src/tests/instructions/AND.rs +++ /dev/null @@ -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)); -} \ No newline at end of file diff --git a/src/tests/instructions/CMP.rs b/src/tests/instructions/CMP.rs index 1da17bf..50f8a2f 100644 --- a/src/tests/instructions/CMP.rs +++ b/src/tests/instructions/CMP.rs @@ -4,12 +4,8 @@ use crate::tests::test_bus::RAMBus; use crate::r6502::{R6502, Bus, Registers, Flags}; -////////////////////////////////////////////////////////////////////////////// -/// IMM IMM IMM IMM IMM IMM IMM IMM IMM -////////////////////////////////////////////////////////////////////////////// - #[test] -fn IMM() +fn less_than() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -41,62 +37,10 @@ fn IMM() 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 - - // 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] -fn ZP0() +fn equal_to() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -108,41 +52,12 @@ fn ZP0() 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 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 - // 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 + bus.write(addr, 0xC9); // CMP - Immediate mode + bus.write(addr + 1, 0x10); // Argument // Restart cpu 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::Z)); 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] -fn ZPX() +fn greater_than() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -200,162 +86,13 @@ fn ZPX() // 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 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 - // Manually put 0x10 into memory - bus.write(0x010A, 0x10); - - // 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 + // 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); @@ -366,305 +103,6 @@ fn ABS() // 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)); -} - -////////////////////////////////////////////////////////////////////////////// -/// 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 assert_eq!(0, cpu.check_flag(Flags::C)); assert_eq!(0, cpu.check_flag(Flags::Z)); diff --git a/src/tests/instructions/EOR.rs b/src/tests/instructions/EOR.rs deleted file mode 100644 index 575cc70..0000000 --- a/src/tests/instructions/EOR.rs +++ /dev/null @@ -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)); -} \ No newline at end of file diff --git a/src/tests/instructions/ORA.rs b/src/tests/instructions/ORA.rs deleted file mode 100644 index d0b80c3..0000000 --- a/src/tests/instructions/ORA.rs +++ /dev/null @@ -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)); - -} diff --git a/src/tests/instructions/SBC.rs b/src/tests/instructions/SBC.rs index 82fdcae..d7224ba 100644 --- a/src/tests/instructions/SBC.rs +++ b/src/tests/instructions/SBC.rs @@ -2,14 +2,11 @@ #![allow(dead_code, non_snake_case)] 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] -fn IMM() +fn basic() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -28,23 +25,21 @@ fn IMM() // Restart cpu 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); // 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)); + 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] -fn ZP0() +fn with_carry() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -56,72 +51,28 @@ fn ZP0() 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, 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 + // Program to subtract 0x09 from 0x08 + bus.write(addr, 0xE9); // SBC - Immediate mode + bus.write(addr + 1, 0x09); // 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, 0x0A); + // manually setup the cpu state + cpu.set_flag(Flags::C); + cpu.debug_set_reg(Registers::A, 0x08); // 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)); + // Is -1 in the A register? + 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] -fn ABS() +fn with_overflow() { let mut cpu = R6502::new(); let mut bus = RAMBus::new(); @@ -133,143 +84,22 @@ fn ABS() 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(0x010A, 0x06); - - // 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 + // Program to subtract 0x7E from 0xFB (-5 - 126) + bus.write(addr, 0xE9); // SBC - Immediate mode + bus.write(addr + 1, 0x7E); // Argument // Restart cpu 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) 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 - bus.write(addr, 0xFD); // SBC - 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, 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)); + assert_eq!(0x7D, cpu.debug_get_reg(Registers::A), "Wrong answer"); + assert_eq!(1, cpu.check_flag(Flags::C), "Carry bit should be set"); + assert_eq!(1, cpu.check_flag(Flags::V), "Overflow bit should be set"); } - -////////////////////////////////////////////////////////////////////////////// -/// 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)); -} \ No newline at end of file diff --git a/src/tests/instructions/STA.rs b/src/tests/instructions/STA.rs deleted file mode 100644 index 308e3c0..0000000 --- a/src/tests/instructions/STA.rs +++ /dev/null @@ -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)); - -} \ No newline at end of file diff --git a/src/tests/instructions/mod.rs b/src/tests/instructions/mod.rs index d4af1c0..8857328 100644 --- a/src/tests/instructions/mod.rs +++ b/src/tests/instructions/mod.rs @@ -1,21 +1,163 @@ -#[cfg(test)] -mod ORA; +#![allow(dead_code, non_snake_case)] -#[cfg(test)] -mod AND; +use crate::tests::test_bus::RAMBus; +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)] mod ADC; -#[cfg(test)] -mod LDA; +#[test] +fn AND() +{ + let mut cpu = R6502::new(); + let mut bus = RAMBus::new(); -#[cfg(test)] -mod STA; + // 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 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)] mod CMP;